diff --git a/src/tree.rs b/src/tree.rs index 10021db..5df10a6 100644 --- a/src/tree.rs +++ b/src/tree.rs @@ -183,6 +183,16 @@ impl NodeRef { }) .ok_or(self) } + + pub(crate) fn first_edge(self) -> Handle, marker::Edge> { + unsafe { Handle::new_edge(self, 0) } + } + + pub(crate) fn last_edge(self) -> Handle, marker::Edge> { + let len = self.len(); + assert!(len > 0); + unsafe { Handle::new_edge(self, len) } + } } impl Handle, marker::Edge> { @@ -616,6 +626,27 @@ impl NodeRef { } } } +impl NodeRef { + fn first_leaf_edge(self) -> Handle, marker::Edge> { + let mut node = self; + loop { + match node.force() { + ForceResult::Leaf(leaf) => break leaf.first_edge(), + ForceResult::Internal(internal) => node = internal.first_edge().descend(), + } + } + } + + fn last_leaf_edge(self) -> Handle, marker::Edge> { + let mut node = self; + loop { + match node.force() { + ForceResult::Leaf(leaf) => break leaf.last_edge(), + ForceResult::Internal(internal) => node = internal.last_edge().descend(), + } + } + } +} impl<'a, K, V> NodeRef, K, V> { pub(super) fn grow_node(&mut self) { @@ -1433,6 +1464,73 @@ unsafe fn slice_insert(slice: &mut [MaybeUninit], idx: usize, value: T) { } } +mod range { + #![allow(dead_code)] + use core::ptr; + + use super::marker; + + use crate::tree::{Handle, NodeRef}; + + enum LeafHandle { + Root(NodeRef), + Edge(Handle, marker::Edge>), + } + + pub(crate) struct LeafRange { + front: Option>, + back: Option>, + } + + impl<'a, K: 'a, V: 'a> Clone for LeafHandle, K, V> { + fn clone(&self) -> Self { + match self { + LeafHandle::Root(node) => LeafHandle::Root(*node), + LeafHandle::Edge(handle) => LeafHandle::Edge(*handle), + } + } + } + + impl LeafHandle { + fn reborrow(&self) -> LeafHandle, K, V> { + match self { + Self::Root(node) => LeafHandle::Root(node.reborrow()), + Self::Edge(handle) => LeafHandle::Edge(handle.reborrow()), + } + } + } + + impl LeafRange { + fn init_front(&mut self) -> Option<&mut Handle, marker::Edge>> { + if let Some(LeafHandle::Root(root)) = &self.front { + self.front = Some(LeafHandle::Edge( + unsafe { ptr::read(root) }.first_leaf_edge(), + )); + } + + match &mut self.front { + None => None, + Some(LeafHandle::Edge(edge)) => Some(edge), + Some(LeafHandle::Root(_)) => unreachable!(), + } + } + + fn init_back(&mut self) -> Option<&mut Handle, marker::Edge>> { + if let Some(LeafHandle::Root(root)) = &self.back { + self.back = Some(LeafHandle::Edge( + unsafe { ptr::read(root) }.last_leaf_edge(), + )); + } + + match &mut self.back { + None => None, + Some(LeafHandle::Edge(edge)) => Some(edge), + Some(LeafHandle::Root(_)) => unreachable!(), + } + } + } +} + #[cfg(test)] mod tests { use super::*;