File: cs_annotate.ml

package info (click to toggle)
galax 1.1-10
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 12,832 kB
  • sloc: ml: 96,603; xml: 26,602; ansic: 4,875; sh: 3,977; makefile: 1,667; java: 1,146
file content (288 lines) | stat: -rw-r--r-- 10,205 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
(***********************************************************************)
(*                                                                     *)
(*                                 GALAX                               *)
(*                              XQuery Engine                          *)
(*                                                                     *)
(*  Copyright 2001-2007.                                               *)
(*  Distributed only by permission.                                    *)
(*                                                                     *)
(***********************************************************************)

(* $Id: cs_annotate.ml,v 1.19 2007/07/13 18:24:42 mff Exp $ *)

(* Module: Cs_annotate
   Description:
     This module implements algebraic annotation for the physical
     layer.
*)

(* NOTE:
   Annotation is really a separate 'sub-phase', that deals with
   annotations needed for physical operators, notably it decides on
   which physical types should be used for each operator.
*)

open Algebra_type

open Xquery_algebra_ast
open Xquery_algebra_ast_util

(***************************)
(* Physical typing context *)
(***************************)

type return_env =
    { contains_side_effect   : bool;
      contains_delta_update  : bool;
      contains_snapped_delta : bool }

let mk_renv cse csd cdu = 
  { contains_side_effect   = cse;
    contains_snapped_delta = csd;
    contains_delta_update  = cdu }

let make_renv_of_annotation ann =
  match ann with
  | {has_nested_snap=hns;has_side_effect=hse;has_delta_update=hdu} ->
      mk_renv hns hse hdu

let make_annotation renv path_annotation =
  { has_nested_snap  = renv.contains_snapped_delta;
    has_side_effect  = renv.contains_side_effect;
    has_delta_update = renv.contains_delta_update;
    path_annotation = path_annotation;
    materialize_tuple_stream = true }


(*************)
(* Dummy code*)
(*************)

let dummy_error alg_ctxt () =
  raise (Error.Query
	   (Error.Malformed_Algebra_Expr
	      "Missing code in the algebraic plan! [Expr]"))
let dummy_code = NoDep ((fun ef -> AOECUnit dummy_error), None)
let decl_dummy_code = PNoDep (PAOECUnit dummy_error)


(*****************************)
(* Annotated op constructors *)
(*****************************)

let combine_renv e1 e2 = 
  mk_renv 
    (e1.contains_side_effect   || e2.contains_side_effect)
    (e1.contains_snapped_delta || e2.contains_snapped_delta) 
    (e1.contains_delta_update  || e2.contains_delta_update) 

let no_side_effect_renv ()     = mk_renv false false false
let atomic_side_effect_renv () = mk_renv true false true
let non_trivial_snap_renv   () = mk_renv true true true
let ensure_delta env           = combine_renv (mk_renv false false true) env

let make_annotated_op op indep dep renv =
  let path_annotation = op.annotation in
  let annotation = make_annotation renv path_annotation in
  algop_mkop
    dummy_code
    op.palgop_expr_eval_sig
    op.palgop_expr_name
    indep
    dep
    annotation
    op.compile_annotations
    op.palgop_expr_origin
    op.palgop_expr_loc

let make_temp_annotated_expr opname indep dep loc =
  let path_annotation = ref None in
  let annotation = make_annotation (no_side_effect_renv()) path_annotation in
  algop_mkop
    dummy_code
    None
    opname
    indep
    dep
    annotation
    None
    None
    loc

(* Lookup the function body *)
let get_function_body_renv compile_ctxt ((name,arity) as fn_name) =
(* Debug.print_default_debug("In get_function_body_renv \n"); *)
  let snap =  if Compile_context.mem_function_from_compile_context compile_ctxt fn_name
  then
    begin
      let func_defn =
	Compile_context.get_function_from_compile_context "get_function_body_renv" compile_ctxt fn_name
      in
      match !(func_defn.palgop_func_optimized_logical_plan) with
      |	AOEFunctionImported -> (* Assume 'the worst' *) non_trivial_snap_renv ()
      |	AOEFunctionUser userbody -> 
	  make_renv_of_annotation userbody.annotation
    end
  else (* Assume 'the worst' *)
    non_trivial_snap_renv ()
  in
(* Debug.print_default_debug("Out get_function_body_renv \n"); *)
  snap

let rec has_non_trivial_snap compile_ctxt algop =
  match algop.palgop_expr_name with
  | AOESnap sm ->
      let indep,renv =
	has_non_trivial_snap_subexpr compile_ctxt algop.psub_expression
      in
      let dep, renv =
	has_non_trivial_snap_subexpr compile_ctxt algop.pdep_sub_expression
      in
      let renv        =
	if renv.contains_delta_update
	then non_trivial_snap_renv ()
	else no_side_effect_renv ()
      in
      (make_annotated_op algop indep dep renv), renv
  | AOECallUserDefined  ((cfname,arity), _,_,_, _) ->
      let indep,renv1 =
	has_non_trivial_snap_subexpr compile_ctxt algop.psub_expression
      in 
      let _ = access_unitsub algop.pdep_sub_expression in
      let body_renv = get_function_body_renv compile_ctxt (cfname,arity) in
      let renv      = combine_renv renv1 body_renv in 
      (make_annotated_op algop indep NoSub renv), renv
  | AOEDelete
  | AOEInsert _ 
  | AOERename _
  | AOEReplace _ ->
      let indep,renv1 = has_non_trivial_snap_subexpr compile_ctxt algop.psub_expression in 
      let dep,renv2   = has_non_trivial_snap_subexpr compile_ctxt algop.pdep_sub_expression in 
      let combined    = combine_renv renv1 renv2 in 
      let renv        = ensure_delta combined in 
      (make_annotated_op algop indep dep combined), renv
  | _ -> 
      let indep,renv1 = has_non_trivial_snap_subexpr compile_ctxt algop.psub_expression in 
      let dep,renv2   = has_non_trivial_snap_subexpr compile_ctxt algop.pdep_sub_expression in 
      let renv        = combine_renv renv1 renv2 in 
      (make_annotated_op algop indep dep renv), renv

