btree_slab/generic/
node.rs

1use std::{borrow::Borrow, cmp::Ordering, fmt};
2
3mod addr;
4pub mod internal;
5mod item;
6mod leaf;
7
8pub use addr::Address;
9pub use internal::Internal as InternalNode;
10pub use item::Item;
11pub use leaf::Leaf as LeafNode;
12
13/// Type identifier by a key.
14///
15/// This is implemented by [`Item`] and [`internal::Branch`].
16pub trait Keyed {
17	type Key;
18
19	fn key(&self) -> &Self::Key;
20}
21
22/// Offset in a node.
23#[derive(Clone, Copy, PartialEq, Eq, Hash)]
24pub struct Offset(usize);
25
26impl Offset {
27	pub fn before() -> Offset {
28		Offset(usize::MAX)
29	}
30
31	pub fn is_before(&self) -> bool {
32		self.0 == usize::MAX
33	}
34
35	pub fn value(&self) -> Option<usize> {
36		if self.0 == usize::MAX {
37			None
38		} else {
39			Some(self.0)
40		}
41	}
42
43	pub fn unwrap(self) -> usize {
44		if self.0 == usize::MAX {
45			panic!("Offset out of bounds")
46		} else {
47			self.0
48		}
49	}
50
51	pub fn incr(&mut self) {
52		if self.0 == usize::MAX {
53			self.0 = 0
54		} else {
55			self.0 += 1
56		}
57	}
58
59	pub fn decr(&mut self) {
60		if self.0 == 0 {
61			self.0 = usize::MAX
62		} else {
63			self.0 -= 1
64		}
65	}
66}
67
68impl PartialOrd for Offset {
69	fn partial_cmp(&self, offset: &Offset) -> Option<Ordering> {
70		if self.0 == usize::MAX || offset.0 == usize::MAX {
71			if self.0 == usize::MAX && offset.0 == usize::MAX {
72				Some(Ordering::Equal)
73			} else if self.0 == usize::MAX {
74				Some(Ordering::Less)
75			} else {
76				Some(Ordering::Greater)
77			}
78		} else {
79			self.0.partial_cmp(&offset.0)
80		}
81	}
82}
83
84impl Ord for Offset {
85	fn cmp(&self, offset: &Offset) -> Ordering {
86		if self.0 == usize::MAX || offset.0 == usize::MAX {
87			if self.0 == usize::MAX && offset.0 == usize::MAX {
88				Ordering::Equal
89			} else if self.0 == usize::MAX {
90				Ordering::Less
91			} else {
92				Ordering::Greater
93			}
94		} else {
95			self.0.cmp(&offset.0)
96		}
97	}
98}
99
100impl PartialEq<usize> for Offset {
101	fn eq(&self, offset: &usize) -> bool {
102		self.0 != usize::MAX && self.0 == *offset
103	}
104}
105
106impl PartialOrd<usize> for Offset {
107	fn partial_cmp(&self, offset: &usize) -> Option<Ordering> {
108		if self.0 == usize::MAX {
109			Some(Ordering::Less)
110		} else {
111			self.0.partial_cmp(offset)
112		}
113	}
114}
115
116impl From<usize> for Offset {
117	fn from(offset: usize) -> Offset {
118		Offset(offset)
119	}
120}
121
122impl fmt::Display for Offset {
123	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
124		if self.0 == usize::MAX {
125			write!(f, "-1")
126		} else {
127			self.0.fmt(f)
128		}
129	}
130}
131
132impl fmt::Debug for Offset {
133	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
134		if self.0 == usize::MAX {
135			write!(f, "-1")
136		} else {
137			self.0.fmt(f)
138		}
139	}
140}
141
142/// Node balance.
143#[derive(Debug)]
144pub enum Balance {
145	/// The node is balanced.
146	Balanced,
147
148	/// The node is overflowing.
149	Overflow,
150
151	/// The node is underflowing.
152	///
153	/// The boolean is `true` if the node is empty.
154	Underflow(bool),
155}
156
157/// Error returned when an operation on the node would result in an underflow.
158pub struct WouldUnderflow;
159
160/// Type of the value returned by `Node::pop_right`.
161///
162/// It includes the offset of the popped item, the item itself and the index of
163/// the right child of the item if it is removed from an internal node.
164pub type PoppedItem<K, V> = (Offset, Item<K, V>, Option<usize>);
165
166/// B-tree node.
167#[derive(Clone)]
168pub enum Node<K, V> {
169	/// Internal node.
170	Internal(InternalNode<K, V>),
171
172	/// Leaf node.
173	Leaf(LeafNode<K, V>),
174}
175
176impl<K, V> Node<K, V> {
177	#[inline]
178	pub fn binary(
179		parent: Option<usize>,
180		left_id: usize,
181		median: Item<K, V>,
182		right_id: usize,
183	) -> Node<K, V> {
184		Node::Internal(InternalNode::binary(parent, left_id, median, right_id))
185	}
186
187	#[inline]
188	pub fn leaf(parent: Option<usize>, item: Item<K, V>) -> Node<K, V> {
189		Node::Leaf(LeafNode::new(parent, item))
190	}
191
192	#[inline]
193	pub fn balance(&self) -> Balance {
194		match self {
195			Node::Internal(node) => node.balance(),
196			Node::Leaf(leaf) => leaf.balance(),
197		}
198	}
199
200	#[inline]
201	pub fn is_underflowing(&self) -> bool {
202		match self {
203			Node::Internal(node) => node.is_underflowing(),
204			Node::Leaf(leaf) => leaf.is_underflowing(),
205		}
206	}
207
208	#[inline]
209	pub fn is_overflowing(&self) -> bool {
210		match self {
211			Node::Internal(node) => node.is_overflowing(),
212			Node::Leaf(leaf) => leaf.is_overflowing(),
213		}
214	}
215
216	#[inline]
217	pub fn parent(&self) -> Option<usize> {
218		match self {
219			Node::Internal(node) => node.parent(),
220			Node::Leaf(leaf) => leaf.parent(),
221		}
222	}
223
224	#[inline]
225	pub fn set_parent(&mut self, p: Option<usize>) {
226		match self {
227			Node::Internal(node) => node.set_parent(p),
228			Node::Leaf(leaf) => leaf.set_parent(p),
229		}
230	}
231
232	#[inline]
233	pub fn item_count(&self) -> usize {
234		match self {
235			Node::Internal(node) => node.item_count(),
236			Node::Leaf(leaf) => leaf.item_count(),
237		}
238	}
239
240	#[inline]
241	pub fn child_count(&self) -> usize {
242		match self {
243			Node::Internal(node) => node.child_count(),
244			Node::Leaf(_) => 0,
245		}
246	}
247
248	#[inline]
249	pub fn child_index(&self, id: usize) -> Option<usize> {
250		match self {
251			Node::Internal(node) => node.child_index(id),
252			_ => None,
253		}
254	}
255
256	#[inline]
257	pub fn child_id(&self, index: usize) -> usize {
258		match self {
259			Node::Internal(node) => node.child_id(index),
260			_ => panic!("only internal nodes can be indexed"),
261		}
262	}
263
264	#[inline]
265	pub fn child_id_opt(&self, index: usize) -> Option<usize> {
266		match self {
267			Node::Internal(node) => node.child_id_opt(index),
268			Node::Leaf(_) => None,
269		}
270	}
271
272	#[inline]
273	pub fn get<Q: ?Sized>(&self, key: &Q) -> Result<Option<&V>, usize>
274	where
275		K: Borrow<Q>,
276		Q: Ord,
277	{
278		match self {
279			Node::Leaf(leaf) => Ok(leaf.get(key)),
280			Node::Internal(node) => match node.get(key) {
281				Ok(value) => Ok(Some(value)),
282				Err(e) => Err(e),
283			},
284		}
285	}
286
287	#[inline]
288	pub fn get_mut<Q: ?Sized>(&mut self, key: &Q) -> Result<Option<&mut V>, usize>
289	where
290		K: Borrow<Q>,
291		Q: Ord,
292	{
293		match self {
294			Node::Leaf(leaf) => Ok(leaf.get_mut(key)),
295			Node::Internal(node) => match node.get_mut(key) {
296				Ok(value) => Ok(Some(value)),
297				Err(e) => Err(e),
298			},
299		}
300	}
301
302	/// Find the offset of the item matching the given key.
303	///
304	/// If the key matches no item in this node,
305	/// this funtion returns the index and id of the child that may match the key,
306	/// or `Err(None)` if it is a leaf.
307	#[inline]
308	pub fn offset_of<Q: ?Sized>(&self, key: &Q) -> Result<Offset, (usize, Option<usize>)>
309	where
310		K: Borrow<Q>,
311		Q: Ord,
312	{
313		match self {
314			Node::Internal(node) => match node.offset_of(key) {
315				Ok(i) => Ok(i),
316				Err((index, child_id)) => Err((index, Some(child_id))),
317			},
318			Node::Leaf(leaf) => match leaf.offset_of(key) {
319				Ok(i) => Ok(i),
320				Err(index) => Err((index.unwrap(), None)),
321			},
322		}
323	}
324
325	#[inline]
326	pub fn item(&self, offset: Offset) -> Option<&Item<K, V>> {
327		match self {
328			Node::Internal(node) => node.item(offset),
329			Node::Leaf(leaf) => leaf.item(offset),
330		}
331	}
332
333	#[inline]
334	pub fn item_mut(&mut self, offset: Offset) -> Option<&mut Item<K, V>> {
335		match self {
336			Node::Internal(node) => node.item_mut(offset),
337			Node::Leaf(leaf) => leaf.item_mut(offset),
338		}
339	}
340
341	/// Insert by key.
342	///
343	/// It is assumed that the node is not free.
344	/// If it is a leaf node, there must be a free space in it for the inserted value.
345	#[inline]
346	pub fn insert_by_key(
347		&mut self,
348		key: K,
349		value: V,
350	) -> Result<(Offset, Option<V>), internal::InsertionError<K, V>>
351	where
352		K: Ord,
353	{
354		match self {
355			Node::Internal(node) => match node.insert_by_key(key, value) {
356				Ok((offset, value)) => Ok((offset, Some(value))),
357				Err(e) => Err(e),
358			},
359			Node::Leaf(leaf) => Ok(leaf.insert_by_key(key, value)),
360		}
361	}
362
363	/// Split the node.
364	/// Return the length of the node after split, the median item and the right node.
365	#[inline]
366	pub fn split(&mut self) -> (usize, Item<K, V>, Node<K, V>) {
367		match self {
368			Node::Internal(node) => {
369				let (len, item, right_node) = node.split();
370				(len, item, Node::Internal(right_node))
371			}
372			Node::Leaf(leaf) => {
373				let (len, item, right_leaf) = leaf.split();
374				(len, item, Node::Leaf(right_leaf))
375			}
376		}
377	}
378
379	#[inline]
380	pub fn merge(
381		&mut self,
382		left_index: usize,
383		right_index: usize,
384	) -> (usize, usize, usize, Item<K, V>, Balance) {
385		match self {
386			Node::Internal(node) => node.merge(left_index, right_index),
387			_ => panic!("only internal nodes can merge children"),
388		}
389	}
390
391	/// Return the offset of the separator.
392	#[inline]
393	pub fn append(&mut self, separator: Item<K, V>, other: Node<K, V>) -> Offset {
394		match (self, other) {
395			(Node::Internal(node), Node::Internal(other)) => node.append(separator, other),
396			(Node::Leaf(leaf), Node::Leaf(other)) => leaf.append(separator, other),
397			_ => panic!("incompatibles nodes"),
398		}
399	}
400
401	#[inline]
402	pub fn push_left(&mut self, item: Item<K, V>, opt_child_id: Option<usize>) {
403		match self {
404			Node::Internal(node) => node.push_left(item, opt_child_id.unwrap()),
405			Node::Leaf(leaf) => leaf.push_left(item),
406		}
407	}
408
409	#[inline]
410	pub fn pop_left(&mut self) -> Result<(Item<K, V>, Option<usize>), WouldUnderflow> {
411		match self {
412			Node::Internal(node) => {
413				let (item, child_id) = node.pop_left()?;
414				Ok((item, Some(child_id)))
415			}
416			Node::Leaf(leaf) => Ok((leaf.pop_left()?, None)),
417		}
418	}
419
420	#[inline]
421	pub fn push_right(&mut self, item: Item<K, V>, opt_child_id: Option<usize>) -> Offset {
422		match self {
423			Node::Internal(node) => node.push_right(item, opt_child_id.unwrap()),
424			Node::Leaf(leaf) => leaf.push_right(item),
425		}
426	}
427
428	#[inline]
429	pub fn pop_right(&mut self) -> Result<PoppedItem<K, V>, WouldUnderflow> {
430		match self {
431			Node::Internal(node) => {
432				let (offset, item, child_id) = node.pop_right()?;
433				Ok((offset, item, Some(child_id)))
434			}
435			Node::Leaf(leaf) => {
436				let (offset, item) = leaf.pop_right()?;
437				Ok((offset, item, None))
438			}
439		}
440	}
441
442	#[inline]
443	pub fn leaf_remove(&mut self, offset: Offset) -> Option<Result<Item<K, V>, usize>> {
444		match self {
445			Node::Internal(node) => {
446				if offset < node.item_count() {
447					let left_child_index = offset.unwrap();
448					Some(Err(node.child_id(left_child_index)))
449				} else {
450					None
451				}
452			}
453			Node::Leaf(leaf) => {
454				if offset < leaf.item_count() {
455					Some(Ok(leaf.remove(offset)))
456				} else {
457					None
458				}
459			}
460		}
461	}
462
463	#[inline]
464	pub fn remove_rightmost_leaf(&mut self) -> Result<Item<K, V>, usize> {
465		match self {
466			Node::Internal(node) => {
467				let child_index = node.child_count() - 1;
468				let child_id = node.child_id(child_index);
469				Err(child_id)
470			}
471			Node::Leaf(leaf) => Ok(leaf.remove_last()),
472		}
473	}
474
475	/// Put an item in a node.
476	///
477	/// It is assumed that the node will not overflow.
478	#[inline]
479	pub fn insert(&mut self, offset: Offset, item: Item<K, V>, opt_right_child_id: Option<usize>) {
480		match self {
481			Node::Internal(node) => node.insert(offset, item, opt_right_child_id.unwrap()),
482			Node::Leaf(leaf) => leaf.insert(offset, item),
483		}
484	}
485
486	#[inline]
487	pub fn replace(&mut self, offset: Offset, item: Item<K, V>) -> Item<K, V> {
488		match self {
489			Node::Internal(node) => node.replace(offset, item),
490			_ => panic!("can only replace in internal nodes"),
491		}
492	}
493
494	#[inline]
495	pub fn separators(&self, i: usize) -> (Option<&K>, Option<&K>) {
496		match self {
497			Node::Leaf(_) => (None, None),
498			Node::Internal(node) => node.separators(i),
499		}
500	}
501
502	#[inline]
503	pub fn children(&self) -> Children<K, V> {
504		match self {
505			Node::Leaf(_) => Children::Leaf,
506			Node::Internal(node) => node.children(),
507		}
508	}
509
510	#[inline]
511	pub fn children_with_separators(&self) -> ChildrenWithSeparators<K, V> {
512		match self {
513			Node::Leaf(_) => ChildrenWithSeparators::Leaf,
514			Node::Internal(node) => node.children_with_separators(),
515		}
516	}
517
518	/// Write the label of the node in the DOT format.
519	///
520	/// Requires the `dot` feature.
521	#[cfg(feature = "dot")]
522	#[inline]
523	pub fn dot_write_label<W: std::io::Write>(&self, f: &mut W) -> std::io::Result<()>
524	where
525		K: std::fmt::Display,
526		V: std::fmt::Display,
527	{
528		match self {
529			Node::Leaf(leaf) => leaf.dot_write_label(f),
530			Node::Internal(node) => node.dot_write_label(f),
531		}
532	}
533
534	#[cfg(debug_assertions)]
535	pub fn validate(&self, parent: Option<usize>, min: Option<&K>, max: Option<&K>)
536	where
537		K: Ord,
538	{
539		match self {
540			Node::Leaf(leaf) => leaf.validate(parent, min, max),
541			Node::Internal(node) => node.validate(parent, min, max),
542		}
543	}
544}
545
546pub enum Children<'a, K, V> {
547	Leaf,
548	Internal(Option<usize>, std::slice::Iter<'a, internal::Branch<K, V>>),
549}
550
551impl<'a, K, V> Iterator for Children<'a, K, V> {
552	type Item = usize;
553
554	#[inline]
555	fn next(&mut self) -> Option<usize> {
556		match self {
557			Children::Leaf => None,
558			Children::Internal(first, rest) => match first.take() {
559				Some(child) => Some(child),
560				None => rest.next().map(|branch| branch.child),
561			},
562		}
563	}
564}
565
566pub enum ChildrenWithSeparators<'a, K, V> {
567	Leaf,
568	Internal(
569		Option<usize>,
570		Option<&'a Item<K, V>>,
571		std::iter::Peekable<std::slice::Iter<'a, internal::Branch<K, V>>>,
572	),
573}
574
575impl<'a, K, V> Iterator for ChildrenWithSeparators<'a, K, V> {
576	type Item = (Option<&'a Item<K, V>>, usize, Option<&'a Item<K, V>>);
577
578	#[inline]
579	fn next(&mut self) -> Option<Self::Item> {
580		match self {
581			ChildrenWithSeparators::Leaf => None,
582			ChildrenWithSeparators::Internal(first, left_sep, rest) => match first.take() {
583				Some(child) => {
584					let right_sep = rest.peek().map(|right| &right.item);
585					*left_sep = right_sep;
586					Some((None, child, right_sep))
587				}
588				None => match rest.next() {
589					Some(branch) => {
590						let right_sep = rest.peek().map(|right| &right.item);
591						let result = Some((*left_sep, branch.child, right_sep));
592						*left_sep = right_sep;
593						result
594					}
595					None => None,
596				},
597			},
598		}
599	}
600}