@@ -525,7 +525,39 @@ impl<K: Ord, V> BTreeMap<K, V> {
525525 }
526526 }
527527
528- /// Clears the map, removing all values.
528+ /// Clears the map, returning all key-value pairs as an iterator.
529+ ///
530+ /// # Examples
531+ ///
532+ /// Basic usage:
533+ ///
534+ /// ```
535+ /// #![feature(btree_drain_retain)]
536+ /// use std::collections::BTreeMap;
537+ ///
538+ /// let mut a = BTreeMap::new();
539+ /// a.insert(1, "a");
540+ /// a.insert(2, "b");
541+ ///
542+ /// for (k, v) in a.drain().take(1) {
543+ /// assert!(k == 1 || k == 2);
544+ /// assert!(v == "a" || v == "b");
545+ /// }
546+ ///
547+ /// assert!(a.is_empty());
548+ /// ```
549+ #[ unstable( feature = "btree_drain_retain" , issue = "42849" ) ]
550+ pub fn drain ( & mut self ) -> IntoIter < K , V > {
551+ let length = mem:: replace ( & mut self . length , 0 ) ;
552+ let root = mem:: replace ( & mut self . root , node:: Root :: shared_empty_root ( ) ) ;
553+ let root1 = unsafe { ptr:: read ( & root) . into_ref ( ) } ;
554+ let root2 = unsafe { ptr:: read ( & root) . into_ref ( ) } ;
555+ let front = first_leaf_edge ( root1) ;
556+ let back = last_leaf_edge ( root2) ;
557+ IntoIter { front, back, length }
558+ }
559+
560+ /// Clears the map, removing all key-value pairs.
529561 ///
530562 /// # Examples
531563 ///
@@ -842,6 +874,47 @@ impl<K: Ord, V> BTreeMap<K, V> {
842874 }
843875 }
844876
877+ /// Retains only the elements specified by the predicate.
878+ ///
879+ /// In other words, remove all pairs `(k, v)` such that `f(&k, &mut v)` returns `false`.
880+ ///
881+ /// # Examples
882+ ///
883+ /// ```
884+ /// #![feature(btree_drain_retain)]
885+ /// use std::collections::BTreeMap;
886+ ///
887+ /// let mut map: BTreeMap<i32, i32> = (0..8).map(|x|(x, x)).collect();
888+ /// map.retain(|&k, _| k % 2 == 0);
889+ /// assert_eq!(map.len(), 4);
890+ /// ```
891+ #[ unstable( feature = "btree_drain_retain" , issue = "42849" ) ]
892+ pub fn retain < F > ( & mut self , mut f : F )
893+ where F : FnMut ( & K , & mut V ) -> bool ,
894+ {
895+ let mut cur_leaf_edge = first_leaf_edge ( self . root . as_mut ( ) ) ;
896+ while let Some ( ( kv, next_leaf_edge) ) = RangeMut :: next_handles ( cur_leaf_edge) {
897+ let ( k, v) = unsafe { ptr:: read ( & kv) . into_kv_mut ( ) } ;
898+ let retain = f ( k, v) ;
899+ cur_leaf_edge = if retain {
900+ next_leaf_edge
901+ } else {
902+ let ( k, _v, hole) = OccupiedEntry :: remove_kv_by_handle ( kv) ;
903+ // next_leaf_edge is now invalid or wrong
904+ self . length -= 1 ;
905+ match hole {
906+ Some ( next_leaf_edge) => next_leaf_edge,
907+ None => {
908+ let root1 = self . root . as_mut ( ) ;
909+ let root2 = unsafe { ptr:: read ( & root1) } ;
910+ let ( front, _back) = range_search ( root1, root2, k..) ;
911+ front
912+ }
913+ }
914+ }
915+ }
916+ }
917+
845918 /// Moves all elements from `other` into `Self`, leaving `other` empty.
846919 ///
847920 /// # Examples
@@ -1804,6 +1877,41 @@ impl<'a, K, V> RangeMut<'a, K, V> {
18041877 }
18051878 }
18061879 }
1880+
1881+ // Transform given leaf edge handle into handles of next kv and next leaf edge
1882+ fn next_handles (
1883+ leaf_edge : Handle < NodeRef < marker:: Mut < ' a > , K , V , marker:: Leaf > , marker:: Edge >
1884+ ) -> Option < ( Handle < NodeRef < marker:: Mut < ' a > , K , V , marker:: LeafOrInternal > , marker:: KV > ,
1885+ Handle < NodeRef < marker:: Mut < ' a > , K , V , marker:: Leaf > , marker:: Edge > ) > {
1886+ let mut cur_edge = match leaf_edge. right_kv ( ) {
1887+ Ok ( kv) => {
1888+ let next_leaf_edge = unsafe { ptr:: read ( & kv) . right_edge ( ) } ;
1889+ return Some ( ( kv. forget_node_type ( ) , next_leaf_edge) ) ;
1890+ }
1891+ Err ( last_edge) => {
1892+ match last_edge. into_node ( ) . ascend ( ) {
1893+ Ok ( next_level) => next_level,
1894+ Err ( _) => return None ,
1895+ }
1896+ }
1897+ } ;
1898+
1899+ loop {
1900+ cur_edge = match cur_edge. right_kv ( ) {
1901+ Ok ( kv) => {
1902+ let right_edge = unsafe { ptr:: read ( & kv) . right_edge ( ) } ;
1903+ let next_leaf_edge = first_leaf_edge ( right_edge. descend ( ) ) ;
1904+ return Some ( ( kv. forget_node_type ( ) , next_leaf_edge) ) ;
1905+ }
1906+ Err ( last_edge) => {
1907+ match last_edge. into_node ( ) . ascend ( ) {
1908+ Ok ( next_level) => next_level,
1909+ Err ( _) => return None ,
1910+ }
1911+ }
1912+ }
1913+ }
1914+ }
18071915}
18081916
18091917#[ stable( feature = "btree_range" , since = "1.17.0" ) ]
@@ -2618,9 +2726,21 @@ impl<'a, K: Ord, V> OccupiedEntry<'a, K, V> {
26182726 fn remove_kv ( self ) -> ( K , V ) {
26192727 * self . length -= 1 ;
26202728
2621- let ( small_leaf, old_key, old_val) = match self . handle . force ( ) {
2729+ let ( k, v, _) = OccupiedEntry :: remove_kv_by_handle ( self . handle ) ;
2730+ ( k, v)
2731+ }
2732+
2733+ // Removes and returns a key/value-pair, and optionally (if cheap), returns the resulting edge
2734+ // corresponding to the former left and right edges of the entry.
2735+ fn remove_kv_by_handle (
2736+ handle : Handle < NodeRef < marker:: Mut < ' a > , K , V , marker:: LeafOrInternal > , marker:: KV > )
2737+ -> ( K , V , Option < Handle < NodeRef < marker:: Mut < ' a > , K , V , marker:: Leaf > , marker:: Edge > > ) {
2738+ let ( small_leaf, old_key, old_val) = match handle. force ( ) {
26222739 Leaf ( leaf) => {
26232740 let ( hole, old_key, old_val) = leaf. remove ( ) ;
2741+ if hole. reborrow ( ) . into_node ( ) . len ( ) >= node:: MIN_LEN {
2742+ return ( old_key, old_val, Some ( hole) )
2743+ }
26242744 ( hole. into_node ( ) , old_key, old_val)
26252745 }
26262746 Internal ( mut internal) => {
@@ -2641,7 +2761,7 @@ impl<'a, K: Ord, V> OccupiedEntry<'a, K, V> {
26412761
26422762 // Handle underflow
26432763 let mut cur_node = small_leaf. forget_type ( ) ;
2644- while cur_node. len ( ) < node:: CAPACITY / 2 {
2764+ while cur_node. len ( ) < node:: MIN_LEN {
26452765 match handle_underfull_node ( cur_node) {
26462766 AtRoot => break ,
26472767 EmptyParent ( _) => unreachable ! ( ) ,
@@ -2658,7 +2778,7 @@ impl<'a, K: Ord, V> OccupiedEntry<'a, K, V> {
26582778 }
26592779 }
26602780
2661- ( old_key, old_val)
2781+ ( old_key, old_val, None )
26622782 }
26632783}
26642784
0 commit comments