8 个版本 (2 个稳定版)
使用旧的 Rust 2015
1.0.1 | 2018 年 9 月 28 日 |
---|---|
0.4.2 | 2018 年 9 月 25 日 |
0.3.0 | 2018 年 9 月 6 日 |
0.2.0 | 2018 年 9 月 5 日 |
0.1.0 | 2018 年 8 月 19 日 |
#632 in 内存管理
每月 22 次下载
15KB
338 行
宝库
可克隆和合并的线程本地竞技场分配器。
宝库设计为用于不可变数据结构的灵活分配器和动态借用检查器。
竞技场将每个附加的值存储在固定的内存位置中,并且只一次性释放它们。这是通过使用多个支持向量的数组来实现的,这些向量按长度递增排列,如下所示
克隆和合并
竞技场可以被克隆和合并,这是通过顶层 Arena
类型是映射递增 id 到子竞技场的 VecMap
来实现的。当一个竞技场被克隆时,将创建 两个 新的子竞技场,并赋予它们两个新的 id。
如果通过旧竞技场的引用请求可变借用,无论是从克隆的竞技场中的任何一个,都会克隆并放入新的子竞技场中,这样旧的引用仍然有效。
#[test]
fn clone() {
let arena_a = Arena::new();
let a = arena_a.append(0);
let mut b = arena_a.append(1);
// c is cloned from b, since mutably accesing b makes it point to its
// new memory location.
let c = b.clone();
assert_eq!(*arena_a.get(&a), 0);
assert_eq!(*arena_a.get(&b), 1);
let arena_b = arena_a.clone();
// change the value in arena_a
*arena_a.get_mut(&mut b) += 1;
// value changed
assert_eq!(*arena_a.get(&b), 2);
// old reference `c` is still pointing to the unmodified entry
assert_eq!(*arena_b.get(&c), 1);
}
#[test]
fn merge() {
let arena_a = Arena::new();
let arena_b = Arena::new();
let a = arena_a.append(0);
let b = arena_b.append(1);
// merge the arenas into one, leaving both `a` and `b` accessible
// through `arena_c`
let arena_c = Arena::merge(&arena_a, &arena_b);
assert_eq!(*arena_c.get(&a), 0);
assert_eq!(*arena_c.get(&b), 1);
}
内存布局
每个子竞技场的内存布局排列如下
[0, 1]
[2, 3, 4, 5]
[6, 7, 8, 9, 10, 11, 12, 13]
此实现使用第一行向量的大小为 32,并将加倍向量按 32 行排列。
这确保了不可能重新分配和移动条目,并允许我们从竞技场的不可变借用安全地创建一个 RefMut
。
依赖项
~90KB