raw_btree/node/
mod.rs

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