and has_non_trivial_snap_subexpr compile_ctxt sexpr = 
  match sexpr with 
  | NoSub -> NoSub, (no_side_effect_renv ())
  | OneSub op -> 
      let op, renv = has_non_trivial_snap compile_ctxt op in
      (OneSub op), renv
  | TwoSub (op1,op2) ->
      let op1, renv1 = has_non_trivial_snap compile_ctxt op1 in 
      let op2, renv2 = has_non_trivial_snap compile_ctxt op2 in 
      (TwoSub(op1,op2)), (combine_renv renv1 renv2)
  | ManySub ops ->	    
      let renv_ref = ref (no_side_effect_renv ()) in 
      let process_op op = 
	let op,renv = has_non_trivial_snap compile_ctxt op in 
	begin
	  renv_ref := combine_renv !renv_ref renv;
	  op
	end
      in
      let ops = Array.map process_op ops in 
      (ManySub ops), !renv_ref


(********************)
(* Internal Helpers *)
(********************)
	   
let annotate_decl context dd = (* annotate subexprs and then go! *)
  let indep,renv1 = has_non_trivial_snap_subexpr context dd.alg_decl_indep in
  let dep, renv2  = has_non_trivial_snap_subexpr context dd.alg_decl_dep in
  let renv        = combine_renv renv1 renv2 in 
  let path_annotation = dd.alg_decl_annotation in
  let annotation  = make_annotation renv path_annotation in 
  algop_decl_mkop
    decl_dummy_code
    dd.alg_decl_name
    indep
    dep
    annotation
    dd.alg_decl_loc 

let annotate_function_body compile_context func_defn = 
  let func_body = 
    match !(func_defn.palgop_func_optimized_logical_plan) with
    | AOEFunctionImported -> AOEFunctionImported
    | AOEFunctionUser userbody -> 
	let op, _ = has_non_trivial_snap compile_context userbody in 
	(AOEFunctionUser op)
  in
  fmkalgop_function_body func_defn.palgop_func_formal_args func_body None func_defn.palgop_func_output_type
  
let annotate_function_decl compile_context 
  { palgop_function_decl_desc=(fname,signature,fn_body,upd);
    palgop_function_decl_loc=loc } =
  (* Annotate the body *)
  let fn_body = annotate_function_body compile_context fn_body in
  if (Compile_context.mem_function_from_compile_context compile_context fname) 
  then ()
  else Compile_context.add_function_to_compile_context compile_context fname fn_body;
  (* Update the compile context *)
  fmkalgop_function_decl (fname,signature,fn_body,upd) loc


(************)
(* External *)
(************)

let annotate_statement compile_ctxt ae = 
  let op, _ = has_non_trivial_snap compile_ctxt ae in op

let annotate_expr compile_ctxt ae = 
  let op, _ = has_non_trivial_snap compile_ctxt ae in op

let annotate_prolog_with_bindings compile_ctxt p = 
  (* function decls have the side-effect of adding themselves to the compile context *)
  let fds  = List.map (annotate_function_decl compile_ctxt) p.palgop_prolog_functions in
  let vars = List.map (annotate_decl compile_ctxt) p.palgop_prolog_vars in 
  let ind  = List.map (annotate_decl compile_ctxt) p.palgop_prolog_indices in 
  (fmkalgop_prolog fds vars ind), compile_ctxt

let annotate_prolog compile_ctxt p =
  let compile_ctxt = Compile_context.copy_without_functions compile_ctxt in
  annotate_prolog_with_bindings compile_ctxt p 

(* annotate takes an old style compile_context *)
let annotate_module_with_bindings comp_ctxt m = 
  let prolog,(comp_ctxt:alg_compile_context) =
    annotate_prolog_with_bindings comp_ctxt m.palgop_module_prolog
  in 
  let statements =
    List.map (annotate_statement comp_ctxt) m.palgop_module_statements
  in
  (fmkalgop_xmodule prolog statements), comp_ctxt

let annotate_module comp_ctxt m = 
  let prolog,(comp_ctxt:alg_compile_context) =
    annotate_prolog comp_ctxt m.palgop_module_prolog
  in 
  let statements =
    List.map (annotate_statement comp_ctxt) m.palgop_module_statements
  in
  (fmkalgop_xmodule prolog statements), comp_ctxt

let annotate_context context =  
  let comp_ctxt = Compile_context.copy_without_functions context in
  let annotate_functions ht key func_defn  =
    let op = 
      match !(func_defn.palgop_func_optimized_logical_plan) with
      |	AOEFunctionImported -> AOEFunctionImported 
      |	AOEFunctionUser userbody -> AOEFunctionUser(annotate_statement comp_ctxt userbody)
    in 
    (* Order of bindings is unimportant because we are just dealing
    with their ops here *)
    let func_defn' = fmkalgop_function_body 
	func_defn.palgop_func_formal_args op None func_defn.palgop_func_output_type in
    Namespace_util.RQNameIntHashtbl.add ht key func_defn'
  in
  Compile_context.map_function_bodies context annotate_functions