commonware_storage/rmap/mod.rs
1//! A collection that manages disjoint, inclusive ranges `[start, end]`.
2//!
3//! # Design
4//!
5//! - Ranges are stored in ascending order of their start points.
6//! - Ranges are disjoint; there are no overlapping ranges.
7//! - Adjacent ranges are merged (e.g., inserting `5` into `[0,4]` and then inserting `4` results in `[0,5]`).
8//! - Each key in the [BTreeMap] represents the inclusive start of a range, and its
9//! corresponding value represents the inclusive end of that range.
10
11use std::collections::BTreeMap;
12
13/// A collection that manages disjoint, inclusive ranges `[start, end]`.
14#[derive(Debug, Default, PartialEq)]
15pub struct RMap {
16 ranges: BTreeMap<u64, u64>,
17}
18
19impl RMap {
20 /// Creates a new, empty [RMap].
21 pub const fn new() -> Self {
22 Self {
23 ranges: BTreeMap::new(),
24 }
25 }
26
27 /// Inserts a value into the [RMap].
28 ///
29 /// # Behavior
30 ///
31 /// - Create a new range `[value, value]` if `value` is isolated.
32 /// - Extend an existing range if `value` is adjacent to it (e.g., inserting `5` into `[1, 4]` results in `[1, 5]`).
33 /// - Merge two ranges if `value` bridges them (e.g., inserting `3` into a map with `[1, 2]` and `[4, 5]` results in `[1, 5]`).
34 /// - Do nothing if `value` is already covered by an existing range.
35 ///
36 /// # Complexity
37 ///
38 /// The time complexity is typically O(log N) due to `BTreeMap` lookups and insertions,
39 /// where N is the number of disjoint ranges in the map. In scenarios involving merges,
40 /// a few extra map operations (removals, insertions) might occur, but the overall
41 /// complexity remains logarithmic.
42 ///
43 /// # Example
44 ///
45 /// ```
46 /// use commonware_storage::rmap::RMap;
47 ///
48 /// let mut map = RMap::new();
49 /// map.insert(1); // Map: [1, 1]
50 /// assert_eq!(map.next_gap(0), (None, Some(1)));
51 /// map.insert(3); // Map: [1, 1], [3, 3]
52 /// assert_eq!(map.next_gap(1), (Some(1), Some(3)));
53 /// map.insert(2); // Map: [1, 3]
54 /// map.insert(0); // Map: [0, 3]
55 /// map.insert(5); // Map: [0, 3], [5, 5]
56 /// map.insert(4); // Map: [0, 5]
57 /// assert_eq!(map.get(&3), Some((0, 5)));
58 /// ```
59 pub fn insert(&mut self, value: u64) {
60 let prev_opt = self
61 .ranges
62 .range(..=value)
63 .next_back()
64 .map(|(&s, &e)| (s, e));
65 let next_opt = match value {
66 u64::MAX => None,
67 _ => self.ranges.range(value + 1..).next().map(|(&s, &e)| (s, e)),
68 };
69
70 match (prev_opt, next_opt) {
71 (Some((p_start, p_end)), Some((n_start, n_end))) => {
72 if value <= p_end {
73 // Value is within prev range
74 return;
75 }
76 if value == p_end + 1 && value + 1 == n_start {
77 // Value bridges prev and next
78 self.ranges.remove(&p_start);
79 self.ranges.remove(&n_start);
80 self.ranges.insert(p_start, n_end);
81 } else if value == p_end + 1 {
82 // Value is adjacent to prev's end
83 self.ranges.remove(&p_start);
84 self.ranges.insert(p_start, value);
85 } else if value + 1 == n_start {
86 // Value is adjacent to next's start
87 self.ranges.remove(&n_start);
88 self.ranges.insert(value, n_end);
89 } else {
90 // New isolated range
91 self.ranges.insert(value, value);
92 }
93 }
94 (Some((p_start, p_end)), None) => {
95 if value <= p_end {
96 // Value is within prev range
97 return;
98 }
99 if value == p_end + 1 {
100 // Value is adjacent to prev's end
101 self.ranges.remove(&p_start);
102 self.ranges.insert(p_start, value);
103 } else {
104 // New isolated range
105 self.ranges.insert(value, value);
106 }
107 }
108 (None, Some((n_start, n_end))) => {
109 if value + 1 == n_start {
110 // Value is adjacent to next's start
111 self.ranges.remove(&n_start);
112 self.ranges.insert(value, n_end);
113 } else {
114 // New isolated range
115 self.ranges.insert(value, value);
116 }
117 }
118 (None, None) => {
119 // Map is empty or value is isolated
120 self.ranges.insert(value, value);
121 }
122 }
123 }
124
125 /// Returns the range that contains the given value.
126 pub fn get(&self, value: &u64) -> Option<(u64, u64)> {
127 if let Some((&start, &end)) = self.ranges.range(..=value).next_back() {
128 if *value <= end {
129 return Some((start, end));
130 }
131 }
132 None
133 }
134
135 /// Removes a range `[start, end]` (inclusive) from the [RMap].
136 ///
137 /// # Behavior
138 ///
139 /// - If the removal range completely covers an existing range, the existing range is removed.
140 /// - If the removal range is a sub-range of an existing range, the existing range may be split
141 /// into two (e.g., removing `[3, 4]` from `[1, 6]` results in `[1, 2]` and `[5, 6]`).
142 /// - If the removal range overlaps with the start or end of an existing range, the existing
143 /// range is truncated (e.g., removing `[1, 2]` from `[1, 5]` results in `[3, 5]`).
144 /// - If the removal range covers multiple existing ranges, all such ranges are affected or removed.
145 /// - If `start > end`, the method does nothing.
146 /// - If the removal range does not overlap with any existing range, the map remains unchanged.
147 ///
148 /// # Complexity
149 ///
150 /// The time complexity is O(M + K log N), where N is the total number of ranges in the map,
151 /// M is the number of ranges that overlap with the removal range (iterate part), and K is the number of
152 /// new ranges created or ranges removed (at most 2 additions and M removals).
153 ///
154 /// # Example
155 ///
156 /// ```
157 /// use commonware_storage::rmap::RMap;
158 ///
159 /// let mut map = RMap::new();
160 /// map.insert(1); map.insert(2); map.insert(3); // Map: [1, 3]
161 /// map.insert(5); map.insert(6); map.insert(7); // Map: [1, 3], [5, 7]
162 ///
163 /// map.remove(2, 6); // Results in [1, 1], [7, 7]
164 /// assert_eq!(map.get(&1), Some((1, 1)));
165 /// assert_eq!(map.get(&2), None);
166 /// assert_eq!(map.get(&6), None);
167 /// assert_eq!(map.get(&7), Some((7, 7)));
168 /// ```
169 pub fn remove(&mut self, start: u64, end: u64) {
170 if start > end {
171 return;
172 }
173
174 // Iterate over ranges that could possibly overlap with the removal range `[start, end]`.
175 // A range (r_start, r_end) overlaps if r_start <= end AND r_end >= start.
176 //
177 // We optimize the BTreeMap iteration by only looking at ranges whose start (r_start)
178 // is less than or equal to the `end` of the removal range. If r_start > end,
179 // then (r_start, r_end) cannot overlap with [start, end].
180 let mut to_add = Vec::new();
181 let mut to_remove = Vec::new();
182
183 for (&r_start, &r_end) in self.ranges.iter() {
184 // Case 1: No overlap
185 if r_end < start || r_start > end {
186 continue;
187 }
188
189 // Case 2: Removal range completely covers current range
190 if start <= r_start && end >= r_end {
191 to_remove.push(r_start);
192 continue;
193 }
194
195 // Case 3: Current range completely covers removal range (split)
196 if r_start < start && r_end > end {
197 to_remove.push(r_start);
198 to_add.push((r_start, start - 1));
199 to_add.push((end + 1, r_end));
200 continue;
201 }
202
203 // Case 4: Removal range overlaps start of current range
204 if start <= r_start && end < r_end {
205 // and end >= r_start implied by not Case 1
206 to_remove.push(r_start);
207 to_add.push((end + 1, r_end));
208 continue;
209 }
210
211 // Case 5: Removal range overlaps end of current range
212 if start > r_start && end >= r_end {
213 // and start <= r_end implied by not Case 1
214 to_remove.push(r_start);
215 to_add.push((r_start, start - 1));
216 continue;
217 }
218 }
219
220 // Remove anything no longer needed.
221 for r_start in to_remove {
222 self.ranges.remove(&r_start);
223 }
224
225 // Add anything that is now needed.
226 for (a_start, a_end) in to_add {
227 if a_start <= a_end {
228 // Ensure valid range before adding
229 self.ranges.insert(a_start, a_end);
230 }
231 }
232 }
233
234 /// Returns an iterator over the ranges `(start, end)` in the [RMap].
235 ///
236 /// The ranges are yielded in ascending order of their start points.
237 /// Each tuple represents an inclusive range `[start, end]`.
238 ///
239 /// # Example
240 ///
241 /// ```
242 /// use commonware_storage::rmap::RMap;
243 ///
244 /// let mut map = RMap::new();
245 /// map.insert(0); map.insert(1); // Map: [0, 1]
246 /// map.insert(3); map.insert(4); // Map: [0, 1], [3, 4]
247 ///
248 /// let mut iter = map.iter();
249 /// assert_eq!(iter.next(), Some((&0, &1)));
250 /// assert_eq!(iter.next(), Some((&3, &4)));
251 /// assert_eq!(iter.next(), None);
252 /// ```
253 pub fn iter(&self) -> impl Iterator<Item = (&u64, &u64)> {
254 self.ranges.iter()
255 }
256
257 /// Returns an iterator over ranges `(start, end)` that overlap or follow `from`.
258 ///
259 /// A range overlaps `from` if its end >= `from`. Ranges are yielded in
260 /// ascending order of their start points.
261 ///
262 /// # Example
263 ///
264 /// ```
265 /// use commonware_storage::rmap::RMap;
266 ///
267 /// let mut map = RMap::new();
268 /// map.insert(0); map.insert(1); // Map: [0, 1]
269 /// map.insert(3); map.insert(4); // Map: [0, 1], [3, 4]
270 /// map.insert(7); // Map: [0, 1], [3, 4], [7, 7]
271 ///
272 /// let v: Vec<_> = map.iter_from(2).collect();
273 /// assert_eq!(v, vec![(&3, &4), (&7, &7)]);
274 ///
275 /// let v: Vec<_> = map.iter_from(1).collect();
276 /// assert_eq!(v, vec![(&0, &1), (&3, &4), (&7, &7)]);
277 ///
278 /// let v: Vec<_> = map.iter_from(4).collect();
279 /// assert_eq!(v, vec![(&3, &4), (&7, &7)]);
280 /// ```
281 pub fn iter_from(&self, from: u64) -> impl Iterator<Item = (&u64, &u64)> {
282 // The last range whose start <= `from` might contain `from` (if its end >= `from`).
283 let candidate = self
284 .ranges
285 .range(..=from)
286 .next_back()
287 .filter(|(_, &end)| end >= from);
288
289 // All ranges starting after `from` are guaranteed to follow.
290 let tail = match from {
291 u64::MAX => None,
292 _ => Some(self.ranges.range(from + 1..)),
293 };
294 candidate.into_iter().chain(tail.into_iter().flatten())
295 }
296
297 /// Retrieve the first index in the [RMap].
298 ///
299 /// # Example
300 ///
301 /// ```
302 /// use commonware_storage::rmap::RMap;
303 ///
304 /// let mut map = RMap::new();
305 /// assert_eq!(map.first_index(), None);
306 /// map.insert(3); map.insert(4); // Map: [3, 4]
307 /// assert_eq!(map.first_index(), Some(3));
308 /// map.insert(1); // Map: [1, 1], [3, 4]
309 /// assert_eq!(map.first_index(), Some(1));
310 /// ```
311 pub fn first_index(&self) -> Option<u64> {
312 self.ranges.first_key_value().map(|(&start, _)| start)
313 }
314
315 /// Retrieve the last index in the [RMap].
316 ///
317 /// # Example
318 ///
319 /// ```
320 /// use commonware_storage::rmap::RMap;
321 ///
322 /// let mut map = RMap::new();
323 /// assert_eq!(map.last_index(), None);
324 /// map.insert(1); map.insert(2); // Map: [1, 2]
325 /// assert_eq!(map.last_index(), Some(2));
326 /// map.insert(5); // Map: [1, 2], [5, 5]
327 /// assert_eq!(map.last_index(), Some(5));
328 /// ```
329 pub fn last_index(&self) -> Option<u64> {
330 self.ranges.last_key_value().map(|(_, &end)| end)
331 }
332
333 /// Finds the end of the range containing `value` and the start of the
334 /// range succeeding `value`. This method is useful for identifying gaps around a given point.
335 ///
336 /// # Behavior
337 ///
338 /// - If `value` falls within an existing range `[r_start, r_end]`, `current_range_end` will be `Some(r_end)`.
339 /// - If `value` falls in a gap between two ranges `[..., prev_end]` and `[next_start, ...]`,
340 /// `current_range_end` will be `None` and `next_range_start` will be `Some(next_start)`.
341 /// - If `value` is before all ranges in the map, `current_range_end` will be `None`.
342 /// - If `value` is after all ranges in the map (or within the last range), `next_range_start` will be `None`.
343 /// - If the map is empty, both will be `None`.
344 ///
345 /// # Arguments
346 ///
347 /// * `value`: The `u64` value to query around.
348 ///
349 /// # Returns
350 ///
351 /// A tuple `(Option<u64>, Option<u64>)` where:
352 /// - The first element (`current_range_end`) is `Some(end)` of the range that contains `value`. It's `None` if `value` is before all ranges, the map is empty, or `value` is not in any range.
353 /// - The second element (`next_range_start`) is `Some(start)` of the first range that begins strictly after `value`. It's `None` if no range starts after `value` or the map is empty.
354 ///
355 /// # Complexity
356 ///
357 /// O(log N) where N is the number of ranges in [RMap].
358 ///
359 /// # Example
360 ///
361 /// ```
362 /// use commonware_storage::rmap::RMap;
363 ///
364 /// let mut map = RMap::new();
365 /// map.insert(1); map.insert(2); // Map: [1, 2]
366 /// map.insert(5); map.insert(6); // Map: [1, 2], [5, 6]
367 ///
368 /// assert_eq!(map.next_gap(0), (None, Some(1))); // Before all ranges
369 /// assert_eq!(map.next_gap(1), (Some(2), Some(5))); // Value is at the start of a range
370 /// assert_eq!(map.next_gap(2), (Some(2), Some(5))); // Value is at the end of a range
371 /// assert_eq!(map.next_gap(3), (None, Some(5))); // Value is in a gap
372 /// assert_eq!(map.next_gap(5), (Some(6), None)); // Value is at the start of the last range
373 /// assert_eq!(map.next_gap(6), (Some(6), None)); // Value is at the end of the last range
374 /// assert_eq!(map.next_gap(7), (None, None)); // After all ranges
375 /// ```
376 pub fn next_gap(&self, value: u64) -> (Option<u64>, Option<u64>) {
377 let current_range_end = match self.ranges.range(..=value).next_back().map(|(_, &end)| end) {
378 Some(end) if end >= value => Some(end),
379 _ => None,
380 };
381
382 let next_range_start = match value {
383 u64::MAX => None,
384 _ => self
385 .ranges
386 .range(value + 1..)
387 .next()
388 .map(|(&start, _)| start),
389 };
390
391 (current_range_end, next_range_start)
392 }
393
394 /// Returns up to `max` missing items starting from `start`.
395 ///
396 /// This method iterates through gaps between existing ranges, collecting missing indices
397 /// until either `max` items are found or there are no more gaps to fill.
398 ///
399 /// # Arguments
400 ///
401 /// * `start`: The index to start searching from (inclusive).
402 /// * `max`: The maximum number of missing items to return.
403 ///
404 /// # Returns
405 ///
406 /// A vector containing up to `max` missing indices from gaps between ranges.
407 /// The vector may contain fewer than `max` items if there aren't enough gaps.
408 /// If there are no more ranges after the current position, no items are returned.
409 ///
410 /// # Complexity
411 ///
412 /// O(G log N + M) where N is the number of ranges in [RMap], G is the number of gaps
413 /// visited (at most N), and M is the number of missing items returned (at most `max`).
414 /// Each gap requires a `next_gap` call (O(log N)) and collecting items (O(items in gap)).
415 ///
416 /// # Example
417 ///
418 /// ```
419 /// use commonware_storage::rmap::RMap;
420 ///
421 /// let mut map = RMap::new();
422 /// map.insert(1); map.insert(2); // Map: [1, 2]
423 /// map.insert(5); map.insert(6); // Map: [1, 2], [5, 6]
424 /// map.insert(10); // Map: [1, 2], [5, 6], [10, 10]
425 ///
426 /// // Starting from 0, find up to 5 missing items
427 /// assert_eq!(map.missing_items(0, 5), vec![0, 3, 4, 7, 8]);
428 ///
429 /// // Starting from 3, find up to 3 missing items
430 /// assert_eq!(map.missing_items(3, 3), vec![3, 4, 7]);
431 ///
432 /// // Starting from 7, find up to 10 missing items (only gaps are returned)
433 /// assert_eq!(map.missing_items(7, 10), vec![7, 8, 9]);
434 ///
435 /// // Starting from 11, there are no more ranges, so no gaps
436 /// assert_eq!(map.missing_items(11, 5), Vec::<u64>::new());
437 /// ```
438 pub fn missing_items(&self, start: u64, max: usize) -> Vec<u64> {
439 // Ensure input is valid
440 assert!(max > 0, "max must be greater than 0");
441 let mut current = start;
442
443 // Collect missing items
444 let mut missing = Vec::with_capacity(max);
445 loop {
446 // If we're inside a range, skip to just after it
447 let (current_range_end, next_range_start) = self.next_gap(current);
448 if let Some(end) = current_range_end {
449 // Check if we can move past this range
450 if end == u64::MAX {
451 break missing; // No gaps possible after u64::MAX
452 }
453 current = end + 1;
454 continue;
455 }
456
457 // We're in a gap - check if there's a next range
458 let Some(next_start) = next_range_start else {
459 break missing; // No more ranges, so no more gaps to fill
460 };
461
462 // Collect items from this gap until we hit the next range or have enough
463 let gap_end = next_start - 1; // next_start must be greater than or equal to 1
464 let items_needed = max - missing.len(); // there must be at least one item to collect
465 let gap_end = gap_end.min(current.saturating_add(items_needed as u64 - 1));
466 for index in current..=gap_end {
467 missing.push(index);
468 }
469
470 // If we have enough items, break
471 if missing.len() >= max {
472 break missing;
473 }
474
475 // Move to the start of the next range to check for more gaps
476 current = next_start;
477 }
478 }
479}
480
481#[cfg(test)]
482mod tests {
483 use super::*;
484
485 #[test]
486 fn test_new() {
487 let map = RMap::new();
488 assert_eq!(map.iter().count(), 0);
489 }
490
491 #[test]
492 fn test_insert_empty() {
493 let mut map = RMap::new();
494 map.insert(5);
495 assert_eq!(map.get(&5), Some((5, 5)));
496 assert_eq!(map.iter().collect::<Vec<_>>(), vec![(&5, &5)]);
497 }
498
499 #[test]
500 fn test_insert_isolated() {
501 let mut map = RMap::new();
502 map.insert(5);
503 map.insert(10);
504 assert_eq!(map.get(&5), Some((5, 5)));
505 assert_eq!(map.get(&10), Some((10, 10)));
506 assert_eq!(map.iter().collect::<Vec<_>>(), vec![(&5, &5), (&10, &10)]);
507 }
508
509 #[test]
510 fn test_insert_covered() {
511 let mut map = RMap::new();
512 map.insert(1);
513 map.insert(2);
514 map.insert(3); // Range is 1-3
515 map.insert(2); // Insert value already covered
516 assert_eq!(map.get(&1), Some((1, 3)));
517 assert_eq!(map.get(&2), Some((1, 3)));
518 assert_eq!(map.get(&3), Some((1, 3)));
519 assert_eq!(map.iter().count(), 1);
520 assert_eq!(map.iter().next(), Some((&1, &3)));
521 }
522
523 #[test]
524 fn test_insert_adjacent_end() {
525 let mut map = RMap::new();
526 map.insert(1);
527 map.insert(2); // Range is 1-2
528 map.insert(3); // Adjacent to end
529 assert_eq!(map.get(&1), Some((1, 3)));
530 assert_eq!(map.get(&3), Some((1, 3)));
531 assert_eq!(map.iter().next(), Some((&1, &3)));
532 }
533
534 #[test]
535 fn test_insert_adjacent_start() {
536 let mut map = RMap::new();
537 map.insert(2);
538 map.insert(3); // Range is 2-3
539 map.insert(1); // Adjacent to start
540 assert_eq!(map.get(&1), Some((1, 3)));
541 assert_eq!(map.get(&3), Some((1, 3)));
542 assert_eq!(map.iter().next(), Some((&1, &3)));
543 }
544
545 #[test]
546 fn test_insert_bridge_ranges() {
547 let mut map = RMap::new();
548 map.insert(1);
549 map.insert(2);
550 assert_eq!(map.get(&1), Some((1, 2)));
551 map.insert(5);
552 map.insert(6);
553 assert_eq!(map.get(&5), Some((5, 6)));
554 // Current: (1,2), (5,6)
555 map.insert(3); // Insert 3, should become (1,3), (5,6)
556 assert_eq!(map.get(&1), Some((1, 3)));
557 assert_eq!(map.get(&2), Some((1, 3)));
558 assert_eq!(map.get(&3), Some((1, 3)));
559 assert_eq!(map.get(&5), Some((5, 6)));
560 assert_eq!(map.iter().collect::<Vec<_>>(), vec![(&1, &3), (&5, &6)]);
561
562 map.insert(4); // Insert 4, should bridge to (1,6)
563 assert_eq!(map.get(&1), Some((1, 6)));
564 assert_eq!(map.get(&3), Some((1, 6)));
565 assert_eq!(map.get(&4), Some((1, 6)));
566 assert_eq!(map.get(&6), Some((1, 6)));
567 assert_eq!(map.iter().count(), 1);
568 assert_eq!(map.iter().next(), Some((&1, &6)));
569 }
570
571 #[test]
572 fn test_insert_complex_merging_and_ordering() {
573 let mut map = RMap::new();
574 map.insert(10); // (10,10)
575 map.insert(12); // (10,10), (12,12)
576 map.insert(11); // (10,12)
577 assert_eq!(map.get(&10), Some((10, 12)));
578 assert_eq!(map.get(&11), Some((10, 12)));
579 assert_eq!(map.get(&12), Some((10, 12)));
580
581 map.insert(15); // (10,12), (15,15)
582 map.insert(13); // (10,13), (15,15)
583 assert_eq!(map.get(&13), Some((10, 13)));
584 assert_eq!(map.get(&12), Some((10, 13)));
585 assert_eq!(map.get(&15), Some((15, 15)));
586
587 map.insert(14); // (10,15)
588 assert_eq!(map.get(&10), Some((10, 15)));
589 assert_eq!(map.get(&14), Some((10, 15)));
590 assert_eq!(map.get(&15), Some((10, 15)));
591 assert_eq!(map.iter().count(), 1);
592 assert_eq!(map.iter().next(), Some((&10, &15)));
593
594 map.insert(5); // (5,5), (10,15)
595 map.insert(7); // (5,5), (7,7), (10,15)
596 map.insert(6); // (5,7), (10,15)
597 assert_eq!(map.get(&5), Some((5, 7)));
598 assert_eq!(map.get(&6), Some((5, 7)));
599 assert_eq!(map.get(&7), Some((5, 7)));
600 assert_eq!(map.iter().collect::<Vec<_>>(), vec![(&5, &7), (&10, &15)]);
601
602 map.insert(9); // (5,7), (9,9), (10,15) -> should become (5,7), (9,15)
603 assert_eq!(map.get(&9), Some((9, 15)));
604 assert_eq!(map.get(&10), Some((9, 15)));
605 assert_eq!(map.iter().collect::<Vec<_>>(), vec![(&5, &7), (&9, &15)]);
606
607 map.insert(8); // (5,15)
608 assert_eq!(map.get(&5), Some((5, 15)));
609 assert_eq!(map.get(&8), Some((5, 15)));
610 assert_eq!(map.get(&15), Some((5, 15)));
611 assert_eq!(map.iter().next(), Some((&5, &15)));
612 }
613
614 #[test]
615 fn test_insert_max_value() {
616 let mut map = RMap::new();
617 map.insert(u64::MAX);
618 assert_eq!(map.get(&u64::MAX), Some((u64::MAX, u64::MAX)));
619 map.insert(u64::MAX - 1);
620 assert_eq!(map.get(&(u64::MAX - 1)), Some((u64::MAX - 1, u64::MAX)));
621 assert_eq!(map.get(&u64::MAX), Some((u64::MAX - 1, u64::MAX)));
622 }
623
624 #[test]
625 fn test_get() {
626 let mut map = RMap::new();
627 map.insert(1);
628 map.insert(2);
629 map.insert(3); // Range 1-3
630 map.insert(5);
631 map.insert(6); // Range 5-6
632
633 assert_eq!(map.get(&1), Some((1, 3)));
634 assert_eq!(map.get(&2), Some((1, 3)));
635 assert_eq!(map.get(&3), Some((1, 3)));
636 assert_eq!(map.get(&4), None);
637 assert_eq!(map.get(&5), Some((5, 6)));
638 assert_eq!(map.get(&6), Some((5, 6)));
639 assert_eq!(map.get(&0), None);
640 assert_eq!(map.get(&7), None);
641 }
642
643 #[test]
644 fn test_remove_empty() {
645 let mut map = RMap::new();
646 map.remove(1, 5);
647 assert_eq!(map.iter().count(), 0);
648 }
649
650 #[test]
651 fn test_remove_invalid_range() {
652 let mut map = RMap::new();
653 map.insert(1);
654 map.insert(2); // 1-2
655 map.remove(5, 1); // start > end, should do nothing
656 assert_eq!(map.iter().next(), Some((&1, &2)));
657 }
658
659 #[test]
660 fn test_remove_non_existent() {
661 let mut map = RMap::new();
662 map.insert(5);
663 map.insert(6); // 5-6
664 map.remove(1, 3); // Before existing
665 assert_eq!(map.iter().next(), Some((&5, &6)));
666 map.remove(8, 10); // After existing
667 assert_eq!(map.iter().next(), Some((&5, &6)));
668 map.remove(1, 10); // Covers existing
669 assert_eq!(map.iter().count(), 0);
670 }
671
672 #[test]
673 fn test_remove_exact_match() {
674 let mut map = RMap::new();
675 map.insert(1);
676 map.insert(2);
677 map.insert(3); // 1-3
678 map.insert(5);
679 map.insert(6); // 5-6
680 map.remove(1, 3);
681 assert_eq!(map.get(&2), None);
682 assert_eq!(map.iter().next(), Some((&5, &6)));
683 map.remove(5, 6);
684 assert_eq!(map.iter().count(), 0);
685 }
686
687 #[test]
688 fn test_remove_subset_split() {
689 let mut map = RMap::new();
690 map.insert(1);
691 map.insert(2);
692 map.insert(3);
693 map.insert(4);
694 map.insert(5); // 1-5
695 map.remove(3, 3); // Remove 3 from 1-5 -> (1,2), (4,5)
696 assert_eq!(map.get(&2), Some((1, 2)));
697 assert_eq!(map.get(&3), None);
698 assert_eq!(map.get(&4), Some((4, 5)));
699 assert_eq!(map.iter().collect::<Vec<_>>(), vec![(&1, &2), (&4, &5)]);
700
701 // Reset and test another split
702 let mut map2 = RMap::new();
703 map2.insert(1);
704 map2.insert(2);
705 map2.insert(3);
706 map2.insert(4);
707 map2.insert(5); // 1-5
708 map2.remove(2, 4); // Remove 2-4 from 1-5 -> (1,1), (5,5)
709 assert_eq!(map2.get(&1), Some((1, 1)));
710 assert_eq!(map2.get(&2), None);
711 assert_eq!(map2.get(&3), None);
712 assert_eq!(map2.get(&4), None);
713 assert_eq!(map2.get(&5), Some((5, 5)));
714 assert_eq!(map2.iter().collect::<Vec<_>>(), vec![(&1, &1), (&5, &5)]);
715 }
716
717 #[test]
718 fn test_remove_overlap_start() {
719 let mut map = RMap::new();
720 map.insert(1);
721 map.insert(2);
722 map.insert(3);
723 map.insert(4);
724 map.insert(5); // 1-5
725 map.remove(0, 2); // Remove 0-2 from 1-5 -> (3,5)
726 assert_eq!(map.get(&1), None);
727 assert_eq!(map.get(&2), None);
728 assert_eq!(map.get(&3), Some((3, 5)));
729 assert_eq!(map.iter().next(), Some((&3, &5)));
730 }
731
732 #[test]
733 fn test_remove_overlap_end() {
734 let mut map = RMap::new();
735 map.insert(1);
736 map.insert(2);
737 map.insert(3);
738 map.insert(4);
739 map.insert(5); // 1-5
740 map.remove(4, 6); // Remove 4-6 from 1-5 -> (1,3)
741 assert_eq!(map.get(&3), Some((1, 3)));
742 assert_eq!(map.get(&4), None);
743 assert_eq!(map.get(&5), None);
744 assert_eq!(map.iter().next(), Some((&1, &3)));
745 }
746
747 #[test]
748 fn test_remove_cover_multiple_ranges() {
749 let mut map = RMap::new();
750 map.insert(1);
751 map.insert(2); // 1-2
752 map.insert(4);
753 map.insert(5); // 4-5
754 map.insert(7);
755 map.insert(8); // 7-8
756
757 map.remove(3, 6); // Removes 4-5, no truncation as 3 and 6 are in gaps. (1,2), (7,8)
758 assert_eq!(map.get(&2), Some((1, 2)));
759 assert_eq!(map.get(&4), None);
760 assert_eq!(map.get(&5), None);
761 assert_eq!(map.get(&7), Some((7, 8)));
762 assert_eq!(map.iter().collect::<Vec<_>>(), vec![(&1, &2), (&7, &8)]);
763
764 map.remove(0, 10); // Removes all remaining ranges
765 assert_eq!(map.iter().count(), 0);
766 }
767
768 #[test]
769 fn test_remove_partial_overlap_multiple_ranges() {
770 let mut map = RMap::new();
771 map.insert(1);
772 map.insert(2);
773 map.insert(3); // 1-3
774 map.insert(5);
775 map.insert(6);
776 map.insert(7); // 5-7
777 map.insert(9);
778 map.insert(10);
779 map.insert(11); // 9-11
780
781 map.remove(2, 6); // Affects 1-3 (becomes 1-1) and 5-7 (becomes 7-7)
782 assert_eq!(map.get(&1), Some((1, 1)));
783 assert_eq!(map.get(&2), None);
784 assert_eq!(map.get(&3), None);
785 assert_eq!(map.get(&5), None);
786 assert_eq!(map.get(&6), None);
787 assert_eq!(map.get(&7), Some((7, 7)));
788 assert_eq!(map.get(&9), Some((9, 11)));
789 assert_eq!(
790 map.iter().collect::<Vec<_>>(),
791 vec![(&1, &1), (&7, &7), (&9, &11)]
792 );
793
794 // Reset and test removing all
795 let mut map2 = RMap::new();
796 map2.insert(1);
797 map2.insert(2);
798 map2.insert(3);
799 map2.insert(5);
800 map2.insert(6);
801 map2.insert(7);
802 map2.insert(9);
803 map2.insert(10);
804 map2.insert(11);
805 map2.remove(0, 20); // remove all
806 assert_eq!(map2.iter().count(), 0);
807 }
808
809 #[test]
810 fn test_remove_touching_boundaries_no_merge() {
811 let mut map = RMap::new();
812 map.insert(0);
813 map.insert(1);
814 map.insert(2); // 0-2
815 map.insert(4);
816 map.insert(5); // 4-5
817
818 // Remove range that is exactly between two existing ranges
819 map.remove(3, 3);
820 assert_eq!(map.iter().collect::<Vec<_>>(), vec![(&0, &2), (&4, &5)]);
821 }
822
823 #[test]
824 fn test_remove_max_value_ranges() {
825 let mut map = RMap::new();
826 map.insert(u64::MAX - 2);
827 map.insert(u64::MAX - 1);
828 map.insert(u64::MAX); // MAX-2 to MAX
829
830 map.remove(u64::MAX, u64::MAX); // Remove MAX -> (MAX-2, MAX-1)
831 assert_eq!(map.get(&(u64::MAX - 2)), Some((u64::MAX - 2, u64::MAX - 1)));
832 assert_eq!(map.get(&u64::MAX), None);
833
834 map.remove(u64::MAX - 2, u64::MAX - 2); // Remove MAX-2 -> (MAX-1, MAX-1)
835 assert_eq!(map.get(&(u64::MAX - 2)), None);
836 assert_eq!(map.get(&(u64::MAX - 1)), Some((u64::MAX - 1, u64::MAX - 1)));
837
838 map.remove(u64::MAX - 1, u64::MAX - 1); // Remove MAX-1 -> empty
839 assert_eq!(map.iter().count(), 0);
840
841 map.insert(u64::MAX - 1);
842 map.insert(u64::MAX); // MAX-1 to MAX
843 map.remove(u64::MIN, u64::MAX); // Remove all
844 assert_eq!(map.iter().count(), 0);
845 }
846
847 #[test]
848 fn test_iter() {
849 let mut map = RMap::new();
850 assert_eq!(map.iter().next(), None);
851 map.insert(5);
852 map.insert(6); // 5-6
853 map.insert(1);
854 map.insert(2); // 1-2
855 let mut iter = map.iter();
856 assert_eq!(iter.next(), Some((&1, &2)));
857 assert_eq!(iter.next(), Some((&5, &6)));
858 assert_eq!(iter.next(), None);
859 }
860
861 #[test]
862 fn test_first_index() {
863 let mut map = RMap::new();
864 assert_eq!(map.first_index(), None);
865
866 map.insert(5);
867 map.insert(6); // [5, 6]
868 assert_eq!(map.first_index(), Some(5));
869
870 map.insert(1); // [1, 1], [5, 6]
871 assert_eq!(map.first_index(), Some(1));
872
873 map.remove(0, 4); // [5, 6]
874 assert_eq!(map.first_index(), Some(5));
875
876 map.remove(5, 6); // empty
877 assert_eq!(map.first_index(), None);
878 }
879
880 #[test]
881 fn test_last_index() {
882 let mut map = RMap::new();
883 assert_eq!(map.last_index(), None);
884
885 map.insert(1);
886 map.insert(2); // [1, 2]
887 assert_eq!(map.last_index(), Some(2));
888
889 map.insert(5); // [1, 2], [5, 5]
890 assert_eq!(map.last_index(), Some(5));
891
892 map.insert(6); // [1, 2], [5, 6]
893 assert_eq!(map.last_index(), Some(6));
894
895 map.remove(5, 10); // [1, 2]
896 assert_eq!(map.last_index(), Some(2));
897
898 map.remove(0, 2); // empty
899 assert_eq!(map.last_index(), None);
900 }
901
902 #[test]
903 fn test_next_gap_empty() {
904 let map = RMap::new();
905 assert_eq!(map.next_gap(5), (None, None));
906 }
907
908 #[test]
909 fn test_next_gap_single_range() {
910 let mut map = RMap::new();
911 map.insert(5);
912 map.insert(6);
913 map.insert(7); // 5-7
914 assert_eq!(map.next_gap(4), (None, Some(5))); // Before range
915 assert_eq!(map.next_gap(5), (Some(7), None)); // Start of range
916 assert_eq!(map.next_gap(6), (Some(7), None)); // Middle of range
917 assert_eq!(map.next_gap(7), (Some(7), None)); // End of range
918 assert_eq!(map.next_gap(8), (None, None)); // After range
919 }
920
921 #[test]
922 fn test_next_gap_multiple_ranges() {
923 let mut map = RMap::new();
924 map.insert(1);
925 map.insert(2); // 1-2
926 map.insert(5);
927 map.insert(6); // 5-6
928 map.insert(10); // 10-10
929
930 assert_eq!(map.next_gap(0), (None, Some(1))); // Before all
931 assert_eq!(map.next_gap(1), (Some(2), Some(5))); // Start of first range
932 assert_eq!(map.next_gap(2), (Some(2), Some(5))); // End of first range
933 assert_eq!(map.next_gap(3), (None, Some(5))); // Gap between 1st and 2nd
934 assert_eq!(map.next_gap(4), (None, Some(5))); // Gap, closer to 2nd
935 assert_eq!(map.next_gap(5), (Some(6), Some(10))); // Start of 2nd range
936 assert_eq!(map.next_gap(6), (Some(6), Some(10))); // End of 2nd range
937 assert_eq!(map.next_gap(7), (None, Some(10))); // Gap between 2nd and 3rd
938 assert_eq!(map.next_gap(8), (None, Some(10))); // Gap
939 assert_eq!(map.next_gap(9), (None, Some(10))); // Gap, closer to 3rd
940 assert_eq!(map.next_gap(10), (Some(10), None)); // Start/End of 3rd range
941 assert_eq!(map.next_gap(11), (None, None)); // After all
942 }
943
944 #[test]
945 fn test_next_gap_value_is_max() {
946 let mut map = RMap::new();
947 map.insert(u64::MAX - 5);
948 map.insert(u64::MAX - 4); // MAX-5 to MAX-4
949 map.insert(u64::MAX - 1);
950 map.insert(u64::MAX); // MAX-1 to MAX
951
952 assert_eq!(map.next_gap(u64::MAX - 6), (None, Some(u64::MAX - 5)));
953 assert_eq!(
954 map.next_gap(u64::MAX - 5),
955 (Some(u64::MAX - 4), Some(u64::MAX - 1))
956 );
957 assert_eq!(
958 map.next_gap(u64::MAX - 4),
959 (Some(u64::MAX - 4), Some(u64::MAX - 1))
960 );
961 assert_eq!(map.next_gap(u64::MAX - 3), (None, Some(u64::MAX - 1))); // In gap
962 assert_eq!(map.next_gap(u64::MAX - 2), (None, Some(u64::MAX - 1))); // In gap
963 assert_eq!(map.next_gap(u64::MAX - 1), (Some(u64::MAX), None));
964 assert_eq!(map.next_gap(u64::MAX), (Some(u64::MAX), None));
965 }
966
967 #[test]
968 fn test_odd_ranges() {
969 // Insert values
970 let mut map = RMap::new();
971 map.insert(1);
972 map.insert(10);
973 map.insert(11);
974 map.insert(14);
975
976 // Sanity check next_gap
977 assert_eq!(map.next_gap(0), (None, Some(1)));
978 assert_eq!(map.next_gap(1), (Some(1), Some(10)));
979 assert_eq!(map.next_gap(10), (Some(11), Some(14)));
980 assert_eq!(map.next_gap(11), (Some(11), Some(14)));
981 assert_eq!(map.next_gap(12), (None, Some(14)));
982 assert_eq!(map.next_gap(14), (Some(14), None));
983 }
984
985 #[test]
986 fn test_missing_items_empty_map() {
987 let map = RMap::new();
988 assert_eq!(map.missing_items(0, 5), Vec::<u64>::new());
989 assert_eq!(map.missing_items(100, 10), Vec::<u64>::new());
990 }
991
992 #[test]
993 fn test_missing_items_single_gap() {
994 let mut map = RMap::new();
995 map.insert(1);
996 map.insert(2); // [1, 2]
997 map.insert(5);
998 map.insert(6); // [1, 2], [5, 6]
999
1000 // Gap between ranges: 3, 4
1001 assert_eq!(map.missing_items(3, 5), vec![3, 4]);
1002 assert_eq!(map.missing_items(3, 2), vec![3, 4]);
1003 assert_eq!(map.missing_items(3, 1), vec![3]);
1004 assert_eq!(map.missing_items(4, 1), vec![4]);
1005 }
1006
1007 #[test]
1008 fn test_missing_items_multiple_gaps() {
1009 let mut map = RMap::new();
1010 map.insert(1);
1011 map.insert(2); // [1, 2]
1012 map.insert(5);
1013 map.insert(6); // [1, 2], [5, 6]
1014 map.insert(10); // [1, 2], [5, 6], [10, 10]
1015
1016 // Starting from 0 (before first range)
1017 assert_eq!(map.missing_items(0, 5), vec![0, 3, 4, 7, 8]);
1018 assert_eq!(map.missing_items(0, 6), vec![0, 3, 4, 7, 8, 9]);
1019 assert_eq!(map.missing_items(0, 7), vec![0, 3, 4, 7, 8, 9]);
1020
1021 // Starting from within first gap
1022 assert_eq!(map.missing_items(3, 3), vec![3, 4, 7]);
1023 assert_eq!(map.missing_items(4, 2), vec![4, 7]);
1024
1025 // Starting from within second gap
1026 assert_eq!(map.missing_items(7, 10), vec![7, 8, 9]);
1027 assert_eq!(map.missing_items(8, 2), vec![8, 9]);
1028
1029 // Starting after last range (no more gaps)
1030 assert_eq!(map.missing_items(11, 5), Vec::<u64>::new());
1031 assert_eq!(map.missing_items(100, 10), Vec::<u64>::new());
1032 }
1033
1034 #[test]
1035 fn test_missing_items_starting_in_range() {
1036 let mut map = RMap::new();
1037 map.insert(1);
1038 map.insert(2);
1039 map.insert(3); // [1, 3]
1040 map.insert(7);
1041 map.insert(8);
1042 map.insert(9); // [1, 3], [7, 9]
1043
1044 // Starting within first range
1045 assert_eq!(map.missing_items(1, 3), vec![4, 5, 6]);
1046 assert_eq!(map.missing_items(2, 4), vec![4, 5, 6]);
1047 assert_eq!(map.missing_items(3, 2), vec![4, 5]);
1048
1049 // Starting within second range
1050 assert_eq!(map.missing_items(7, 5), Vec::<u64>::new());
1051 assert_eq!(map.missing_items(8, 3), Vec::<u64>::new());
1052 assert_eq!(map.missing_items(9, 1), Vec::<u64>::new());
1053 }
1054
1055 #[test]
1056 #[should_panic]
1057 fn test_missing_items_zero_n() {
1058 let mut map = RMap::new();
1059 map.insert(1);
1060 map.insert(5);
1061
1062 map.missing_items(1, 0);
1063 }
1064
1065 #[test]
1066 fn test_missing_items_large_gap() {
1067 let mut map = RMap::new();
1068 map.insert(1);
1069 map.insert(1000);
1070
1071 // Large gap between 1 and 1000
1072 assert_eq!(map.missing_items(2, 5), vec![2, 3, 4, 5, 6]);
1073 assert_eq!(map.missing_items(995, 5), vec![995, 996, 997, 998, 999]);
1074
1075 // Request more items than exist in gap
1076 let items = map.missing_items(2, 998);
1077 assert_eq!(items.len(), 998);
1078 assert_eq!(items[0], 2);
1079 assert_eq!(items[997], 999);
1080 }
1081
1082 #[test]
1083 fn test_missing_items_at_boundaries() {
1084 let mut map = RMap::new();
1085 map.insert(5);
1086 map.insert(6); // [5, 6]
1087 map.insert(10); // [5, 6], [10, 10]
1088
1089 // Starting at exact boundary of range start
1090 assert_eq!(map.missing_items(5, 3), vec![7, 8, 9]);
1091
1092 // Starting at exact boundary of range end
1093 assert_eq!(map.missing_items(6, 3), vec![7, 8, 9]);
1094
1095 // Starting at isolated range
1096 assert_eq!(map.missing_items(10, 5), Vec::<u64>::new());
1097 }
1098
1099 #[test]
1100 fn test_missing_items_near_max() {
1101 let mut map = RMap::new();
1102 map.insert(u64::MAX - 5);
1103 map.insert(u64::MAX - 3);
1104 map.insert(u64::MAX);
1105
1106 // Gap: MAX-4, MAX-2, MAX-1
1107 assert_eq!(
1108 map.missing_items(u64::MAX - 6, 5),
1109 vec![u64::MAX - 6, u64::MAX - 4, u64::MAX - 2, u64::MAX - 1]
1110 );
1111 assert_eq!(
1112 map.missing_items(u64::MAX - 4, 3),
1113 vec![u64::MAX - 4, u64::MAX - 2, u64::MAX - 1]
1114 );
1115
1116 // Starting at MAX (no gaps possible)
1117 assert_eq!(map.missing_items(u64::MAX, 5), Vec::<u64>::new());
1118 }
1119
1120 #[test]
1121 fn test_missing_items_range_ending_at_max() {
1122 let mut map = RMap::new();
1123 map.insert(u64::MAX - 2);
1124 map.insert(u64::MAX - 1);
1125 map.insert(u64::MAX); // [MAX-2, MAX]
1126
1127 assert_eq!(map.missing_items(u64::MAX - 2, 3), Vec::<u64>::new());
1128 assert_eq!(map.missing_items(u64::MAX - 1, 3), Vec::<u64>::new());
1129 assert_eq!(map.missing_items(u64::MAX, 3), Vec::<u64>::new());
1130 }
1131
1132 #[test]
1133 fn test_missing_items_contiguous_ranges() {
1134 let mut map = RMap::new();
1135 map.insert(1);
1136 map.insert(2);
1137 map.insert(3); // [1, 3]
1138 map.insert(4);
1139 map.insert(5);
1140 map.insert(6); // [1, 6] (merged)
1141
1142 // No gaps in contiguous range
1143 assert_eq!(map.missing_items(0, 3), vec![0]);
1144 assert_eq!(map.missing_items(7, 5), Vec::<u64>::new());
1145 }
1146}