1个不稳定版本
0.1.0 | 2020年12月14日 |
---|
#620 in 内存管理
520KB
9K SLoC
刚玉:Rust中的持久内存编程库
crndm
为Rust应用程序提供持久内存支持。这对于开发无需过多关注崩溃一致性和数据丢失的可靠持久内存应用程序很有用。
通过仔细使用Rust的严格类型检查规则和借用机制,crndm
确保实现中不存在常见的持久内存相关错误。crndm
使软件实现避免了以下类型的零持久内存相关问题
- 指向易失性堆的持久指针,
- 跨池指针,
- 对数据的不可恢复修改,
- 因电源故障导致的数据不一致,
- 以及 Rust处理的全部内存相关问题。
开发者将在设计时看到这些问题。因此,这降低了犯错误的风险。crndm
的编程模型由使用安全的持久指针和软件事务内存组成。
crndm
接口的核心是三个指针包装器。开发者可以使用它们安全地分配持久内存。
依赖项
crndm
依赖于Rust的一些不稳定特性。因此,它需要一个nightly Rust编译器 1.50.0-nightly。请运行以下命令以下载最新的Rust版本(有关详细信息,请参阅https://www.rust-lang.net.cn/tools/install)。
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
rustup default nightly
氧化铝也部分依赖于一些第三方crate,这些crate列在Cargo.toml
中。
使用方法
使用以下任一指令将crndm
添加到您的Cargo.toml
依赖项部分
[dependencies]
crndm = { git = "https://github.com/NVSL/Corundum.git" }
或者(将在crates.io
上提供,很快)
[dependencies]
crndm = "0.1.0"
内存池
内存池是一种实现了与持久内存工作所需的所有接口的类型。您可以使用默认的内存池,或者定义一个新的内存池类型。后者需要您的类型实现MemPool
特质。请参考中继分配器作为示例。要自动实现新的池类型,提供了一个创建具有BuddyAlloc
类型的模块的pool!()
宏。
crndm::pool!(my_pool);
打开内存池文件
在使用之前,首先要打开内存池文件。您可以通过使用open()
或open_no_root()
方法来完成此操作。第一个方法返回给定根对象类型的根对象。第二个方法返回一个guard
对象;只要root
/guard
对象在作用域内,池就保持打开状态。打开函数接受池文件路径和创建池文件的标志。
if let Ok(_) = my_mod::BuddyAlloc::open_no_root("image", O_F) {
println!("Image file is formatted and ready to use");
} else {
println!("No image file found");
}
if let Ok(root) = my_mod::BuddyAlloc::open::<Root>("image", O_F) {
println!("Image file is formatted and the root object is created ({:?})", root);
} else {
println!("No image file");
}
PM安全数据结构
您可以使用给定的指针定义任何数据结构,而不需要任何原始指针或引用。氧化铝可以帮助您编写正确的代码。
use crndm::rc::Prc;
use crndm::cell::LogCell;
type A = BuddyAlloc;
struct MyData {
id: i32,
link: Option<Prc<LogRefCell<MyData, A>, A>>
}
您可能会发现,在每种类型中指定池会令人烦恼。氧化铝使用类型别名和过程宏提供了一种更简单的方式来定义新的数据结构。pool!()
宏将所有与内部池类型关联的持久类型别名。例如
pool!(my_pool);
use my_pool::*;
struct MyData {
id: i32,
link: Option<Prc<PRefCell<MyData>>>
}
PClone
和Root
过程宏也可以用来自动推导类型的相应特质的实现。
use crndm::default::*;
#[derive(PClone, Root)]
struct MyData {
id: i32,
link: Option<Prc<PRefCell<MyData>>>
}
事务性内存
crndm
不允许在事务之外对受保护的数据进行任何修改。要允许可变借用受保护的数据,您可以将它包裹在LogCell
、Mutex
等中,并使用它们的相应接口进行内部可变性,这需要引用一个日志对象。要获取日志,您可以使用transaction
。
transaction(|j| {
let my_data = Prc::new(LogRefCell::new(
MyData {
id: 1,
link: None
}), j);
let mut my_data = my_data.borrow_mut(j);
my_data.id = 2;
})
文档
请访问Documentation
页面获取更多信息。
问题和贡献
请随时通过GitHub问题报告任何错误。
如果您有其他问题或建议,您可以联系[email protected]。
许可证
'crndm' crate是在Apache License, Version 2.0(http://www.apache.org/licenses/LICENSE-2.0)下许可的。
除非您明确表示,否则您有意提交的任何贡献,包括您提交给许可人的工作,都应遵守本许可的条款和条件,而无需任何额外的条款或条件。
依赖项
~4.5–6MB
~117K SLoC