Skip to main content

db_rs/
lookup.rs

1use crate::errors::DbResult;
2use crate::logger::Logger;
3use crate::table::Table;
4use crate::TableId;
5use serde::de::DeserializeOwned;
6use serde::{Deserialize, Serialize};
7use std::collections::HashMap;
8use std::hash::{BuildHasher, Hash, RandomState};
9
10/// A table backed by a [HashMap] of type `K`, `V`
11#[derive(Debug)]
12#[cfg_attr(feature = "clone", derive(Clone))]
13pub struct LookupTable<K, V, S=RandomState>
14where
15    K: Hash + Eq + Serialize,
16    V: Serialize,
17    S: BuildHasher + Default
18{
19    table_id: TableId,
20    inner: HashMap<K, V, S>,
21    pub logger: Logger,
22}
23
24#[derive(Serialize, Deserialize)]
25pub enum LogEntry<K, V> {
26    Insert(K, V),
27    Remove(K),
28    Clear,
29}
30
31impl<K, V, S> Table for LookupTable<K, V, S>
32where
33    K: Hash + Eq + Serialize + DeserializeOwned,
34    V: Serialize + DeserializeOwned,
35    S: BuildHasher + Default
36{
37    fn init(table_id: TableId, logger: Logger) -> Self {
38        Self { table_id, inner: HashMap::with_hasher(S::default()), logger }
39    }
40
41    fn handle_event(&mut self, bytes: &[u8]) -> DbResult<()> {
42        match bincode::deserialize(bytes)? {
43            LogEntry::Insert(k, v) => {
44                self.inner.insert(k, v);
45            }
46            LogEntry::Remove(k) => {
47                self.inner.remove(&k);
48            }
49            LogEntry::Clear => {
50                self.inner.clear();
51            }
52        };
53
54        Ok(())
55    }
56
57    fn compact_repr(&self) -> DbResult<Vec<u8>> {
58        let mut repr = vec![];
59        for (k, v) in &self.inner {
60            let data = bincode::serialize(&LogEntry::Insert(k, v))?;
61            let mut data = Logger::log_entry(self.table_id, data);
62            repr.append(&mut data);
63        }
64
65        Ok(repr)
66    }
67}
68
69impl<K, V, S> LookupTable<K, V, S>
70where
71    K: Hash + Eq + Serialize,
72    V: Serialize,
73    S: BuildHasher + Default
74{
75    pub fn insert(&mut self, key: K, value: V) -> DbResult<Option<V>> {
76        let log_entry = LogEntry::Insert(&key, &value);
77        let data = bincode::serialize(&log_entry)?;
78
79        let ret = self.inner.insert(key, value);
80
81        self.logger.write(self.table_id, data)?;
82        Ok(ret)
83    }
84
85    pub fn remove(&mut self, key: &K) -> DbResult<Option<V>> {
86        let log_entry = LogEntry::Remove::<&K, &V>(key);
87        let data = bincode::serialize(&log_entry)?;
88        let ret = self.inner.remove(key);
89        self.logger.write(self.table_id, data)?;
90        Ok(ret)
91    }
92
93    pub fn get(&self) -> &HashMap<K, V, S> {
94        &self.inner
95    }
96
97    pub fn clear(&mut self) -> DbResult<()> {
98        self.inner.clear();
99        let log_entry = LogEntry::<K, V>::Clear;
100        let data = bincode::serialize(&log_entry)?;
101        self.logger.write(self.table_id, data)?;
102
103        Ok(())
104    }
105}