4 个版本

0.1.3 2024 年 1 月 27 日
0.1.2 2024 年 1 月 27 日
0.1.1 2022 年 7 月 16 日
0.1.0 2019 年 2 月 15 日

#194数据库接口

Download history 108/week @ 2024-04-07 282/week @ 2024-04-14 254/week @ 2024-04-21 265/week @ 2024-04-28 344/week @ 2024-05-05 217/week @ 2024-05-12 264/week @ 2024-05-19 58/week @ 2024-05-26 32/week @ 2024-06-02 164/week @ 2024-06-09 363/week @ 2024-06-16 450/week @ 2024-06-23 186/week @ 2024-06-30 40/week @ 2024-07-07 6/week @ 2024-07-14 12/week @ 2024-07-21

每月 245 次下载

MIT 许可证

245KB
6K SLoC

Nut

Bolt DB 的 Rust 端口

  • 兼容 Bolt 的数据库格式并提供类似的 API。

    由于 Nut 支持与 Bolt 相同的格式,因此存在已知问题

    • Bolt 使用 Memmap 进行操作,没有 LRU 或其他缓存,因此如果数据库无法放入内存,那么就是游戏结束,Nut 将不可避免地崩溃。
    • 数据结构直接写入磁盘。不进行序列化,因此 Nut 无法理解来自具有不同 Endianness 的计算机的 db 文件,例如。
  • 基于事务的。在出现错误的情况下,事务将被回滚。

  • 多读单写。Nut 与 Bolt 的工作方式相同:您可以同时有一个写入器和多个读取器,只需确保它们在不同的线程上运行即可。在同一个线程中使写入器和读取器进行事务会导致死锁。如果内存映射有足够的空闲页面,写入器可以自由写入,否则它将等待读取事务关闭。

用法

在 crates.io 上提供包:https://crates.io/crates/nut

https://docs.rs/nut/0.1.2/nut/ 上提供文档

通常的做法是在控制台中运行 cargo build --release。文档可通过 cargo doc --no-deps --open 获取。如果您熟悉 Bolt,API 非常相似。

示例

创建 db 并放入一些内容

use nut::DBBuilder;

let mut db = DBBuilder::new("test.db").build().unwrap();
let mut tx = db.begin_rw_tx().unwrap();
{
	let mut flowers = tx.create_bucket(b"flowers").unwrap();
	// returns mutable reference to bucket,
		// which prevents of reborrowing tx

	flowers.put(
		b"iris",
		b"song by American alternative rock band Goo Goo Dolls".to_vec()
	).unwrap();
	flowers.put(
		b"binary data",
		vec![127, 127, 127, 127]
	).unwrap();

	{
		// you can create subbuckets as well
		let mut annuals = flowers
			.create_bucket_if_not_exists(b"annuals").unwrap();

		// api is basically same as for transaction
		annuals.put(
			b"corn",
			b"American nu metal band from Bakersfield".to_vec()
		).unwrap();
		// releasing subbucket
	}

	// releasing bucket to be able use tx again
}
// due to RAII tx will be automatically closed if no error occured,
// or rolled back if there was some.
// Additionally you can commit or rollback manually
tx.rollback().unwrap();

注意:在调用 rollbackcommit 之前,应先丢弃从事务中获得的所有桶。

获取数据

use nut::DBBuilder;

let mut db = DBBuilder::new("test.db").build().unwrap();

// creating read only transaction
// read only ransaction will be automatically rolled back
let mut tx = db.begin_tx().unwrap();

// getting bucket
let flowers = tx.bucket(b"flowers").unwrap();
let data = flowers.get(b"iris").unwrap();
assert_eq!(
	data,
	&b"song by American alternative rock band Goo Goo Dolls"[..]
);

获取可用桶

use nut::DBBuilder;

let mut db = DBBuilder::new("test.db").build().unwrap();
let mut tx = db.begin_tx().unwrap();

{
	// .buckets() available to conveniently retrieve all buckets keys
	let bucket_names = tx.buckets(); // returns Vec<Vec<u8>>

	// bucket key is any binary data, not only string
	assert_eq!(bucket_names, vec!["flowers".as_bytes().to_vec()]);
}

{
	// additionally there is .cursor() method
	// that returns Cursor struct,
	// which is able to iterate through bucket contents
	let cursor = tx.cursor();

	assert_eq!(
		&cursor.first().unwrap().value.unwrap(),
		&"flowers".as_bytes()
	);
}

Nut 二进制文件

该软件包还提供了 nut 二进制文件,有助于以各种方式检查数据库文件。您可以在运行 cargo build --release 后在 ./target/release/nut 找到它。

来自 man 的摘录

USAGE:
    nut [SUBCOMMAND]

FLAGS:
    -h, --help       Prints help information
    -V, --version    Prints version information

SUBCOMMANDS:
    check    Runs an exhaustive check to verify that all pages are accessible or are marked as freed.
    dump     Dumps hex of the page
    help     Prints this message or the help of the given subcommand(s)
    info     Prints database info
    pages    Prints a table of pages with their type (Meta, Leaf, Branch, Freelist)
    tree     Prints buckets tree

免责声明

我不打算积极维护这个项目,因为这个项目只是一个为了探索Rust而进行的兴趣爱好项目,而且在性能方面有更好的替代品。


MIT许可

依赖项

~2–7.5MB
~54K SLoC