ax-linked-list-r4l
路径:
components/linked_list_r4l类型:库 crate 分层:组件层 / intrusive 链表基础件 版本:0.3.0文档依据:Cargo.toml、README.md、src/lib.rs、src/raw_list.rs、src/linked_list.rs、tests/cursor.rs
ax-linked-list-r4l 提供一套来自 Rust-for-Linux 思路的 intrusive 双向链表实现,重点能力是“任意节点 O(1) 删除”。它属于容器叶子基础件:不是调度器、不是任务队列框架,也不是通用对象生命周期系统。
架构设计
设计定位
普通 LinkedList 很难在持有节点句柄时做到 O(1) 任意删除,而内核调度队列、等待队列常常需要“节点自己带着链表指针”。ax-linked-list-r4l 就是为这种场景准备的:
- 节点把
Links<Self>内嵌到对象里。 - 链表只串接这些 links,不额外分配节点壳。
- 节点一旦在链上,就能在 O(1) 时间被删除。
在当前仓库里,axsched 的 FIFO 和 RR 调度器直接用它维护 ready queue,这正是 intrusive 链表 最典型的用法。
1.2 模块分层
raw_list:底层 intrusive 链表,直接操作裸指针和Links<T>。linked_list:在RawList之上增加Box/Arc/&T等包装器语义。def_node!:帮助用户快速定义内嵌Links的节点类型。
1.3 核心对象
Links<T>:嵌入到元素内部,保存前驱/后继和inserted状态。GetLinks:告诉链表如何从元素上拿到对应的Links。RawList<G>:最底层的 intrusive 循环双向链表。Wrapper<T>:把Box<T>、Arc<T>、&T统一成可入链对象。List<G>:对外更友好的拥有型封装。
1.4 关键机制
1.4.1 单元素单链表约束
Links<T> 里的 AtomicBool inserted 用来防止同一组 links 被重复插入。也就是说:
- 一个元素如果只提供一组
Links,同一时刻只能在一条链上。 - 如果想同时加入多条链,元素必须自己定义多组 links,并分别通过不同
GetLinks暴露。
1.4.2 intrusive + 包装器双层设计
RawList 只关心裸指针是否有效;List 再通过 Wrapper trait 把所有权拿回来。因此:
RawList更底层,适合需要自己管理对象生命周期的场景。List更适合直接存Box<Node>、Arc<Node>等对象。
1.4.3 Cursor 访问模型
List 和 RawList 都提供 cursor。可变 cursor 在 Arc 场景下被标成 unsafe,因为如果强引用数不为 1,就无法保证独占可变访问。这一点直接体现了该 crate 的设计原则:它只负责链表结构,不替用户掩盖别名与所有权风险。
核心功能
功能概览
- intrusive 双向链表插入、删除、前后遍历。
- O(1) 任意节点删除。
Box/Arc/&T等包装对象入链。- 游标式遍历、插入和删除。
def_node!快速定义节点类型。
使用场景
List::push_back()/push_front():ax_sched::fifo与ax_sched::round_robin用来维护就绪队列。List::pop_front():调度器取下一个 runnable 实体时使用。List::remove()/CursorMut::remove_current():适合等待队列或 ready queue 的 O(1) 删除场景。def_node!:为简单节点类型提供低样板定义方式。
边界说明
ax-linked-list-r4l只提供容器语义,不提供调度、公平性或优先级逻辑。- 它也不是通用“安全集合”;
RawList暴露了大量unsafe,使用者必须自己保证节点生命周期。 - 若元素需要同时挂多条链,必须由调用方自己建多组
Links,这不是链表内部自动完成的事。