@@ -1256,6 +1256,48 @@ impl<K: Ord, V> BTreeMap<K, V> {
1256
1256
right
1257
1257
}
1258
1258
1259
+ /// Creates an iterator which uses a closure to determine if an element should be removed.
1260
+ ///
1261
+ /// If the closure returns true, the element is removed from the map and yielded.
1262
+ /// If the closure returns false, or panics, the element remains in the map and will not be
1263
+ /// yielded.
1264
+ ///
1265
+ /// Note that `drain_filter` lets you mutate every value in the filter closure, regardless of
1266
+ /// whether you choose to keep or remove it.
1267
+ ///
1268
+ /// If the iterator is only partially consumed or not consumed at all, each of the remaining
1269
+ /// elements will still be subjected to the closure and removed and dropped if it returns true.
1270
+ ///
1271
+ /// It is unspecified how many more elements will be subjected to the closure
1272
+ /// if a panic occurs in the closure, or a panic occurs while dropping an element,
1273
+ /// or if the `DrainFilter` value is leaked.
1274
+ ///
1275
+ /// # Examples
1276
+ ///
1277
+ /// Splitting a map into even and odd keys, reusing the original map:
1278
+ ///
1279
+ /// ```
1280
+ /// #![feature(btree_drain_filter)]
1281
+ /// use std::collections::BTreeMap;
1282
+ ///
1283
+ /// let mut map: BTreeMap<i32, i32> = (0..8).map(|x| (x, x)).collect();
1284
+ /// let evens: BTreeMap<_, _> = map.drain_filter(|k, _v| k % 2 == 0).collect();
1285
+ /// let odds = map;
1286
+ /// assert_eq!(evens.keys().copied().collect::<Vec<_>>(), vec![0, 2, 4, 6]);
1287
+ /// assert_eq!(odds.keys().copied().collect::<Vec<_>>(), vec![1, 3, 5, 7]);
1288
+ /// ```
1289
+ #[ unstable( feature = "btree_drain_filter" , issue = "70530" ) ]
1290
+ pub fn drain_filter < F > ( & mut self , pred : F ) -> DrainFilter < ' _ , K , V , F >
1291
+ where
1292
+ F : FnMut ( & K , & mut V ) -> bool ,
1293
+ {
1294
+ DrainFilter { pred, inner : self . drain_filter_inner ( ) }
1295
+ }
1296
+ pub ( super ) fn drain_filter_inner ( & mut self ) -> DrainFilterInner < ' _ , K , V > {
1297
+ let front = self . root . as_mut ( ) . map ( |r| r. as_mut ( ) . first_leaf_edge ( ) ) ;
1298
+ DrainFilterInner { length : & mut self . length , cur_leaf_edge : front }
1299
+ }
1300
+
1259
1301
/// Calculates the number of elements if it is incorrect.
1260
1302
fn recalc_length ( & mut self ) {
1261
1303
fn dfs < ' a , K , V > ( node : NodeRef < marker:: Immut < ' a > , K , V , marker:: LeafOrInternal > ) -> usize
@@ -1653,6 +1695,124 @@ impl<K, V> Clone for Values<'_, K, V> {
1653
1695
}
1654
1696
}
1655
1697
1698
+ /// An iterator produced by calling `drain_filter` on BTreeMap.
1699
+ #[ unstable( feature = "btree_drain_filter" , issue = "70530" ) ]
1700
+ pub struct DrainFilter < ' a , K , V , F >
1701
+ where
1702
+ K : ' a + Ord , // This Ord bound should be removed before stabilization.
1703
+ V : ' a ,
1704
+ F : ' a + FnMut ( & K , & mut V ) -> bool ,
1705
+ {
1706
+ pred : F ,
1707
+ inner : DrainFilterInner < ' a , K , V > ,
1708
+ }
1709
+ pub ( super ) struct DrainFilterInner < ' a , K , V >
1710
+ where
1711
+ K : ' a + Ord ,
1712
+ V : ' a ,
1713
+ {
1714
+ length : & ' a mut usize ,
1715
+ cur_leaf_edge : Option < Handle < NodeRef < marker:: Mut < ' a > , K , V , marker:: Leaf > , marker:: Edge > > ,
1716
+ }
1717
+
1718
+ #[ unstable( feature = "btree_drain_filter" , issue = "70530" ) ]
1719
+ impl < ' a , K , V , F > Drop for DrainFilter < ' a , K , V , F >
1720
+ where
1721
+ K : ' a + Ord ,
1722
+ V : ' a ,
1723
+ F : ' a + FnMut ( & K , & mut V ) -> bool ,
1724
+ {
1725
+ fn drop ( & mut self ) {
1726
+ self . for_each ( drop) ;
1727
+ }
1728
+ }
1729
+
1730
+ #[ unstable( feature = "btree_drain_filter" , issue = "70530" ) ]
1731
+ impl < ' a , K , V , F > fmt:: Debug for DrainFilter < ' a , K , V , F >
1732
+ where
1733
+ K : ' a + fmt:: Debug + Ord ,
1734
+ V : ' a + fmt:: Debug ,
1735
+ F : ' a + FnMut ( & K , & mut V ) -> bool ,
1736
+ {
1737
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
1738
+ f. debug_tuple ( "DrainFilter" ) . field ( & self . inner . peek ( ) ) . finish ( )
1739
+ }
1740
+ }
1741
+
1742
+ #[ unstable( feature = "btree_drain_filter" , issue = "70530" ) ]
1743
+ impl < ' a , K , V , F > Iterator for DrainFilter < ' a , K , V , F >
1744
+ where
1745
+ K : ' a + Ord ,
1746
+ V : ' a ,
1747
+ F : ' a + FnMut ( & K , & mut V ) -> bool ,
1748
+ {
1749
+ type Item = ( K , V ) ;
1750
+
1751
+ fn next ( & mut self ) -> Option < ( K , V ) > {
1752
+ self . inner . next ( & mut self . pred )
1753
+ }
1754
+
1755
+ fn size_hint ( & self ) -> ( usize , Option < usize > ) {
1756
+ self . inner . size_hint ( )
1757
+ }
1758
+ }
1759
+
1760
+ impl < ' a , K , V > DrainFilterInner < ' a , K , V >
1761
+ where
1762
+ K : ' a + Ord ,
1763
+ V : ' a ,
1764
+ {
1765
+ /// Allow Debug implementations to predict the next element.
1766
+ pub ( super ) fn peek ( & self ) -> Option < ( & K , & V ) > {
1767
+ let edge = self . cur_leaf_edge . as_ref ( ) ?;
1768
+ edge. reborrow ( ) . next_kv ( ) . ok ( ) . map ( |kv| kv. into_kv ( ) )
1769
+ }
1770
+
1771
+ unsafe fn next_kv (
1772
+ & mut self ,
1773
+ ) -> Option < Handle < NodeRef < marker:: Mut < ' a > , K , V , marker:: LeafOrInternal > , marker:: KV > > {
1774
+ let edge = self . cur_leaf_edge . as_ref ( ) ?;
1775
+ ptr:: read ( edge) . next_kv ( ) . ok ( )
1776
+ }
1777
+
1778
+ /// Implementation of a typical `DrainFilter::next` method, given the predicate.
1779
+ pub ( super ) fn next < F > ( & mut self , pred : & mut F ) -> Option < ( K , V ) >
1780
+ where
1781
+ F : FnMut ( & K , & mut V ) -> bool ,
1782
+ {
1783
+ while let Some ( kv) = unsafe { self . next_kv ( ) } {
1784
+ let ( k, v) = unsafe { ptr:: read ( & kv) } . into_kv_mut ( ) ;
1785
+ if pred ( k, v) {
1786
+ * self . length -= 1 ;
1787
+ let ( k, v, leaf_edge_location) = kv. remove_kv_tracking ( ) ;
1788
+ // `remove_kv_tracking` has either preserved or invalidated `self.cur_leaf_edge`
1789
+ if let Some ( node) = leaf_edge_location {
1790
+ match search:: search_tree ( node, & k) {
1791
+ search:: SearchResult :: Found ( _) => unreachable ! ( ) ,
1792
+ search:: SearchResult :: GoDown ( leaf) => self . cur_leaf_edge = Some ( leaf) ,
1793
+ }
1794
+ } ;
1795
+ return Some ( ( k, v) ) ;
1796
+ }
1797
+ self . cur_leaf_edge = Some ( kv. next_leaf_edge ( ) ) ;
1798
+ }
1799
+ None
1800
+ }
1801
+
1802
+ /// Implementation of a typical `DrainFilter::size_hint` method.
1803
+ pub ( super ) fn size_hint ( & self ) -> ( usize , Option < usize > ) {
1804
+ ( 0 , Some ( * self . length ) )
1805
+ }
1806
+ }
1807
+
1808
+ #[ unstable( feature = "btree_drain_filter" , issue = "70530" ) ]
1809
+ impl < K , V , F > FusedIterator for DrainFilter < ' _ , K , V , F >
1810
+ where
1811
+ K : Ord ,
1812
+ F : FnMut ( & K , & mut V ) -> bool ,
1813
+ {
1814
+ }
1815
+
1656
1816
#[ stable( feature = "btree_range" , since = "1.17.0" ) ]
1657
1817
impl < ' a , K , V > Iterator for Range < ' a , K , V > {
1658
1818
type Item = ( & ' a K , & ' a V ) ;
@@ -2531,12 +2691,31 @@ impl<'a, K: Ord, V> OccupiedEntry<'a, K, V> {
2531
2691
fn remove_kv ( self ) -> ( K , V ) {
2532
2692
* self . length -= 1 ;
2533
2693
2534
- let ( small_leaf, old_key, old_val) = match self . handle . force ( ) {
2694
+ let ( old_key, old_val, _) = self . handle . remove_kv_tracking ( ) ;
2695
+ ( old_key, old_val)
2696
+ }
2697
+ }
2698
+
2699
+ impl < ' a , K : ' a , V : ' a > Handle < NodeRef < marker:: Mut < ' a > , K , V , marker:: LeafOrInternal > , marker:: KV > {
2700
+ /// Removes a key/value-pair from the map, and returns that pair, as well as
2701
+ /// the whereabouts of the leaf edge corresponding to that former pair:
2702
+ /// if None is returned, the leaf edge is still the left leaf edge of the KV handle;
2703
+ /// if a node is returned, it heads the subtree where the leaf edge may be found.
2704
+ fn remove_kv_tracking (
2705
+ self ,
2706
+ ) -> ( K , V , Option < NodeRef < marker:: Mut < ' a > , K , V , marker:: LeafOrInternal > > ) {
2707
+ let mut levels_down_handled: isize ;
2708
+ let ( small_leaf, old_key, old_val) = match self . force ( ) {
2535
2709
Leaf ( leaf) => {
2710
+ levels_down_handled = 1 ; // handled at same level, but affects only the right side
2536
2711
let ( hole, old_key, old_val) = leaf. remove ( ) ;
2537
2712
( hole. into_node ( ) , old_key, old_val)
2538
2713
}
2539
2714
Internal ( mut internal) => {
2715
+ // Replace the location freed in the internal node with the next KV,
2716
+ // and remove that next KV from its leaf.
2717
+ levels_down_handled = unsafe { ptr:: read ( & internal) . into_node ( ) . height ( ) } as isize ;
2718
+
2540
2719
let key_loc = internal. kv_mut ( ) . 0 as * mut K ;
2541
2720
let val_loc = internal. kv_mut ( ) . 1 as * mut V ;
2542
2721
@@ -2556,27 +2735,39 @@ impl<'a, K: Ord, V> OccupiedEntry<'a, K, V> {
2556
2735
let mut cur_node = small_leaf. forget_type ( ) ;
2557
2736
while cur_node. len ( ) < node:: MIN_LEN {
2558
2737
match handle_underfull_node ( cur_node) {
2559
- AtRoot => break ,
2738
+ AtRoot ( root) => {
2739
+ cur_node = root;
2740
+ break ;
2741
+ }
2560
2742
EmptyParent ( _) => unreachable ! ( ) ,
2561
2743
Merged ( parent) => {
2744
+ levels_down_handled -= 1 ;
2562
2745
if parent. len ( ) == 0 {
2563
2746
// We must be at the root
2564
- parent. into_root_mut ( ) . pop_level ( ) ;
2747
+ let root = parent. into_root_mut ( ) ;
2748
+ root. pop_level ( ) ;
2749
+ cur_node = root. as_mut ( ) ;
2565
2750
break ;
2566
2751
} else {
2567
2752
cur_node = parent. forget_type ( ) ;
2568
2753
}
2569
2754
}
2570
- Stole ( _) => break ,
2755
+ Stole ( internal_node) => {
2756
+ levels_down_handled -= 1 ;
2757
+ cur_node = internal_node. forget_type ( ) ;
2758
+ // This internal node might be underfull, but only if it's the root.
2759
+ break ;
2760
+ }
2571
2761
}
2572
2762
}
2573
2763
2574
- ( old_key, old_val)
2764
+ let leaf_edge_location = if levels_down_handled > 0 { None } else { Some ( cur_node) } ;
2765
+ ( old_key, old_val, leaf_edge_location)
2575
2766
}
2576
2767
}
2577
2768
2578
2769
enum UnderflowResult < ' a , K , V > {
2579
- AtRoot ,
2770
+ AtRoot ( NodeRef < marker :: Mut < ' a > , K , V , marker :: LeafOrInternal > ) ,
2580
2771
EmptyParent ( NodeRef < marker:: Mut < ' a > , K , V , marker:: Internal > ) ,
2581
2772
Merged ( NodeRef < marker:: Mut < ' a > , K , V , marker:: Internal > ) ,
2582
2773
Stole ( NodeRef < marker:: Mut < ' a > , K , V , marker:: Internal > ) ,
@@ -2585,10 +2776,9 @@ enum UnderflowResult<'a, K, V> {
2585
2776
fn handle_underfull_node < K , V > (
2586
2777
node : NodeRef < marker:: Mut < ' _ > , K , V , marker:: LeafOrInternal > ,
2587
2778
) -> UnderflowResult < ' _ , K , V > {
2588
- let parent = if let Ok ( parent) = node. ascend ( ) {
2589
- parent
2590
- } else {
2591
- return AtRoot ;
2779
+ let parent = match node. ascend ( ) {
2780
+ Ok ( parent) => parent,
2781
+ Err ( root) => return AtRoot ( root) ,
2592
2782
} ;
2593
2783
2594
2784
let ( is_left, mut handle) = match parent. left_kv ( ) {
0 commit comments