@@ -112,6 +112,36 @@ impl<T> PacketBuf<T> {
112112 . filter_map ( move |( i, slot) | slot. as_ref ( ) . map ( |v| ( start + i as u64 , v) ) )
113113 }
114114
115+ pub fn retain ( & mut self , f : impl FnMut ( u64 , & mut T ) -> bool ) {
116+ let mut f = f;
117+ let base = base ( self . min , self . max ) ;
118+ for i in self . min ..self . max {
119+ let offset = ( i - base) as usize ;
120+ let Some ( v) = & mut self . data [ offset] else {
121+ continue ;
122+ } ;
123+ if !f ( i, v) {
124+ self . data [ offset] = None ;
125+ }
126+ }
127+ // Now adjust min and max
128+ let start = ( self . min - base) as usize ;
129+ let end = ( self . max - base) as usize ;
130+ let min1 = self . data [ start..end]
131+ . iter ( )
132+ . position ( |slot| slot. is_some ( ) )
133+ . map ( |p| p + start)
134+ . unwrap_or ( end) as u64 + base;
135+ let max1 = self . data [ start..end]
136+ . iter ( )
137+ . rev ( )
138+ . position ( |slot| slot. is_some ( ) )
139+ . map ( |p| end - p)
140+ . unwrap_or ( start + 1 ) as u64 + base;
141+ self . resize ( min1, max1) ;
142+ self . check_invariants ( ) ;
143+ }
144+
115145 /// Retain only the elements in the given index range.
116146 pub fn retain_range < R : std:: ops:: RangeBounds < u64 > > ( & mut self , range : R ) {
117147 let ( min1, max1) = self . clip_bounds ( range) ;
@@ -281,7 +311,7 @@ impl<T> PacketBuf<T> {
281311 // nothing to do
282312 return ;
283313 }
284- if min1 = = max1 {
314+ if min1 > = max1 {
285315 // resizing to empty buffer
286316 * self = Self :: new ( ) ;
287317 return ;
@@ -471,6 +501,33 @@ mod tests {
471501 assert_eq ! ( pairs, ( 10 ..20 ) . map( |i| ( i, i * 10 ) ) . collect:: <Vec <_>>( ) ) ;
472502 }
473503
504+
505+ #[ test]
506+ fn test_retain ( ) {
507+ let mut pb = PacketBuf :: default ( ) ;
508+ for i in 0 ..100 {
509+ pb. insert ( i, i * 10 ) ;
510+ }
511+
512+ pb. retain ( |i, _v| i % 2 == 0 ) ;
513+
514+ assert_eq ! ( pb. keys( ) . next( ) , Some ( 0 ) ) ;
515+ assert_eq ! ( pb. keys( ) . next_back( ) , Some ( 98 ) ) ;
516+ assert_eq ! ( pb. keys( ) . count( ) , 50 ) ;
517+ for i in 0 ..100 {
518+ if i % 2 == 0 {
519+ assert_eq ! ( pb. get( i) , Some ( & ( i * 10 ) ) ) ;
520+ } else {
521+ assert_eq ! ( pb. get( i) , None ) ;
522+ }
523+ }
524+ pb. check_invariants_expensive ( ) ;
525+
526+ pb. retain ( |_, _| false ) ;
527+ assert ! ( pb. is_empty( ) ) ;
528+ pb. check_invariants_expensive ( ) ;
529+ }
530+
474531 #[ test]
475532 fn test_retain_range ( ) {
476533 let mut pb = PacketBuf :: default ( ) ;
@@ -531,7 +588,7 @@ mod tests {
531588 proptest ! {
532589 #[ test]
533590 fn test_matches_btreemap( ops in prop:: collection:: vec( op_strategy( ) , 0 ..1000 ) ) {
534- let mut pb = PacketBuffer :: default ( ) ;
591+ let mut pb = PacketBuf :: default ( ) ;
535592 let mut reference = BTreeMap :: new( ) ;
536593
537594 for op in ops {
0 commit comments