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:
bors 2014-12-16 11:02:56 +00:00
commit 59287b0170
2 changed files with 270 additions and 309 deletions

View file

@ -20,7 +20,10 @@
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 @@ pub fn get<Sized? Q>(&self, key: &Q) -> Option<&V> where Q: BorrowFrom<K> + Ord
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 @@ pub fn get_mut<Sized? Q>(&mut self, key: &Q) -> Option<&mut V> where Q: BorrowFr
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 @@ pub fn insert(&mut self, mut key: K, mut value: V) -> Option<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 @@ pub fn remove<Sized? Q>(&mut self, key: &Q) -> Option<V> where Q: BorrowFrom<K>
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 @@ fn deref_mut(&mut self) -> &mut T {
}
}
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 @@ pub struct Pusher<'id, 'a, K:'a, V:'a> {
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 @@ impl<'id, 'a, K, V> Pusher<'id, 'a, K, V> {
/// 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 @@ pub fn into_top(mut self) -> &'a mut V {
)
}
}
}
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 @@ pub fn remove(mut self) -> V {
};
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 @@ pub fn remove(mut self) -> V {
}
}
}
}
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 @@ pub fn remove(mut self) -> V {
/// 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 @@ fn leafify(&mut self) {
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 @@ fn leafify(&mut self) {
}
}
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 @@ pub fn entry<'a>(&'a mut self, mut key: K) -> Entry<'a, 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));
}
};
}
}
}
});

View file

@ -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 @@ fn clone(&self) -> 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 @@ fn clone(&self) -> 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 @@ pub fn search<Sized? Q, NodeRef: Deref<Node<K, V>>>(node: NodeRef, key: &Q)
// 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 @@ pub fn is_full(&self) -> bool {
}
}
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 @@ pub fn edge_mut(&mut self) -> Option<&mut Node<K, V>> {
/// 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 @@ pub fn insert_as_leaf(mut self, key: K, value: V) ->
(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 @@ pub fn handle_underflow(mut self) {
}
}
/// 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 @@ unsafe fn handle_underflow_to_right(&mut self) {
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 @@ pub fn into_kv(self) -> (&'a K, &'a 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 @@ pub fn into_kv_mut(self) -> (&'a mut K, &'a mut 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 @@ pub fn node(&'a self) -> &'a Node<K, V> {
// }
}
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 @@ pub fn val_mut(&'a mut self) -> &'a mut V {
}
}
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 @@ pub fn left_edge<'a>(&'a mut self) -> EdgeNodeHandle<&'a mut Node<K, V>> {
/// 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 @@ unsafe fn steal_rightward(&mut self) {
// 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 @@ unsafe fn steal_leftward(&mut self) {
// 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 @@ unsafe fn steal_leftward(&mut self) {
// 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 @@ unsafe fn merge_children(mut self) {
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 @@ pub fn into_iter(self) -> MoveTraversal<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());