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	/// Removes the item at the given address and returns it.
227	///
228	/// # Safety
229	///
230	/// Target node must not have been deallocated.
231	#[inline]
232	pub unsafe fn remove_at(&mut self, addr: Address<S::Node>) -> Option<T> {
233		let r = unsafe { self.nodes.remove_at(self.root, addr) }?;
234		self.root = r.new_root;
235		self.len -= 1;
236		Some(r.item)
237	}
238
239	pub fn visit_from_leaves(&self, mut f: impl FnMut(S::Node)) {
240		if let Some(id) = self.root {
241			let node = unsafe { self.nodes.get(id) };
242			node.visit_from_leaves(&self.nodes, &mut f);
243			f(id)
244		}
245	}
246
247	pub fn visit_from_leaves_mut(&mut self, mut f: impl FnMut(S::Node, &mut Node<T, S>)) {
248		if let Some(root_id) = self.root {
249			let root_node: &mut Node<T, S> =
250				unsafe { std::mem::transmute(self.nodes.get_mut(root_id)) };
251			root_node.visit_from_leaves_mut(&mut self.nodes, &mut f);
252			f(root_id, root_node)
253		}
254	}
255
256	pub fn forget(&mut self) {
257		use storage::Dropper;
258		let mut dropper = self.nodes.start_dropping();
259
260		self.visit_from_leaves_mut(|id, node| unsafe {
261			node.forget();
262			if let Some(dropper) = &mut dropper {
263				dropper.drop_node(id);
264			}
265		});
266
267		self.root = None;
268		self.len = 0;
269		self.nodes = S::default();
270	}
271
272	pub fn clear(&mut self) {
273		use storage::Dropper;
274		if let Some(mut dropper) = self.nodes.start_dropping() {
275			self.visit_from_leaves(|id| unsafe { dropper.drop_node(id) })
276		}
277
278		self.root = None;
279		self.len = 0;
280		self.nodes = S::default();
281	}
282
283	#[cfg(debug_assertions)]
284	pub fn validate(&self, cmp: impl Fn(&T, &T) -> Ordering) {
285		if let Some(id) = self.root {
286			self.validate_node(&cmp, id, None, None, None);
287		}
288	}
289
290	/// Validate the given node and returns the depth of the node.
291	#[cfg(debug_assertions)]
292	pub fn validate_node(
293		&self,
294		cmp: &impl Fn(&T, &T) -> Ordering,
295		id: S::Node,
296		parent: Option<S::Node>,
297		mut min: Option<&T>,
298		mut max: Option<&T>,
299	) -> usize {
300		let node = unsafe { self.nodes.get(id) };
301		node.validate(cmp, parent, min, max);
302
303		let mut depth = None;
304		for (i, child_id) in node.children().enumerate() {
305			let (child_min, child_max) = node.separators(i);
306			let min = child_min.or_else(|| min.take());
307			let max = child_max.or_else(|| max.take());
308
309			let child_depth = self.validate_node(cmp, child_id, Some(id), min, max);
310			match depth {
311				None => depth = Some(child_depth),
312				Some(depth) => {
313					if depth != child_depth {
314						panic!("tree not balanced")
315					}
316				}
317			}
318		}
319
320		match depth {
321			Some(depth) => depth + 1,
322			None => 0,
323		}
324	}
325
326	/// Write the tree in the DOT graph descrption language.
327	///
328	/// Requires the `dot` feature.
329	#[cfg(feature = "dot")]
330	#[inline]
331	pub fn dot_write<W: std::io::Write>(&self, f: &mut W) -> std::io::Result<()>
332	where
333		T: std::fmt::Display,
334		S::Node: Into<usize>,
335	{
336		write!(f, "digraph tree {{\n\tnode [shape=record];\n")?;
337		if let Some(id) = self.root {
338			self.dot_write_node(f, id)?
339		}
340		write!(f, "}}")
341	}
342
343	/// Write the given node in the DOT graph descrption language.
344	///
345	/// Requires the `dot` feature.
346	#[cfg(feature = "dot")]
347	#[inline]
348	fn dot_write_node<W: std::io::Write>(&self, f: &mut W, id: S::Node) -> std::io::Result<()>
349	where
350		T: std::fmt::Display,
351		S::Node: Into<usize>,
352	{
353		let name = format!("n{:?}", id.into());
354		let node = unsafe { self.nodes.get(id) };
355
356		write!(f, "\t{} [label=\"", name)?;
357		if let Some(parent) = node.parent() {
358			write!(f, "({:?})|", parent.into())?;
359		}
360
361		node.dot_write_label(f)?;
362		writeln!(f, "({:?})\"];", id.into())?;
363
364		for child_id in node.children() {
365			self.dot_write_node(f, child_id)?;
366			let child_name = format!("n{:?}", child_id.into());
367			writeln!(f, "\t{} -> {}", name, child_name)?;
368		}
369
370		Ok(())
371	}
372}
373
374impl<T, S: Storage<T>> Drop for RawBTree<T, S> {
375	fn drop(&mut self) {
376		self.clear();
377	}
378}
379
380impl<T: Clone, S: Storage<T>> Clone for RawBTree<T, S> {
381	fn clone(&self) -> Self {
382		unsafe fn clone_node<T: Clone, S: Storage<T>>(
383			old_nodes: &S,
384			new_nodes: &mut S,
385			parent: Option<S::Node>,
386			node_id: S::Node,
387		) -> S::Node {
388			let clone = match old_nodes.get(node_id) {
389				Node::Leaf(node) => Node::Leaf(node::LeafNode::new(parent, node.items().clone())),
390				Node::Internal(node) => {
391					let first = clone_node(old_nodes, new_nodes, None, node.first_child_id());
392					let mut branches = Array::new();
393					for b in node.branches() {
394						branches.push(node::internal::Branch {
395							item: b.item.clone(),
396							child: clone_node(old_nodes, new_nodes, None, b.child),
397						})
398					}
399
400					Node::Internal(node::InternalNode::new(parent, first, branches))
401				}
402			};
403
404			new_nodes.insert_node(clone)
405		}
406
407		let mut nodes = S::default();
408		let root = self
409			.root
410			.map(|root| unsafe { clone_node(&self.nodes, &mut nodes, None, root) });
411
412		Self {
413			nodes,
414			root,
415			len: self.len,
416			item: PhantomData,
417		}
418	}
419}
420
421pub struct Iter<'a, T, S: Storage<T> = BoxStorage> {
422	/// The tree reference.
423	btree: &'a RawBTree<T, S>,
424
425	/// Address of the next item.
426	addr: Option<Address<S::Node>>,
427
428	/// End address.
429	end: Option<Address<S::Node>>,
430
431	/// Remaining item count.
432	len: usize,
433}
434
435impl<'a, T, S: Storage<T>> Iter<'a, T, S> {
436	#[inline]
437	fn new(btree: &'a RawBTree<T, S>) -> Self {
438		let addr = btree.first_item_address();
439		let len = btree.len();
440		Iter {
441			btree,
442			addr,
443			end: None,
444			len,
445		}
446	}
447}
448
449impl<'a, T, S: Storage<T>> Iterator for Iter<'a, T, S> {
450	type Item = &'a T;
451
452	#[inline]
453	fn size_hint(&self) -> (usize, Option<usize>) {
454		(self.len, Some(self.len))
455	}
456
457	#[inline]
458	fn next(&mut self) -> Option<&'a T> {
459		match self.addr {
460			Some(addr) => unsafe {
461				if self.len > 0 {
462					self.len -= 1;
463
464					let item = self.btree.get_at(addr).unwrap();
465					self.addr = self.btree.nodes.next_item_address(addr);
466					Some(item)
467				} else {
468					None
469				}
470			},
471			None => None,
472		}
473	}
474}
475
476impl<'a, T, S: Storage<T>> FusedIterator for Iter<'a, T, S> {}
477impl<'a, T, S: Storage<T>> ExactSizeIterator for Iter<'a, T, S> {}
478
479impl<'a, T, S: Storage<T>> DoubleEndedIterator for Iter<'a, T, S> {
480	#[inline]
481	fn next_back(&mut self) -> Option<&'a T> {
482		if self.len > 0 {
483			unsafe {
484				let addr = match self.end {
485					Some(addr) => self.btree.nodes.previous_item_address(addr).unwrap(),
486					None => self.btree.last_item_address().unwrap(),
487				};
488
489				self.len -= 1;
490
491				let item = self.btree.get_at(addr).unwrap();
492				self.end = Some(addr);
493				Some(item)
494			}
495		} else {
496			None
497		}
498	}
499}
500
501impl<'a, T, S: Storage<T>> Clone for Iter<'a, T, S> {
502	fn clone(&self) -> Self {
503		*self
504	}
505}
506
507impl<'a, T, S: Storage<T>> Copy for Iter<'a, T, S> {}
508
509impl<'a, T, S: Storage<T>> IntoIterator for &'a RawBTree<T, S> {
510	type IntoIter = Iter<'a, T, S>;
511	type Item = &'a T;
512
513	#[inline]
514	fn into_iter(self) -> Iter<'a, T, S> {
515		self.iter()
516	}
517}
518
519pub struct IterMut<'a, T, S: Storage<T> = BoxStorage> {
520	/// The tree reference.
521	btree: &'a mut RawBTree<T, S>,
522
523	/// Address of the next item.
524	addr: Option<Address<S::Node>>,
525
526	/// End address.
527	end: Option<Address<S::Node>>,
528
529	/// Remaining item count.
530	len: usize,
531}
532
533impl<'a, T, S: Storage<T>> IterMut<'a, T, S> {
534	#[inline]
535	fn new(btree: &'a mut RawBTree<T, S>) -> Self {
536		let addr = btree.first_item_address();
537		let len = btree.len();
538		Self {
539			btree,
540			addr,
541			end: None,
542			len,
543		}
544	}
545}
546
547impl<'a, T, S: Storage<T>> Iterator for IterMut<'a, T, S> {
548	type Item = &'a mut T;
549
550	#[inline]
551	fn size_hint(&self) -> (usize, Option<usize>) {
552		(self.len, Some(self.len))
553	}
554
555	#[inline]
556	fn next(&mut self) -> Option<&'a mut T> {
557		match self.addr {
558			Some(addr) => unsafe {
559				if self.len > 0 {
560					self.len -= 1;
561					self.addr = self.btree.nodes.next_item_address(addr);
562					Some(std::mem::transmute::<&mut T, &'a mut T>(
563						self.btree.get_mut_at(addr).unwrap(),
564					))
565				} else {
566					None
567				}
568			},
569			None => None,
570		}
571	}
572}
573
574impl<'a, T, S: Storage<T>> FusedIterator for IterMut<'a, T, S> {}
575impl<'a, T, S: Storage<T>> ExactSizeIterator for IterMut<'a, T, S> {}
576
577impl<'a, T, S: Storage<T>> DoubleEndedIterator for IterMut<'a, T, S> {
578	#[inline]
579	fn next_back(&mut self) -> Option<&'a mut T> {
580		if self.len > 0 {
581			unsafe {
582				let addr = match self.end {
583					Some(addr) => self.btree.nodes.previous_item_address(addr).unwrap(),
584					None => self.btree.last_item_address().unwrap(),
585				};
586
587				self.len -= 1;
588				self.end = Some(addr);
589				Some(std::mem::transmute::<&mut T, &'a mut T>(
590					self.btree.get_mut_at(addr).unwrap(),
591				))
592			}
593		} else {
594			None
595		}
596	}
597}
598
599impl<'a, T, S: Storage<T>> IntoIterator for &'a mut RawBTree<T, S> {
600	type IntoIter = IterMut<'a, T, S>;
601	type Item = &'a mut T;
602
603	#[inline]
604	fn into_iter(self) -> IterMut<'a, T, S> {
605		self.iter_mut()
606	}
607}
608
609pub struct IntoIter<T, S: Storage<T> = BoxStorage> {
610	/// The tree.
611	btree: RawBTree<T, S>,
612
613	/// Address of the next item.
614	addr: Option<Address<S::Node>>,
615
616	/// End address.
617	end: Option<Address<S::Node>>,
618
619	/// Remaining item count.
620	len: usize,
621}
622
623impl<T, S: Storage<T>> IntoIter<T, S> {
624	#[inline]
625	fn new(btree: RawBTree<T, S>) -> Self {
626		let addr = btree.first_item_address();
627		let len = btree.len();
628		Self {
629			btree,
630			addr,
631			end: None,
632			len,
633		}
634	}
635}
636
637impl<T, S: Storage<T>> Iterator for IntoIter<T, S> {
638	type Item = T;
639
640	#[inline]
641	fn size_hint(&self) -> (usize, Option<usize>) {
642		(self.len, Some(self.len))
643	}
644
645	#[inline]
646	fn next(&mut self) -> Option<T> {
647		match self.addr {
648			Some(addr) => unsafe {
649				if self.len > 0 {
650					self.len -= 1;
651					self.addr = self.btree.nodes.next_item_address(addr);
652					Some(std::ptr::read(self.btree.get_at(addr).unwrap()))
653				} else {
654					None
655				}
656			},
657			None => None,
658		}
659	}
660}
661
662impl<T, S: Storage<T>> FusedIterator for IntoIter<T, S> {}
663impl<T, S: Storage<T>> ExactSizeIterator for IntoIter<T, S> {}
664
665impl<T, S: Storage<T>> DoubleEndedIterator for IntoIter<T, S> {
666	#[inline]
667	fn next_back(&mut self) -> Option<T> {
668		if self.len > 0 {
669			unsafe {
670				let addr = match self.end {
671					Some(addr) => self.btree.nodes.previous_item_address(addr).unwrap(),
672					None => self.btree.last_item_address().unwrap(),
673				};
674
675				self.len -= 1;
676				self.end = Some(addr);
677				Some(std::ptr::read(self.btree.get_at(addr).unwrap()))
678			}
679		} else {
680			None
681		}
682	}
683}
684
685impl<T, S: Storage<T>> IntoIterator for RawBTree<T, S> {
686	type IntoIter = IntoIter<T, S>;
687	type Item = T;
688
689	#[inline]
690	fn into_iter(self) -> IntoIter<T, S> {
691		IntoIter::new(self)
692	}
693}
694
695impl<T, S: Storage<T>> Drop for IntoIter<T, S> {
696	fn drop(&mut self) {
697		let _ = self.last();
698		self.btree.forget();
699	}
700}