/* 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, WriteTransaction}; 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 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>> { 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()))) }) } }