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