Skip to main content

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, Offset};
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	/// Returns the identifier of the root node, if any.
191	#[inline]
192	pub fn root(&self) -> Option<S::Node> {
193		self.root
194	}
195
196	/// Returns the address of the item located directly after the given
197	/// address, if any.
198	///
199	/// # Safety
200	///
201	/// The address's node must not have been deallocated.
202	#[inline]
203	pub unsafe fn next_item_address(&self, addr: Address<S::Node>) -> Option<Address<S::Node>> {
204		self.nodes.next_item_address(addr)
205	}
206
207	/// Returns the address of the item located directly before the given
208	/// address, if any.
209	///
210	/// # Safety
211	///
212	/// The address's node must not have been deallocated.
213	#[inline]
214	pub unsafe fn previous_item_address(&self, addr: Address<S::Node>) -> Option<Address<S::Node>> {
215		self.nodes.previous_item_address(addr)
216	}
217
218	/// Returns the front address directly preceding the given address, if
219	/// any.
220	///
221	/// # Safety
222	///
223	/// The address's node must not have been deallocated.
224	#[inline]
225	pub unsafe fn previous_front_address(
226		&self,
227		addr: Address<S::Node>,
228	) -> Option<Address<S::Node>> {
229		self.nodes.previous_front_address(addr)
230	}
231
232	/// Returns the back address directly following the given address, if
233	/// any.
234	///
235	/// # Safety
236	///
237	/// The address's node must not have been deallocated.
238	#[inline]
239	pub unsafe fn next_back_address(&self, addr: Address<S::Node>) -> Option<Address<S::Node>> {
240		self.nodes.next_back_address(addr)
241	}
242
243	/// Returns the item address, or back address, directly following the
244	/// given address, if any.
245	///
246	/// # Safety
247	///
248	/// The address's node must not have been deallocated.
249	#[inline]
250	pub unsafe fn next_item_or_back_address(
251		&self,
252		addr: Address<S::Node>,
253	) -> Option<Address<S::Node>> {
254		self.nodes.next_item_or_back_address(addr)
255	}
256
257	/// Normalizes the given address so that an out-of-node-bounds address
258	/// points to the next item.
259	///
260	/// # Safety
261	///
262	/// The address's node must not have been deallocated.
263	#[inline]
264	pub unsafe fn normalize(&self, addr: Address<S::Node>) -> Option<Address<S::Node>> {
265		self.nodes.normalize(addr)
266	}
267
268	/// Returns the greatest valid leaf address that directly precedes (or is)
269	/// the given address.
270	///
271	/// # Safety
272	///
273	/// The address's node must not have been deallocated.
274	#[inline]
275	pub unsafe fn leaf_address(&self, addr: Address<S::Node>) -> Address<S::Node> {
276		self.nodes.leaf_address(addr)
277	}
278
279	/// Inserts the given item at the given address.
280	///
281	/// The address is first converted into a leaf address using
282	/// [`Self::leaf_address`], and the item is inserted using
283	/// [`Self::insert_exactly_at`].
284	///
285	/// Returns the address of the inserted item, which may differ from the
286	/// input address if the tree gets rebalanced. `addr` may be `None` only if
287	/// the tree is empty.
288	///
289	/// # Correctness
290	///
291	/// It is assumed that it is btree-correct to insert the given item at the
292	/// given address.
293	///
294	/// # Safety
295	///
296	/// The address's node (if any) must not have been deallocated.
297	#[inline]
298	pub unsafe fn insert_at(
299		&mut self,
300		addr: Option<Address<S::Node>>,
301		item: T,
302	) -> Option<Address<S::Node>> {
303		let (root, addr) = self.nodes.insert_at(self.root, addr, item);
304		self.root = root;
305		self.len += 1;
306		addr
307	}
308
309	/// Inserts the given item exactly at the given **leaf** address.
310	///
311	/// If the address refers to an internal node, `opt_right_id` defines the
312	/// identifier of the child node inserted on the right of the inserted
313	/// item.
314	///
315	/// Returns the address of the inserted item, which may differ from the
316	/// input address if the tree gets rebalanced. `addr` may be `None` only
317	/// if the tree is empty.
318	///
319	/// # Correctness
320	///
321	/// It is assumed that it is btree-correct to insert the given item at the
322	/// given address.
323	///
324	/// # Panics
325	///
326	/// This function panics if the address refers to an internal node and
327	/// `opt_right_id` is `None`.
328	///
329	/// # Safety
330	///
331	/// The address's node (if any) must not have been deallocated.
332	#[inline]
333	pub unsafe fn insert_exactly_at(
334		&mut self,
335		addr: Option<Address<S::Node>>,
336		item: T,
337		opt_right_id: Option<S::Node>,
338	) -> Option<Address<S::Node>> {
339		let (root, addr) = self
340			.nodes
341			.insert_exactly_at(self.root, addr, item, opt_right_id);
342		self.root = root;
343		self.len += 1;
344		addr
345	}
346
347	/// Replaces the item located at the given address, returning the
348	/// previous item.
349	///
350	/// # Safety
351	///
352	/// The address's node must not have been deallocated.
353	#[inline]
354	pub unsafe fn replace_at(&mut self, addr: Address<S::Node>, item: T) -> T {
355		self.nodes.replace_at(addr, item)
356	}
357
358	/// Removes the item at the given address, if any.
359	///
360	/// If an item is removed, this function returns the removed item and the
361	/// updated address where an item could be reinserted to preserve the
362	/// tree's order, if any.
363	///
364	/// # Safety
365	///
366	/// The address's node must not have been deallocated.
367	#[inline]
368	pub unsafe fn remove_at(
369		&mut self,
370		addr: Address<S::Node>,
371	) -> Option<(T, Option<Address<S::Node>>)> {
372		self.nodes.remove_at(self.root, addr).map(|r| {
373			self.root = r.new_root;
374			self.len -= 1;
375			(r.item, r.new_addr)
376		})
377	}
378
379	/// Returns a reference to the node identified by `id`.
380	///
381	/// # Safety
382	///
383	/// `id` must not have been deallocated.
384	#[inline]
385	pub unsafe fn node(&self, id: S::Node) -> &Node<T, S> {
386		self.nodes.get(id)
387	}
388
389	/// Returns a mutable reference to the node identified by `id`.
390	///
391	/// # Safety
392	///
393	/// `id` must not have been deallocated.
394	#[inline]
395	pub unsafe fn node_mut(&mut self, id: S::Node) -> &mut Node<T, S> {
396		self.nodes.get_mut(id)
397	}
398
399	pub fn iter(&self) -> Iter<'_, T, S> {
400		Iter::new(self)
401	}
402
403	pub fn iter_mut(&mut self) -> IterMut<'_, T, S> {
404		IterMut::new(self)
405	}
406
407	#[inline]
408	pub fn insert(&mut self, cmp: impl Fn(&T, &T) -> Ordering, item: T) -> Option<T> {
409		match self.address_of(cmp, &item) {
410			Ok(addr) => Some(unsafe { self.nodes.replace_at(addr, item) }),
411			Err(addr) => {
412				let (root, _) =
413					unsafe { self.nodes.insert_exactly_at(self.root, addr, item, None) };
414				self.root = root;
415				self.len += 1;
416				None
417			}
418		}
419	}
420
421	/// Remove the next item and return it.
422	#[inline]
423	pub fn remove<Q: ?Sized>(&mut self, cmp: impl Fn(&T, &Q) -> Ordering, key: &Q) -> Option<T> {
424		match self.address_of(cmp, key) {
425			Ok(addr) => {
426				let r = unsafe { self.nodes.remove_at(self.root, addr).unwrap() };
427				self.root = r.new_root;
428				self.len -= 1;
429				Some(r.item)
430			}
431			Err(_) => None,
432		}
433	}
434
435	pub fn visit_from_leaves(&self, mut f: impl FnMut(S::Node)) {
436		if let Some(id) = self.root {
437			let node = unsafe { self.nodes.get(id) };
438			node.visit_from_leaves(&self.nodes, &mut f);
439			f(id)
440		}
441	}
442
443	pub fn visit_from_leaves_mut(&mut self, mut f: impl FnMut(S::Node, &mut Node<T, S>)) {
444		if let Some(root_id) = self.root {
445			let root_node: &mut Node<T, S> =
446				unsafe { std::mem::transmute(self.nodes.get_mut(root_id)) };
447			root_node.visit_from_leaves_mut(&mut self.nodes, &mut f);
448			f(root_id, root_node)
449		}
450	}
451
452	pub fn forget(&mut self) {
453		use storage::Dropper;
454		let mut dropper = self.nodes.start_dropping();
455
456		self.visit_from_leaves_mut(|id, node| unsafe {
457			node.forget();
458			if let Some(dropper) = &mut dropper {
459				dropper.drop_node(id);
460			}
461		});
462
463		self.root = None;
464		self.len = 0;
465		self.nodes = S::default();
466	}
467
468	pub fn clear(&mut self) {
469		use storage::Dropper;
470		if let Some(mut dropper) = self.nodes.start_dropping() {
471			self.visit_from_leaves(|id| unsafe { dropper.drop_node(id) })
472		}
473
474		self.root = None;
475		self.len = 0;
476		self.nodes = S::default();
477	}
478
479	#[cfg(debug_assertions)]
480	pub fn validate(&self, cmp: impl Fn(&T, &T) -> Ordering) {
481		if let Some(id) = self.root {
482			self.validate_node(&cmp, id, None, None, None);
483		}
484	}
485
486	/// Validate the given node and returns the depth of the node.
487	#[cfg(debug_assertions)]
488	pub fn validate_node(
489		&self,
490		cmp: &impl Fn(&T, &T) -> Ordering,
491		id: S::Node,
492		parent: Option<S::Node>,
493		mut min: Option<&T>,
494		mut max: Option<&T>,
495	) -> usize {
496		let node = unsafe { self.nodes.get(id) };
497		node.validate(cmp, parent, min, max);
498
499		let mut depth = None;
500		for (i, child_id) in node.children().enumerate() {
501			let (child_min, child_max) = node.separators(i);
502			let min = child_min.or_else(|| min.take());
503			let max = child_max.or_else(|| max.take());
504
505			let child_depth = self.validate_node(cmp, child_id, Some(id), min, max);
506			match depth {
507				None => depth = Some(child_depth),
508				Some(depth) => {
509					if depth != child_depth {
510						panic!("tree not balanced")
511					}
512				}
513			}
514		}
515
516		match depth {
517			Some(depth) => depth + 1,
518			None => 0,
519		}
520	}
521
522	/// Write the tree in the DOT graph descrption language.
523	///
524	/// Requires the `dot` feature.
525	#[cfg(feature = "dot")]
526	#[inline]
527	pub fn dot_write<W: std::io::Write>(&self, f: &mut W) -> std::io::Result<()>
528	where
529		T: std::fmt::Display,
530		S::Node: Into<usize>,
531	{
532		write!(f, "digraph tree {{\n\tnode [shape=record];\n")?;
533		if let Some(id) = self.root {
534			self.dot_write_node(f, id)?
535		}
536		write!(f, "}}")
537	}
538
539	/// Write the given node in the DOT graph descrption language.
540	///
541	/// Requires the `dot` feature.
542	#[cfg(feature = "dot")]
543	#[inline]
544	fn dot_write_node<W: std::io::Write>(&self, f: &mut W, id: S::Node) -> std::io::Result<()>
545	where
546		T: std::fmt::Display,
547		S::Node: Into<usize>,
548	{
549		let name = format!("n{:?}", id.into());
550		let node = unsafe { self.nodes.get(id) };
551
552		write!(f, "\t{} [label=\"", name)?;
553		if let Some(parent) = node.parent() {
554			write!(f, "({:?})|", parent.into())?;
555		}
556
557		node.dot_write_label(f)?;
558		writeln!(f, "({:?})\"];", id.into())?;
559
560		for child_id in node.children() {
561			self.dot_write_node(f, child_id)?;
562			let child_name = format!("n{:?}", child_id.into());
563			writeln!(f, "\t{} -> {}", name, child_name)?;
564		}
565
566		Ok(())
567	}
568}
569
570impl<T, S: Storage<T>> Drop for RawBTree<T, S> {
571	fn drop(&mut self) {
572		self.clear();
573	}
574}
575
576impl<T: Clone, S: Storage<T>> Clone for RawBTree<T, S> {
577	fn clone(&self) -> Self {
578		unsafe fn clone_node<T: Clone, S: Storage<T>>(
579			old_nodes: &S,
580			new_nodes: &mut S,
581			parent: Option<S::Node>,
582			node_id: S::Node,
583		) -> S::Node {
584			let clone = match old_nodes.get(node_id) {
585				Node::Leaf(node) => Node::Leaf(node::LeafNode::new(parent, node.items().clone())),
586				Node::Internal(node) => {
587					let first = clone_node(old_nodes, new_nodes, None, node.first_child_id());
588					let mut branches = Array::new();
589					for b in node.branches() {
590						branches.push(node::internal::Branch {
591							item: b.item.clone(),
592							child: clone_node(old_nodes, new_nodes, None, b.child),
593						})
594					}
595
596					Node::Internal(node::InternalNode::new(parent, first, branches))
597				}
598			};
599
600			new_nodes.insert_node(clone)
601		}
602
603		let mut nodes = S::default();
604		let root = self
605			.root
606			.map(|root| unsafe { clone_node(&self.nodes, &mut nodes, None, root) });
607
608		Self {
609			nodes,
610			root,
611			len: self.len,
612			item: PhantomData,
613		}
614	}
615}
616
617pub struct Iter<'a, T, S: Storage<T> = BoxStorage> {
618	/// The tree reference.
619	btree: &'a RawBTree<T, S>,
620
621	/// Address of the next item.
622	addr: Option<Address<S::Node>>,
623
624	/// End address.
625	end: Option<Address<S::Node>>,
626
627	/// Remaining item count.
628	len: usize,
629}
630
631impl<'a, T, S: Storage<T>> Iter<'a, T, S> {
632	#[inline]
633	fn new(btree: &'a RawBTree<T, S>) -> Self {
634		let addr = btree.first_item_address();
635		let len = btree.len();
636		Iter {
637			btree,
638			addr,
639			end: None,
640			len,
641		}
642	}
643}
644
645impl<'a, T, S: Storage<T>> Iterator for Iter<'a, T, S> {
646	type Item = &'a T;
647
648	#[inline]
649	fn size_hint(&self) -> (usize, Option<usize>) {
650		(self.len, Some(self.len))
651	}
652
653	#[inline]
654	fn next(&mut self) -> Option<&'a T> {
655		match self.addr {
656			Some(addr) => unsafe {
657				if self.len > 0 {
658					self.len -= 1;
659
660					let item = self.btree.get_at(addr).unwrap();
661					self.addr = self.btree.nodes.next_item_address(addr);
662					Some(item)
663				} else {
664					None
665				}
666			},
667			None => None,
668		}
669	}
670}
671
672impl<'a, T, S: Storage<T>> FusedIterator for Iter<'a, T, S> {}
673impl<'a, T, S: Storage<T>> ExactSizeIterator for Iter<'a, T, S> {}
674
675impl<'a, T, S: Storage<T>> DoubleEndedIterator for Iter<'a, T, S> {
676	#[inline]
677	fn next_back(&mut self) -> Option<&'a T> {
678		if self.len > 0 {
679			unsafe {
680				let addr = match self.end {
681					Some(addr) => self.btree.nodes.previous_item_address(addr).unwrap(),
682					None => self.btree.last_item_address().unwrap(),
683				};
684
685				self.len -= 1;
686
687				let item = self.btree.get_at(addr).unwrap();
688				self.end = Some(addr);
689				Some(item)
690			}
691		} else {
692			None
693		}
694	}
695}
696
697impl<'a, T, S: Storage<T>> Clone for Iter<'a, T, S> {
698	fn clone(&self) -> Self {
699		*self
700	}
701}
702
703impl<'a, T, S: Storage<T>> Copy for Iter<'a, T, S> {}
704
705impl<'a, T, S: Storage<T>> IntoIterator for &'a RawBTree<T, S> {
706	type IntoIter = Iter<'a, T, S>;
707	type Item = &'a T;
708
709	#[inline]
710	fn into_iter(self) -> Iter<'a, T, S> {
711		self.iter()
712	}
713}
714
715pub struct IterMut<'a, T, S: Storage<T> = BoxStorage> {
716	/// The tree reference.
717	btree: &'a mut RawBTree<T, S>,
718
719	/// Address of the next item.
720	addr: Option<Address<S::Node>>,
721
722	/// End address.
723	end: Option<Address<S::Node>>,
724
725	/// Remaining item count.
726	len: usize,
727}
728
729impl<'a, T, S: Storage<T>> IterMut<'a, T, S> {
730	#[inline]
731	fn new(btree: &'a mut RawBTree<T, S>) -> Self {
732		let addr = btree.first_item_address();
733		let len = btree.len();
734		Self {
735			btree,
736			addr,
737			end: None,
738			len,
739		}
740	}
741}
742
743impl<'a, T, S: Storage<T>> Iterator for IterMut<'a, T, S> {
744	type Item = &'a mut T;
745
746	#[inline]
747	fn size_hint(&self) -> (usize, Option<usize>) {
748		(self.len, Some(self.len))
749	}
750
751	#[inline]
752	fn next(&mut self) -> Option<&'a mut T> {
753		match self.addr {
754			Some(addr) => unsafe {
755				if self.len > 0 {
756					self.len -= 1;
757					self.addr = self.btree.nodes.next_item_address(addr);
758					Some(std::mem::transmute::<&mut T, &'a mut T>(
759						self.btree.get_mut_at(addr).unwrap(),
760					))
761				} else {
762					None
763				}
764			},
765			None => None,
766		}
767	}
768}
769
770impl<'a, T, S: Storage<T>> FusedIterator for IterMut<'a, T, S> {}
771impl<'a, T, S: Storage<T>> ExactSizeIterator for IterMut<'a, T, S> {}
772
773impl<'a, T, S: Storage<T>> DoubleEndedIterator for IterMut<'a, T, S> {
774	#[inline]
775	fn next_back(&mut self) -> Option<&'a mut T> {
776		if self.len > 0 {
777			unsafe {
778				let addr = match self.end {
779					Some(addr) => self.btree.nodes.previous_item_address(addr).unwrap(),
780					None => self.btree.last_item_address().unwrap(),
781				};
782
783				self.len -= 1;
784				self.end = Some(addr);
785				Some(std::mem::transmute::<&mut T, &'a mut T>(
786					self.btree.get_mut_at(addr).unwrap(),
787				))
788			}
789		} else {
790			None
791		}
792	}
793}
794
795impl<'a, T, S: Storage<T>> IntoIterator for &'a mut RawBTree<T, S> {
796	type IntoIter = IterMut<'a, T, S>;
797	type Item = &'a mut T;
798
799	#[inline]
800	fn into_iter(self) -> IterMut<'a, T, S> {
801		self.iter_mut()
802	}
803}
804
805pub struct IntoIter<T, S: Storage<T> = BoxStorage> {
806	/// The tree.
807	btree: RawBTree<T, S>,
808
809	/// Address of the next item.
810	addr: Option<Address<S::Node>>,
811
812	/// End address.
813	end: Option<Address<S::Node>>,
814
815	/// Remaining item count.
816	len: usize,
817}
818
819impl<T, S: Storage<T>> IntoIter<T, S> {
820	#[inline]
821	fn new(btree: RawBTree<T, S>) -> Self {
822		let addr = btree.first_item_address();
823		let len = btree.len();
824		Self {
825			btree,
826			addr,
827			end: None,
828			len,
829		}
830	}
831}
832
833impl<T, S: Storage<T>> Iterator for IntoIter<T, S> {
834	type Item = T;
835
836	#[inline]
837	fn size_hint(&self) -> (usize, Option<usize>) {
838		(self.len, Some(self.len))
839	}
840
841	#[inline]
842	fn next(&mut self) -> Option<T> {
843		match self.addr {
844			Some(addr) => unsafe {
845				if self.len > 0 {
846					self.len -= 1;
847					self.addr = self.btree.nodes.next_item_address(addr);
848					Some(std::ptr::read(self.btree.get_at(addr).unwrap()))
849				} else {
850					None
851				}
852			},
853			None => None,
854		}
855	}
856}
857
858impl<T, S: Storage<T>> FusedIterator for IntoIter<T, S> {}
859impl<T, S: Storage<T>> ExactSizeIterator for IntoIter<T, S> {}
860
861impl<T, S: Storage<T>> DoubleEndedIterator for IntoIter<T, S> {
862	#[inline]
863	fn next_back(&mut self) -> Option<T> {
864		if self.len > 0 {
865			unsafe {
866				let addr = match self.end {
867					Some(addr) => self.btree.nodes.previous_item_address(addr).unwrap(),
868					None => self.btree.last_item_address().unwrap(),
869				};
870
871				self.len -= 1;
872				self.end = Some(addr);
873				Some(std::ptr::read(self.btree.get_at(addr).unwrap()))
874			}
875		} else {
876			None
877		}
878	}
879}
880
881impl<T, S: Storage<T>> IntoIterator for RawBTree<T, S> {
882	type IntoIter = IntoIter<T, S>;
883	type Item = T;
884
885	#[inline]
886	fn into_iter(self) -> IntoIter<T, S> {
887		IntoIter::new(self)
888	}
889}
890
891impl<T, S: Storage<T>> Drop for IntoIter<T, S> {
892	fn drop(&mut self) {
893		let _ = self.last();
894		self.btree.forget();
895	}
896}