aboutsummaryrefslogtreecommitdiff
path: root/database
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2026-01-24 04:31:48 +0100
committermetamuffin <metamuffin@disroot.org>2026-01-24 04:31:48 +0100
commitb2e88a8beabf04adc28947cf82996e8692a68b71 (patch)
tree23d66c8672b69cce7835ffabae4092669062ada8 /database
parent774f64c0789529884dd7a5232f190e347ad29532 (diff)
downloadjellything-b2e88a8beabf04adc28947cf82996e8692a68b71.tar
jellything-b2e88a8beabf04adc28947cf82996e8692a68b71.tar.bz2
jellything-b2e88a8beabf04adc28947cf82996e8692a68b71.tar.zst
move things around; kv crate
Diffstat (limited to 'database')
-rw-r--r--database/Cargo.toml3
-rw-r--r--database/src/backends/memory.rs76
-rw-r--r--database/src/backends/mod.rs49
-rw-r--r--database/src/backends/redb.rs93
-rw-r--r--database/src/backends/rocksdb.rs78
-rw-r--r--database/src/lib.rs9
-rw-r--r--database/src/sort/mod.rs3
-rw-r--r--database/src/sort/none.rs2
-rw-r--r--database/src/sort/value.rs2
-rw-r--r--database/src/table.rs13
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;