/* 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 */ use crate::backends::{ Database, ReadTransaction, ReadTxnFunction, WriteTransaction, WriteTxnFunction, }; use anyhow::Result; use std::{ collections::BTreeMap, sync::{RwLock, RwLockReadGuard, RwLockWriteGuard}, }; type MemdbInner = BTreeMap, Vec>; type Memdb = RwLock; pub fn new() -> Memdb { Memdb::default() } impl Database for Memdb { fn write_transaction(&self, f: &mut WriteTxnFunction) -> Result<()> { f(&mut self.write().unwrap()) } fn read_transaction(&self, f: &mut ReadTxnFunction) -> 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>> { Ok((**self).get(key).cloned()) } fn iter<'a>( &'a self, key: &[u8], reverse: bool, ) -> Result>> + '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>> { Ok((**self).get(key).cloned()) } fn iter<'a>( &'a self, key: &[u8], reverse: bool, ) -> Result>> + '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()))) }) } }