Skip to content

Commit

Permalink
Sled and transactions
Browse files Browse the repository at this point in the history
  • Loading branch information
voltrevo committed Oct 26, 2023
1 parent e6b948b commit 8d2f0bd
Show file tree
Hide file tree
Showing 8 changed files with 337 additions and 69 deletions.
101 changes: 93 additions & 8 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions storage/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ serde = { version = "1", features = ["derive"] }
bincode = "1"
num-bigint = "0.4.3"
rand = "0.8.5"
sled = "0.34.7"
18 changes: 6 additions & 12 deletions storage/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
mod memory_storage;
mod memory_backend;
mod storage;

#[cfg(test)]
mod tests {
use crate::{memory_storage::MemoryStorage, storage::Storage};
mod sled_backend;
mod tests;

#[test]
fn number() {
let mut storage = Storage::new(MemoryStorage::new());

let key = storage.write_number(123.456);
assert_eq!(storage.read_number(key), Some(123.456));
}
}
pub use self::storage::{Storage, StorageBackend, StorageKey};
pub use memory_backend::MemoryBackend;
pub use sled_backend::SledBackend;
49 changes: 49 additions & 0 deletions storage/src/memory_backend.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
use std::collections::HashMap;
use std::fmt::Debug as DebugTrait;

use crate::storage::{StorageBackend, StorageBackendHandle, StorageKey};

pub struct MemoryBackend {
data: HashMap<StorageKey, Vec<u8>>,
}

impl MemoryBackend {
pub fn new() -> Self {
Self {
data: HashMap::new(),
}
}
}

impl StorageBackend for MemoryBackend {
type Error<E: DebugTrait> = E;
type InTransactionError<E> = E;
type Handle<'a, E> = MemoryStorageHandle<'a>;

fn transaction<F, T, E: DebugTrait>(&mut self, f: F) -> Result<T, Self::Error<E>>
where
F: Fn(&mut Self::Handle<'_, E>) -> Result<T, Self::InTransactionError<E>>,
{
let mut handle = MemoryStorageHandle { storage: self };
f(&mut handle)
}
}

pub struct MemoryStorageHandle<'a> {
storage: &'a mut MemoryBackend,
}

impl<'a, E> StorageBackendHandle<'a, E> for MemoryStorageHandle<'a> {
fn read(&self, key: StorageKey) -> Result<Option<Vec<u8>>, E> {
Ok(self.storage.data.get(&key).cloned())
}

fn write(&mut self, key: StorageKey, data: Option<Vec<u8>>) -> Result<(), E> {
match data {
Some(data) => self.storage.data.insert(key, data),
None => self.storage.data.remove(&key),
};

Ok(())
}
}
28 changes: 0 additions & 28 deletions storage/src/memory_storage.rs

This file was deleted.

69 changes: 69 additions & 0 deletions storage/src/sled_backend.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
use std::fmt::Debug as DebugTrait;

use crate::storage::{StorageBackend, StorageBackendHandle, StorageKey};

pub struct SledBackend {
db: sled::Db,
}

impl SledBackend {
pub fn open<P>(path: P) -> Result<Self, sled::Error>
where
P: AsRef<std::path::Path>,
{
Ok(Self {
db: sled::open(path)?,
})
}

pub fn open_in_memory() -> Result<Self, sled::Error> {
Ok(Self {
db: sled::Config::new().temporary(true).open()?,
})
}
}

impl StorageBackend for SledBackend {
type Error<E: DebugTrait> = sled::transaction::TransactionError<E>;
type InTransactionError<E> = sled::transaction::ConflictableTransactionError<E>;
type Handle<'a, E> = SledBackendHandle<'a>;

fn transaction<F, T, E: DebugTrait>(&mut self, f: F) -> Result<T, Self::Error<E>>
where
F: Fn(&mut Self::Handle<'_, E>) -> Result<T, Self::InTransactionError<E>>,
{
self.db.transaction(|tx| {
let mut handle = SledBackendHandle { tx };
f(&mut handle)
})
}
}

pub struct SledBackendHandle<'a> {
tx: &'a sled::transaction::TransactionalTree,
}

impl<'a, E> StorageBackendHandle<'a, sled::transaction::ConflictableTransactionError<E>>
for SledBackendHandle<'a>
{
fn read(
&self,
key: StorageKey,
) -> Result<Option<Vec<u8>>, sled::transaction::ConflictableTransactionError<E>> {
let value = self.tx.get(key.to_bytes())?.map(|value| value.to_vec());
Ok(value)
}

fn write(
&mut self,
key: StorageKey,
data: Option<Vec<u8>>,
) -> Result<(), sled::transaction::ConflictableTransactionError<E>> {
match data {
Some(data) => self.tx.insert(key.to_bytes(), data)?,
None => self.tx.remove(key.to_bytes())?,
};

Ok(())
}
}
Loading

0 comments on commit 8d2f0bd

Please sign in to comment.