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