Skip to main content

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}