ee14b34184fc0bcc59d425858283cd58962d93b2
[SXSI/xpathcomp.git] / main.ml
1 (******************************************************************************)
2 (*  SXSI : XPath evaluator                                                    *)
3 (*  Kim Nguyen (Kim.Nguyen@nicta.com.au)                                      *)
4 (*  Copyright NICTA 2008                                                      *)
5 (*  Distributed under the terms of the LGPL (see LICENCE)                     *)
6 (******************************************************************************)
7
8 open Ata
9 INCLUDE "utils.ml"
10 let () = init_timer();;
11
12 let enabled_gc = Gc.get()
13 let disabled_gc = { Gc.get() with
14                       Gc.max_overhead = 1000000; 
15                       Gc.space_overhead = 100 }
16 let hash x = 131*x/(x-1+1)
17 let test_loop tree tag =
18   let t' = Tree.tagged_desc tree tag  Tree.root in
19   let f = Hashtbl.create 4096
20   in
21   let jump t _ =  Tree.tagged_foll_ctx tree tag t Tree.root in
22   let g t ctx = 
23     if t == Tree.nil then 0
24     else 1+ ((Hashtbl.find f (hash 101)) (jump t ctx) ctx)
25   in
26   Hashtbl.add f (hash 101) g;
27   (Hashtbl.find f (hash 101)) t' Tree.root
28 let test_loop2 tree tag =
29   let t' = Tree.tagged_desc tree tag  Tree.root in
30   let f = Hashtbl.create 4096
31   in
32   let jump t _ =  Tree.tagged_foll_ctx tree tag t Tree.root in
33   let rec g t ctx = 
34     if t == Tree.nil then 0
35     else 1+ (match (Hashtbl.find f (hash 101)) with
36                 `Foo ->g (jump t ctx) ctx
37             ) 
38   in
39   Hashtbl.add f (hash 101) `Foo;
40   g t' Tree.root
41
42 let main v query_string output =
43  
44     let _ = Tag.init (Tree.tag_pool v) in
45       Printf.eprintf "Parsing query : ";    
46       let query = try
47         time
48           XPath.Parser.parse_string query_string
49       with
50           Ulexer.Loc.Exc_located ((x,y),e) -> Printf.eprintf "character %i-%i %s\n" x y (Printexc.to_string e);exit 1
51       in
52       let _ = Printf.eprintf "Timing //keyword :" in
53       let r = time (test_loop v) (Tag.tag "keyword") in
54       let _ = Printf.eprintf "Count is %i\n%!" r in
55       let _ = Printf.eprintf "Timing //keyword 2:" in
56       let r = time (test_loop2 v) (Tag.tag "keyword") in
57       let _ = Printf.eprintf "Count is %i\n%!" r in
58       XPath.Ast.print Format.err_formatter query;
59       Format.fprintf Format.err_formatter "\n%!";
60       Printf.eprintf "Compiling query : ";
61       let auto,ltags,contains = time (XPath.Compile.compile ~querystring:query_string) query in 
62       let _ = Ata.dump Format.err_formatter auto in
63       let _ = Printf.eprintf "%!" in
64       let jump_to = 
65         match contains with
66            None -> (max_int,`NOTHING)
67           | Some s -> 
68               let r = Tree.count v s 
69               in
70               Printf.eprintf "%i documents in the TextCollection\n" (Tree.text_size v);
71               Printf.eprintf "Global count is %i, using " r;
72               if r < !Options.tc_threshold then begin             
73                 Printf.eprintf "TextCollection contains\nCalling global contains : ";
74                 time (Tree.init_contains v) s;
75               end
76               else begin
77                 Printf.eprintf "Naive contains\nCalling global contains : ";
78                 time (Tree.init_naive_contains v) s
79               end;(r,`CONTAINS(s))
80       in
81       let test_list = jump_to in
82       (*
83         let test_list = 
84         if (!Options.backward) then begin
85         Printf.eprintf "Finding min occurences : ";
86         time 
87         ( List.fold_left (fun ((min_occ,kind)as acc)  (tag,_) ->
88                               let numtags = Tree.subtree_tags v tag Tree.root in
89                                 if  ((numtags < min_occ) && numtags >= 2)
90                                 then (numtags,`TAG(tag))
91                                 else acc) jump_to) ltags
92           end
93           else (max_int,`NOTHING)
94         in*)
95         let _ = if (snd test_list) != `NOTHING then
96           let occ,s1,s2 = match test_list with
97             | (x,`TAG (tag)) -> (x, "tag", (Tag.to_string tag))
98             | (x,`CONTAINS(s)) -> (x, "contains()", s)
99             | _ -> assert false
100           in
101             Printf.eprintf "Will jump to %s %s occuring %i time\n%!" s1 s2 occ
102         in
103           Printf.eprintf "Execution time %s : "
104             (if !Options.count_only then "(counting only)" else if !Options.backward then "(bottomup)" else "");
105           begin
106             let _ = Gc.full_major();Gc.compact() in
107             let _ = Printf.eprintf "%!" in
108             let _ = Gc.set (disabled_gc) in
109               if !Options.backward && ((snd test_list) != `NOTHING )then 
110                 
111                 let r = time (bottom_up_count auto v )(snd test_list)  in
112                 let _ = Printf.eprintf "Number of nodes in the result set : %i\n%!" r 
113                 in ()
114               else
115                 let _ = 
116                   if !Options.backward then Printf.eprintf "WARNING: couldn't find a jumping point, running top-down\n" 
117                 in
118                 if !Options.count_only then
119                   let r = time ( top_down_count auto ) v in 
120                   let _ = Printf.eprintf "Number of nodes in the result set : %i\n%!" r
121                   in ()
122                 else      
123                   let result = time (top_down auto) v in          
124                   let rcount = IdSet.length result in
125                     Printf.eprintf "Number of nodes in the result set : %i\n" rcount;
126                     Printf.eprintf "\n%!";
127                     begin
128                       match output with
129                         | None -> ()
130                         | Some f ->                   
131                             Printf.eprintf "Serializing results : ";
132                             time( fun () ->
133                                     let oc = open_out f in
134                                       output_string oc "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";                          
135                                       IdSet.iter (fun t -> 
136                                                     Tree.print_xml_fast oc v t;
137                                                     output_char oc '\n';
138
139                                                  ) result) ();
140                     end;
141           end;
142           let _ = Gc.set enabled_gc in
143             Printf.eprintf "Total running time : %fms\n%!" (total_time())
144 ;;
145
146 Options.parse_cmdline();;
147
148 let v =
149   if (Filename.check_suffix !Options.input_file ".srx")
150   then 
151     begin
152       Printf.eprintf "Loading from file : ";
153       time (Tree.load  ~sample:!Options.sample_factor )
154         !Options.input_file;
155         end
156   else 
157     let v = 
158       time (fun () -> let v = Tree.parse_xml_uri !Options.input_file;
159             in Printf.eprintf "Parsing document : %!";v
160            ) () 
161     in
162       if !Options.save_file <> ""
163       then begin
164         Printf.eprintf "Writing file to disk : ";
165         time (Tree.save v) !Options.save_file;
166       end;
167       v
168 in
169   main v !Options.query !Options.output_file;;
170