btree_slab/generic/node/
internal.rs

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