22// SPDX-FileCopyrightText: Copyright the Vortex contributors
33
44use vortex_dtype:: { FieldName , StructFields } ;
5- use vortex_error:: { VortexResult , vortex_err} ;
6- use vortex_utils:: aliases:: hash_map:: HashMap ;
5+ use vortex_error:: VortexExpect ;
76use vortex_utils:: aliases:: hash_set:: HashSet ;
87
9- use crate :: transform:: access_analysis:: AccessesAnalysis ;
10- use crate :: traversal:: TraversalOrder ;
8+ use crate :: transform:: annotations:: { AnnotationFn , Annotations , descendent_annotations} ;
119use crate :: { ExprRef , GetItemVTable , SelectVTable , is_root} ;
1210
13- pub type FieldAccesses < ' a > = HashMap < & ' a ExprRef , HashSet < FieldName > > ;
11+ pub type FieldAccesses < ' a > = Annotations < ' a , FieldName > ;
12+
13+ /// An [`AnnotationFn`] for annotating scope accesses.
14+ pub fn annotate_scope_access ( scope : & StructFields ) -> impl AnnotationFn < Annotation = FieldName > {
15+ move |expr : & ExprRef | {
16+ assert ! (
17+ !expr. is:: <SelectVTable >( ) ,
18+ "cannot analyse select, simplify the expression"
19+ ) ;
20+
21+ if let Some ( get_item) = expr. as_opt :: < GetItemVTable > ( ) {
22+ if is_root ( get_item. child ( ) ) {
23+ return vec ! [ get_item. field( ) . clone( ) ] ;
24+ }
25+ } else if is_root ( expr) {
26+ return scope. names ( ) . iter ( ) . cloned ( ) . collect ( ) ;
27+ }
28+
29+ vec ! [ ]
30+ }
31+ }
1432
1533/// For all subexpressions in an expression, find the fields that are accessed directly from the
1634/// scope, but not any fields in those fields
@@ -21,38 +39,18 @@ pub type FieldAccesses<'a> = HashMap<&'a ExprRef, HashSet<FieldName>>;
2139/// by an expression.
2240pub fn immediate_scope_accesses < ' a > (
2341 expr : & ' a ExprRef ,
24- scope_dtype : & ' a StructFields ,
25- ) -> VortexResult < FieldAccesses < ' a > > {
26- AccessesAnalysis :: analyze ( expr, move |node| {
27- assert ! (
28- !node. is:: <SelectVTable >( ) ,
29- "cannot analyse select, simplify the expression"
30- ) ;
31- if let Some ( get_item) = node. as_opt :: < GetItemVTable > ( ) {
32- if is_root ( get_item. child ( ) ) {
33- return ( TraversalOrder :: Skip , vec ! [ get_item. field( ) . clone( ) ] ) ;
34- }
35- } else if is_root ( node) {
36- let st_dtype = & scope_dtype;
37- return (
38- TraversalOrder :: Skip ,
39- st_dtype. names ( ) . iter ( ) . cloned ( ) . collect ( ) ,
40- ) ;
41- }
42-
43- ( TraversalOrder :: Continue , vec ! [ ] )
44- } )
42+ scope : & ' a StructFields ,
43+ ) -> FieldAccesses < ' a > {
44+ descendent_annotations ( expr, annotate_scope_access ( scope) )
4545}
4646
4747/// This returns the immediate scope_access (as explained `immediate_scope_accesses`) for `expr`.
4848pub fn immediate_scope_access < ' a > (
4949 expr : & ' a ExprRef ,
50- scope_dtype : & ' a StructFields ,
51- ) -> VortexResult < HashSet < FieldName > > {
52- immediate_scope_accesses ( expr, scope_dtype ) ?
50+ scope : & ' a StructFields ,
51+ ) -> HashSet < FieldName > {
52+ immediate_scope_accesses ( expr, scope )
5353 . get ( expr)
54- . ok_or_else ( || {
55- vortex_err ! ( "Expression missing from scope accesses, this is a internal bug" )
56- } )
57- . cloned ( )
54+ . vortex_expect ( "Expression missing from scope accesses, this is a internal bug" )
55+ . clone ( )
5856}
0 commit comments