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