raw_btree/
lib.rs

1//! This library provides a [`RawBTree`] type that can be used as a basis for
2//! any B-Tree-based data structure.
3//!
4//! [`RawBTree`]: crate::RawBTree
5pub(crate) mod utils;
6
7pub mod node;
8pub use node::{Address, Node};
9use std::{cmp::Ordering, iter::FusedIterator, marker::PhantomData};
10
11mod balancing;
12mod item;
13pub mod storage;
14
15pub use item::Item;
16use storage::BoxStorage;
17pub use storage::Storage;
18
19use crate::utils::Array;
20
21/// Knuth order of the B-Trees.
22///
23/// Must be at least 4.
24pub const M: usize = 8;
25
26pub struct RawBTree<T, S: Storage<T> = BoxStorage> {
27	/// Allocated and free nodes.
28	nodes: S,
29
30	/// Root node.
31	root: Option<S::Node>,
32
33	/// Number of items in the tree.
34	len: usize,
35
36	item: PhantomData<T>,
37}
38
39impl<T, S: Storage<T>> Default for RawBTree<T, S> {
40	fn default() -> Self {
41		Self::new()
42	}
43}
44
45impl<T, S: Storage<T>> RawBTree<T, S> {
46	/// Create a new empty B-tree.
47	#[inline]
48	pub fn new() -> RawBTree<T, S> {
49		RawBTree {
50			nodes: Default::default(),
51			root: None,
52			len: 0,
53			item: PhantomData,
54		}
55	}
56
57	#[inline]
58	pub fn is_empty(&self) -> bool {
59		self.root.is_none()
60	}
61
62	#[inline]
63	pub fn len(&self) -> usize {
64		self.len
65	}
66
67	pub fn address_of<Q: ?Sized>(
68		&self,
69		cmp: impl Fn(&T, &Q) -> Ordering,
70		key: &Q,
71	) -> Result<Address<S::Node>, Option<Address<S::Node>>> {
72		match self.root {
73			Some(id) => unsafe { self.nodes.address_in(id, cmp, key).map_err(Some) },
74			None => Err(None),
75		}
76	}
77
78	pub fn first_item_address(&self) -> Option<Address<S::Node>> {
79		self.root.map(|mut id| unsafe {
80			loop {
81				match self.nodes.get(id).child_id_opt(0) {
82					Some(child_id) => id = child_id,
83					None => break Address::new(id, 0.into()),
84				}
85			}
86		})
87	}
88
89	// fn first_back_address(&self) -> Address {
90	// 	match self.root {
91	// 		Some(mut id) => loop {
92	// 			match self.node(id).child_id_opt(0) {
93	// 				Some(child_id) => id = child_id,
94	// 				None => return Address::new(id, 0.into()), // TODO FIXME thechnically not the first
95	// 			}
96	// 		},
97	// 		None => Address::nowhere(),
98	// 	}
99	// }
100
101	fn last_item_address(&self) -> Option<Address<S::Node>> {
102		self.root.map(|mut id| unsafe {
103			loop {
104				let node = self.nodes.get(id);
105				let index = node.item_count();
106				match node.child_id_opt(index) {
107					Some(child_id) => id = child_id,
108					None => break Address::new(id, (index - 1).into()),
109				}
110			}
111		})
112	}
113
114	// fn last_valid_address(&self) -> Address {
115	// 	match self.root {
116	// 		Some(mut id) => loop {
117	// 			let node = self.node(id);
118	// 			let index = node.item_count();
119	// 			match node.child_id_opt(index) {
120	// 				Some(child_id) => id = child_id,
121	// 				None => return Address::new(id, index.into()),
122	// 			}
123	// 		},
124	// 		None => Address::nowhere(),
125	// 	}
126	// }
127
128	/// Return the item at the given address.
129	///
130	/// # Safety
131	///
132	/// The address's node must not have been deallocated.
133	#[inline]
134	pub unsafe fn get_at(&self, addr: Address<S::Node>) -> Option<&T> {
135		self.nodes.get(addr.node).item(addr.offset)
136	}
137
138	/// Returns a mutable reference to the item at the given address.
139	///
140	/// # Safety
141	///
142	/// The address's node must not have been deallocated.
143	#[inline]
144	pub unsafe fn get_mut_at(&mut self, addr: Address<S::Node>) -> Option<&mut T> {
145		self.nodes.get_mut(addr.node).item_mut(addr.offset)
146	}
147
148	#[inline]
149	pub fn get<Q: ?Sized>(&self, cmp: impl Fn(&T, &Q) -> Ordering, key: &Q) -> Option<&T> {
150		self.address_of(cmp, key)
151			.ok()
152			.and_then(|addr| unsafe { self.get_at(addr) })
153	}
154
155	#[inline]
156	pub fn get_mut<Q: ?Sized>(
157		&mut self,
158		cmp: impl Fn(&T, &Q) -> Ordering,
159		key: &Q,
160	) -> Option<&mut T> {
161		self.address_of(cmp, key)
162			.ok()
163			.and_then(|addr| unsafe { self.get_mut_at(addr) })
164	}
165
166	#[inline]
167	pub fn first(&self) -> Option<&T> {
168		self.first_item_address()
169			.and_then(|addr| unsafe { self.get_at(addr) })
170	}
171
172	#[inline]
173	pub fn first_mut(&mut self) -> Option<&mut T> {
174		self.first_item_address()
175			.and_then(|addr| unsafe { self.get_mut_at(addr) })
176	}
177
178	#[inline]
179	pub fn last(&self) -> Option<&T> {
180		self.last_item_address()
181			.and_then(|addr| unsafe { self.get_at(addr) })
182	}
183
184	#[inline]
185	pub fn last_mut(&mut self) -> Option<&mut T> {
186		self.last_item_address()
187			.and_then(|addr| unsafe { self.get_mut_at(addr) })
188	}
189
190	pub fn iter(&self) -> Iter<T, S> {
191		Iter::new(self)
192	}
193
194	pub fn iter_mut(&mut self) -> IterMut<T, S> {
195		IterMut::new(self)
196	}
197
198	#[inline]
199	pub fn insert(&mut self, cmp: impl Fn(&T, &T) -> Ordering, item: T) -> Option<T> {
200		match self.address_of(cmp, &item) {
201			Ok(addr) => Some(unsafe { self.nodes.replace_at(addr, item) }),
202			Err(addr) => {
203				let (root, _) =
204					unsafe { self.nodes.insert_exactly_at(self.root, addr, item, None) };
205				self.root = root;
206				self.len += 1;
207				None
208			}
209		}
210	}
211
212	/// Remove the next item and return it.
213	#[inline]
214	pub fn remove<Q: ?Sized>(&mut self, cmp: impl Fn(&T, &Q) -> Ordering, key: &Q) -> Option<T> {
215		match self.address_of(cmp, key) {
216			Ok(addr) => {
217				let r = unsafe { self.nodes.remove_at(self.root, addr).unwrap() };
218				self.root = r.new_root;
219				self.len -= 1;
220				Some(r.item)
221			}
222			Err(_) => None,
223		}
224	}
225
226	pub fn visit_from_leaves(&self, mut f: impl FnMut(S::Node)) {
227		if let Some(id) = self.root {
228			let node = unsafe { self.nodes.get(id) };
229			node.visit_from_leaves(&self.nodes, &mut f);
230			f(id)
231		}
232	}
233
234	pub fn visit_from_leaves_mut(&mut self, mut f: impl FnMut(S::Node, &mut Node<T, S>)) {
235		if let Some(root_id) = self.root {
236			let root_node: &mut Node<T, S> =
237				unsafe { std::mem::transmute(self.nodes.get_mut(root_id)) };
238			root_node.visit_from_leaves_mut(&mut self.nodes, &mut f);
239			f(root_id, root_node)
240		}
241	}
242
243	pub fn forget(&mut self) {
244		use storage::Dropper;
245		let mut dropper = self.nodes.start_dropping();
246
247		self.visit_from_leaves_mut(|id, node| unsafe {
248			node.forget();
249			if let Some(dropper) = &mut dropper {
250				dropper.drop_node(id);
251			}
252		});
253
254		self.root = None;
255		self.len = 0;
256		self.nodes = S::default();
257	}
258
259	pub fn clear(&mut self) {
260		use storage::Dropper;
261		if let Some(mut dropper) = self.nodes.start_dropping() {
262			self.visit_from_leaves(|id| unsafe { dropper.drop_node(id) })
263		}
264
265		self.root = None;
266		self.len = 0;
267		self.nodes = S::default();
268	}
269
270	#[cfg(debug_assertions)]
271	pub fn validate(&self, cmp: impl Fn(&T, &T) -> Ordering) {
272		if let Some(id) = self.root {
273			self.validate_node(&cmp, id, None, None, None);
274		}
275	}
276
277	/// Validate the given node and returns the depth of the node.
278	#[cfg(debug_assertions)]
279	pub fn validate_node(
280		&self,
281		cmp: &impl Fn(&T, &T) -> Ordering,
282		id: S::Node,
283		parent: Option<S::Node>,
284		mut min: Option<&T>,
285		mut max: Option<&T>,
286	) -> usize {
287		let node = unsafe { self.nodes.get(id) };
288		node.validate(cmp, parent, min, max);
289
290		let mut depth = None;
291		for (i, child_id) in node.children().enumerate() {
292			let (child_min, child_max) = node.separators(i);
293			let min = child_min.or_else(|| min.take());
294			let max = child_max.or_else(|| max.take());
295
296			let child_depth = self.validate_node(cmp, child_id, Some(id), min, max);
297			match depth {
298				None => depth = Some(child_depth),
299				Some(depth) => {
300					if depth != child_depth {
301						panic!("tree not balanced")
302					}
303				}
304			}
305		}
306
307		match depth {
308			Some(depth) => depth + 1,
309			None => 0,
310		}
311	}
312
313	/// Write the tree in the DOT graph descrption language.
314	///
315	/// Requires the `dot` feature.
316	#[cfg(feature = "dot")]
317	#[inline]
318	pub fn dot_write<W: std::io::Write>(&self, f: &mut W) -> std::io::Result<()>
319	where
320		T: std::fmt::Display,
321		S::Node: Into<usize>,
322	{
323		write!(f, "digraph tree {{\n\tnode [shape=record];\n")?;
324		if let Some(id) = self.root {
325			self.dot_write_node(f, id)?
326		}
327		write!(f, "}}")
328	}
329
330	/// Write the given node in the DOT graph descrption language.
331	///
332	/// Requires the `dot` feature.
333	#[cfg(feature = "dot")]
334	#[inline]
335	fn dot_write_node<W: std::io::Write>(&self, f: &mut W, id: S::Node) -> std::io::Result<()>
336	where
337		T: std::fmt::Display,
338		S::Node: Into<usize>,
339	{
340		let name = format!("n{:?}", id.into());
341		let node = unsafe { self.nodes.get(id) };
342
343		write!(f, "\t{} [label=\"", name)?;
344		if let Some(parent) = node.parent() {
345			write!(f, "({:?})|", parent.into())?;
346		}
347
348		node.dot_write_label(f)?;
349		writeln!(f, "({:?})\"];", id.into())?;
350
351		for child_id in node.children() {
352			self.dot_write_node(f, child_id)?;
353			let child_name = format!("n{:?}", child_id.into());
354			writeln!(f, "\t{} -> {}", name, child_name)?;
355		}
356
357		Ok(())
358	}
359}
360
361impl<T, S: Storage<T>> Drop for RawBTree<T, S> {
362	fn drop(&mut self) {
363		self.clear();
364	}
365}
366
367impl<T: Clone, S: Storage<T>> Clone for RawBTree<T, S> {
368	fn clone(&self) -> Self {
369		unsafe fn clone_node<T: Clone, S: Storage<T>>(
370			old_nodes: &S,
371			new_nodes: &mut S,
372			parent: Option<S::Node>,
373			node_id: S::Node,
374		) -> S::Node {
375			let clone = match old_nodes.get(node_id) {
376				Node::Leaf(node) => Node::Leaf(node::LeafNode::new(parent, node.items().clone())),
377				Node::Internal(node) => {
378					let first = clone_node(old_nodes, new_nodes, None, node.first_child_id());
379					let mut branches = Array::new();
380					for b in node.branches() {
381						branches.push(node::internal::Branch {
382							item: b.item.clone(),
383							child: clone_node(old_nodes, new_nodes, None, b.child),
384						})
385					}
386
387					Node::Internal(node::InternalNode::new(parent, first, branches))
388				}
389			};
390
391			new_nodes.insert_node(clone)
392		}
393
394		let mut nodes = S::default();
395		let root = self
396			.root
397			.map(|root| unsafe { clone_node(&self.nodes, &mut nodes, None, root) });
398
399		Self {
400			nodes,
401			root,
402			len: self.len,
403			item: PhantomData,
404		}
405	}
406}
407
408pub struct Iter<'a, T, S: Storage<T> = BoxStorage> {
409	/// The tree reference.
410	btree: &'a RawBTree<T, S>,
411
412	/// Address of the next item.
413	addr: Option<Address<S::Node>>,
414
415	/// End address.
416	end: Option<Address<S::Node>>,
417
418	/// Remaining item count.
419	len: usize,
420}
421
422impl<'a, T, S: Storage<T>> Iter<'a, T, S> {
423	#[inline]
424	fn new(btree: &'a RawBTree<T, S>) -> Self {
425		let addr = btree.first_item_address();
426		let len = btree.len();
427		Iter {
428			btree,
429			addr,
430			end: None,
431			len,
432		}
433	}
434}
435
436impl<'a, T, S: Storage<T>> Iterator for Iter<'a, T, S> {
437	type Item = &'a T;
438
439	#[inline]
440	fn size_hint(&self) -> (usize, Option<usize>) {
441		(self.len, Some(self.len))
442	}
443
444	#[inline]
445	fn next(&mut self) -> Option<&'a T> {
446		match self.addr {
447			Some(addr) => unsafe {
448				if self.len > 0 {
449					self.len -= 1;
450
451					let item = self.btree.get_at(addr).unwrap();
452					self.addr = self.btree.nodes.next_item_address(addr);
453					Some(item)
454				} else {
455					None
456				}
457			},
458			None => None,
459		}
460	}
461}
462
463impl<'a, T, S: Storage<T>> FusedIterator for Iter<'a, T, S> {}
464impl<'a, T, S: Storage<T>> ExactSizeIterator for Iter<'a, T, S> {}
465
466impl<'a, T, S: Storage<T>> DoubleEndedIterator for Iter<'a, T, S> {
467	#[inline]
468	fn next_back(&mut self) -> Option<&'a T> {
469		if self.len > 0 {
470			unsafe {
471				let addr = match self.end {
472					Some(addr) => self.btree.nodes.previous_item_address(addr).unwrap(),
473					None => self.btree.last_item_address().unwrap(),
474				};
475
476				self.len -= 1;
477
478				let item = self.btree.get_at(addr).unwrap();
479				self.end = Some(addr);
480				Some(item)
481			}
482		} else {
483			None
484		}
485	}
486}
487
488impl<'a, T, S: Storage<T>> Clone for Iter<'a, T, S> {
489	fn clone(&self) -> Self {
490		*self
491	}
492}
493
494impl<'a, T, S: Storage<T>> Copy for Iter<'a, T, S> {}
495
496impl<'a, T, S: Storage<T>> IntoIterator for &'a RawBTree<T, S> {
497	type IntoIter = Iter<'a, T, S>;
498	type Item = &'a T;
499
500	#[inline]
501	fn into_iter(self) -> Iter<'a, T, S> {
502		self.iter()
503	}
504}
505
506pub struct IterMut<'a, T, S: Storage<T> = BoxStorage> {
507	/// The tree reference.
508	btree: &'a mut RawBTree<T, S>,
509
510	/// Address of the next item.
511	addr: Option<Address<S::Node>>,
512
513	/// End address.
514	end: Option<Address<S::Node>>,
515
516	/// Remaining item count.
517	len: usize,
518}
519
520impl<'a, T, S: Storage<T>> IterMut<'a, T, S> {
521	#[inline]
522	fn new(btree: &'a mut RawBTree<T, S>) -> Self {
523		let addr = btree.first_item_address();
524		let len = btree.len();
525		Self {
526			btree,
527			addr,
528			end: None,
529			len,
530		}
531	}
532}
533
534impl<'a, T, S: Storage<T>> Iterator for IterMut<'a, T, S> {
535	type Item = &'a mut T;
536
537	#[inline]
538	fn size_hint(&self) -> (usize, Option<usize>) {
539		(self.len, Some(self.len))
540	}
541
542	#[inline]
543	fn next(&mut self) -> Option<&'a mut T> {
544		match self.addr {
545			Some(addr) => unsafe {
546				if self.len > 0 {
547					self.len -= 1;
548					self.addr = self.btree.nodes.next_item_address(addr);
549					Some(std::mem::transmute::<&mut T, &'a mut T>(
550						self.btree.get_mut_at(addr).unwrap(),
551					))
552				} else {
553					None
554				}
555			},
556			None => None,
557		}
558	}
559}
560
561impl<'a, T, S: Storage<T>> FusedIterator for IterMut<'a, T, S> {}
562impl<'a, T, S: Storage<T>> ExactSizeIterator for IterMut<'a, T, S> {}
563
564impl<'a, T, S: Storage<T>> DoubleEndedIterator for IterMut<'a, T, S> {
565	#[inline]
566	fn next_back(&mut self) -> Option<&'a mut T> {
567		if self.len > 0 {
568			unsafe {
569				let addr = match self.end {
570					Some(addr) => self.btree.nodes.previous_item_address(addr).unwrap(),
571					None => self.btree.last_item_address().unwrap(),
572				};
573
574				self.len -= 1;
575				self.end = Some(addr);
576				Some(std::mem::transmute::<&mut T, &'a mut T>(
577					self.btree.get_mut_at(addr).unwrap(),
578				))
579			}
580		} else {
581			None
582		}
583	}
584}
585
586impl<'a, T, S: Storage<T>> IntoIterator for &'a mut RawBTree<T, S> {
587	type IntoIter = IterMut<'a, T, S>;
588	type Item = &'a mut T;
589
590	#[inline]
591	fn into_iter(self) -> IterMut<'a, T, S> {
592		self.iter_mut()
593	}
594}
595
596pub struct IntoIter<T, S: Storage<T> = BoxStorage> {
597	/// The tree.
598	btree: RawBTree<T, S>,
599
600	/// Address of the next item.
601	addr: Option<Address<S::Node>>,
602
603	/// End address.
604	end: Option<Address<S::Node>>,
605
606	/// Remaining item count.
607	len: usize,
608}
609
610impl<T, S: Storage<T>> IntoIter<T, S> {
611	#[inline]
612	fn new(btree: RawBTree<T, S>) -> Self {
613		let addr = btree.first_item_address();
614		let len = btree.len();
615		Self {
616			btree,
617			addr,
618			end: None,
619			len,
620		}
621	}
622}
623
624impl<T, S: Storage<T>> Iterator for IntoIter<T, S> {
625	type Item = T;
626
627	#[inline]
628	fn size_hint(&self) -> (usize, Option<usize>) {
629		(self.len, Some(self.len))
630	}
631
632	#[inline]
633	fn next(&mut self) -> Option<T> {
634		match self.addr {
635			Some(addr) => unsafe {
636				if self.len > 0 {
637					self.len -= 1;
638					self.addr = self.btree.nodes.next_item_address(addr);
639					Some(std::ptr::read(self.btree.get_at(addr).unwrap()))
640				} else {
641					None
642				}
643			},
644			None => None,
645		}
646	}
647}
648
649impl<T, S: Storage<T>> FusedIterator for IntoIter<T, S> {}
650impl<T, S: Storage<T>> ExactSizeIterator for IntoIter<T, S> {}
651
652impl<T, S: Storage<T>> DoubleEndedIterator for IntoIter<T, S> {
653	#[inline]
654	fn next_back(&mut self) -> Option<T> {
655		if self.len > 0 {
656			unsafe {
657				let addr = match self.end {
658					Some(addr) => self.btree.nodes.previous_item_address(addr).unwrap(),
659					None => self.btree.last_item_address().unwrap(),
660				};
661
662				self.len -= 1;
663				self.end = Some(addr);
664				Some(std::ptr::read(self.btree.get_at(addr).unwrap()))
665			}
666		} else {
667			None
668		}
669	}
670}
671
672impl<T, S: Storage<T>> IntoIterator for RawBTree<T, S> {
673	type IntoIter = IntoIter<T, S>;
674	type Item = T;
675
676	#[inline]
677	fn into_iter(self) -> IntoIter<T, S> {
678		IntoIter::new(self)
679	}
680}
681
682impl<T, S: Storage<T>> Drop for IntoIter<T, S> {
683	fn drop(&mut self) {
684		let _ = self.last();
685		self.btree.forget();
686	}
687}