diff options
| author | metamuffin <metamuffin@disroot.org> | 2026-02-05 20:31:55 +0100 |
|---|---|---|
| committer | metamuffin <metamuffin@disroot.org> | 2026-02-05 20:31:55 +0100 |
| commit | 65ca3f3450d0067668111f6e13cc3089768c9efe (patch) | |
| tree | 89dceed4f711d25ff2763e18a4be7e1a59e79507 /kv | |
| parent | 1af0468788c0a592a76398206e6c7479384853ec (diff) | |
| download | jellything-65ca3f3450d0067668111f6e13cc3089768c9efe.tar jellything-65ca3f3450d0067668111f6e13cc3089768c9efe.tar.bz2 jellything-65ca3f3450d0067668111f6e13cc3089768c9efe.tar.zst | |
remove read/write distinction for kv transactions; traitify database
Diffstat (limited to 'kv')
| -rw-r--r-- | kv/src/lib.rs | 16 | ||||
| -rw-r--r-- | kv/src/memory.rs | 37 | ||||
| -rw-r--r-- | kv/src/redb.rs | 46 | ||||
| -rw-r--r-- | kv/src/rocksdb.rs | 30 |
4 files changed, 19 insertions, 110 deletions
diff --git a/kv/src/lib.rs b/kv/src/lib.rs index 939391c..83f2635 100644 --- a/kv/src/lib.rs +++ b/kv/src/lib.rs @@ -18,22 +18,12 @@ pub use anyhow; use anyhow::Result; -pub type WriteTxnFunction = dyn FnMut(&mut dyn WriteTransaction) -> Result<()>; -pub type ReadTxnFunction = dyn FnMut(&dyn ReadTransaction) -> Result<()>; - -pub trait Database: Send + Sync + 'static { - fn write_transaction( - &self, - f: &mut dyn FnMut(&mut dyn WriteTransaction) -> Result<()>, - ) -> Result<()>; - fn read_transaction(&self, f: &mut dyn FnMut(&dyn ReadTransaction) -> Result<()>) - -> Result<()>; +pub trait Store: Send + Sync + 'static { + fn transaction(&self, f: &mut dyn FnMut(&mut dyn Transaction) -> Result<()>) -> Result<()>; } -pub trait WriteTransaction: ReadTransaction { +pub trait Transaction { fn set(&mut self, key: &[u8], value: &[u8]) -> Result<()>; fn del(&mut self, key: &[u8]) -> Result<()>; -} -pub trait ReadTransaction { fn get(&self, key: &[u8]) -> Result<Option<Vec<u8>>>; fn iter<'a>( &'a self, diff --git a/kv/src/memory.rs b/kv/src/memory.rs index ad13350..1e8d1c3 100644 --- a/kv/src/memory.rs +++ b/kv/src/memory.rs @@ -4,11 +4,11 @@ Copyright (C) 2026 metamuffin <metamuffin.org> */ -use crate::{Database, ReadTransaction, WriteTransaction}; +use crate::{Store, Transaction}; use anyhow::Result; use std::{ collections::BTreeMap, - sync::{RwLock, RwLockReadGuard, RwLockWriteGuard}, + sync::{RwLock, RwLockWriteGuard}, }; type MemdbInner = BTreeMap<Vec<u8>, Vec<u8>>; @@ -18,21 +18,12 @@ pub fn new() -> Memory { Default::default() } -impl Database for Memory { - fn write_transaction( - &self, - f: &mut dyn FnMut(&mut dyn WriteTransaction) -> Result<()>, - ) -> Result<()> { +impl Store for Memory { + fn transaction(&self, f: &mut dyn FnMut(&mut dyn Transaction) -> Result<()>) -> Result<()> { f(&mut self.write().unwrap()) } - fn read_transaction( - &self, - f: &mut dyn FnMut(&dyn ReadTransaction) -> Result<()>, - ) -> Result<()> { - f(&self.read().unwrap()) - } } -impl WriteTransaction for RwLockWriteGuard<'_, MemdbInner> { +impl Transaction for RwLockWriteGuard<'_, MemdbInner> { fn set(&mut self, key: &[u8], value: &[u8]) -> Result<()> { self.insert(key.to_vec(), value.to_vec()); Ok(()) @@ -41,24 +32,6 @@ impl WriteTransaction for RwLockWriteGuard<'_, MemdbInner> { self.remove(key); Ok(()) } -} -impl ReadTransaction for RwLockWriteGuard<'_, MemdbInner> { - fn get(&self, key: &[u8]) -> Result<Option<Vec<u8>>> { - Ok((**self).get(key).cloned()) - } - fn iter<'a>( - &'a self, - key: &[u8], - reverse: bool, - ) -> Result<Box<dyn Iterator<Item = Result<Vec<u8>>> + 'a>> { - Ok(if reverse { - Box::new(self.range(key.to_vec()..).map(|e| Ok(e.0.to_vec()))) - } else { - Box::new(self.range(..=key.to_vec()).rev().map(|e| Ok(e.0.to_vec()))) - }) - } -} -impl ReadTransaction for RwLockReadGuard<'_, MemdbInner> { fn get(&self, key: &[u8]) -> Result<Option<Vec<u8>>> { Ok((**self).get(key).cloned()) } diff --git a/kv/src/redb.rs b/kv/src/redb.rs index e43fdfb..094acb9 100644 --- a/kv/src/redb.rs +++ b/kv/src/redb.rs @@ -4,22 +4,20 @@ Copyright (C) 2026 metamuffin <metamuffin.org> */ -use crate::{Database, ReadTransaction, WriteTransaction}; use anyhow::Result; -use redb::{AccessGuard, ReadableDatabase, ReadableTable, StorageError, Table, TableDefinition}; +use redb::{AccessGuard, ReadableTable, StorageError, Table, TableDefinition}; use std::path::Path; +use crate::{Store, Transaction}; + const TABLE: TableDefinition<&[u8], &[u8]> = TableDefinition::new("kv"); pub fn new(path: &Path) -> Result<redb::Database> { Ok(redb::Database::create(path)?) } -impl Database for redb::Database { - fn write_transaction( - &self, - f: &mut dyn FnMut(&mut dyn WriteTransaction) -> Result<()>, - ) -> Result<()> { +impl Store for redb::Database { + fn transaction(&self, f: &mut dyn FnMut(&mut dyn Transaction) -> Result<()>) -> Result<()> { let txn = self.begin_write()?; let mut table = txn.open_table(TABLE)?; f(&mut table)?; @@ -27,17 +25,9 @@ impl Database for redb::Database { txn.commit()?; Ok(()) } - fn read_transaction( - &self, - f: &mut dyn FnMut(&dyn ReadTransaction) -> Result<()>, - ) -> Result<()> { - let mut txn = self.begin_read()?; - f(&mut txn)?; - Ok(()) - } } -impl WriteTransaction for Table<'_, &[u8], &[u8]> { +impl Transaction for Table<'_, &[u8], &[u8]> { fn set(&mut self, key: &[u8], value: &[u8]) -> Result<()> { self.insert(key, value)?; Ok(()) @@ -46,8 +36,6 @@ impl WriteTransaction for Table<'_, &[u8], &[u8]> { self.remove(key)?; Ok(()) } -} -impl ReadTransaction for Table<'_, &[u8], &[u8]> { fn get<'a>(&'a self, key: &[u8]) -> Result<Option<Vec<u8>>> { match ReadableTable::get(self, key)? { Some(v) => Ok(Some(v.value().to_vec())), @@ -69,25 +57,3 @@ impl ReadTransaction for Table<'_, &[u8], &[u8]> { }) } } -impl ReadTransaction for redb::ReadTransaction { - fn get<'a>(&'a self, key: &[u8]) -> Result<Option<Vec<u8>>> { - match self.open_table(TABLE)?.get(key)? { - Some(v) => Ok(Some(v.value().to_vec())), - None => Ok(None), - } - } - fn iter<'a>( - &'a self, - key: &[u8], - reverse: bool, - ) -> Result<Box<dyn Iterator<Item = Result<Vec<u8>>> + 'a>> { - let k = |e: Result<(AccessGuard<'_, &[u8]>, AccessGuard<'_, &[u8]>), StorageError>| { - e.map(|e| e.0.value().to_vec()).map_err(|e| e.into()) - }; - Ok(if reverse { - Box::new(self.open_table(TABLE)?.range(..=key)?.rev().map(k)) - } else { - Box::new(self.open_table(TABLE)?.range(key..)?.map(k)) - }) - } -} diff --git a/kv/src/rocksdb.rs b/kv/src/rocksdb.rs index 8aa559c..c78dd96 100644 --- a/kv/src/rocksdb.rs +++ b/kv/src/rocksdb.rs @@ -8,17 +8,14 @@ use anyhow::Result; use rocksdb::{Direction, ErrorKind, IteratorMode, OptimisticTransactionDB}; use std::path::Path; -use crate::{BlobStorage, Database, ReadTransaction, WriteTransaction}; +use crate::{BlobStorage, Store, Transaction}; pub fn new(path: &Path) -> Result<OptimisticTransactionDB> { Ok(OptimisticTransactionDB::open_default(path)?) } -impl Database for OptimisticTransactionDB { - fn write_transaction( - &self, - f: &mut dyn FnMut(&mut dyn WriteTransaction) -> Result<()>, - ) -> Result<()> { +impl Store for OptimisticTransactionDB { + fn transaction(&self, f: &mut dyn FnMut(&mut dyn Transaction) -> Result<()>) -> Result<()> { loop { let mut txn = self.transaction(); f(&mut txn)?; @@ -29,33 +26,16 @@ impl Database for OptimisticTransactionDB { } } } - fn read_transaction( - &self, - f: &mut dyn FnMut(&dyn ReadTransaction) -> Result<()>, - ) -> Result<()> { - loop { - let txn = self.transaction(); - f(&txn)?; - match txn.commit() { - Ok(()) => break Ok(()), - Err(e) if e.kind() == ErrorKind::Busy => continue, - Err(e) => return Err(e.into()), - } - } - } } -impl WriteTransaction for rocksdb::Transaction<'_, OptimisticTransactionDB> { - fn set(&mut self, key: &[u8], value: &[u8]) -> Result<()> { +impl Transaction for rocksdb::Transaction<'_, OptimisticTransactionDB> { + fn set(&mut self, key: &[u8], value: &[u8]) -> Result<()> { Ok(self.put(key, value)?) } fn del(&mut self, key: &[u8]) -> Result<()> { Ok(self.delete(key)?) } -} - -impl ReadTransaction for rocksdb::Transaction<'_, OptimisticTransactionDB> { fn get(&self, key: &[u8]) -> Result<Option<Vec<u8>>> { Ok(self.get(key)?) } |