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(
|
||||
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))]
|
||||
|
||||
|
|
|
|||
625
src/tree.rs
625
src/tree.rs
|
|
@ -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();
|
||||
|
|
|
|||
Loading…
Reference in a new issue