@@ -54,6 +54,7 @@ use crate::hash;
5454use crate :: kernel:: BindCtx ;
5555use crate :: kernel:: KernelRef ;
5656use crate :: kernel:: ValidateKernel ;
57+ use crate :: optimizer:: ArrayOptimizer ;
5758use crate :: stats:: StatsSetRef ;
5859use crate :: vtable:: ArrayId ;
5960use crate :: vtable:: ArrayVTable ;
@@ -196,6 +197,12 @@ pub trait Array:
196197
197198 /// Invoke the batch execution function for the array to produce a canonical vector.
198199 fn bind_kernel ( & self , ctx : & mut BindCtx ) -> VortexResult < KernelRef > ;
200+
201+ /// Reduce the array to a more simple representation, if possible.
202+ fn reduce ( & self ) -> VortexResult < Option < ArrayRef > > ;
203+
204+ /// Attempt to perform a reduction of the parent of this array.
205+ fn reduce_parent ( & self , parent : & ArrayRef , child_idx : usize ) -> VortexResult < Option < ArrayRef > > ;
199206}
200207
201208impl Array for Arc < dyn Array > {
@@ -309,6 +316,14 @@ impl Array for Arc<dyn Array> {
309316 fn bind_kernel ( & self , ctx : & mut BindCtx ) -> VortexResult < KernelRef > {
310317 self . as_ref ( ) . bind_kernel ( ctx)
311318 }
319+
320+ fn reduce ( & self ) -> VortexResult < Option < ArrayRef > > {
321+ self . as_ref ( ) . reduce ( )
322+ }
323+
324+ fn reduce_parent ( & self , parent : & ArrayRef , child_idx : usize ) -> VortexResult < Option < ArrayRef > > {
325+ self . as_ref ( ) . reduce_parent ( parent, child_idx)
326+ }
312327}
313328
314329/// A reference counted pointer to a dynamic [`Array`] trait object.
@@ -512,11 +527,15 @@ impl<V: VTable> Array for ArrayAdapter<V> {
512527
513528 fn filter ( & self , mask : Mask ) -> VortexResult < ArrayRef > {
514529 vortex_ensure ! ( self . len( ) == mask. len( ) , "Filter mask length mismatch" ) ;
515- Ok ( FilterArray :: new ( self . to_array ( ) , mask) . into_array ( ) )
530+ FilterArray :: new ( self . to_array ( ) , mask)
531+ . into_array ( )
532+ . optimize ( )
516533 }
517534
518535 fn take ( & self , indices : ArrayRef ) -> VortexResult < ArrayRef > {
519- Ok ( DictArray :: try_new ( indices, self . to_array ( ) ) ?. into_array ( ) )
536+ DictArray :: try_new ( indices, self . to_array ( ) ) ?
537+ . into_array ( )
538+ . optimize ( )
520539 }
521540
522541 fn scalar_at ( & self , index : usize ) -> Scalar {
@@ -658,6 +677,42 @@ impl<V: VTable> Array for ArrayAdapter<V> {
658677 Ok ( kernel)
659678 }
660679 }
680+
681+ fn reduce ( & self ) -> VortexResult < Option < ArrayRef > > {
682+ let Some ( reduced) = V :: reduce ( & self . 0 ) ? else {
683+ return Ok ( None ) ;
684+ } ;
685+ vortex_ensure ! ( reduced. len( ) == self . len( ) , "Reduced array length mismatch" ) ;
686+ vortex_ensure ! (
687+ reduced. dtype( ) == self . dtype( ) ,
688+ "Reduced array dtype mismatch"
689+ ) ;
690+ Ok ( Some ( reduced) )
691+ }
692+
693+ fn reduce_parent ( & self , parent : & ArrayRef , child_idx : usize ) -> VortexResult < Option < ArrayRef > > {
694+ #[ cfg( debug_assertions) ]
695+ vortex_ensure ! (
696+ Arc :: as_ptr( & parent. children( ) [ child_idx] ) == self ,
697+ "Parent array's child at index {} does not match self" ,
698+ child_idx
699+ ) ;
700+
701+ let Some ( reduced) = V :: reduce_parent ( & self . 0 , parent, child_idx) ? else {
702+ return Ok ( None ) ;
703+ } ;
704+
705+ vortex_ensure ! (
706+ reduced. len( ) == parent. len( ) ,
707+ "Reduced array length mismatch"
708+ ) ;
709+ vortex_ensure ! (
710+ reduced. dtype( ) == parent. dtype( ) ,
711+ "Reduced array dtype mismatch"
712+ ) ;
713+
714+ Ok ( Some ( reduced) )
715+ }
661716}
662717
663718impl < V : VTable > ArrayHash for ArrayAdapter < V > {
0 commit comments