bca2073fd341091422f6930d198b5809fdada8f1
[SXSI/xpathcomp.git] / src / lexindex_stub.cpp
1 #include <cstring>
2 #include <utility>
3 #include <algorithm>
4 #include <vector>
5 #include <array>
6 #include "xml-tree.hpp"
7 #include "utils_stub.hpp"
8 #include <iostream>
9
10 // #include <algorithm>
11 using namespace std;
12
13 struct myclass {
14   xml_tree * tree;
15   bool operator() (int32_t i,int32_t j) { 
16   return (strcmp((const char*) tree->get_text(i),
17                  (const char*) tree->get_text(j))<0);}
18 } myobject;
19
20 //define a type for the lexicographic index
21 class lex_index {
22 public:
23   //The tag IDs
24   xml_tree::tag_t tag;
25   xml_tree::tag_t tag2;
26   //The text data
27   vector<int32_t> tagVector;           
28   vector<int32_t>::iterator tagVectorIt;
29   vector<int32_t> tag2Vector;           
30   vector<int32_t>::iterator tag2VectorIt;
31   void printVector(xml_tree::tag_t t, vector<int32_t> v);
32   void print();
33 };
34
35 void lex_index::printVector(xml_tree::tag_t t, vector<int32_t> v){
36   vector<int32_t>::iterator i=v.begin();
37   if (i!=v.end()) {
38       printf("%i-vector: [%i", t, *i);
39       for (++i; i!=v.end(); ++i)
40         printf(",%i",  *i);
41       printf("]\n");
42     }
43 }
44
45 void lex_index::print(){
46   printf("Print called\n");
47   printVector(tag, tagVector);
48 }
49
50 // class prefix_treeNode {
51 // public:
52   //  std::map<char, prefix_treeNode> Children;
53 //  std::array<prefix_treeNode, 256> Children;
54 //  uint32 textID;
55 //};
56
57 using namespace SXSI;
58
59 static xml_tree*& XMLTREE(value v)
60 {
61   return Obj_val<xml_tree*>(v);
62 }
63
64 static lex_index*& LEXINDEX(value v)
65 {
66   return Obj_val<lex_index*>(v);
67 }
68
69 static xml_tree::node_t TREENODE(value i)
70 {
71   return static_cast<xml_tree::node_t>(Int_val(i));
72 }
73
74 static xml_tree::tag_t TAG(value i)
75 {
76   return static_cast<xml_tree::tag_t>(Int_val(i));
77 }
78
79 void preorderTraverse(xml_tree * tree, xml_tree::tag_t parent_tag, xml_tree::node_t node, lex_index* lindex){  
80   if (tree->tag(node)==tree->PCDATA_OPEN_TAG_ID)
81   if (parent_tag==lindex->tag) lindex->tagVectorIt = 
82                                lindex->tagVector.insert(lindex->tagVectorIt, tree->text_id(node));
83   else if (parent_tag==lindex->tag2) lindex->tag2VectorIt = 
84                                      lindex->tag2Vector.insert(lindex->tag2VectorIt, tree->text_id(node));
85   if (tree->tag(tree->first_child(node))!=0) preorderTraverse(tree,tree->tag(node),tree->first_child(node),lindex);
86   if (tree->tag(tree->next_sibling(node))!=0) preorderTraverse(tree,parent_tag,tree->next_sibling(node),lindex);
87 }
88
89 vector<int32_t> mergeJoin(xml_tree * tree, vector<int32_t> v1, vector<int32_t> v2){
90   vector<int32_t> v;
91   vector<int32_t>::iterator i=v.begin();
92   vector<int32_t>::iterator i1=v1.begin();
93   vector<int32_t>::iterator i2=v2.begin();
94   int k;
95
96   while((i1!=v1.end()) && (i2!=v2.end())){
97     k = strcmp((const char*) tree->get_text(*i1),
98                (const char*) tree->get_text(*i2));
99     if (k==0) 
100       {
101         i = v.insert( i, *i1 );
102         //advance left
103         i1++;
104         //advance right     
105         i2++;
106       }
107     else if (k<0) i1++; //advance left
108     else i2++; //advance right
109   }
110   return(v);
111 }
112
113 void printVector(const char * label, vector<int32_t> v){
114   vector<int32_t>::iterator i=v.begin();
115   if (i!=v.end()) {
116       printf("%s-vector: [%i", label, *i);
117       for (++i; i!=v.end(); ++i)
118         printf(",%i",  *i);
119       printf("]\n");
120     }
121 }
122
123 ML_BINDING value caml_build_lex_index(value vtree, value vtag, value vtag2)
124 {
125   CAMLparam2(vtree, vtag);
126   CAMLlocal1(vindex);
127   vindex = sxsi_alloc_custom<lex_index*>();
128   xml_tree * tree = XMLTREE(vtree);
129   myobject.tree = tree;
130
131   //allocate a lex index
132   lex_index* mylindex = new lex_index();
133
134   //take the tag parameter given by ocaml and convert
135   //it to a C++ tag and store it in the tag field of mylindex
136   if ((TAG(vtag)==-1) || (TAG(vtag2)==-1)) caml_failwith("<INVALID TAG>");
137   mylindex->tag = TAG(vtag);
138   mylindex->tag2 = TAG(vtag2);
139
140   //initialize iterators for the two vectors 
141   mylindex->tagVectorIt=mylindex->tagVector.begin();
142   mylindex->tag2VectorIt=mylindex->tag2Vector.begin();
143
144   preorderTraverse(tree, 0, tree->first_child(tree->ROOT), mylindex);
145   sort(mylindex->tagVector.begin(), mylindex->tagVector.end(), myobject); 
146   sort(mylindex->tag2Vector.begin(), mylindex->tag2Vector.end(), myobject); 
147   printVector(tree->get_tag_name_by_ref(mylindex->tag), mylindex->tagVector);
148   printVector(tree->get_tag_name_by_ref(mylindex->tag2), mylindex->tag2Vector);
149   printVector("Result" , mergeJoin(tree, mylindex->tagVector, mylindex->tag2Vector));
150
151   //Uncomment the following and comment the failwith line
152   //LEXINDEX(vindex) = ... return a lex_index* ....  
153   LEXINDEX(vindex)=mylindex;
154 }
155
156 ML_BINDING value caml_print_lex_index(value vindex)
157 {
158   CAMLparam1(vindex);
159   lex_index* index = LEXINDEX(vindex);
160
161   //Print the index to the terminal
162   //  caml_failwith("print_lex_index not implemented");
163   index->print();
164   CAMLreturn (Val_unit);
165 }