2个版本

0.1.1 2024年1月21日
0.1.0 2024年1月1日

#2298数据库接口


bitcasky-database 中使用

MIT 许可证

46KB
1K SLoC

Bitcasky

Crates.io MIT licensed codecov Build Status

Bitcasky是Rust实现的Bitcask键值存储。它是一个ACID兼容的、只增的键值存储,提供高写入吞吐量。它针对重写工作负载进行了优化,通常用于日志存储和时间序列数据等应用。

功能

  • 只增存储,保证持久性和一致性
  • 内存映射文件,提高I/O效率
  • 键值存储,读写性能为O(1)
  • 存储可过期值

使用方法

基本使用

要使用Bitcasky,只需将其添加到您的Cargo.toml文件中

[dependencies]
bitcasky = "0.1.2"

然后,在您的Rust代码中,导入bitcasky crate并开始使用键值存储

use bitcasky::Bitcasky;

fn main() {
    let mut db = Bitcasky::open("/path/to/db", BitcaskyOptions::default()).unwrap()

    db.put("key", "value").unwrap();

    assert!(db.has("key").unwrap());

    let value = db.get("key").unwrap().unwrap();

    println!("{:?}", value);
}

存储可过期值

db.put_with_ttl("key", "value", Duration::from_secs(60)).unwrap();

// 60 seconds later
assert!(db.get("key").unwrap().is_none());

删除一些值或整个数据库

db.put("key1", "value1").unwrap();
db.put("key2", "value2").unwrap();

// delete some value
db.delete("key1").unwrap();
assert!(db.get("key1").unwrap().is_none());

// drop database
db.drop().unwrap();
assert!(db.get("key2").unwrap().is_none());

迭代数据库

迭代所有键。

// iterate and print all keys in database
bc.foreach_key(|k| println!("{}", String::from_utf8_lossy(k))).unwrap();

// fold all keys by concatenate them
let ret = bc.fold_key(
        |k, accumulator: Option<String>| match accumulator {
            // concatenate new key to folded key string
            Some(folded_k) => Ok(Some(folded_k + &String::from_utf8_lossy(k))),
            
            // if we have not fold anything, use this new key as folded key
            None => Ok(Some(String::from_utf8_lossy(k).into())),
        },
        // init accumulator
        None,
    )
    .unwrap();
assert!(ret.is_some());
println!("{}", ret.unwrap());

迭代所有键和值。

// iterate and print all keys and values in database
bc.foreach(|k, v| {
    println!(
        "key: {}, value: {}",
        String::from_utf8_lossy(k),
        String::from_utf8_lossy(v)
    )
})
.unwrap();

// fold all keys and values by concatenate them
let ret = bc
    .fold(
        |k, v, accumulator: Option<String>| match accumulator {
            // concatenate new key and value to folded values
            Some(folded_vals) => Ok(Some(format!(
                "{} key: {}, val: {};",
                folded_vals,
                String::from_utf8_lossy(k),
                String::from_utf8_lossy(v)
            ))),

            // if we have not fold anything, use this new key and value as folded values
            None => Ok(Some(format!(
                "key: {}, val: {};",
                String::from_utf8_lossy(k),
                String::from_utf8_lossy(v)
            ))),
        },
        // init accumulator
        None,
    )
    .unwrap();
assert!(ret.is_some());
println!("{}", ret.unwrap());

同步策略

通过选择同步策略,您可以配置写入的持久性,通过指定何时将数据同步到磁盘。

以下同步策略可用

  • None — 让操作系统管理写入同步
  • OSync — 使用O_SYNC标志,强制在每个写入时进行同步
  • 时间间隔 — 在指定间隔同步(默认:60秒)

例如,创建一个每35秒同步的Bitcasky数据库如下

let db = Bitcasky::open(
        "/path/to/db", 
        BitcaskyOptions::default().sync_strategy(SyncStrategy::Interval(Duration::from_secs(35)))
    ).unwrap();

合并过程

Bitcasky需要定期调用合并以减少磁盘使用。合并过程遍历数据文件,通过消除过时和删除的键值对来回收空间,只将当前键值对写入目录中的新文件集。

通过在Bitcasky实例上调用merge来启动合并过程

db.merge().unwrap();

许可证

本项目采用MIT许可证

依赖项

~3–12MB
~145K SLoC