@@ -12,21 +12,48 @@ const FILTER_SLICES_SELECTIVITY_THRESHOLD: f64 = 0.8;
1212impl < T : Copy > Filter for & Buffer < T > {
1313 type Output = Buffer < T > ;
1414
15- fn filter ( self , mask : & Mask ) -> Buffer < T > {
16- assert_eq ! ( mask. len( ) , self . len( ) ) ;
17- match mask {
15+ fn filter ( self , selection_mask : & Mask ) -> Buffer < T > {
16+ assert_eq ! (
17+ selection_mask. len( ) ,
18+ self . len( ) ,
19+ "Selection mask length must equal the buffer length"
20+ ) ;
21+
22+ match selection_mask {
1823 Mask :: AllTrue ( _) => self . clone ( ) ,
1924 Mask :: AllFalse ( _) => Buffer :: empty ( ) ,
2025 Mask :: Values ( v) => match v. threshold_iter ( FILTER_SLICES_SELECTIVITY_THRESHOLD ) {
2126 MaskIter :: Indices ( indices) => filter_indices ( self . as_slice ( ) , indices) ,
2227 MaskIter :: Slices ( slices) => {
23- filter_slices ( self . as_slice ( ) , mask . true_count ( ) , slices)
28+ filter_slices ( self . as_slice ( ) , selection_mask . true_count ( ) , slices)
2429 }
2530 } ,
2631 }
2732 }
2833}
2934
35+ impl < T : Copy > Filter for Buffer < T > {
36+ type Output = Self ;
37+
38+ fn filter ( self , selection_mask : & Mask ) -> Self {
39+ assert_eq ! (
40+ selection_mask. len( ) ,
41+ self . len( ) ,
42+ "Selection mask length must equal the buffer length"
43+ ) ;
44+
45+ // If we have exclusive access, we can perform the filter in place.
46+ match self . try_into_mut ( ) {
47+ Ok ( mut buffer_mut) => {
48+ ( & mut buffer_mut) . filter ( selection_mask) ;
49+ buffer_mut. freeze ( )
50+ }
51+ // Otherwise, allocate a new buffer and fill it in (delegate to the `&Buffer` impl).
52+ Err ( buffer) => ( & buffer) . filter ( selection_mask) ,
53+ }
54+ }
55+ }
56+
3057fn filter_indices < T : Copy > ( values : & [ T ] , indices : & [ usize ] ) -> Buffer < T > {
3158 Buffer :: < T > :: from_trusted_len_iter ( indices. iter ( ) . map ( |& idx| values[ idx] ) )
3259}
0 commit comments