btree_range_map/generic/
map.rs

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/// Range map.
19#[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	/// Create a new empty map.
26	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		// let key = AnyRange::from(key);
169
170		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	/// Returns an iterator over the gaps (unbounded keys) of the map.
199	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				// Merge with the next item.
333				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				// Merge with the next item.
362				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			// Merge with the next item.
394			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), // we wait the last minute to remove the item.
445								}
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), // we wait the last minute to remove the item.
454						};
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), // we wait the last minute to remove the item.
477								}
478							}
479							None => (addr, next_addr), // we wait the last minute to remove the item.
480						};
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										// Let's go for another turn!
500										// One item back this time.
501										key = key_before;
502										(prev_addr, addr)
503									}
504									_ => {
505										// there is no previous connected item, we must insert here!
506										match f(None) {
507											Some(value) => {
508												if removed_item_value.is_some() {
509													// we cannot reuse the item
510													// insert
511													self.insert_item(addr, key_before, value);
512												} else {
513													// we can reuse the item
514													// reuse
515													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); // finally remove the item.
523												}
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				// case (G)
572				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	/// Insert a new key-value binding.
602	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 value = Some(value);
616				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										// We can move one to the previous item.
667										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										// There is no previous item, we must get it done now.
677										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				// case (G)
696				self.btree.insert_at(addr, Item::new(key, value));
697			}
698		}
699	}
700
701	/// Remove a key.
702	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; // no need to go further, the removed range was totaly included in this one.
728						}
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; // no need to go further, the removed range does not intersect anything below this range.
734						}
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
774/// Iterator over the gaps (unbound keys) of a `RangeMap`.
775pub 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
848/// Search for the index of the gratest item less/below or equal/including the given element.
849///
850/// If `connected` is `true`, then it will search for the gratest item less/below or equal/including **or connected to** the given element.
851pub 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		// invariants:
879		// vec[i].as_ref().key() < range
880		// vec[j].as_ref().key() >= range
881		// j > i
882
883		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; // FIXME: that's bad. Maybe we should expect a total order.
894			}
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	// for floats, connected or disconnected makes no difference for singletons.
983	#[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			// 'A'..='Z',
1088			// 'a'..='z',
1089			// '0'..='9',
1090			// '-'..='-',
1091			// '.'..='.',
1092			// '_'..='_',
1093			// '~'..='~',
1094			// '%'..='%',
1095			// '!'..='!',
1096			// '$'..='$',
1097			// '&'..='&',
1098			// '\''..='\'',
1099			// '('..='(',
1100			// ')'..=')',
1101			// '*'..='*',
1102			// '+'..='+',
1103			','..=',',
1104			';'..=';',
1105			'='..='=',
1106			':'..=':',
1107			// '@'..='@',
1108			// '['..='[',
1109			// '0'..='9',
1110			// '1'..='9',
1111			// '1'..='1',
1112			// '2'..='2',
1113			// '2'..='2',
1114			// 'A'..='Z',
1115			// 'a'..='z',
1116			// '0'..='9',
1117			// '-'..='-',
1118			// '.'..='.',
1119			// '_'..='_',
1120			// '~'..='~',
1121			// '%'..='%',
1122			// '!'..='!',
1123			// '$'..='$',
1124			// '&'..='&',
1125			'\''..='\'',
1126			'('..='(',
1127			')'..=')',
1128			'*'..='*',
1129			'+'..='+',
1130			// ','..=',',
1131
1132			// ';'..=';',
1133			// '='..='=',
1134			// ':'..=':',
1135			// '/'..='/',
1136			// '?'..='?',
1137			// '#'..='#'
1138		];
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		// let mut ranges = map.iter();
1219		// let (a, _) = ranges.next().unwrap();
1220		// assert_eq!(a.first(), Some('('));
1221		// assert_eq!(a.last(), Some(')'));
1222
1223		// let (b, _) = ranges.next().unwrap();
1224		// assert_eq!(b.first(), Some('*'));
1225		// assert_eq!(b.last(), Some('*'));
1226
1227		// let (c, _) = ranges.next().unwrap();
1228		// assert_eq!(c.first(), Some('+'));
1229		// assert_eq!(c.last(), Some('9'));
1230	}
1231}