stage2 提供近乎完整的功能但出现严重性能问题 添加stage0的原生性能记录 stage1添加更多内置函数 nob重构代码使其更加健壮
This commit is contained in:
1 parent
b5a7a811b3
commit
e02b0c633a
35 files changed
+14018
-216
No files matched your search
+39
-12
@@ -49,14 +49,17 @@ fn new(elem_size: usize, elem_align: usize): VecResult {
|
||||
ret .Ok(blank(elem_size, elem_align));
|
||||
}
|
||||
|
||||
fn valid(self: Vec): bool {
|
||||
if self.elem_size == 0 || !valid_alignment(self.elem_align) { ret false; }
|
||||
// 按指针接收,避免每次调用复制整个 Vec;内联对齐检查,省一次函数调用。
|
||||
fn valid(self: *Vec): bool {
|
||||
if self.elem_size == 0 { ret false; }
|
||||
var a = self.elem_align;
|
||||
if a == 0 || (a & (a - 1)) != 0 { ret false; }
|
||||
if self.len > self.cap { ret false; }
|
||||
if self.cap == 0 {
|
||||
ret self.raw == null && self.data == null && self.len == 0;
|
||||
}
|
||||
if self.raw == null || self.data == null { ret false; }
|
||||
ret (self.data as usize & (self.elem_align - 1)) == 0;
|
||||
ret (self.data as usize & (a - 1)) == 0;
|
||||
}
|
||||
|
||||
fn status_error(kind: Kind): Status {
|
||||
@@ -108,9 +111,8 @@ fn allocate(capacity: usize, elem_size: usize, elem_align: usize): VecResult {
|
||||
});
|
||||
}
|
||||
|
||||
// 保证至少可容纳 need 个元素。所有检查在原对象改变前完成。
|
||||
fn reserve(self: *Vec, need: usize): Status {
|
||||
if !valid(self.*) { ret status_error(.InvalidArgument); }
|
||||
// 与 reserve 相同,但假定调用方已校验 self(内部热路径用,省去重复 valid)。
|
||||
fn reserve_raw(self: *Vec, need: usize): Status {
|
||||
if need <= self.cap { ret .Ok; }
|
||||
|
||||
var new_cap = grow_capacity(self.cap, 8, need);
|
||||
@@ -140,14 +142,25 @@ fn reserve(self: *Vec, need: usize): Status {
|
||||
ret .Ok;
|
||||
}
|
||||
|
||||
// 保证至少可容纳 need 个元素(外部入口,含校验)。
|
||||
fn reserve(self: *Vec, need: usize): Status {
|
||||
if !valid(self) { ret status_error(.InvalidArgument); }
|
||||
ret reserve_raw(self, need);
|
||||
}
|
||||
|
||||
// 预分配恰好 capacity 个元素(等价“with_capacity”)。
|
||||
fn with_capacity(elem_size: usize, elem_align: usize, capacity: usize): VecResult {
|
||||
ret allocate(capacity, elem_size, elem_align);
|
||||
}
|
||||
|
||||
fn get(self: *Vec, index: usize): PtrResult {
|
||||
if !valid(self.*) { ret .Err(Error.make(.InvalidArgument)); }
|
||||
if !valid(self) { ret .Err(Error.make(.InvalidArgument)); }
|
||||
if index >= self.len { ret .Err(Error.make(.OutOfRange)); }
|
||||
ret .Ok(self.data + index * self.elem_size);
|
||||
}
|
||||
|
||||
fn set(self: *Vec, index: usize, elem: *u8): Status {
|
||||
if !valid(self.*) || elem == null { ret status_error(.InvalidArgument); }
|
||||
if !valid(self) || elem == null { ret status_error(.InvalidArgument); }
|
||||
if index >= self.len { ret status_error(.OutOfRange); }
|
||||
var dst = self.data + index * self.elem_size;
|
||||
ret move(dst[0..self.elem_size], elem[0..self.elem_size]);
|
||||
@@ -155,7 +168,7 @@ fn set(self: *Vec, index: usize, elem: *u8): Status {
|
||||
|
||||
// 追加 count 个连续元素。elems 可以指向 self 当前已初始化的元素区。
|
||||
fn append(self: *Vec, elems: *u8, count: usize): Status {
|
||||
if !valid(self.*) { ret status_error(.InvalidArgument); }
|
||||
if !valid(self) { ret status_error(.InvalidArgument); }
|
||||
if count == 0 { ret .Ok; }
|
||||
if elems == null { ret status_error(.InvalidArgument); }
|
||||
|
||||
@@ -190,7 +203,7 @@ fn append(self: *Vec, elems: *u8, count: usize): Status {
|
||||
}
|
||||
}
|
||||
|
||||
match reserve(self, new_len) {
|
||||
match reserve_raw(self, new_len) {
|
||||
.Ok => {},
|
||||
.Err(error) => { ret .Err(error); },
|
||||
}
|
||||
@@ -209,9 +222,23 @@ fn push(self: *Vec, elem: *u8): Status {
|
||||
ret append(self, elem, 1);
|
||||
}
|
||||
|
||||
// 热路径:假定 self 有效且已有容量时直接写入;容量不足才回退到 append。
|
||||
fn push_raw(self: *Vec, elem: *u8): bool {
|
||||
if self.len < self.cap {
|
||||
copy(self.data + self.len * self.elem_size, elem, self.elem_size);
|
||||
self.len = self.len + 1;
|
||||
ret true;
|
||||
}
|
||||
match append(self, elem, 1) {
|
||||
.Ok => { ret true; },
|
||||
.Err(error) => { ret false; },
|
||||
}
|
||||
ret false;
|
||||
}
|
||||
|
||||
// 将末元素复制到 out,然后缩短数组。out 可以与元素区重叠。
|
||||
fn pop(self: *Vec, out: *u8): Status {
|
||||
if !valid(self.*) || out == null { ret status_error(.InvalidArgument); }
|
||||
if !valid(self) || out == null { ret status_error(.InvalidArgument); }
|
||||
if self.len == 0 { ret status_error(.OutOfRange); }
|
||||
var source = self.data + (self.len - 1) * self.elem_size;
|
||||
match move(out[0..self.elem_size], source[0..self.elem_size]) {
|
||||
@@ -229,7 +256,7 @@ fn clear(self: *Vec) {
|
||||
// 成功时先释放 out 原有存储再提交副本;失败保持 out 不变。
|
||||
// out 与 src 指向同一个 Vec 也允许。
|
||||
fn clone(out: *Vec, src: Vec): Status {
|
||||
if !valid(out.*) || !valid(src) { ret status_error(.InvalidArgument); }
|
||||
if !valid(out) || !valid(&src) { ret status_error(.InvalidArgument); }
|
||||
if out.elem_size != src.elem_size || out.elem_align != src.elem_align {
|
||||
ret status_error(.InvalidArgument);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user