/* 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::{Db, ReadTransaction, ReadTxnFunction, WriteTransaction, WriteTxnFunction}; use anyhow::Result; use std::{ collections::BTreeMap, sync::{RwLock, RwLockReadGuard, RwLockWriteGuard}, }; type Inner = BTreeMap, Vec>; pub struct Memory(RwLock, Vec>>); impl Memory { pub fn new() -> Self { Self(RwLock::new(BTreeMap::new())) } } impl Db for Memory { fn write_transaction(&self, f: &mut WriteTxnFunction) -> Result<()> { f(&mut self.0.write().unwrap()) } fn read_transaction(&self, f: &mut ReadTxnFunction) -> Result<()> { f(&self.0.read().unwrap()) } } impl WriteTransaction for RwLockWriteGuard<'_, Inner> { 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<'_, Inner> { 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<'_, Inner> { 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()))) }) } }