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;
/// 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> {
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;
}
}
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;
}
}
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))
}
- };
+ }
}
}
});
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))
+ }
}
}
});
/// 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
}
}
- 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
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.
/// 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 }
)
}
}
+ }
+ 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
};
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;
}
}
}
}
+ }
+
+ 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
/// 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();
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();
+ }
}
}
}
}
}
- 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.
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));
- }
- };
+ }
}
}
});
pub use self::InsertionResult::*;
pub use self::SearchResult::*;
+pub use self::ForceResult::*;
pub use self::TraversalItem::*;
use core::prelude::*;
/// 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.
}
}
-/// 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
/// }
/// ```
#[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,
// 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
})
}
}
-impl<'a, K: 'a, V: 'a> EdgeNodeHandle<&'a Node<K, V>> {
+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.
- ///
- /// 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))
- }
+ pub fn into_edge(self) -> &'a Node<K, V> {
+ unsafe {
+ self.node.edges().unsafe_get(self.index)
}
}
}
-impl<'a, K: 'a, V: 'a> EdgeNodeHandle<&'a mut Node<K, V>> {
+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.
- ///
- /// 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))
- }
+ 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>>> 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`.
- pub fn node(&self) -> &Node<K, V> {
- &*self.node
- }
-
+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.
///
/// 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 _ })
(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 {
}
}
- /// 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) {
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`.
}
}
-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`.
)
}
}
-}
-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
+ /// 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, 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
// }
}
-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.
}
}
-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
}
/// 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
// 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),
// 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
// 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),
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
}
}
/// 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());