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    /// Retrieve the first index in the [RMap].
258    ///
259    /// # Example
260    ///
261    /// ```
262    /// use commonware_storage::rmap::RMap;
263    ///
264    /// let mut map = RMap::new();
265    /// assert_eq!(map.first_index(), None);
266    /// map.insert(3); map.insert(4); // Map: [3, 4]
267    /// assert_eq!(map.first_index(), Some(3));
268    /// map.insert(1); // Map: [1, 1], [3, 4]
269    /// assert_eq!(map.first_index(), Some(1));
270    /// ```
271    pub fn first_index(&self) -> Option<u64> {
272        self.ranges.first_key_value().map(|(&start, _)| start)
273    }
274
275    /// Retrieve the last index in the [RMap].
276    ///
277    /// # Example
278    ///
279    /// ```
280    /// use commonware_storage::rmap::RMap;
281    ///
282    /// let mut map = RMap::new();
283    /// assert_eq!(map.last_index(), None);
284    /// map.insert(1); map.insert(2); // Map: [1, 2]
285    /// assert_eq!(map.last_index(), Some(2));
286    /// map.insert(5); // Map: [1, 2], [5, 5]
287    /// assert_eq!(map.last_index(), Some(5));
288    /// ```
289    pub fn last_index(&self) -> Option<u64> {
290        self.ranges.last_key_value().map(|(_, &end)| end)
291    }
292
293    /// Finds the end of the range containing `value` and the start of the
294    /// range succeeding `value`. This method is useful for identifying gaps around a given point.
295    ///
296    /// # Behavior
297    ///
298    /// - If `value` falls within an existing range `[r_start, r_end]`, `current_range_end` will be `Some(r_end)`.
299    /// - If `value` falls in a gap between two ranges `[..., prev_end]` and `[next_start, ...]`,
300    ///   `current_range_end` will be `None` and `next_range_start` will be `Some(next_start)`.
301    /// - If `value` is before all ranges in the map, `current_range_end` will be `None`.
302    /// - If `value` is after all ranges in the map (or within the last range), `next_range_start` will be `None`.
303    /// - If the map is empty, both will be `None`.
304    ///
305    /// # Arguments
306    ///
307    /// * `value`: The `u64` value to query around.
308    ///
309    /// # Returns
310    ///
311    /// A tuple `(Option<u64>, Option<u64>)` where:
312    /// - 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.
313    /// - 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.
314    ///
315    /// # Complexity
316    ///
317    /// O(log N) where N is the number of ranges in [RMap].
318    ///
319    /// # Example
320    ///
321    /// ```
322    /// use commonware_storage::rmap::RMap;
323    ///
324    /// let mut map = RMap::new();
325    /// map.insert(1); map.insert(2); // Map: [1, 2]
326    /// map.insert(5); map.insert(6); // Map: [1, 2], [5, 6]
327    ///
328    /// assert_eq!(map.next_gap(0), (None, Some(1)));        // Before all ranges
329    /// assert_eq!(map.next_gap(1), (Some(2), Some(5)));     // Value is at the start of a range
330    /// assert_eq!(map.next_gap(2), (Some(2), Some(5)));     // Value is at the end of a range
331    /// assert_eq!(map.next_gap(3), (None, Some(5)));     // Value is in a gap
332    /// assert_eq!(map.next_gap(5), (Some(6), None));        // Value is at the start of the last range
333    /// assert_eq!(map.next_gap(6), (Some(6), None));        // Value is at the end of the last range
334    /// assert_eq!(map.next_gap(7), (None, None));        // After all ranges
335    /// ```
336    pub fn next_gap(&self, value: u64) -> (Option<u64>, Option<u64>) {
337        let current_range_end = match self.ranges.range(..=value).next_back().map(|(_, &end)| end) {
338            Some(end) if end >= value => Some(end),
339            _ => None,
340        };
341
342        let next_range_start = match value {
343            u64::MAX => None,
344            _ => self
345                .ranges
346                .range(value + 1..)
347                .next()
348                .map(|(&start, _)| start),
349        };
350
351        (current_range_end, next_range_start)
352    }
353
354    /// Returns up to `max` missing items starting from `start`.
355    ///
356    /// This method iterates through gaps between existing ranges, collecting missing indices
357    /// until either `max` items are found or there are no more gaps to fill.
358    ///
359    /// # Arguments
360    ///
361    /// * `start`: The index to start searching from (inclusive).
362    /// * `max`: The maximum number of missing items to return.
363    ///
364    /// # Returns
365    ///
366    /// A vector containing up to `max` missing indices from gaps between ranges.
367    /// The vector may contain fewer than `max` items if there aren't enough gaps.
368    /// If there are no more ranges after the current position, no items are returned.
369    ///
370    /// # Complexity
371    ///
372    /// O(G log N + M) where N is the number of ranges in [RMap], G is the number of gaps
373    /// visited (at most N), and M is the number of missing items returned (at most `max`).
374    /// Each gap requires a `next_gap` call (O(log N)) and collecting items (O(items in gap)).
375    ///
376    /// # Example
377    ///
378    /// ```
379    /// use commonware_storage::rmap::RMap;
380    ///
381    /// let mut map = RMap::new();
382    /// map.insert(1); map.insert(2); // Map: [1, 2]
383    /// map.insert(5); map.insert(6); // Map: [1, 2], [5, 6]
384    /// map.insert(10);                // Map: [1, 2], [5, 6], [10, 10]
385    ///
386    /// // Starting from 0, find up to 5 missing items
387    /// assert_eq!(map.missing_items(0, 5), vec![0, 3, 4, 7, 8]);
388    ///
389    /// // Starting from 3, find up to 3 missing items
390    /// assert_eq!(map.missing_items(3, 3), vec![3, 4, 7]);
391    ///
392    /// // Starting from 7, find up to 10 missing items (only gaps are returned)
393    /// assert_eq!(map.missing_items(7, 10), vec![7, 8, 9]);
394    ///
395    /// // Starting from 11, there are no more ranges, so no gaps
396    /// assert_eq!(map.missing_items(11, 5), Vec::<u64>::new());
397    /// ```
398    pub fn missing_items(&self, start: u64, max: usize) -> Vec<u64> {
399        // Ensure input is valid
400        assert!(max > 0, "max must be greater than 0");
401        let mut current = start;
402
403        // Collect missing items
404        let mut missing = Vec::with_capacity(max);
405        loop {
406            // If we're inside a range, skip to just after it
407            let (current_range_end, next_range_start) = self.next_gap(current);
408            if let Some(end) = current_range_end {
409                // Check if we can move past this range
410                if end == u64::MAX {
411                    break missing; // No gaps possible after u64::MAX
412                }
413                current = end + 1;
414                continue;
415            }
416
417            // We're in a gap - check if there's a next range
418            let Some(next_start) = next_range_start else {
419                break missing; // No more ranges, so no more gaps to fill
420            };
421
422            // Collect items from this gap until we hit the next range or have enough
423            let gap_end = next_start - 1; // next_start must be greater than or equal to 1
424            let items_needed = max - missing.len(); // there must be at least one item to collect
425            let gap_end = gap_end.min(current.saturating_add(items_needed as u64 - 1));
426            for index in current..=gap_end {
427                missing.push(index);
428            }
429
430            // If we have enough items, break
431            if missing.len() >= max {
432                break missing;
433            }
434
435            // Move to the start of the next range to check for more gaps
436            current = next_start;
437        }
438    }
439}
440
441#[cfg(test)]
442mod tests {
443    use super::*;
444
445    #[test]
446    fn test_new() {
447        let map = RMap::new();
448        assert_eq!(map.iter().count(), 0);
449    }
450
451    #[test]
452    fn test_insert_empty() {
453        let mut map = RMap::new();
454        map.insert(5);
455        assert_eq!(map.get(&5), Some((5, 5)));
456        assert_eq!(map.iter().collect::<Vec<_>>(), vec![(&5, &5)]);
457    }
458
459    #[test]
460    fn test_insert_isolated() {
461        let mut map = RMap::new();
462        map.insert(5);
463        map.insert(10);
464        assert_eq!(map.get(&5), Some((5, 5)));
465        assert_eq!(map.get(&10), Some((10, 10)));
466        assert_eq!(map.iter().collect::<Vec<_>>(), vec![(&5, &5), (&10, &10)]);
467    }
468
469    #[test]
470    fn test_insert_covered() {
471        let mut map = RMap::new();
472        map.insert(1);
473        map.insert(2);
474        map.insert(3); // Range is 1-3
475        map.insert(2); // Insert value already covered
476        assert_eq!(map.get(&1), Some((1, 3)));
477        assert_eq!(map.get(&2), Some((1, 3)));
478        assert_eq!(map.get(&3), Some((1, 3)));
479        assert_eq!(map.iter().count(), 1);
480        assert_eq!(map.iter().next(), Some((&1, &3)));
481    }
482
483    #[test]
484    fn test_insert_adjacent_end() {
485        let mut map = RMap::new();
486        map.insert(1);
487        map.insert(2); // Range is 1-2
488        map.insert(3); // Adjacent to end
489        assert_eq!(map.get(&1), Some((1, 3)));
490        assert_eq!(map.get(&3), Some((1, 3)));
491        assert_eq!(map.iter().next(), Some((&1, &3)));
492    }
493
494    #[test]
495    fn test_insert_adjacent_start() {
496        let mut map = RMap::new();
497        map.insert(2);
498        map.insert(3); // Range is 2-3
499        map.insert(1); // Adjacent to start
500        assert_eq!(map.get(&1), Some((1, 3)));
501        assert_eq!(map.get(&3), Some((1, 3)));
502        assert_eq!(map.iter().next(), Some((&1, &3)));
503    }
504
505    #[test]
506    fn test_insert_bridge_ranges() {
507        let mut map = RMap::new();
508        map.insert(1);
509        map.insert(2);
510        assert_eq!(map.get(&1), Some((1, 2)));
511        map.insert(5);
512        map.insert(6);
513        assert_eq!(map.get(&5), Some((5, 6)));
514        // Current: (1,2), (5,6)
515        map.insert(3); // Insert 3, should become (1,3), (5,6)
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.get(&5), Some((5, 6)));
520        assert_eq!(map.iter().collect::<Vec<_>>(), vec![(&1, &3), (&5, &6)]);
521
522        map.insert(4); // Insert 4, should bridge to (1,6)
523        assert_eq!(map.get(&1), Some((1, 6)));
524        assert_eq!(map.get(&3), Some((1, 6)));
525        assert_eq!(map.get(&4), Some((1, 6)));
526        assert_eq!(map.get(&6), Some((1, 6)));
527        assert_eq!(map.iter().count(), 1);
528        assert_eq!(map.iter().next(), Some((&1, &6)));
529    }
530
531    #[test]
532    fn test_insert_complex_merging_and_ordering() {
533        let mut map = RMap::new();
534        map.insert(10); // (10,10)
535        map.insert(12); // (10,10), (12,12)
536        map.insert(11); // (10,12)
537        assert_eq!(map.get(&10), Some((10, 12)));
538        assert_eq!(map.get(&11), Some((10, 12)));
539        assert_eq!(map.get(&12), Some((10, 12)));
540
541        map.insert(15); // (10,12), (15,15)
542        map.insert(13); // (10,13), (15,15)
543        assert_eq!(map.get(&13), Some((10, 13)));
544        assert_eq!(map.get(&12), Some((10, 13)));
545        assert_eq!(map.get(&15), Some((15, 15)));
546
547        map.insert(14); // (10,15)
548        assert_eq!(map.get(&10), Some((10, 15)));
549        assert_eq!(map.get(&14), Some((10, 15)));
550        assert_eq!(map.get(&15), Some((10, 15)));
551        assert_eq!(map.iter().count(), 1);
552        assert_eq!(map.iter().next(), Some((&10, &15)));
553
554        map.insert(5); // (5,5), (10,15)
555        map.insert(7); // (5,5), (7,7), (10,15)
556        map.insert(6); // (5,7), (10,15)
557        assert_eq!(map.get(&5), Some((5, 7)));
558        assert_eq!(map.get(&6), Some((5, 7)));
559        assert_eq!(map.get(&7), Some((5, 7)));
560        assert_eq!(map.iter().collect::<Vec<_>>(), vec![(&5, &7), (&10, &15)]);
561
562        map.insert(9); // (5,7), (9,9), (10,15) -> should become (5,7), (9,15)
563        assert_eq!(map.get(&9), Some((9, 15)));
564        assert_eq!(map.get(&10), Some((9, 15)));
565        assert_eq!(map.iter().collect::<Vec<_>>(), vec![(&5, &7), (&9, &15)]);
566
567        map.insert(8); // (5,15)
568        assert_eq!(map.get(&5), Some((5, 15)));
569        assert_eq!(map.get(&8), Some((5, 15)));
570        assert_eq!(map.get(&15), Some((5, 15)));
571        assert_eq!(map.iter().next(), Some((&5, &15)));
572    }
573
574    #[test]
575    fn test_insert_max_value() {
576        let mut map = RMap::new();
577        map.insert(u64::MAX);
578        assert_eq!(map.get(&u64::MAX), Some((u64::MAX, u64::MAX)));
579        map.insert(u64::MAX - 1);
580        assert_eq!(map.get(&(u64::MAX - 1)), Some((u64::MAX - 1, u64::MAX)));
581        assert_eq!(map.get(&u64::MAX), Some((u64::MAX - 1, u64::MAX)));
582    }
583
584    #[test]
585    fn test_get() {
586        let mut map = RMap::new();
587        map.insert(1);
588        map.insert(2);
589        map.insert(3); // Range 1-3
590        map.insert(5);
591        map.insert(6); // Range 5-6
592
593        assert_eq!(map.get(&1), Some((1, 3)));
594        assert_eq!(map.get(&2), Some((1, 3)));
595        assert_eq!(map.get(&3), Some((1, 3)));
596        assert_eq!(map.get(&4), None);
597        assert_eq!(map.get(&5), Some((5, 6)));
598        assert_eq!(map.get(&6), Some((5, 6)));
599        assert_eq!(map.get(&0), None);
600        assert_eq!(map.get(&7), None);
601    }
602
603    #[test]
604    fn test_remove_empty() {
605        let mut map = RMap::new();
606        map.remove(1, 5);
607        assert_eq!(map.iter().count(), 0);
608    }
609
610    #[test]
611    fn test_remove_invalid_range() {
612        let mut map = RMap::new();
613        map.insert(1);
614        map.insert(2); // 1-2
615        map.remove(5, 1); // start > end, should do nothing
616        assert_eq!(map.iter().next(), Some((&1, &2)));
617    }
618
619    #[test]
620    fn test_remove_non_existent() {
621        let mut map = RMap::new();
622        map.insert(5);
623        map.insert(6); // 5-6
624        map.remove(1, 3); // Before existing
625        assert_eq!(map.iter().next(), Some((&5, &6)));
626        map.remove(8, 10); // After existing
627        assert_eq!(map.iter().next(), Some((&5, &6)));
628        map.remove(1, 10); // Covers existing
629        assert_eq!(map.iter().count(), 0);
630    }
631
632    #[test]
633    fn test_remove_exact_match() {
634        let mut map = RMap::new();
635        map.insert(1);
636        map.insert(2);
637        map.insert(3); // 1-3
638        map.insert(5);
639        map.insert(6); // 5-6
640        map.remove(1, 3);
641        assert_eq!(map.get(&2), None);
642        assert_eq!(map.iter().next(), Some((&5, &6)));
643        map.remove(5, 6);
644        assert_eq!(map.iter().count(), 0);
645    }
646
647    #[test]
648    fn test_remove_subset_split() {
649        let mut map = RMap::new();
650        map.insert(1);
651        map.insert(2);
652        map.insert(3);
653        map.insert(4);
654        map.insert(5); // 1-5
655        map.remove(3, 3); // Remove 3 from 1-5 -> (1,2), (4,5)
656        assert_eq!(map.get(&2), Some((1, 2)));
657        assert_eq!(map.get(&3), None);
658        assert_eq!(map.get(&4), Some((4, 5)));
659        assert_eq!(map.iter().collect::<Vec<_>>(), vec![(&1, &2), (&4, &5)]);
660
661        // Reset and test another split
662        let mut map2 = RMap::new();
663        map2.insert(1);
664        map2.insert(2);
665        map2.insert(3);
666        map2.insert(4);
667        map2.insert(5); // 1-5
668        map2.remove(2, 4); // Remove 2-4 from 1-5 -> (1,1), (5,5)
669        assert_eq!(map2.get(&1), Some((1, 1)));
670        assert_eq!(map2.get(&2), None);
671        assert_eq!(map2.get(&3), None);
672        assert_eq!(map2.get(&4), None);
673        assert_eq!(map2.get(&5), Some((5, 5)));
674        assert_eq!(map2.iter().collect::<Vec<_>>(), vec![(&1, &1), (&5, &5)]);
675    }
676
677    #[test]
678    fn test_remove_overlap_start() {
679        let mut map = RMap::new();
680        map.insert(1);
681        map.insert(2);
682        map.insert(3);
683        map.insert(4);
684        map.insert(5); // 1-5
685        map.remove(0, 2); // Remove 0-2 from 1-5 -> (3,5)
686        assert_eq!(map.get(&1), None);
687        assert_eq!(map.get(&2), None);
688        assert_eq!(map.get(&3), Some((3, 5)));
689        assert_eq!(map.iter().next(), Some((&3, &5)));
690    }
691
692    #[test]
693    fn test_remove_overlap_end() {
694        let mut map = RMap::new();
695        map.insert(1);
696        map.insert(2);
697        map.insert(3);
698        map.insert(4);
699        map.insert(5); // 1-5
700        map.remove(4, 6); // Remove 4-6 from 1-5 -> (1,3)
701        assert_eq!(map.get(&3), Some((1, 3)));
702        assert_eq!(map.get(&4), None);
703        assert_eq!(map.get(&5), None);
704        assert_eq!(map.iter().next(), Some((&1, &3)));
705    }
706
707    #[test]
708    fn test_remove_cover_multiple_ranges() {
709        let mut map = RMap::new();
710        map.insert(1);
711        map.insert(2); // 1-2
712        map.insert(4);
713        map.insert(5); // 4-5
714        map.insert(7);
715        map.insert(8); // 7-8
716
717        map.remove(3, 6); // Removes 4-5, no truncation as 3 and 6 are in gaps. (1,2), (7,8)
718        assert_eq!(map.get(&2), Some((1, 2)));
719        assert_eq!(map.get(&4), None);
720        assert_eq!(map.get(&5), None);
721        assert_eq!(map.get(&7), Some((7, 8)));
722        assert_eq!(map.iter().collect::<Vec<_>>(), vec![(&1, &2), (&7, &8)]);
723
724        map.remove(0, 10); // Removes all remaining ranges
725        assert_eq!(map.iter().count(), 0);
726    }
727
728    #[test]
729    fn test_remove_partial_overlap_multiple_ranges() {
730        let mut map = RMap::new();
731        map.insert(1);
732        map.insert(2);
733        map.insert(3); // 1-3
734        map.insert(5);
735        map.insert(6);
736        map.insert(7); // 5-7
737        map.insert(9);
738        map.insert(10);
739        map.insert(11); // 9-11
740
741        map.remove(2, 6); // Affects 1-3 (becomes 1-1) and 5-7 (becomes 7-7)
742        assert_eq!(map.get(&1), Some((1, 1)));
743        assert_eq!(map.get(&2), None);
744        assert_eq!(map.get(&3), None);
745        assert_eq!(map.get(&5), None);
746        assert_eq!(map.get(&6), None);
747        assert_eq!(map.get(&7), Some((7, 7)));
748        assert_eq!(map.get(&9), Some((9, 11)));
749        assert_eq!(
750            map.iter().collect::<Vec<_>>(),
751            vec![(&1, &1), (&7, &7), (&9, &11)]
752        );
753
754        // Reset and test removing all
755        let mut map2 = RMap::new();
756        map2.insert(1);
757        map2.insert(2);
758        map2.insert(3);
759        map2.insert(5);
760        map2.insert(6);
761        map2.insert(7);
762        map2.insert(9);
763        map2.insert(10);
764        map2.insert(11);
765        map2.remove(0, 20); // remove all
766        assert_eq!(map2.iter().count(), 0);
767    }
768
769    #[test]
770    fn test_remove_touching_boundaries_no_merge() {
771        let mut map = RMap::new();
772        map.insert(0);
773        map.insert(1);
774        map.insert(2); // 0-2
775        map.insert(4);
776        map.insert(5); // 4-5
777
778        // Remove range that is exactly between two existing ranges
779        map.remove(3, 3);
780        assert_eq!(map.iter().collect::<Vec<_>>(), vec![(&0, &2), (&4, &5)]);
781    }
782
783    #[test]
784    fn test_remove_max_value_ranges() {
785        let mut map = RMap::new();
786        map.insert(u64::MAX - 2);
787        map.insert(u64::MAX - 1);
788        map.insert(u64::MAX); // MAX-2 to MAX
789
790        map.remove(u64::MAX, u64::MAX); // Remove MAX -> (MAX-2, MAX-1)
791        assert_eq!(map.get(&(u64::MAX - 2)), Some((u64::MAX - 2, u64::MAX - 1)));
792        assert_eq!(map.get(&u64::MAX), None);
793
794        map.remove(u64::MAX - 2, u64::MAX - 2); // Remove MAX-2 -> (MAX-1, MAX-1)
795        assert_eq!(map.get(&(u64::MAX - 2)), None);
796        assert_eq!(map.get(&(u64::MAX - 1)), Some((u64::MAX - 1, u64::MAX - 1)));
797
798        map.remove(u64::MAX - 1, u64::MAX - 1); // Remove MAX-1 -> empty
799        assert_eq!(map.iter().count(), 0);
800
801        map.insert(u64::MAX - 1);
802        map.insert(u64::MAX); // MAX-1 to MAX
803        map.remove(u64::MIN, u64::MAX); // Remove all
804        assert_eq!(map.iter().count(), 0);
805    }
806
807    #[test]
808    fn test_iter() {
809        let mut map = RMap::new();
810        assert_eq!(map.iter().next(), None);
811        map.insert(5);
812        map.insert(6); // 5-6
813        map.insert(1);
814        map.insert(2); // 1-2
815        let mut iter = map.iter();
816        assert_eq!(iter.next(), Some((&1, &2)));
817        assert_eq!(iter.next(), Some((&5, &6)));
818        assert_eq!(iter.next(), None);
819    }
820
821    #[test]
822    fn test_next_gap_empty() {
823        let map = RMap::new();
824        assert_eq!(map.next_gap(5), (None, None));
825    }
826
827    #[test]
828    fn test_next_gap_single_range() {
829        let mut map = RMap::new();
830        map.insert(5);
831        map.insert(6);
832        map.insert(7); // 5-7
833        assert_eq!(map.next_gap(4), (None, Some(5))); // Before range
834        assert_eq!(map.next_gap(5), (Some(7), None)); // Start of range
835        assert_eq!(map.next_gap(6), (Some(7), None)); // Middle of range
836        assert_eq!(map.next_gap(7), (Some(7), None)); // End of range
837        assert_eq!(map.next_gap(8), (None, None)); // After range
838    }
839
840    #[test]
841    fn test_next_gap_multiple_ranges() {
842        let mut map = RMap::new();
843        map.insert(1);
844        map.insert(2); // 1-2
845        map.insert(5);
846        map.insert(6); // 5-6
847        map.insert(10); // 10-10
848
849        assert_eq!(map.next_gap(0), (None, Some(1))); // Before all
850        assert_eq!(map.next_gap(1), (Some(2), Some(5))); // Start of first range
851        assert_eq!(map.next_gap(2), (Some(2), Some(5))); // End of first range
852        assert_eq!(map.next_gap(3), (None, Some(5))); // Gap between 1st and 2nd
853        assert_eq!(map.next_gap(4), (None, Some(5))); // Gap, closer to 2nd
854        assert_eq!(map.next_gap(5), (Some(6), Some(10))); // Start of 2nd range
855        assert_eq!(map.next_gap(6), (Some(6), Some(10))); // End of 2nd range
856        assert_eq!(map.next_gap(7), (None, Some(10))); // Gap between 2nd and 3rd
857        assert_eq!(map.next_gap(8), (None, Some(10))); // Gap
858        assert_eq!(map.next_gap(9), (None, Some(10))); // Gap, closer to 3rd
859        assert_eq!(map.next_gap(10), (Some(10), None)); // Start/End of 3rd range
860        assert_eq!(map.next_gap(11), (None, None)); // After all
861    }
862
863    #[test]
864    fn test_next_gap_value_is_max() {
865        let mut map = RMap::new();
866        map.insert(u64::MAX - 5);
867        map.insert(u64::MAX - 4); // MAX-5 to MAX-4
868        map.insert(u64::MAX - 1);
869        map.insert(u64::MAX); // MAX-1 to MAX
870
871        assert_eq!(map.next_gap(u64::MAX - 6), (None, Some(u64::MAX - 5)));
872        assert_eq!(
873            map.next_gap(u64::MAX - 5),
874            (Some(u64::MAX - 4), Some(u64::MAX - 1))
875        );
876        assert_eq!(
877            map.next_gap(u64::MAX - 4),
878            (Some(u64::MAX - 4), Some(u64::MAX - 1))
879        );
880        assert_eq!(map.next_gap(u64::MAX - 3), (None, Some(u64::MAX - 1))); // In gap
881        assert_eq!(map.next_gap(u64::MAX - 2), (None, Some(u64::MAX - 1))); // In gap
882        assert_eq!(map.next_gap(u64::MAX - 1), (Some(u64::MAX), None));
883        assert_eq!(map.next_gap(u64::MAX), (Some(u64::MAX), None));
884    }
885
886    #[test]
887    fn test_odd_ranges() {
888        // Insert values
889        let mut map = RMap::new();
890        map.insert(1);
891        map.insert(10);
892        map.insert(11);
893        map.insert(14);
894
895        // Sanity check next_gap
896        assert_eq!(map.next_gap(0), (None, Some(1)));
897        assert_eq!(map.next_gap(1), (Some(1), Some(10)));
898        assert_eq!(map.next_gap(10), (Some(11), Some(14)));
899        assert_eq!(map.next_gap(11), (Some(11), Some(14)));
900        assert_eq!(map.next_gap(12), (None, Some(14)));
901        assert_eq!(map.next_gap(14), (Some(14), None));
902    }
903
904    #[test]
905    fn test_missing_items_empty_map() {
906        let map = RMap::new();
907        assert_eq!(map.missing_items(0, 5), Vec::<u64>::new());
908        assert_eq!(map.missing_items(100, 10), Vec::<u64>::new());
909    }
910
911    #[test]
912    fn test_missing_items_single_gap() {
913        let mut map = RMap::new();
914        map.insert(1);
915        map.insert(2); // [1, 2]
916        map.insert(5);
917        map.insert(6); // [1, 2], [5, 6]
918
919        // Gap between ranges: 3, 4
920        assert_eq!(map.missing_items(3, 5), vec![3, 4]);
921        assert_eq!(map.missing_items(3, 2), vec![3, 4]);
922        assert_eq!(map.missing_items(3, 1), vec![3]);
923        assert_eq!(map.missing_items(4, 1), vec![4]);
924    }
925
926    #[test]
927    fn test_missing_items_multiple_gaps() {
928        let mut map = RMap::new();
929        map.insert(1);
930        map.insert(2); // [1, 2]
931        map.insert(5);
932        map.insert(6); // [1, 2], [5, 6]
933        map.insert(10); // [1, 2], [5, 6], [10, 10]
934
935        // Starting from 0 (before first range)
936        assert_eq!(map.missing_items(0, 5), vec![0, 3, 4, 7, 8]);
937        assert_eq!(map.missing_items(0, 6), vec![0, 3, 4, 7, 8, 9]);
938        assert_eq!(map.missing_items(0, 7), vec![0, 3, 4, 7, 8, 9]);
939
940        // Starting from within first gap
941        assert_eq!(map.missing_items(3, 3), vec![3, 4, 7]);
942        assert_eq!(map.missing_items(4, 2), vec![4, 7]);
943
944        // Starting from within second gap
945        assert_eq!(map.missing_items(7, 10), vec![7, 8, 9]);
946        assert_eq!(map.missing_items(8, 2), vec![8, 9]);
947
948        // Starting after last range (no more gaps)
949        assert_eq!(map.missing_items(11, 5), Vec::<u64>::new());
950        assert_eq!(map.missing_items(100, 10), Vec::<u64>::new());
951    }
952
953    #[test]
954    fn test_missing_items_starting_in_range() {
955        let mut map = RMap::new();
956        map.insert(1);
957        map.insert(2);
958        map.insert(3); // [1, 3]
959        map.insert(7);
960        map.insert(8);
961        map.insert(9); // [1, 3], [7, 9]
962
963        // Starting within first range
964        assert_eq!(map.missing_items(1, 3), vec![4, 5, 6]);
965        assert_eq!(map.missing_items(2, 4), vec![4, 5, 6]);
966        assert_eq!(map.missing_items(3, 2), vec![4, 5]);
967
968        // Starting within second range
969        assert_eq!(map.missing_items(7, 5), Vec::<u64>::new());
970        assert_eq!(map.missing_items(8, 3), Vec::<u64>::new());
971        assert_eq!(map.missing_items(9, 1), Vec::<u64>::new());
972    }
973
974    #[test]
975    #[should_panic]
976    fn test_missing_items_zero_n() {
977        let mut map = RMap::new();
978        map.insert(1);
979        map.insert(5);
980
981        map.missing_items(1, 0);
982    }
983
984    #[test]
985    fn test_missing_items_large_gap() {
986        let mut map = RMap::new();
987        map.insert(1);
988        map.insert(1000);
989
990        // Large gap between 1 and 1000
991        assert_eq!(map.missing_items(2, 5), vec![2, 3, 4, 5, 6]);
992        assert_eq!(map.missing_items(995, 5), vec![995, 996, 997, 998, 999]);
993
994        // Request more items than exist in gap
995        let items = map.missing_items(2, 998);
996        assert_eq!(items.len(), 998);
997        assert_eq!(items[0], 2);
998        assert_eq!(items[997], 999);
999    }
1000
1001    #[test]
1002    fn test_missing_items_at_boundaries() {
1003        let mut map = RMap::new();
1004        map.insert(5);
1005        map.insert(6); // [5, 6]
1006        map.insert(10); // [5, 6], [10, 10]
1007
1008        // Starting at exact boundary of range start
1009        assert_eq!(map.missing_items(5, 3), vec![7, 8, 9]);
1010
1011        // Starting at exact boundary of range end
1012        assert_eq!(map.missing_items(6, 3), vec![7, 8, 9]);
1013
1014        // Starting at isolated range
1015        assert_eq!(map.missing_items(10, 5), Vec::<u64>::new());
1016    }
1017
1018    #[test]
1019    fn test_missing_items_near_max() {
1020        let mut map = RMap::new();
1021        map.insert(u64::MAX - 5);
1022        map.insert(u64::MAX - 3);
1023        map.insert(u64::MAX);
1024
1025        // Gap: MAX-4, MAX-2, MAX-1
1026        assert_eq!(
1027            map.missing_items(u64::MAX - 6, 5),
1028            vec![u64::MAX - 6, u64::MAX - 4, u64::MAX - 2, u64::MAX - 1]
1029        );
1030        assert_eq!(
1031            map.missing_items(u64::MAX - 4, 3),
1032            vec![u64::MAX - 4, u64::MAX - 2, u64::MAX - 1]
1033        );
1034
1035        // Starting at MAX (no gaps possible)
1036        assert_eq!(map.missing_items(u64::MAX, 5), Vec::<u64>::new());
1037    }
1038
1039    #[test]
1040    fn test_missing_items_contiguous_ranges() {
1041        let mut map = RMap::new();
1042        map.insert(1);
1043        map.insert(2);
1044        map.insert(3); // [1, 3]
1045        map.insert(4);
1046        map.insert(5);
1047        map.insert(6); // [1, 6] (merged)
1048
1049        // No gaps in contiguous range
1050        assert_eq!(map.missing_items(0, 3), vec![0]);
1051        assert_eq!(map.missing_items(7, 5), Vec::<u64>::new());
1052    }
1053}