Skip to main content

db_rs/
lookup_list.rs

1use crate::table::Table;
2use crate::{DbResult, Logger, TableId};
3use serde::de::DeserializeOwned;
4use serde::{Deserialize, Serialize};
5use std::collections::HashMap;
6use std::hash::{BuildHasher, Hash, RandomState};
7
8/// A special case of [crate::lookup::LookupTable] where the value of the [HashMap] is a `Vec<V>`.
9#[derive(Debug)]
10#[cfg_attr(feature = "clone", derive(Clone))]
11pub struct LookupList<K, V, S=RandomState>
12where
13    K: Hash + Eq + Serialize,
14    V: Serialize + Eq,
15{
16    table_id: TableId,
17    inner: HashMap<K, Vec<V>, S>,
18    pub logger: Logger,
19}
20
21#[derive(Serialize, Deserialize)]
22pub enum LogEntry<K, V> {
23    Push(K, V),
24    Remove(K, usize),
25    CreateKey(K),
26    ClearKey(K),
27    Clear,
28}
29
30impl<K, V, S> Table for LookupList<K, V, S>
31where
32    K: Hash + Eq + Serialize + DeserializeOwned,
33    V: Serialize + DeserializeOwned + Eq + Hash,
34    S: Default + BuildHasher
35{
36    fn init(table_id: TableId, logger: Logger) -> Self {
37        let inner = HashMap::with_hasher(S::default());
38        Self { table_id, inner, logger }
39    }
40
41    fn handle_event(&mut self, bytes: &[u8]) -> DbResult<()> {
42        match bincode::deserialize::<LogEntry<K, V>>(bytes)? {
43            LogEntry::Push(k, v) => {
44                self.push_inner(k, v);
45            }
46            LogEntry::Remove(k, idx) => {
47                if let Some(vec) = self.inner.get_mut(&k) {
48                    vec.remove(idx);
49                }
50            }
51            LogEntry::CreateKey(k) => {
52                self.inner.insert(k, Vec::new());
53            }
54            LogEntry::ClearKey(k) => {
55                self.inner.remove(&k);
56            }
57            LogEntry::Clear => {
58                self.inner.clear();
59            }
60        };
61
62        Ok(())
63    }
64
65    fn compact_repr(&self) -> DbResult<Vec<u8>> {
66        let mut repr = vec![];
67        for (k, values) in &self.inner {
68            if values.is_empty() {
69                let data = bincode::serialize(&LogEntry::<&K, &V>::CreateKey(k))?;
70                let mut data = Logger::log_entry(self.table_id, data);
71                repr.append(&mut data);
72                continue;
73            }
74            for v in values {
75                let data = bincode::serialize(&LogEntry::Push(k, v))?;
76                let mut data = Logger::log_entry(self.table_id, data);
77                repr.append(&mut data);
78            }
79        }
80
81        Ok(repr)
82    }
83}
84
85impl<K, V, S> LookupList<K, V, S>
86where
87    K: Hash + Eq + Serialize + DeserializeOwned,
88    V: Serialize + DeserializeOwned + Eq + Hash,
89    S: BuildHasher
90{
91    pub(crate) fn push_inner(&mut self, k: K, v: V) {
92        if let Some(vec) = self.inner.get_mut(&k) {
93            vec.push(v);
94        } else {
95            self.inner.insert(k, vec![v]);
96        }
97    }
98    pub fn push(&mut self, k: K, v: V) -> DbResult<()> {
99        let log_entry = LogEntry::Push(&k, &v);
100        let data = bincode::serialize(&log_entry)?;
101        self.push_inner(k, v);
102        self.logger.write(self.table_id, data)?;
103        Ok(())
104    }
105
106    pub fn create_key(&mut self, key: K) -> DbResult<Option<Vec<V>>> {
107        let log_entry = LogEntry::<&K, &V>::CreateKey(&key);
108        let data = bincode::serialize(&log_entry)?;
109
110        let ret = self.inner.insert(key, Vec::new());
111
112        self.logger.write(self.table_id, data)?;
113        Ok(ret)
114    }
115
116    pub fn remove(&mut self, key: &K, idx: usize) -> DbResult<bool> {
117        if let Some(vec) = self.inner.get_mut(key) {
118            let log_entry = LogEntry::Remove::<&K, &V>(key, idx);
119            let data = bincode::serialize(&log_entry)?;
120            self.logger.write(self.table_id, data)?;
121            vec.remove(idx);
122            Ok(true)
123        } else {
124            Ok(false)
125        }
126    }
127
128    pub fn get(&self) -> &HashMap<K, Vec<V>, S> {
129        &self.inner
130    }
131
132    pub fn clear(&mut self) -> DbResult<()> {
133        self.inner.clear();
134        let log_entry = LogEntry::<K, V>::Clear;
135        let data = bincode::serialize(&log_entry)?;
136        self.logger.write(self.table_id, data)?;
137
138        Ok(())
139    }
140
141    pub fn clear_key(&mut self, key: &K) -> DbResult<Option<Vec<V>>> {
142        let log_entry = LogEntry::<&K, &V>::ClearKey(key);
143        let data = bincode::serialize(&log_entry)?;
144        let ret = self.inner.remove(key);
145        self.logger.write(self.table_id, data)?;
146
147        Ok(ret)
148    }
149}