diff options
| author | metamuffin <metamuffin@disroot.org> | 2026-01-24 04:31:48 +0100 |
|---|---|---|
| committer | metamuffin <metamuffin@disroot.org> | 2026-01-24 04:31:48 +0100 |
| commit | b2e88a8beabf04adc28947cf82996e8692a68b71 (patch) | |
| tree | 23d66c8672b69cce7835ffabae4092669062ada8 /database | |
| parent | 774f64c0789529884dd7a5232f190e347ad29532 (diff) | |
| download | jellything-b2e88a8beabf04adc28947cf82996e8692a68b71.tar jellything-b2e88a8beabf04adc28947cf82996e8692a68b71.tar.bz2 jellything-b2e88a8beabf04adc28947cf82996e8692a68b71.tar.zst | |
move things around; kv crate
Diffstat (limited to 'database')
| -rw-r--r-- | database/Cargo.toml | 3 | ||||
| -rw-r--r-- | database/src/backends/memory.rs | 76 | ||||
| -rw-r--r-- | database/src/backends/mod.rs | 49 | ||||
| -rw-r--r-- | database/src/backends/redb.rs | 93 | ||||
| -rw-r--r-- | database/src/backends/rocksdb.rs | 78 | ||||
| -rw-r--r-- | database/src/lib.rs | 9 | ||||
| -rw-r--r-- | database/src/sort/mod.rs | 3 | ||||
| -rw-r--r-- | database/src/sort/none.rs | 2 | ||||
| -rw-r--r-- | database/src/sort/value.rs | 2 | ||||
| -rw-r--r-- | database/src/table.rs | 13 |
10 files changed, 15 insertions, 313 deletions
diff --git a/database/Cargo.toml b/database/Cargo.toml index d15cee6..078694e 100644 --- a/database/Cargo.toml +++ b/database/Cargo.toml @@ -8,7 +8,6 @@ jellyobject = { path = "../common/object" } serde = { version = "1.0.228", features = ["derive"] } log = { workspace = true } serde_json = "1.0.145" -redb = "3.1.0" anyhow = "1.0.100" -rocksdb = { version = "0.24.0", features = ["multi-threaded-cf"] } bytemuck = { version = "1.24.0", features = ["derive"] } +jellykv = { path = "../kv" } diff --git a/database/src/backends/memory.rs b/database/src/backends/memory.rs deleted file mode 100644 index e010a84..0000000 --- a/database/src/backends/memory.rs +++ /dev/null @@ -1,76 +0,0 @@ -/* - This file is part of jellything (https://codeberg.org/metamuffin/jellything) - which is licensed under the GNU Affero General Public License (version 3); see /COPYING. - Copyright (C) 2026 metamuffin <metamuffin.org> -*/ - -use crate::backends::{Database, ReadTransaction, WriteTransaction}; -use anyhow::Result; -use std::{ - collections::BTreeMap, - sync::{RwLock, RwLockReadGuard, RwLockWriteGuard}, -}; - -type MemdbInner = BTreeMap<Vec<u8>, Vec<u8>>; -type Memdb = RwLock<MemdbInner>; - -pub fn new() -> Memdb { - Memdb::default() -} - -impl Database for Memdb { - fn write_transaction( - &self, - f: &mut dyn FnMut(&mut dyn WriteTransaction) -> 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> { - fn set(&mut self, key: &[u8], value: &[u8]) -> Result<()> { - (**self).insert(key.to_vec(), value.to_vec()); - Ok(()) - } - fn del(&mut self, key: &[u8]) -> Result<()> { - (**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()) - } - 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()))) - }) - } -} diff --git a/database/src/backends/mod.rs b/database/src/backends/mod.rs deleted file mode 100644 index 1a3998f..0000000 --- a/database/src/backends/mod.rs +++ /dev/null @@ -1,49 +0,0 @@ -/* - This file is part of jellything (https://codeberg.org/metamuffin/jellything) - which is licensed under the GNU Affero General Public License (version 3); see /COPYING. - Copyright (C) 2026 metamuffin <metamuffin.org> -*/ - -mod memory; -mod redb; -mod rocksdb; - -use anyhow::{Result, bail}; -use std::{path::Path, sync::Arc}; - -pub use memory::new as new_memory; -pub use redb::new as new_redb; -pub use rocksdb::new as new_rocksdb; - -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 WriteTransaction: ReadTransaction { - 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, - key: &[u8], - reverse: bool, - ) -> Result<Box<dyn Iterator<Item = Result<Vec<u8>>> + 'a>>; -} - -pub fn create_database(driver: &str, path: &Path) -> Result<Arc<dyn Database>> { - Ok(match driver { - "rocksdb" => Arc::new(rocksdb::new(path)?), - "redb" => Arc::new(redb::new(path)?), - "memory" => Arc::new(memory::new()), - _ => bail!("unknown db driver"), - }) -} diff --git a/database/src/backends/redb.rs b/database/src/backends/redb.rs deleted file mode 100644 index c0887c8..0000000 --- a/database/src/backends/redb.rs +++ /dev/null @@ -1,93 +0,0 @@ -/* - This file is part of jellything (https://codeberg.org/metamuffin/jellything) - which is licensed under the GNU Affero General Public License (version 3); see /COPYING. - Copyright (C) 2026 metamuffin <metamuffin.org> -*/ - -use crate::backends::{Database, ReadTransaction, WriteTransaction}; -use anyhow::Result; -use redb::{AccessGuard, ReadableDatabase, ReadableTable, StorageError, Table, TableDefinition}; -use std::path::Path; - -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<()> { - let txn = self.begin_write()?; - let mut table = txn.open_table(TABLE)?; - f(&mut table)?; - drop(table); - 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]> { - fn set(&mut self, key: &[u8], value: &[u8]) -> Result<()> { - self.insert(key, value)?; - Ok(()) - } - fn del(&mut self, key: &[u8]) -> Result<()> { - self.remove(key)?; - Ok(()) - } -} -impl ReadTransaction for Table<'_, &[u8], &[u8]> { - fn get<'a>(&'a self, key: &[u8]) -> Result<Option<Vec<u8>>> { - match <Self as ReadableTable<_, _>>::get(self, 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.range(..=key)?.rev().map(k)) - } else { - Box::new(self.range(key..)?.map(k)) - }) - } -} -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/database/src/backends/rocksdb.rs b/database/src/backends/rocksdb.rs deleted file mode 100644 index 056af9e..0000000 --- a/database/src/backends/rocksdb.rs +++ /dev/null @@ -1,78 +0,0 @@ -/* - This file is part of jellything (https://codeberg.org/metamuffin/jellything) - which is licensed under the GNU Affero General Public License (version 3); see /COPYING. - Copyright (C) 2026 metamuffin <metamuffin.org> -*/ - -use crate::backends::{Database, ReadTransaction, WriteTransaction}; -use anyhow::Result; -use rocksdb::{Direction, ErrorKind, IteratorMode, OptimisticTransactionDB}; -use std::path::Path; - -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<()> { - loop { - let mut txn = self.transaction(); - f(&mut txn)?; - match txn.commit() { - Ok(()) => break Ok(()), - Err(e) if e.kind() == ErrorKind::Busy => continue, - Err(e) => return Err(e.into()), - } - } - } - 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<()> { - 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)?) - } - - fn iter<'a>( - &'a self, - key: &[u8], - reverse: bool, - ) -> Result<Box<dyn Iterator<Item = Result<Vec<u8>>> + 'a>> { - let mut iter = self.iterator(IteratorMode::Start); - iter.set_mode(IteratorMode::From( - key, - if reverse { - Direction::Reverse - } else { - Direction::Forward - }, - )); - Ok(Box::new(iter.map(|e| { - e.map(|(k, _)| k.into_vec()).map_err(|e| e.into()) - }))) - } -} diff --git a/database/src/lib.rs b/database/src/lib.rs index cd9777d..d5d6d21 100644 --- a/database/src/lib.rs +++ b/database/src/lib.rs @@ -3,13 +3,14 @@ which is licensed under the GNU Affero General Public License (version 3); see /COPYING. Copyright (C) 2026 metamuffin <metamuffin.org> */ -pub mod backends; -pub mod sort; +pub mod filter; pub mod prefix_iterator; -pub mod table; pub mod query; -pub mod filter; +pub mod sort; +pub mod table; #[cfg(test)] pub mod test_shared; pub type Pad32 = u32; + +pub use jellykv as kv; diff --git a/database/src/sort/mod.rs b/database/src/sort/mod.rs index b058766..e87630c 100644 --- a/database/src/sort/mod.rs +++ b/database/src/sort/mod.rs @@ -4,8 +4,9 @@ Copyright (C) 2026 metamuffin <metamuffin.org> */ -use crate::{backends::WriteTransaction, table::RowNum}; +use crate::table::RowNum; use anyhow::Result; +use jellykv::WriteTransaction; use jellyobject::Object; pub mod none; diff --git a/database/src/sort/none.rs b/database/src/sort/none.rs index 9285998..65454a2 100644 --- a/database/src/sort/none.rs +++ b/database/src/sort/none.rs @@ -5,12 +5,12 @@ */ use crate::{ - backends::WriteTransaction, filter::binning::Binning, sort::Index, table::{RowNum, TableNum}, }; use anyhow::Result; +use jellykv::WriteTransaction; use jellyobject::Object; pub struct UnsortedIndex { diff --git a/database/src/sort/value.rs b/database/src/sort/value.rs index 6eb638c..bd79db9 100644 --- a/database/src/sort/value.rs +++ b/database/src/sort/value.rs @@ -5,13 +5,13 @@ */ use crate::{ - backends::WriteTransaction, filter::binning::Binning, query::{MultiBehaviour, ValueSortComponent}, sort::Index, table::{RowNum, TableNum}, }; use anyhow::Result; +use jellykv::WriteTransaction; use jellyobject::Object; pub struct ValueIndex { diff --git a/database/src/table.rs b/database/src/table.rs index 4535b4c..c3b4342 100644 --- a/database/src/table.rs +++ b/database/src/table.rs @@ -4,12 +4,9 @@ Copyright (C) 2026 metamuffin <metamuffin.org> */ -use crate::{ - backends::{ReadTransaction, WriteTransaction}, - query::Query, - sort::Index, -}; +use crate::{query::Query, sort::Index}; use anyhow::{Result, anyhow}; +use jellykv::{ReadTransaction, WriteTransaction}; use jellyobject::ObjectBuffer; pub type TableNum = u64; @@ -107,15 +104,15 @@ impl Table { #[cfg(test)] mod test { use crate::{ - backends::{Database, new_memory}, table::Table, test_shared::{NAME, new_bob}, }; use anyhow::Result; + use jellykv::Database; #[test] pub fn insert_get() -> Result<()> { - let db = new_memory(); + let db = jellykv_memory::new(); let table = Table::new(5); let mut bob_row = 0; @@ -136,7 +133,7 @@ mod test { #[test] pub fn update() -> Result<()> { - let db = new_memory(); + let db = jellykv_memory::new(); let table = Table::new(5); let mut bob_row = 0; |