1use super::Node;
2use crate::{
3 range::{Difference, ProductArg},
4 AnyRange, AsRange, IntoRange, RangeOrdering, RangePartialOrd,
5};
6use btree_slab::generic::{
7 map::{BTreeExt, BTreeExtMut, BTreeMap},
8 node::{Address, Item, Offset},
9};
10use cc_traits::{SimpleCollectionMut, SimpleCollectionRef, Slab, SlabMut};
11use range_traits::{Bounded, Measure, PartialEnum};
12use std::{
13 cmp::{Ord, Ordering, PartialOrd},
14 fmt,
15 hash::{Hash, Hasher},
16};
17
18#[derive(Clone)]
20pub struct RangeMap<K, V, C> {
21 btree: BTreeMap<AnyRange<K>, V, C>,
22}
23
24impl<K, V, C> RangeMap<K, V, C> {
25 pub fn new() -> RangeMap<K, V, C>
27 where
28 C: Default,
29 {
30 RangeMap {
31 btree: BTreeMap::new(),
32 }
33 }
34}
35
36impl<K, T, C: Default> Default for RangeMap<K, T, C> {
37 fn default() -> Self {
38 Self::new()
39 }
40}
41
42impl<K, V, C: Slab<Node<AnyRange<K>, V>>> RangeMap<K, V, C>
43where
44 C: SimpleCollectionRef,
45{
46 pub fn len(&self) -> K::Len
47 where
48 K: Measure + PartialEnum + Bounded,
49 {
50 let mut len = K::Len::default();
51 for (range, _) in self {
52 len = len + range.len()
53 }
54
55 len
56 }
57
58 pub fn bounded_len(&self) -> Option<K::Len>
59 where
60 K: Measure + PartialEnum,
61 {
62 let mut len = K::Len::default();
63 for (range, _) in self {
64 len = len + range.bounded_len()?
65 }
66
67 Some(len)
68 }
69
70 pub fn is_empty(&self) -> bool
71 where
72 K: Measure + PartialEnum,
73 {
74 self.bounded_len() == Some(K::Len::default())
75 }
76
77 pub fn range_count(&self) -> usize {
78 self.btree.len()
79 }
80
81 fn address_of<T>(&self, key: &T, connected: bool) -> Result<Address, Address>
82 where
83 K: PartialEnum + Measure,
84 T: RangePartialOrd<K>,
85 {
86 if connected {
87 if let Ok(addr) = self.address_of(key, false) {
88 return Ok(addr);
89 }
90 }
91
92 match self.btree.root_id() {
93 Some(id) => self.address_in(id, key, connected),
94 None => Err(Address::nowhere()),
95 }
96 }
97
98 fn address_in<T>(&self, mut id: usize, key: &T, connected: bool) -> Result<Address, Address>
99 where
100 K: PartialEnum + Measure,
101 T: RangePartialOrd<K>,
102 {
103 loop {
104 match self.offset_in(id, key, connected) {
105 Ok(offset) => return Ok(Address::new(id, offset)),
106 Err((offset, None)) => return Err(Address::new(id, offset.into())),
107 Err((_, Some(child_id))) => {
108 id = child_id;
109 }
110 }
111 }
112 }
113
114 fn offset_in<T>(
115 &self,
116 id: usize,
117 key: &T,
118 connected: bool,
119 ) -> Result<Offset, (usize, Option<usize>)>
120 where
121 K: PartialEnum + Measure,
122 T: RangePartialOrd<K>,
123 {
124 match self.btree.node(id) {
125 Node::Internal(node) => {
126 let branches = node.branches();
127 match binary_search(branches, key, connected) {
128 Some(i) => {
129 let b = &branches[i];
130 if key
131 .range_partial_cmp(b.item.key())
132 .unwrap_or(RangeOrdering::After(false))
133 .matches(connected)
134 {
135 Ok(i.into())
136 } else {
137 Err((i + 1, Some(b.child)))
138 }
139 }
140 None => Err((0, Some(node.first_child_id()))),
141 }
142 }
143 Node::Leaf(leaf) => {
144 let items = leaf.items();
145 match binary_search(items, key, connected) {
146 Some(i) => {
147 let item = &items[i];
148 let ord = key
149 .range_partial_cmp(item.key())
150 .unwrap_or(RangeOrdering::After(false));
151 if ord.matches(connected) {
152 Ok(i.into())
153 } else {
154 Err((i + 1, None))
155 }
156 }
157 None => Err((0, None)),
158 }
159 }
160 }
161 }
162
163 pub fn intersects<R: AsRange<Item = K>>(&self, key: R) -> bool
164 where
165 K: PartialEnum + Measure,
166 V: PartialEq,
167 {
168 if key.is_empty() {
171 false
172 } else {
173 self.address_of(&key, false).is_ok()
174 }
175 }
176
177 pub fn contains_key(&self, key: K) -> bool
178 where
179 K: PartialEnum + RangePartialOrd + Measure,
180 {
181 self.address_of(&key, false).is_ok()
182 }
183
184 pub fn get(&self, key: K) -> Option<&V>
185 where
186 K: PartialEnum + RangePartialOrd + Measure,
187 {
188 match self.address_of(&key, false) {
189 Ok(addr) => Some(self.btree.item(addr).unwrap().value()),
190 Err(_) => None,
191 }
192 }
193
194 pub fn iter(&self) -> Iter<K, V, C> {
195 self.btree.iter()
196 }
197
198 pub fn gaps(&self) -> Gaps<K, V, C> {
200 Gaps {
201 inner: self.btree.iter(),
202 prev: None,
203 done: false,
204 }
205 }
206}
207
208impl<K: fmt::Debug, V: fmt::Debug, C: Slab<Node<AnyRange<K>, V>>> fmt::Debug for RangeMap<K, V, C>
209where
210 C: SimpleCollectionRef,
211{
212 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
213 write!(f, "{{")?;
214
215 for (range, value) in self {
216 write!(f, "{:?}=>{:?}", range, value)?
217 }
218
219 write!(f, "}}")
220 }
221}
222
223impl<K, L, V, W, C: Slab<Node<AnyRange<K>, V>>, D: Slab<Node<AnyRange<L>, W>>>
224 PartialEq<RangeMap<L, W, D>> for RangeMap<K, V, C>
225where
226 L: Measure<K> + PartialOrd<K> + PartialEnum,
227 K: PartialEnum,
228 W: PartialEq<V>,
229 C: SimpleCollectionRef,
230 D: SimpleCollectionRef,
231{
232 fn eq(&self, other: &RangeMap<L, W, D>) -> bool {
233 self.btree == other.btree
234 }
235}
236
237impl<K, V, C: Slab<Node<AnyRange<K>, V>>> Eq for RangeMap<K, V, C>
238where
239 K: Measure + PartialEnum + Ord,
240 V: Eq,
241 C: SimpleCollectionRef,
242{
243}
244
245impl<K, L, V, W, C: Slab<Node<AnyRange<K>, V>>, D: Slab<Node<AnyRange<L>, W>>>
246 PartialOrd<RangeMap<L, W, D>> for RangeMap<K, V, C>
247where
248 L: Measure<K> + PartialOrd<K> + PartialEnum,
249 K: PartialEnum,
250 W: PartialOrd<V>,
251 C: SimpleCollectionRef,
252 D: SimpleCollectionRef,
253{
254 fn partial_cmp(&self, other: &RangeMap<L, W, D>) -> Option<Ordering> {
255 self.btree.partial_cmp(&other.btree)
256 }
257}
258
259impl<K, V, C: Slab<Node<AnyRange<K>, V>>> Ord for RangeMap<K, V, C>
260where
261 K: Measure + PartialEnum + Ord,
262 V: Ord,
263 C: SimpleCollectionRef,
264{
265 fn cmp(&self, other: &Self) -> Ordering {
266 self.btree.cmp(&other.btree)
267 }
268}
269
270impl<K, V, C: Slab<Node<AnyRange<K>, V>>> Hash for RangeMap<K, V, C>
271where
272 K: Hash + PartialEnum,
273 V: Hash,
274 C: SimpleCollectionRef,
275{
276 fn hash<H: Hasher>(&self, h: &mut H) {
277 for range in self {
278 range.hash(h)
279 }
280 }
281}
282
283impl<'a, K, V, C: Slab<Node<AnyRange<K>, V>>> IntoIterator for &'a RangeMap<K, V, C>
284where
285 C: SimpleCollectionRef,
286{
287 type Item = (&'a AnyRange<K>, &'a V);
288 type IntoIter = Iter<'a, K, V, C>;
289
290 fn into_iter(self) -> Self::IntoIter {
291 self.iter()
292 }
293}
294
295impl<K, V, C: SlabMut<Node<AnyRange<K>, V>>> RangeMap<K, V, C>
296where
297 C: SimpleCollectionRef,
298 C: SimpleCollectionMut,
299{
300 fn merge_forward(&mut self, addr: Address, next_addr: Option<Address>)
301 where
302 K: Clone + PartialEnum + Measure,
303 V: PartialEq,
304 {
305 if let Some(next_addr) = next_addr {
306 let item = self.btree.item(addr).unwrap();
307 let next_item = self.btree.item(next_addr).unwrap();
308 if item.key().connected_to(next_item.key()) && item.value() == next_item.value() {
309 let (removed_item, non_normalized_new_addr) = self.btree.remove_at(addr).unwrap();
310 let new_addr = self.btree.normalize(non_normalized_new_addr).unwrap();
311 let item = self.btree.item_mut(new_addr).unwrap();
312 item.key_mut().add(removed_item.key());
313 }
314 }
315 }
316
317 fn set_item_key(
318 &mut self,
319 addr: Address,
320 next_addr: Option<Address>,
321 new_key: AnyRange<K>,
322 ) -> (Address, Option<Address>)
323 where
324 K: Clone + PartialEnum + Measure,
325 V: PartialEq,
326 {
327 if let Some(next_addr) = next_addr {
328 let next_item = self.btree.item(next_addr).unwrap();
329 if new_key.connected_to(next_item.key())
330 && next_item.value() == self.btree.item(addr).unwrap().value()
331 {
332 let (_, non_normalized_new_addr) = self.btree.remove_at(addr).unwrap();
334 let new_addr = self.btree.normalize(non_normalized_new_addr).unwrap();
335 let item = self.btree.item_mut(new_addr).unwrap();
336 item.key_mut().add(&new_key);
337
338 return (new_addr, self.btree.next_item_address(new_addr));
339 }
340 }
341
342 let item = self.btree.item_mut(addr).unwrap();
343 *item.key_mut() = new_key;
344 (addr, next_addr)
345 }
346
347 fn set_item(
348 &mut self,
349 addr: Address,
350 next_addr: Option<Address>,
351 new_key: AnyRange<K>,
352 new_value: V,
353 ) -> (Address, Option<Address>, V)
354 where
355 K: Clone + PartialEnum + Measure,
356 V: PartialEq,
357 {
358 if let Some(next_addr) = next_addr {
359 let next_item = self.btree.item(next_addr).unwrap();
360 if new_key.connected_to(next_item.key()) && *next_item.value() == new_value {
361 let (removed_item, non_normalized_new_addr) = self.btree.remove_at(addr).unwrap();
363 let new_addr = self.btree.normalize(non_normalized_new_addr).unwrap();
364 let item = self.btree.item_mut(new_addr).unwrap();
365 item.key_mut().add(&new_key);
366
367 return (
368 new_addr,
369 self.btree.next_item_address(new_addr),
370 removed_item.into_value(),
371 );
372 }
373 }
374
375 let item = self.btree.item_mut(addr).unwrap();
376 let removed_value = item.set_value(new_value);
377 *item.key_mut() = new_key;
378 (addr, next_addr, removed_value)
379 }
380
381 fn insert_item(
382 &mut self,
383 addr: Address,
384 key: AnyRange<K>,
385 value: V,
386 ) -> (Address, Option<Address>)
387 where
388 K: Clone + PartialEnum + Measure,
389 V: PartialEq,
390 {
391 let next_item = self.btree.item(addr).unwrap();
392 if key.connected_to(next_item.key()) && *next_item.value() == value {
393 let item = self.btree.item_mut(addr).unwrap();
395 item.key_mut().add(&key);
396
397 return (addr, self.btree.next_item_address(addr));
398 }
399
400 let new_addr = self.btree.insert_at(addr, Item::new(key, value));
401 (new_addr, self.btree.next_item_address(new_addr))
402 }
403
404 fn remove_item(&mut self, addr: Address) -> (Address, Option<Address>) {
405 let (_, non_normalized_addr) = self.btree.remove_at(addr).unwrap();
406 let new_addr = self
407 .btree
408 .previous_item_address(non_normalized_addr)
409 .unwrap();
410 (new_addr, self.btree.normalize(non_normalized_addr))
411 }
412
413 pub fn update<R: AsRange<Item = K>, F>(&mut self, key: R, f: F)
414 where
415 K: Clone + PartialEnum + Measure,
416 F: Fn(Option<&V>) -> Option<V>,
417 V: PartialEq + Clone,
418 {
419 let mut key = AnyRange::from(key);
420
421 if key.is_empty() {
422 return;
423 }
424
425 match self.address_of(&key, true) {
426 Ok(mut addr) => {
427 let mut next_addr = self.btree.next_item_address(addr);
428
429 loop {
430 let (prev_addr, prev_next_addr) = {
431 let product = key.product(self.btree.item(addr).unwrap().key()).cloned();
432
433 let mut removed_item_value = None;
434
435 let (addr, next_addr) = match product.after {
436 Some(ProductArg::Subject(key_after)) => {
437 match f(None) {
438 Some(value) => {
439 let (new_addr, new_next_addr, removed_value) =
440 self.set_item(addr, next_addr, key_after, value);
441 removed_item_value = Some(removed_value);
442 (new_addr, new_next_addr)
443 }
444 None => (addr, next_addr), }
446 }
447 Some(ProductArg::Object(item_after)) => {
448 let item = self.btree.item_mut(addr).unwrap();
449 item.set_key(item_after);
450 removed_item_value = Some(item.value().clone());
451 (addr, next_addr)
452 }
453 None => (addr, next_addr), };
455
456 let (addr, next_addr) = match product.intersection {
457 Some(intersection) => {
458 let new_value = match removed_item_value.as_ref() {
459 Some(value) => f(Some(value)),
460 None => f(Some(self.btree.item(addr).unwrap().value())),
461 };
462
463 match new_value {
464 Some(new_value) => {
465 if removed_item_value.is_some() {
466 let (new_addr, new_next_addr) =
467 self.insert_item(addr, intersection, new_value);
468 (new_addr, new_next_addr)
469 } else {
470 let (new_addr, new_next_addr, removed_value) = self
471 .set_item(addr, next_addr, intersection, new_value);
472 removed_item_value = Some(removed_value);
473 (new_addr, new_next_addr)
474 }
475 }
476 None => (addr, next_addr), }
478 }
479 None => (addr, next_addr), };
481
482 match product.before {
483 Some(ProductArg::Subject(key_before)) => {
484 match self.btree.previous_item_address(addr) {
485 Some(prev_addr)
486 if self
487 .btree
488 .item(prev_addr)
489 .unwrap()
490 .key()
491 .connected_to(&key_before) =>
492 {
493 let (prev_addr, addr) = if removed_item_value.is_none() {
494 self.remove_item(addr)
495 } else {
496 (prev_addr, Some(addr))
497 };
498
499 key = key_before;
502 (prev_addr, addr)
503 }
504 _ => {
505 match f(None) {
507 Some(value) => {
508 if removed_item_value.is_some() {
509 self.insert_item(addr, key_before, value);
512 } else {
513 self.set_item(
516 addr, next_addr, key_before, value,
517 );
518 }
519 }
520 None => {
521 if removed_item_value.is_none() {
522 self.btree.remove_at(addr); }
524 }
525 }
526
527 break;
528 }
529 }
530 }
531 Some(ProductArg::Object(item_before)) => {
532 match removed_item_value {
533 Some(value) => {
534 self.insert_item(addr, item_before, value);
535 }
536 None => {
537 self.set_item_key(addr, next_addr, item_before);
538 }
539 }
540
541 break;
542 }
543 None => {
544 match self.btree.previous_item_address(addr) {
545 Some(prev_addr) => {
546 let (prev_addr, addr) = if removed_item_value.is_none() {
547 self.remove_item(addr)
548 } else {
549 (prev_addr, Some(addr))
550 };
551
552 self.merge_forward(prev_addr, addr)
553 }
554 _ => {
555 if removed_item_value.is_none() {
556 self.btree.remove_at(addr).unwrap();
557 }
558 }
559 }
560
561 break;
562 }
563 }
564 };
565
566 addr = prev_addr;
567 next_addr = prev_next_addr;
568 }
569 }
570 Err(addr) => {
571 if let Some(new_value) = f(None) {
573 self.btree.insert_at(addr, Item::new(key, new_value));
574 }
575 }
576 }
577
578 for (range, _) in self.iter() {
579 debug_assert!(!range.is_empty());
580 }
581 }
582
583 pub fn insert_disconnected<R: IntoRange<Item = K>>(
584 &mut self,
585 key: R,
586 value: V,
587 ) -> Result<(), (AnyRange<K>, V)>
588 where
589 K: PartialEnum + Measure,
590 {
591 let key = key.into_range();
592 match self.address_of(&key, true) {
593 Ok(_) => Err((key, value)),
594 Err(addr) => {
595 self.btree.insert_at(addr, Item::new(key, value));
596 Ok(())
597 }
598 }
599 }
600
601 pub fn insert<R: IntoRange<Item = K>>(&mut self, key: R, value: V)
603 where
604 K: Clone + PartialEnum + Measure,
605 V: PartialEq + Clone,
606 {
607 let mut key = key.into_range();
608
609 if key.is_empty() {
610 return;
611 }
612
613 match self.address_of(&key, true) {
614 Ok(mut addr) => {
615 let mut next_addr = self.btree.next_item_address(addr);
617
618 loop {
619 let (prev_addr, prev_next_addr) = {
620 let product = key.product(self.btree.item(addr).unwrap().key()).cloned();
621
622 let mut removed_item_value = None;
623
624 if let Some(ProductArg::Object(item_after)) = product.after {
625 let item = self.btree.item_mut(addr).unwrap();
626 item.set_key(item_after);
627 removed_item_value = Some(item.value().clone());
628 }
629
630 match product.before {
631 Some(ProductArg::Object(item_before)) => {
632 match removed_item_value {
633 Some(old_value) => {
634 if old_value == value {
635 key.add(&item_before);
636 self.insert_item(addr, key, value);
637 } else {
638 let (addr, _) = self.insert_item(addr, key, value);
639 self.insert_item(addr, item_before, old_value);
640 }
641 }
642 None => {
643 if *self.btree.item(addr).unwrap().value() == value {
644 key.add(&item_before);
645 self.set_item_key(addr, next_addr, key);
646 } else {
647 let (_, _, old_value) =
648 self.set_item(addr, next_addr, key, value);
649 self.insert_item(addr, item_before, old_value);
650 }
651 }
652 }
653
654 break;
655 }
656 Some(ProductArg::Subject(_)) | None => {
657 match self.btree.previous_item_address(addr) {
658 Some(prev_addr)
659 if self
660 .btree
661 .item(prev_addr)
662 .unwrap()
663 .key()
664 .connected_to(&key) =>
665 {
666 let (prev_addr, addr) = if removed_item_value.is_none() {
668 self.remove_item(addr)
669 } else {
670 (prev_addr, Some(addr))
671 };
672
673 (prev_addr, addr)
674 }
675 _ => {
676 if removed_item_value.is_some() {
678 self.insert_item(addr, key, value);
679 } else {
680 self.set_item(addr, next_addr, key, value);
681 }
682
683 break;
684 }
685 }
686 }
687 }
688 };
689
690 addr = prev_addr;
691 next_addr = prev_next_addr;
692 }
693 }
694 Err(addr) => {
695 self.btree.insert_at(addr, Item::new(key, value));
697 }
698 }
699 }
700
701 pub fn remove<R: AsRange<Item = K>>(&mut self, key: R)
703 where
704 K: Clone + PartialEnum + Measure,
705 V: Clone,
706 {
707 let key = AnyRange::from(key);
708 if let Ok(mut addr) = self.address_of(&key, false) {
709 loop {
710 if self
711 .btree
712 .item(addr)
713 .map(|item| item.key().intersects(&key))
714 .unwrap_or(false)
715 {
716 match self.btree.item(addr).unwrap().key().without(&key) {
717 Difference::Split(left, right) => {
718 let left = left.cloned();
719 let right = right.cloned();
720
721 let right_value = {
722 let item = self.btree.item_mut(addr).unwrap();
723 *item.key_mut() = right;
724 item.value().clone()
725 };
726 self.btree.insert_at(addr, Item::new(left, right_value));
727 break; }
729 Difference::Before(left, _) => {
730 let left = left.cloned();
731 let item = self.btree.item_mut(addr).unwrap();
732 *item.key_mut() = left;
733 break; }
735 Difference::After(right, _) => {
736 let right = right.cloned();
737 let item = self.btree.item_mut(addr).unwrap();
738 *item.key_mut() = right;
739 }
740 Difference::Empty => {
741 let (_, next_addr) = self.btree.remove_at(addr).unwrap();
742 addr = next_addr
743 }
744 }
745
746 match self.btree.previous_item_address(addr) {
747 Some(prev_addr) => addr = prev_addr,
748 None => break,
749 }
750 } else {
751 break;
752 }
753 }
754 }
755 }
756}
757
758impl<K, V, C: SlabMut<Node<AnyRange<K>, V>>> IntoIterator for RangeMap<K, V, C>
759where
760 C: SimpleCollectionRef,
761 C: SimpleCollectionMut,
762{
763 type Item = (AnyRange<K>, V);
764 type IntoIter = IntoIter<K, V, C>;
765
766 fn into_iter(self) -> Self::IntoIter {
767 self.btree.into_iter()
768 }
769}
770
771pub type Iter<'a, K, V, C> = btree_slab::generic::map::Iter<'a, AnyRange<K>, V, C>;
772pub type IntoIter<K, V, C> = btree_slab::generic::map::IntoIter<AnyRange<K>, V, C>;
773
774pub struct Gaps<'a, K, V, C> {
776 inner: Iter<'a, K, V, C>,
777 prev: Option<std::ops::Bound<&'a K>>,
778 done: bool,
779}
780
781impl<'a, K: Measure + PartialEnum, V, C: Slab<Node<AnyRange<K>, V>>> Iterator for Gaps<'a, K, V, C>
782where
783 C: SimpleCollectionRef,
784{
785 type Item = AnyRange<&'a K>;
786
787 fn next(&mut self) -> Option<Self::Item> {
788 use std::ops::{Bound, RangeBounds};
789
790 if self.done {
791 None
792 } else {
793 loop {
794 match self.inner.next() {
795 Some((range, _)) => {
796 let start = match self.prev.take() {
797 Some(bound) => bound,
798 None => Bound::Unbounded,
799 };
800
801 self.prev = match range.end_bound() {
802 Bound::Unbounded => {
803 self.done = true;
804 None
805 }
806 Bound::Included(t) => Some(Bound::Excluded(t)),
807 Bound::Excluded(t) => Some(Bound::Included(t)),
808 };
809
810 let end = match range.start_bound() {
811 Bound::Unbounded => continue,
812 Bound::Included(t) => Bound::Excluded(t),
813 Bound::Excluded(t) => Bound::Included(t),
814 };
815
816 let gap = AnyRange { start, end };
817
818 if !gap.ref_is_empty() {
819 break Some(gap);
820 }
821 }
822 None => {
823 self.done = true;
824 let start = self.prev.take();
825 match start {
826 Some(bound) => {
827 let gap = AnyRange {
828 start: bound,
829 end: Bound::Unbounded,
830 };
831
832 break if gap.ref_is_empty() { None } else { Some(gap) };
833 }
834 None => {
835 break Some(AnyRange {
836 start: Bound::Unbounded,
837 end: Bound::Unbounded,
838 })
839 }
840 }
841 }
842 }
843 }
844 }
845 }
846}
847
848pub fn binary_search<T: Measure + PartialEnum, U, V, I: AsRef<Item<AnyRange<T>, V>>>(
852 items: &[I],
853 element: &U,
854 connected: bool,
855) -> Option<usize>
856where
857 U: RangePartialOrd<T>,
858{
859 if items.is_empty()
860 || element
861 .range_partial_cmp(items[0].as_ref().key())
862 .unwrap_or(RangeOrdering::Before(false))
863 .is_before(connected)
864 {
865 None
866 } else {
867 let mut i = 0;
868 let mut j = items.len() - 1;
869
870 if !element
871 .range_partial_cmp(items[j].as_ref().key())
872 .unwrap_or(RangeOrdering::After(false))
873 .is_before(connected)
874 {
875 return Some(j);
876 }
877
878 while j - i > 1 {
884 let k = (i + j) / 2;
885
886 if let Some(ord) = element.range_partial_cmp(items[k].as_ref().key()) {
887 if ord.is_before(connected) {
888 j = k;
889 } else {
890 i = k;
891 }
892 } else {
893 return None; }
895 }
896
897 Some(i)
898 }
899}
900
901#[cfg(test)]
902mod tests {
903 use std::{collections::HashSet, ops::Bound};
904
905 use super::*;
906
907 macro_rules! items {
908 [$($item:expr),*] => {
909 &[
910 $(
911 Item::new(AnyRange::from($item), ())
912 ),*
913 ]
914 };
915 }
916
917 #[test]
918 fn binary_search_disconnected_singletons() {
919 assert_eq!(binary_search(items![0], &0, false), Some(0));
920
921 assert_eq!(binary_search(items![0, 2, 4], &0, false), Some(0));
922 assert_eq!(binary_search(items![0, 2, 4], &1, false), Some(0));
923 assert_eq!(binary_search(items![0, 2, 4], &2, false), Some(1));
924 assert_eq!(binary_search(items![0, 2, 4], &3, false), Some(1));
925 assert_eq!(binary_search(items![0, 2, 4], &4, false), Some(2));
926 assert_eq!(binary_search(items![0, 2, 4], &5, false), Some(2));
927
928 assert_eq!(binary_search(items![0, 3, 6], &0, false), Some(0));
929 assert_eq!(binary_search(items![0, 3, 6], &1, false), Some(0));
930 assert_eq!(binary_search(items![0, 3, 6], &2, false), Some(0));
931 assert_eq!(binary_search(items![0, 3, 6], &3, false), Some(1));
932 assert_eq!(binary_search(items![0, 3, 6], &4, false), Some(1));
933 assert_eq!(binary_search(items![0, 3, 6], &5, false), Some(1));
934 assert_eq!(binary_search(items![0, 3, 6], &6, false), Some(2));
935 assert_eq!(binary_search(items![0, 3, 6], &7, false), Some(2));
936 }
937
938 #[test]
939 fn binary_search_disconnected_singletons_float() {
940 assert_eq!(binary_search(items![0.0], &0.0, false), Some(0));
941
942 assert_eq!(binary_search(items![0.0, 2.0, 4.0], &-1.0, false), None);
943 assert_eq!(binary_search(items![0.0, 2.0, 4.0], &0.0, false), Some(0));
944 assert_eq!(binary_search(items![0.0, 2.0, 4.0], &1.0, false), Some(0));
945 assert_eq!(binary_search(items![0.0, 2.0, 4.0], &2.0, false), Some(1));
946 assert_eq!(binary_search(items![0.0, 2.0, 4.0], &3.0, false), Some(1));
947 assert_eq!(binary_search(items![0.0, 2.0, 4.0], &4.0, false), Some(2));
948 assert_eq!(binary_search(items![0.0, 2.0, 4.0], &5.0, false), Some(2));
949
950 assert_eq!(binary_search(items![0.0, 3.0, 6.0], &0.0, false), Some(0));
951 assert_eq!(binary_search(items![0.0, 3.0, 6.0], &1.0, false), Some(0));
952 assert_eq!(binary_search(items![0.0, 3.0, 6.0], &2.0, false), Some(0));
953 assert_eq!(binary_search(items![0.0, 3.0, 6.0], &3.0, false), Some(1));
954 assert_eq!(binary_search(items![0.0, 3.0, 6.0], &4.0, false), Some(1));
955 assert_eq!(binary_search(items![0.0, 3.0, 6.0], &5.0, false), Some(1));
956 assert_eq!(binary_search(items![0.0, 3.0, 6.0], &6.0, false), Some(2));
957 assert_eq!(binary_search(items![0.0, 3.0, 6.0], &7.0, false), Some(2));
958 }
959
960 #[test]
961 fn binary_search_connected_singletons() {
962 assert_eq!(binary_search(items![0], &0, true), Some(0));
963
964 assert_eq!(binary_search(items![0, 2, 4], &0, true), Some(0));
965 assert_eq!(binary_search(items![0, 2, 4], &1, true), Some(1));
966 assert_eq!(binary_search(items![0, 2, 4], &2, true), Some(1));
967 assert_eq!(binary_search(items![0, 2, 4], &3, true), Some(2));
968 assert_eq!(binary_search(items![0, 2, 4], &4, true), Some(2));
969 assert_eq!(binary_search(items![0, 2, 4], &5, true), Some(2));
970 assert_eq!(binary_search(items![2, 4, 8], &0, true), None);
971
972 assert_eq!(binary_search(items![0, 3, 6], &0, true), Some(0));
973 assert_eq!(binary_search(items![0, 3, 6], &1, true), Some(0));
974 assert_eq!(binary_search(items![0, 3, 6], &2, true), Some(1));
975 assert_eq!(binary_search(items![0, 3, 6], &3, true), Some(1));
976 assert_eq!(binary_search(items![0, 3, 6], &4, true), Some(1));
977 assert_eq!(binary_search(items![0, 3, 6], &5, true), Some(2));
978 assert_eq!(binary_search(items![0, 3, 6], &6, true), Some(2));
979 assert_eq!(binary_search(items![0, 3, 6], &7, true), Some(2));
980 }
981
982 #[test]
984 fn binary_search_connected_singletons_float() {
985 assert_eq!(binary_search(items![0.0], &0.0, true), Some(0));
986
987 assert_eq!(binary_search(items![0.0, 2.0, 4.0], &-1.0, true), None);
988 assert_eq!(binary_search(items![0.0, 2.0, 4.0], &0.0, true), Some(0));
989 assert_eq!(binary_search(items![0.0, 2.0, 4.0], &1.0, true), Some(0));
990 assert_eq!(binary_search(items![0.0, 2.0, 4.0], &2.0, true), Some(1));
991 assert_eq!(binary_search(items![0.0, 2.0, 4.0], &3.0, true), Some(1));
992 assert_eq!(binary_search(items![0.0, 2.0, 4.0], &4.0, true), Some(2));
993 assert_eq!(binary_search(items![0.0, 2.0, 4.0], &5.0, true), Some(2));
994
995 assert_eq!(binary_search(items![0.0, 3.0, 6.0], &0.0, true), Some(0));
996 assert_eq!(binary_search(items![0.0, 3.0, 6.0], &1.0, true), Some(0));
997 assert_eq!(binary_search(items![0.0, 3.0, 6.0], &2.0, true), Some(0));
998 assert_eq!(binary_search(items![0.0, 3.0, 6.0], &3.0, true), Some(1));
999 assert_eq!(binary_search(items![0.0, 3.0, 6.0], &4.0, true), Some(1));
1000 assert_eq!(binary_search(items![0.0, 3.0, 6.0], &5.0, true), Some(1));
1001 assert_eq!(binary_search(items![0.0, 3.0, 6.0], &6.0, true), Some(2));
1002 assert_eq!(binary_search(items![0.0, 3.0, 6.0], &7.0, true), Some(2));
1003 }
1004
1005 #[test]
1006 fn insert() {
1007 let mut map: crate::RangeMap<char, usize> = crate::RangeMap::new();
1008
1009 map.insert('+', 0);
1010 map.insert('-', 1);
1011 map.insert('0'..='9', 2);
1012 map.insert('.', 3);
1013
1014 assert_eq!(*map.get('.').unwrap(), 3)
1015 }
1016
1017 #[test]
1018 fn insert_around() {
1019 let mut map: crate::RangeMap<char, usize> = crate::RangeMap::new();
1020
1021 map.insert(' ', 0);
1022 map.insert('#', 1);
1023 map.insert('e', 2);
1024 map.insert('%', 3);
1025 map.insert('A'..='Z', 4);
1026 map.insert('a'..='z', 5);
1027
1028 assert!(map.get('a').is_some())
1029 }
1030
1031 #[test]
1032 fn update_connected_after() {
1033 let mut map: crate::RangeMap<char, usize> = crate::RangeMap::new();
1034
1035 map.insert('+', 0);
1036 map.insert('-', 1);
1037 map.insert('0'..='9', 2);
1038 map.update('.', |binding| {
1039 assert!(binding.is_none());
1040 Some(3)
1041 });
1042
1043 assert_eq!(*map.get('.').unwrap(), 3)
1044 }
1045
1046 #[test]
1047 fn update_singleton() {
1048 let mut map: crate::RangeMap<char, usize> = crate::RangeMap::new();
1049
1050 map.insert('*', 0);
1051 map.update('*', |_| Some(1));
1052
1053 assert_eq!(map.iter().count(), 1);
1054 assert_eq!(map.get('*'), Some(&1))
1055 }
1056
1057 #[test]
1058 fn update_connected_before() {
1059 let mut map: crate::RangeMap<char, usize> = crate::RangeMap::new();
1060
1061 map.insert('+', 0);
1062 map.insert('.', 1);
1063 map.insert('0'..='9', 2);
1064 map.update('-', |binding| {
1065 assert!(binding.is_none());
1066 Some(3)
1067 });
1068
1069 assert_eq!(map.iter().count(), 4);
1070 assert_eq!(*map.get('-').unwrap(), 3)
1071 }
1072
1073 #[test]
1074 fn update_around() {
1075 let mut map: crate::RangeMap<char, usize> = crate::RangeMap::new();
1076
1077 map.insert('e', 0);
1078 map.update('a'..='z', |_| Some(1));
1079
1080 assert_eq!(map.iter().count(), 1);
1081 assert_eq!(map.get('a'), Some(&1))
1082 }
1083
1084 #[test]
1085 fn update_stress() {
1086 let ranges = [
1087 ','..=',',
1104 ';'..=';',
1105 '='..='=',
1106 ':'..=':',
1107 '\''..='\'',
1126 '('..='(',
1127 ')'..=')',
1128 '*'..='*',
1129 '+'..='+',
1130 ];
1139
1140 let mut map: crate::RangeMap<char, Vec<usize>> = crate::RangeMap::new();
1141
1142 for (i, range) in ranges.into_iter().enumerate() {
1143 map.update(range, |current| {
1144 let mut list = current.cloned().unwrap_or_default();
1145 list.push(i);
1146 Some(list)
1147 });
1148 }
1149
1150 eprintln!("before: {map:?}");
1151
1152 map.update(','..=',', |current| {
1153 let mut list = current.cloned().unwrap_or_default();
1154 list.push(9);
1155 Some(list)
1156 });
1157
1158 eprintln!("after: {map:?}");
1159
1160 let mut found_ranges = HashSet::new();
1161 for (range, _) in map.iter() {
1162 eprintln!("looking for range: {range:?}");
1163 assert!(found_ranges.insert(range))
1164 }
1165 }
1166
1167 #[test]
1168 fn update_stress2() {
1169 let mut map: crate::RangeMap<char, usize> = crate::RangeMap::new();
1170
1171 map.insert('+'..='+', 0);
1172 map.insert(AnyRange::new(Bound::Excluded('+'), Bound::Included(',')), 1);
1173 map.update(','..=',', |_| Some(2));
1174
1175 let mut found_ranges = HashSet::new();
1176 for (range, _) in map.iter() {
1177 eprintln!("looking for range: {range:?}");
1178 assert!(found_ranges.insert(range))
1179 }
1180 }
1181
1182 #[test]
1183 fn update_test() {
1184 let mut map: crate::RangeMap<char, usize> = crate::RangeMap::new();
1185
1186 map.insert('0'..='9', 0);
1187 map.insert(
1188 AnyRange::new(Bound::Excluded('\''), Bound::Included('(')),
1189 1,
1190 );
1191 map.insert(AnyRange::new(Bound::Excluded('('), Bound::Included(')')), 2);
1192 map.insert(AnyRange::new(Bound::Excluded(')'), Bound::Included('*')), 3);
1193 map.insert('+', 4);
1194 map.insert(',', 5);
1195 map.insert('-', 6);
1196 map.insert('.', 7);
1197 map.insert('/', 8);
1198
1199 assert_eq!(map.range_count(), 9);
1200 assert_eq!(map.iter().count(), 9);
1201
1202 map.update(
1203 AnyRange::new(Bound::Excluded('\''), Bound::Included('(')),
1204 |_| Some(10),
1205 );
1206 map.update(
1207 AnyRange::new(Bound::Excluded('('), Bound::Included(')')),
1208 |_| Some(11),
1209 );
1210 map.update(
1211 AnyRange::new(Bound::Excluded(')'), Bound::Included('*')),
1212 |_| Some(12),
1213 );
1214
1215 assert_eq!(map.range_count(), 9);
1216 assert_eq!(map.iter().count(), 9);
1217
1218 }
1231}