6 个版本 (破坏性)
| 0.5.0 | 2023年12月24日 |
|---|---|
| 0.4.0 | 2023年10月21日 |
| 0.3.0 | 2023年1月2日 |
| 0.2.0 | 2022年4月2日 |
| 0.1.1 | 2021年6月14日 |
120 在 内存管理 中
每月 33 次下载
130KB
1.5K SLoC
CactusRef
单线程、周期感知、引用计数指针。'Rc' 代表 '引用计数'。
如果我们在智能指针中放一个哈希表,会怎么样呢?
CactusRef 是一个单线程、引用计数的智能指针,可以在不使用弱指针的情况下处理循环。从 std 中的 Rc 可能难以使用,因为创建 Rc 的循环会导致内存泄漏。
CactusRef 是 std::rc::Rc 的近似直接替换品,它引入了额外的 API,用于在 Rc 的图中记录所有权关系。
结合 CactusRef 的 采用 API 以跟踪对象图中的链接并驱动垃圾回收,以及 Rust 的 析构粘合剂,实现了一种追踪垃圾收集器。CactusRefs 的图检测到连接的 CactusRefs 图中的局部循环,并且不需要像在追踪垃圾收集器中通常所需的那样扫描整个堆。
CactusRefs 的循环在它们不再从循环外部可达时确定性地收集和释放。
自引用数据结构
CactusRef 可以用于实现自引用数据结构,如双向链表,而不需要使用弱引用。
用法
将以下内容添加到您的 Cargo.toml
[dependencies]
cactusref = "0.5.0"
CactusRef 主要是一个用于替换 std::rc::Rc 的直接替换品,可以像这样使用
use cactusref::Rc;
let node = Rc::new(123_i32);
let another = Rc::clone(&node);
assert_eq!(Rc::strong_count(&another), 2);
let weak = Rc::downgrade(&node);
assert!(weak.upgrade().is_some());
或者开始创建自引用数据结构,如下
use std::cell::RefCell;
use cactusref::{Adopt, Rc};
struct Node {
next: Option<Rc<RefCell<Node>>>,
data: i32,
}
let left = Node { next: None, data: 123 };
let left = Rc::new(RefCell::new(left));
let right = Node { next: Some(Rc::clone(&left)), data: 456 };
let right = Rc::new(RefCell::new(right));
unsafe {
// bookkeep that `right` has added an owning ref to `left`.
Rc::adopt_unchecked(&right, &left);
}
left.borrow_mut().next = Some(Rc::clone(&right));
unsafe {
// bookkeep that `left` has added an owning ref to `right`.
Rc::adopt_unchecked(&left, &right);
}
let mut node = Rc::clone(&left);
// this loop will print:
//
// > traversing ring and found node with data = 123
// > traversing ring and found node with data = 456
// > traversing ring and found node with data = 123
// > traversing ring and found node with data = 456
// > traversing ring and found node with data = 123
for _ in 0..5 {
println!("traversing ring and found node with data = {}", node.borrow().data);
let next = if let Some(ref next) = node.borrow().next {
Rc::clone(next)
} else {
break;
};
node = next;
}
assert_eq!(Rc::strong_count(&node), 3);
drop(node);
drop(left);
drop(right);
// All members of the ring are garbage collected and deallocated.
成熟度
CactusRef 是实验性的。这个包有一些限制
- CactusRef 仅在 nightly 版本中可用。
- 循环检测需要使用 不安全代码。
CactusRef 是 std::rc::Rc 的非平凡扩展,并且尚未证明是安全的。尽管 CactusRef 会尽力检测悬垂的 Rc 并终止程序,但这个包可能是不安全的。
no_std
CactusRef 与 no_std 兼容,默认启用对 std 的可选依赖。CactusRef 依赖于 alloc 包。
包功能
所有功能默认启用。
许可证
CactusRef 使用 MIT 许可证 (c) Ryan Lopopolo。
CactusRef 来自 Rust 标准库中的 Rc,位于 f586d79d,该库使用 MIT 许可证和 Apache 2.0 许可证双重许可。
依赖关系
~725KB
~10K SLoC