usecrate::TryReserveError; use core::borrow::Borrow; use core::cmp::Ordering; use core::fmt::Debug; use core::hash::{Hash, Hasher}; use core::iter::{FromIterator, FusedIterator, Peekable}; use core::marker::PhantomData; use core::ops::Bound::{Excluded, Included, Unbounded}; use core::ops::{Index, RangeBounds}; use core::{fmt, intrinsics, mem, ptr};
/// 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 (log<sub>2</sub>n). 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 i<sup>th</sup> 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 log<sub>B</sub>n) 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. /// /// [`Ord`]: ../../std/cmp/trait.Ord.html /// [`Cell`]: ../../std/cell/struct.Cell.html /// [`RefCell`]: ../../std/cell/struct.RefCell.html /// /// # Examples /// /// ``` /// use std::collections::BTreeMap; /// /// // type inference lets us omit an explicit type signature (which /// // would be `BTreeMap<&str, &str>` in this example). /// let mut movie_reviews = BTreeMap::new(); /// /// // review some movies. /// movie_reviews.insert("Office Space", "Deals with real issues in the workplace."); /// movie_reviews.insert("Pulp Fiction", "Masterpiece."); /// movie_reviews.insert("The Godfather", "Very enjoyable."); /// movie_reviews.insert("The Blues Brothers", "Eye lyked it a lot."); /// /// // check for a specific one. /// if !movie_reviews.contains_key("Les Misérables") { /// println!("We've got {} reviews, but Les Misérables ain't one.", /// movie_reviews.len()); /// } /// /// // oops, this review has a lot of spelling mistakes, let's delete it. /// movie_reviews.remove("The Blues Brothers"); /// /// // look up the values associated with some keys. /// let to_find = ["Up!", "Office Space"]; /// for book in &to_find { /// match movie_reviews.get(book) { /// Some(review) => println!("{}: {}", book, review), /// None => println!("{} is unreviewed.", book) /// } /// } /// /// // Look up the value for a key (will panic if the key is not found). /// println!("Movie review: {}", movie_reviews["Office Space"]); /// /// // iterate over everything. /// for (movie, review) in &movie_reviews { /// println!("{}: \"{}\"", movie, review); /// } /// ``` /// /// `BTreeMap` also implements an [`Entry API`](#method.entry), which allows /// for more complex methods of getting, setting, updating and removing keys and /// their values: /// /// ``` /// use std::collections::BTreeMap; /// /// // type inference lets us omit an explicit type signature (which /// // would be `BTreeMap<&str, u8>` in this example). /// let mut player_stats = BTreeMap::new(); /// /// fn random_stat_buff() -> u8 { /// // could actually return some random value here - let's just return /// // some fixed value for now /// 42 /// } /// /// // insert a key only if it doesn't already exist /// player_stats.entry("health").or_insert(100); /// /// // insert a key using a function that provides a new value only if it /// // doesn't already exist /// player_stats.entry("defence").or_insert_with(random_stat_buff); /// /// // update a key, guarding against the key possibly not being set /// let stat = player_stats.entry("attack").or_insert(100); /// *stat += random_stat_buff(); /// ```
let k = (*k).try_clone()?; let v = (*v).try_clone()?; let subtree = clone_subtree(in_edge.descend())?;
// We can't destructure subtree directly // because BTreeMap implements Drop let (subroot, sublength) = unsafe { let root = ptr::read(&subtree.root); let length = subtree.length;
mem::forget(subtree);
(root, length)
};
let k = (*k).clone(); let v = (*v).clone(); let subtree = clone_subtree(in_edge.descend());
// We can't destructure subtree directly // because BTreeMap implements Drop let (subroot, sublength) = unsafe { let root = ptr::read(&subtree.root); let length = subtree.length;
mem::forget(subtree);
(root, length)
};
/// An iterator over the entries of a `BTreeMap`. /// /// This `struct` is created by the [`iter`] method on [`BTreeMap`]. See its /// documentation for more. /// /// [`iter`]: struct.BTreeMap.html#method.iter /// [`BTreeMap`]: struct.BTreeMap.html
/// A mutable iterator over the entries of a `BTreeMap`. /// /// This `struct` is created by the [`iter_mut`] method on [`BTreeMap`]. See its /// documentation for more. /// /// [`iter_mut`]: struct.BTreeMap.html#method.iter_mut /// [`BTreeMap`]: struct.BTreeMap.html
/// An owning iterator over the entries of a `BTreeMap`. /// /// This `struct` is created by the [`into_iter`] method on [`BTreeMap`][`BTreeMap`] /// (provided by the `IntoIterator` trait). See its documentation for more. /// /// [`into_iter`]: struct.BTreeMap.html#method.into_iter /// [`BTreeMap`]: struct.BTreeMap.html
impl<K: fmt::Debug, V: fmt::Debug> fmt::Debug for IntoIter<K, V> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let range = Range {
front: self.front.reborrow(),
back: self.back.reborrow(),
};
f.debug_list().entries(range).finish()
}
}
/// An iterator over the keys of a `BTreeMap`. /// /// This `struct` is created by the [`keys`] method on [`BTreeMap`]. See its /// documentation for more. /// /// [`keys`]: struct.BTreeMap.html#method.keys /// [`BTreeMap`]: struct.BTreeMap.html
/// An iterator over the values of a `BTreeMap`. /// /// This `struct` is created by the [`values`] method on [`BTreeMap`]. See its /// documentation for more. /// /// [`values`]: struct.BTreeMap.html#method.values /// [`BTreeMap`]: struct.BTreeMap.html
/// A mutable iterator over the values of a `BTreeMap`. /// /// This `struct` is created by the [`values_mut`] method on [`BTreeMap`]. See its /// documentation for more. /// /// [`values_mut`]: struct.BTreeMap.html#method.values_mut /// [`BTreeMap`]: struct.BTreeMap.html
/// An iterator over a sub-range of entries in a `BTreeMap`. /// /// This `struct` is created by the [`range`] method on [`BTreeMap`]. See its /// documentation for more. /// /// [`range`]: struct.BTreeMap.html#method.range /// [`BTreeMap`]: struct.BTreeMap.html
/// A mutable iterator over a sub-range of entries in a `BTreeMap`. /// /// This `struct` is created by the [`range_mut`] method on [`BTreeMap`]. See its /// documentation for more. /// /// [`range_mut`]: struct.BTreeMap.html#method.range_mut /// [`BTreeMap`]: struct.BTreeMap.html
// Be invariant in `K` and `V`
_marker: PhantomData<&'a mut (K, V)>,
}
impl<K: fmt::Debug, V: fmt::Debug> fmt::Debug for RangeMut<'_, K, V> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let range = Range {
front: self.front.reborrow(),
back: self.back.reborrow(),
};
f.debug_list().entries(range).finish()
}
}
/// A view into a single entry in a map, which may either be vacant or occupied. /// /// This `enum` is constructed from the [`entry`] method on [`BTreeMap`]. /// /// [`BTreeMap`]: struct.BTreeMap.html /// [`entry`]: struct.BTreeMap.html#method.entry
// An iterator for merging two sorted sequences into one struct MergeIter<K, V, I: Iterator<Item = (K, V)>> {
left: Peekable<I>,
right: Peekable<I>,
}
impl<K: Ord, V> BTreeMap<K, V> { /// Makes a new empty BTreeMap with a reasonable choice for B. /// /// # Examples /// /// Basic usage: /// /// ``` /// use std::collections::BTreeMap; /// /// let mut map = BTreeMap::new(); /// /// // entries can now be inserted into the empty map /// map.insert(1, "a"); /// ```
/// 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 /// /// Basic usage: /// /// ``` /// 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); /// ```
/// Returns the key-value pair corresponding to the supplied key. /// /// The supplied 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 /// /// ``` /// #![feature(map_get_key_value)] /// use std::collections::BTreeMap; /// /// let mut map = BTreeMap::new(); /// map.insert(1, "a"); /// assert_eq!(map.get_key_value(&1), Some((&1, &"a"))); /// assert_eq!(map.get_key_value(&2), None); /// ``` pubfn get_key_value<Q: ?Sized>(&self, k: &Q) -> Option<(&K, &V)> where
K: Borrow<Q>,
Q: Ord,
{ match search::search_tree(self.root.as_ref(), k) {
Found(handle) => Some(handle.into_kv()),
GoDown(_) => None,
}
}
/// 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 /// /// Basic usage: /// /// ``` /// 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); /// ```
/// 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 /// /// Basic usage: /// /// ``` /// 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
/// Inserts a key-value pair into the map. /// /// If the map did not have this key present, `None` is returned. /// /// If the map did have this key present, the value is updated, and the old /// value is returned. The key is not updated, though; this matters for /// types that can be `==` without being identical. See the [module-level /// documentation] for more. /// /// [module-level documentation]: index.html#insert-and-complex-keys /// /// # Examples /// /// Basic usage: /// /// ``` /// 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"); /// ```
/// 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 /// /// Basic usage: /// /// ``` /// 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); /// ```
/// Moves all elements from `other` into `Self`, leaving `other` empty. /// /// # Examples /// /// ``` /// use std::collections::BTreeMap; /// /// let mut a = BTreeMap::new(); /// a.insert(1, "a"); /// a.insert(2, "b"); /// a.insert(3, "c"); /// /// let mut b = BTreeMap::new(); /// b.insert(3, "d"); /// b.insert(4, "e"); /// b.insert(5, "f"); /// /// a.append(&mut b); /// /// assert_eq!(a.len(), 5); /// assert_eq!(b.len(), 0); /// /// assert_eq!(a[&1], "a"); /// assert_eq!(a[&2], "b"); /// assert_eq!(a[&3], "d"); /// assert_eq!(a[&4], "e"); /// assert_eq!(a[&5], "f"); /// ```
pubfn append(&mutself, other: &mutSelf) { // Do we have to append anything at all? if other.len() == 0 { return;
}
// We can just swap `self` and `other` if `self` is empty. ifself.len() == 0 {
mem::swap(self, other); return;
}
// First, we merge `self` and `other` into a sorted sequence in linear time. let self_iter = mem::replace(self, BTreeMap::new()).into_iter(); let other_iter = mem::replace(other, BTreeMap::new()).into_iter(); let iter = MergeIter {
left: self_iter.peekable(),
right: other_iter.peekable(),
};
// Second, we build a tree from the sorted sequence in linear time. self.from_sorted_iter(iter); self.fix_right_edge();
}
/// Constructs a double-ended iterator over a sub-range of elements in the map. /// The simplest way is to use the range syntax `min..max`, thus `range(min..max)` will /// yield elements from min (inclusive) to max (exclusive). /// The range may also be entered as `(Bound<T>, Bound<T>)`, so for example /// `range((Excluded(4), Included(10)))` will yield a left-exclusive, right-inclusive /// range from 4 to 10. /// /// # Panics /// /// Panics if range `start > end`. /// Panics if range `start == end` and both bounds are `Excluded`. /// /// # Examples /// /// Basic usage: /// /// ``` /// use std::collections::BTreeMap; /// use std::ops::Bound::Included; /// /// 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(4..).next()); /// ```
pubfn range<T: ?Sized, R>(&self, range: R) -> Range<'_, K, V> where
T: Ord,
K: Borrow<T>,
R: RangeBounds<T>,
{ let root1 = self.root.as_ref(); let root2 = self.root.as_ref(); let (f, b) = range_search(root1, root2, range);
Range { front: f, back: b }
}
/// Constructs a mutable double-ended iterator over a sub-range of elements in the map. /// The simplest way is to use the range syntax `min..max`, thus `range(min..max)` will /// yield elements from min (inclusive) to max (exclusive). /// The range may also be entered as `(Bound<T>, Bound<T>)`, so for example /// `range((Excluded(4), Included(10)))` will yield a left-exclusive, right-inclusive /// range from 4 to 10. /// /// # Panics /// /// Panics if range `start > end`. /// Panics if range `start == end` and both bounds are `Excluded`. /// /// # Examples /// /// Basic usage: /// /// ``` /// use std::collections::BTreeMap; /// /// let mut map: BTreeMap<&str, i32> = ["Alice", "Bob", "Carol", "Cheryl"] /// .iter() /// .map(|&s| (s, 0)) /// .collect(); /// for (_, balance) in map.range_mut("B".."Cheryl") { /// *balance += 100; /// } /// for (name, balance) in &map { /// println!("{} => {}", name, balance); /// } /// ```
pubfn range_mut<T: ?Sized, R>(&mutself, range: R) -> RangeMut<'_, K, V> where
T: Ord,
K: Borrow<T>,
R: RangeBounds<T>,
{ let root1 = self.root.as_mut(); let root2 = unsafe { ptr::read(&root1) }; let (f, b) = range_search(root1, root2, range);
/// Gets the given key's corresponding entry in the map for in-place manipulation. /// /// # Examples /// /// Basic usage: /// /// ``` /// 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); /// ```
fn from_sorted_iter<I: Iterator<Item = (K, V)>>(&mutself, iter: I) { self.ensure_root_is_owned().expect("Out Of Mem"); letmut cur_node = last_leaf_edge(self.root.as_mut()).into_node(); // Iterate through all key-value pairs, pushing them into nodes at the right level. for (key, value) in iter { // Try to push key-value pair into the current leaf node. if cur_node.len() < node::CAPACITY {
cur_node.push(key, value);
} else { // No space left, go up and push there. letmut open_node; letmut test_node = cur_node.forget_type(); loop { match test_node.ascend() {
Ok(parent) => { let parent = parent.into_node(); if parent.len() < node::CAPACITY { // Found a node with space left, push here.
open_node = parent; break;
} else { // Go up again.
test_node = parent.forget_type();
}
}
Err(node) => { // We are at the top, create a new root node and push there.
open_node = node.into_root_mut().push_level().expect("Out of Mem"); break;
}
}
}
// Push key-value pair and new right subtree. let tree_height = open_node.height() - 1; letmut right_tree = node::Root::new_leaf().expect("Out of Mem"); for _ in0..tree_height {
right_tree.push_level().expect("Out of Mem");
}
open_node.push(key, value, right_tree);
// Go down to the right-most leaf again.
cur_node = last_leaf_edge(open_node.forget_type()).into_node();
}
self.length += 1;
}
}
fn fix_right_edge(&mutself) { // Handle underfull nodes, start from the top. letmut cur_node = self.root.as_mut(); whilelet Internal(internal) = cur_node.force() { // Check if right-most child is underfull. letmut last_edge = internal.last_edge(); let right_child_len = last_edge.reborrow().descend().len(); if right_child_len < node::MIN_LEN { // We need to steal. letmut last_kv = match last_edge.left_kv() {
Ok(left) => left,
Err(_) => unreachable!(),
};
last_kv.bulk_steal_left(node::MIN_LEN - right_child_len);
last_edge = last_kv.right_edge();
}
// Go further down.
cur_node = last_edge.descend();
}
}
/// Splits the collection into two at the given key. Returns everything after the given key, /// including the key. /// /// # Examples /// /// Basic usage: /// /// ``` /// use std::collections::BTreeMap; /// /// let mut a = BTreeMap::new(); /// a.insert(1, "a"); /// a.insert(2, "b"); /// a.insert(3, "c"); /// a.insert(17, "d"); /// a.insert(41, "e"); /// /// let b = a.split_off(&3); /// /// assert_eq!(a.len(), 2); /// assert_eq!(b.len(), 3); /// /// assert_eq!(a[&1], "a"); /// assert_eq!(a[&2], "b"); /// /// assert_eq!(b[&3], "c"); /// assert_eq!(b[&17], "d"); /// assert_eq!(b[&41], "e"); /// ```
loop { letmut split_edge = match search::search_node(left_node, key) { // key is going to the right tree
Found(handle) => handle.left_edge(),
GoDown(handle) => handle,
};
/// Calculates the number of elements if it is incorrect. fn recalc_length(&mutself) { fn dfs<'a, K, V>(node: NodeRef<marker::Immut<'a>, K, V, marker::LeafOrInternal>) -> usize where
K: 'a,
V: 'a,
{ letmut res = node.len();
letmut cur_handle = match handle.right_kv() {
Ok(kv) => { self.front = ptr::read(&kv).right_edge(); // Doing the descend invalidates the references returned by `into_kv_mut`, // so we have to do this last. let (k, v) = kv.into_kv_mut(); return (k, v); // coerce k from `&mut K` to `&K`
}
Err(last_edge) => { let next_level = last_edge.into_node().ascend().ok();
unwrap_unchecked(next_level)
}
};
loop { match cur_handle.right_kv() {
Ok(kv) => { self.front = first_leaf_edge(ptr::read(&kv).right_edge().descend()); // Doing the descend invalidates the references returned by `into_kv_mut`, // so we have to do this last. let (k, v) = kv.into_kv_mut(); return (k, v); // coerce k from `&mut K` to `&K`
}
Err(last_edge) => { let next_level = last_edge.into_node().ascend().ok();
cur_handle = unwrap_unchecked(next_level);
}
}
}
}
}
letmut cur_handle = match handle.left_kv() {
Ok(kv) => { self.back = ptr::read(&kv).left_edge(); // Doing the descend invalidates the references returned by `into_kv_mut`, // so we have to do this last. let (k, v) = kv.into_kv_mut(); return (k, v); // coerce k from `&mut K` to `&K`
}
Err(last_edge) => { let next_level = last_edge.into_node().ascend().ok();
unwrap_unchecked(next_level)
}
};
loop { match cur_handle.left_kv() {
Ok(kv) => { self.back = last_leaf_edge(ptr::read(&kv).left_edge().descend()); // Doing the descend invalidates the references returned by `into_kv_mut`, // so we have to do this last. let (k, v) = kv.into_kv_mut(); return (k, v); // coerce k from `&mut K` to `&K`
}
Err(last_edge) => { let next_level = last_edge.into_node().ascend().ok();
cur_handle = unwrap_unchecked(next_level);
}
}
}
}
}
impl<K: Ord, Q: ?Sized, V> Index<&Q> for BTreeMap<K, V> where
K: Borrow<Q>,
Q: Ord,
{ type Output = V;
/// Returns a reference to the value corresponding to the supplied key. /// /// # Panics /// /// Panics if the key is not present in the `BTreeMap`. #[inline] fn index(&self, key: &Q) -> &V { self.get(key).expect("no entry found for key")
}
}
/// Gets a mutable iterator over the entries of the map, sorted by key. /// /// # Examples /// /// Basic usage: /// /// ``` /// 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; /// } /// } /// ```
/// Gets an iterator over the values of the map, in order by key. /// /// # Examples /// /// Basic usage: /// /// ``` /// use std::collections::BTreeMap; /// /// let mut a = BTreeMap::new(); /// a.insert(1, "hello"); /// a.insert(2, "goodbye"); /// /// let values: Vec<&str> = a.values().cloned().collect(); /// assert_eq!(values, ["hello", "goodbye"]); /// ```
/// Gets a mutable iterator over the values of the map, in order by key. /// /// # Examples /// /// Basic usage: /// /// ``` /// use std::collections::BTreeMap; /// /// let mut a = BTreeMap::new(); /// a.insert(1, String::from("hello")); /// a.insert(2, String::from("goodbye")); /// /// for value in a.values_mut() { /// value.push_str("!"); /// } /// /// let values: Vec<String> = a.values().cloned().collect(); /// assert_eq!(values, [String::from("hello!"), /// String::from("goodbye!")]); /// ```
/// Returns the number of elements in the map. /// /// # Examples /// /// Basic usage: /// /// ``` /// use std::collections::BTreeMap; /// /// let mut a = BTreeMap::new(); /// assert_eq!(a.len(), 0); /// a.insert(1, "a"); /// assert_eq!(a.len(), 1); /// ```
impl<'a, K: Ord, V> Entry<'a, K, V> { /// Ensures a value is in the entry by inserting the default if empty, and returns /// a mutable reference to the value in the entry. /// /// # Examples /// /// ``` /// use std::collections::BTreeMap; /// /// let mut map: BTreeMap<&str, usize> = BTreeMap::new(); /// map.entry("poneyland").or_insert(12); /// /// assert_eq!(map["poneyland"], 12); /// ```
/// 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. /// /// # Examples /// /// ``` /// use std::collections::BTreeMap; /// /// let mut map: BTreeMap<&str, String> = BTreeMap::new(); /// let s = "hoho".to_string(); /// /// map.entry("poneyland").or_insert_with(|| s); /// /// assert_eq!(map["poneyland"], "hoho".to_string()); /// ```
impl<'a, K: Ord, V: Default> Entry<'a, K, V> { /// Ensures a value is in the entry by inserting the default value if empty, /// and returns a mutable reference to the value in the entry. /// /// # Examples /// /// ``` /// # fn main() { /// use std::collections::BTreeMap; /// /// let mut map: BTreeMap<&str, Option<usize>> = BTreeMap::new(); /// map.entry("poneyland").or_default(); /// /// assert_eq!(map["poneyland"], None); /// # } /// ``` pubfn or_default(self) -> Result<&'a mut V, TryReserveError> { matchself {
Occupied(entry) => Ok(entry.into_mut()),
Vacant(entry) => entry.try_insert(Default::default()),
}
}
}
impl<'a, K: Ord, V> VacantEntry<'a, K, V> { /// Gets a reference to the key that would be used when inserting a value /// through the VacantEntry. /// /// # Examples /// /// ``` /// use std::collections::BTreeMap; /// /// let mut map: BTreeMap<&str, usize> = BTreeMap::new(); /// assert_eq!(map.entry("poneyland").key(), &"poneyland"); /// ```
/// Take ownership of the key. /// /// # Examples /// /// ``` /// use std::collections::BTreeMap; /// use std::collections::btree_map::Entry; /// /// let mut map: BTreeMap<&str, usize> = BTreeMap::new(); /// /// if let Entry::Vacant(v) = map.entry("poneyland") { /// v.into_key(); /// } /// ``` #[inline(always)] pubfn into_key(self) -> K { self.key
}
/// Sets the value of the entry with the `VacantEntry`'s key, /// and returns a mutable reference to it. /// /// # 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); /// ```
/// Take ownership of the key and value from the map. /// /// # Examples /// /// ``` /// use std::collections::BTreeMap; /// use std::collections::btree_map::Entry; /// /// let mut map: BTreeMap<&str, usize> = BTreeMap::new(); /// map.entry("poneyland").or_insert(12); /// /// if let Entry::Occupied(o) = map.entry("poneyland") { /// // We delete the entry from the map. /// o.remove_entry(); /// } /// /// // If now try to get the value, it will panic: /// // println!("{}", map["poneyland"]); /// ```
/// Gets a reference to the value in the entry. /// /// # Examples /// /// ``` /// use std::collections::BTreeMap; /// use std::collections::btree_map::Entry; /// /// let mut map: BTreeMap<&str, usize> = BTreeMap::new(); /// map.entry("poneyland").or_insert(12); /// /// if let Entry::Occupied(o) = map.entry("poneyland") { /// assert_eq!(o.get(), &12); /// } /// ```
/// Gets a mutable reference to the value in the entry. /// /// If you need a reference to the `OccupiedEntry` that may outlive the /// destruction of the `Entry` value, see [`into_mut`]. /// /// [`into_mut`]: #method.into_mut /// /// # Examples /// /// ``` /// use std::collections::BTreeMap; /// use std::collections::btree_map::Entry; /// /// let mut map: BTreeMap<&str, usize> = BTreeMap::new(); /// map.entry("poneyland").or_insert(12); /// /// assert_eq!(map["poneyland"], 12); /// if let Entry::Occupied(mut o) = map.entry("poneyland") { /// *o.get_mut() += 10; /// assert_eq!(*o.get(), 22); /// /// // We can use the same Entry multiple times. /// *o.get_mut() += 2; /// } /// assert_eq!(map["poneyland"], 24); /// ``` #[inline] pubfn get_mut(&mutself) -> &mut V { self.handle.kv_mut().1
}
/// Converts the entry into a mutable reference to its value. /// /// If you need multiple references to the `OccupiedEntry`, see [`get_mut`]. /// /// [`get_mut`]: #method.get_mut /// /// # Examples /// /// ``` /// use std::collections::BTreeMap; /// use std::collections::btree_map::Entry; /// /// let mut map: BTreeMap<&str, usize> = BTreeMap::new(); /// map.entry("poneyland").or_insert(12); /// /// assert_eq!(map["poneyland"], 12); /// if let Entry::Occupied(o) = map.entry("poneyland") { /// *o.into_mut() += 10; /// } /// assert_eq!(map["poneyland"], 22); /// ``` #[inline] pubfn into_mut(self) -> &'a mut V { self.handle.into_kv_mut().1
}
/// Sets the value of the entry with the `OccupiedEntry`'s key, /// and returns the entry's old value. /// /// # Examples /// /// ``` /// use std::collections::BTreeMap; /// use std::collections::btree_map::Entry; /// /// let mut map: BTreeMap<&str, usize> = BTreeMap::new(); /// map.entry("poneyland").or_insert(12); /// /// if let Entry::Occupied(mut o) = map.entry("poneyland") { /// assert_eq!(o.insert(15), 12); /// } /// assert_eq!(map["poneyland"], 15); /// ``` #[inline] pubfn insert(&mutself, value: V) -> V {
mem::replace(self.get_mut(), value)
}
/// Takes the value of the entry out of the map, and returns it. /// /// # Examples /// /// ``` /// use std::collections::BTreeMap; /// use std::collections::btree_map::Entry; /// /// let mut map: BTreeMap<&str, usize> = BTreeMap::new(); /// map.entry("poneyland").or_insert(12); /// /// if let Entry::Occupied(o) = map.entry("poneyland") { /// assert_eq!(o.remove(), 12); /// } /// // If we try to get "poneyland"'s value, it'll panic: /// // println!("{}", map["poneyland"]); /// ``` #[inline] pubfn remove(self) -> V { self.remove_kv().1
}
fn remove_kv(self) -> (K, V) {
*self.length -= 1;
let (small_leaf, old_key, old_val) = matchself.handle.force() {
Leaf(leaf) => { let (hole, old_key, old_val) = leaf.remove();
(hole.into_node(), old_key, old_val)
}
Internal(mut internal) => { let key_loc = internal.kv_mut().0as *mut K; let val_loc = internal.kv_mut().1as *mut V;
let to_remove = first_leaf_edge(internal.right_edge().descend())
.right_kv()
.ok(); let to_remove = unsafe { unwrap_unchecked(to_remove) };
let (hole, key, val) = to_remove.remove();
let old_key = unsafe { mem::replace(&mut *key_loc, key) }; let old_val = unsafe { mem::replace(&mut *val_loc, val) };
(hole.into_node(), old_key, old_val)
}
};
// Handle underflow letmut cur_node = small_leaf.forget_type(); while cur_node.len() < node::CAPACITY / 2 { match handle_underfull_node(cur_node) {
AtRoot => break,
EmptyParent(_) => unreachable!(),
Merged(parent) => { if parent.len() == 0 { // We must be at the root
parent.into_root_mut().pop_level(); break;
} else {
cur_node = parent.forget_type();
}
}
Stole(_) => break,
}
}
// Check which elements comes first and only advance the corresponding iterator. // If two keys are equal, take the value from `right`. match res {
Ordering::Less => self.left.next(),
Ordering::Greater => self.right.next(),
Ordering::Equal => { self.left.next(); self.right.next()
}
}
}
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.39 Sekunden
(vorverarbeitet am 2026-06-20)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.