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