auto merge of #19782 : gereeter/rust/cleanup-btree-node, r=Gankro
Before: ``` test btree::map::bench::find_rand_100 ... bench: 12 ns/iter (+/- 0) test btree::map::bench::find_rand_10_000 ... bench: 13 ns/iter (+/- 1) test btree::map::bench::find_seq_100 ... bench: 11 ns/iter (+/- 0) test btree::map::bench::find_seq_10_000 ... bench: 11 ns/iter (+/- 1) test btree::map::bench::insert_rand_100 ... bench: 106 ns/iter (+/- 1) test btree::map::bench::insert_rand_10_000 ... bench: 326 ns/iter (+/- 8) test btree::map::bench::insert_seq_100 ... bench: 198 ns/iter (+/- 1) test btree::map::bench::insert_seq_10_000 ... bench: 312 ns/iter (+/- 3) test btree::map::bench::iter_1000 ... bench: 16563 ns/iter (+/- 173) test btree::map::bench::iter_100000 ... bench: 1686508 ns/iter (+/- 108592) test btree::map::bench::iter_20 ... bench: 365 ns/iter (+/- 25) ``` After: ``` test btree::map::bench::find_rand_100 ... bench: 12 ns/iter (+/- 0) test btree::map::bench::find_rand_10_000 ... bench: 12 ns/iter (+/- 0) test btree::map::bench::find_seq_100 ... bench: 11 ns/iter (+/- 0) test btree::map::bench::find_seq_10_000 ... bench: 11 ns/iter (+/- 0) test btree::map::bench::insert_rand_100 ... bench: 89 ns/iter (+/- 1) test btree::map::bench::insert_rand_10_000 ... bench: 121 ns/iter (+/- 3) test btree::map::bench::insert_seq_100 ... bench: 149 ns/iter (+/- 0) test btree::map::bench::insert_seq_10_000 ... bench: 228 ns/iter (+/- 1) test btree::map::bench::iter_1000 ... bench: 16965 ns/iter (+/- 220) test btree::map::bench::iter_100000 ... bench: 1687836 ns/iter (+/- 18746) test btree::map::bench::iter_20 ... bench: 366 ns/iter (+/- 21) ```
This commit is contained in:
commit
59287b0170
@ -20,7 +20,10 @@ pub use self::Entry::*;
|
||||
use core::prelude::*;
|
||||
|
||||
use self::StackOp::*;
|
||||
use super::node::*;
|
||||
use super::node::{mod, Node, Found, GoDown};
|
||||
use super::node::{Traversal, MutTraversal, MoveTraversal};
|
||||
use super::node::TraversalItem::{mod, Elem, Edge};
|
||||
use super::node::ForceResult::{Leaf, Internal};
|
||||
use core::borrow::BorrowFrom;
|
||||
use std::hash::{Writer, Hash};
|
||||
use core::default::Default;
|
||||
@ -125,12 +128,12 @@ pub enum Entry<'a, K:'a, V:'a> {
|
||||
/// A vacant Entry.
|
||||
pub struct VacantEntry<'a, K:'a, V:'a> {
|
||||
key: K,
|
||||
stack: stack::VacantSearchStack<'a, K, V>,
|
||||
stack: stack::SearchStack<'a, K, V, node::Edge, node::Leaf>,
|
||||
}
|
||||
|
||||
/// An occupied Entry.
|
||||
pub struct OccupiedEntry<'a, K:'a, V:'a> {
|
||||
stack: stack::OccupiedSearchStack<'a, K, V>,
|
||||
stack: stack::SearchStack<'a, K, V, node::KV, node::LeafOrInternal>,
|
||||
}
|
||||
|
||||
impl<K: Ord, V> BTreeMap<K, V> {
|
||||
@ -208,10 +211,10 @@ impl<K: Ord, V> BTreeMap<K, V> {
|
||||
loop {
|
||||
match Node::search(cur_node, key) {
|
||||
Found(handle) => return Some(handle.into_kv().1),
|
||||
GoDown(handle) => match handle.into_edge() {
|
||||
None => return None,
|
||||
Some(next_node) => {
|
||||
cur_node = next_node;
|
||||
GoDown(handle) => match handle.force() {
|
||||
Leaf(_) => return None,
|
||||
Internal(internal_handle) => {
|
||||
cur_node = internal_handle.into_edge();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@ -272,10 +275,10 @@ impl<K: Ord, V> BTreeMap<K, V> {
|
||||
let cur_node = temp_node;
|
||||
match Node::search(cur_node, key) {
|
||||
Found(handle) => return Some(handle.into_kv_mut().1),
|
||||
GoDown(handle) => match handle.into_edge_mut() {
|
||||
None => return None,
|
||||
Some(next_node) => {
|
||||
temp_node = next_node;
|
||||
GoDown(handle) => match handle.force() {
|
||||
Leaf(_) => return None,
|
||||
Internal(internal_handle) => {
|
||||
temp_node = internal_handle.into_edge_mut();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@ -354,27 +357,27 @@ impl<K: Ord, V> BTreeMap<K, V> {
|
||||
let result = stack.with(move |pusher, node| {
|
||||
// Same basic logic as found in `find`, but with PartialSearchStack mediating the
|
||||
// actual nodes for us
|
||||
match Node::search(node, &key) {
|
||||
return match Node::search(node, &key) {
|
||||
Found(mut handle) => {
|
||||
// Perfect match, swap the values and return the old one
|
||||
mem::swap(handle.val_mut(), &mut value);
|
||||
return Finished(Some(value));
|
||||
Finished(Some(value))
|
||||
},
|
||||
GoDown(handle) => {
|
||||
// We need to keep searching, try to get the search stack
|
||||
// to go down further
|
||||
match pusher.push(handle) {
|
||||
stack::Done(new_stack) => {
|
||||
match handle.force() {
|
||||
Leaf(leaf_handle) => {
|
||||
// We've reached a leaf, perform the insertion here
|
||||
new_stack.insert(key, value);
|
||||
return Finished(None);
|
||||
pusher.seal(leaf_handle).insert(key, value);
|
||||
Finished(None)
|
||||
}
|
||||
stack::Grew(new_stack) => {
|
||||
Internal(internal_handle) => {
|
||||
// We've found the subtree to insert this key/value pair in,
|
||||
// keep searching
|
||||
return Continue((new_stack, key, value));
|
||||
Continue((pusher.push(internal_handle), key, value))
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -452,18 +455,18 @@ impl<K: Ord, V> BTreeMap<K, V> {
|
||||
let mut stack = stack::PartialSearchStack::new(self);
|
||||
loop {
|
||||
let result = stack.with(move |pusher, node| {
|
||||
match Node::search(node, key) {
|
||||
return match Node::search(node, key) {
|
||||
Found(handle) => {
|
||||
// Perfect match. Terminate the stack here, and remove the entry
|
||||
return Finished(Some(pusher.seal(handle).remove()));
|
||||
Finished(Some(pusher.seal(handle).remove()))
|
||||
},
|
||||
GoDown(handle) => {
|
||||
// We need to keep searching, try to go down the next edge
|
||||
match pusher.push(handle) {
|
||||
match handle.force() {
|
||||
// We're at a leaf; the key isn't in here
|
||||
stack::Done(_) => return Finished(None),
|
||||
stack::Grew(new_stack) => return Continue(new_stack)
|
||||
};
|
||||
Leaf(_) => Finished(None),
|
||||
Internal(internal_handle) => Continue(pusher.push(internal_handle))
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -486,12 +489,11 @@ enum Continuation<A, B> {
|
||||
/// to nodes. By using this module much better safety guarantees can be made, and more search
|
||||
/// boilerplate gets cut out.
|
||||
mod stack {
|
||||
pub use self::PushResult::*;
|
||||
use core::prelude::*;
|
||||
use core::kinds::marker;
|
||||
use core::mem;
|
||||
use super::BTreeMap;
|
||||
use super::super::node::*;
|
||||
use super::super::node::{mod, Node, Fit, Split, KV, Edge, Internal, Leaf, LeafOrInternal};
|
||||
use vec::Vec;
|
||||
|
||||
/// A generic mutable reference, identical to `&mut` except for the fact that its lifetime
|
||||
@ -515,30 +517,23 @@ mod stack {
|
||||
}
|
||||
}
|
||||
|
||||
type StackItem<K, V> = EdgeNodeHandle<*mut Node<K, V>>;
|
||||
type StackItem<K, V> = node::Handle<*mut Node<K, V>, Edge, Internal>;
|
||||
type Stack<K, V> = Vec<StackItem<K, V>>;
|
||||
|
||||
/// A PartialSearchStack handles the construction of a search stack.
|
||||
/// A `PartialSearchStack` handles the construction of a search stack.
|
||||
pub struct PartialSearchStack<'a, K:'a, V:'a> {
|
||||
map: &'a mut BTreeMap<K, V>,
|
||||
stack: Stack<K, V>,
|
||||
next: *mut Node<K, V>,
|
||||
}
|
||||
|
||||
/// An OccupiedSearchStack represents a full path to an element of interest. It provides methods
|
||||
/// for manipulating the element at the top of its stack.
|
||||
pub struct OccupiedSearchStack<'a, K:'a, V:'a> {
|
||||
/// A `SearchStack` represents a full path to an element or an edge of interest. It provides
|
||||
/// methods depending on the type of what the path points to for removing an element, inserting
|
||||
/// a new element, and manipulating to element at the top of the stack.
|
||||
pub struct SearchStack<'a, K:'a, V:'a, Type, NodeType> {
|
||||
map: &'a mut BTreeMap<K, V>,
|
||||
stack: Stack<K, V>,
|
||||
top: KVNodeHandle<*mut Node<K, V>>,
|
||||
}
|
||||
|
||||
/// A VacantSearchStack represents a full path to a spot for a new element of interest. It
|
||||
/// provides a method inserting an element at the top of its stack.
|
||||
pub struct VacantSearchStack<'a, K:'a, V:'a> {
|
||||
map: &'a mut BTreeMap<K, V>,
|
||||
stack: Stack<K, V>,
|
||||
top: EdgeNodeHandle<*mut Node<K, V>>,
|
||||
top: node::Handle<*mut Node<K, V>, Type, NodeType>,
|
||||
}
|
||||
|
||||
/// A `PartialSearchStack` that doesn't hold a a reference to the next node, and is just
|
||||
@ -550,14 +545,6 @@ mod stack {
|
||||
marker: marker::InvariantLifetime<'id>
|
||||
}
|
||||
|
||||
/// The result of asking a PartialSearchStack to push another node onto itself. Either it
|
||||
/// Grew, in which case it's still Partial, or it found its last node was actually a leaf, in
|
||||
/// which case it seals itself and yields a complete SearchStack.
|
||||
pub enum PushResult<'a, K:'a, V:'a> {
|
||||
Grew(PartialSearchStack<'a, K, V>),
|
||||
Done(VacantSearchStack<'a, K, V>),
|
||||
}
|
||||
|
||||
impl<'a, K, V> PartialSearchStack<'a, K, V> {
|
||||
/// Creates a new PartialSearchStack from a BTreeMap by initializing the stack with the
|
||||
/// root of the tree.
|
||||
@ -605,40 +592,29 @@ mod stack {
|
||||
/// Pushes the requested child of the stack's current top on top of the stack. If the child
|
||||
/// exists, then a new PartialSearchStack is yielded. Otherwise, a VacantSearchStack is
|
||||
/// yielded.
|
||||
pub fn push(mut self, mut edge: EdgeNodeHandle<IdRef<'id, Node<K, V>>>)
|
||||
-> PushResult<'a, K, V> {
|
||||
let to_insert = edge.as_raw();
|
||||
match edge.edge_mut() {
|
||||
None => {
|
||||
Done(VacantSearchStack {
|
||||
map: self.map,
|
||||
stack: self.stack,
|
||||
top: to_insert,
|
||||
})
|
||||
},
|
||||
Some(node) => {
|
||||
self.stack.push(to_insert);
|
||||
Grew(PartialSearchStack {
|
||||
map: self.map,
|
||||
stack: self.stack,
|
||||
next: node as *mut _,
|
||||
})
|
||||
},
|
||||
pub fn push(mut self, mut edge: node::Handle<IdRef<'id, Node<K, V>>, Edge, Internal>)
|
||||
-> PartialSearchStack<'a, K, V> {
|
||||
self.stack.push(edge.as_raw());
|
||||
PartialSearchStack {
|
||||
map: self.map,
|
||||
stack: self.stack,
|
||||
next: edge.edge_mut() as *mut _,
|
||||
}
|
||||
}
|
||||
|
||||
/// Converts the PartialSearchStack into an OccupiedSearchStack.
|
||||
pub fn seal(self, mut node: KVNodeHandle<IdRef<'id, Node<K, V>>>)
|
||||
-> OccupiedSearchStack<'a, K, V> {
|
||||
OccupiedSearchStack {
|
||||
/// Converts the PartialSearchStack into a SearchStack.
|
||||
pub fn seal<Type, NodeType>
|
||||
(self, mut handle: node::Handle<IdRef<'id, Node<K, V>>, Type, NodeType>)
|
||||
-> SearchStack<'a, K, V, Type, NodeType> {
|
||||
SearchStack {
|
||||
map: self.map,
|
||||
stack: self.stack,
|
||||
top: node.as_raw(),
|
||||
top: handle.as_raw(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, K, V> OccupiedSearchStack<'a, K, V> {
|
||||
impl<'a, K, V, NodeType> SearchStack<'a, K, V, KV, NodeType> {
|
||||
/// Gets a reference to the value the stack points to.
|
||||
pub fn peek(&self) -> &V {
|
||||
unsafe { self.top.from_raw().into_kv().1 }
|
||||
@ -659,20 +635,13 @@ mod stack {
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, K, V> SearchStack<'a, K, V, KV, Leaf> {
|
||||
/// Removes the key and value in the top element of the stack, then handles underflows as
|
||||
/// described in BTree's pop function.
|
||||
pub fn remove(mut self) -> V {
|
||||
// Ensure that the search stack goes to a leaf. This is necessary to perform deletion
|
||||
// in a BTree. Note that this may put the tree in an inconsistent state (further
|
||||
// described in leafify's comments), but this is immediately fixed by the
|
||||
// removing the value we want to remove
|
||||
self.leafify();
|
||||
|
||||
let map = self.map;
|
||||
map.length -= 1;
|
||||
|
||||
let mut stack = self.stack;
|
||||
fn remove_leaf(mut self) -> V {
|
||||
self.map.length -= 1;
|
||||
|
||||
// Remove the key-value pair from the leaf that this search stack points to.
|
||||
// Then, note if the leaf is underfull, and promptly forget the leaf and its ptr
|
||||
@ -684,16 +653,16 @@ mod stack {
|
||||
};
|
||||
|
||||
loop {
|
||||
match stack.pop() {
|
||||
match self.stack.pop() {
|
||||
None => {
|
||||
// We've reached the root, so no matter what, we're done. We manually
|
||||
// access the root via the tree itself to avoid creating any dangling
|
||||
// pointers.
|
||||
if map.root.len() == 0 && !map.root.is_leaf() {
|
||||
if self.map.root.len() == 0 && !self.map.root.is_leaf() {
|
||||
// We've emptied out the root, so make its only child the new root.
|
||||
// If it's a leaf, we just let it become empty.
|
||||
map.depth -= 1;
|
||||
map.root.into_edge();
|
||||
self.map.depth -= 1;
|
||||
self.map.root.hoist_lone_child();
|
||||
}
|
||||
return value;
|
||||
}
|
||||
@ -712,6 +681,18 @@ mod stack {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, K, V> SearchStack<'a, K, V, KV, LeafOrInternal> {
|
||||
/// Removes the key and value in the top element of the stack, then handles underflows as
|
||||
/// described in BTree's pop function.
|
||||
pub fn remove(self) -> V {
|
||||
// Ensure that the search stack goes to a leaf. This is necessary to perform deletion
|
||||
// in a BTree. Note that this may put the tree in an inconsistent state (further
|
||||
// described in into_leaf's comments), but this is immediately fixed by the
|
||||
// removing the value we want to remove
|
||||
self.into_leaf().remove_leaf()
|
||||
}
|
||||
|
||||
/// Subroutine for removal. Takes a search stack for a key that might terminate at an
|
||||
/// internal node, and mutates the tree and search stack to *make* it a search stack
|
||||
@ -719,7 +700,7 @@ mod stack {
|
||||
/// leaves the tree in an inconsistent state that must be repaired by the caller by
|
||||
/// removing the entry in question. Specifically the key-value pair and its successor will
|
||||
/// become swapped.
|
||||
fn leafify(&mut self) {
|
||||
fn into_leaf(mut self) -> SearchStack<'a, K, V, KV, Leaf> {
|
||||
unsafe {
|
||||
let mut top_raw = self.top;
|
||||
let mut top = top_raw.from_raw_mut();
|
||||
@ -728,31 +709,43 @@ mod stack {
|
||||
let val_ptr = top.val_mut() as *mut _;
|
||||
|
||||
// Try to go into the right subtree of the found key to find its successor
|
||||
let mut right_edge = top.right_edge();
|
||||
let right_edge_raw = right_edge.as_raw();
|
||||
match right_edge.edge_mut() {
|
||||
None => {
|
||||
match top.force() {
|
||||
Leaf(mut leaf_handle) => {
|
||||
// We're a proper leaf stack, nothing to do
|
||||
return SearchStack {
|
||||
map: self.map,
|
||||
stack: self.stack,
|
||||
top: leaf_handle.as_raw()
|
||||
}
|
||||
}
|
||||
Some(mut temp_node) => {
|
||||
Internal(mut internal_handle) => {
|
||||
let mut right_handle = internal_handle.right_edge();
|
||||
|
||||
//We're not a proper leaf stack, let's get to work.
|
||||
self.stack.push(right_edge_raw);
|
||||
self.stack.push(right_handle.as_raw());
|
||||
|
||||
let mut temp_node = right_handle.edge_mut();
|
||||
loop {
|
||||
// Walk into the smallest subtree of this node
|
||||
let node = temp_node;
|
||||
|
||||
if node.is_leaf() {
|
||||
// This node is a leaf, do the swap and return
|
||||
let mut handle = node.kv_handle(0);
|
||||
self.top = handle.as_raw();
|
||||
mem::swap(handle.key_mut(), &mut *key_ptr);
|
||||
mem::swap(handle.val_mut(), &mut *val_ptr);
|
||||
break;
|
||||
} else {
|
||||
// This node is internal, go deeper
|
||||
let mut handle = node.edge_handle(0);
|
||||
self.stack.push(handle.as_raw());
|
||||
temp_node = handle.into_edge_mut().unwrap();
|
||||
match node.kv_handle(0).force() {
|
||||
Leaf(mut handle) => {
|
||||
// This node is a leaf, do the swap and return
|
||||
mem::swap(handle.key_mut(), &mut *key_ptr);
|
||||
mem::swap(handle.val_mut(), &mut *val_ptr);
|
||||
return SearchStack {
|
||||
map: self.map,
|
||||
stack: self.stack,
|
||||
top: handle.as_raw()
|
||||
}
|
||||
},
|
||||
Internal(kv_handle) => {
|
||||
// This node is internal, go deeper
|
||||
let mut handle = kv_handle.into_left_edge();
|
||||
self.stack.push(handle.as_raw());
|
||||
temp_node = handle.into_edge_mut();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -761,7 +754,7 @@ mod stack {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, K, V> VacantSearchStack<'a, K, V> {
|
||||
impl<'a, K, V> SearchStack<'a, K, V, Edge, Leaf> {
|
||||
/// Inserts the key and value into the top element in the stack, and if that node has to
|
||||
/// split recursively inserts the split contents into the next element stack until
|
||||
/// splits stop.
|
||||
@ -1273,27 +1266,28 @@ impl<K: Ord, V> BTreeMap<K, V> {
|
||||
let mut stack = stack::PartialSearchStack::new(self);
|
||||
loop {
|
||||
let result = stack.with(move |pusher, node| {
|
||||
match Node::search(node, &key) {
|
||||
return match Node::search(node, &key) {
|
||||
Found(handle) => {
|
||||
// Perfect match
|
||||
return Finished(Occupied(OccupiedEntry {
|
||||
Finished(Occupied(OccupiedEntry {
|
||||
stack: pusher.seal(handle)
|
||||
}));
|
||||
}))
|
||||
},
|
||||
GoDown(handle) => {
|
||||
match pusher.push(handle) {
|
||||
stack::Done(new_stack) => {
|
||||
// Not in the tree, but we've found where it goes
|
||||
return Finished(Vacant(VacantEntry {
|
||||
stack: new_stack,
|
||||
match handle.force() {
|
||||
Leaf(leaf_handle) => {
|
||||
Finished(Vacant(VacantEntry {
|
||||
stack: pusher.seal(leaf_handle),
|
||||
key: key,
|
||||
}));
|
||||
}))
|
||||
},
|
||||
Internal(internal_handle) => {
|
||||
Continue((
|
||||
pusher.push(internal_handle),
|
||||
key
|
||||
))
|
||||
}
|
||||
stack::Grew(new_stack) => {
|
||||
// We've found the subtree this key must go in
|
||||
return Continue((new_stack, key));
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
pub use self::InsertionResult::*;
|
||||
pub use self::SearchResult::*;
|
||||
pub use self::ForceResult::*;
|
||||
pub use self::TraversalItem::*;
|
||||
|
||||
use core::prelude::*;
|
||||
@ -34,9 +35,9 @@ pub enum InsertionResult<K, V> {
|
||||
/// Represents the result of a search for a key in a single node
|
||||
pub enum SearchResult<NodeRef> {
|
||||
/// The element was found at the given index
|
||||
Found(KVNodeHandle<NodeRef>),
|
||||
Found(Handle<NodeRef, KV, LeafOrInternal>),
|
||||
/// The element wasn't found, but if it's anywhere, it must be beyond this edge
|
||||
GoDown(EdgeNodeHandle<NodeRef>),
|
||||
GoDown(Handle<NodeRef, Edge, LeafOrInternal>),
|
||||
}
|
||||
|
||||
/// A B-Tree Node. We keep keys/edges/values separate to optimize searching for keys.
|
||||
@ -428,8 +429,10 @@ impl<K: Clone, V: Clone> Clone for Node<K, V> {
|
||||
}
|
||||
}
|
||||
|
||||
/// A reference to a key/value pair in the middle of a `Node`. Methods are provided for removing
|
||||
/// the pair and accessing the pair and the adjacent edges.
|
||||
/// A reference to something in the middle of a `Node`. There are two `Type`s of `Handle`s,
|
||||
/// namely `KV` handles, which point to key/value pairs, and `Edge` handles, which point to edges
|
||||
/// before or after key/value pairs. Methods are provided for removing pairs, inserting into edges,
|
||||
/// accessing the stored values, and moving around the `Node`.
|
||||
///
|
||||
/// This handle is generic, and can take any sort of reference to a `Node`. The reason for this is
|
||||
/// two-fold. First of all, it reduces the amount of repetitive code, implementing functions that
|
||||
@ -490,20 +493,17 @@ impl<K: Clone, V: Clone> Clone for Node<K, V> {
|
||||
/// }
|
||||
/// ```
|
||||
#[deriving(Copy)]
|
||||
pub struct KVNodeHandle<NodeRef> {
|
||||
pub struct Handle<NodeRef, Type, NodeType> {
|
||||
node: NodeRef,
|
||||
index: uint
|
||||
}
|
||||
|
||||
/// A reference to an edge in the middle of a `Node`. Methods are provided for inserting stuff into
|
||||
/// the space, handling underflow, and accessing the pointed-to edge.
|
||||
///
|
||||
/// Please see the notes on `KVNodeHandle` about the generic parameter and safety concerns.
|
||||
#[deriving(Copy)]
|
||||
pub struct EdgeNodeHandle<NodeRef> {
|
||||
node: NodeRef,
|
||||
index: uint
|
||||
}
|
||||
pub enum KV {}
|
||||
pub enum Edge {}
|
||||
|
||||
pub enum LeafOrInternal {}
|
||||
pub enum Leaf {}
|
||||
pub enum Internal {}
|
||||
|
||||
impl<K: Ord, V> Node<K, V> {
|
||||
/// Searches for the given key in the node. If it finds an exact match,
|
||||
@ -516,12 +516,12 @@ impl<K: Ord, V> Node<K, V> {
|
||||
// worse for uints.
|
||||
let (found, index) = node.search_linear(key);
|
||||
if found {
|
||||
Found(KVNodeHandle {
|
||||
Found(Handle {
|
||||
node: node,
|
||||
index: index
|
||||
})
|
||||
} else {
|
||||
GoDown(EdgeNodeHandle {
|
||||
GoDown(Handle {
|
||||
node: node,
|
||||
index: index
|
||||
})
|
||||
@ -586,70 +586,104 @@ impl <K, V> Node<K, V> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, K: 'a, V: 'a> EdgeNodeHandle<&'a Node<K, V>> {
|
||||
/// Turns the handle into a reference to the edge it points at. This is necessary because the
|
||||
/// returned pointer has a larger lifetime than what would be returned by `edge` or `edge_mut`,
|
||||
/// making it more suitable for moving down a chain of nodes.
|
||||
///
|
||||
/// Returns `None` if called on an edge in a leaf node.
|
||||
pub fn into_edge(self) -> Option<&'a Node<K, V>> {
|
||||
if self.node.is_leaf() {
|
||||
None
|
||||
} else {
|
||||
unsafe {
|
||||
Some(self.node.edges().unsafe_get(self.index))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, K: 'a, V: 'a> EdgeNodeHandle<&'a mut Node<K, V>> {
|
||||
/// Turns the handle into a mutable reference to the edge it points at. This is necessary
|
||||
/// because the returned pointer has a larger lifetime than what would be returned by
|
||||
/// `edge_mut`, making it more suitable for moving down a chain of nodes.
|
||||
///
|
||||
/// Returns `None` if called on an edge in a leaf node.
|
||||
pub fn into_edge_mut(self) -> Option<&'a mut Node<K, V>> {
|
||||
if self.node.is_leaf() {
|
||||
None
|
||||
} else {
|
||||
unsafe {
|
||||
Some(self.node.edges_mut().unsafe_mut(self.index))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<K, V, NodeRef: Deref<Node<K, V>>> EdgeNodeHandle<NodeRef> {
|
||||
/// Returns a reference to the node that contains the pointed-to edge. This is very different
|
||||
/// from `edge` and `edge_mut` because those return children of the node returned by `node`.
|
||||
impl<K, V, NodeRef: Deref<Node<K, V>>, Type, NodeType> Handle<NodeRef, Type, NodeType> {
|
||||
/// Returns a reference to the node that contains the pointed-to edge or key/value pair. This
|
||||
/// is very different from `edge` and `edge_mut` because those return children of the node
|
||||
/// returned by `node`.
|
||||
pub fn node(&self) -> &Node<K, V> {
|
||||
&*self.node
|
||||
}
|
||||
}
|
||||
|
||||
impl<K, V, NodeRef: DerefMut<Node<K, V>>, Type, NodeType> Handle<NodeRef, Type, NodeType> {
|
||||
/// Converts a handle into one that stores the same information using a raw pointer. This can
|
||||
/// be useful in conjunction with `from_raw` when the type system is insufficient for
|
||||
/// determining the lifetimes of the nodes.
|
||||
pub fn as_raw(&mut self) -> Handle<*mut Node<K, V>, Type, NodeType> {
|
||||
Handle {
|
||||
node: &mut *self.node as *mut _,
|
||||
index: self.index
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<K, V, Type, NodeType> Handle<*mut Node<K, V>, Type, NodeType> {
|
||||
/// Converts from a handle stored with a raw pointer, which isn't directly usable, to a handle
|
||||
/// stored with a reference. This is an unsafe inverse of `as_raw`, and together they allow
|
||||
/// unsafely extending the lifetime of the reference to the `Node`.
|
||||
pub unsafe fn from_raw<'a>(&'a self) -> Handle<&'a Node<K, V>, Type, NodeType> {
|
||||
Handle {
|
||||
node: &*self.node,
|
||||
index: self.index
|
||||
}
|
||||
}
|
||||
|
||||
/// Converts from a handle stored with a raw pointer, which isn't directly usable, to a handle
|
||||
/// stored with a mutable reference. This is an unsafe inverse of `as_raw`, and together they
|
||||
/// allow unsafely extending the lifetime of the reference to the `Node`.
|
||||
pub unsafe fn from_raw_mut<'a>(&'a mut self) -> Handle<&'a mut Node<K, V>, Type, NodeType> {
|
||||
Handle {
|
||||
node: &mut *self.node,
|
||||
index: self.index
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, K: 'a, V: 'a> Handle<&'a Node<K, V>, Edge, Internal> {
|
||||
/// Turns the handle into a reference to the edge it points at. This is necessary because the
|
||||
/// returned pointer has a larger lifetime than what would be returned by `edge` or `edge_mut`,
|
||||
/// making it more suitable for moving down a chain of nodes.
|
||||
pub fn into_edge(self) -> &'a Node<K, V> {
|
||||
unsafe {
|
||||
self.node.edges().unsafe_get(self.index)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, K: 'a, V: 'a> Handle<&'a mut Node<K, V>, Edge, Internal> {
|
||||
/// Turns the handle into a mutable reference to the edge it points at. This is necessary
|
||||
/// because the returned pointer has a larger lifetime than what would be returned by
|
||||
/// `edge_mut`, making it more suitable for moving down a chain of nodes.
|
||||
pub fn into_edge_mut(self) -> &'a mut Node<K, V> {
|
||||
unsafe {
|
||||
self.node.edges_mut().unsafe_mut(self.index)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<K, V, NodeRef: Deref<Node<K, V>>> Handle<NodeRef, Edge, Internal> {
|
||||
// This doesn't exist because there are no uses for it,
|
||||
// but is fine to add, analagous to edge_mut.
|
||||
//
|
||||
// /// Returns a reference to the edge pointed-to by this handle. This should not be
|
||||
// /// confused with `node`, which references the parent node of what is returned here.
|
||||
// ///
|
||||
// /// Returns `None` when called on an edge in a leaf node.
|
||||
// pub fn edge(&self) -> Option<&Node<K, V>>
|
||||
// pub fn edge(&self) -> &Node<K, V>
|
||||
}
|
||||
|
||||
impl<K, V, NodeRef: DerefMut<Node<K, V>>> EdgeNodeHandle<NodeRef> {
|
||||
/// Returns a mutable reference to the edge pointed-to by this handle. This should not be
|
||||
/// confused with `node`, which references the parent node of what is returned here.
|
||||
///
|
||||
/// Returns `None` when called on an edge in a leaf node.
|
||||
pub fn edge_mut(&mut self) -> Option<&mut Node<K, V>> {
|
||||
pub enum ForceResult<NodeRef, Type> {
|
||||
Leaf(Handle<NodeRef, Type, Leaf>),
|
||||
Internal(Handle<NodeRef, Type, Internal>)
|
||||
}
|
||||
|
||||
impl<K, V, NodeRef: Deref<Node<K, V>>, Type> Handle<NodeRef, Type, LeafOrInternal> {
|
||||
/// Figure out whether this handle is pointing to something in a leaf node or to something in
|
||||
/// an internal node, clarifying the type according to the result.
|
||||
pub fn force(self) -> ForceResult<NodeRef, Type> {
|
||||
if self.node.is_leaf() {
|
||||
None
|
||||
Leaf(Handle {
|
||||
node: self.node,
|
||||
index: self.index
|
||||
})
|
||||
} else {
|
||||
unsafe { Some(self.node.edges_mut().unsafe_mut(self.index)) }
|
||||
Internal(Handle {
|
||||
node: self.node,
|
||||
index: self.index
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<K, V, NodeRef: DerefMut<Node<K, V>>> Handle<NodeRef, Edge, Leaf> {
|
||||
/// Tries to insert this key-value pair at the given index in this leaf node
|
||||
/// If the node is full, we have to split it.
|
||||
///
|
||||
@ -657,10 +691,6 @@ impl<K, V, NodeRef: DerefMut<Node<K, V>>> EdgeNodeHandle<NodeRef> {
|
||||
/// they're done mutating the tree, but we don't want to borrow anything for now.
|
||||
pub fn insert_as_leaf(mut self, key: K, value: V) ->
|
||||
(InsertionResult<K, V>, *mut V) {
|
||||
// Necessary for correctness, but in a private module
|
||||
debug_assert!(self.node.is_leaf(),
|
||||
"insert_as_leaf must only be called on leaf nodes");
|
||||
|
||||
if !self.node.is_full() {
|
||||
// The element can fit, just insert it
|
||||
(Fit, unsafe { self.node.insert_kv(self.index, key, value) as *mut _ })
|
||||
@ -683,15 +713,21 @@ impl<K, V, NodeRef: DerefMut<Node<K, V>>> EdgeNodeHandle<NodeRef> {
|
||||
(Split(new_key, new_val, new_right), ptr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<K, V, NodeRef: DerefMut<Node<K, V>>> Handle<NodeRef, Edge, Internal> {
|
||||
/// Returns a mutable reference to the edge pointed-to by this handle. This should not be
|
||||
/// confused with `node`, which references the parent node of what is returned here.
|
||||
pub fn edge_mut(&mut self) -> &mut Node<K, V> {
|
||||
unsafe {
|
||||
self.node.edges_mut().unsafe_mut(self.index)
|
||||
}
|
||||
}
|
||||
|
||||
/// Tries to insert this key-value pair at the given index in this internal node
|
||||
/// If the node is full, we have to split it.
|
||||
pub fn insert_as_internal(mut self, key: K, value: V, right: Node<K, V>)
|
||||
-> InsertionResult<K, V> {
|
||||
// Necessary for correctness, but in a private module
|
||||
debug_assert!(!self.node.is_leaf(),
|
||||
"insert_as_internal must only be called on internal nodes");
|
||||
|
||||
if !self.node.is_full() {
|
||||
// The element can fit, just insert it
|
||||
unsafe {
|
||||
@ -739,26 +775,6 @@ impl<K, V, NodeRef: DerefMut<Node<K, V>>> EdgeNodeHandle<NodeRef> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Gets the handle pointing to the key/value pair just to the left of the pointed-to edge.
|
||||
/// This is unsafe because the handle might point to the first edge in the node, which has no
|
||||
/// pair to its left.
|
||||
unsafe fn left_kv<'a>(&'a mut self) -> KVNodeHandle<&'a mut Node<K, V>> {
|
||||
KVNodeHandle {
|
||||
node: &mut *self.node,
|
||||
index: self.index - 1
|
||||
}
|
||||
}
|
||||
|
||||
/// Gets the handle pointing to the key/value pair just to the right of the pointed-to edge.
|
||||
/// This is unsafe because the handle might point to the last edge in the node, which has no
|
||||
/// pair to its right.
|
||||
unsafe fn right_kv<'a>(&'a mut self) -> KVNodeHandle<&'a mut Node<K, V>> {
|
||||
KVNodeHandle {
|
||||
node: &mut *self.node,
|
||||
index: self.index
|
||||
}
|
||||
}
|
||||
|
||||
/// Right is underflowed. Tries to steal from left,
|
||||
/// but merges left and right if left is low too.
|
||||
unsafe fn handle_underflow_to_left(&mut self) {
|
||||
@ -780,41 +796,31 @@ impl<K, V, NodeRef: DerefMut<Node<K, V>>> EdgeNodeHandle<NodeRef> {
|
||||
self.right_kv().merge_children();
|
||||
}
|
||||
}
|
||||
|
||||
/// Converts a handle into one that stores the same information using a raw pointer. This can
|
||||
/// be useful in conjunction with `from_raw` in the cases in which the type system is
|
||||
/// insufficient for determining the lifetimes of the nodes.
|
||||
pub fn as_raw(&mut self) -> EdgeNodeHandle<*mut Node<K, V>> {
|
||||
EdgeNodeHandle {
|
||||
node: &mut *self.node as *mut _,
|
||||
index: self.index
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<K, V> EdgeNodeHandle<*mut Node<K, V>> {
|
||||
/// Converts from a handle stored with a raw pointer, which isn't directly usable, to a handle
|
||||
/// stored with a reference. This is an unsafe inverse of `as_raw`, and together they allow
|
||||
/// unsafely extending the lifetime of the reference to the `Node`.
|
||||
pub unsafe fn from_raw<'a>(&'a self) -> EdgeNodeHandle<&'a Node<K, V>> {
|
||||
EdgeNodeHandle {
|
||||
node: &*self.node,
|
||||
index: self.index
|
||||
impl<K, V, NodeRef: DerefMut<Node<K, V>>, NodeType> Handle<NodeRef, Edge, NodeType> {
|
||||
/// Gets the handle pointing to the key/value pair just to the left of the pointed-to edge.
|
||||
/// This is unsafe because the handle might point to the first edge in the node, which has no
|
||||
/// pair to its left.
|
||||
unsafe fn left_kv<'a>(&'a mut self) -> Handle<&'a mut Node<K, V>, KV, NodeType> {
|
||||
Handle {
|
||||
node: &mut *self.node,
|
||||
index: self.index - 1
|
||||
}
|
||||
}
|
||||
|
||||
/// Converts from a handle stored with a raw pointer, which isn't directly usable, to a handle
|
||||
/// stored with a mutable reference. This is an unsafe inverse of `as_raw`, and together they
|
||||
/// allow unsafely extending the lifetime of the reference to the `Node`.
|
||||
pub unsafe fn from_raw_mut<'a>(&'a mut self) -> EdgeNodeHandle<&'a mut Node<K, V>> {
|
||||
EdgeNodeHandle {
|
||||
/// Gets the handle pointing to the key/value pair just to the right of the pointed-to edge.
|
||||
/// This is unsafe because the handle might point to the last edge in the node, which has no
|
||||
/// pair to its right.
|
||||
unsafe fn right_kv<'a>(&'a mut self) -> Handle<&'a mut Node<K, V>, KV, NodeType> {
|
||||
Handle {
|
||||
node: &mut *self.node,
|
||||
index: self.index
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, K: 'a, V: 'a> KVNodeHandle<&'a Node<K, V>> {
|
||||
impl<'a, K: 'a, V: 'a, NodeType> Handle<&'a Node<K, V>, KV, NodeType> {
|
||||
/// Turns the handle into references to the key and value it points at. This is necessary
|
||||
/// because the returned pointers have larger lifetimes than what would be returned by `key`
|
||||
/// or `val`.
|
||||
@ -829,7 +835,7 @@ impl<'a, K: 'a, V: 'a> KVNodeHandle<&'a Node<K, V>> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, K: 'a, V: 'a> KVNodeHandle<&'a mut Node<K, V>> {
|
||||
impl<'a, K: 'a, V: 'a, NodeType> Handle<&'a mut Node<K, V>, KV, NodeType> {
|
||||
/// Turns the handle into mutable references to the key and value it points at. This is
|
||||
/// necessary because the returned pointers have larger lifetimes than what would be returned
|
||||
/// by `key_mut` or `val_mut`.
|
||||
@ -842,14 +848,19 @@ impl<'a, K: 'a, V: 'a> KVNodeHandle<&'a mut Node<K, V>> {
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert this handle into one pointing at the edge immediately to the left of the key/value
|
||||
/// pair pointed-to by this handle. This is useful because it returns a reference with larger
|
||||
/// lifetime than `left_edge`.
|
||||
pub fn into_left_edge(self) -> Handle<&'a mut Node<K, V>, Edge, NodeType> {
|
||||
Handle {
|
||||
node: &mut *self.node,
|
||||
index: self.index
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, K: 'a, V: 'a, NodeRef: Deref<Node<K, V>> + 'a> KVNodeHandle<NodeRef> {
|
||||
/// Returns a reference to the node that contains the pointed-to key/value pair.
|
||||
pub fn node(&'a self) -> &'a Node<K, V> {
|
||||
&*self.node
|
||||
}
|
||||
|
||||
impl<'a, K: 'a, V: 'a, NodeRef: Deref<Node<K, V>> + 'a, NodeType> Handle<NodeRef, KV, NodeType> {
|
||||
// These are fine to include, but are currently unneeded.
|
||||
//
|
||||
// /// Returns a reference to the key pointed-to by this handle. This doesn't return a
|
||||
@ -867,7 +878,7 @@ impl<'a, K: 'a, V: 'a, NodeRef: Deref<Node<K, V>> + 'a> KVNodeHandle<NodeRef> {
|
||||
// }
|
||||
}
|
||||
|
||||
impl<'a, K: 'a, V: 'a, NodeRef: DerefMut<Node<K, V>> + 'a> KVNodeHandle<NodeRef> {
|
||||
impl<'a, K: 'a, V: 'a, NodeRef: DerefMut<Node<K, V>> + 'a, NodeType> Handle<NodeRef, KV, NodeType> {
|
||||
/// Returns a mutable reference to the key pointed-to by this handle. This doesn't return a
|
||||
/// reference with a lifetime as large as `into_kv_mut`, but it also does not consume the
|
||||
/// handle.
|
||||
@ -883,11 +894,11 @@ impl<'a, K: 'a, V: 'a, NodeRef: DerefMut<Node<K, V>> + 'a> KVNodeHandle<NodeRef>
|
||||
}
|
||||
}
|
||||
|
||||
impl<K, V, NodeRef: DerefMut<Node<K, V>>> KVNodeHandle<NodeRef> {
|
||||
impl<K, V, NodeRef: DerefMut<Node<K, V>>, NodeType> Handle<NodeRef, KV, NodeType> {
|
||||
/// Gets the handle pointing to the edge immediately to the left of the key/value pair pointed
|
||||
/// to by this handle.
|
||||
pub fn left_edge<'a>(&'a mut self) -> EdgeNodeHandle<&'a mut Node<K, V>> {
|
||||
EdgeNodeHandle {
|
||||
pub fn left_edge<'a>(&'a mut self) -> Handle<&'a mut Node<K, V>, Edge, NodeType> {
|
||||
Handle {
|
||||
node: &mut *self.node,
|
||||
index: self.index
|
||||
}
|
||||
@ -895,41 +906,33 @@ impl<K, V, NodeRef: DerefMut<Node<K, V>>> KVNodeHandle<NodeRef> {
|
||||
|
||||
/// Gets the handle pointing to the edge immediately to the right of the key/value pair pointed
|
||||
/// to by this handle.
|
||||
pub fn right_edge<'a>(&'a mut self) -> EdgeNodeHandle<&'a mut Node<K, V>> {
|
||||
EdgeNodeHandle {
|
||||
pub fn right_edge<'a>(&'a mut self) -> Handle<&'a mut Node<K, V>, Edge, NodeType> {
|
||||
Handle {
|
||||
node: &mut *self.node,
|
||||
index: self.index + 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<K, V, NodeRef: DerefMut<Node<K, V>>> Handle<NodeRef, KV, Leaf> {
|
||||
/// Removes the key/value pair at the handle's location.
|
||||
///
|
||||
/// # Panics (in debug build)
|
||||
///
|
||||
/// Panics if the node containing the pair is not a leaf node.
|
||||
pub fn remove_as_leaf(mut self) -> (K, V) {
|
||||
// Necessary for correctness, but in a private module
|
||||
debug_assert!(self.node.is_leaf(), "remove_as_leaf must only be called on leaf nodes");
|
||||
unsafe { self.node.remove_kv(self.index) }
|
||||
}
|
||||
}
|
||||
|
||||
/// Converts a handle into one that stores the same information using a raw pointer. This can
|
||||
/// be useful in conjunction with `from_raw` in the cases in which the type system is
|
||||
/// insufficient for determining the lifetimes of the nodes.
|
||||
pub fn as_raw(&mut self) -> KVNodeHandle<*mut Node<K, V>> {
|
||||
KVNodeHandle {
|
||||
node: &mut *self.node as *mut _,
|
||||
index: self.index
|
||||
}
|
||||
}
|
||||
|
||||
impl<K, V, NodeRef: DerefMut<Node<K, V>>> Handle<NodeRef, KV, Internal> {
|
||||
/// Steal! Stealing is roughly analogous to a binary tree rotation.
|
||||
/// In this case, we're "rotating" right.
|
||||
unsafe fn steal_rightward(&mut self) {
|
||||
// Take the biggest stuff off left
|
||||
let (mut key, mut val, edge) = {
|
||||
let mut left_handle = self.left_edge();
|
||||
let left = left_handle.edge_mut().unwrap();
|
||||
let left = left_handle.edge_mut();
|
||||
let (key, val) = left.pop_kv();
|
||||
let edge = if left.is_leaf() {
|
||||
None
|
||||
@ -946,7 +949,7 @@ impl<K, V, NodeRef: DerefMut<Node<K, V>>> KVNodeHandle<NodeRef> {
|
||||
|
||||
// Put them at the start of right
|
||||
let mut right_handle = self.right_edge();
|
||||
let right = right_handle.edge_mut().unwrap();
|
||||
let right = right_handle.edge_mut();
|
||||
right.insert_kv(0, key, val);
|
||||
match edge {
|
||||
Some(edge) => right.insert_edge(0, edge),
|
||||
@ -960,7 +963,7 @@ impl<K, V, NodeRef: DerefMut<Node<K, V>>> KVNodeHandle<NodeRef> {
|
||||
// Take the smallest stuff off right
|
||||
let (mut key, mut val, edge) = {
|
||||
let mut right_handle = self.right_edge();
|
||||
let right = right_handle.edge_mut().unwrap();
|
||||
let right = right_handle.edge_mut();
|
||||
let (key, val) = right.remove_kv(0);
|
||||
let edge = if right.is_leaf() {
|
||||
None
|
||||
@ -977,7 +980,7 @@ impl<K, V, NodeRef: DerefMut<Node<K, V>>> KVNodeHandle<NodeRef> {
|
||||
|
||||
// Put them at the end of left
|
||||
let mut left_handle = self.left_edge();
|
||||
let left = left_handle.edge_mut().unwrap();
|
||||
let left = left_handle.edge_mut();
|
||||
left.push_kv(key, val);
|
||||
match edge {
|
||||
Some(edge) => left.push_edge(edge),
|
||||
@ -994,57 +997,21 @@ impl<K, V, NodeRef: DerefMut<Node<K, V>>> KVNodeHandle<NodeRef> {
|
||||
let right = self.node.remove_edge(self.index + 1);
|
||||
|
||||
// Give left right's stuff.
|
||||
self.left_edge().edge_mut().unwrap()
|
||||
self.left_edge().edge_mut()
|
||||
.absorb(key, val, right);
|
||||
}
|
||||
}
|
||||
|
||||
impl<K, V> KVNodeHandle<*mut Node<K, V>> {
|
||||
/// Converts from a handle stored with a raw pointer, which isn't directly usable, to a handle
|
||||
/// stored with a reference. This is an unsafe inverse of `as_raw`, and together they allow
|
||||
/// unsafely extending the lifetime of the reference to the `Node`.
|
||||
pub unsafe fn from_raw<'a>(&'a self) -> KVNodeHandle<&'a Node<K, V>> {
|
||||
KVNodeHandle {
|
||||
node: &*self.node,
|
||||
index: self.index
|
||||
}
|
||||
}
|
||||
|
||||
/// Converts from a handle stored with a raw pointer, which isn't directly usable, to a handle
|
||||
/// stored with a mutable reference. This is an unsafe inverse of `as_raw`, and together they
|
||||
/// allow unsafely extending the lifetime of the reference to the `Node`.
|
||||
pub unsafe fn from_raw_mut<'a>(&'a mut self) -> KVNodeHandle<&'a mut Node<K, V>> {
|
||||
KVNodeHandle {
|
||||
node: &mut *self.node,
|
||||
index: self.index
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<K, V> Node<K, V> {
|
||||
/// Returns the mutable handle pointing to the key/value pair at a given index.
|
||||
///
|
||||
/// # Panics (in debug build)
|
||||
///
|
||||
/// Panics if the given index is out of bounds.
|
||||
pub fn kv_handle(&mut self, index: uint) -> KVNodeHandle<&mut Node<K, V>> {
|
||||
pub fn kv_handle(&mut self, index: uint) -> Handle<&mut Node<K, V>, KV, LeafOrInternal> {
|
||||
// Necessary for correctness, but in a private module
|
||||
debug_assert!(index < self.len(), "kv_handle index out of bounds");
|
||||
KVNodeHandle {
|
||||
node: self,
|
||||
index: index
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the mutable handle pointing to the edge at a given index.
|
||||
///
|
||||
/// # Panics (in debug build)
|
||||
///
|
||||
/// Panics if the given index is out of bounds.
|
||||
pub fn edge_handle(&mut self, index: uint) -> EdgeNodeHandle<&mut Node<K, V>> {
|
||||
// Necessary for correctness, but in a private module
|
||||
debug_assert!(index <= self.len(), "edge_handle index out of bounds");
|
||||
EdgeNodeHandle {
|
||||
Handle {
|
||||
node: self,
|
||||
index: index
|
||||
}
|
||||
@ -1100,7 +1067,7 @@ impl<K, V> Node<K, V> {
|
||||
}
|
||||
|
||||
/// When a node has no keys or values and only a single edge, extract that edge.
|
||||
pub fn into_edge(&mut self) {
|
||||
pub fn hoist_lone_child(&mut self) {
|
||||
// Necessary for correctness, but in a private module
|
||||
debug_assert!(self.len() == 0);
|
||||
debug_assert!(!self.is_leaf());
|
||||
|
Loading…
x
Reference in New Issue
Block a user