1use crate::{
8 index::{
9 Cursor as CursorTrait, Ordered, Unordered,
10 storage::{Cursor as CursorImpl, IndexEntry, Overflow, Values, push_displaced},
11 },
12 translator::{OrderedTranslator, Translator},
13};
14use commonware_runtime::{
15 Metrics,
16 telemetry::metrics::{Counter, Gauge, MetricsExt as _},
17};
18use std::{
19 collections::{
20 BTreeMap, HashMap,
21 btree_map::{
22 Entry as BTreeEntry, OccupiedEntry as BTreeOccupiedEntry,
23 VacantEntry as BTreeVacantEntry,
24 },
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: OrderedTranslator, 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 if let Some(values) = self.prev_translated_values_no_cycle(key) {
145 return Some((values, false));
146 }
147 self.last_translated_values().map(|values| (values, true))
148 }
149
150 fn next_translated_key<'a>(
151 &'a self,
152 key: &[u8],
153 ) -> Option<(impl Iterator<Item = &'a V> + Send + 'a, bool)> {
154 if let Some(values) = self.next_translated_values_no_cycle(key) {
155 return Some((values, false));
156 }
157 self.first_translated_values().map(|values| (values, true))
158 }
159
160 fn first_translated_key<'a>(&'a self) -> Option<impl Iterator<Item = &'a V> + Send + 'a> {
161 self.first_translated_values()
162 }
163
164 fn last_translated_key<'a>(&'a self) -> Option<impl Iterator<Item = &'a V> + Send + 'a> {
165 self.last_translated_values()
166 }
167}
168
169impl<T: Translator, V: Send + Sync> super::Factory for Index<T, V> {
170 type Translator = T;
171
172 fn new(ctx: impl commonware_runtime::Metrics, translator: T) -> Self {
173 Self::new(ctx, translator)
174 }
175}
176
177impl<T: Translator, V: Send + Sync> Unordered for Index<T, V> {
178 type Value = V;
179
180 const LOOKUP_WARMS_UPDATE: bool = false;
183
184 fn get_many<'a, K: AsRef<[u8]>>(
185 &'a self,
186 keys: impl IntoIterator<Item = K>,
187 mut visit: impl FnMut(usize, &'a V),
188 ) {
189 let mut order: Vec<(T::Key, usize)> = keys
192 .into_iter()
193 .enumerate()
194 .map(|(key_idx, key)| (self.translator.transform(key.as_ref()), key_idx))
195 .collect();
196 order.sort_unstable();
197 for (translated, key_idx) in order {
198 for value in self.get_translated(translated) {
199 visit(key_idx, value);
200 }
201 }
202 }
203 type Cursor<'a>
204 = Cursor<'a, T::Key, V, T>
205 where
206 Self: 'a;
207
208 fn get<'a>(&'a self, key: &[u8]) -> impl Iterator<Item = &'a V> + 'a {
209 self.get_translated(self.translator.transform(key))
210 }
211
212 fn get_mut<'a>(&'a mut self, key: &[u8]) -> Option<Self::Cursor<'a>> {
213 let k = self.translator.transform(key);
214 match self.map.entry(k) {
215 BTreeEntry::Occupied(entry) => Some(Cursor::<'_, T::Key, V, T>::new(
216 entry,
217 &mut self.overflow,
218 &self.keys,
219 &self.items,
220 &self.pruned,
221 )),
222 BTreeEntry::Vacant(_) => None,
223 }
224 }
225
226 fn get_mut_or_insert<'a>(&'a mut self, key: &[u8], value: V) -> Option<Self::Cursor<'a>> {
227 let k = self.translator.transform(key);
228 match self.map.entry(k) {
229 BTreeEntry::Occupied(entry) => Some(Cursor::<'_, T::Key, V, T>::new(
230 entry,
231 &mut self.overflow,
232 &self.keys,
233 &self.items,
234 &self.pruned,
235 )),
236 BTreeEntry::Vacant(entry) => {
237 Self::create(&self.keys, &self.items, entry, value);
238 None
239 }
240 }
241 }
242
243 fn insert(&mut self, key: &[u8], value: V) {
244 let k = self.translator.transform(key);
245 match self.map.entry(k) {
246 BTreeEntry::Occupied(mut entry) => {
247 let old = std::mem::replace(entry.get_mut(), value);
250 push_displaced(&mut self.overflow, k, old);
251 self.items.inc();
252 }
253 BTreeEntry::Vacant(entry) => {
254 Self::create(&self.keys, &self.items, entry, value);
255 }
256 }
257 }
258
259 fn insert_and_retain(
260 &mut self,
261 key: &[u8],
262 value: V,
263 mut should_retain: impl FnMut(&V) -> bool,
264 ) {
265 let k = self.translator.transform(key);
266 match self.map.entry(k) {
267 BTreeEntry::Occupied(mut entry) => {
268 #[allow(clippy::map_entry)]
270 if !self.overflow.contains_key(&k) {
271 match (should_retain(entry.get()), should_retain(&value)) {
272 (true, true) => {
274 self.overflow.insert(k, vec![value]);
275 self.items.inc();
276 }
277 (false, true) => {
279 *entry.get_mut() = value;
280 self.pruned.inc();
281 }
282 (false, false) => {
284 entry.remove();
285 self.keys.dec();
286 self.items.dec();
287 self.pruned.inc();
288 }
289 (true, false) => {}
291 }
292 return;
293 }
294
295 let mut cursor = Cursor::<'_, T::Key, V, T>::new(
297 entry,
298 &mut self.overflow,
299 &self.keys,
300 &self.items,
301 &self.pruned,
302 );
303
304 cursor.retain(&mut should_retain);
306
307 if should_retain(&value) {
309 cursor.insert(value);
310 }
311 }
312 BTreeEntry::Vacant(entry) => {
313 if should_retain(&value) {
315 Self::create(&self.keys, &self.items, entry, value);
316 }
317 }
318 }
319 }
320
321 fn remove(&mut self, key: &[u8]) {
322 let k = self.translator.transform(key);
323 if self.map.remove(&k).is_some() {
324 self.keys.dec();
326 self.items.dec();
327 self.pruned.inc();
328 if !self.overflow.is_empty()
329 && let Some(chain) = self.overflow.remove(&k)
330 {
331 self.items.dec_by(chain.len() as i64);
332 self.pruned.inc_by(chain.len() as u64);
333 }
334 }
335 }
336
337 #[cfg(test)]
338 fn keys(&self) -> usize {
339 self.keys.get() as usize
340 }
341
342 #[cfg(test)]
343 fn items(&self) -> usize {
344 self.items.get() as usize
345 }
346
347 #[cfg(test)]
348 fn pruned(&self) -> usize {
349 self.pruned.get() as usize
350 }
351}
352
353#[cfg(test)]
354mod tests {
355 use super::*;
356 use crate::translator::OneCap;
357 use commonware_formatting::hex;
358 use commonware_macros::test_traced;
359 use commonware_runtime::{Runner, deterministic};
360
361 #[test_traced]
362 fn test_ordered_empty_index() {
363 let runner = deterministic::Runner::default();
364 runner.start(|context| async move {
365 let index = Index::<_, u64>::new(context, OneCap);
366
367 assert!(index.first_translated_key().is_none());
368 assert!(index.last_translated_key().is_none());
369 assert!(index.prev_translated_key(b"key").is_none());
370 assert!(index.next_translated_key(b"key").is_none());
371 });
372 }
373
374 #[test_traced]
375 fn test_ordered_index_ordering() {
376 let runner = deterministic::Runner::default();
377 runner.start(|context| async move {
378 let mut index = Index::<_, u64>::new(context, OneCap);
379 assert_eq!(index.keys(), 0);
380
381 let k1 = &hex!("0x0b02AA"); let k2 = &hex!("0x1c04CC"); let k2_collides = &hex!("0x1c0311");
384 let k3 = &hex!("0x2d06EE"); index.insert(k1, 1);
386 index.insert(k2, 21);
387 index.insert(k2_collides, 22);
388 index.insert(k3, 3);
389 assert_eq!(index.keys(), 3);
390
391 let mut next = index.first_translated_key().unwrap();
393 assert_eq!(next.next().unwrap(), &1);
394 assert_eq!(next.next(), None);
395
396 let (mut next, wrapped) = index.next_translated_key(&[0x00]).unwrap();
398 assert!(!wrapped);
399 assert_eq!(next.next().unwrap(), &1);
400 assert_eq!(next.next(), None);
401
402 let (mut next, wrapped) = index.next_translated_key(&hex!("0x0b0102")).unwrap();
404 assert!(!wrapped);
405 assert_eq!(next.next().unwrap(), &22);
406 assert_eq!(next.next().unwrap(), &21);
407 assert_eq!(next.next(), None);
408
409 let (mut next, wrapped) = index.next_translated_key(&hex!("0x1b010203")).unwrap();
411 assert!(!wrapped);
412 assert_eq!(next.next().unwrap(), &22);
413 assert_eq!(next.next().unwrap(), &21);
414 assert_eq!(next.next(), None);
415
416 let (mut next, wrapped) = index.next_translated_key(&hex!("0x2a01020304")).unwrap();
418 assert!(!wrapped);
419 assert_eq!(next.next().unwrap(), &3);
420 assert_eq!(next.next(), None);
421
422 let (mut next, wrapped) = index.next_translated_key(k3).unwrap();
424 assert!(wrapped);
425 assert_eq!(next.next().unwrap(), &1);
426 assert_eq!(next.next(), None);
427
428 let (mut next, wrapped) = index.next_translated_key(&hex!("0x2eFF")).unwrap();
430 assert!(wrapped);
431 assert_eq!(next.next().unwrap(), &1);
432 assert_eq!(next.next(), None);
433
434 let (mut prev, wrapped) = index.prev_translated_key(k1).unwrap();
436 assert!(wrapped);
437 assert_eq!(prev.next().unwrap(), &3);
438 assert_eq!(prev.next(), None);
439
440 let (mut prev, wrapped) = index.prev_translated_key(&hex!("0x0c0102")).unwrap();
442 assert!(!wrapped);
443 assert_eq!(prev.next().unwrap(), &1);
444 assert_eq!(prev.next(), None);
445
446 let (mut prev, wrapped) = index.prev_translated_key(&hex!("0x1d0102")).unwrap();
448 assert!(!wrapped);
449 assert_eq!(prev.next().unwrap(), &22);
450 assert_eq!(prev.next().unwrap(), &21);
451 assert_eq!(prev.next(), None);
452
453 let (mut prev, wrapped) = index.prev_translated_key(&hex!("0xCC0102")).unwrap();
455 assert!(!wrapped);
456 assert_eq!(prev.next().unwrap(), &3);
457 assert_eq!(prev.next(), None);
458
459 let mut last = index.last_translated_key().unwrap();
461 assert_eq!(last.next().unwrap(), &3);
462 assert_eq!(last.next(), None);
463 });
464 }
465}