Skip to content

Commit e3f363f

Browse files
committed
implement removal and add more tests
1 parent d828e05 commit e3f363f

File tree

1 file changed

+190
-14
lines changed

1 file changed

+190
-14
lines changed

quinn-proto/src/range_set/btree_range_set.rs

Lines changed: 190 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -121,18 +121,24 @@ impl RangeSet {
121121
}
122122
Some(_) | None => false,
123123
};
124+
125+
let removed_end = self
126+
.0
127+
.extract_if((Excluded(x.start), Excluded(x.end)), |_, _| true)
128+
.last()
129+
.map(|(_start, end)| end);
130+
124131
let mut after = false;
125-
while let Some((start, end)) = self.succ(x.start) {
126-
if start >= x.end {
127-
break;
128-
}
132+
133+
if let Some(removed_end) = removed_end {
129134
after = true;
130-
self.0.remove(&start);
131-
if end > x.end {
132-
self.0.insert(x.end, end);
133-
break;
135+
136+
let over_removed = removed_end > x.end;
137+
if over_removed {
138+
self.0.insert(x.end, removed_end);
134139
}
135140
}
141+
136142
before || after
137143
}
138144

@@ -382,7 +388,21 @@ mod tests {
382388
}
383389

384390
#[test]
385-
fn insert_merges_abutting_range() {
391+
fn insert_extends_prev_joint_range() {
392+
// given
393+
let mut set = RangeSet::new();
394+
set.insert(0..10);
395+
396+
// when
397+
set.insert(10..20);
398+
399+
// then
400+
let expected_inner = BTreeMap::from_iter([(0, 20)]);
401+
assert_eq!(set.0, expected_inner, "ranges should have merged");
402+
}
403+
404+
#[test]
405+
fn insert_merges_touching_range() {
386406
// given
387407
let mut set = RangeSet::new();
388408
set.insert(10..20);
@@ -392,7 +412,7 @@ mod tests {
392412

393413
// then
394414
let expected_inner = BTreeMap::from_iter([(5, 20)]);
395-
assert_eq!(set.0, expected_inner, "Ranges should have merged.");
415+
assert_eq!(set.0, expected_inner, "ranges should have merged.");
396416
}
397417

398418
#[test]
@@ -406,7 +426,7 @@ mod tests {
406426

407427
// then
408428
let expected_inner = BTreeMap::from_iter([(10, 25)]);
409-
assert_eq!(set.0, expected_inner, "Ranges should have merged.");
429+
assert_eq!(set.0, expected_inner, "ranges should have merged.");
410430
}
411431

412432
#[test]
@@ -416,11 +436,15 @@ mod tests {
416436
set.insert(10..20);
417437

418438
// when
419-
set.insert(12..15);
439+
let insert_result = set.insert(14..16);
420440

421441
// then
422442
let expected_inner = BTreeMap::from_iter([(10, 20)]);
423-
assert_eq!(set.0, expected_inner, "Ranges should have merged.");
443+
assert_eq!(set.0, expected_inner, "insertion should be ignored");
444+
assert!(
445+
!insert_result,
446+
"insert should return false when inserting an already contained range"
447+
);
424448
}
425449

426450
#[test]
@@ -435,6 +459,158 @@ mod tests {
435459

436460
// then
437461
let expected_inner = BTreeMap::from_iter([(0, 30)]);
438-
assert_eq!(set.0, expected_inner, "Ranges should have merged.");
462+
assert_eq!(set.0, expected_inner, "existing ranges should have merged");
463+
}
464+
465+
#[test]
466+
fn remove_splits_contained_range() {
467+
// given
468+
let mut set = RangeSet::new();
469+
set.insert(0..10);
470+
471+
// when
472+
let changed = set.remove(2..8);
473+
474+
// then
475+
assert!(changed);
476+
let expected_inner = BTreeMap::from_iter([(0, 2), (8, 10)]);
477+
assert_eq!(set.0, expected_inner, "range should have split into two");
478+
}
479+
480+
#[test]
481+
fn remove_trims_start_of_range() {
482+
// given
483+
let mut set = RangeSet::new();
484+
set.insert(10..20);
485+
486+
// when
487+
let changed = set.remove(5..15);
488+
489+
// then
490+
assert!(changed);
491+
let expected_inner = BTreeMap::from_iter([(15, 20)]);
492+
assert_eq!(
493+
set.0, expected_inner,
494+
"start of range should have been trimmed"
495+
);
496+
}
497+
498+
#[test]
499+
fn remove_trims_end_of_range() {
500+
// given
501+
let mut set = RangeSet::new();
502+
set.insert(0..10);
503+
504+
// when
505+
let changed = set.remove(5..15);
506+
507+
// then
508+
assert!(changed);
509+
let expected_inner = BTreeMap::from_iter([(0, 5)]);
510+
assert_eq!(
511+
set.0, expected_inner,
512+
"end of range should have been trimmed"
513+
);
514+
}
515+
516+
#[test]
517+
fn remove_swallows_multiple_ranges() {
518+
// given
519+
let mut set = RangeSet::new();
520+
set.insert(0..5);
521+
set.insert(10..15);
522+
set.insert(20..25);
523+
524+
// when
525+
let changed = set.remove(0..25);
526+
527+
// then
528+
assert!(changed);
529+
let expected_inner = BTreeMap::new();
530+
assert_eq!(
531+
set.0, expected_inner,
532+
"all ranges should be gone as the removal swallowed them"
533+
);
534+
}
535+
536+
#[test]
537+
fn remove_specific_range_in_set() {
538+
// given
539+
let mut set = RangeSet::new();
540+
set.insert(10..20);
541+
542+
// when
543+
let changed = set.remove(10..20);
544+
545+
// then
546+
assert!(changed);
547+
let expected_inner = BTreeMap::new();
548+
assert_eq!(set.0, expected_inner, "set should be empty");
549+
}
550+
551+
#[test]
552+
fn removing_range_touching_existing_ranges_is_ignored() {
553+
// given
554+
let mut set = RangeSet::new();
555+
set.insert(10..20);
556+
557+
// when
558+
let changed_start = set.remove(0..10);
559+
let changed_end = set.remove(20..30);
560+
561+
// then
562+
assert!(!changed_start);
563+
assert!(!changed_end);
564+
let expected_inner = BTreeMap::from_iter([(10, 20)]);
565+
assert_eq!(
566+
set.0, expected_inner,
567+
"touching ranges should not remove anything."
568+
);
569+
}
570+
571+
#[test]
572+
fn removing_range_crossing_existing_ranges_that_should_be_trimmed() {
573+
// given
574+
let mut set = RangeSet::new();
575+
set.insert(0..5);
576+
set.insert(10..15);
577+
578+
// when
579+
let changed = set.remove(4..11);
580+
581+
// then
582+
assert!(changed);
583+
let expected_inner = BTreeMap::from_iter([(0, 4), (11, 15)]);
584+
assert_eq!(set.0, expected_inner, "existing ranges should be trimmed");
585+
}
586+
587+
#[test]
588+
fn remove_crossing_range_trims_start() {
589+
// given
590+
let mut set = RangeSet::new();
591+
set.insert(10..20);
592+
593+
// when
594+
let changed = set.remove(9..12);
595+
596+
// then
597+
assert!(changed);
598+
let expected_inner = BTreeMap::from_iter([(12, 20)]);
599+
assert_eq!(set.0, expected_inner);
600+
}
601+
602+
#[test]
603+
fn remove_no_overlap_before_and_after() {
604+
// given
605+
let mut set = RangeSet::new();
606+
set.insert(10..20);
607+
608+
// when
609+
let changed = set.remove(0..5);
610+
611+
// then
612+
assert!(!changed);
613+
let expected_inner = BTreeMap::from_iter([(10, 20)]);
614+
assert_eq!(set.0, expected_inner, "disjoint removals should be ignored");
439615
}
440616
}

0 commit comments

Comments
 (0)