Skip to main content

btree_range_map/generic/
map.rs

1use super::Node;
2use crate::{
3	AnyRange, AsRange, IntoRange, RangeOrdering, RangePartialOrd,
4	range::{Difference, ProductArg},
5};
6use range_traits::{Bounded, Measure, PartialEnum};
7use raw_btree::{Address, Item, RawBTree, Storage, node::Offset};
8use std::{
9	cmp::{Ord, Ordering, PartialOrd},
10	fmt,
11	hash::{Hash, Hasher},
12};
13
14/// Range map.
15pub struct RangeMap<K, V, C: Storage<Item<AnyRange<K>, V>>> {
16	btree: RawBTree<Item<AnyRange<K>, V>, C>,
17}
18
19impl<K: Clone, V: Clone, C: Storage<Item<AnyRange<K>, V>>> Clone for RangeMap<K, V, C> {
20	fn clone(&self) -> Self {
21		RangeMap {
22			btree: self.btree.clone(),
23		}
24	}
25}
26
27impl<K, V, C: Storage<Item<AnyRange<K>, V>>> RangeMap<K, V, C> {
28	/// Create a new empty map.
29	pub fn new() -> RangeMap<K, V, C> {
30		RangeMap {
31			btree: RawBTree::new(),
32		}
33	}
34}
35
36impl<K, V, C: Storage<Item<AnyRange<K>, V>>> Default for RangeMap<K, V, C> {
37	fn default() -> Self {
38		Self::new()
39	}
40}
41
42pub struct CandidateOffset<N> {
43	pub offset: Result<Offset, Offset>,
44	pub node: Option<N>,
45}
46
47impl<K, V, C: Storage<Item<AnyRange<K>, V>>> RangeMap<K, V, C> {
48	pub fn len(&self) -> K::Len
49	where
50		K: Measure + PartialEnum + Bounded,
51	{
52		let mut len = K::Len::default();
53		for (range, _) in self {
54			len = len + range.len()
55		}
56
57		len
58	}
59
60	pub fn bounded_len(&self) -> Option<K::Len>
61	where
62		K: Measure + PartialEnum,
63	{
64		let mut len = K::Len::default();
65		for (range, _) in self {
66			len = len + range.bounded_len()?
67		}
68
69		Some(len)
70	}
71
72	pub fn is_empty(&self) -> bool
73	where
74		K: Measure + PartialEnum,
75	{
76		self.bounded_len() == Some(K::Len::default())
77	}
78
79	pub fn range_count(&self) -> usize {
80		self.btree.len()
81	}
82
83	fn address_of<T>(
84		&self,
85		key: &T,
86		connected: bool,
87	) -> Result<Address<C::Node>, Option<Address<C::Node>>>
88	where
89		K: PartialEnum + Measure,
90		T: RangePartialOrd<K>,
91	{
92		if connected && let Ok(addr) = self.address_of(key, false) {
93			return Ok(addr);
94		}
95
96		match self.btree.root() {
97			Some(id) => self.address_in(id, key, connected).map_err(Some),
98			None => Err(None),
99		}
100	}
101
102	fn address_in<T>(
103		&self,
104		mut id: C::Node,
105		key: &T,
106		connected: bool,
107	) -> Result<Address<C::Node>, Address<C::Node>>
108	where
109		K: PartialEnum + Measure,
110		T: RangePartialOrd<K>,
111	{
112		let mut candidate = None;
113
114		loop {
115			match self.offset_in(id, key, connected) {
116				CandidateOffset {
117					offset: Ok(offset),
118					node: None,
119				} => {
120					// Found the best match!
121					return Ok(Address::new(id, offset));
122				}
123				CandidateOffset {
124					offset: Ok(offset),
125					node: Some(child_id),
126				} => {
127					// Found a candidate, but a better one may be deeper in the tree.
128					candidate = Some(Address::new(id, offset));
129					id = child_id;
130				}
131				CandidateOffset {
132					offset: Err(_),
133					node: Some(child_id),
134				} => {
135					// No candidate here, but one may be deeper in the tree.
136					id = child_id;
137				}
138				CandidateOffset {
139					offset: Err(offset),
140					node: None,
141				} => {
142					// We won't find any more candidates.
143					return candidate.ok_or(Address::new(id, offset));
144				}
145			}
146		}
147	}
148
149	fn offset_in<T>(&self, id: C::Node, key: &T, connected: bool) -> CandidateOffset<C::Node>
150	where
151		K: PartialEnum + Measure,
152		T: RangePartialOrd<K>,
153	{
154		match unsafe { self.btree.node(id) } {
155			Node::Internal(node) => {
156				let branches = node.branches();
157				match binary_search(branches, key, connected) {
158					Some(i) => {
159						let b = &branches[i];
160						if key
161							.range_partial_cmp(&b.item.key)
162							.unwrap_or(RangeOrdering::After(false))
163							.matches(connected)
164						{
165							CandidateOffset {
166								offset: Ok(i.into()),
167								node: Some(b.child),
168							}
169						} else {
170							CandidateOffset {
171								offset: Err(i.into()),
172								node: Some(b.child),
173							}
174						}
175					}
176					None => CandidateOffset {
177						offset: Err(0.into()),
178						node: Some(node.first_child_id()),
179					},
180				}
181			}
182			Node::Leaf(leaf) => {
183				let items = leaf.items();
184				match binary_search(items, key, connected) {
185					Some(i) => {
186						let item = &items[i];
187						let ord = key
188							.range_partial_cmp(&item.key)
189							.unwrap_or(RangeOrdering::After(false));
190						if ord.matches(connected) {
191							CandidateOffset {
192								offset: Ok(i.into()),
193								node: None,
194							}
195						} else {
196							CandidateOffset {
197								offset: Err((i + 1).into()),
198								node: None,
199							}
200						}
201					}
202					None => CandidateOffset {
203						offset: Err(0.into()),
204						node: None,
205					},
206				}
207			}
208		}
209	}
210
211	/// # Complexity
212	///
213	/// `O(log n)`, where `n` is the number of ranges in the map
214	/// ([`Self::range_count`]). A single top-down search through the B-tree
215	/// locates the (at most one) range intersecting `key`.
216	pub fn intersects<R: AsRange<Item = K>>(&self, key: R) -> bool
217	where
218		K: PartialEnum + Measure,
219		V: PartialEq,
220	{
221		// let key = AnyRange::from(key);
222
223		if key.is_empty() {
224			false
225		} else {
226			self.address_of(&key, false).is_ok()
227		}
228	}
229
230	/// # Complexity
231	///
232	/// `O(log n)`, where `n` is the number of ranges in the map
233	/// ([`Self::range_count`]). Same single-search cost as [`Self::get`].
234	pub fn contains_key(&self, key: K) -> bool
235	where
236		K: PartialEnum + RangePartialOrd + Measure,
237	{
238		self.address_of(&key, false).is_ok()
239	}
240
241	/// # Complexity
242	///
243	/// `O(log n)`, where `n` is the number of ranges in the map
244	/// ([`Self::range_count`]). A single top-down binary search through the
245	/// B-tree locates the range containing `key`.
246	pub fn get(&self, key: K) -> Option<&V>
247	where
248		K: PartialEnum + RangePartialOrd + Measure,
249	{
250		match self.address_of(&key, false) {
251			Ok(addr) => Some(&unsafe { self.btree.get_at(addr) }.unwrap().value),
252			Err(_) => None,
253		}
254	}
255
256	pub fn iter(&self) -> Iter<'_, K, V, C> {
257		Iter {
258			inner: self.btree.iter(),
259		}
260	}
261
262	/// Returns an iterator over the gaps (unbounded keys) of the map.
263	pub fn gaps(&self) -> Gaps<'_, K, V, C> {
264		Gaps {
265			inner: self.iter(),
266			prev: None,
267			done: false,
268		}
269	}
270}
271
272impl<K: fmt::Debug, V: fmt::Debug, C: Storage<Item<AnyRange<K>, V>>> fmt::Debug
273	for RangeMap<K, V, C>
274{
275	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
276		write!(f, "{{")?;
277
278		for (range, value) in self {
279			write!(f, "{:?}=>{:?}", range, value)?
280		}
281
282		write!(f, "}}")
283	}
284}
285
286impl<K, V, C, D> PartialEq<RangeMap<K, V, D>> for RangeMap<K, V, C>
287where
288	K: Measure + PartialOrd + PartialEnum,
289	V: PartialEq,
290	C: Storage<Item<AnyRange<K>, V>>,
291	D: Storage<Item<AnyRange<K>, V>>,
292{
293	fn eq(&self, other: &RangeMap<K, V, D>) -> bool {
294		self.iter().eq(other.iter())
295	}
296}
297
298impl<K, V, C: Storage<Item<AnyRange<K>, V>>> Eq for RangeMap<K, V, C>
299where
300	K: Measure + PartialEnum + Ord,
301	V: Eq,
302{
303}
304
305impl<K, V, C, D> PartialOrd<RangeMap<K, V, D>> for RangeMap<K, V, C>
306where
307	K: Measure + PartialOrd + PartialEnum,
308	V: PartialOrd,
309	C: Storage<Item<AnyRange<K>, V>>,
310	D: Storage<Item<AnyRange<K>, V>>,
311{
312	fn partial_cmp(&self, other: &RangeMap<K, V, D>) -> Option<Ordering> {
313		self.iter().partial_cmp(other.iter())
314	}
315}
316
317impl<K, V, C: Storage<Item<AnyRange<K>, V>>> Ord for RangeMap<K, V, C>
318where
319	K: Measure + PartialEnum + Ord,
320	V: Ord,
321{
322	fn cmp(&self, other: &Self) -> Ordering {
323		self.iter().cmp(other.iter())
324	}
325}
326
327impl<K, V, C: Storage<Item<AnyRange<K>, V>>> Hash for RangeMap<K, V, C>
328where
329	K: Hash + PartialEnum,
330	V: Hash,
331{
332	fn hash<H: Hasher>(&self, h: &mut H) {
333		for range in self {
334			range.hash(h)
335		}
336	}
337}
338
339impl<'a, K, V, C: Storage<Item<AnyRange<K>, V>>> IntoIterator for &'a RangeMap<K, V, C> {
340	type Item = (&'a AnyRange<K>, &'a V);
341	type IntoIter = Iter<'a, K, V, C>;
342
343	fn into_iter(self) -> Self::IntoIter {
344		self.iter()
345	}
346}
347
348impl<K, V, C: Storage<Item<AnyRange<K>, V>>> RangeMap<K, V, C> {
349	fn merge_forward(&mut self, addr: Address<C::Node>, next_addr: Option<Address<C::Node>>)
350	where
351		K: Clone + PartialEnum + Measure,
352		V: PartialEq,
353	{
354		if let Some(next_addr) = next_addr {
355			// SAFETY: `addr` is a valid address in this tree.
356			let item = unsafe { self.btree.get_at(addr) }.unwrap();
357			// SAFETY: `next_addr` is a valid address in this tree.
358			let next_item = unsafe { self.btree.get_at(next_addr) }.unwrap();
359			if item.key.connected_to(&next_item.key) && item.value == next_item.value {
360				// SAFETY: `addr` is a valid address in this tree.
361				let (removed_item, non_normalized_new_addr) =
362					unsafe { self.btree.remove_at(addr) }.unwrap();
363				let new_addr = non_normalized_new_addr
364					.and_then(|a| {
365						// SAFETY: `a` was just returned by `remove_at` as a valid address.
366						unsafe { self.btree.normalize(a) }
367					})
368					.unwrap();
369				// SAFETY: `new_addr` was just returned by `normalize` as a valid address.
370				let item = unsafe { self.btree.get_mut_at(new_addr) }.unwrap();
371				item.key.add(&removed_item.key);
372			}
373		}
374	}
375
376	fn set_item_key(
377		&mut self,
378		addr: Address<C::Node>,
379		next_addr: Option<Address<C::Node>>,
380		new_key: AnyRange<K>,
381	) -> (Address<C::Node>, Option<Address<C::Node>>)
382	where
383		K: Clone + PartialEnum + Measure,
384		V: PartialEq,
385	{
386		if let Some(next_addr) = next_addr {
387			// SAFETY: `next_addr` is a valid address in this tree.
388			let next_item = unsafe { self.btree.get_at(next_addr) }.unwrap();
389			// SAFETY: `addr` is a valid address in this tree.
390			let addr_value = &unsafe { self.btree.get_at(addr) }.unwrap().value;
391			if new_key.connected_to(&next_item.key) && next_item.value == *addr_value {
392				// Merge with the next item.
393				// SAFETY: `addr` is a valid address in this tree.
394				let (_, non_normalized_new_addr) = unsafe { self.btree.remove_at(addr) }.unwrap();
395				let new_addr = non_normalized_new_addr
396					.and_then(|a| {
397						// SAFETY: `a` was just returned by `remove_at` as a valid address.
398						unsafe { self.btree.normalize(a) }
399					})
400					.unwrap();
401				// SAFETY: `new_addr` was just returned by `normalize` as a valid address.
402				let item = unsafe { self.btree.get_mut_at(new_addr) }.unwrap();
403				item.key.add(&new_key);
404
405				// SAFETY: `new_addr` was just returned by `normalize` as a valid address.
406				let next_addr = unsafe { self.btree.next_item_address(new_addr) };
407				return (new_addr, next_addr);
408			}
409		}
410
411		// SAFETY: `addr` is a valid address in this tree.
412		let item = unsafe { self.btree.get_mut_at(addr) }.unwrap();
413		item.key = new_key;
414		(addr, next_addr)
415	}
416
417	fn set_item(
418		&mut self,
419		addr: Address<C::Node>,
420		next_addr: Option<Address<C::Node>>,
421		new_key: AnyRange<K>,
422		new_value: V,
423	) -> SetItem<C::Node, V>
424	where
425		K: Clone + PartialEnum + Measure,
426		V: PartialEq,
427	{
428		if let Some(next_addr) = next_addr {
429			// SAFETY: `next_addr` is a valid address in this tree.
430			let next_item = unsafe { self.btree.get_at(next_addr) }.unwrap();
431			if new_key.connected_to(&next_item.key) && next_item.value == new_value {
432				// Merge with the next item.
433				// SAFETY: `addr` is a valid address in this tree.
434				let (removed_item, non_normalized_new_addr) =
435					unsafe { self.btree.remove_at(addr) }.unwrap();
436				let new_addr = non_normalized_new_addr
437					.and_then(|a| {
438						// SAFETY: `a` was just returned by `remove_at` as a valid address.
439						unsafe { self.btree.normalize(a) }
440					})
441					.unwrap();
442				// SAFETY: `new_addr` was just returned by `normalize` as a valid address.
443				let item = unsafe { self.btree.get_mut_at(new_addr) }.unwrap();
444				item.key.add(&new_key);
445
446				// SAFETY: `new_addr` was just returned by `normalize` as a valid address.
447				let after_addr = unsafe { self.btree.next_item_address(new_addr) };
448				return SetItem::new(new_addr, after_addr, removed_item.value);
449			}
450		}
451
452		// SAFETY: `addr` is a valid address in this tree.
453		let item = unsafe { self.btree.get_mut_at(addr) }.unwrap();
454		let removed_value = std::mem::replace(&mut item.value, new_value);
455		item.key = new_key;
456		SetItem::new(addr, next_addr, removed_value)
457	}
458
459	fn insert_item(
460		&mut self,
461		addr: Address<C::Node>,
462		key: AnyRange<K>,
463		value: V,
464	) -> (Address<C::Node>, Option<Address<C::Node>>)
465	where
466		K: Clone + PartialEnum + Measure,
467		V: PartialEq,
468	{
469		// SAFETY: `addr` is a valid address in this tree.
470		let next_item = unsafe { self.btree.get_at(addr) }.unwrap();
471		if key.connected_to(&next_item.key) && next_item.value == value {
472			// Merge with the next item.
473			// SAFETY: `addr` is a valid address in this tree.
474			let item = unsafe { self.btree.get_mut_at(addr) }.unwrap();
475			item.key.add(&key);
476
477			// SAFETY: `addr` is a valid address in this tree.
478			let next_addr = unsafe { self.btree.next_item_address(addr) };
479			return (addr, next_addr);
480		}
481
482		// SAFETY: `addr` is a valid address in this tree (`Some` is always
483		// returned by `insert_at` when inserting, since insertion can only
484		// overflow a node, never leave the tree empty).
485		let new_addr = unsafe { self.btree.insert_at(Some(addr), Item::new(key, value)) }.unwrap();
486		// SAFETY: `new_addr` was just returned by `insert_at` as a valid address.
487		let next_addr = unsafe { self.btree.next_item_address(new_addr) };
488		(new_addr, next_addr)
489	}
490
491	fn remove_item(
492		&mut self,
493		addr: Address<C::Node>,
494	) -> (Address<C::Node>, Option<Address<C::Node>>) {
495		// SAFETY: `addr` is a valid address in this tree.
496		let (_, non_normalized_addr) = unsafe { self.btree.remove_at(addr) }.unwrap();
497		let non_normalized_addr = non_normalized_addr.expect("range map unexpectedly became empty");
498		// SAFETY: `non_normalized_addr` was just returned by `remove_at` as a
499		// valid address.
500		let new_addr = unsafe { self.btree.previous_item_address(non_normalized_addr) }.unwrap();
501		// SAFETY: `non_normalized_addr` was just returned by `remove_at` as a
502		// valid address.
503		let normalized_addr = unsafe { self.btree.normalize(non_normalized_addr) };
504		(new_addr, normalized_addr)
505	}
506
507	/// # Complexity
508	///
509	/// `O((k + 1) log n)`, where `n` is the number of ranges in the map
510	/// ([`Self::range_count`]) and `k` is the number of existing ranges that
511	/// overlap, or are connected to, `key`. Each of the `k` affected ranges is
512	/// merged, split or removed with one `O(log n)` B-tree operation, on top
513	/// of the initial `O(log n)` lookup. This is `O(log n)` when `key` only
514	/// touches a handful of existing ranges (the common case), and `O(n log
515	/// n)` in the worst case (`key` overlaps or connects to every stored
516	/// range). This primitive underlies
517	/// [`RangeMultiMap::insert`](crate::generic::RangeMultiMap::insert) and
518	/// [`RangeMultiMap::remove`](crate::generic::RangeMultiMap::remove).
519	pub fn update<R: AsRange<Item = K>, F>(&mut self, key: R, f: F)
520	where
521		K: Clone + PartialEnum + Measure,
522		F: Fn(Option<&V>) -> Option<V>,
523		V: PartialEq + Clone,
524	{
525		let mut key = AnyRange::from(key);
526
527		if key.is_empty() {
528			return;
529		}
530
531		match self.address_of(&key, true) {
532			Ok(mut addr) => {
533				// SAFETY: `addr` is a valid address in this tree.
534				let mut next_addr = unsafe { self.btree.next_item_address(addr) };
535
536				loop {
537					let (prev_addr, prev_next_addr) = {
538						// SAFETY: `addr` is a valid address in this tree.
539						let addr_key = &unsafe { self.btree.get_at(addr) }.unwrap().key;
540						let product = key.product(addr_key).cloned();
541
542						let mut removed_item_value = None;
543
544						let (addr, next_addr) = match product.after {
545							Some(ProductArg::Subject(key_after)) => {
546								match f(None) {
547									Some(value) => {
548										let SetItem {
549											new_addr,
550											new_next_addr,
551											removed_value,
552										} = self.set_item(addr, next_addr, key_after, value);
553										removed_item_value = Some(removed_value);
554										(new_addr, new_next_addr)
555									}
556									None => (addr, next_addr), // we wait the last minute to remove the item.
557								}
558							}
559							Some(ProductArg::Object(item_after)) => {
560								// SAFETY: `addr` is a valid address in this tree.
561								let item = unsafe { self.btree.get_mut_at(addr) }.unwrap();
562								item.key = item_after;
563								removed_item_value = Some(item.value.clone());
564								(addr, next_addr)
565							}
566							None => (addr, next_addr), // we wait the last minute to remove the item.
567						};
568
569						let (addr, next_addr) = match product.intersection {
570							Some(intersection) => {
571								let new_value = match removed_item_value.as_ref() {
572									Some(value) => f(Some(value)),
573									None => {
574										// SAFETY: `addr` is a valid address in this tree.
575										let value =
576											&unsafe { self.btree.get_at(addr) }.unwrap().value;
577										f(Some(value))
578									}
579								};
580
581								match new_value {
582									Some(new_value) => {
583										if removed_item_value.is_some() {
584											let (new_addr, new_next_addr) =
585												self.insert_item(addr, intersection, new_value);
586											(new_addr, new_next_addr)
587										} else {
588											let SetItem {
589												new_addr,
590												new_next_addr,
591												removed_value,
592											} = self.set_item(
593												addr,
594												next_addr,
595												intersection,
596												new_value,
597											);
598											removed_item_value = Some(removed_value);
599											(new_addr, new_next_addr)
600										}
601									}
602									None => (addr, next_addr), // we wait the last minute to remove the item.
603								}
604							}
605							None => (addr, next_addr), // we wait the last minute to remove the item.
606						};
607
608						match product.before {
609							Some(ProductArg::Subject(key_before)) => {
610								// SAFETY: `addr` is a valid address in this tree. The
611								// closure is only ever called with `prev_addr` values
612								// returned by `previous_item_address` itself.
613								let prev = unsafe { self.btree.previous_item_address(addr) }
614									.filter(|&prev_addr| {
615										// SAFETY: `prev_addr` was just returned by
616										// `previous_item_address` as a valid address.
617										unsafe { self.btree.get_at(prev_addr) }
618											.unwrap()
619											.key
620											.connected_to(&key_before)
621									});
622
623								match prev {
624									Some(prev_addr) => {
625										let (prev_addr, addr) = if removed_item_value.is_none() {
626											self.remove_item(addr)
627										} else {
628											(prev_addr, Some(addr))
629										};
630
631										// Let's go for another turn!
632										// One item back this time.
633										key = key_before;
634										(prev_addr, addr)
635									}
636									None => {
637										// there is no previous connected item, we must insert here!
638										match f(None) {
639											Some(value) => {
640												if removed_item_value.is_some() {
641													// we cannot reuse the item
642													// insert
643													self.insert_item(addr, key_before, value);
644												} else {
645													// we can reuse the item
646													// reuse
647													self.set_item(
648														addr, next_addr, key_before, value,
649													);
650												}
651											}
652											None => {
653												if removed_item_value.is_none() {
654													// finally remove the item.
655													// SAFETY: `addr` is a valid address in this tree.
656													unsafe { self.btree.remove_at(addr) };
657												}
658											}
659										}
660
661										break;
662									}
663								}
664							}
665							Some(ProductArg::Object(item_before)) => {
666								match removed_item_value {
667									Some(value) => {
668										self.insert_item(addr, item_before, value);
669									}
670									None => {
671										self.set_item_key(addr, next_addr, item_before);
672									}
673								}
674
675								break;
676							}
677							None => {
678								// SAFETY: `addr` is a valid address in this tree.
679								match unsafe { self.btree.previous_item_address(addr) } {
680									Some(prev_addr) => {
681										let (prev_addr, addr) = if removed_item_value.is_none() {
682											self.remove_item(addr)
683										} else {
684											(prev_addr, Some(addr))
685										};
686
687										self.merge_forward(prev_addr, addr)
688									}
689									_ => {
690										if removed_item_value.is_none() {
691											// SAFETY: `addr` is a valid address in this tree.
692											unsafe { self.btree.remove_at(addr) }.unwrap();
693										}
694									}
695								}
696
697								break;
698							}
699						}
700					};
701
702					addr = prev_addr;
703					next_addr = prev_next_addr;
704				}
705			}
706			Err(addr) => {
707				// case (G)
708				if let Some(new_value) = f(None) {
709					// SAFETY: `addr` is `None` only if the tree is empty, which
710					// `insert_at` handles.
711					unsafe { self.btree.insert_at(addr, Item::new(key, new_value)) };
712				}
713			}
714		}
715	}
716
717	pub fn insert_disconnected<R: IntoRange<Item = K>>(
718		&mut self,
719		key: R,
720		value: V,
721	) -> Result<(), (AnyRange<K>, V)>
722	where
723		K: PartialEnum + Measure,
724	{
725		let key = key.into_range();
726		match self.address_of(&key, true) {
727			Ok(_) => Err((key, value)),
728			Err(addr) => {
729				unsafe {
730					self.btree.insert_at(addr, Item::new(key, value));
731				}
732				Ok(())
733			}
734		}
735	}
736
737	/// Insert a new key-value binding.
738	///
739	/// # Complexity
740	///
741	/// `O((k + 1) log n)`, where `n` is the number of ranges in the map
742	/// ([`Self::range_count`]) and `k` is the number of existing ranges that
743	/// overlap, or are connected to, `key`. Each of the `k` affected ranges is
744	/// merged, split or replaced with one `O(log n)` B-tree operation, on top
745	/// of the initial `O(log n)` lookup. Usually `O(log n)`; worst case (e.g.
746	/// inserting a range spanning the whole map) is `O(n log n)`.
747	pub fn insert<R: IntoRange<Item = K>>(&mut self, key: R, value: V)
748	where
749		K: Clone + PartialEnum + Measure,
750		V: PartialEq + Clone,
751	{
752		let mut key = key.into_range();
753
754		if key.is_empty() {
755			return;
756		}
757
758		match self.address_of(&key, true) {
759			Ok(mut addr) => {
760				// let mut value = Some(value);
761				// SAFETY: `addr` is a valid address in this tree.
762				let mut next_addr = unsafe { self.btree.next_item_address(addr) };
763
764				loop {
765					let (prev_addr, prev_next_addr) = {
766						// SAFETY: `addr` is a valid address in this tree.
767						let addr_key = &unsafe { self.btree.get_at(addr) }.unwrap().key;
768						let product = key.product(addr_key).cloned();
769
770						let mut removed_item_value = None;
771
772						if let Some(ProductArg::Object(item_after)) = product.after {
773							// SAFETY: `addr` is a valid address in this tree.
774							let item = unsafe { self.btree.get_mut_at(addr) }.unwrap();
775							item.key = item_after;
776							removed_item_value = Some(item.value.clone());
777						}
778
779						match product.before {
780							Some(ProductArg::Object(item_before)) => {
781								match removed_item_value {
782									Some(old_value) => {
783										if old_value == value {
784											key.add(&item_before);
785											self.insert_item(addr, key, value);
786										} else {
787											let (addr, _) = self.insert_item(addr, key, value);
788											self.insert_item(addr, item_before, old_value);
789										}
790									}
791									None => {
792										// SAFETY: `addr` is a valid address in this tree.
793										let addr_value =
794											&unsafe { self.btree.get_at(addr) }.unwrap().value;
795										if *addr_value == value {
796											key.add(&item_before);
797											self.set_item_key(addr, next_addr, key);
798										} else {
799											let old_value = self
800												.set_item(addr, next_addr, key, value)
801												.removed_value;
802											self.insert_item(addr, item_before, old_value);
803										}
804									}
805								}
806
807								break;
808							}
809							Some(ProductArg::Subject(_)) | None => {
810								// SAFETY: `addr` is a valid address in this tree. The
811								// closure is only ever called with `prev_addr` values
812								// returned by `previous_item_address` itself.
813								let prev = unsafe { self.btree.previous_item_address(addr) }
814									.filter(|&prev_addr| {
815										// SAFETY: `prev_addr` was just returned by
816										// `previous_item_address` as a valid address.
817										unsafe { self.btree.get_at(prev_addr) }
818											.unwrap()
819											.key
820											.connected_to(&key)
821									});
822
823								match prev {
824									Some(prev_addr) => {
825										// We can move one to the previous item.
826										let (prev_addr, addr) = if removed_item_value.is_none() {
827											self.remove_item(addr)
828										} else {
829											(prev_addr, Some(addr))
830										};
831
832										(prev_addr, addr)
833									}
834									None => {
835										// There is no previous item, we must get it done now.
836										if removed_item_value.is_some() {
837											self.insert_item(addr, key, value);
838										} else {
839											self.set_item(addr, next_addr, key, value);
840										}
841
842										break;
843									}
844								}
845							}
846						}
847					};
848
849					addr = prev_addr;
850					next_addr = prev_next_addr;
851				}
852			}
853			Err(addr) => {
854				// case (G)
855				// SAFETY: `addr` is `None` only if the tree is empty, which
856				// `insert_at` handles.
857				unsafe { self.btree.insert_at(addr, Item::new(key, value)) };
858			}
859		}
860	}
861
862	/// Remove a key.
863	///
864	/// # Complexity
865	///
866	/// `O((k + 1) log n)`, where `n` is the number of ranges in the map
867	/// ([`Self::range_count`]) and `k` is the number of existing ranges that
868	/// intersect `key`. Each intersecting range costs one `O(log n)` B-tree
869	/// operation (split, shrink or removal), on top of the initial `O(log n)`
870	/// lookup. Usually `O(log n)`; worst case (`key` intersects every stored
871	/// range) is `O(n log n)`.
872	pub fn remove<R: AsRange<Item = K>>(&mut self, key: R)
873	where
874		K: Clone + PartialEnum + Measure,
875		V: Clone,
876	{
877		let key = AnyRange::from(key);
878		if let Ok(mut addr) = self.address_of(&key, false) {
879			loop {
880				// SAFETY: `addr` is a valid address in this tree.
881				let intersects = unsafe { self.btree.get_at(addr) }
882					.map(|item| item.key.intersects(&key))
883					.unwrap_or(false);
884
885				if intersects {
886					// SAFETY: `addr` is a valid address in this tree.
887					let difference = unsafe { self.btree.get_at(addr) }
888						.unwrap()
889						.key
890						.without(&key);
891					match difference {
892						Difference::Split(left, right) => {
893							let left = left.cloned();
894							let right = right.cloned();
895
896							let right_value = {
897								// SAFETY: `addr` is a valid address in this tree.
898								let item = unsafe { self.btree.get_mut_at(addr) }.unwrap();
899								item.key = right;
900								item.value.clone()
901							};
902							// SAFETY: `addr` is a valid address in this tree.
903							unsafe {
904								self.btree
905									.insert_at(Some(addr), Item::new(left, right_value))
906							};
907							break; // no need to go further, the removed range was totaly included in this one.
908						}
909						Difference::Before(left, _) => {
910							let left = left.cloned();
911							// SAFETY: `addr` is a valid address in this tree.
912							let item = unsafe { self.btree.get_mut_at(addr) }.unwrap();
913							item.key = left;
914							break; // no need to go further, the removed range does not intersect anything below this range.
915						}
916						Difference::After(right, _) => {
917							let right = right.cloned();
918							// SAFETY: `addr` is a valid address in this tree.
919							let item = unsafe { self.btree.get_mut_at(addr) }.unwrap();
920							item.key = right;
921						}
922						Difference::Empty => {
923							// SAFETY: `addr` is a valid address in this tree.
924							let (_, next_addr) = unsafe { self.btree.remove_at(addr) }.unwrap();
925							match next_addr {
926								Some(next_addr) => addr = next_addr,
927								None => break,
928							}
929						}
930					}
931
932					// SAFETY: `addr` is a valid address in this tree.
933					match unsafe { self.btree.previous_item_address(addr) } {
934						Some(prev_addr) => addr = prev_addr,
935						None => break,
936					}
937				} else {
938					break;
939				}
940			}
941		}
942	}
943}
944
945struct SetItem<N, V> {
946	new_addr: Address<N>,
947	new_next_addr: Option<Address<N>>,
948	removed_value: V,
949}
950
951impl<N, V> SetItem<N, V> {
952	fn new(new_addr: Address<N>, new_next_addr: Option<Address<N>>, removed_value: V) -> Self {
953		SetItem {
954			new_addr,
955			new_next_addr,
956			removed_value,
957		}
958	}
959}
960
961impl<N, V> From<SetItem<N, V>> for (Address<N>, Option<Address<N>>, V) {
962	fn from(item: SetItem<N, V>) -> Self {
963		(item.new_addr, item.new_next_addr, item.removed_value)
964	}
965}
966
967impl<K, V, C: Storage<Item<AnyRange<K>, V>>> IntoIterator for RangeMap<K, V, C> {
968	type Item = (AnyRange<K>, V);
969	type IntoIter = IntoIter<K, V, C>;
970
971	fn into_iter(self) -> Self::IntoIter {
972		IntoIter {
973			inner: self.btree.into_iter(),
974		}
975	}
976}
977
978/// Iterator over the entries of a `RangeMap`.
979pub struct Iter<'a, K, V, C: Storage<Item<AnyRange<K>, V>>> {
980	inner: raw_btree::Iter<'a, Item<AnyRange<K>, V>, C>,
981}
982
983impl<'a, K, V, C: Storage<Item<AnyRange<K>, V>>> Iterator for Iter<'a, K, V, C> {
984	type Item = (&'a AnyRange<K>, &'a V);
985
986	fn next(&mut self) -> Option<Self::Item> {
987		self.inner.next().map(Item::as_pair)
988	}
989
990	fn size_hint(&self) -> (usize, Option<usize>) {
991		self.inner.size_hint()
992	}
993}
994
995impl<'a, K, V, C: Storage<Item<AnyRange<K>, V>>> DoubleEndedIterator for Iter<'a, K, V, C> {
996	fn next_back(&mut self) -> Option<Self::Item> {
997		self.inner.next_back().map(Item::as_pair)
998	}
999}
1000
1001impl<'a, K, V, C: Storage<Item<AnyRange<K>, V>>> ExactSizeIterator for Iter<'a, K, V, C> {}
1002
1003impl<'a, K, V, C: Storage<Item<AnyRange<K>, V>>> Clone for Iter<'a, K, V, C> {
1004	fn clone(&self) -> Self {
1005		Iter { inner: self.inner }
1006	}
1007}
1008
1009/// Consuming iterator over the entries of a `RangeMap`.
1010pub struct IntoIter<K, V, C: Storage<Item<AnyRange<K>, V>>> {
1011	inner: raw_btree::IntoIter<Item<AnyRange<K>, V>, C>,
1012}
1013
1014impl<K, V, C: Storage<Item<AnyRange<K>, V>>> Iterator for IntoIter<K, V, C> {
1015	type Item = (AnyRange<K>, V);
1016
1017	fn next(&mut self) -> Option<Self::Item> {
1018		self.inner.next().map(Item::into_pair)
1019	}
1020
1021	fn size_hint(&self) -> (usize, Option<usize>) {
1022		self.inner.size_hint()
1023	}
1024}
1025
1026impl<K, V, C: Storage<Item<AnyRange<K>, V>>> DoubleEndedIterator for IntoIter<K, V, C> {
1027	fn next_back(&mut self) -> Option<Self::Item> {
1028		self.inner.next_back().map(Item::into_pair)
1029	}
1030}
1031
1032impl<K, V, C: Storage<Item<AnyRange<K>, V>>> ExactSizeIterator for IntoIter<K, V, C> {}
1033
1034/// Iterator over the gaps (unbound keys) of a `RangeMap`.
1035pub struct Gaps<'a, K, V, C: Storage<Item<AnyRange<K>, V>>> {
1036	inner: Iter<'a, K, V, C>,
1037	prev: Option<std::ops::Bound<&'a K>>,
1038	done: bool,
1039}
1040
1041impl<'a, K: Measure + PartialEnum, V, C: Storage<Item<AnyRange<K>, V>>> Iterator
1042	for Gaps<'a, K, V, C>
1043{
1044	type Item = AnyRange<&'a K>;
1045
1046	fn next(&mut self) -> Option<Self::Item> {
1047		use std::ops::{Bound, RangeBounds};
1048
1049		if self.done {
1050			None
1051		} else {
1052			loop {
1053				match self.inner.next() {
1054					Some((range, _)) => {
1055						let start = match self.prev.take() {
1056							Some(bound) => bound,
1057							None => Bound::Unbounded,
1058						};
1059
1060						self.prev = match range.end_bound() {
1061							Bound::Unbounded => {
1062								self.done = true;
1063								None
1064							}
1065							Bound::Included(t) => Some(Bound::Excluded(t)),
1066							Bound::Excluded(t) => Some(Bound::Included(t)),
1067						};
1068
1069						let end = match range.start_bound() {
1070							Bound::Unbounded => continue,
1071							Bound::Included(t) => Bound::Excluded(t),
1072							Bound::Excluded(t) => Bound::Included(t),
1073						};
1074
1075						let gap = AnyRange { start, end };
1076
1077						if !gap.ref_is_empty() {
1078							break Some(gap);
1079						}
1080					}
1081					None => {
1082						self.done = true;
1083						let start = self.prev.take();
1084						match start {
1085							Some(bound) => {
1086								let gap = AnyRange {
1087									start: bound,
1088									end: Bound::Unbounded,
1089								};
1090
1091								break if gap.ref_is_empty() { None } else { Some(gap) };
1092							}
1093							None => {
1094								break Some(AnyRange {
1095									start: Bound::Unbounded,
1096									end: Bound::Unbounded,
1097								});
1098							}
1099						}
1100					}
1101				}
1102			}
1103		}
1104	}
1105}
1106
1107/// Search for the index of the greatest item less/below or equal/including the given element.
1108///
1109/// If `connected` is `true`, then it will search for the greatest item less/below or equal/including **or connected to** the given element.
1110pub fn binary_search<T: Measure + PartialEnum, U, V, I: AsRef<Item<AnyRange<T>, V>>>(
1111	items: &[I],
1112	element: &U,
1113	connected: bool,
1114) -> Option<usize>
1115where
1116	U: RangePartialOrd<T>,
1117{
1118	if items.is_empty()
1119		|| element
1120			.range_partial_cmp(&items[0].as_ref().key)
1121			.unwrap_or(RangeOrdering::Before(false))
1122			.is_before(connected)
1123	{
1124		None
1125	} else {
1126		let mut i = 0;
1127		let mut j = items.len() - 1;
1128
1129		if !element
1130			.range_partial_cmp(&items[j].as_ref().key)
1131			.unwrap_or(RangeOrdering::After(false))
1132			.is_before(connected)
1133		{
1134			return Some(j);
1135		}
1136
1137		// invariants:
1138		// vec[i].as_ref().key() < range
1139		// vec[j].as_ref().key() >= range
1140		// j > i
1141
1142		while j - i > 1 {
1143			let k = (i + j) / 2;
1144
1145			{
1146				let ord = element.range_partial_cmp(&items[k].as_ref().key)?;
1147				if ord.is_before(connected) {
1148					j = k;
1149				} else {
1150					i = k;
1151				}
1152			}
1153		}
1154
1155		Some(i)
1156	}
1157}
1158
1159#[cfg(test)]
1160mod tests {
1161	use std::{collections::HashSet, ops::Bound};
1162
1163	use super::*;
1164
1165	macro_rules! items {
1166		[$($item:expr),*] => {
1167			&[
1168				$(
1169					Item::new(AnyRange::from($item), ())
1170				),*
1171			]
1172		};
1173	}
1174
1175	#[test]
1176	fn binary_search_disconnected_singletons() {
1177		assert_eq!(binary_search(items![0], &0, false), Some(0));
1178
1179		assert_eq!(binary_search(items![0, 2, 4], &0, false), Some(0));
1180		assert_eq!(binary_search(items![0, 2, 4], &1, false), Some(0));
1181		assert_eq!(binary_search(items![0, 2, 4], &2, false), Some(1));
1182		assert_eq!(binary_search(items![0, 2, 4], &3, false), Some(1));
1183		assert_eq!(binary_search(items![0, 2, 4], &4, false), Some(2));
1184		assert_eq!(binary_search(items![0, 2, 4], &5, false), Some(2));
1185
1186		assert_eq!(binary_search(items![0, 3, 6], &0, false), Some(0));
1187		assert_eq!(binary_search(items![0, 3, 6], &1, false), Some(0));
1188		assert_eq!(binary_search(items![0, 3, 6], &2, false), Some(0));
1189		assert_eq!(binary_search(items![0, 3, 6], &3, false), Some(1));
1190		assert_eq!(binary_search(items![0, 3, 6], &4, false), Some(1));
1191		assert_eq!(binary_search(items![0, 3, 6], &5, false), Some(1));
1192		assert_eq!(binary_search(items![0, 3, 6], &6, false), Some(2));
1193		assert_eq!(binary_search(items![0, 3, 6], &7, false), Some(2));
1194	}
1195
1196	#[test]
1197	fn binary_search_disconnected_singletons_float() {
1198		assert_eq!(binary_search(items![0.0], &0.0, false), Some(0));
1199
1200		assert_eq!(binary_search(items![0.0, 2.0, 4.0], &-1.0, false), None);
1201		assert_eq!(binary_search(items![0.0, 2.0, 4.0], &0.0, false), Some(0));
1202		assert_eq!(binary_search(items![0.0, 2.0, 4.0], &1.0, false), Some(0));
1203		assert_eq!(binary_search(items![0.0, 2.0, 4.0], &2.0, false), Some(1));
1204		assert_eq!(binary_search(items![0.0, 2.0, 4.0], &3.0, false), Some(1));
1205		assert_eq!(binary_search(items![0.0, 2.0, 4.0], &4.0, false), Some(2));
1206		assert_eq!(binary_search(items![0.0, 2.0, 4.0], &5.0, false), Some(2));
1207
1208		assert_eq!(binary_search(items![0.0, 3.0, 6.0], &0.0, false), Some(0));
1209		assert_eq!(binary_search(items![0.0, 3.0, 6.0], &1.0, false), Some(0));
1210		assert_eq!(binary_search(items![0.0, 3.0, 6.0], &2.0, false), Some(0));
1211		assert_eq!(binary_search(items![0.0, 3.0, 6.0], &3.0, false), Some(1));
1212		assert_eq!(binary_search(items![0.0, 3.0, 6.0], &4.0, false), Some(1));
1213		assert_eq!(binary_search(items![0.0, 3.0, 6.0], &5.0, false), Some(1));
1214		assert_eq!(binary_search(items![0.0, 3.0, 6.0], &6.0, false), Some(2));
1215		assert_eq!(binary_search(items![0.0, 3.0, 6.0], &7.0, false), Some(2));
1216	}
1217
1218	#[test]
1219	fn binary_search_connected_singletons() {
1220		assert_eq!(binary_search(items![0], &0, true), Some(0));
1221
1222		assert_eq!(binary_search(items![0, 2, 4], &0, true), Some(0));
1223		assert_eq!(binary_search(items![0, 2, 4], &1, true), Some(1));
1224		assert_eq!(binary_search(items![0, 2, 4], &2, true), Some(1));
1225		assert_eq!(binary_search(items![0, 2, 4], &3, true), Some(2));
1226		assert_eq!(binary_search(items![0, 2, 4], &4, true), Some(2));
1227		assert_eq!(binary_search(items![0, 2, 4], &5, true), Some(2));
1228		assert_eq!(binary_search(items![2, 4, 8], &0, true), None);
1229
1230		assert_eq!(binary_search(items![0, 3, 6], &0, true), Some(0));
1231		assert_eq!(binary_search(items![0, 3, 6], &1, true), Some(0));
1232		assert_eq!(binary_search(items![0, 3, 6], &2, true), Some(1));
1233		assert_eq!(binary_search(items![0, 3, 6], &3, true), Some(1));
1234		assert_eq!(binary_search(items![0, 3, 6], &4, true), Some(1));
1235		assert_eq!(binary_search(items![0, 3, 6], &5, true), Some(2));
1236		assert_eq!(binary_search(items![0, 3, 6], &6, true), Some(2));
1237		assert_eq!(binary_search(items![0, 3, 6], &7, true), Some(2));
1238	}
1239
1240	// for floats, connected or disconnected makes no difference for singletons.
1241	#[test]
1242	fn binary_search_connected_singletons_float() {
1243		assert_eq!(binary_search(items![0.0], &0.0, true), Some(0));
1244
1245		assert_eq!(binary_search(items![0.0, 2.0, 4.0], &-1.0, true), None);
1246		assert_eq!(binary_search(items![0.0, 2.0, 4.0], &0.0, true), Some(0));
1247		assert_eq!(binary_search(items![0.0, 2.0, 4.0], &1.0, true), Some(0));
1248		assert_eq!(binary_search(items![0.0, 2.0, 4.0], &2.0, true), Some(1));
1249		assert_eq!(binary_search(items![0.0, 2.0, 4.0], &3.0, true), Some(1));
1250		assert_eq!(binary_search(items![0.0, 2.0, 4.0], &4.0, true), Some(2));
1251		assert_eq!(binary_search(items![0.0, 2.0, 4.0], &5.0, true), Some(2));
1252
1253		assert_eq!(binary_search(items![0.0, 3.0, 6.0], &0.0, true), Some(0));
1254		assert_eq!(binary_search(items![0.0, 3.0, 6.0], &1.0, true), Some(0));
1255		assert_eq!(binary_search(items![0.0, 3.0, 6.0], &2.0, true), Some(0));
1256		assert_eq!(binary_search(items![0.0, 3.0, 6.0], &3.0, true), Some(1));
1257		assert_eq!(binary_search(items![0.0, 3.0, 6.0], &4.0, true), Some(1));
1258		assert_eq!(binary_search(items![0.0, 3.0, 6.0], &5.0, true), Some(1));
1259		assert_eq!(binary_search(items![0.0, 3.0, 6.0], &6.0, true), Some(2));
1260		assert_eq!(binary_search(items![0.0, 3.0, 6.0], &7.0, true), Some(2));
1261	}
1262
1263	#[test]
1264	fn insert() {
1265		let mut map: crate::RangeMap<char, usize> = crate::RangeMap::new();
1266
1267		map.insert('+', 0);
1268		map.insert('-', 1);
1269		map.insert('0'..='9', 2);
1270		map.insert('.', 3);
1271
1272		assert_eq!(*map.get('.').unwrap(), 3)
1273	}
1274
1275	#[test]
1276	fn insert_around() {
1277		let mut map: crate::RangeMap<char, usize> = crate::RangeMap::new();
1278
1279		map.insert(' ', 0);
1280		map.insert('#', 1);
1281		map.insert('e', 2);
1282		map.insert('%', 3);
1283		map.insert('A'..='Z', 4);
1284		map.insert('a'..='z', 5);
1285
1286		assert!(map.get('a').is_some())
1287	}
1288
1289	#[test]
1290	fn update_connected_after() {
1291		let mut map: crate::RangeMap<char, usize> = crate::RangeMap::new();
1292
1293		map.insert('+', 0);
1294		map.insert('-', 1);
1295		map.insert('0'..='9', 2);
1296		map.update('.', |binding| {
1297			assert!(binding.is_none());
1298			Some(3)
1299		});
1300
1301		assert_eq!(*map.get('.').unwrap(), 3)
1302	}
1303
1304	#[test]
1305	fn update_singleton() {
1306		let mut map: crate::RangeMap<char, usize> = crate::RangeMap::new();
1307
1308		map.insert('*', 0);
1309		map.update('*', |_| Some(1));
1310
1311		assert_eq!(map.iter().count(), 1);
1312		assert_eq!(map.get('*'), Some(&1))
1313	}
1314
1315	#[test]
1316	fn update_connected_before() {
1317		let mut map: crate::RangeMap<char, usize> = crate::RangeMap::new();
1318
1319		map.insert('+', 0);
1320		map.insert('.', 1);
1321		map.insert('0'..='9', 2);
1322		map.update('-', |binding| {
1323			assert!(binding.is_none());
1324			Some(3)
1325		});
1326
1327		assert_eq!(map.iter().count(), 4);
1328		assert_eq!(*map.get('-').unwrap(), 3)
1329	}
1330
1331	#[test]
1332	fn update_around() {
1333		let mut map: crate::RangeMap<char, usize> = crate::RangeMap::new();
1334
1335		map.insert('e', 0);
1336		map.update('a'..='z', |_| Some(1));
1337
1338		assert_eq!(map.iter().count(), 1);
1339		assert_eq!(map.get('a'), Some(&1))
1340	}
1341
1342	#[test]
1343	fn update_stress() {
1344		let ranges = [
1345			// 'A'..='Z',
1346			// 'a'..='z',
1347			// '0'..='9',
1348			// '-'..='-',
1349			// '.'..='.',
1350			// '_'..='_',
1351			// '~'..='~',
1352			// '%'..='%',
1353			// '!'..='!',
1354			// '$'..='$',
1355			// '&'..='&',
1356			// '\''..='\'',
1357			// '('..='(',
1358			// ')'..=')',
1359			// '*'..='*',
1360			// '+'..='+',
1361			','..=',',
1362			';'..=';',
1363			'='..='=',
1364			':'..=':',
1365			// '@'..='@',
1366			// '['..='[',
1367			// '0'..='9',
1368			// '1'..='9',
1369			// '1'..='1',
1370			// '2'..='2',
1371			// '2'..='2',
1372			// 'A'..='Z',
1373			// 'a'..='z',
1374			// '0'..='9',
1375			// '-'..='-',
1376			// '.'..='.',
1377			// '_'..='_',
1378			// '~'..='~',
1379			// '%'..='%',
1380			// '!'..='!',
1381			// '$'..='$',
1382			// '&'..='&',
1383			'\''..='\'',
1384			'('..='(',
1385			')'..=')',
1386			'*'..='*',
1387			'+'..='+',
1388			// ','..=',',
1389
1390			// ';'..=';',
1391			// '='..='=',
1392			// ':'..=':',
1393			// '/'..='/',
1394			// '?'..='?',
1395			// '#'..='#'
1396		];
1397
1398		let mut map: crate::RangeMap<char, Vec<usize>> = crate::RangeMap::new();
1399
1400		for (i, range) in ranges.into_iter().enumerate() {
1401			map.update(range, |current| {
1402				let mut list = current.cloned().unwrap_or_default();
1403				list.push(i);
1404				Some(list)
1405			});
1406		}
1407
1408		eprintln!("before: {map:?}");
1409
1410		map.update(','..=',', |current| {
1411			let mut list = current.cloned().unwrap_or_default();
1412			list.push(9);
1413			Some(list)
1414		});
1415
1416		eprintln!("after: {map:?}");
1417
1418		let mut found_ranges = HashSet::new();
1419		for (range, _) in map.iter() {
1420			eprintln!("looking for range: {range:?}");
1421			assert!(found_ranges.insert(range))
1422		}
1423	}
1424
1425	#[test]
1426	fn update_stress2() {
1427		let mut map: crate::RangeMap<char, usize> = crate::RangeMap::new();
1428
1429		map.insert('+'..='+', 0);
1430		map.insert(AnyRange::new(Bound::Excluded('+'), Bound::Included(',')), 1);
1431		map.update(','..=',', |_| Some(2));
1432
1433		let mut found_ranges = HashSet::new();
1434		for (range, _) in map.iter() {
1435			eprintln!("looking for range: {range:?}");
1436			assert!(found_ranges.insert(range))
1437		}
1438	}
1439
1440	#[test]
1441	fn update_test() {
1442		let mut map: crate::RangeMap<char, usize> = crate::RangeMap::new();
1443
1444		map.insert('0'..='9', 0);
1445		map.insert(
1446			AnyRange::new(Bound::Excluded('\''), Bound::Included('(')),
1447			1,
1448		);
1449		map.insert(AnyRange::new(Bound::Excluded('('), Bound::Included(')')), 2);
1450		map.insert(AnyRange::new(Bound::Excluded(')'), Bound::Included('*')), 3);
1451		map.insert('+', 4);
1452		map.insert(',', 5);
1453		map.insert('-', 6);
1454		map.insert('.', 7);
1455		map.insert('/', 8);
1456
1457		assert_eq!(map.range_count(), 9);
1458		assert_eq!(map.iter().count(), 9);
1459
1460		map.update(
1461			AnyRange::new(Bound::Excluded('\''), Bound::Included('(')),
1462			|_| Some(10),
1463		);
1464		map.update(
1465			AnyRange::new(Bound::Excluded('('), Bound::Included(')')),
1466			|_| Some(11),
1467		);
1468		map.update(
1469			AnyRange::new(Bound::Excluded(')'), Bound::Included('*')),
1470			|_| Some(12),
1471		);
1472
1473		assert_eq!(map.range_count(), 9);
1474		assert_eq!(map.iter().count(), 9);
1475
1476		// let mut ranges = map.iter();
1477		// let (a, _) = ranges.next().unwrap();
1478		// assert_eq!(a.first(), Some('('));
1479		// assert_eq!(a.last(), Some(')'));
1480
1481		// let (b, _) = ranges.next().unwrap();
1482		// assert_eq!(b.first(), Some('*'));
1483		// assert_eq!(b.last(), Some('*'));
1484
1485		// let (c, _) = ranges.next().unwrap();
1486		// assert_eq!(c.first(), Some('+'));
1487		// assert_eq!(c.last(), Some('9'));
1488	}
1489
1490	/// Reproduces an overlapping-ranges bug found by folding a single wide
1491	/// range (`'0'..='9'`) into a map that already has several separate
1492	/// single-character entries (`'1'..='1'`, `'2'..='2'`, ..., `'9'..='9'`),
1493	/// each mapped to a *distinct* value, via repeated calls to `update`.
1494	/// `update` merges values on overlap. The resulting map must always be a
1495	/// proper partition of the key space: no two entries may overlap.
1496	#[test]
1497	fn update_digit_fanout() {
1498		use std::collections::BTreeSet;
1499
1500		let mut map: crate::RangeMap<char, BTreeSet<i32>> = crate::RangeMap::new();
1501
1502		// Simulate the `DIGIT` rule: one wide range, single target `0`.
1503		map.update('0'..='9', |current: Option<&BTreeSet<i32>>| {
1504			let mut set = current.cloned().unwrap_or_default();
1505			set.insert(0);
1506			Some(set)
1507		});
1508
1509		// Simulate the `NZDIGIT` rule's fan-out: one single-char range per
1510		// literal, each with a *distinct* target id (as would arise from
1511		// Thompson's construction of an alternation of literals).
1512		for (i, c) in ('1'..='9').enumerate() {
1513			let id = 100 + i as i32;
1514			map.update(c..=c, move |current: Option<&BTreeSet<i32>>| {
1515				let mut set = current.cloned().unwrap_or_default();
1516				set.insert(id);
1517				Some(set)
1518			});
1519		}
1520
1521		for (range, set) in map.iter() {
1522			eprintln!("{range:?} -> {set:?}");
1523		}
1524
1525		let entries: Vec<_> = map.iter().collect();
1526		for i in 0..entries.len() {
1527			for j in (i + 1)..entries.len() {
1528				assert!(
1529					!entries[i].0.intersects(entries[j].0),
1530					"overlapping ranges: {:?} and {:?}",
1531					entries[i].0,
1532					entries[j].0
1533				);
1534			}
1535		}
1536
1537		// Every digit must be covered by exactly the union of `{0}` and
1538		// whichever `NZDIGIT` literal (if any) matches it.
1539		for c in '0'..='9' {
1540			let set = map.get(c).unwrap_or_else(|| panic!("no entry for {c:?}"));
1541			assert!(
1542				set.contains(&0),
1543				"digit {c:?} should always contain 0, got {set:?}"
1544			);
1545		}
1546	}
1547
1548	/// Same scenario as [`update_digit_fanout`], but with the single-character
1549	/// updates applied *before* the wide range update.
1550	///
1551	/// This used to reproduce a bug in `RangeMap`'s `address_in`/`offset_in`
1552	/// binary search: once *9* (but not fewer - see the loop below)
1553	/// pre-existing, adjacent, distinctly-valued single-item ranges existed
1554	/// in the map, the tree grew an internal node (the Knuth order is
1555	/// `M = 8`), and `address_of` would stop as soon as it found a match on
1556	/// an *internal separator* item instead of also checking that
1557	/// separator's right subtree for an even further-right match. Folding a
1558	/// wider range on top of all 9 items via `update` would then only walk
1559	/// backward from that separator, silently skipping every item to its
1560	/// right (`'6'..='6'`, `'7'..='7'`, `'8'..='8'`, `'9'..='9'`), leaving
1561	/// them orphaned while a bogus `'5'..='9'` entry appeared over them.
1562	fn digit_fanout_reversed_with_count(n: u32) {
1563		use std::collections::BTreeSet;
1564
1565		let mut map: crate::RangeMap<char, BTreeSet<i32>> = crate::RangeMap::new();
1566
1567		let digits: Vec<char> = ('1'..='9').take(n as usize).collect();
1568
1569		for (i, &c) in digits.iter().enumerate() {
1570			let id = 100 + i as i32;
1571			map.update(c..=c, move |current: Option<&BTreeSet<i32>>| {
1572				let mut set = current.cloned().unwrap_or_default();
1573				set.insert(id);
1574				Some(set)
1575			});
1576		}
1577
1578		let last = *digits.last().unwrap();
1579		map.update('0'..=last, |current: Option<&BTreeSet<i32>>| {
1580			let mut set = current.cloned().unwrap_or_default();
1581			set.insert(0);
1582			Some(set)
1583		});
1584
1585		println!("-- n = {n} --");
1586		for (range, set) in map.iter() {
1587			println!("{range:?} -> {set:?}");
1588		}
1589
1590		let entries: Vec<_> = map.iter().collect();
1591		for i in 0..entries.len() {
1592			for j in (i + 1)..entries.len() {
1593				assert!(
1594					!entries[i].0.intersects(entries[j].0),
1595					"n={n}: overlapping ranges: {:?} and {:?}",
1596					entries[i].0,
1597					entries[j].0
1598				);
1599			}
1600		}
1601	}
1602
1603	/// Regression test for the overlapping-ranges bug that motivated the
1604	/// switch from `btree-slab` to `raw-btree`: see
1605	/// [`digit_fanout_reversed_with_count`]. This now passes at every `n`.
1606	#[test]
1607	fn update_digit_fanout_reversed() {
1608		for n in 1..=9 {
1609			digit_fanout_reversed_with_count(n);
1610		}
1611	}
1612}