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#[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}