unicstl/doc/notes.md
jf-home 72db0be317 feat(stl): 新增 arraylist 并统一迭代器顺序枚举类型
- 重构迭代器顺序枚举,引入 linear_order_t、tree_order_t 等通用类型,并替换。
- 修复 darray 中二分查找返回索引计算错误的问题
- 优化 segarray 的内存分配错误处理
- 增强 logger 模块,支持时间戳打印及格式化输出
2026-05-17 10:48:19 +08:00

95 lines
3.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# notes
## rawbuf
> 只对malloc封装方便对特定目标进行index访问
- 特点:支持随机访问,不支持扩容
## segarray
`2026-05-16`
### 1. darray + darray
> 放弃darray做map不好管理索引
### 2. ringbuf + darray
> 放弃darray随机访问只能访问有效区域
### 3. ringbuf + rawbuf
> 实现便捷,但扩容时,可能存在空闲内存问题
$$ objs:capacity = mapcap * segcap * objsize $$
$$ memory = mapcap * sizeof(pointer) + objs:capacity $$
最坏情况浪费内存:(mapcap - 1) * segcap * objsize
### 4. ringbuf + rawbuf + ringbuf(use stack: mapfree)
> 完美
**用栈作free比queue有优势因为刚刚使用过的内存缓存命中概率高。**
$$ objs:capacity = mapcap * segcap * objsize $$
$$ memory = 2 * mapcap * sizeof(pointer) + objs:capacity $$
最坏情况浪费内存:(segcap - 1) * objsize
### 5. based on scheme 4, limited to 512 bytes
> obj_size < 512 ? segsize=512 : segsize=1
## ringbuf
对于嵌入式场景下没有malloc也即不扩容的场景需要用到的estack和equeue只选择ringbuf即可。而不使用segarray。
```c
bool ringbuf_init(struct _ringbuf *self, size_t obj_size, size_t capacity, void *mem_base);|
```
### 不扩容场景
ringbuf比segarray更节省内存。ringbuf只多一个obj_size的空间。
$$
membase:size = objsize * (capacity + 1)
$$
而segarray是不确定的所以segarray就得按照可能的最大空间分配。比如方案4的情况下
seghead默认是放中间的方便不需要库容的时候push_back和push_front一开始不用分配内存。
则为了保证push_back和push_front都能够用至少需要三个空间。
$$
mem_base_size = obj_size * (capacity * 3)
$$
当然了若非要将segarray用于嵌入式场景。也可以将seghead初始放在首段开头那么需要的总内存为
$$
mem_base_size = obj_size * (capacity * 2)
$$
**因此若嵌入式不扩容场景下ringbuf更节省内存。**
这可能也是Rust的底层VecDeque选择使用ringbuf的原因。
### 小文件库容
对于小文件ringbuf库容全内存搬移还尚可以接受。
segarray扩容开新segment然后指向新的segment性能也不差。
### 大文件扩容
但对于大文件ringbuf库容全内存搬移代价太大。
而segarray库容不会触发大量数据搬移而是新建一个segment然后指向新的segment。
**因此对于大文件扩容场景下segarray远胜于ringbuf**
## 经典问题
### 2026-05-17
1. 单测多少或者调整顺序都能导致segarray报错经过排查new之后函数结构体成员函数的指针应该是异常了。
push_back没有执行而是莫名其妙跳到了segarray_free。暂未找到原因。只是单测先保留已重构的tree和graph暂时先不测试了。
### 2026-05-15
1. ringbufferresize扩容截断的处理代码简化了。
### 2026-05-14
> 这就是单元测试的魅力
1. darray模块insert传参obj没有判断NULL导致crash
2. darray模块resize没有处理当realloc之后size > capacity 的情况