feat: add sled

This commit is contained in:
nathan 2023-03-15 21:08:52 +08:00
parent 6110c69374
commit 2b3650eb63
5 changed files with 142 additions and 14 deletions

65
Cargo.lock generated
View File

@ -877,6 +877,19 @@ dependencies = [
"crossbeam-utils",
]
[[package]]
name = "crossbeam-epoch"
version = "0.9.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46bd5f3f85273295a9d14aedfb86f6aadbff6d8f5295c4a9edb08e819dcf5695"
dependencies = [
"autocfg",
"cfg-if",
"crossbeam-utils",
"memoffset",
"scopeguard",
]
[[package]]
name = "crossbeam-queue"
version = "0.3.8"
@ -1158,6 +1171,16 @@ dependencies = [
"percent-encoding",
]
[[package]]
name = "fs2"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213"
dependencies = [
"libc",
"winapi",
]
[[package]]
name = "futures"
version = "0.3.26"
@ -1258,6 +1281,15 @@ dependencies = [
"slab",
]
[[package]]
name = "fxhash"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c"
dependencies = [
"byteorder",
]
[[package]]
name = "generic-array"
version = "0.14.6"
@ -1692,6 +1724,15 @@ version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
[[package]]
name = "memoffset"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1"
dependencies = [
"autocfg",
]
[[package]]
name = "mime"
version = "0.3.16"
@ -2204,6 +2245,14 @@ dependencies = [
"winreg",
]
[[package]]
name = "revdb"
version = "0.1.0"
dependencies = [
"sled",
"thiserror",
]
[[package]]
name = "ring"
version = "0.16.20"
@ -2451,6 +2500,22 @@ dependencies = [
"autocfg",
]
[[package]]
name = "sled"
version = "0.34.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f96b4737c2ce5987354855aed3797279def4ebf734436c6aa4552cf8e169935"
dependencies = [
"crc32fast",
"crossbeam-epoch",
"crossbeam-utils",
"fs2",
"fxhash",
"libc",
"log",
"parking_lot 0.11.2",
]
[[package]]
name = "smallvec"
version = "1.10.0"

View File

@ -6,3 +6,5 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
sled = "0.34.7"
thiserror = "1.0.30"

65
crates/revdb/src/db.rs Normal file
View File

@ -0,0 +1,65 @@
use crate::error::RevDBError;
use sled::Db;
use std::path::Path;
pub struct RevDB {
pub(crate) db: Db,
}
impl RevDB {
pub fn open(path: impl AsRef<Path>) -> Result<Self, RevDBError> {
let db = sled::open(path)?;
Ok(Self { db })
}
pub fn insert(&self, uid: i64, rev_id: i64, data: &[u8]) -> Result<(), RevDBError> {
let key = make_seq_key(uid, rev_id);
let _ = self.db.insert(key, data)?;
Ok(())
}
pub fn get(&self, uid: i64, rev_id: i64) -> Result<Option<Vec<u8>>, RevDBError> {
let key = make_seq_key(uid, rev_id);
let value = self.db.get(key)?;
Ok(value.map(|value| value.to_vec()))
}
}
// Optimize your data layout: Sled's B-Tree implementation works best when the keys are sequential,
// so try to organize the data in a way that maximizes sequential access.
fn make_seq_key(uid: i64, rev_id: i64) -> [u8; 16] {
let mut key = [0; 16];
key[0..8].copy_from_slice(&uid.to_be_bytes());
key[8..16].copy_from_slice(&rev_id.to_be_bytes());
key
}
#[cfg(test)]
mod tests {
use crate::db::RevDB;
use std::path::Path;
use std::time::Instant;
#[test]
fn insert_speed() {
let path = Path::new(".");
let db = RevDB::open(path).unwrap();
let start_time = Instant::now();
for i in 0..=100000 {
db.insert(1, i, b"hello world").unwrap();
}
for i in 0..=100000 {
db.get(1, i).unwrap();
}
let end_time = Instant::now();
let elapsed_time = end_time - start_time;
// Print the elapsed time in seconds and milliseconds
println!(
"Elapsed time: {}s, {}ms",
elapsed_time.as_secs(),
elapsed_time.subsec_millis()
);
}
}

View File

@ -0,0 +1,8 @@
#[derive(Debug, thiserror::Error)]
pub enum RevDBError {
#[error(transparent)]
Db(#[from] sled::Error),
#[error("invalid data")]
InvalidData,
}

View File

@ -1,14 +1,2 @@
pub fn add(left: usize, right: usize) -> usize {
left + right
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_works() {
let result = add(2, 2);
assert_eq!(result, 4);
}
}
mod db;
pub mod error;