1use crate::core::store::Store;
2
3use super::{
4 QueryResult, QueryResultDistinct,
5 index::{Index, Insert, Remove, Update},
6};
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
9pub struct Key {
10 pub id: u64,
11}
12
13#[cfg(not(feature = "std"))]
14pub type DefaultStore<In> = alloc::collections::BTreeMap<Key, In>;
15
16#[cfg(feature = "std")]
17pub type DefaultStore<In> = std::collections::HashMap<Key, In>;
18
19pub struct Collection<In, Ix, S = DefaultStore<In>> {
21 index: Ix,
22 data: S,
23 next_key_id: u64,
24 _marker: core::marker::PhantomData<fn() -> In>,
25}
26
27impl<In, Ix> Collection<In, Ix> {
28 pub fn new(ix: Ix) -> Self
30 where
31 In: 'static,
32 Ix: Index<In>,
33 DefaultStore<In>: Store<In>,
34 {
35 Collection::new_with_empty_store(ix)
36 }
37}
38
39impl<In, Ix, S: Default> Collection<In, Ix, S> {
40 pub fn new_with_empty_store(ix: Ix) -> Self {
42 Collection::new_with_store(S::default(), ix)
43 }
44}
45
46impl<In, Ix, S> Collection<In, Ix, S> {
47 pub fn new_with_store(store: S, ix: Ix) -> Self {
49 Collection {
50 data: store,
51 next_key_id: 0,
52 index: ix,
53 _marker: core::marker::PhantomData,
54 }
55 }
56}
57
58impl<In, Ix, S> Collection<In, Ix, S>
59where
60 In: 'static,
61 Ix: Index<In>,
62 S: Store<In>,
63{
64 pub fn get_by_key(&self, key: Key) -> Option<&In> {
66 self.data.get(key)
67 }
68
69 pub fn insert(&mut self, value: In) -> Key {
71 let key = self.mk_key();
72 let existing = self.data.insert(key, value);
73
74 debug_assert!(existing.is_none());
76
77 self.index.insert(&Insert {
78 key,
79 new: self.data.get_unwrapped(key),
80 });
81
82 key
83 }
84
85 pub fn iter(&self) -> impl IntoIterator<Item = (Key, &In)> {
87 self.data.iter()
88 }
89
90 pub fn update_by_key_mut<F>(&mut self, key: Key, f: F)
92 where
93 F: FnOnce(&mut Option<In>),
94 {
95 let mut existing = self.delete_by_key(key);
96 f(&mut existing);
97
98 if let Some(existing) = existing {
99 self.data.insert(key, existing);
100 self.index.insert(&Insert {
101 key,
102 new: self.data.get_unwrapped(key),
103 });
104 }
105 }
106
107 pub fn update_by_key<F>(&mut self, key: Key, f: F)
109 where
110 F: FnOnce(Option<&In>) -> In,
111 {
112 let existing = self.data.get(key);
113 let new = f(existing);
114
115 match existing {
116 Some(existing) => {
117 self.index.update(&Update {
118 key,
119 new: &new,
120 existing,
121 });
122 self.data.insert(key, new);
123 }
124 None => {
125 self.index.insert(&Insert { key, new: &new });
126 self.data.insert(key, new);
127 }
128 };
129 }
130
131 pub fn adjust_by_key_mut<F>(&mut self, key: Key, f: F)
133 where
134 F: FnOnce(&mut In),
135 {
136 if let Some(mut existing) = self.delete_by_key(key) {
137 f(&mut existing);
138 self.data.insert(key, existing);
139 self.index.insert(&Insert {
140 key,
141 new: self.data.get_unwrapped(key),
142 });
143 }
144 }
145
146 pub fn adjust_by_key<F>(&mut self, key: Key, f: F)
148 where
149 F: FnOnce(&In) -> In,
150 {
151 if let Some(existing) = self.data.get(key) {
152 let new = f(existing);
153 self.index.update(&Update {
154 key,
155 new: &new,
156 existing,
157 });
158 self.data.insert(key, new);
159 }
160 }
161
162 pub fn delete_by_key(&mut self, key: Key) -> Option<In> {
164 let existing = self.data.remove(key);
165
166 if let Some(ref existing) = existing {
167 self.index.remove(&Remove { key, existing });
168 }
169
170 existing
171 }
172
173 pub fn query<Res>(&self, f: impl FnOnce(&Ix) -> Res) -> Res::Resolved<&In>
175 where
176 Res: QueryResult,
177 {
178 let res = f(&self.index);
179 res.map(|k| self.data.get_unwrapped(k))
180 }
181
182 pub fn delete<Res>(&mut self, f: impl FnOnce(&Ix) -> Res) -> usize
183 where
184 Res: QueryResult,
185 {
186 let mut affected_count = 0;
187 let res = f(&self.index);
188 res.map(|key| {
189 self.delete_by_key(key);
190 affected_count += 1;
191 });
192 affected_count
193 }
194
195 pub fn update<Res, F>(
196 &mut self,
197 f: impl FnOnce(&Ix) -> Res,
198 update_fn: impl Fn(&In) -> In,
199 ) -> Res::Resolved<()>
200 where
201 Res: QueryResultDistinct,
202 {
203 let res = f(&self.index);
204 res.map(|key| {
205 self.data.update(key, |existing| {
206 let new = update_fn(existing);
207 self.index.update(&Update {
208 key,
209 new: &new,
210 existing,
211 });
212 new
213 });
214 })
215 }
216
217 pub fn take<Res>(&mut self, f: impl FnOnce(&Ix) -> Res) -> Res::Resolved<In>
218 where
219 Res: QueryResultDistinct,
220 {
221 let res = f(&self.index);
222 res.map(|k| self.delete_by_key(k).unwrap())
223 }
224
225 pub fn len(&self) -> usize {
227 self.data.len()
228 }
229
230 pub fn is_empty(&self) -> bool {
231 self.data.is_empty()
232 }
233
234 fn mk_key(&mut self) -> Key {
235 let k = Key {
236 id: self.next_key_id,
237 };
238 self.next_key_id += 1;
239 k
240 }
241}
242
243#[cfg(test)]
244mod tests {
245 use super::*;
246
247 struct TrivialIndex;
248 impl<In> Index<In> for TrivialIndex {
249 fn insert(&mut self, _op: &Insert<In>) {}
250 fn remove(&mut self, _op: &Remove<In>) {}
251 }
252
253 #[test]
254 fn test_len() {
255 let mut collection = Collection::new(TrivialIndex);
256 assert_eq!(collection.len(), 0);
257
258 collection.insert(1);
259 assert_eq!(collection.len(), 1);
260
261 collection.insert(2);
262 assert_eq!(collection.len(), 2);
263
264 let key = collection.insert(3);
265 assert_eq!(collection.len(), 3);
266
267 collection.delete_by_key(key);
268 assert_eq!(collection.len(), 2);
269 }
270
271 }