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::Hash;
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>
12where
13    K: Hash + Eq + Serialize,
14    V: Serialize + Eq,
15{
16    table_id: TableId,
17    inner: HashMap<K, Vec<V>>,
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> Table for LookupList<K, V>
31where
32    K: Hash + Eq + Serialize + DeserializeOwned,
33    V: Serialize + DeserializeOwned + Eq + Hash,
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::<LogEntry<K, V>>(bytes)? {
41            LogEntry::Push(k, v) => {
42                self.push_inner(k, v);
43            }
44            LogEntry::Remove(k, idx) => {
45                if let Some(vec) = self.inner.get_mut(&k) {
46                    vec.remove(idx);
47                }
48            }
49            LogEntry::CreateKey(k) => {
50                self.inner.insert(k, Vec::new());
51            }
52            LogEntry::ClearKey(k) => {
53                self.inner.remove(&k);
54            }
55            LogEntry::Clear => {
56                self.inner.clear();
57            }
58        };
59
60        Ok(())
61    }
62
63    fn compact_repr(&self) -> DbResult<Vec<u8>> {
64        let mut repr = vec![];
65        for (k, values) in &self.inner {
66            if values.is_empty() {
67                let data = bincode::serialize(&LogEntry::<&K, &V>::CreateKey(k))?;
68                let mut data = Logger::log_entry(self.table_id, data);
69                repr.append(&mut data);
70                continue;
71            }
72            for v in values {
73                let data = bincode::serialize(&LogEntry::Push(k, v))?;
74                let mut data = Logger::log_entry(self.table_id, data);
75                repr.append(&mut data);
76            }
77        }
78
79        Ok(repr)
80    }
81}
82
83impl<K, V> LookupList<K, V>
84where
85    K: Hash + Eq + Serialize + DeserializeOwned,
86    V: Serialize + DeserializeOwned + Eq + Hash,
87{
88    pub(crate) fn push_inner(&mut self, k: K, v: V) {
89        if let Some(vec) = self.inner.get_mut(&k) {
90            vec.push(v);
91        } else {
92            self.inner.insert(k, vec![v]);
93        }
94    }
95    pub fn push(&mut self, k: K, v: V) -> DbResult<()> {
96        let log_entry = LogEntry::Push(&k, &v);
97        let data = bincode::serialize(&log_entry)?;
98        self.push_inner(k, v);
99        self.logger.write(self.table_id, data)?;
100        Ok(())
101    }
102
103    pub fn create_key(&mut self, key: K) -> DbResult<Option<Vec<V>>> {
104        let log_entry = LogEntry::<&K, &V>::CreateKey(&key);
105        let data = bincode::serialize(&log_entry)?;
106
107        let ret = self.inner.insert(key, Vec::new());
108
109        self.logger.write(self.table_id, data)?;
110        Ok(ret)
111    }
112
113    pub fn remove(&mut self, key: &K, idx: usize) -> DbResult<bool> {
114        if let Some(vec) = self.inner.get_mut(key) {
115            let log_entry = LogEntry::Remove::<&K, &V>(key, idx);
116            let data = bincode::serialize(&log_entry)?;
117            self.logger.write(self.table_id, data)?;
118            vec.remove(idx);
119            Ok(true)
120        } else {
121            Ok(false)
122        }
123    }
124
125    pub fn get(&self) -> &HashMap<K, Vec<V>> {
126        &self.inner
127    }
128
129    pub fn clear(&mut self) -> DbResult<()> {
130        self.inner.clear();
131        let log_entry = LogEntry::<K, V>::Clear;
132        let data = bincode::serialize(&log_entry)?;
133        self.logger.write(self.table_id, data)?;
134
135        Ok(())
136    }
137
138    pub fn clear_key(&mut self, key: &K) -> DbResult<Option<Vec<V>>> {
139        let log_entry = LogEntry::<&K, &V>::ClearKey(key);
140        let data = bincode::serialize(&log_entry)?;
141        let ret = self.inner.remove(key);
142        self.logger.write(self.table_id, data)?;
143
144        Ok(ret)
145    }
146}