use std::collections::HashMap;
use crate::{Database, Change, ColumnId, Transaction, error};
use parking_lot::RwLock;
#[derive(Default)]
pub struct MemDb<H: Clone + Send + Sync + Eq + PartialEq + Default + std::hash::Hash>
(RwLock<(HashMap<ColumnId, HashMap<Vec<u8>, Vec<u8>>>, HashMap<H, Vec<u8>>)>);
impl<H> Database<H> for MemDb<H>
where H: Clone + Send + Sync + Eq + PartialEq + Default + std::hash::Hash
{
fn commit(&self, transaction: Transaction<H>) -> error::Result<()> {
let mut s = self.0.write();
for change in transaction.0.into_iter() {
match change {
Change::Set(col, key, value) => { s.0.entry(col).or_default().insert(key, value); },
Change::Remove(col, key) => { s.0.entry(col).or_default().remove(&key); },
Change::Store(hash, preimage) => { s.1.insert(hash, preimage); },
Change::Release(hash) => { s.1.remove(&hash); },
}
}
Ok(())
}
fn get(&self, col: ColumnId, key: &[u8]) -> Option<Vec<u8>> {
let s = self.0.read();
s.0.get(&col).and_then(|c| c.get(key).cloned())
}
fn lookup(&self, hash: &H) -> Option<Vec<u8>> {
let s = self.0.read();
s.1.get(hash).cloned()
}
}
impl<H> MemDb<H>
where H: Clone + Send + Sync + Eq + PartialEq + Default + std::hash::Hash
{
pub fn new() -> Self {
MemDb::default()
}
pub fn count(&self, col: ColumnId) -> usize {
let s = self.0.read();
s.0.get(&col).map(|c| c.len()).unwrap_or(0)
}
}