1use crate::{
8 index::{
9 storage::{push_displaced, Cursor as CursorImpl, IndexEntry, Overflow, Values},
10 Cursor as CursorTrait, Ordered, Unordered,
11 },
12 translator::Translator,
13};
14use commonware_runtime::{
15 telemetry::metrics::{Counter, Gauge, MetricsExt as _},
16 Metrics,
17};
18use std::{
19 collections::{
20 btree_map::{
21 Entry as BTreeEntry, OccupiedEntry as BTreeOccupiedEntry,
22 VacantEntry as BTreeVacantEntry,
23 },
24 BTreeMap, HashMap,
25 },
26 ops::Bound::{Excluded, Unbounded},
27};
28
29impl<K: Ord + Send + Sync, V: Send + Sync> IndexEntry<V> for BTreeOccupiedEntry<'_, K, V> {
31 type Key = K;
32
33 fn key(&self) -> &K {
34 BTreeOccupiedEntry::key(self)
35 }
36
37 fn get_mut(&mut self) -> &mut V {
38 self.get_mut()
39 }
40
41 fn remove(self) {
42 self.remove_entry();
43 }
44}
45
46pub type Cursor<'a, K, V, S> = CursorImpl<'a, K, V, BTreeOccupiedEntry<'a, K, V>, S>;
48
49pub struct Index<T: Translator, V: Send + Sync> {
56 translator: T,
57 map: BTreeMap<T::Key, V>,
58 overflow: Overflow<T::Key, V, T>,
59
60 keys: Gauge,
61 items: Gauge,
62 pruned: Counter,
63}
64
65impl<T: Translator, V: Send + Sync> Index<T, V> {
66 fn create(keys: &Gauge, items: &Gauge, vacant: BTreeVacantEntry<'_, T::Key, V>, v: V) {
68 keys.inc();
69 items.inc();
70 vacant.insert(v);
71 }
72
73 pub fn new(ctx: impl Metrics, translator: T) -> Self {
75 Self {
76 overflow: HashMap::with_hasher(translator.clone()),
77 translator,
78 map: BTreeMap::new(),
79 keys: ctx.gauge("keys", "Number of translated keys in the index"),
80 items: ctx.gauge("items", "Number of items in the index"),
81 pruned: ctx.counter("pruned", "Number of items pruned"),
82 }
83 }
84
85 fn values<'a>(&'a self, k: &T::Key, head: &'a V) -> Values<'a, T::Key, V, T> {
88 Values::new(Some(head), &self.overflow, *k)
89 }
90
91 pub(super) fn get_translated(&self, key: T::Key) -> Values<'_, T::Key, V, T> {
93 Values::new(self.map.get(&key), &self.overflow, key)
94 }
95
96 pub(super) fn next_translated_values_no_cycle(
99 &self,
100 key: &[u8],
101 ) -> Option<Values<'_, T::Key, V, T>> {
102 let k = self.translator.transform(key);
103 self.map
104 .range((Excluded(k), Unbounded))
105 .next()
106 .map(|(k, head)| self.values(k, head))
107 }
108
109 pub(super) fn prev_translated_values_no_cycle(
112 &self,
113 key: &[u8],
114 ) -> Option<Values<'_, T::Key, V, T>> {
115 let k = self.translator.transform(key);
116 self.map
117 .range(..k)
118 .next_back()
119 .map(|(k, head)| self.values(k, head))
120 }
121
122 pub(super) fn first_translated_values(&self) -> Option<Values<'_, T::Key, V, T>> {
125 self.map
126 .first_key_value()
127 .map(|(k, head)| self.values(k, head))
128 }
129
130 pub(super) fn last_translated_values(&self) -> Option<Values<'_, T::Key, V, T>> {
133 self.map
134 .last_key_value()
135 .map(|(k, head)| self.values(k, head))
136 }
137}
138
139impl<T: Translator, V: Send + Sync> Ordered for Index<T, V> {
140 fn prev_translated_key<'a>(
141 &'a self,
142 key: &[u8],
143 ) -> Option<(impl Iterator<Item = &'a V> + Send + 'a, bool)>
144 where
145 V: 'a,
146 {
147 if let Some(values) = self.prev_translated_values_no_cycle(key) {
148 return Some((values, false));
149 }
150 self.last_translated_values().map(|values| (values, true))
151 }
152
153 fn next_translated_key<'a>(
154 &'a self,
155 key: &[u8],
156 ) -> Option<(impl Iterator<Item = &'a V> + Send + 'a, bool)>
157 where
158 V: 'a,
159 {
160 if let Some(values) = self.next_translated_values_no_cycle(key) {
161 return Some((values, false));
162 }
163 self.first_translated_values().map(|values| (values, true))
164 }
165
166 fn first_translated_key<'a>(&'a self) -> Option<impl Iterator<Item = &'a V> + Send + 'a>
167 where
168 V: 'a,
169 {
170 self.first_translated_values()
171 }
172
173 fn last_translated_key<'a>(&'a self) -> Option<impl Iterator<Item = &'a V> + Send + 'a>
174 where
175 V: 'a,
176 {
177 self.last_translated_values()
178 }
179}
180
181impl<T: Translator, V: Send + Sync> super::Factory<T> for Index<T, V> {
182 fn new(ctx: impl commonware_runtime::Metrics, translator: T) -> Self {
183 Self::new(ctx, translator)
184 }
185}
186
187impl<T: Translator, V: Send + Sync> Unordered for Index<T, V> {
188 type Value = V;
189
190 fn get_many<'a, K: AsRef<[u8]>>(&'a self, keys: &[K], mut visit: impl FnMut(usize, &'a V))
191 where
192 V: 'a,
193 {
194 let mut order: Vec<(T::Key, usize)> = keys
197 .iter()
198 .enumerate()
199 .map(|(key_idx, key)| (self.translator.transform(key.as_ref()), key_idx))
200 .collect();
201 order.sort_unstable();
202 for (translated, key_idx) in order {
203 for value in self.get_translated(translated) {
204 visit(key_idx, value);
205 }
206 }
207 }
208 type Cursor<'a>
209 = Cursor<'a, T::Key, V, T>
210 where
211 Self: 'a;
212
213 fn get<'a>(&'a self, key: &[u8]) -> impl Iterator<Item = &'a V> + 'a
214 where
215 V: 'a,
216 {
217 self.get_translated(self.translator.transform(key))
218 }
219
220 fn get_mut<'a>(&'a mut self, key: &[u8]) -> Option<Self::Cursor<'a>> {
221 let k = self.translator.transform(key);
222 match self.map.entry(k) {
223 BTreeEntry::Occupied(entry) => Some(Cursor::<'_, T::Key, V, T>::new(
224 entry,
225 &mut self.overflow,
226 &self.keys,
227 &self.items,
228 &self.pruned,
229 )),
230 BTreeEntry::Vacant(_) => None,
231 }
232 }
233
234 fn get_mut_or_insert<'a>(&'a mut self, key: &[u8], value: V) -> Option<Self::Cursor<'a>> {
235 let k = self.translator.transform(key);
236 match self.map.entry(k) {
237 BTreeEntry::Occupied(entry) => Some(Cursor::<'_, T::Key, V, T>::new(
238 entry,
239 &mut self.overflow,
240 &self.keys,
241 &self.items,
242 &self.pruned,
243 )),
244 BTreeEntry::Vacant(entry) => {
245 Self::create(&self.keys, &self.items, entry, value);
246 None
247 }
248 }
249 }
250
251 fn insert(&mut self, key: &[u8], value: V) {
252 let k = self.translator.transform(key);
253 match self.map.entry(k) {
254 BTreeEntry::Occupied(mut entry) => {
255 let old = std::mem::replace(entry.get_mut(), value);
258 push_displaced(&mut self.overflow, k, old);
259 self.items.inc();
260 }
261 BTreeEntry::Vacant(entry) => {
262 Self::create(&self.keys, &self.items, entry, value);
263 }
264 }
265 }
266
267 fn insert_and_retain(&mut self, key: &[u8], value: V, should_retain: impl Fn(&V) -> bool) {
268 let k = self.translator.transform(key);
269 match self.map.entry(k) {
270 BTreeEntry::Occupied(mut entry) => {
271 #[allow(clippy::map_entry)]
273 if !self.overflow.contains_key(&k) {
274 match (should_retain(entry.get()), should_retain(&value)) {
275 (true, true) => {
277 self.overflow.insert(k, vec![value]);
278 self.items.inc();
279 }
280 (false, true) => {
282 *entry.get_mut() = value;
283 self.pruned.inc();
284 }
285 (false, false) => {
287 entry.remove();
288 self.keys.dec();
289 self.items.dec();
290 self.pruned.inc();
291 }
292 (true, false) => {}
294 }
295 return;
296 }
297
298 let mut cursor = Cursor::<'_, T::Key, V, T>::new(
300 entry,
301 &mut self.overflow,
302 &self.keys,
303 &self.items,
304 &self.pruned,
305 );
306
307 cursor.retain(&should_retain);
309
310 if should_retain(&value) {
312 cursor.insert(value);
313 }
314 }
315 BTreeEntry::Vacant(entry) => {
316 if should_retain(&value) {
318 Self::create(&self.keys, &self.items, entry, value);
319 }
320 }
321 }
322 }
323
324 fn remove(&mut self, key: &[u8]) {
325 let k = self.translator.transform(key);
326 if self.map.remove(&k).is_some() {
327 self.keys.dec();
329 self.items.dec();
330 self.pruned.inc();
331 if !self.overflow.is_empty() {
332 if let Some(chain) = self.overflow.remove(&k) {
333 self.items.dec_by(chain.len() as i64);
334 self.pruned.inc_by(chain.len() as u64);
335 }
336 }
337 }
338 }
339
340 #[cfg(test)]
341 fn keys(&self) -> usize {
342 self.map.len()
343 }
344
345 #[cfg(test)]
346 fn items(&self) -> usize {
347 self.items.get() as usize
348 }
349
350 #[cfg(test)]
351 fn pruned(&self) -> usize {
352 self.pruned.get() as usize
353 }
354}
355
356#[cfg(test)]
357mod tests {
358 use super::*;
359 use crate::translator::OneCap;
360 use commonware_formatting::hex;
361 use commonware_macros::test_traced;
362 use commonware_runtime::{deterministic, Runner};
363
364 #[test_traced]
365 fn test_ordered_empty_index() {
366 let runner = deterministic::Runner::default();
367 runner.start(|context| async move {
368 let index = Index::<_, u64>::new(context, OneCap);
369
370 assert!(index.first_translated_key().is_none());
371 assert!(index.last_translated_key().is_none());
372 assert!(index.prev_translated_key(b"key").is_none());
373 assert!(index.next_translated_key(b"key").is_none());
374 });
375 }
376
377 #[test_traced]
378 fn test_ordered_index_ordering() {
379 let runner = deterministic::Runner::default();
380 runner.start(|context| async move {
381 let mut index = Index::<_, u64>::new(context, OneCap);
382 assert_eq!(index.keys(), 0);
383
384 let k1 = &hex!("0x0b02AA"); let k2 = &hex!("0x1c04CC"); let k2_collides = &hex!("0x1c0311");
387 let k3 = &hex!("0x2d06EE"); index.insert(k1, 1);
389 index.insert(k2, 21);
390 index.insert(k2_collides, 22);
391 index.insert(k3, 3);
392 assert_eq!(index.keys(), 3);
393
394 let mut next = index.first_translated_key().unwrap();
396 assert_eq!(next.next().unwrap(), &1);
397 assert_eq!(next.next(), None);
398
399 let (mut next, wrapped) = index.next_translated_key(&[0x00]).unwrap();
401 assert!(!wrapped);
402 assert_eq!(next.next().unwrap(), &1);
403 assert_eq!(next.next(), None);
404
405 let (mut next, wrapped) = index.next_translated_key(&hex!("0x0b0102")).unwrap();
407 assert!(!wrapped);
408 assert_eq!(next.next().unwrap(), &22);
409 assert_eq!(next.next().unwrap(), &21);
410 assert_eq!(next.next(), None);
411
412 let (mut next, wrapped) = index.next_translated_key(&hex!("0x1b010203")).unwrap();
414 assert!(!wrapped);
415 assert_eq!(next.next().unwrap(), &22);
416 assert_eq!(next.next().unwrap(), &21);
417 assert_eq!(next.next(), None);
418
419 let (mut next, wrapped) = index.next_translated_key(&hex!("0x2a01020304")).unwrap();
421 assert!(!wrapped);
422 assert_eq!(next.next().unwrap(), &3);
423 assert_eq!(next.next(), None);
424
425 let (mut next, wrapped) = index.next_translated_key(k3).unwrap();
427 assert!(wrapped);
428 assert_eq!(next.next().unwrap(), &1);
429 assert_eq!(next.next(), None);
430
431 let (mut next, wrapped) = index.next_translated_key(&hex!("0x2eFF")).unwrap();
433 assert!(wrapped);
434 assert_eq!(next.next().unwrap(), &1);
435 assert_eq!(next.next(), None);
436
437 let (mut prev, wrapped) = index.prev_translated_key(k1).unwrap();
439 assert!(wrapped);
440 assert_eq!(prev.next().unwrap(), &3);
441 assert_eq!(prev.next(), None);
442
443 let (mut prev, wrapped) = index.prev_translated_key(&hex!("0x0c0102")).unwrap();
445 assert!(!wrapped);
446 assert_eq!(prev.next().unwrap(), &1);
447 assert_eq!(prev.next(), None);
448
449 let (mut prev, wrapped) = index.prev_translated_key(&hex!("0x1d0102")).unwrap();
451 assert!(!wrapped);
452 assert_eq!(prev.next().unwrap(), &22);
453 assert_eq!(prev.next().unwrap(), &21);
454 assert_eq!(prev.next(), None);
455
456 let (mut prev, wrapped) = index.prev_translated_key(&hex!("0xCC0102")).unwrap();
458 assert!(!wrapped);
459 assert_eq!(prev.next().unwrap(), &3);
460 assert_eq!(prev.next(), None);
461
462 let mut last = index.last_translated_key().unwrap();
464 assert_eq!(last.next().unwrap(), &3);
465 assert_eq!(last.next(), None);
466 });
467 }
468}