1use crate::{
4 index::{
5 ordered::Index as OrderedIndex, partitioned::partition_index_and_sub_key,
6 Ordered as OrderedTrait, Unordered as UnorderedTrait,
7 },
8 translator::Translator,
9};
10use commonware_runtime::Metrics;
11
12pub struct Index<T: Translator, V: Eq + Send + Sync, const P: usize> {
17 partitions: Vec<OrderedIndex<T, V>>,
18}
19
20impl<T: Translator, V: Eq + Send + Sync, const P: usize> Index<T, V, P> {
21 pub fn new(ctx: impl Metrics, translator: T) -> Self {
23 let partition_count = 1 << (P * 8);
24 let mut partitions = Vec::with_capacity(partition_count);
25 for i in 0..partition_count {
26 partitions.push(OrderedIndex::new(
27 ctx.with_label(&format!("partition_{i}")),
28 translator.clone(),
29 ));
30 }
31
32 Self { partitions }
33 }
34
35 fn get_partition<'a>(&self, key: &'a [u8]) -> (&OrderedIndex<T, V>, &'a [u8]) {
37 let (i, sub_key) = partition_index_and_sub_key::<P>(key);
38
39 (&self.partitions[i], sub_key)
40 }
41
42 fn get_partition_mut<'a>(&mut self, key: &'a [u8]) -> (&mut OrderedIndex<T, V>, &'a [u8]) {
45 let (i, sub_key) = partition_index_and_sub_key::<P>(key);
46
47 (&mut self.partitions[i], sub_key)
48 }
49}
50
51impl<T: Translator, V: Eq + Send + Sync, const P: usize> UnorderedTrait for Index<T, V, P> {
52 type Value = V;
53 type Cursor<'a>
54 = <OrderedIndex<T, V> as UnorderedTrait>::Cursor<'a>
55 where
56 Self: 'a;
57
58 fn get<'a>(&'a self, key: &[u8]) -> impl Iterator<Item = &'a Self::Value> + 'a
59 where
60 Self::Value: 'a,
61 {
62 let (partition, sub_key) = self.get_partition(key);
63
64 partition.get(sub_key)
65 }
66
67 fn get_mut<'a>(&'a mut self, key: &[u8]) -> Option<Self::Cursor<'a>> {
68 let (partition, sub_key) = self.get_partition_mut(key);
69
70 partition.get_mut(sub_key)
71 }
72
73 fn get_mut_or_insert<'a>(
74 &'a mut self,
75 key: &[u8],
76 value: Self::Value,
77 ) -> Option<Self::Cursor<'a>> {
78 let (partition, sub_key) = self.get_partition_mut(key);
79
80 partition.get_mut_or_insert(sub_key, value)
81 }
82
83 fn insert(&mut self, key: &[u8], value: Self::Value) {
84 let (partition, sub_key) = self.get_partition_mut(key);
85
86 partition.insert(sub_key, value);
87 }
88
89 fn insert_and_prune(
90 &mut self,
91 key: &[u8],
92 value: Self::Value,
93 predicate: impl Fn(&Self::Value) -> bool,
94 ) {
95 let (partition, sub_key) = self.get_partition_mut(key);
96
97 partition.insert_and_prune(sub_key, value, predicate);
98 }
99
100 fn prune(&mut self, key: &[u8], predicate: impl Fn(&Self::Value) -> bool) {
101 let (partition, sub_key) = self.get_partition_mut(key);
102
103 partition.prune(sub_key, predicate);
104 }
105
106 fn remove(&mut self, key: &[u8]) {
107 let (partition, sub_key) = self.get_partition_mut(key);
108
109 partition.remove(sub_key);
110 }
111
112 #[cfg(test)]
113 fn keys(&self) -> usize {
114 let mut keys = 0;
116 for partition in &self.partitions {
117 keys += partition.keys();
118 }
119
120 keys
121 }
122
123 #[cfg(test)]
124 fn items(&self) -> usize {
125 let mut items = 0;
127 for partition in &self.partitions {
128 items += partition.items();
129 }
130
131 items
132 }
133
134 #[cfg(test)]
135 fn pruned(&self) -> usize {
136 let mut pruned = 0;
138 for partition in &self.partitions {
139 pruned += partition.pruned();
140 }
141
142 pruned
143 }
144}
145
146impl<T: Translator, V: Eq + Send + Sync, const P: usize> OrderedTrait for Index<T, V, P> {
147 type Iterator<'a>
148 = <OrderedIndex<T, V> as OrderedTrait>::Iterator<'a>
149 where
150 Self: 'a;
151
152 fn prev_translated_key<'a>(&'a self, key: &[u8]) -> Option<(Self::Iterator<'a>, bool)>
153 where
154 Self::Value: 'a,
155 {
156 let (partition_index, sub_key) = partition_index_and_sub_key::<P>(key);
157 {
158 let partition = &self.partitions[partition_index];
159 let iter = partition.prev_translated_key_no_cycle(sub_key);
160 if let Some(iter) = iter {
161 return Some((iter, false));
162 }
163 }
164
165 for partition in self.partitions[..partition_index].iter().rev() {
166 let iter = partition.last_translated_key();
167 if let Some(iter) = iter {
168 return Some((iter, false));
169 }
170 }
171
172 self.last_translated_key().map(|iter| (iter, true))
173 }
174
175 fn next_translated_key<'a>(&'a self, key: &[u8]) -> Option<(Self::Iterator<'a>, bool)>
176 where
177 Self::Value: 'a,
178 {
179 let (partition_index, sub_key) = partition_index_and_sub_key::<P>(key);
180 {
181 let partition = &self.partitions[partition_index];
182 let iter = partition.next_translated_key_no_cycle(sub_key);
183 if let Some(iter) = iter {
184 return Some((iter, false));
185 }
186 }
187
188 for partition in self.partitions[partition_index + 1..].iter() {
189 let iter = partition.first_translated_key();
190 if let Some(iter) = iter {
191 return Some((iter, false));
192 }
193 }
194
195 self.first_translated_key().map(|iter| (iter, true))
196 }
197
198 fn first_translated_key<'a>(&'a self) -> Option<Self::Iterator<'a>>
199 where
200 Self::Value: 'a,
201 {
202 for partition in &self.partitions {
203 let iter = partition.first_translated_key();
204 if iter.is_none() {
205 continue;
206 }
207 return iter;
208 }
209
210 None
211 }
212
213 fn last_translated_key<'a>(&'a self) -> Option<Self::Iterator<'a>>
214 where
215 Self::Value: 'a,
216 {
217 for partition in self.partitions.iter().rev() {
218 let iter = partition.last_translated_key();
219 if iter.is_none() {
220 continue;
221 }
222 return iter;
223 }
224
225 None
226 }
227}
228
229#[cfg(test)]
230mod tests {
231 use super::*;
232 use crate::translator::OneCap;
233 use commonware_macros::test_traced;
234 use commonware_runtime::{deterministic, Runner};
235 use commonware_utils::hex;
236
237 #[test_traced]
238 fn test_ordered_trait_empty_index() {
239 let runner = deterministic::Runner::default();
240 runner.start(|context| async move {
241 let index = Index::<_, u64, 1>::new(context, OneCap);
242
243 assert!(index.first_translated_key().is_none());
244 assert!(index.last_translated_key().is_none());
245 assert!(index.prev_translated_key(b"key").is_none());
246 assert!(index.next_translated_key(b"key").is_none());
247 });
248 }
249
250 #[test_traced]
251 fn test_ordered_trait_single_key() {
252 let runner = deterministic::Runner::default();
253 runner.start(|context| async move {
254 let mut index = Index::<_, u64, 1>::new(context, OneCap);
255 let key = b"\x0a\xff";
256
257 index.insert(key, 42u64);
258
259 let mut first = index.first_translated_key().unwrap();
260 assert_eq!(first.next(), Some(&42));
261 assert!(first.next().is_none());
262
263 let mut last = index.last_translated_key().unwrap();
264 assert_eq!(last.next(), Some(&42));
265 assert!(last.next().is_none());
266
267 let (mut iter, wrapped) = index.prev_translated_key(key).unwrap();
268 assert!(wrapped);
269 assert_eq!(iter.next(), Some(&42));
270 assert!(iter.next().is_none());
271 let (mut iter, wrapped) = index.next_translated_key(key).unwrap();
272 assert!(wrapped);
273 assert_eq!(iter.next(), Some(&42));
274 assert!(iter.next().is_none());
275
276 let (mut next, wrapped) = index.next_translated_key(b"\x00").unwrap();
277 assert!(!wrapped);
278 assert_eq!(next.next(), Some(&42));
279 assert!(next.next().is_none());
280
281 let (mut prev, wrapped) = index.prev_translated_key(b"\xff\x00").unwrap();
282 assert!(!wrapped);
283 assert_eq!(prev.next(), Some(&42));
284 assert!(prev.next().is_none());
285 });
286 }
287
288 #[test_traced]
289 fn test_ordered_trait_all_keys() {
290 let runner = deterministic::Runner::default();
291 runner.start(|context| async move {
292 let mut index = Index::<_, u64, 1>::new(context, OneCap);
293 for b1 in 0..=255u8 {
295 for b2 in 0..=255u8 {
296 let key = [b1, b2];
297 index.insert(&key, (b1 as u64) << 8 | b2 as u64);
298 }
299 }
300
301 for b1 in (0..=255u8).rev() {
303 for b2 in 0..=255u8 {
304 let key = [b1, b2, 0xff];
305 index.insert(&key, u64::MAX);
306 }
307 }
308
309 let first_translated_key = index.first_translated_key().unwrap().next().unwrap();
310 assert_eq!(*first_translated_key, 0);
311
312 let last_translated_key = index.last_translated_key().unwrap().next().unwrap();
313 assert_eq!(*last_translated_key, (255u64 << 8) | 255);
314
315 let last = [255u8, 255u8];
316 let (mut iter, wrapped) = index.next_translated_key(&last).unwrap();
317 assert!(wrapped);
318 assert_eq!(iter.next(), Some(first_translated_key));
319
320 for b1 in 0..=255u8 {
321 for b2 in 0..=255u8 {
322 let key = [b1, b2];
323 if !(b1 == 255 && b2 == 255) {
324 let (mut iter, _) = index.next_translated_key(&key).unwrap();
325 let next = *iter.next().unwrap();
326 assert_eq!(next, ((b1 as u64) << 8 | b2 as u64) + 1);
327 let next = *iter.next().unwrap();
328 assert_eq!(next, u64::MAX);
329 assert!(iter.next().is_none());
330 }
331 if !(b1 == 0 && b2 == 0) {
332 let (mut iter, _) = index.prev_translated_key(&key).unwrap();
333 let prev = *iter.next().unwrap();
334 assert_eq!(prev, ((b1 as u64) << 8 | b2 as u64) - 1);
335 let prev = *iter.next().unwrap();
336 assert_eq!(prev, u64::MAX);
337 assert!(iter.next().is_none());
338 }
339 }
340 }
341 });
342 }
343
344 #[test_traced]
345 fn test_ordered_trait_multiple_keys() {
346 let runner = deterministic::Runner::default();
347 runner.start(|context| async move {
348 let mut index = Index::<_, u64, 1>::new(context, OneCap);
349 assert_eq!(index.keys(), 0);
350
351 let k1 = &hex!("0x0b02AA"); let k2 = &hex!("0x1c04CC"); let k2_collides = &hex!("0x1c0411");
354 let k3 = &hex!("0x2d06EE"); index.insert(k1, 1);
356 index.insert(k2, 21);
357 index.insert(k2_collides, 22);
358 index.insert(k3, 3);
359 assert_eq!(index.keys(), 3);
360
361 let mut iter = index.first_translated_key().unwrap();
363 assert_eq!(iter.next(), Some(&1));
364 assert_eq!(iter.next(), None);
365
366 let (mut iter, wrapped) = index.next_translated_key(&[0x00]).unwrap();
368 assert!(!wrapped);
369 assert_eq!(iter.next(), Some(&1));
370 assert_eq!(iter.next(), None);
371
372 let (mut iter, wrapped) = index.next_translated_key(&hex!("0x0b02F2")).unwrap();
374 assert!(!wrapped);
375 assert_eq!(iter.next(), Some(&21));
376 assert_eq!(iter.next(), Some(&22));
377 assert_eq!(iter.next(), None);
378
379 let (mut iter, wrapped) = index.next_translated_key(&hex!("0x1b010203")).unwrap();
381 assert!(!wrapped);
382 assert_eq!(iter.next(), Some(&21));
383 assert_eq!(iter.next(), Some(&22));
384 assert_eq!(iter.next(), None);
385
386 let (mut iter, wrapped) = index.next_translated_key(&hex!("0x2a01020304")).unwrap();
388 assert!(!wrapped);
389 assert_eq!(iter.next(), Some(&3));
390 assert_eq!(iter.next(), None);
391
392 let (mut iter, wrapped) = index.next_translated_key(k3).unwrap();
394 assert!(wrapped);
395 assert_eq!(iter.next(), Some(&1));
396 assert_eq!(iter.next(), None);
397
398 let (mut iter, wrapped) = index.next_translated_key(&hex!("0x2eFF")).unwrap();
400 assert!(wrapped);
401 assert_eq!(iter.next(), Some(&1));
402 assert_eq!(iter.next(), None);
403
404 let (mut iter, wrapped) = index.prev_translated_key(k1).unwrap();
406 assert!(wrapped);
407 assert_eq!(iter.next(), Some(&3));
408 assert_eq!(iter.next(), None);
409
410 let (mut iter, wrapped) = index.prev_translated_key(&hex!("0x0c0102")).unwrap();
412 assert!(!wrapped);
413 assert_eq!(iter.next(), Some(&1));
414 assert_eq!(iter.next(), None);
415
416 let (mut iter, wrapped) = index.prev_translated_key(&hex!("0x1d0102")).unwrap();
418 assert!(!wrapped);
419 assert_eq!(iter.next(), Some(&21));
420 assert_eq!(iter.next(), Some(&22));
421 assert_eq!(iter.next(), None);
422
423 let (mut iter, wrapped) = index.prev_translated_key(&hex!("0xCC0102")).unwrap();
425 assert!(!wrapped);
426 assert_eq!(iter.next(), Some(&3));
427 assert_eq!(iter.next(), None);
428
429 let mut iter = index.last_translated_key().unwrap();
431 assert_eq!(iter.next(), Some(&3));
432 assert_eq!(iter.next(), None);
433 });
434 }
435}