feat(tree): enhance tree structure with debug traits and new methods

- Add `Debug` implementations for tree-related structs and enums
- Introduce new methods for node manipulation, including `make_internal_node`
- Refactor `Tree::entry` to support key insertion and retrieval
- Improve internal node handling with enhanced parent-child link management
- Add test cases for tree operations and debug output
This commit is contained in:
Janis 2025-08-08 20:57:02 +02:00
parent b6c16f2739
commit e07e69a0c4
2 changed files with 565 additions and 67 deletions

View file

@ -1,7 +1,12 @@
#![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(
feature = "nightly",
feature(strict_provenance_atomic_ptr, box_vec_non_null, maybe_uninit_slice)
feature(
strict_provenance_atomic_ptr,
box_vec_non_null,
maybe_uninit_slice,
debug_closure_helpers
)
)]
#![cfg_attr(feature = "transposed-option", feature(try_trait_v2))]

View file

@ -24,18 +24,29 @@ use core::{
mod marker {
use core::marker::PhantomData;
#[derive(Debug)]
pub struct LeafOrInternal;
#[derive(Debug)]
pub struct Leaf;
#[derive(Debug)]
pub struct Internal;
#[derive(Debug)]
pub struct Edge;
#[derive(Debug)]
pub struct Value;
#[derive(Debug)]
pub struct Owned;
#[derive(Debug)]
pub struct Mut<'a>(PhantomData<&'a mut ()>);
#[derive(Debug)]
pub struct ValMut<'a>(PhantomData<&'a mut ()>);
#[derive(Debug)]
pub struct Immut<'a>(PhantomData<&'a ()>);
#[derive(Debug)]
pub struct Dying;
#[derive(Debug)]
pub struct DormantMut;
pub trait BorrowType {
@ -55,13 +66,15 @@ mod marker {
const CAPACITY: usize = 16;
#[derive(Debug)]
struct LeafNode<K, V> {
parent: Option<NonNull<InternalNode<K, V>>>,
parent_idx: MaybeUninit<u16>,
value: Option<MaybeUninit<V>>,
value: Option<V>,
leaf: bool,
}
#[derive(Debug)]
struct InternalNode<K, V> {
data: LeafNode<K, V>,
next: Option<NonNull<InternalNode<K, V>>>,
@ -72,11 +85,13 @@ struct InternalNode<K, V> {
type BoxedNode<K, V> = NonNull<LeafNode<K, V>>;
#[derive(Debug)]
struct NodeRef<BorrowType, K, V, Type> {
node: NonNull<LeafNode<K, V>>,
_marker: PhantomData<(BorrowType, Type)>,
}
#[derive(Debug)]
struct Handle<Node, Type> {
node: Node,
idx: usize,
@ -140,6 +155,7 @@ impl<K, V> InternalNode<K, V> {
unsafe fn init(this: *mut Self) {
unsafe {
LeafNode::init(&raw mut (*this).data);
(&raw mut (*this).data.leaf).write(false);
(&raw mut (*this).next).write(None);
(&raw mut (*this).len).write(0);
// keys and edges may be left uninitialized
@ -150,6 +166,7 @@ impl<K, V> InternalNode<K, V> {
let mut uninit: Box<MaybeUninit<LeafNode<K, V>>> = unsafe { core::mem::transmute(leaf) };
unsafe {
core::ptr::swap(&raw mut (*this).data, uninit.as_mut_ptr());
(&raw mut (*this).data.leaf).write(false);
(&raw mut (*this).next).write(None);
(&raw mut (*this).len).write(1);
}
@ -183,11 +200,15 @@ impl<K, V> NodeRef<marker::Owned, K, V, marker::Leaf> {
}
impl<K, V> NodeRef<marker::Owned, K, V, marker::Internal> {
fn new_internal(child: Root<K, V>) -> Self {
fn new_internal_with_child(child: Root<K, V>) -> Self {
let mut node = InternalNode::new();
node.edges[0].write(child.node);
// SAFETY: `height` isn't zero
unsafe { NodeRef::from_new_internal(node) }
}
fn new_internal() -> Self {
let node = InternalNode::new();
unsafe { NodeRef::from_new_internal(node) }
}
@ -199,7 +220,6 @@ impl<K, V> NodeRef<marker::Owned, K, V, marker::Internal> {
node,
_marker: PhantomData,
};
this.borrow_mut().correct_all_childrens_parent_links();
this
}
}
@ -295,41 +315,34 @@ impl<BorrowType: marker::BorrowType, K, V>
}
}
impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>, marker::Edge> {
/// Fixes the parent pointer and index in the child node that this edge
/// links to. This is useful when the ordering of edges has been changed,
fn correct_parent_link(self) {
// Create backpointer without invalidating other references to the node.
let ptr = unsafe { NonNull::new_unchecked(NodeRef::as_internal_ptr(&self.node)) };
let idx = self.idx;
let mut child = self.descend();
child.set_parent_link(ptr, idx);
}
}
impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal> {
/// Sets the node's link to its parent edge,
/// without invalidating other references to the node.
fn set_parent_link(&mut self, parent: NonNull<InternalNode<K, V>>, parent_idx: usize) {
let leaf = Self::as_leaf_ptr(self);
unsafe { (*leaf).parent = Some(parent) };
unsafe { (*leaf).parent_idx.write(parent_idx as u16) };
}
}
impl<'a, K, V> NodeRef<marker::Mut<'a>, K, V, marker::Internal> {
/// # Safety
/// Every item returned by `range` is a valid edge index for the node.
unsafe fn correct_childrens_parent_links<R: Iterator<Item = usize>>(&mut self, range: R) {
for i in range {
debug_assert!(i <= self.len());
unsafe { Handle::new_edge(self.reborrow_mut(), i) }.correct_parent_link();
impl<'a, K, V, NodeType, HandleType> Handle<NodeRef<marker::Mut<'a>, K, V, NodeType>, HandleType> {
/// Temporarily takes out another mutable handle on the same location. Beware, as
/// this method is very dangerous, doubly so since it might not immediately appear
/// dangerous.
///
/// For details, see `NodeRef::reborrow_mut`.
pub(super) unsafe fn reborrow_mut(
&mut self,
) -> Handle<NodeRef<marker::Mut<'_>, K, V, NodeType>, HandleType> {
// We can't use Handle::new_kv or Handle::new_edge because we don't know our type
Handle {
node: unsafe { self.node.reborrow_mut() },
idx: self.idx,
_marker: PhantomData,
}
}
fn correct_all_childrens_parent_links(&mut self) {
let len = self.len();
unsafe { self.correct_childrens_parent_links(0..=len) };
/// Returns a dormant copy of this handle which can be reawakened later.
///
/// See `DormantMutRef` for more details.
pub(super) fn dormant(
&self,
) -> Handle<NodeRef<marker::DormantMut, K, V, NodeType>, HandleType> {
Handle {
node: self.node.dormant(),
idx: self.idx,
_marker: PhantomData,
}
}
}
@ -341,6 +354,11 @@ impl<BorrowType, K, V> NodeRef<BorrowType, K, V, marker::Internal> {
// SAFETY: the static node type is `Internal`.
this.node.as_ptr() as *mut InternalNode<K, V>
}
fn as_internal_non_null(this: &Self) -> NonNull<InternalNode<K, V>> {
// SAFETY: the static node type is `Internal`.
unsafe { NonNull::new_unchecked(Self::as_internal_ptr(this)) }
}
}
impl<'a, K, V> NodeRef<marker::Mut<'a>, K, V, marker::Internal> {
@ -349,6 +367,19 @@ impl<'a, K, V> NodeRef<marker::Mut<'a>, K, V, marker::Internal> {
let ptr = Self::as_internal_ptr(self);
unsafe { &mut *ptr }
}
pub(super) fn len_mut(&mut self) -> &mut u16 {
// SAFETY: we have exclusive access to the entire node.
unsafe { &mut (*Self::as_internal_ptr(self)).len }
}
pub(super) fn next_mut(&mut self) -> Option<NodeRef<marker::Mut<'a>, K, V, marker::Internal>> {
let internal = self.as_internal_mut();
internal.next.map(|next| NodeRef {
node: next.cast(),
_marker: PhantomData,
})
}
}
impl<K, V, Type> NodeRef<marker::Owned, K, V, Type> {
@ -422,6 +453,46 @@ impl<'a, K, V, Type> NodeRef<marker::Mut<'a>, K, V, Type> {
}
}
impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::Internal> {
/// Borrows exclusive access to an element of the key storage area.
///
/// # Safety
/// `index` is in bounds of 0..CAPACITY
unsafe fn key_area_mut<I, Output: ?Sized>(&mut self, index: I) -> &mut Output
where
I: core::slice::SliceIndex<[MaybeUninit<K>], Output = Output>,
{
// SAFETY: the caller will not be able to call further methods on self
// until the key slice reference is dropped, as we have unique access
// for the lifetime of the borrow.
unsafe {
self.as_internal_mut()
.keys
.as_mut_slice()
.get_unchecked_mut(index)
}
}
/// Borrows exclusive access to an element or slice of the node's value storage area.
///
/// # Safety
/// `index` is in bounds of 0..CAPACITY
unsafe fn edge_area_mut<I, Output: ?Sized>(&mut self, index: I) -> &mut Output
where
I: core::slice::SliceIndex<[MaybeUninit<BoxedNode<K, V>>], Output = Output>,
{
// SAFETY: the caller will not be able to call further methods on self
// until the value slice reference is dropped, as we have unique access
// for the lifetime of the borrow.
unsafe {
self.as_internal_mut()
.edges
.as_mut_slice()
.get_unchecked_mut(index)
}
}
}
impl<K, V, Type> NodeRef<marker::DormantMut, K, V, Type> {
/// Revert to the unique borrow initially captured.
///
@ -492,13 +563,6 @@ impl<BorrowType, K, V, Type> NodeRef<BorrowType, K, V, Type> {
}
impl<'a, K: 'a, V: 'a> NodeRef<marker::Immut<'a>, K, V, marker::Internal> {
/// Exposes the leaf portion of any leaf or internal node in an immutable tree.
fn into_leaf(self) -> &'a LeafNode<K, V> {
let ptr = Self::as_leaf_ptr(&self);
// SAFETY: there can be no mutable references into this tree borrowed as `Immut`.
unsafe { &*ptr }
}
fn into_internal(self) -> &'a InternalNode<K, V> {
// SAFETY: the static node type is `Internal`.
unsafe { &*Self::as_internal_ptr(&self) }
@ -514,6 +578,24 @@ impl<'a, K: 'a, V: 'a> NodeRef<marker::Immut<'a>, K, V, marker::Internal> {
.assume_init_ref()
}
}
pub(super) fn edges(&self) -> &[BoxedNode<K, V>] {
let internal = self.into_internal();
unsafe {
internal
.edges
.get_unchecked(..usize::from(internal.len + 1))
.assume_init_ref()
}
}
pub(super) fn next(&self) -> Option<NodeRef<marker::Immut<'a>, K, V, marker::Internal>> {
let internal = self.into_internal();
internal.next.map(|next| NodeRef {
node: next.cast(),
_marker: PhantomData,
})
}
}
impl<BorrowType, K, V, NodeType, HandleType>
@ -545,11 +627,35 @@ impl<'a, K: 'a, V: 'a, NodeType> Handle<NodeRef<marker::Immut<'a>, K, V, NodeTyp
/// SAFETY: the caller must ensure that `idx < node.len()`
pub(super) unsafe fn into_value(self) -> &'a V {
let leaf = self.node.into_leaf();
let v = unsafe { leaf.value.as_ref().unwrap().assume_init_ref() };
let v = leaf.value.as_ref().unwrap();
v
}
}
impl<BorrowType, K, V> Handle<NodeRef<BorrowType, K, V, marker::Leaf>, marker::Edge> {
pub(super) fn forget_node_type(
self,
) -> Handle<NodeRef<BorrowType, K, V, marker::LeafOrInternal>, marker::Edge> {
unsafe { Handle::new_edge(self.node.forget_type(), self.idx) }
}
}
impl<BorrowType, K, V> Handle<NodeRef<BorrowType, K, V, marker::Internal>, marker::Edge> {
pub(super) fn forget_node_type(
self,
) -> Handle<NodeRef<BorrowType, K, V, marker::LeafOrInternal>, marker::Edge> {
unsafe { Handle::new_edge(self.node.forget_type(), self.idx) }
}
}
impl<BorrowType, K, V> Handle<NodeRef<BorrowType, K, V, marker::Leaf>, marker::Value> {
pub(super) fn forget_node_type(
self,
) -> Handle<NodeRef<BorrowType, K, V, marker::LeafOrInternal>, marker::Value> {
unsafe { Handle::new_value(self.node.forget_type()) }
}
}
pub(super) enum ForceResult<Leaf, Internal> {
Leaf(Leaf),
Internal(Internal),
@ -629,6 +735,50 @@ impl<BorrowType, K, V, Type> NodeRef<BorrowType, K, V, Type> {
}
}
impl<'a, K, V> NodeRef<marker::Mut<'a>, K, V, marker::Leaf> {
/// node must have parent/ be a leaf node.
pub(super) unsafe fn make_internal_node(
self,
) -> NodeRef<marker::Mut<'a>, K, V, marker::Internal> {
let leaf = self.node;
let mut parent = self.ascend().ok().unwrap();
let internal = Box::into_non_null(InternalNode::new_with_leaf(unsafe {
Box::from_non_null(leaf)
}))
.cast();
parent.node.as_internal_mut().edges[parent.idx].write(internal);
NodeRef {
node: internal,
_marker: PhantomData,
}
}
}
impl<'a, K, V, Type> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, Type> {
/// node must have parent/ be a leaf node.
pub(super) unsafe fn make_internal_node(
self,
) -> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>, Type> {
Handle {
node: unsafe { self.node.make_internal_node() },
idx: self.idx,
_marker: PhantomData,
}
}
}
impl<BorrowType, K, V> Handle<NodeRef<BorrowType, K, V, marker::LeafOrInternal>, marker::Edge> {
/// Converts this edge handle into a value handle.
pub(super) fn into_value(
self,
) -> Handle<NodeRef<BorrowType, K, V, marker::LeafOrInternal>, marker::Value> {
unsafe { Handle::new_value(self.node) }
}
}
impl<'a, K, V> NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal> {
/// Unsafely asserts to the compiler the static information that this node is a `Leaf`.
pub(super) unsafe fn cast_to_leaf_unchecked(
@ -653,22 +803,89 @@ impl<'a, K: 'a, V: 'a, Type> Handle<NodeRef<marker::Mut<'a>, K, V, Type>, marker
/// Inserts a key-value pair into
pub(super) unsafe fn insert_recursing<Q>(
mut self,
mut key: Q,
mut key_seq: Q,
val: V,
) -> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::Value>
) -> Handle<NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal>, marker::Value>
where
Q: Iterator<Item = K>,
K: Ord,
{
let Some(key) = key_seq.next() else {
// key has run out: insert value here.
self.node.as_leaf_mut().value = Some(val);
// TODO: handle occupied values.
return unsafe { Handle::new_value(self.node.as_leaf_or_internal()) };
};
let idx = self.idx;
match unsafe { self.force() } {
let mut internal = match self.force() {
ForceResult::Leaf(leaf) => {
// need to turn the leaf into an internal node.
}
ForceResult::Internal(internal) => todo!(),
}
todo!()
// SAFETY: root is allocated as an internal node.
// the only node that doesn't have a parent is the root node,
// all parent nodes are internal nodes.
let internal = unsafe { leaf.make_internal_node() };
internal
}
ForceResult::Internal(mut internal) => {
if idx >= CAPACITY {
// create a sibling node
let mut sibling = NodeRef::new_internal();
let mut sibling = sibling.borrow_mut();
// let sibling = Box::into_non_null(InternalNode::new());
// set parent link
unsafe {
core::ptr::copy_nonoverlapping(
&raw mut internal.node.as_leaf_mut().parent,
&raw mut sibling.as_leaf_mut().parent,
1,
);
core::ptr::copy_nonoverlapping(
&raw mut internal.node.as_leaf_mut().parent_idx,
&raw mut sibling.as_leaf_mut().parent_idx,
1,
);
}
internal.node.as_internal_mut().next =
Some(NodeRef::as_internal_non_null(&sibling));
unsafe { Handle::new_edge(sibling.dormant(), 0).awaken() }
} else {
internal
}
}
};
let last = unsafe {
let mut child = NodeRef::new_leaf();
// set parent link
child.borrow_mut().as_leaf_mut().parent =
Some(NodeRef::as_internal_non_null(&internal.node));
child
.borrow_mut()
.as_leaf_mut()
.parent_idx
.write(internal.idx as u16);
let new_len = internal.node.len() + 1;
slice_insert(internal.node.key_area_mut(..new_len), internal.idx, key);
slice_insert(
internal.node.edge_area_mut(..new_len),
internal.idx,
child.node,
);
*internal.node.len_mut() = new_len as u16;
let child = Handle::new_edge(child.borrow_mut(), 0);
child.insert_recursing(key_seq, val).dormant()
};
unsafe { last.awaken() }
}
}
@ -697,7 +914,7 @@ mod search {
}
impl<BorrowType: marker::BorrowType, K, V> NodeRef<BorrowType, K, V, marker::LeafOrInternal> {
fn search_tree<Q>(
pub(super) fn search_tree<Q>(
mut self,
mut key: Q,
) -> SearchResult<BorrowType, K, V, marker::LeafOrInternal, marker::Leaf>
@ -774,24 +991,51 @@ mod search {
{
match key.cmp(k.borrow()) {
Ordering::Greater => {}
Ordering::Equal => return IndexResult::Edge(start_index + offset),
Ordering::Less => return IndexResult::Insert(start_index + offset),
Ordering::Equal => {
std::eprintln!("found key at index {}", start_index + offset);
return IndexResult::Edge(start_index + offset);
}
Ordering::Less => {
std::eprintln!("insert key at index {}", start_index + offset);
return IndexResult::Insert(start_index + offset);
}
}
}
std::eprintln!("insert key at index {}", keys.len());
IndexResult::Insert(keys.len())
}
}
#[cfg(test)]
mod tests {
use super::super::Tree;
use super::*;
fn build_test_node() {
let mut root = NodeRef::<marker::Owned, char, u32, _>::new_leaf();
#[test]
fn asdf() {
let mut tree = Tree::new();
let entry = tree.entry("+".chars());
std::dbg!(&entry);
entry.or_insert("Plus");
let root_mut = root.borrow_mut();
// root_mut.as_leaf_mut().
let entry = tree.entry("++".chars());
std::dbg!(&entry);
entry.or_insert("PlusPlus");
let entry = tree.entry("+=".chars());
std::dbg!(&entry);
entry.or_insert("PlusEqual");
std::dbg!(tree.entry("++".chars()));
std::eprintln!("tree: {:?}", &tree);
assert_eq!(
tree.entry("++".chars()).or_insert("asdf").get(),
&"PlusPlus"
);
assert_eq!(tree.entry("+".chars()).or_insert("asdf").get(), &"Plus");
}
}
}
@ -809,6 +1053,41 @@ mod entry {
Occupied(OccupiedEntry<'a, K, V>),
}
use core::fmt::Debug;
impl<Q: Debug, K: Debug, V: Debug> Debug for Entry<'_, Q, K, V>
where
Q: Iterator<Item = K>,
{
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
Entry::Vacant(vacant) => write!(f, "Vacant({:?})", vacant),
Entry::Occupied(occupied) => write!(f, "Occupied({:?})", occupied),
}
}
}
impl<Q: Debug, K: Debug, V: Debug> Debug for VacantEntry<'_, Q, K, V>
where
Q: Iterator<Item = K>,
{
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("VacantEntry")
.field("key", &self.key)
.field("handle", &self.handle)
.finish()
}
}
impl<K: Debug, V: Debug> Debug for OccupiedEntry<'_, K, V> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("OccupiedEntry")
.field("value", &self.get())
.field("handle", &self.handle)
.finish()
}
}
pub struct VacantEntry<'a, Q, K, V>
where
Q: Iterator<Item = K>,
@ -827,9 +1106,21 @@ mod entry {
pub(super) _marker: PhantomData<&'a mut (K, V)>,
}
impl<'a, K: Ord, V> OccupiedEntry<'a, K, V> {
pub fn key(&self) -> Option<&K> {
unsafe { self.handle.reborrow().into_kv().0 }
impl<'a, K, V> OccupiedEntry<'a, K, V> {
pub fn get(&self) -> &V {
unsafe { self.handle.reborrow().into_value() }
}
}
impl<'a, Q, K: Ord, V> Entry<'a, Q, K, V>
where
Q: Iterator<Item = K>,
{
pub fn or_insert(self, value: V) -> OccupiedEntry<'a, K, V> {
match self {
Entry::Vacant(vacant) => vacant.insert_entry(value),
Entry::Occupied(occupied) => occupied,
}
}
}
@ -837,16 +1128,25 @@ mod entry {
where
Q: Iterator<Item = K>,
{
pub fn insert(self, value: V) -> OccupiedEntry<'a, K, V> {
pub fn insert_entry(mut self, value: V) -> OccupiedEntry<'a, K, V> {
let handle = match self.handle {
// no root node yet
None => {
unimplemented!()
let tree = unsafe { self.dormant_map.reborrow() };
let root = tree.root.insert(NodeRef::new_internal());
unsafe {
Handle::new_edge(root.borrow_mut(), 0).insert_recursing(self.key, value)
}
}
Some(handle) => {}
Some(handle) => unsafe { handle.insert_recursing(self.key, value) },
};
todo!()
OccupiedEntry {
handle,
dormant_map: self.dormant_map,
_marker: PhantomData,
}
}
}
}
@ -925,13 +1225,71 @@ mod borrow {
}
}
type Root<K, V> = NodeRef<marker::Owned, K, V, marker::LeafOrInternal>;
type Root<K, V> = NodeRef<marker::Owned, K, V, marker::Internal>;
struct Tree<K, V> {
root: Option<Root<K, V>>,
_marker: PhantomData<alloc::boxed::Box<(K, V)>>,
}
impl<'a, K: core::fmt::Debug + 'a, V: core::fmt::Debug + 'a> core::fmt::Debug for &'a Tree<K, V> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let mut map = f.debug_map();
fn format_node_ref<'a, K: 'a, V: 'a>(
f: &mut core::fmt::Formatter<'_>,
node: &NodeRef<marker::Immut<'a>, K, V, marker::LeafOrInternal>,
) -> core::fmt::Result
where
K: core::fmt::Debug,
V: core::fmt::Debug,
{
match node.force() {
ForceResult::Leaf(leaf) => f
.debug_struct("Leaf")
.field("value", &leaf.into_leaf().value)
.finish(),
ForceResult::Internal(internal) => f
.debug_struct("Internal")
.field("value", &internal.into_leaf().value)
.field_with("edges", |f| {
let mut list = f.debug_list();
for (key, edge) in internal.keys().iter().zip(internal.edges()) {
list.entry_with(|f| {
f.debug_set()
.entry(key)
.entry_with(|f| {
format_node_ref(
f,
&NodeRef {
node: *edge,
_marker: PhantomData,
},
)
})
.finish()
});
}
list.finish()
})
.finish(),
}
}
match self.root {
Some(ref root) => {
map.key(&"root").value_with(|f| {
let internal = root.reborrow();
format_node_ref(f, &internal.as_leaf_or_internal())
});
map.finish()
}
None => map.finish(),
}
}
}
impl<K, V> Tree<K, V> {
pub fn new() -> Self {
Self {
@ -941,6 +1299,141 @@ impl<K, V> Tree<K, V> {
}
}
#[derive(Debug)]
pub struct OnceAndIter<I, T>
where
I: Iterator<Item = T>,
{
once: Option<T>,
iter: I,
}
impl<I, T> Iterator for OnceAndIter<I, T>
where
I: Iterator<Item = T>,
{
type Item = T;
fn next(&mut self) -> Option<T> {
if let Some(once) = self.once.take() {
Some(once)
} else {
self.iter.next()
}
}
}
impl<I> From<I> for OnceAndIter<I, I::Item>
where
I: Iterator,
{
fn from(iter: I) -> Self {
Self { once: None, iter }
}
}
impl<I, T> OnceAndIter<I, T>
where
I: Iterator<Item = T>,
{
pub fn once(once: T, iter: I) -> Self {
Self {
once: Some(once),
iter,
}
}
}
impl<K, V> Tree<K, V>
where
K: Ord,
{
// pub fn closest_entry<Q>(
// &mut self,
// mut key_seq: Q,
// ) -> Option<entry::Entry<OnceAndIter<Q, K>, K, V>>
// where
// Q: Iterator<Item = K>,
// {
// use borrow::DormantMutRef;
// use entry::Entry;
// let (tree, dormant) = DormantMutRef::new(self);
// match tree.root {
// None => None,
// Some(ref mut root) => match root.borrow_mut().forget_type().search_tree(&mut key_seq) {
// search::SearchResult::Found(handle) => {
// Some(Entry::Occupied(entry::OccupiedEntry {
// handle,
// dormant_map: dormant,
// _marker: PhantomData,
// }))
// }
// search::SearchResult::GoDown(handle) => match key_seq.next() {
// None => Some(Entry::Occupied(entry::OccupiedEntry {
// handle: handle.forget_node_type().into_value(),
// dormant_map: dormant,
// _marker: PhantomData,
// })),
// Some(key) => Some(Entry::Vacant(entry::VacantEntry {
// key: OnceAndIter::once(key, key_seq),
// handle: Some(handle.forget_node_type()),
// dormant_map: dormant,
// _marker: PhantomData,
// })),
// },
// search::SearchResult::Insert(key, handle) => {
// Some(Entry::Vacant(entry::VacantEntry {
// key: OnceAndIter::once(key, key_seq),
// handle: Some(handle),
// dormant_map: dormant,
// _marker: PhantomData,
// }))
// }
// },
// }
// }
pub fn entry<Q>(&'_ mut self, mut key_seq: Q) -> entry::Entry<'_, OnceAndIter<Q, K>, K, V>
where
Q: Iterator<Item = K>,
{
use borrow::DormantMutRef;
use entry::{Entry::*, OccupiedEntry, VacantEntry};
let (tree, dormant) = DormantMutRef::new(self);
match tree.root {
None => Vacant(VacantEntry {
key: key_seq.into(),
handle: None,
dormant_map: dormant,
_marker: PhantomData,
}),
Some(ref mut root) => match root.borrow_mut().forget_type().search_tree(&mut key_seq) {
search::SearchResult::Found(handle) => Occupied(OccupiedEntry {
handle,
dormant_map: dormant,
_marker: PhantomData,
}),
search::SearchResult::GoDown(handle) => Vacant(VacantEntry {
key: key_seq.into(),
handle: Some(handle.forget_node_type()),
dormant_map: dormant,
_marker: PhantomData,
}),
search::SearchResult::Insert(key, handle) => Vacant(VacantEntry {
key: OnceAndIter::once(key, key_seq),
handle: Some(handle),
dormant_map: dormant,
_marker: PhantomData,
}),
},
}
}
}
unsafe fn slice_insert<T>(slice: &mut [MaybeUninit<T>], idx: usize, value: T) {
unsafe {
let len = slice.len();