raw_btree/node/
internal.rs

1use crate::{
2	utils::{binary_search_min, Array},
3	Storage, M,
4};
5use std::cmp::Ordering;
6
7use super::{Balance, Children, ChildrenWithSeparators, Offset, WouldUnderflow};
8
9/// Underflow threshold.
10///
11/// An internal node is underflowing if it has less items than this constant.
12const UNDERFLOW: usize = M / 2 - 1;
13
14/// Internal node branch.
15///
16/// A branch is an item followed by child node identifier.
17#[derive(Clone)]
18pub struct Branch<T, S: Storage<T>> {
19	/// Item.
20	pub item: T,
21
22	/// Following child node identifier.
23	pub child: S::Node,
24}
25
26impl<T, S: Storage<T>> AsRef<T> for Branch<T, S> {
27	fn as_ref(&self) -> &T {
28		&self.item
29	}
30}
31
32// impl<T, S: Storage<T>> Keyed for Branch<T, S> {
33// 	type Key = K;
34
35// 	#[inline]
36// 	fn key(&self) -> &K {
37// 		self.item.key()
38// 	}
39// }
40
41/// Error returned when a direct insertion by key in the internal node failed.
42pub struct InsertionError<T, S: Storage<T>> {
43	/// Inserted key.
44	pub item: T,
45
46	/// Offset of the child in which the key should be inserted instead.
47	pub child_offset: usize,
48
49	/// Id of the child in which the key should be inserted instead.
50	pub child_id: S::Node,
51}
52
53/// Internal node.
54///
55/// An internal node is a node where each item is surrounded by edges to child nodes.
56// #[derive(Clone)]
57pub struct Internal<T, S: Storage<T>> {
58	parent: Option<S::Node>,
59	first_child: S::Node,
60	other_children: Array<Branch<T, S>, M>,
61}
62
63impl<T, S: Storage<T>> Internal<T, S> {
64	pub fn new(
65		parent: Option<S::Node>,
66		first_child: S::Node,
67		other_children: Array<Branch<T, S>, M>,
68	) -> Self {
69		Self {
70			parent,
71			first_child,
72			other_children,
73		}
74	}
75
76	/// Creates a binary node (with a single item and two children).
77	#[inline]
78	pub fn binary(
79		parent: Option<S::Node>,
80		left_id: S::Node,
81		median: T,
82		right_id: S::Node,
83	) -> Internal<T, S> {
84		let mut other_children = Array::new();
85		other_children.push(Branch {
86			item: median,
87			child: right_id,
88		});
89
90		Internal {
91			parent,
92			first_child: left_id,
93			other_children,
94		}
95	}
96
97	/// Forget the node content, without running the items destructors.
98	///
99	/// The node's children must be manually dropped.
100	pub fn forget(&mut self) {
101		std::mem::forget(std::mem::take(&mut self.other_children))
102	}
103
104	/// Returns the current balance of the node.
105	#[inline]
106	pub fn balance(&self) -> Balance {
107		if self.is_overflowing() {
108			Balance::Overflow
109		} else if self.is_underflowing() {
110			Balance::Underflow(self.other_children.is_empty())
111		} else {
112			Balance::Balanced
113		}
114	}
115
116	#[inline]
117	pub fn is_overflowing(&self) -> bool {
118		self.item_count() >= M
119	}
120
121	#[inline]
122	pub fn is_underflowing(&self) -> bool {
123		self.item_count() < UNDERFLOW
124	}
125
126	#[inline]
127	pub fn parent(&self) -> Option<S::Node> {
128		self.parent
129	}
130
131	#[inline]
132	pub fn set_parent(&mut self, p: Option<S::Node>) {
133		self.parent = p
134	}
135
136	#[inline]
137	pub fn item_count(&self) -> usize {
138		self.other_children.len()
139	}
140
141	#[inline]
142	pub fn child_count(&self) -> usize {
143		1usize + self.item_count()
144	}
145
146	#[inline]
147	pub fn first_child_id(&self) -> S::Node {
148		self.first_child
149	}
150
151	#[inline]
152	pub fn branches(&self) -> &[Branch<T, S>] {
153		self.other_children.as_ref()
154	}
155
156	#[inline]
157	pub fn child_index(&self, id: S::Node) -> Option<usize> {
158		if self.first_child == id {
159			Some(0)
160		} else {
161			for i in 0..self.other_children.len() {
162				if self.other_children[i].child == id {
163					return Some(i + 1);
164				}
165			}
166
167			None
168		}
169	}
170
171	#[inline]
172	pub fn child_id(&self, index: usize) -> S::Node {
173		if index == 0 {
174			self.first_child
175		} else {
176			self.other_children[index - 1].child
177		}
178	}
179
180	#[inline]
181	pub fn child_id_opt(&self, index: usize) -> Option<S::Node> {
182		if index == 0 {
183			Some(self.first_child)
184		} else {
185			self.other_children.get(index - 1).map(|b| b.child)
186		}
187	}
188
189	#[inline]
190	pub fn separators(&self, index: usize) -> (Option<&T>, Option<&T>) {
191		let min = if index > 0 {
192			Some(&self.other_children[index - 1].item)
193		} else {
194			None
195		};
196
197		let max = if index < self.other_children.len() {
198			Some(&self.other_children[index].item)
199		} else {
200			None
201		};
202
203		(min, max)
204	}
205
206	#[inline]
207	pub fn get<Q: ?Sized>(&self, cmp: impl Fn(&T, &Q) -> Ordering, key: &Q) -> Result<&T, S::Node> {
208		match binary_search_min(|a, b| cmp(&a.item, b), &self.other_children, key) {
209			Some((offset, eq)) => {
210				let b = &self.other_children[offset];
211				if eq {
212					Ok(&b.item)
213				} else {
214					Err(b.child)
215				}
216			}
217			None => Err(self.first_child),
218		}
219	}
220
221	#[inline]
222	pub fn get_mut<Q: ?Sized>(
223		&mut self,
224		cmp: impl Fn(&T, &Q) -> Ordering,
225		key: &Q,
226	) -> Result<&mut T, &mut S::Node> {
227		match binary_search_min(|a, b| cmp(&a.item, b), &self.other_children, key) {
228			Some((offset, eq)) => {
229				let b = &mut self.other_children[offset];
230				if eq {
231					Ok(&mut b.item)
232				} else {
233					Err(&mut b.child)
234				}
235			}
236			None => Err(&mut self.first_child),
237		}
238	}
239
240	/// Find the offset of the item matching the given key.
241	///
242	/// If the key matches no item in this node,
243	/// this funtion returns the index and id of the child that may match the key.
244	#[inline]
245	pub fn offset_of<Q: ?Sized>(
246		&self,
247		cmp: impl Fn(&T, &Q) -> Ordering,
248		key: &Q,
249	) -> Result<Offset, (usize, S::Node)> {
250		match binary_search_min(|a, b| cmp(&a.item, b), &self.other_children, key) {
251			Some((offset, eq)) => {
252				if eq {
253					Ok(offset.into())
254				} else {
255					let id = self.other_children[offset].child;
256					Err((offset + 1, id))
257				}
258			}
259			None => Err((0, self.first_child)),
260		}
261	}
262
263	#[inline]
264	pub fn children(&self) -> Children<T, S> {
265		Children::Internal(Some(self.first_child), self.other_children.as_ref().iter())
266	}
267
268	#[inline]
269	pub fn children_with_separators(&self) -> ChildrenWithSeparators<T, S> {
270		ChildrenWithSeparators::Internal(
271			Some(self.first_child),
272			None,
273			self.other_children.as_ref().iter().peekable(),
274		)
275	}
276
277	#[inline]
278	pub fn item(&self, offset: Offset) -> Option<&T> {
279		match self.other_children.get(offset.unwrap()) {
280			Some(b) => Some(&b.item),
281			None => None,
282		}
283	}
284
285	#[inline]
286	pub fn item_mut(&mut self, offset: Offset) -> Option<&mut T> {
287		match self.other_children.get_mut(offset.unwrap()) {
288			Some(b) => Some(&mut b.item),
289			None => None,
290		}
291	}
292
293	/// Insert by key.
294	#[inline]
295	pub fn insert_by_key(
296		&mut self,
297		cmp: impl Fn(&T, &T) -> Ordering,
298		mut item: T,
299	) -> Result<(Offset, T), InsertionError<T, S>> {
300		match binary_search_min(|a, b| cmp(&a.item, b), &self.other_children, &item) {
301			Some((i, eq)) => {
302				if eq {
303					std::mem::swap(&mut item, &mut self.other_children[i].item);
304					Ok((i.into(), item))
305				} else {
306					Err(InsertionError {
307						item,
308						child_offset: i + 1,
309						child_id: self.other_children[i].child,
310					})
311				}
312			}
313			None => Err(InsertionError {
314				item,
315				child_offset: 0,
316				child_id: self.first_child,
317			}),
318		}
319	}
320
321	// /// Get the offset of the item with the given key.
322	// #[inline]
323	// pub fn key_offset(&self, key: &K) -> Result<usize, (usize, usize)> {
324	// 	match binary_search_min(&self.other_children, key) {
325	// 		Some(i) => {
326	// 			if self.other_children[i].item.key() == key {
327	// 				Ok(i)
328	// 			} else {
329	// 				Err((i+1, self.other_children[i].child))
330	// 			}
331	// 		},
332	// 		None => {
333	// 			Err((0, self.first_child))
334	// 		}
335	// 	}
336	// }
337
338	/// Insert item at the given offset.
339	#[inline]
340	pub fn insert(&mut self, offset: Offset, item: T, right_node_id: S::Node) {
341		self.other_children.insert(
342			offset.unwrap(),
343			Branch {
344				item,
345				child: right_node_id,
346			},
347		);
348	}
349
350	/// Replace the item at the given offset.
351	#[inline]
352	pub fn replace(&mut self, offset: Offset, mut item: T) -> T {
353		std::mem::swap(&mut item, &mut self.other_children[offset.unwrap()].item);
354		item
355	}
356
357	/// Remove the item at the given offset.
358	/// Return the child id on the left of the item, the item, and the child id on the right
359	/// (which is also removed).
360	#[inline]
361	pub fn remove(&mut self, offset: Offset) -> (S::Node, T, S::Node) {
362		let offset = offset.unwrap();
363		let b = self.other_children.remove(offset).unwrap();
364		let left_child_id = self.child_id(offset);
365		(left_child_id, b.item, b.child)
366	}
367
368	#[inline]
369	pub fn split(&mut self) -> (usize, T, Internal<T, S>) {
370		assert!(self.is_overflowing()); // implies self.other_children.len() >= 4
371
372		// Index of the median-key item in `other_children`.
373		let median_i = (self.other_children.len() - 1) / 2; // Since M is at least 3, `median_i` is at least 1.
374
375		let right_other_children = self.other_children.drain(median_i + 1..).collect();
376		let median = self.other_children.pop().unwrap();
377
378		let right_node = Internal {
379			parent: self.parent,
380			first_child: median.child,
381			other_children: right_other_children,
382		};
383
384		assert!(!self.is_underflowing());
385		assert!(!right_node.is_underflowing());
386
387		(self.other_children.len(), median.item, right_node)
388	}
389
390	/// Merge the children at the given indexes.
391	///
392	/// It is supposed that `left_index` is `right_index-1`.
393	/// This method returns the identifier of the left node in the tree, the identifier of the right node,
394	/// the item removed from this node to be merged with the merged children and
395	/// the balance status of this node after the merging operation.
396	#[inline]
397	pub fn merge(&mut self, left_index: usize) -> (usize, S::Node, S::Node, T, Balance) {
398		// We remove the right child (the one of index `right_index`).
399		// Since left_index = right_index-1, it is indexed by `left_index` in `other_children`.
400		let branch = self.other_children.remove(left_index).unwrap();
401		let left_id = self.child_id(left_index);
402		let right_id = branch.child;
403		(left_index, left_id, right_id, branch.item, self.balance())
404	}
405
406	#[inline]
407	pub fn push_left(&mut self, item: T, mut child_id: S::Node) {
408		std::mem::swap(&mut self.first_child, &mut child_id);
409		self.other_children.insert(
410			0,
411			Branch {
412				item,
413				child: child_id,
414			},
415		);
416	}
417
418	#[inline]
419	pub fn pop_left(&mut self) -> Result<(T, S::Node), WouldUnderflow> {
420		if self.item_count() <= UNDERFLOW {
421			Err(WouldUnderflow)
422		} else {
423			let first = self.other_children.remove(0).unwrap();
424			let child_id = std::mem::replace(&mut self.first_child, first.child);
425			Ok((first.item, child_id))
426		}
427	}
428
429	#[inline]
430	pub fn push_right(&mut self, item: T, child_id: S::Node) -> Offset {
431		let offset = self.other_children.len();
432		self.other_children.push(Branch {
433			item,
434			child: child_id,
435		});
436		offset.into()
437	}
438
439	#[inline]
440	pub fn pop_right(&mut self) -> Result<RightBranch<T, S>, WouldUnderflow> {
441		if self.item_count() <= UNDERFLOW {
442			Err(WouldUnderflow)
443		} else {
444			let offset = self.other_children.len();
445			let last = self.other_children.pop().unwrap();
446			Ok(RightBranch {
447				offset: offset.into(),
448				item: last.item,
449				child: last.child,
450			})
451		}
452	}
453
454	#[inline]
455	pub fn append(&mut self, separator: T, mut other: Internal<T, S>) -> Offset {
456		let offset = self.other_children.len();
457		self.other_children.push(Branch {
458			item: separator,
459			child: other.first_child,
460		});
461
462		self.other_children.append(&mut other.other_children);
463		offset.into()
464	}
465
466	/// Write the label of the internal node in the DOT format.
467	///
468	/// Requires the `dot` feature.
469	#[cfg(feature = "dot")]
470	#[inline]
471	pub fn dot_write_label<W: std::io::Write>(&self, f: &mut W) -> std::io::Result<()>
472	where
473		T: std::fmt::Display,
474	{
475		write!(f, "<c0> |")?;
476		let mut i = 1;
477		for branch in &self.other_children {
478			write!(f, "{{{}|<c{}>}} |", branch.item, i)?;
479			i += 1;
480		}
481
482		Ok(())
483	}
484
485	#[cfg(debug_assertions)]
486	pub fn validate(
487		&self,
488		cmp: impl Fn(&T, &T) -> Ordering,
489		parent: Option<S::Node>,
490		min: Option<&T>,
491		max: Option<&T>,
492	) {
493		if self.parent() != parent {
494			panic!("wrong parent")
495		}
496
497		if min.is_some() || max.is_some() {
498			// not root
499			match self.balance() {
500				Balance::Overflow => panic!("internal node is overflowing"),
501				Balance::Underflow(_) => panic!("internal node is underflowing"),
502				_ => (),
503			}
504		} else if self.item_count() == 0 {
505			panic!("root node is empty")
506		}
507
508		if !self
509			.other_children
510			.windows(2)
511			.all(|w| cmp(&w[0].item, &w[1].item).is_lt())
512		{
513			panic!("internal node items are not sorted")
514		}
515
516		if let Some(min) = min {
517			if let Some(b) = self.other_children.first() {
518				if cmp(min, &b.item).is_ge() {
519					panic!("internal node item key is greater than right separator")
520				}
521			}
522		}
523
524		if let Some(max) = max {
525			if let Some(b) = self.other_children.last() {
526				if cmp(max, &b.item).is_le() {
527					panic!("internal node item key is less than left separator")
528				}
529			}
530		}
531	}
532}
533
534pub struct RightBranch<T, S: Storage<T>> {
535	pub offset: Offset,
536	pub item: T,
537	pub child: S::Node,
538}