@@ -525,7 +525,39 @@ impl<K: Ord, V> BTreeMap<K, V> {
525
525
}
526
526
}
527
527
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.
529
561
///
530
562
/// # Examples
531
563
///
@@ -842,6 +874,47 @@ impl<K: Ord, V> BTreeMap<K, V> {
842
874
}
843
875
}
844
876
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
+
845
918
/// Moves all elements from `other` into `Self`, leaving `other` empty.
846
919
///
847
920
/// # Examples
@@ -1804,6 +1877,41 @@ impl<'a, K, V> RangeMut<'a, K, V> {
1804
1877
}
1805
1878
}
1806
1879
}
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
+ }
1807
1915
}
1808
1916
1809
1917
#[ stable( feature = "btree_range" , since = "1.17.0" ) ]
@@ -2618,9 +2726,21 @@ impl<'a, K: Ord, V> OccupiedEntry<'a, K, V> {
2618
2726
fn remove_kv ( self ) -> ( K , V ) {
2619
2727
* self . length -= 1 ;
2620
2728
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 ( ) {
2622
2739
Leaf ( leaf) => {
2623
2740
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
+ }
2624
2744
( hole. into_node ( ) , old_key, old_val)
2625
2745
}
2626
2746
Internal ( mut internal) => {
@@ -2641,7 +2761,7 @@ impl<'a, K: Ord, V> OccupiedEntry<'a, K, V> {
2641
2761
2642
2762
// Handle underflow
2643
2763
let mut cur_node = small_leaf. forget_type ( ) ;
2644
- while cur_node. len ( ) < node:: CAPACITY / 2 {
2764
+ while cur_node. len ( ) < node:: MIN_LEN {
2645
2765
match handle_underfull_node ( cur_node) {
2646
2766
AtRoot => break ,
2647
2767
EmptyParent ( _) => unreachable ! ( ) ,
@@ -2658,7 +2778,7 @@ impl<'a, K: Ord, V> OccupiedEntry<'a, K, V> {
2658
2778
}
2659
2779
}
2660
2780
2661
- ( old_key, old_val)
2781
+ ( old_key, old_val, None )
2662
2782
}
2663
2783
}
2664
2784
0 commit comments