cherry pick from local- branch
[SXSI/xpathcomp.git] / timeXMLTree.cpp
1 #include "XMLDocShredder.h"
2 #include "XMLTree.h"
3 #include "Utils.h"
4 #include <sys/time.h>
5 #include <time.h>
6 #include <sys/stat.h> 
7
8 #define read32u() \
9   (intern_src += 4, \
10    ((uintnat)(intern_src[-4]) << 24) + (intern_src[-3] << 16) + \
11    (intern_src[-2] << 8) + intern_src[-1])
12
13 using std::cout;
14 using std::string;
15 using std::left;
16 using std::right;
17
18 static double tFirstChild = 0;
19 static double tNextSibling = 0;
20 static double tParent = 0;
21 static double tTaggedAncestor = 0;
22 static double tTaggedChild = 0;
23 static double tTaggedDesc = 0;
24 static double tTaggedFoll = 0;
25 static double tParentNode = 0;
26 static double tPrevNode = 0;
27 static double tTag = 0;
28 static double tMyText = 0;
29 static double tPrevText = 0;
30 static double tNextText = 0;
31 static double tDocIds = 0;
32
33 static double tFullTraversal = 0;
34 static double tJumpTraversal = 0;
35
36 static unsigned int cFirstChild = 0;
37 static unsigned int cNextSibling = 0;
38 static unsigned int cParent = 0;
39 static unsigned int cTaggedAncestor = 0;
40 static unsigned int cTaggedChild = 0;
41 static unsigned int cTaggedDesc = 0;
42 static unsigned int cTaggedFoll = 0;
43 static unsigned int cParentNode = 0;
44 static unsigned int cPrevNode = 0;
45 static unsigned int cTag = 0;
46 static unsigned int cMyText = 0;
47 static unsigned int cPrevText = 0;
48 static unsigned int cNextText = 0;
49 static unsigned int cDocIds = 0;
50
51 static unsigned int cFullTraversal = 0;
52 static unsigned int cJumpTraversal = 0;
53
54
55 static struct timeval tmpv1;
56 static struct timeval tmpv2;
57
58 static TagType target_tag = -1;
59
60 #define STARTTIMER()   (gettimeofday(&tmpv1,NULL))
61 #define STOPTIMER(x)   do {                                             \
62     gettimeofday(&tmpv2,NULL);                                          \
63     (t##x) = (t##x) + ((tmpv2.tv_sec  - tmpv1.tv_sec) * 1000000.0 +     \
64                        (tmpv2.tv_usec  - tmpv1.tv_usec))/1000.0;        \
65     (c##x)= (c##x)+1;                                                   \
66   } while (0)
67
68 #define PRINTSTATS(x)  do {                                             \
69     std::cout.width(15);                                                \
70     std::cout << std::left << #x;                                       \
71     std::cout << " : ";                                                 \
72     std::cout.width(8);                                                 \
73     std::cout << std::right << c##x << " calls, ";                      \
74     std::cout.width(8);                                                 \
75     std::cout << std::right << (t##x)                                   \
76               << " ms, mean: ";                                         \
77     std::cout.width(8);                                                 \
78     std::cout << std::right                                             \
79               << (t##x)  *1.00 / c##x                                   \
80               << "\n";                                                  \
81   } while (0)
82
83 void traversal(XMLTree * tree, treeNode node,unsigned char* targettagname){
84   treeNode res1,res2;
85   TagType tag;
86   DocID id1,id2,id3;
87   range rg;
88   const unsigned char * tagname;
89   if (node != NULLT){
90
91     STARTTIMER();
92     tag = tree->Tag(node);
93     STOPTIMER(Tag);
94     if (target_tag == -1){
95       tagname = tree->GetTagNameByRef(tag);
96       if (strcmp( (char*) tagname, (char*) targettagname) == 0)
97         target_tag = tag;
98     };
99     STARTTIMER();
100     res1 = tree->Parent(node);
101     STOPTIMER(Parent);
102     /*
103     STARTTIMER();
104     res1 = tree->TaggedChild(node,0,tag);
105     STOPTIMER(TaggedChild);
106
107     STARTTIMER();
108     res1 = tree->TaggedAncestor(node,tag);
109     STOPTIMER(TaggedAncestor);
110     */
111     STARTTIMER();
112     res1 = tree->TaggedDesc(node,tag);
113     STOPTIMER(TaggedDesc);
114
115     STARTTIMER();
116     res1 = tree->TaggedFoll(node,tag);
117     STOPTIMER(TaggedFoll);
118     
119     STARTTIMER();
120     rg = tree->DocIds(node);
121     STOPTIMER(DocIds);
122
123     STARTTIMER();
124     id1 = tree->MyText(node);
125     STOPTIMER(MyText);
126
127     STARTTIMER();
128     id2 = tree->PrevText(node);
129     STOPTIMER(PrevText);
130
131     STARTTIMER();
132     id3 = tree->NextText(node);
133     STOPTIMER(NextText);
134     
135     id1 = max(id1, max(id2,id3));
136
137     STARTTIMER();
138     res1 = tree->ParentNode(id1);
139     STOPTIMER(ParentNode);
140
141     STARTTIMER();
142     res1 = tree->PrevNode(id1);
143     STOPTIMER(PrevNode);
144     
145     STARTTIMER();
146     res1 = tree->FirstChild(node);
147     STOPTIMER(FirstChild);
148
149     STARTTIMER();
150     res2 = tree->NextSibling(node);
151     STOPTIMER(NextSibling);
152
153     traversal(tree,res1,targettagname);
154     traversal(tree,res2,targettagname);
155     
156   };
157   
158 }
159
160 /* This simulates the run function of the automata */
161
162 unsigned int time_traversal(XMLTree *tree,treeNode node){
163   TagType tag;
164   if (node != NULLT) {
165     cFullTraversal++;
166     tag = tree->Tag(node);
167     if (tag == target_tag)      
168       return 1 + 
169         time_traversal(tree,tree->FirstChild(node)) +
170         time_traversal(tree,tree->NextSibling(node)); 
171     else
172       return time_traversal(tree,tree->FirstChild(node)) +
173         time_traversal(tree,tree->NextSibling(node));
174
175   }
176   else 
177     return 0;
178 }
179
180 /* This simulates the run function of the jumping automata*/
181 unsigned int time_jump(XMLTree* tree, treeNode node,treeNode root){
182   TagType tag;
183   if (node != NULLT) {
184     cJumpTraversal++;
185     tag = tree->Tag(node);
186     if (tag == target_tag)
187       return 1 + 
188         time_jump(tree, tree->TaggedDesc(node,target_tag),node) +
189         time_jump(tree, tree->TaggedFollBelow(node,target_tag,root),  root);
190
191     else
192       return time_jump(tree, tree->TaggedDesc(node,target_tag),node) +
193         time_jump(tree, tree->TaggedFollBelow(node,target_tag,root),  root);
194   }
195   else 
196     return 0;
197 }
198
199
200 int usage(char ** argv){
201   
202   std::cout << "usage : " << argv[0] << " [-d] [-s] file.{xml,.srx} tagname\n";
203   return 1;
204
205 }
206
207
208 int main(int argc, char ** argv){
209   unsigned int count1,count2;
210   unsigned char * tagname;
211   string arg,filename,ext;
212   bool disable_tc = false; 
213   bool save = false;
214   bool srx;
215   XMLTree * tree;
216
217   int i = 1;
218   if ( i >= argc)
219     return usage(argv);
220   
221   arg = argv[i];
222   if (arg.compare("-d") == 0){
223     disable_tc = true;
224     i++;
225     if ( i >= argc)
226       return usage(argv);
227     arg = argv[i];
228   };
229
230   if (arg.compare("-s") == 0){
231     save = true;
232     i++;
233     if ( i >= argc)
234       return usage(argv);
235     arg = argv[i];
236   };
237
238
239   // The filename
240   if (arg.size() < 4)
241     return usage(argv);
242   
243   ext=(arg.substr(arg.size()-4,4));
244   if (ext.compare(".srx") == 0){
245     // must truncate
246     filename = arg.substr(0,arg.size()-4);
247
248     srx = true;
249   }
250   else if (ext.compare(".xml")==0) {
251     filename = arg;
252     srx = false;
253   }
254   else 
255     return usage(argv);
256   i++;
257
258   if (i >= argc)
259     return usage(argv);
260
261   tagname = (unsigned char*) argv[i];
262   
263
264   
265   if (srx)     
266     // The samplerate is not taken into account for loading anymore
267     tree = XMLTree::Load((unsigned char*) filename.c_str(),64);
268   else {
269     try {
270       //filename, sampling factor, index empty texts, disable tc
271       XMLDocShredder shredder(filename.c_str(),64,false,disable_tc);      
272       shredder.processStartDocument("");  
273       shredder.parse();  
274       shredder.processEndDocument();         
275       tree = (XMLTree *) shredder.storageIfc_->returnDocument();
276       if (save){
277         filename = filename.substr(0,filename.size()-4).append(".srx");
278         struct stat stats;
279         int exists = stat(filename.c_str(),&stats);
280         if(exists == 0) { 
281           std::cout << "Warning : indexed file " << filename << " exists, not overwriting\n";
282         }
283         else {
284           tree->Save((unsigned char*) filename.substr(0,filename.size()-4).c_str());
285         };
286
287       };
288     }
289     catch (const std::exception& e){
290       std::cout << "Error during parsing : " << e.what() << "\n";
291       return 2;
292     };
293   };    
294   traversal(tree,tree->Root(),tagname);
295
296
297
298   PRINTSTATS(Tag);
299   PRINTSTATS(FirstChild);
300   PRINTSTATS(NextSibling);
301   PRINTSTATS(Parent);
302   PRINTSTATS(TaggedAncestor);
303   PRINTSTATS(TaggedChild);
304   PRINTSTATS(DocIds);
305   PRINTSTATS(TaggedDesc);
306   PRINTSTATS(TaggedFoll);
307   PRINTSTATS(PrevText);
308   PRINTSTATS(MyText);
309   PRINTSTATS(NextText);
310   PRINTSTATS(ParentNode);
311   PRINTSTATS(PrevNode);
312   std::cout << "\n";
313
314   if (target_tag == -1){
315     std::cout << "Warning:  tag " << tagname << " was not found in the document!\n"
316               << "Warning:  not timing traversal and jumping functions\n";
317     return 3;
318   };
319   
320   STARTTIMER();
321   count1 = time_traversal(tree,tree->Root());
322   STOPTIMER(FullTraversal);
323   
324   count2 = time_jump(tree,tree->Root(),tree->Root());
325   STOPTIMER(JumpTraversal);
326   
327   std::cout << "Full traversal found " << count1 << " " << tagname << "  nodes\n";
328   PRINTSTATS(FullTraversal);
329   std::cout << "\n";
330   std::cout << "Jump traversal found " << count2 << " " << tagname << "  nodes\n";
331   PRINTSTATS(JumpTraversal);
332   
333   
334   return 0;
335   
336 }