- Implement popcount in ASM if available
[SXSI/XMLTree.git] / XMLTreeBuilder.cpp
1 #include "basics.h"\r
2 #include "XMLTreeBuilder.h"\r
3 #include "timings.h"\r
4 using std::string;\r
5 \r
6 XMLTreeBuilder::~XMLTreeBuilder(){\r
7   \r
8 }\r
9 \r
10 // OpenDocument(empty_texts): it starts the construction of the data structure for\r
11 // the XML document. Parameter empty_texts indicates whether we index empty texts\r
12 // in document or not. Returns a non-zero value upon success, NULLT in case of error.\r
13 int XMLTreeBuilder::OpenDocument(bool empty_texts, \r
14                                  int sample_rate_text,\r
15                                  bool dtc,\r
16                                  TextCollectionBuilder::index_type_t index_type)\r
17  {\r
18     npar = 0;\r
19     parArraySize = 1;\r
20     disable_tc = dtc;\r
21     text_index_type = index_type;\r
22     STARTTIMER();\r
23    \r
24     par_aux = (pb *)umalloc(sizeof(pb)*parArraySize);\r
25     \r
26     tags_aux = (TagType *) umalloc(sizeof(TagType));\r
27     \r
28     TagName = new vector<string>();\r
29     tIdMap = new std::unordered_map<string,int>();\r
30 \r
31     REGISTER_TAG(TagName,tIdMap,DOCUMENT_OPEN_TAG);\r
32     REGISTER_TAG(TagName,tIdMap,ATTRIBUTE_OPEN_TAG);\r
33     REGISTER_TAG(TagName,tIdMap,PCDATA_OPEN_TAG);\r
34     REGISTER_TAG(TagName,tIdMap,ATTRIBUTE_DATA_OPEN_TAG);\r
35     REGISTER_TAG(TagName,tIdMap,CLOSING_TAG);\r
36     REGISTER_TAG(TagName,tIdMap,DOCUMENT_CLOSE_TAG);\r
37     REGISTER_TAG(TagName,tIdMap,ATTRIBUTE_CLOSE_TAG);\r
38     REGISTER_TAG(TagName,tIdMap,PCDATA_CLOSE_TAG);\r
39     REGISTER_TAG(TagName,tIdMap,ATTRIBUTE_DATA_CLOSE_TAG);\r
40 \r
41 \r
42     if (disable_tc)\r
43         TextBuilder = 0;\r
44     else \r
45         TextBuilder = TextCollectionBuilder::create((unsigned)sample_rate_text, index_type);\r
46 \r
47     Text = 0;\r
48     empty_texts_aux = (unsigned int *)ucalloc(sizeof(unsigned int),1);\r
49     eta_size = sizeof(unsigned int);\r
50     return 1;  // indicates success in the initialization of the data structure\r
51  }\r
52 \r
53 // CloseDocument(): it finishes the construction of the data structure for the XML\r
54 // document. Tree and tags are represented in the final form, dynamic data \r
55 // structures are made static, and the flag "finished" is set to true. After that, \r
56 // the data structure can be queried.\r
57 XMLTree *XMLTreeBuilder::CloseDocument()\r
58  {    \r
59     //closing parenthesis for the tree root\r
60     //par_aux = (pb *)urealloc(par_aux, sizeof(pb)*(1+npar/(8*sizeof(pb))));\r
61     //setbit(par_aux, npar, CP);\r
62     //npar++;\r
63     \r
64     // makes the text collection static\r
65    STOPTIMER(Parsing);\r
66    PRINTTIME("Parsing XML Document", Parsing);\r
67 \r
68     if (!disable_tc) {\r
69        assert(Text == 0);\r
70        assert(TextBuilder != 0);\r
71        STARTTIMER();\r
72        Text = TextBuilder->InitTextCollection();\r
73        delete TextBuilder;\r
74        TextBuilder = 0;\r
75        STOPTIMER(Building);\r
76        PRINTTIME("Building TextCollection", Building);\r
77 \r
78     }\r
79     \r
80     XMLTree *T = new XMLTree(par_aux,\r
81                              npar, \r
82                              TagName,\r
83                              tIdMap,\r
84                              empty_texts_aux,                // freed by the constructor\r
85                              tags_aux,                       //freed by the constructor\r
86                              Text,\r
87                              disable_tc,\r
88                              text_index_type);\r
89     return T; \r
90  }\r
91 \r
92 \r
93 // NewOpenTag(tagname): indicates the event of finding a new opening tag in the document.\r
94 // Tag name is given. Returns a non-zero value upon success, and returns NULLT\r
95 // in case of failing when trying to insert the new tag.\r
96 int XMLTreeBuilder::NewOpenTag(string tagname)\r
97  {\r
98     int i;\r
99     \r
100     // inserts a new opening parentheses in the bit sequence\r
101     if (sizeof(pb)*8*parArraySize == npar) { // no space left for the new parenthesis\r
102        par_aux = (pb *)urealloc(par_aux, sizeof(pb)*2*parArraySize);\r
103        parArraySize *= 2;\r
104     }\r
105     \r
106     setbit(par_aux,npar,OP);  // marks a new opening parenthesis\r
107     \r
108     TagIdMapIT tag_id = tIdMap->find(tagname);\r
109    \r
110     if (tag_id == tIdMap->end()){\r
111       REGISTER_TAG(TagName,tIdMap,tagname);\r
112       i = TagName->size() - 1;\r
113     }\r
114     else\r
115       i = tag_id->second;\r
116 \r
117     if (tagname.compare(PCDATA_OPEN_TAG) == 0 ||\r
118         tagname.compare(ATTRIBUTE_DATA_OPEN_TAG) == 0){\r
119     };\r
120     \r
121     tags_aux = (TagType *) urealloc(tags_aux, sizeof(TagType)*(npar + 1));\r
122     \r
123     tags_aux[npar] = i; // inserts the new tag id within the preorder sequence of tags\r
124     \r
125     npar++;\r
126     \r
127     return 1; // success    \r
128  }\r
129 \r
130 \r
131 // NewClosingTag(tagname): indicates the event of finding a new closing tag in the document.\r
132 // Tag name is given. Returns a non-zero value upon success, and returns NULLT\r
133 // in case of failing when trying to insert the new tag.\r
134 int XMLTreeBuilder::NewClosingTag(string tagname)\r
135  {\r
136     int i;\r
137     \r
138     // inserts a new closing parentheses in the bit sequence\r
139     if (sizeof(pb)*8*parArraySize == npar) { // no space left for the new parenthesis\r
140        par_aux = (pb *)urealloc(par_aux, sizeof(pb)*2*parArraySize);\r
141        parArraySize *= 2;\r
142     }\r
143     \r
144     setbit(par_aux,npar,CP);  // marks a new closing parenthesis\r
145     \r
146     //tagname.insert(0,"/");\r
147 \r
148     //TagIdMapIT tag_id = tIdMap->find(tagname);    \r
149 \r
150     // if (tag_id == tIdMap->end()){\r
151     //   REGISTER_TAG(TagName,tIdMap,tagname);\r
152     //   i = TagName->size() - 1;\r
153     // }\r
154     // else\r
155     //   i = tag_id->second;\r
156 \r
157     tags_aux = (TagType *)urealloc(tags_aux, sizeof(TagType)*(npar + 1));\r
158 \r
159     tags_aux[npar] = CLOSING_TAG_ID; // inserts the new tag id within the preorder sequence of tags\r
160     \r
161     npar++;\r
162 \r
163     return 1; // success\r
164  }\r
165 \r
166 \r
167 // NewText(s): indicates the event of finding a new (non-empty) text s in the document.\r
168 // The new text is inserted within the text collection. Returns a non-zero value upon\r
169 // success, NULLT in case of error.\r
170 int XMLTreeBuilder::NewText(string text)\r
171  {\r
172    if (!disable_tc) {\r
173      if  (text.empty())\r
174        TextBuilder->InsertText((uchar *)"\001");\r
175      else\r
176        TextBuilder->InsertText((uchar *) text.c_str());\r
177    };\r
178 \r
179    int n_eta_size = sizeof(uint)*(1+(npar-1)/(8*sizeof(uint)));\r
180    //see basics.h, recalloc resizes and sets the new area to 0.\r
181    \r
182    empty_texts_aux = (uint *)urecalloc(empty_texts_aux,eta_size,n_eta_size);\r
183    eta_size = n_eta_size;\r
184    bitset(empty_texts_aux, npar-1);  // marks the non-empty text with a 1 in the bit vector\r
185 \r
186    return 1; // success\r
187  }\r
188 \r
189 \r