Rollup merge of #82726 - ssomers:btree_node_rearange, r=Mark-Simulacrum
BTree: move blocks around in node.rs Without changing any names or implementation, reorder some members: - Move down the ones defined long ago on the demised `struct Root`, to below the definition of their current host `struct NodeRef`. - Move up some defined on `struct NodeRef` that are interspersed with those defined on `struct Handle`. - Move up the `correct_…` methods squeezed between the two flavours of `push`. - Move the unchecked static downcasts (`cast_to_…`) after the upcasts (`forget_`) and the (weirdly named) dynamic downcasts (`force`). r? ````@Mark-Simulacrum````
This commit is contained in:
commit
6c13556183
@ -128,106 +128,6 @@ impl<K, V> InternalNode<K, V> {
|
||||
/// is not a separate type and has no destructor.
|
||||
type BoxedNode<K, V> = NonNull<LeafNode<K, V>>;
|
||||
|
||||
/// The root node of an owned tree.
|
||||
///
|
||||
/// Note that this does not have a destructor, and must be cleaned up manually.
|
||||
pub type Root<K, V> = NodeRef<marker::Owned, K, V, marker::LeafOrInternal>;
|
||||
|
||||
impl<K, V> Root<K, V> {
|
||||
/// Returns a new owned tree, with its own root node that is initially empty.
|
||||
pub fn new() -> Self {
|
||||
NodeRef::new_leaf().forget_type()
|
||||
}
|
||||
}
|
||||
|
||||
impl<K, V> NodeRef<marker::Owned, K, V, marker::Leaf> {
|
||||
fn new_leaf() -> Self {
|
||||
Self::from_new_leaf(LeafNode::new())
|
||||
}
|
||||
|
||||
fn from_new_leaf(leaf: Box<LeafNode<K, V>>) -> Self {
|
||||
NodeRef { height: 0, node: NonNull::from(Box::leak(leaf)), _marker: PhantomData }
|
||||
}
|
||||
}
|
||||
|
||||
impl<K, V> NodeRef<marker::Owned, K, V, marker::Internal> {
|
||||
fn new_internal(child: Root<K, V>) -> Self {
|
||||
let mut new_node = unsafe { InternalNode::new() };
|
||||
new_node.edges[0].write(child.node);
|
||||
unsafe { NodeRef::from_new_internal(new_node, child.height + 1) }
|
||||
}
|
||||
|
||||
/// # Safety
|
||||
/// `height` must not be zero.
|
||||
unsafe fn from_new_internal(internal: Box<InternalNode<K, V>>, height: usize) -> Self {
|
||||
debug_assert!(height > 0);
|
||||
let node = NonNull::from(Box::leak(internal)).cast();
|
||||
let mut this = NodeRef { height, node, _marker: PhantomData };
|
||||
this.borrow_mut().correct_all_childrens_parent_links();
|
||||
this
|
||||
}
|
||||
}
|
||||
|
||||
impl<K, V, Type> NodeRef<marker::Owned, K, V, Type> {
|
||||
/// Mutably borrows the owned root node. Unlike `reborrow_mut`, this is safe
|
||||
/// because the return value cannot be used to destroy the root, and there
|
||||
/// cannot be other references to the tree.
|
||||
pub fn borrow_mut(&mut self) -> NodeRef<marker::Mut<'_>, K, V, Type> {
|
||||
NodeRef { height: self.height, node: self.node, _marker: PhantomData }
|
||||
}
|
||||
|
||||
/// Slightly mutably borrows the owned root node.
|
||||
pub fn borrow_valmut(&mut self) -> NodeRef<marker::ValMut<'_>, K, V, Type> {
|
||||
NodeRef { height: self.height, node: self.node, _marker: PhantomData }
|
||||
}
|
||||
|
||||
/// Irreversibly transitions to a reference that permits traversal and offers
|
||||
/// destructive methods and little else.
|
||||
pub fn into_dying(self) -> NodeRef<marker::Dying, K, V, Type> {
|
||||
NodeRef { height: self.height, node: self.node, _marker: PhantomData }
|
||||
}
|
||||
}
|
||||
|
||||
impl<K, V> NodeRef<marker::Owned, K, V, marker::LeafOrInternal> {
|
||||
/// Adds a new internal node with a single edge pointing to the previous root node,
|
||||
/// make that new node the root node, and return it. This increases the height by 1
|
||||
/// and is the opposite of `pop_internal_level`.
|
||||
pub fn push_internal_level(&mut self) -> NodeRef<marker::Mut<'_>, K, V, marker::Internal> {
|
||||
super::mem::take_mut(self, |old_root| NodeRef::new_internal(old_root).forget_type());
|
||||
|
||||
// `self.borrow_mut()`, except that we just forgot we're internal now:
|
||||
NodeRef { height: self.height, node: self.node, _marker: PhantomData }
|
||||
}
|
||||
|
||||
/// Removes the internal root node, using its first child as the new root node.
|
||||
/// As it is intended only to be called when the root node has only one child,
|
||||
/// no cleanup is done on any of the keys, values and other children.
|
||||
/// This decreases the height by 1 and is the opposite of `push_internal_level`.
|
||||
///
|
||||
/// Requires exclusive access to the `Root` object but not to the root node;
|
||||
/// it will not invalidate other handles or references to the root node.
|
||||
///
|
||||
/// Panics if there is no internal level, i.e., if the root node is a leaf.
|
||||
pub fn pop_internal_level(&mut self) {
|
||||
assert!(self.height > 0);
|
||||
|
||||
let top = self.node;
|
||||
|
||||
// SAFETY: we asserted to be internal.
|
||||
let internal_self = unsafe { self.borrow_mut().cast_to_internal_unchecked() };
|
||||
// SAFETY: we borrowed `self` exclusively and its borrow type is exclusive.
|
||||
let internal_node = unsafe { &mut *NodeRef::as_internal_ptr(&internal_self) };
|
||||
// SAFETY: the first edge is always initialized.
|
||||
self.node = unsafe { internal_node.edges[0].assume_init_read() };
|
||||
self.height -= 1;
|
||||
self.clear_parent_link();
|
||||
|
||||
unsafe {
|
||||
Global.deallocate(top.cast(), Layout::new::<InternalNode<K, V>>());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// N.B. `NodeRef` is always covariant in `K` and `V`, even when the `BorrowType`
|
||||
// is `Mut`. This is technically wrong, but cannot result in any unsafety due to
|
||||
// internal use of `NodeRef` because we stay completely generic over `K` and `V`.
|
||||
@ -292,6 +192,11 @@ pub struct NodeRef<BorrowType, K, V, Type> {
|
||||
_marker: PhantomData<(BorrowType, Type)>,
|
||||
}
|
||||
|
||||
/// The root node of an owned tree.
|
||||
///
|
||||
/// Note that this does not have a destructor, and must be cleaned up manually.
|
||||
pub type Root<K, V> = NodeRef<marker::Owned, K, V, marker::LeafOrInternal>;
|
||||
|
||||
impl<'a, K: 'a, V: 'a, Type> Copy for NodeRef<marker::Immut<'a>, K, V, Type> {}
|
||||
impl<'a, K: 'a, V: 'a, Type> Clone for NodeRef<marker::Immut<'a>, K, V, Type> {
|
||||
fn clone(&self) -> Self {
|
||||
@ -307,6 +212,34 @@ unsafe impl<'a, K: Send + 'a, V: Send + 'a, Type> Send for NodeRef<marker::ValMu
|
||||
unsafe impl<K: Send, V: Send, Type> Send for NodeRef<marker::Owned, K, V, Type> {}
|
||||
unsafe impl<K: Send, V: Send, Type> Send for NodeRef<marker::Dying, K, V, Type> {}
|
||||
|
||||
impl<K, V> NodeRef<marker::Owned, K, V, marker::Leaf> {
|
||||
fn new_leaf() -> Self {
|
||||
Self::from_new_leaf(LeafNode::new())
|
||||
}
|
||||
|
||||
fn from_new_leaf(leaf: Box<LeafNode<K, V>>) -> Self {
|
||||
NodeRef { height: 0, node: NonNull::from(Box::leak(leaf)), _marker: PhantomData }
|
||||
}
|
||||
}
|
||||
|
||||
impl<K, V> NodeRef<marker::Owned, K, V, marker::Internal> {
|
||||
fn new_internal(child: Root<K, V>) -> Self {
|
||||
let mut new_node = unsafe { InternalNode::new() };
|
||||
new_node.edges[0].write(child.node);
|
||||
unsafe { NodeRef::from_new_internal(new_node, child.height + 1) }
|
||||
}
|
||||
|
||||
/// # Safety
|
||||
/// `height` must not be zero.
|
||||
unsafe fn from_new_internal(internal: Box<InternalNode<K, V>>, height: usize) -> Self {
|
||||
debug_assert!(height > 0);
|
||||
let node = NonNull::from(Box::leak(internal)).cast();
|
||||
let mut this = NodeRef { height, node, _marker: PhantomData };
|
||||
this.borrow_mut().correct_all_childrens_parent_links();
|
||||
this
|
||||
}
|
||||
}
|
||||
|
||||
impl<BorrowType, K, V> NodeRef<BorrowType, K, V, marker::Internal> {
|
||||
/// Unpack a node reference that was packed as `NodeRef::parent`.
|
||||
fn from_internal(node: NonNull<InternalNode<K, V>>, height: usize) -> Self {
|
||||
@ -420,6 +353,19 @@ impl<BorrowType: marker::BorrowType, K, V, Type> NodeRef<BorrowType, K, V, Type>
|
||||
}
|
||||
}
|
||||
|
||||
impl<BorrowType, K, V, Type> NodeRef<BorrowType, K, V, Type> {
|
||||
/// Could be a public implementation of PartialEq, but only used in this module.
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
let Self { node, height, _marker } = self;
|
||||
if node.eq(&other.node) {
|
||||
debug_assert_eq!(*height, other.height);
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::Immut<'a>, K, V, Type> {
|
||||
/// Exposes the leaf portion of any leaf or internal node in an immutable tree.
|
||||
fn into_leaf(self) -> &'a LeafNode<K, V> {
|
||||
@ -461,20 +407,6 @@ impl<K, V> NodeRef<marker::Dying, 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`.
|
||||
unsafe fn cast_to_leaf_unchecked(self) -> NodeRef<marker::Mut<'a>, K, V, marker::Leaf> {
|
||||
debug_assert!(self.height == 0);
|
||||
NodeRef { height: self.height, node: self.node, _marker: PhantomData }
|
||||
}
|
||||
|
||||
/// Unsafely asserts to the compiler the static information that this node is an `Internal`.
|
||||
unsafe fn cast_to_internal_unchecked(self) -> NodeRef<marker::Mut<'a>, K, V, marker::Internal> {
|
||||
debug_assert!(self.height > 0);
|
||||
NodeRef { height: self.height, node: self.node, _marker: PhantomData }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, K, V, Type> NodeRef<marker::Mut<'a>, K, V, Type> {
|
||||
/// Temporarily takes out another, mutable reference to the same node. Beware, as
|
||||
/// this method is very dangerous, doubly so since it may not immediately appear
|
||||
@ -577,6 +509,22 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::Mut<'a>, K, V, Type> {
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
let len = self.len();
|
||||
unsafe { self.correct_childrens_parent_links(0..=len) };
|
||||
}
|
||||
}
|
||||
|
||||
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.
|
||||
@ -596,6 +544,71 @@ impl<K, V> NodeRef<marker::Owned, K, V, marker::LeafOrInternal> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<K, V> NodeRef<marker::Owned, K, V, marker::LeafOrInternal> {
|
||||
/// Returns a new owned tree, with its own root node that is initially empty.
|
||||
pub fn new() -> Self {
|
||||
NodeRef::new_leaf().forget_type()
|
||||
}
|
||||
|
||||
/// Adds a new internal node with a single edge pointing to the previous root node,
|
||||
/// make that new node the root node, and return it. This increases the height by 1
|
||||
/// and is the opposite of `pop_internal_level`.
|
||||
pub fn push_internal_level(&mut self) -> NodeRef<marker::Mut<'_>, K, V, marker::Internal> {
|
||||
super::mem::take_mut(self, |old_root| NodeRef::new_internal(old_root).forget_type());
|
||||
|
||||
// `self.borrow_mut()`, except that we just forgot we're internal now:
|
||||
NodeRef { height: self.height, node: self.node, _marker: PhantomData }
|
||||
}
|
||||
|
||||
/// Removes the internal root node, using its first child as the new root node.
|
||||
/// As it is intended only to be called when the root node has only one child,
|
||||
/// no cleanup is done on any of the keys, values and other children.
|
||||
/// This decreases the height by 1 and is the opposite of `push_internal_level`.
|
||||
///
|
||||
/// Requires exclusive access to the `Root` object but not to the root node;
|
||||
/// it will not invalidate other handles or references to the root node.
|
||||
///
|
||||
/// Panics if there is no internal level, i.e., if the root node is a leaf.
|
||||
pub fn pop_internal_level(&mut self) {
|
||||
assert!(self.height > 0);
|
||||
|
||||
let top = self.node;
|
||||
|
||||
// SAFETY: we asserted to be internal.
|
||||
let internal_self = unsafe { self.borrow_mut().cast_to_internal_unchecked() };
|
||||
// SAFETY: we borrowed `self` exclusively and its borrow type is exclusive.
|
||||
let internal_node = unsafe { &mut *NodeRef::as_internal_ptr(&internal_self) };
|
||||
// SAFETY: the first edge is always initialized.
|
||||
self.node = unsafe { internal_node.edges[0].assume_init_read() };
|
||||
self.height -= 1;
|
||||
self.clear_parent_link();
|
||||
|
||||
unsafe {
|
||||
Global.deallocate(top.cast(), Layout::new::<InternalNode<K, V>>());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<K, V, Type> NodeRef<marker::Owned, K, V, Type> {
|
||||
/// Mutably borrows the owned root node. Unlike `reborrow_mut`, this is safe
|
||||
/// because the return value cannot be used to destroy the root, and there
|
||||
/// cannot be other references to the tree.
|
||||
pub fn borrow_mut(&mut self) -> NodeRef<marker::Mut<'_>, K, V, Type> {
|
||||
NodeRef { height: self.height, node: self.node, _marker: PhantomData }
|
||||
}
|
||||
|
||||
/// Slightly mutably borrows the owned root node.
|
||||
pub fn borrow_valmut(&mut self) -> NodeRef<marker::ValMut<'_>, K, V, Type> {
|
||||
NodeRef { height: self.height, node: self.node, _marker: PhantomData }
|
||||
}
|
||||
|
||||
/// Irreversibly transitions to a reference that permits traversal and offers
|
||||
/// destructive methods and little else.
|
||||
pub fn into_dying(self) -> NodeRef<marker::Dying, K, V, Type> {
|
||||
NodeRef { height: self.height, node: self.node, _marker: PhantomData }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::Leaf> {
|
||||
/// Adds a key-value pair to the end of the node.
|
||||
pub fn push(&mut self, key: K, val: V) {
|
||||
@ -610,22 +623,6 @@ impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::Leaf> {
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
let len = self.len();
|
||||
unsafe { self.correct_childrens_parent_links(0..=len) };
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::Internal> {
|
||||
/// Adds a key-value pair, and an edge to go to the right of that pair,
|
||||
/// to the end of the node.
|
||||
@ -645,6 +642,20 @@ impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::Internal> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<BorrowType, K, V> NodeRef<BorrowType, K, V, marker::Leaf> {
|
||||
/// Removes any static information asserting that this node is a `Leaf` node.
|
||||
pub fn forget_type(self) -> NodeRef<BorrowType, K, V, marker::LeafOrInternal> {
|
||||
NodeRef { height: self.height, node: self.node, _marker: PhantomData }
|
||||
}
|
||||
}
|
||||
|
||||
impl<BorrowType, K, V> NodeRef<BorrowType, K, V, marker::Internal> {
|
||||
/// Removes any static information asserting that this node is an `Internal` node.
|
||||
pub fn forget_type(self) -> NodeRef<BorrowType, K, V, marker::LeafOrInternal> {
|
||||
NodeRef { height: self.height, node: self.node, _marker: PhantomData }
|
||||
}
|
||||
}
|
||||
|
||||
impl<BorrowType, K, V> NodeRef<BorrowType, K, V, marker::LeafOrInternal> {
|
||||
/// Checks whether a node is an `Internal` node or a `Leaf` node.
|
||||
pub fn force(
|
||||
@ -669,6 +680,20 @@ impl<BorrowType, K, V> NodeRef<BorrowType, 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`.
|
||||
unsafe fn cast_to_leaf_unchecked(self) -> NodeRef<marker::Mut<'a>, K, V, marker::Leaf> {
|
||||
debug_assert!(self.height == 0);
|
||||
NodeRef { height: self.height, node: self.node, _marker: PhantomData }
|
||||
}
|
||||
|
||||
/// Unsafely asserts to the compiler the static information that this node is an `Internal`.
|
||||
unsafe fn cast_to_internal_unchecked(self) -> NodeRef<marker::Mut<'a>, K, V, marker::Internal> {
|
||||
debug_assert!(self.height > 0);
|
||||
NodeRef { height: self.height, node: self.node, _marker: PhantomData }
|
||||
}
|
||||
}
|
||||
|
||||
/// A reference to a specific key-value pair or edge within a node. The `Node` parameter
|
||||
/// must be a `NodeRef`, while the `Type` can either be `KV` (signifying a handle on a key-value
|
||||
/// pair) or `Edge` (signifying a handle on an edge).
|
||||
@ -722,19 +747,6 @@ impl<BorrowType, K, V, NodeType> Handle<NodeRef<BorrowType, K, V, NodeType>, mar
|
||||
}
|
||||
}
|
||||
|
||||
impl<BorrowType, K, V, NodeType> NodeRef<BorrowType, K, V, NodeType> {
|
||||
/// Could be a public implementation of PartialEq, but only used in this module.
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
let Self { node, height, _marker } = self;
|
||||
if node.eq(&other.node) {
|
||||
debug_assert_eq!(*height, other.height);
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<BorrowType, K, V, NodeType, HandleType> PartialEq
|
||||
for Handle<NodeRef<BorrowType, K, V, NodeType>, HandleType>
|
||||
{
|
||||
@ -754,16 +766,6 @@ impl<BorrowType, K, V, NodeType, HandleType>
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, K, V, Type> Handle<NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal>, Type> {
|
||||
/// Unsafely asserts to the compiler the static information that the handle's node is a `Leaf`.
|
||||
pub unsafe fn cast_to_leaf_unchecked(
|
||||
self,
|
||||
) -> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, Type> {
|
||||
let node = unsafe { self.node.cast_to_leaf_unchecked() };
|
||||
Handle { node, idx: self.idx, _marker: PhantomData }
|
||||
}
|
||||
}
|
||||
|
||||
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 may not immediately appear
|
||||
@ -1466,20 +1468,6 @@ impl<'a, K: 'a, V: 'a> BalancingContext<'a, K, V> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<BorrowType, K, V> NodeRef<BorrowType, K, V, marker::Leaf> {
|
||||
/// Removes any static information asserting that this node is a `Leaf` node.
|
||||
pub fn forget_type(self) -> NodeRef<BorrowType, K, V, marker::LeafOrInternal> {
|
||||
NodeRef { height: self.height, node: self.node, _marker: PhantomData }
|
||||
}
|
||||
}
|
||||
|
||||
impl<BorrowType, K, V> NodeRef<BorrowType, K, V, marker::Internal> {
|
||||
/// Removes any static information asserting that this node is an `Internal` node.
|
||||
pub fn forget_type(self) -> NodeRef<BorrowType, K, V, marker::LeafOrInternal> {
|
||||
NodeRef { height: self.height, node: self.node, _marker: PhantomData }
|
||||
}
|
||||
}
|
||||
|
||||
impl<BorrowType, K, V> Handle<NodeRef<BorrowType, K, V, marker::Leaf>, marker::Edge> {
|
||||
pub fn forget_node_type(
|
||||
self,
|
||||
@ -1531,6 +1519,16 @@ impl<BorrowType, K, V, Type> Handle<NodeRef<BorrowType, K, V, marker::LeafOrInte
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, K, V, Type> Handle<NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal>, Type> {
|
||||
/// Unsafely asserts to the compiler the static information that the handle's node is a `Leaf`.
|
||||
pub unsafe fn cast_to_leaf_unchecked(
|
||||
self,
|
||||
) -> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, Type> {
|
||||
let node = unsafe { self.node.cast_to_leaf_unchecked() };
|
||||
Handle { node, idx: self.idx, _marker: PhantomData }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal>, marker::Edge> {
|
||||
/// Move the suffix after `self` from one node to another one. `right` must be empty.
|
||||
/// The first edge of `right` remains unchanged.
|
||||
|
Loading…
x
Reference in New Issue
Block a user