composable_indexes_core/
collection.rs1use std::collections::HashMap;
2
3use crate::index::{Index, QueryEnv};
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
6pub struct Key {
7 pub id: u64,
8}
9
10pub struct Collection<In, Ix> {
12 index: Ix,
13 data: HashMap<Key, In>,
14 next_key_id: u64,
15}
16
17impl<In, Ix> Collection<In, Ix>
18where
19 Ix: Index<In>,
20{
21 pub fn new(ix: Ix) -> Self {
23 Collection {
24 data: HashMap::new(),
25 next_key_id: 0,
26 index: ix,
27 }
28 }
29
30 pub fn get(&self, key: Key) -> Option<&In> {
32 self.data.get(&key)
33 }
34
35 pub fn insert(&mut self, value: In) -> Key {
37 let key = self.mk_key();
38 let existing = self.data.insert(key, value);
39
40 debug_assert!(existing.is_none());
42
43 self.index.insert(&Insert {
44 key,
45 new: &self.data[&key],
46 });
47
48 key
49 }
50
51 pub fn iter(&self) -> impl Iterator<Item = (&Key, &In)> {
53 self.data.iter()
54 }
55
56 pub fn update_mut<F>(&mut self, key: Key, f: F)
58 where
59 F: FnOnce(&mut Option<In>),
60 {
61 let mut existing = self.delete(&key);
62 f(&mut existing);
63
64 if let Some(existing) = existing {
65 self.data.insert(key, existing);
66 self.index.insert(&Insert {
67 key,
68 new: &self.data[&key],
69 });
70 }
71 }
72
73 pub fn update<F>(&mut self, key: Key, f: F)
75 where
76 F: FnOnce(Option<&In>) -> In,
77 {
78 let existing = self.data.get(&key);
79 let new = f(existing);
80
81 match existing {
82 Some(existing) => {
83 self.index.update(&Update {
84 key,
85 new: &new,
86 existing,
87 });
88 self.data.insert(key, new);
89 }
90 None => {
91 self.index.insert(&Insert { key, new: &new });
92 self.data.insert(key, new);
93 }
94 };
95 }
96
97 pub fn adjust_mut<F>(&mut self, key: Key, f: F)
99 where
100 F: FnOnce(&mut In),
101 {
102 if let Some(mut existing) = self.delete(&key) {
103 f(&mut existing);
104 self.data.insert(key, existing);
105 self.index.insert(&Insert {
106 key,
107 new: &self.data[&key],
108 });
109 }
110 }
111
112 pub fn adjust<F>(&mut self, key: Key, f: F)
114 where
115 F: FnOnce(&In) -> In,
116 {
117 if let Some(existing) = self.data.get(&key) {
118 let new = f(existing);
119 self.index.update(&Update {
120 key,
121 new: &new,
122 existing,
123 });
124 self.data.insert(key, new);
125 }
126 }
127
128 pub fn delete(&mut self, key: &Key) -> Option<In> {
130 let existing = self.data.remove_entry(key);
131 if let Some((key, ref existing)) = existing {
132 self.index.remove(&Remove { key, existing });
133 }
134 existing.map(|(_, v)| v)
135 }
136
137 pub fn query(&self) -> Ix::Query<'_, In> {
139 let env = QueryEnv { data: &self.data };
140 self.index.query(env)
141 }
142
143 pub fn len(&self) -> usize {
145 self.data.len()
146 }
147
148 pub fn is_empty(&self) -> bool {
149 self.data.is_empty()
150 }
151
152 fn mk_key(&mut self) -> Key {
153 let k = Key {
154 id: self.next_key_id,
155 };
156 self.next_key_id += 1;
157 k
158 }
159}
160
161#[derive(Clone)]
162pub struct Insert<'t, In> {
163 pub key: Key,
164 pub new: &'t In,
165}
166
167#[derive(Clone)]
168pub struct Update<'t, In> {
169 pub key: Key,
170 pub new: &'t In,
171 pub existing: &'t In,
172}
173
174#[derive(Clone)]
175pub struct Remove<'t, In> {
176 pub key: Key,
177 pub existing: &'t In,
178}
179
180#[cfg(test)]
181mod tests {
182 use super::*;
183
184 struct TrivialIndex;
185 impl<In> Index<In> for TrivialIndex {
186 type Query<'t, Out>
187 = ()
188 where
189 Out: 't,
190 Self: 't;
191
192 fn insert(&mut self, _op: &Insert<In>) {}
193 fn remove(&mut self, _op: &Remove<In>) {}
194
195 fn query<'t, Out: 't>(&'t self, _env: QueryEnv<'t, Out>) -> Self::Query<'t, Out> {}
196 }
197
198 #[test]
199 fn test_len() {
200 let mut collection = Collection::new(TrivialIndex);
201 assert_eq!(collection.len(), 0);
202
203 collection.insert(1);
204 assert_eq!(collection.len(), 1);
205
206 collection.insert(2);
207 assert_eq!(collection.len(), 2);
208
209 let key = collection.insert(3);
210 assert_eq!(collection.len(), 3);
211
212 collection.delete(&key);
213 assert_eq!(collection.len(), 2);
214 }
215
216 }