// Copyright 2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. // This implementation is largely based on the high-level description and analysis of B-Trees // found in *Open Data Structures* (ODS). Although our implementation does not use any of // the source found in ODS, if one wishes to review the high-level design of this structure, it // can be freely downloaded at http://opendatastructures.org/. Its contents are as of this // writing (August 2014) freely licensed under the following Creative Commons Attribution // License: [CC BY 2.5 CA](http://creativecommons.org/licenses/by/2.5/ca/). use self::Entry::*; use core::cmp::Ordering; use core::fmt::Debug; use core::hash::{Hash, Hasher}; use core::iter::{Map, FromIterator}; use core::ops::Index; use core::{fmt, mem, usize}; use Bound::{self, Included, Excluded, Unbounded}; use borrow::Borrow; use vec_deque::VecDeque; use self::Continuation::{Continue, Finished}; use self::StackOp::*; use super::node::ForceResult::{Leaf, Internal}; use super::node::TraversalItem::{self, Elem, Edge}; use super::node::{Traversal, MutTraversal, MoveTraversal}; use super::node::{self, Node, Found, GoDown}; /// A map based on a B-Tree. /// /// B-Trees represent a fundamental compromise between cache-efficiency and actually minimizing /// the amount of work performed in a search. In theory, a binary search tree (BST) is the optimal /// choice for a sorted map, as a perfectly balanced BST performs the theoretical minimum amount of /// comparisons necessary to find an element (log2n). However, in practice the way this /// is done is *very* inefficient for modern computer architectures. In particular, every element /// is stored in its own individually heap-allocated node. This means that every single insertion /// triggers a heap-allocation, and every single comparison should be a cache-miss. Since these /// are both notably expensive things to do in practice, we are forced to at very least reconsider /// the BST strategy. /// /// A B-Tree instead makes each node contain B-1 to 2B-1 elements in a contiguous array. By doing /// this, we reduce the number of allocations by a factor of B, and improve cache efficiency in /// searches. However, this does mean that searches will have to do *more* comparisons on average. /// The precise number of comparisons depends on the node search strategy used. For optimal cache /// efficiency, one could search the nodes linearly. For optimal comparisons, one could search /// the node using binary search. As a compromise, one could also perform a linear search /// that initially only checks every ith element for some choice of i. /// /// Currently, our implementation simply performs naive linear search. This provides excellent /// performance on *small* nodes of elements which are cheap to compare. However in the future we /// would like to further explore choosing the optimal search strategy based on the choice of B, /// and possibly other factors. Using linear search, searching for a random element is expected /// to take O(B logBn) comparisons, which is generally worse than a BST. In practice, /// however, performance is excellent. /// /// It is a logic error for a key to be modified in such a way that the key's ordering relative to /// any other key, as determined by the `Ord` trait, changes while it is in the map. This is /// normally only possible through `Cell`, `RefCell`, global state, I/O, or unsafe code. #[derive(Clone)] #[stable(feature = "rust1", since = "1.0.0")] pub struct BTreeMap { root: Node, length: usize, depth: usize, b: usize, } /// An abstract base over-which all other BTree iterators are built. #[derive(Clone)] struct AbsIter { traversals: VecDeque, size: usize, } /// An iterator over a BTreeMap's entries. #[stable(feature = "rust1", since = "1.0.0")] pub struct Iter<'a, K: 'a, V: 'a> { inner: AbsIter> } /// A mutable iterator over a BTreeMap's entries. #[stable(feature = "rust1", since = "1.0.0")] pub struct IterMut<'a, K: 'a, V: 'a> { inner: AbsIter> } /// An owning iterator over a BTreeMap's entries. #[stable(feature = "rust1", since = "1.0.0")] pub struct IntoIter { inner: AbsIter> } /// An iterator over a BTreeMap's keys. #[stable(feature = "rust1", since = "1.0.0")] pub struct Keys<'a, K: 'a, V: 'a> { inner: Map, fn((&'a K, &'a V)) -> &'a K> } /// An iterator over a BTreeMap's values. #[stable(feature = "rust1", since = "1.0.0")] pub struct Values<'a, K: 'a, V: 'a> { inner: Map, fn((&'a K, &'a V)) -> &'a V> } /// An iterator over a sub-range of BTreeMap's entries. pub struct Range<'a, K: 'a, V: 'a> { inner: AbsIter> } /// A mutable iterator over a sub-range of BTreeMap's entries. pub struct RangeMut<'a, K: 'a, V: 'a> { inner: AbsIter> } /// A view into a single entry in a map, which may either be vacant or occupied. #[stable(feature = "rust1", since = "1.0.0")] pub enum Entry<'a, K:'a, V:'a> { /// A vacant Entry #[stable(feature = "rust1", since = "1.0.0")] Vacant(VacantEntry<'a, K, V>), /// An occupied Entry #[stable(feature = "rust1", since = "1.0.0")] Occupied(OccupiedEntry<'a, K, V>), } /// A vacant Entry. #[stable(feature = "rust1", since = "1.0.0")] pub struct VacantEntry<'a, K:'a, V:'a> { key: K, stack: stack::SearchStack<'a, K, V, node::handle::Edge, node::handle::Leaf>, } /// An occupied Entry. #[stable(feature = "rust1", since = "1.0.0")] pub struct OccupiedEntry<'a, K:'a, V:'a> { stack: stack::SearchStack<'a, K, V, node::handle::KV, node::handle::LeafOrInternal>, } impl BTreeMap { /// Makes a new empty BTreeMap with a reasonable choice for B. #[stable(feature = "rust1", since = "1.0.0")] #[allow(deprecated)] pub fn new() -> BTreeMap { //FIXME(Gankro): Tune this as a function of size_of? BTreeMap::with_b(6) } /// Makes a new empty BTreeMap with the given B. /// /// B cannot be less than 2. #[unstable(feature = "btree_b", reason = "probably want this to be on the type, eventually", issue = "27795")] #[deprecated(since = "1.4.0", reason = "niche API")] pub fn with_b(b: usize) -> BTreeMap { assert!(b > 1, "B must be greater than 1"); BTreeMap { length: 0, depth: 1, root: Node::make_leaf_root(b), b: b, } } /// Clears the map, removing all values. /// /// # Examples /// /// ``` /// use std::collections::BTreeMap; /// /// let mut a = BTreeMap::new(); /// a.insert(1, "a"); /// a.clear(); /// assert!(a.is_empty()); /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[allow(deprecated)] pub fn clear(&mut self) { let b = self.b; // avoid recursive destructors by manually traversing the tree for _ in mem::replace(self, BTreeMap::with_b(b)) {}; } // Searching in a B-Tree is pretty straightforward. // // Start at the root. Try to find the key in the current node. If we find it, return it. // If it's not in there, follow the edge *before* the smallest key larger than // the search key. If no such key exists (they're *all* smaller), then just take the last // edge in the node. If we're in a leaf and we don't find our key, then it's not // in the tree. /// Returns a reference to the value corresponding to the key. /// /// The key may be any borrowed form of the map's key type, but the ordering /// on the borrowed form *must* match the ordering on the key type. /// /// # Examples /// /// ``` /// use std::collections::BTreeMap; /// /// let mut map = BTreeMap::new(); /// map.insert(1, "a"); /// assert_eq!(map.get(&1), Some(&"a")); /// assert_eq!(map.get(&2), None); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn get(&self, key: &Q) -> Option<&V> where K: Borrow, Q: Ord { let mut cur_node = &self.root; loop { match Node::search(cur_node, key) { Found(handle) => return Some(handle.into_kv().1), GoDown(handle) => match handle.force() { Leaf(_) => return None, Internal(internal_handle) => { cur_node = internal_handle.into_edge(); continue; } } } } } /// Returns true if the map contains a value for the specified key. /// /// The key may be any borrowed form of the map's key type, but the ordering /// on the borrowed form *must* match the ordering on the key type. /// /// # Examples /// /// ``` /// use std::collections::BTreeMap; /// /// let mut map = BTreeMap::new(); /// map.insert(1, "a"); /// assert_eq!(map.contains_key(&1), true); /// assert_eq!(map.contains_key(&2), false); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn contains_key(&self, key: &Q) -> bool where K: Borrow, Q: Ord { self.get(key).is_some() } /// Returns a mutable reference to the value corresponding to the key. /// /// The key may be any borrowed form of the map's key type, but the ordering /// on the borrowed form *must* match the ordering on the key type. /// /// # Examples /// /// ``` /// use std::collections::BTreeMap; /// /// let mut map = BTreeMap::new(); /// map.insert(1, "a"); /// if let Some(x) = map.get_mut(&1) { /// *x = "b"; /// } /// assert_eq!(map[&1], "b"); /// ``` // See `get` for implementation notes, this is basically a copy-paste with mut's added #[stable(feature = "rust1", since = "1.0.0")] pub fn get_mut(&mut self, key: &Q) -> Option<&mut V> where K: Borrow, Q: Ord { // temp_node is a Borrowck hack for having a mutable value outlive a loop iteration let mut temp_node = &mut self.root; loop { let cur_node = temp_node; match Node::search(cur_node, key) { Found(handle) => return Some(handle.into_kv_mut().1), GoDown(handle) => match handle.force() { Leaf(_) => return None, Internal(internal_handle) => { temp_node = internal_handle.into_edge_mut(); continue; } } } } } // Insertion in a B-Tree is a bit complicated. // // First we do the same kind of search described in `find`. But we need to maintain a stack of // all the nodes/edges in our search path. If we find a match for the key we're trying to // insert, just swap the vals and return the old ones. However, when we bottom out in a leaf, // we attempt to insert our key-value pair at the same location we would want to follow another // edge. // // If the node has room, then this is done in the obvious way by shifting elements. However, // if the node itself is full, we split node into two, and give its median key-value // pair to its parent to insert the new node with. Of course, the parent may also be // full, and insertion can propagate until we reach the root. If we reach the root, and // it is *also* full, then we split the root and place the two nodes under a newly made root. // // Note that we subtly deviate from Open Data Structures in our implementation of split. // ODS describes inserting into the node *regardless* of its capacity, and then // splitting *afterwards* if it happens to be overfull. However, this is inefficient. // Instead, we split beforehand, and then insert the key-value pair into the appropriate // result node. This has two consequences: // // 1) While ODS produces a left node of size B-1, and a right node of size B, // we may potentially reverse this. However, this shouldn't effect the analysis. // // 2) While ODS may potentially return the pair we *just* inserted after // the split, we will never do this. Again, this shouldn't effect the analysis. /// Inserts a key-value pair into the map. If the key already had a value /// present in the map, that value is returned. Otherwise, `None` is returned. /// /// # Examples /// /// ``` /// use std::collections::BTreeMap; /// /// let mut map = BTreeMap::new(); /// assert_eq!(map.insert(37, "a"), None); /// assert_eq!(map.is_empty(), false); /// /// map.insert(37, "b"); /// assert_eq!(map.insert(37, "c"), Some("b")); /// assert_eq!(map[&37], "c"); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn insert(&mut self, mut key: K, mut value: V) -> Option { // This is a stack of rawptrs to nodes paired with indices, respectively // representing the nodes and edges of our search path. We have to store rawptrs // because as far as Rust is concerned, we can mutate aliased data with such a // stack. It is of course correct, but what it doesn't know is that we will only // be popping and using these ptrs one at a time in child-to-parent order. The alternative // to doing this is to take the Nodes from their parents. This actually makes // borrowck *really* happy and everything is pretty smooth. However, this creates // *tons* of pointless writes, and requires us to always walk all the way back to // the root after an insertion, even if we only needed to change a leaf. Therefore, // we accept this potential unsafety and complexity in the name of performance. // // Regardless, the actual dangerous logic is completely abstracted away from BTreeMap // by the stack module. All it can do is immutably read nodes, and ask the search stack // to proceed down some edge by index. This makes the search logic we'll be reusing in a // few different methods much neater, and of course drastically improves safety. let mut stack = stack::PartialSearchStack::new(self); loop { 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) { Found(mut handle) => { // Perfect match, swap the values and return the old one mem::swap(handle.val_mut(), &mut value); Finished(Some(value)) }, GoDown(handle) => { // We need to keep searching, try to get the search stack // to go down further match handle.force() { Leaf(leaf_handle) => { // We've reached a leaf, perform the insertion here pusher.seal(leaf_handle).insert(key, value); Finished(None) } Internal(internal_handle) => { // We've found the subtree to insert this key/value pair in, // keep searching Continue((pusher.push(internal_handle), key, value)) } } } } }); match result { Finished(ret) => return ret, Continue((new_stack, renewed_key, renewed_val)) => { stack = new_stack; key = renewed_key; value = renewed_val; } } } } // Deletion is the most complicated operation for a B-Tree. // // First we do the same kind of search described in // `find`. But we need to maintain a stack of all the nodes/edges in our search path. // If we don't find the key, then we just return `None` and do nothing. If we do find the // key, we perform two operations: remove the item, and then possibly handle underflow. // // # removing the item // If the node is a leaf, we just remove the item, and shift // any items after it back to fill the hole. // // If the node is an internal node, we *swap* the item with the smallest item in // in its right subtree (which must reside in a leaf), and then revert to the leaf // case // // # handling underflow // After removing an item, there may be too few items in the node. We want nodes // to be mostly full for efficiency, although we make an exception for the root, which // may have as few as one item. If this is the case, we may first try to steal // an item from our left or right neighbour. // // To steal from the left (right) neighbour, // we take the largest (smallest) item and child from it. We then swap the taken item // with the item in their mutual parent that separates them, and then insert the // parent's item and the taken child into the first (last) index of the underflowed node. // // However, stealing has the possibility of underflowing our neighbour. If this is the // case, we instead *merge* with our neighbour. This of course reduces the number of // children in the parent. Therefore, we also steal the item that separates the now // merged nodes, and insert it into the merged node. // // Merging may cause the parent to underflow. If this is the case, then we must repeat // the underflow handling process on the parent. If merging merges the last two children // of the root, then we replace the root with the merged node. /// Removes a key from the map, returning the value at the key if the key /// was previously in the map. /// /// The key may be any borrowed form of the map's key type, but the ordering /// on the borrowed form *must* match the ordering on the key type. /// /// # Examples /// /// ``` /// use std::collections::BTreeMap; /// /// let mut map = BTreeMap::new(); /// map.insert(1, "a"); /// assert_eq!(map.remove(&1), Some("a")); /// assert_eq!(map.remove(&1), None); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn remove(&mut self, key: &Q) -> Option where K: Borrow, Q: Ord { // See `swap` for a more thorough description of the stuff going on in here let mut stack = stack::PartialSearchStack::new(self); loop { let result = stack.with(move |pusher, node| { match Node::search(node, key) { Found(handle) => { // Perfect match. Terminate the stack here, and remove the entry Finished(Some(pusher.seal(handle).remove())) }, GoDown(handle) => { // We need to keep searching, try to go down the next edge match handle.force() { // We're at a leaf; the key isn't in here Leaf(_) => Finished(None), Internal(internal_handle) => Continue(pusher.push(internal_handle)) } } } }); match result { Finished(ret) => return ret.map(|(_, v)| v), Continue(new_stack) => stack = new_stack } } } } #[stable(feature = "rust1", since = "1.0.0")] impl IntoIterator for BTreeMap { type Item = (K, V); type IntoIter = IntoIter; /// Gets an owning iterator over the entries of the map. /// /// # Examples /// /// ``` /// use std::collections::BTreeMap; /// /// let mut map = BTreeMap::new(); /// map.insert(1, "a"); /// map.insert(2, "b"); /// map.insert(3, "c"); /// /// for (key, value) in map.into_iter() { /// println!("{}: {}", key, value); /// } /// ``` fn into_iter(self) -> IntoIter { let len = self.len(); let mut lca = VecDeque::new(); lca.push_back(Traverse::traverse(self.root)); IntoIter { inner: AbsIter { traversals: lca, size: len, } } } } #[stable(feature = "rust1", since = "1.0.0")] impl<'a, K, V> IntoIterator for &'a BTreeMap { type Item = (&'a K, &'a V); type IntoIter = Iter<'a, K, V>; fn into_iter(self) -> Iter<'a, K, V> { self.iter() } } #[stable(feature = "rust1", since = "1.0.0")] impl<'a, K, V> IntoIterator for &'a mut BTreeMap { type Item = (&'a K, &'a mut V); type IntoIter = IterMut<'a, K, V>; fn into_iter(mut self) -> IterMut<'a, K, V> { self.iter_mut() } } /// A helper enum useful for deciding whether to continue a loop since we can't /// return from a closure enum Continuation { Continue(A), Finished(B) } /// The stack module provides a safe interface for constructing and manipulating a stack of ptrs /// to nodes. By using this module much better safety guarantees can be made, and more search /// boilerplate gets cut out. mod stack { use core::marker; use core::mem; use core::ops::{Deref, DerefMut}; use super::BTreeMap; use super::super::node::{self, Node, Fit, Split, Internal, Leaf}; use super::super::node::handle; use vec::Vec; struct InvariantLifetime<'id>( marker::PhantomData<::core::cell::Cell<&'id ()>>); impl<'id> InvariantLifetime<'id> { fn new() -> InvariantLifetime<'id> { InvariantLifetime(marker::PhantomData) } } /// A generic mutable reference, identical to `&mut` except for the fact that its lifetime /// parameter is invariant. This means that wherever an `IdRef` is expected, only an `IdRef` /// with the exact requested lifetime can be used. This is in contrast to normal references, /// where `&'static` can be used in any function expecting any lifetime reference. pub struct IdRef<'id, T: 'id> { inner: &'id mut T, _marker: InvariantLifetime<'id>, } impl<'id, T> Deref for IdRef<'id, T> { type Target = T; fn deref(&self) -> &T { &*self.inner } } impl<'id, T> DerefMut for IdRef<'id, T> { fn deref_mut(&mut self) -> &mut T { &mut *self.inner } } type StackItem = node::Handle<*mut Node, handle::Edge, handle::Internal>; type Stack = Vec>; /// A `PartialSearchStack` handles the construction of a search stack. pub struct PartialSearchStack<'a, K:'a, V:'a> { map: &'a mut BTreeMap, stack: Stack, next: *mut Node, } /// 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, stack: Stack, top: node::Handle<*mut Node, Type, NodeType>, } /// A `PartialSearchStack` that doesn't hold a a reference to the next node, and is just /// just waiting for a `Handle` to that next node to be pushed. See `PartialSearchStack::with` /// for more details. pub struct Pusher<'id, 'a, K:'a, V:'a> { map: &'a mut BTreeMap, stack: Stack, _marker: InvariantLifetime<'id>, } 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. pub fn new(map: &'a mut BTreeMap) -> PartialSearchStack<'a, K, V> { let depth = map.depth; PartialSearchStack { next: &mut map.root as *mut _, map: map, stack: Vec::with_capacity(depth), } } /// Breaks up the stack into a `Pusher` and the next `Node`, allowing the given closure /// to interact with, search, and finally push the `Node` onto the stack. The passed in /// closure must be polymorphic on the `'id` lifetime parameter, as this statically /// ensures that only `Handle`s from the correct `Node` can be pushed. /// /// The reason this works is that the `Pusher` has an `'id` parameter, and will only accept /// handles with the same `'id`. The closure could only get references with that lifetime /// through its arguments or through some other `IdRef` that it has lying around. However, /// no other `IdRef` could possibly work - because the `'id` is held in an invariant /// parameter, it would need to have precisely the correct lifetime, which would mean that /// at least one of the calls to `with` wouldn't be properly polymorphic, wanting a /// specific lifetime instead of the one that `with` chooses to give it. /// /// See also Haskell's `ST` monad, which uses a similar trick. pub fn with FnOnce(Pusher<'id, 'a, K, V>, IdRef<'id, Node>) -> T>(self, closure: F) -> T { let pusher = Pusher { map: self.map, stack: self.stack, _marker: InvariantLifetime::new(), }; let node = IdRef { inner: unsafe { &mut *self.next }, _marker: InvariantLifetime::new(), }; closure(pusher, node) } } 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: node::Handle>, handle::Edge, handle::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 a SearchStack. pub fn seal (self, mut handle: node::Handle>, Type, NodeType>) -> SearchStack<'a, K, V, Type, NodeType> { SearchStack { map: self.map, stack: self.stack, top: handle.as_raw(), } } } impl<'a, K, V, NodeType> SearchStack<'a, K, V, handle::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 } } /// Gets a mutable reference to the value the stack points to. pub fn peek_mut(&mut self) -> &mut V { unsafe { self.top.from_raw_mut().into_kv_mut().1 } } /// Converts the stack into a mutable reference to the value it points to, with a lifetime /// tied to the original tree. pub fn into_top(mut self) -> &'a mut V { unsafe { &mut *(self.top.from_raw_mut().val_mut() as *mut V) } } } impl<'a, K, V> SearchStack<'a, K, V, handle::KV, handle::Leaf> { /// Removes the key and value in the top element of the stack, then handles underflows as /// described in BTree's pop function. fn remove_leaf(mut self) -> (K, 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 // to avoid ownership issues. let (key_val, mut underflow) = unsafe { let key_val = self.top.from_raw_mut().remove_as_leaf(); let underflow = self.top.from_raw().node().is_underfull(); (key_val, underflow) }; loop { 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 self.map.root.is_empty() && !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. self.map.depth -= 1; self.map.root.hoist_lone_child(); } return key_val; } Some(mut handle) => { if underflow { // Underflow! Handle it! unsafe { handle.from_raw_mut().handle_underflow(); underflow = handle.from_raw().node().is_underfull(); } } else { // All done! return key_val; } } } } } } impl<'a, K, V> SearchStack<'a, K, V, handle::KV, handle::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) -> (K, 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 /// for that same key that *does* terminates at a leaf. If the mutation occurs, then this /// 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 into_leaf(mut self) -> SearchStack<'a, K, V, handle::KV, handle::Leaf> { unsafe { let mut top_raw = self.top; let mut top = top_raw.from_raw_mut(); let key_ptr = top.key_mut() as *mut _; let val_ptr = top.val_mut() as *mut _; // Try to go into the right subtree of the found key to find its successor 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() } } 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_handle.as_raw()); let mut temp_node = right_handle.edge_mut(); loop { // Walk into the smallest subtree of this node let node = temp_node; 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> SearchStack<'a, K, V, handle::Edge, handle::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. /// /// Assumes that the stack represents a search path from the root to a leaf. /// /// An &mut V is returned to the inserted value, for callers that want a reference to this. pub fn insert(mut self, key: K, val: V) -> &'a mut V { unsafe { self.map.length += 1; // Insert the key and value into the leaf at the top of the stack let (mut insertion, inserted_ptr) = self.top.from_raw_mut() .insert_as_leaf(key, val); loop { match insertion { Fit => { // The last insertion went off without a hitch, no splits! We can stop // inserting now. return &mut *inserted_ptr; } Split(key, val, right) => match self.stack.pop() { // The last insertion triggered a split, so get the next element on the // stack to recursively insert the split node into. None => { // The stack was empty; we've split the root, and need to make a // a new one. This is done in-place because we can't move the // root out of a reference to the tree. Node::make_internal_root(&mut self.map.root, self.map.b, key, val, right); self.map.depth += 1; return &mut *inserted_ptr; } Some(mut handle) => { // The stack wasn't empty, do the insertion and recurse insertion = handle.from_raw_mut() .insert_as_internal(key, val, right); continue; } } } } } } } } #[stable(feature = "rust1", since = "1.0.0")] impl FromIterator<(K, V)> for BTreeMap { fn from_iter>(iter: T) -> BTreeMap { let mut map = BTreeMap::new(); map.extend(iter); map } } #[stable(feature = "rust1", since = "1.0.0")] impl Extend<(K, V)> for BTreeMap { #[inline] fn extend>(&mut self, iter: T) { for (k, v) in iter { self.insert(k, v); } } } #[stable(feature = "extend_ref", since = "1.2.0")] impl<'a, K: Ord + Copy, V: Copy> Extend<(&'a K, &'a V)> for BTreeMap { fn extend>(&mut self, iter: I) { self.extend(iter.into_iter().map(|(&key, &value)| (key, value))); } } #[stable(feature = "rust1", since = "1.0.0")] impl Hash for BTreeMap { fn hash(&self, state: &mut H) { for elt in self { elt.hash(state); } } } #[stable(feature = "rust1", since = "1.0.0")] impl Default for BTreeMap { #[stable(feature = "rust1", since = "1.0.0")] fn default() -> BTreeMap { BTreeMap::new() } } #[stable(feature = "rust1", since = "1.0.0")] impl PartialEq for BTreeMap { fn eq(&self, other: &BTreeMap) -> bool { self.len() == other.len() && self.iter().zip(other).all(|(a, b)| a == b) } } #[stable(feature = "rust1", since = "1.0.0")] impl Eq for BTreeMap {} #[stable(feature = "rust1", since = "1.0.0")] impl PartialOrd for BTreeMap { #[inline] fn partial_cmp(&self, other: &BTreeMap) -> Option { self.iter().partial_cmp(other.iter()) } } #[stable(feature = "rust1", since = "1.0.0")] impl Ord for BTreeMap { #[inline] fn cmp(&self, other: &BTreeMap) -> Ordering { self.iter().cmp(other.iter()) } } #[stable(feature = "rust1", since = "1.0.0")] impl Debug for BTreeMap { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_map().entries(self.iter()).finish() } } #[stable(feature = "rust1", since = "1.0.0")] impl<'a, K: Ord, Q: ?Sized, V> Index<&'a Q> for BTreeMap where K: Borrow, Q: Ord { type Output = V; #[inline] fn index(&self, key: &Q) -> &V { self.get(key).expect("no entry found for key") } } /// Genericises over how to get the correct type of iterator from the correct type /// of Node ownership. trait Traverse { fn traverse(node: N) -> Self; } impl<'a, K, V> Traverse<&'a Node> for Traversal<'a, K, V> { fn traverse(node: &'a Node) -> Traversal<'a, K, V> { node.iter() } } impl<'a, K, V> Traverse<&'a mut Node> for MutTraversal<'a, K, V> { fn traverse(node: &'a mut Node) -> MutTraversal<'a, K, V> { node.iter_mut() } } impl Traverse> for MoveTraversal { fn traverse(node: Node) -> MoveTraversal { node.into_iter() } } /// Represents an operation to perform inside the following iterator methods. /// This is necessary to use in `next` because we want to modify `self.traversals` inside /// a match that borrows it. Similarly in `next_back`. Instead, we use this enum to note /// what we want to do, and do it after the match. enum StackOp { Push(T), Pop, } impl Iterator for AbsIter where T: DoubleEndedIterator> + Traverse, { type Item = (K, V); // Our iterator represents a queue of all ancestors of elements we have // yet to yield, from smallest to largest. Note that the design of these // iterators permits an *arbitrary* initial pair of min and max, making // these arbitrary sub-range iterators. fn next(&mut self) -> Option<(K, V)> { loop { // We want the smallest element, so try to get the back of the queue let op = match self.traversals.back_mut() { None => return None, // The queue wasn't empty, so continue along the node in its head Some(iter) => match iter.next() { // The head is empty, so Pop it off and continue the process None => Pop, // The head yielded an edge, so make that the new head Some(Edge(next)) => Push(Traverse::traverse(next)), // The head yielded an entry, so yield that Some(Elem(kv)) => { self.size -= 1; return Some(kv) } } }; // Handle any operation as necessary, without a conflicting borrow of the queue match op { Push(item) => { self.traversals.push_back(item); }, Pop => { self.traversals.pop_back(); }, } } } fn size_hint(&self) -> (usize, Option) { (self.size, Some(self.size)) } } impl DoubleEndedIterator for AbsIter where T: DoubleEndedIterator> + Traverse, { // next_back is totally symmetric to next #[inline] fn next_back(&mut self) -> Option<(K, V)> { loop { let op = match self.traversals.front_mut() { None => return None, Some(iter) => match iter.next_back() { None => Pop, Some(Edge(next)) => Push(Traverse::traverse(next)), Some(Elem(kv)) => { self.size -= 1; return Some(kv) } } }; match op { Push(item) => { self.traversals.push_front(item); }, Pop => { self.traversals.pop_front(); } } } } } impl<'a, K, V> Clone for Iter<'a, K, V> { fn clone(&self) -> Iter<'a, K, V> { Iter { inner: self.inner.clone() } } } #[stable(feature = "rust1", since = "1.0.0")] impl<'a, K, V> Iterator for Iter<'a, K, V> { type Item = (&'a K, &'a V); fn next(&mut self) -> Option<(&'a K, &'a V)> { self.inner.next() } fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } } #[stable(feature = "rust1", since = "1.0.0")] impl<'a, K, V> DoubleEndedIterator for Iter<'a, K, V> { fn next_back(&mut self) -> Option<(&'a K, &'a V)> { self.inner.next_back() } } #[stable(feature = "rust1", since = "1.0.0")] impl<'a, K, V> ExactSizeIterator for Iter<'a, K, V> {} #[stable(feature = "rust1", since = "1.0.0")] impl<'a, K, V> Iterator for IterMut<'a, K, V> { type Item = (&'a K, &'a mut V); fn next(&mut self) -> Option<(&'a K, &'a mut V)> { self.inner.next() } fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } } #[stable(feature = "rust1", since = "1.0.0")] impl<'a, K, V> DoubleEndedIterator for IterMut<'a, K, V> { fn next_back(&mut self) -> Option<(&'a K, &'a mut V)> { self.inner.next_back() } } #[stable(feature = "rust1", since = "1.0.0")] impl<'a, K, V> ExactSizeIterator for IterMut<'a, K, V> {} #[stable(feature = "rust1", since = "1.0.0")] impl Iterator for IntoIter { type Item = (K, V); fn next(&mut self) -> Option<(K, V)> { self.inner.next() } fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } } #[stable(feature = "rust1", since = "1.0.0")] impl DoubleEndedIterator for IntoIter { fn next_back(&mut self) -> Option<(K, V)> { self.inner.next_back() } } #[stable(feature = "rust1", since = "1.0.0")] impl ExactSizeIterator for IntoIter {} impl<'a, K, V> Clone for Keys<'a, K, V> { fn clone(&self) -> Keys<'a, K, V> { Keys { inner: self.inner.clone() } } } #[stable(feature = "rust1", since = "1.0.0")] impl<'a, K, V> Iterator for Keys<'a, K, V> { type Item = &'a K; fn next(&mut self) -> Option<(&'a K)> { self.inner.next() } fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } } #[stable(feature = "rust1", since = "1.0.0")] impl<'a, K, V> DoubleEndedIterator for Keys<'a, K, V> { fn next_back(&mut self) -> Option<(&'a K)> { self.inner.next_back() } } #[stable(feature = "rust1", since = "1.0.0")] impl<'a, K, V> ExactSizeIterator for Keys<'a, K, V> {} impl<'a, K, V> Clone for Values<'a, K, V> { fn clone(&self) -> Values<'a, K, V> { Values { inner: self.inner.clone() } } } #[stable(feature = "rust1", since = "1.0.0")] impl<'a, K, V> Iterator for Values<'a, K, V> { type Item = &'a V; fn next(&mut self) -> Option<(&'a V)> { self.inner.next() } fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } } #[stable(feature = "rust1", since = "1.0.0")] impl<'a, K, V> DoubleEndedIterator for Values<'a, K, V> { fn next_back(&mut self) -> Option<(&'a V)> { self.inner.next_back() } } #[stable(feature = "rust1", since = "1.0.0")] impl<'a, K, V> ExactSizeIterator for Values<'a, K, V> {} impl<'a, K, V> Clone for Range<'a, K, V> { fn clone(&self) -> Range<'a, K, V> { Range { inner: self.inner.clone() } } } impl<'a, K, V> Iterator for Range<'a, K, V> { type Item = (&'a K, &'a V); fn next(&mut self) -> Option<(&'a K, &'a V)> { self.inner.next() } } impl<'a, K, V> DoubleEndedIterator for Range<'a, K, V> { fn next_back(&mut self) -> Option<(&'a K, &'a V)> { self.inner.next_back() } } impl<'a, K, V> Iterator for RangeMut<'a, K, V> { type Item = (&'a K, &'a mut V); fn next(&mut self) -> Option<(&'a K, &'a mut V)> { self.inner.next() } } impl<'a, K, V> DoubleEndedIterator for RangeMut<'a, K, V> { fn next_back(&mut self) -> Option<(&'a K, &'a mut V)> { self.inner.next_back() } } impl<'a, K: Ord, V> Entry<'a, K, V> { #[stable(feature = "rust1", since = "1.0.0")] /// Ensures a value is in the entry by inserting the default if empty, and returns /// a mutable reference to the value in the entry. pub fn or_insert(self, default: V) -> &'a mut V { match self { Occupied(entry) => entry.into_mut(), Vacant(entry) => entry.insert(default), } } #[stable(feature = "rust1", since = "1.0.0")] /// Ensures a value is in the entry by inserting the result of the default function if empty, /// and returns a mutable reference to the value in the entry. pub fn or_insert_with V>(self, default: F) -> &'a mut V { match self { Occupied(entry) => entry.into_mut(), Vacant(entry) => entry.insert(default()), } } } impl<'a, K: Ord, V> VacantEntry<'a, K, V> { /// Sets the value of the entry with the VacantEntry's key, /// and returns a mutable reference to it. #[stable(feature = "rust1", since = "1.0.0")] pub fn insert(self, value: V) -> &'a mut V { self.stack.insert(self.key, value) } } impl<'a, K: Ord, V> OccupiedEntry<'a, K, V> { /// Gets a reference to the value in the entry. #[stable(feature = "rust1", since = "1.0.0")] pub fn get(&self) -> &V { self.stack.peek() } /// Gets a mutable reference to the value in the entry. #[stable(feature = "rust1", since = "1.0.0")] pub fn get_mut(&mut self) -> &mut V { self.stack.peek_mut() } /// Converts the entry into a mutable reference to its value. #[stable(feature = "rust1", since = "1.0.0")] pub fn into_mut(self) -> &'a mut V { self.stack.into_top() } /// Sets the value of the entry with the OccupiedEntry's key, /// and returns the entry's old value. #[stable(feature = "rust1", since = "1.0.0")] pub fn insert(&mut self, mut value: V) -> V { mem::swap(self.stack.peek_mut(), &mut value); value } /// Takes the value of the entry out of the map, and returns it. #[stable(feature = "rust1", since = "1.0.0")] pub fn remove(self) -> V { self.stack.remove().1 } } impl BTreeMap { /// Gets an iterator over the entries of the map. /// /// # Examples /// /// ``` /// use std::collections::BTreeMap; /// /// let mut map = BTreeMap::new(); /// map.insert(1, "a"); /// map.insert(2, "b"); /// map.insert(3, "c"); /// /// for (key, value) in map.iter() { /// println!("{}: {}", key, value); /// } /// /// let (first_key, first_value) = map.iter().next().unwrap(); /// assert_eq!((*first_key, *first_value), (1, "a")); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn iter(&self) -> Iter { let len = self.len(); // NB. The initial capacity for ringbuf is large enough to avoid reallocs in many cases. let mut lca = VecDeque::new(); lca.push_back(Traverse::traverse(&self.root)); Iter { inner: AbsIter { traversals: lca, size: len, } } } /// Gets a mutable iterator over the entries of the map. /// /// # Examples /// /// ``` /// use std::collections::BTreeMap; /// /// let mut map = BTreeMap::new(); /// map.insert("a", 1); /// map.insert("b", 2); /// map.insert("c", 3); /// /// // add 10 to the value if the key isn't "a" /// for (key, value) in map.iter_mut() { /// if key != &"a" { /// *value += 10; /// } /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn iter_mut(&mut self) -> IterMut { let len = self.len(); let mut lca = VecDeque::new(); lca.push_back(Traverse::traverse(&mut self.root)); IterMut { inner: AbsIter { traversals: lca, size: len, } } } /// Gets an iterator over the keys of the map. /// /// # Examples /// /// ``` /// use std::collections::BTreeMap; /// /// let mut a = BTreeMap::new(); /// a.insert(1, "a"); /// a.insert(2, "b"); /// /// let keys: Vec<_> = a.keys().cloned().collect(); /// assert_eq!(keys, [1, 2]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn keys<'a>(&'a self) -> Keys<'a, K, V> { fn first((a, _): (A, B)) -> A { a } let first: fn((&'a K, &'a V)) -> &'a K = first; // coerce to fn pointer Keys { inner: self.iter().map(first) } } /// Gets an iterator over the values of the map. /// /// # Examples /// /// ``` /// use std::collections::BTreeMap; /// /// let mut a = BTreeMap::new(); /// a.insert(1, "a"); /// a.insert(2, "b"); /// /// let values: Vec<&str> = a.values().cloned().collect(); /// assert_eq!(values, ["a", "b"]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn values<'a>(&'a self) -> Values<'a, K, V> { fn second((_, b): (A, B)) -> B { b } let second: fn((&'a K, &'a V)) -> &'a V = second; // coerce to fn pointer Values { inner: self.iter().map(second) } } /// Returns the number of elements in the map. /// /// # Examples /// /// ``` /// use std::collections::BTreeMap; /// /// let mut a = BTreeMap::new(); /// assert_eq!(a.len(), 0); /// a.insert(1, "a"); /// assert_eq!(a.len(), 1); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn len(&self) -> usize { self.length } /// Returns true if the map contains no elements. /// /// # Examples /// /// ``` /// use std::collections::BTreeMap; /// /// let mut a = BTreeMap::new(); /// assert!(a.is_empty()); /// a.insert(1, "a"); /// assert!(!a.is_empty()); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn is_empty(&self) -> bool { self.len() == 0 } } macro_rules! range_impl { ($root:expr, $min:expr, $max:expr, $as_slices_internal:ident, $iter:ident, $Range:ident, $edges:ident, [$($mutability:ident)*]) => ( { // A deque that encodes two search paths containing (left-to-right): // a series of truncated-from-the-left iterators, the LCA's doubly-truncated iterator, // and a series of truncated-from-the-right iterators. let mut traversals = VecDeque::new(); let (root, min, max) = ($root, $min, $max); let mut leftmost = None; let mut rightmost = None; match (&min, &max) { (&Unbounded, &Unbounded) => { traversals.push_back(Traverse::traverse(root)) } (&Unbounded, &Included(_)) | (&Unbounded, &Excluded(_)) => { rightmost = Some(root); } (&Included(_), &Unbounded) | (&Excluded(_), &Unbounded) => { leftmost = Some(root); } (&Included(min_key), &Included(max_key)) | (&Included(min_key), &Excluded(max_key)) | (&Excluded(min_key), &Included(max_key)) | (&Excluded(min_key), &Excluded(max_key)) => { // lca represents the Lowest Common Ancestor, above which we never // walk, since everything else is outside the range to iterate. // ___________________ // |__0_|_80_|_85_|_90_| (root) // | | | | | // | // v // ___________________ // |__5_|_15_|_30_|_73_| // | | | | | // | // v // ___________________ // |_33_|_58_|_63_|_68_| lca for the range [41, 65] // | |\___|___/| | iterator at traversals[2] // | | // | v // v rightmost // leftmost let mut is_leaf = root.is_leaf(); let mut lca = root.$as_slices_internal(); loop { let slice = lca.slice_from(min_key).slice_to(max_key); if let [ref $($mutability)* edge] = slice.edges { // Follow the only edge that leads the node that covers the range. is_leaf = edge.is_leaf(); lca = edge.$as_slices_internal(); } else { let mut iter = slice.$iter(); if is_leaf { leftmost = None; rightmost = None; } else { // Only change the state of nodes with edges. leftmost = iter.next_edge_item(); rightmost = iter.next_edge_item_back(); } traversals.push_back(iter); break; } } } } // Keep narrowing the range by going down. // ___________________ // |_38_|_43_|_48_|_53_| // | |____|____|____/ iterator at traversals[1] // | // v // ___________________ // |_39_|_40_|_41_|_42_| (leaf, the last leftmost) // \_________| iterator at traversals[0] match min { Included(key) | Excluded(key) => while let Some(left) = leftmost { let is_leaf = left.is_leaf(); let mut iter = left.$as_slices_internal().slice_from(key).$iter(); leftmost = if is_leaf { None } else { // Only change the state of nodes with edges. iter.next_edge_item() }; traversals.push_back(iter); }, _ => {} } // If the leftmost iterator starts with an element, then it was an exact match. if let (Excluded(_), Some(leftmost_iter)) = (min, traversals.back_mut()) { // Drop this excluded element. `next_kv_item` has no effect when // the next item is an edge. leftmost_iter.next_kv_item(); } // The code for the right side is similar. match max { Included(key) | Excluded(key) => while let Some(right) = rightmost { let is_leaf = right.is_leaf(); let mut iter = right.$as_slices_internal().slice_to(key).$iter(); rightmost = if is_leaf { None } else { iter.next_edge_item_back() }; traversals.push_front(iter); }, _ => {} } if let (Excluded(_), Some(rightmost_iter)) = (max, traversals.front_mut()) { rightmost_iter.next_kv_item_back(); } $Range { inner: AbsIter { traversals: traversals, size: usize::MAX, // unused } } } ) } impl BTreeMap { /// Constructs a double-ended iterator over a sub-range of elements in the map, starting /// at min, and ending at max. If min is `Unbounded`, then it will be treated as "negative /// infinity", and if max is `Unbounded`, then it will be treated as "positive infinity". /// Thus range(Unbounded, Unbounded) will yield the whole collection. /// /// # Examples /// /// ``` /// #![feature(btree_range, collections_bound)] /// /// use std::collections::BTreeMap; /// use std::collections::Bound::{Included, Unbounded}; /// /// let mut map = BTreeMap::new(); /// map.insert(3, "a"); /// map.insert(5, "b"); /// map.insert(8, "c"); /// for (&key, &value) in map.range(Included(&4), Included(&8)) { /// println!("{}: {}", key, value); /// } /// assert_eq!(Some((&5, &"b")), map.range(Included(&4), Unbounded).next()); /// ``` #[unstable(feature = "btree_range", reason = "matches collection reform specification, waiting for dust to settle", issue = "27787")] pub fn range(&self, min: Bound<&Min>, max: Bound<&Max>) -> Range where K: Borrow + Borrow, { range_impl!(&self.root, min, max, as_slices_internal, iter, Range, edges, []) } /// Constructs a mutable double-ended iterator over a sub-range of elements in the map, starting /// at min, and ending at max. If min is `Unbounded`, then it will be treated as "negative /// infinity", and if max is `Unbounded`, then it will be treated as "positive infinity". /// Thus range(Unbounded, Unbounded) will yield the whole collection. /// /// # Examples /// /// ``` /// #![feature(btree_range, collections_bound)] /// /// use std::collections::BTreeMap; /// use std::collections::Bound::{Included, Excluded}; /// /// let mut map: BTreeMap<&str, i32> = ["Alice", "Bob", "Carol", "Cheryl"].iter() /// .map(|&s| (s, 0)) /// .collect(); /// for (_, balance) in map.range_mut(Included("B"), Excluded("Cheryl")) { /// *balance += 100; /// } /// for (name, balance) in &map { /// println!("{} => {}", name, balance); /// } /// ``` #[unstable(feature = "btree_range", reason = "matches collection reform specification, waiting for dust to settle", issue = "27787")] pub fn range_mut(&mut self, min: Bound<&Min>, max: Bound<&Max>) -> RangeMut where K: Borrow + Borrow, { range_impl!(&mut self.root, min, max, as_slices_internal_mut, iter_mut, RangeMut, edges_mut, [mut]) } /// Gets the given key's corresponding entry in the map for in-place manipulation. /// /// # Examples /// /// ``` /// use std::collections::BTreeMap; /// /// let mut count: BTreeMap<&str, usize> = BTreeMap::new(); /// /// // count the number of occurrences of letters in the vec /// for x in vec!["a","b","a","c","a","b"] { /// *count.entry(x).or_insert(0) += 1; /// } /// /// assert_eq!(count["a"], 3); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn entry(&mut self, mut key: K) -> Entry { // same basic logic of `swap` and `pop`, blended together let mut stack = stack::PartialSearchStack::new(self); loop { let result = stack.with(move |pusher, node| { match Node::search(node, &key) { Found(handle) => { // Perfect match Finished(Occupied(OccupiedEntry { stack: pusher.seal(handle) })) }, GoDown(handle) => { 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 )) } } } } }); match result { Finished(finished) => return finished, Continue((new_stack, renewed_key)) => { stack = new_stack; key = renewed_key; } } } } } impl super::Recover for BTreeMap where K: Borrow + Ord, Q: Ord { type Key = K; fn get(&self, key: &Q) -> Option<&K> { let mut cur_node = &self.root; loop { match Node::search(cur_node, key) { Found(handle) => return Some(handle.into_kv().0), GoDown(handle) => match handle.force() { Leaf(_) => return None, Internal(internal_handle) => { cur_node = internal_handle.into_edge(); continue; } } } } } fn take(&mut self, key: &Q) -> Option { // See `remove` for an explanation of this. let mut stack = stack::PartialSearchStack::new(self); loop { let result = stack.with(move |pusher, node| { match Node::search(node, key) { Found(handle) => { // Perfect match. Terminate the stack here, and remove the entry Finished(Some(pusher.seal(handle).remove())) }, GoDown(handle) => { // We need to keep searching, try to go down the next edge match handle.force() { // We're at a leaf; the key isn't in here Leaf(_) => Finished(None), Internal(internal_handle) => Continue(pusher.push(internal_handle)) } } } }); match result { Finished(ret) => return ret.map(|(k, _)| k), Continue(new_stack) => stack = new_stack } } } fn replace(&mut self, mut key: K) -> Option { // See `insert` for an explanation of this. let mut stack = stack::PartialSearchStack::new(self); loop { let result = stack.with(move |pusher, node| { match Node::search::(node, &key) { Found(mut handle) => { mem::swap(handle.key_mut(), &mut key); Finished(Some(key)) }, GoDown(handle) => { match handle.force() { Leaf(leaf_handle) => { pusher.seal(leaf_handle).insert(key, ()); Finished(None) } Internal(internal_handle) => { Continue((pusher.push(internal_handle), key, ())) } } } } }); match result { Finished(ret) => return ret, Continue((new_stack, renewed_key, _)) => { stack = new_stack; key = renewed_key; } } } } }