feat: add sled
This commit is contained in:
parent
6110c69374
commit
2b3650eb63
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum RevDBError {
|
||||
#[error(transparent)]
|
||||
Db(#[from] sled::Error),
|
||||
|
||||
#[error("invalid data")]
|
||||
InvalidData,
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue