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}