@@ -7,26 +7,18 @@ use std::ops::Range;
77use vortex_buffer:: BufferHandle ;
88use vortex_compute:: filter:: Filter ;
99use vortex_dtype:: DType ;
10+ use vortex_error:: vortex_bail;
1011use vortex_error:: VortexExpect ;
1112use vortex_error:: VortexResult ;
12- use vortex_error:: vortex_bail;
1313use vortex_mask:: Mask ;
1414use vortex_scalar:: Scalar ;
1515
16- use crate :: Array ;
17- use crate :: ArrayBufferVisitor ;
18- use crate :: ArrayChildVisitor ;
19- use crate :: ArrayEq ;
20- use crate :: ArrayHash ;
21- use crate :: ArrayRef ;
22- use crate :: Canonical ;
23- use crate :: IntoArray ;
24- use crate :: Precision ;
25- use crate :: arrays:: LEGACY_SESSION ;
2616use crate :: arrays:: filter:: array:: FilterArray ;
17+ use crate :: arrays:: filter:: kernel:: FilterKernel ;
18+ use crate :: arrays:: LEGACY_SESSION ;
2719use crate :: kernel:: BindCtx ;
2820use crate :: kernel:: KernelRef ;
29- use crate :: kernel:: kernel ;
21+ use crate :: kernel:: PushDownResult ;
3022use crate :: serde:: ArrayChildren ;
3123use crate :: stats:: StatsSetRef ;
3224use crate :: vectors:: VectorIntoArray ;
@@ -41,6 +33,15 @@ use crate::vtable::OperationsVTable;
4133use crate :: vtable:: VTable ;
4234use crate :: vtable:: ValidityVTable ;
4335use crate :: vtable:: VisitorVTable ;
36+ use crate :: Array ;
37+ use crate :: ArrayBufferVisitor ;
38+ use crate :: ArrayChildVisitor ;
39+ use crate :: ArrayEq ;
40+ use crate :: ArrayHash ;
41+ use crate :: ArrayRef ;
42+ use crate :: Canonical ;
43+ use crate :: IntoArray ;
44+ use crate :: Precision ;
4445
4546vtable ! ( Filter ) ;
4647
@@ -95,9 +96,40 @@ impl VTable for FilterVTable {
9596 }
9697
9798 fn bind_kernel ( array : & Self :: Array , ctx : & mut BindCtx ) -> VortexResult < KernelRef > {
98- let child = array. child . bind_kernel ( ctx) ?;
99+ let mut child = array. child . bind_kernel ( ctx) ?;
99100 let mask = array. mask . clone ( ) ;
100- Ok ( kernel ( move || Ok ( Filter :: filter ( & child. execute ( ) ?, & mask) ) ) )
101+
102+ let full_cost = child. cost_estimate ( & Mask :: new_true ( array. child . len ( ) ) ) ;
103+ let pushdown_cost = child. cost_estimate ( & mask) ;
104+ log:: debug!(
105+ "Filter kernel cost estimate: full={}, pushdown={}" ,
106+ full_cost,
107+ pushdown_cost
108+ ) ;
109+
110+ if pushdown_cost < full_cost {
111+ // Try to push down the filter to the child if it's cheaper.
112+ child = match child. push_down_filter ( & mask) ? {
113+ PushDownResult :: Pushed ( new_k) => {
114+ log:: debug!( "Filter push down kernel:\n {:?}" , new_k) ;
115+ return Ok ( new_k) ;
116+ }
117+ PushDownResult :: NotPushed ( child) => {
118+ log:: debug!(
119+ "Filter pushdown was cheaper but not supported by child array {}" ,
120+ array. child. display_tree( )
121+ ) ;
122+ child
123+ }
124+ } ;
125+ }
126+
127+ // Otherwise, wrap up the child in a filter kernel.
128+ Ok ( Box :: new ( FilterKernel :: new (
129+ child,
130+ mask,
131+ array. dtype ( ) . clone ( ) ,
132+ ) ) )
101133 }
102134}
103135
0 commit comments