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:
parent
b6c16f2739
commit
e07e69a0c4
|
|
@ -1,7 +1,12 @@
|
||||||
#![cfg_attr(not(feature = "std"), no_std)]
|
#![cfg_attr(not(feature = "std"), no_std)]
|
||||||
#![cfg_attr(
|
#![cfg_attr(
|
||||||
feature = "nightly",
|
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))]
|
#![cfg_attr(feature = "transposed-option", feature(try_trait_v2))]
|
||||||
|
|
||||||
|
|
|
||||||
625
src/tree.rs
625
src/tree.rs
|
|
@ -24,18 +24,29 @@ use core::{
|
||||||
mod marker {
|
mod marker {
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct LeafOrInternal;
|
pub struct LeafOrInternal;
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct Leaf;
|
pub struct Leaf;
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct Internal;
|
pub struct Internal;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct Edge;
|
pub struct Edge;
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct Value;
|
pub struct Value;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct Owned;
|
pub struct Owned;
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct Mut<'a>(PhantomData<&'a mut ()>);
|
pub struct Mut<'a>(PhantomData<&'a mut ()>);
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct ValMut<'a>(PhantomData<&'a mut ()>);
|
pub struct ValMut<'a>(PhantomData<&'a mut ()>);
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct Immut<'a>(PhantomData<&'a ()>);
|
pub struct Immut<'a>(PhantomData<&'a ()>);
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct Dying;
|
pub struct Dying;
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct DormantMut;
|
pub struct DormantMut;
|
||||||
|
|
||||||
pub trait BorrowType {
|
pub trait BorrowType {
|
||||||
|
|
@ -55,13 +66,15 @@ mod marker {
|
||||||
|
|
||||||
const CAPACITY: usize = 16;
|
const CAPACITY: usize = 16;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
struct LeafNode<K, V> {
|
struct LeafNode<K, V> {
|
||||||
parent: Option<NonNull<InternalNode<K, V>>>,
|
parent: Option<NonNull<InternalNode<K, V>>>,
|
||||||
parent_idx: MaybeUninit<u16>,
|
parent_idx: MaybeUninit<u16>,
|
||||||
value: Option<MaybeUninit<V>>,
|
value: Option<V>,
|
||||||
leaf: bool,
|
leaf: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
struct InternalNode<K, V> {
|
struct InternalNode<K, V> {
|
||||||
data: LeafNode<K, V>,
|
data: LeafNode<K, V>,
|
||||||
next: Option<NonNull<InternalNode<K, V>>>,
|
next: Option<NonNull<InternalNode<K, V>>>,
|
||||||
|
|
@ -72,11 +85,13 @@ struct InternalNode<K, V> {
|
||||||
|
|
||||||
type BoxedNode<K, V> = NonNull<LeafNode<K, V>>;
|
type BoxedNode<K, V> = NonNull<LeafNode<K, V>>;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
struct NodeRef<BorrowType, K, V, Type> {
|
struct NodeRef<BorrowType, K, V, Type> {
|
||||||
node: NonNull<LeafNode<K, V>>,
|
node: NonNull<LeafNode<K, V>>,
|
||||||
_marker: PhantomData<(BorrowType, Type)>,
|
_marker: PhantomData<(BorrowType, Type)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
struct Handle<Node, Type> {
|
struct Handle<Node, Type> {
|
||||||
node: Node,
|
node: Node,
|
||||||
idx: usize,
|
idx: usize,
|
||||||
|
|
@ -140,6 +155,7 @@ impl<K, V> InternalNode<K, V> {
|
||||||
unsafe fn init(this: *mut Self) {
|
unsafe fn init(this: *mut Self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
LeafNode::init(&raw mut (*this).data);
|
LeafNode::init(&raw mut (*this).data);
|
||||||
|
(&raw mut (*this).data.leaf).write(false);
|
||||||
(&raw mut (*this).next).write(None);
|
(&raw mut (*this).next).write(None);
|
||||||
(&raw mut (*this).len).write(0);
|
(&raw mut (*this).len).write(0);
|
||||||
// keys and edges may be left uninitialized
|
// 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) };
|
let mut uninit: Box<MaybeUninit<LeafNode<K, V>>> = unsafe { core::mem::transmute(leaf) };
|
||||||
unsafe {
|
unsafe {
|
||||||
core::ptr::swap(&raw mut (*this).data, uninit.as_mut_ptr());
|
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).next).write(None);
|
||||||
(&raw mut (*this).len).write(1);
|
(&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> {
|
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();
|
let mut node = InternalNode::new();
|
||||||
node.edges[0].write(child.node);
|
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) }
|
unsafe { NodeRef::from_new_internal(node) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -199,7 +220,6 @@ impl<K, V> NodeRef<marker::Owned, K, V, marker::Internal> {
|
||||||
node,
|
node,
|
||||||
_marker: PhantomData,
|
_marker: PhantomData,
|
||||||
};
|
};
|
||||||
this.borrow_mut().correct_all_childrens_parent_links();
|
|
||||||
this
|
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> {
|
impl<'a, K, V, NodeType, HandleType> Handle<NodeRef<marker::Mut<'a>, K, V, NodeType>, HandleType> {
|
||||||
/// Fixes the parent pointer and index in the child node that this edge
|
/// Temporarily takes out another mutable handle on the same location. Beware, as
|
||||||
/// links to. This is useful when the ordering of edges has been changed,
|
/// this method is very dangerous, doubly so since it might not immediately appear
|
||||||
fn correct_parent_link(self) {
|
/// dangerous.
|
||||||
// Create backpointer without invalidating other references to the node.
|
///
|
||||||
let ptr = unsafe { NonNull::new_unchecked(NodeRef::as_internal_ptr(&self.node)) };
|
/// For details, see `NodeRef::reborrow_mut`.
|
||||||
let idx = self.idx;
|
pub(super) unsafe fn reborrow_mut(
|
||||||
let mut child = self.descend();
|
&mut self,
|
||||||
child.set_parent_link(ptr, idx);
|
) -> 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() },
|
||||||
impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal> {
|
idx: self.idx,
|
||||||
/// Sets the node's link to its parent edge,
|
_marker: PhantomData,
|
||||||
/// 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();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn correct_all_childrens_parent_links(&mut self) {
|
/// Returns a dormant copy of this handle which can be reawakened later.
|
||||||
let len = self.len();
|
///
|
||||||
unsafe { self.correct_childrens_parent_links(0..=len) };
|
/// 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`.
|
// SAFETY: the static node type is `Internal`.
|
||||||
this.node.as_ptr() as *mut InternalNode<K, V>
|
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> {
|
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);
|
let ptr = Self::as_internal_ptr(self);
|
||||||
unsafe { &mut *ptr }
|
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> {
|
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> {
|
impl<K, V, Type> NodeRef<marker::DormantMut, K, V, Type> {
|
||||||
/// Revert to the unique borrow initially captured.
|
/// 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> {
|
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> {
|
fn into_internal(self) -> &'a InternalNode<K, V> {
|
||||||
// SAFETY: the static node type is `Internal`.
|
// SAFETY: the static node type is `Internal`.
|
||||||
unsafe { &*Self::as_internal_ptr(&self) }
|
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()
|
.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>
|
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()`
|
/// SAFETY: the caller must ensure that `idx < node.len()`
|
||||||
pub(super) unsafe fn into_value(self) -> &'a V {
|
pub(super) unsafe fn into_value(self) -> &'a V {
|
||||||
let leaf = self.node.into_leaf();
|
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
|
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> {
|
pub(super) enum ForceResult<Leaf, Internal> {
|
||||||
Leaf(Leaf),
|
Leaf(Leaf),
|
||||||
Internal(Internal),
|
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> {
|
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`.
|
/// Unsafely asserts to the compiler the static information that this node is a `Leaf`.
|
||||||
pub(super) unsafe fn cast_to_leaf_unchecked(
|
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
|
/// Inserts a key-value pair into
|
||||||
pub(super) unsafe fn insert_recursing<Q>(
|
pub(super) unsafe fn insert_recursing<Q>(
|
||||||
mut self,
|
mut self,
|
||||||
mut key: Q,
|
mut key_seq: Q,
|
||||||
val: V,
|
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
|
where
|
||||||
Q: Iterator<Item = K>,
|
Q: Iterator<Item = K>,
|
||||||
K: Ord,
|
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;
|
let idx = self.idx;
|
||||||
match unsafe { self.force() } {
|
let mut internal = match self.force() {
|
||||||
ForceResult::Leaf(leaf) => {
|
ForceResult::Leaf(leaf) => {
|
||||||
// need to turn the leaf into an internal node.
|
// 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> {
|
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 self,
|
||||||
mut key: Q,
|
mut key: Q,
|
||||||
) -> SearchResult<BorrowType, K, V, marker::LeafOrInternal, marker::Leaf>
|
) -> SearchResult<BorrowType, K, V, marker::LeafOrInternal, marker::Leaf>
|
||||||
|
|
@ -774,24 +991,51 @@ mod search {
|
||||||
{
|
{
|
||||||
match key.cmp(k.borrow()) {
|
match key.cmp(k.borrow()) {
|
||||||
Ordering::Greater => {}
|
Ordering::Greater => {}
|
||||||
Ordering::Equal => return IndexResult::Edge(start_index + offset),
|
Ordering::Equal => {
|
||||||
Ordering::Less => return IndexResult::Insert(start_index + offset),
|
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())
|
IndexResult::Insert(keys.len())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use super::super::Tree;
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
fn build_test_node() {
|
#[test]
|
||||||
let mut root = NodeRef::<marker::Owned, char, u32, _>::new_leaf();
|
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();
|
let entry = tree.entry("++".chars());
|
||||||
// root_mut.as_leaf_mut().
|
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>),
|
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>
|
pub struct VacantEntry<'a, Q, K, V>
|
||||||
where
|
where
|
||||||
Q: Iterator<Item = K>,
|
Q: Iterator<Item = K>,
|
||||||
|
|
@ -827,9 +1106,21 @@ mod entry {
|
||||||
pub(super) _marker: PhantomData<&'a mut (K, V)>,
|
pub(super) _marker: PhantomData<&'a mut (K, V)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, K: Ord, V> OccupiedEntry<'a, K, V> {
|
impl<'a, K, V> OccupiedEntry<'a, K, V> {
|
||||||
pub fn key(&self) -> Option<&K> {
|
pub fn get(&self) -> &V {
|
||||||
unsafe { self.handle.reborrow().into_kv().0 }
|
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
|
where
|
||||||
Q: Iterator<Item = K>,
|
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 {
|
let handle = match self.handle {
|
||||||
// no root node yet
|
// no root node yet
|
||||||
None => {
|
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> {
|
struct Tree<K, V> {
|
||||||
root: Option<Root<K, V>>,
|
root: Option<Root<K, V>>,
|
||||||
_marker: PhantomData<alloc::boxed::Box<(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> {
|
impl<K, V> Tree<K, V> {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
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 fn slice_insert<T>(slice: &mut [MaybeUninit<T>], idx: usize, value: T) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let len = slice.len();
|
let len = slice.len();
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue