- Added an option to disable the TextCollection.
[SXSI/XMLTree.git] / XMLTree.cpp
index b5e53a7..ecc9a27 100644 (file)
@@ -101,7 +101,7 @@ XMLTree *XMLTree::Load(unsigned char *filename, int sample_rate_text)
     if (!(XML_Tree->indexing_empty_texts)) XML_Tree->EBVector = static_bitsequence_rrr02::load(fp);\r
 \r
     // loads the tags\r
-    XML_Tree->Tags = static_sequence_wvtree::load(fp);\r
+    XML_Tree->Tags = static_sequence::load(fp);\r
 \r
     // loads the texts   \r
     XML_Tree->Text->Load(fp,sample_rate_text);\r
@@ -126,16 +126,16 @@ XMLTree::~XMLTree()
     free(TagName);\r
 \r
     if (!indexing_empty_texts) {\r
-       EBVector->~static_bitsequence_rrr02();\r
+       //EBVector->~static_bitsequence_rrr02();\r
        delete EBVector;\r
        EBVector = NULL;\r
     }\r
 \r
-    Tags->~static_sequence_wvtree();\r
+    //Tags->~static_sequence_wvtree();\r
     delete Tags;\r
     Tags = NULL;\r
 \r
-    Text->~TextCollection();\r
+    //Text->~TextCollection();\r
     delete Text;\r
     Text = NULL;\r
 \r
@@ -311,8 +311,10 @@ treeNode XMLTree::Parent(treeNode x)
        fprintf(stderr, "Error: data structure has not been constructed properly\n");\r
        exit(1);\r
     }\r
-\r
-    return parent(Par, x);\r
+    if (x == Root())\r
+      return NULLT;\r
+    else\r
+      return parent(Par, x);\r
  }\r
 \r
 // Child(x,i): returns the i-th child of node x, assuming it exists.\r
@@ -345,7 +347,9 @@ treeNode XMLTree::NextSibling(treeNode x)
        fprintf(stderr, "Error: data structure has not been constructed properly\n");\r
        exit(1);\r
     }\r
-\r
+    if (x == Root())\r
+      return NULLT;\r
\r
     return next_sibling(Par, x);\r
  }\r
 \r
@@ -566,22 +570,23 @@ treeNode XMLTree::ParentNode(DocID d)
 // OpenDocument(empty_texts): it starts the construction of the data structure for\r
 // the XML document. Parameter empty_texts indicates whether we index empty texts\r
 // in document or not. Returns a non-zero value upon success, NULLT in case of error.\r
-int XMLTree::OpenDocument(bool empty_texts, int sample_rate_text)\r
+int XMLTree::OpenDocument(bool empty_texts, int sample_rate_text,bool dtc)\r
  {\r
     initialized = true;\r
     finished = false;\r
+    found_attributes = false;\r
     npar = 0;\r
-    ntagnames = 0;\r
+    parArraySize = 1;\r
+    ntagnames = 2;    \r
+    disable_tc = dtc;\r
     \r
     indexing_empty_texts = empty_texts;\r
     \r
-    par_aux = (pb *)malloc(sizeof(pb));\r
+    par_aux = (pb *)malloc(sizeof(pb)*parArraySize);\r
     if (!par_aux) {\r
        fprintf(stderr, "Error: not enough memory\n");\r
        return NULLT;\r
     }\r
-    setbit(par_aux,npar,OP);  // marks a new opening parenthesis for the tree root\r
-    npar++;\r
     \r
     tags_aux = (TagType *) malloc(sizeof(TagType));\r
     if (!tags_aux) {\r
@@ -589,7 +594,28 @@ int XMLTree::OpenDocument(bool empty_texts, int sample_rate_text)
        return NULLT;\r
     }\r
     \r
-    TagName = NULL;\r
+    TagName = (unsigned char **) malloc(2*sizeof(unsigned char*));\r
+    if (!TagName){\r
+       fprintf(stderr, "Error: not enough memory\n");\r
+       return NULLT;\r
+    }\r
+\r
+    TagName[0] = (unsigned char *) malloc(4*sizeof(unsigned char));\r
+    strcpy((char *) TagName[0], "<@>");\r
+\r
+    if (!TagName[0]){\r
+      fprintf(stderr, "Error: not enough memory\n");\r
+      return NULLT;\r
+    }\r
+\r
+    TagName[1] = (unsigned char *) malloc(4*sizeof(unsigned char));\r
+    if (!TagName[1]){\r
+      fprintf(stderr, "Error: not enough memory\n");\r
+      return NULLT;\r
+    }\r
+\r
+    strcpy((char *) TagName[1], "<$>");\r
+\r
 \r
     if (!indexing_empty_texts) {\r
        empty_texts_aux = (unsigned int *)malloc(sizeof(unsigned int));\r
@@ -621,24 +647,38 @@ int XMLTree::CloseDocument()
        fprintf(stderr, "Error: not enough memory\n");\r
        return NULLT;    \r
     }\r
-    setbit(par_aux,npar,CP); \r
-    npar++;\r
     \r
     // creates the data structure for the tree topology\r
-    Par = (bp *)malloc(sizeof(bp));      \r
+    Par = (bp *)malloc(sizeof(bp));\r
     bp_construct(Par, npar, par_aux, OPT_DEGREE|0);    \r
     // creates structure for tags\r
-    alphabet_mapper * am = new alphabet_mapper_none();\r
-    static_bitsequence_builder * bmb = new static_bitsequence_builder_rrr02(32); \r
-    wt_coder * wtc = new wt_coder_huff((uint *)tags_aux,npar-1,am);\r
-    Tags = new static_sequence_wvtree((uint *) tags_aux, (uint) npar-1, wtc, bmb, am);\r
+    static_bitsequence_builder * bmb = new static_bitsequence_builder_brw32(20);\r
+    static_permutation_builder * pmb = new static_permutation_builder_mrrr(PERM_SAMPLE, bmb);\r
+    static_sequence_builder * ssb = new static_sequence_builder_gmr_chunk(bmb, pmb);\r
+\r
+\r
+    // If we found an attribute then "<@>" is present in the tree\r
+    // if we didn't then it is not. "<$>" is never present in the tree\r
+    int ntagsize = found_attributes ? 2*ntagnames-1 : 2*ntagnames - 2;\r
 \r
+    Tags = new static_sequence_gmr((uint *) tags_aux, (uint) npar-1,ntagsize, bmb, ssb);\r
+    \r
+    delete bmb;\r
+    delete pmb;\r
+    delete ssb;\r
     // makes the text collection static\r
-    Text->MakeStatic();\r
+    if (!disable_tc)\r
+      Text->MakeStatic();\r
     \r
     // creates the data structure marking the non-empty texts (just in the case it is necessary)\r
-    if (!indexing_empty_texts) \r
+    if (!indexing_empty_texts)  {\r
        EBVector = new static_bitsequence_rrr02((uint *)empty_texts_aux,(ulong)npar,(uint)32);\r
+       free (empty_texts_aux);\r
+       empty_texts_aux = NULL;\r
+    }\r
+   \r
+    free(tags_aux);\r
+    tags_aux = NULL;\r
 \r
     finished = true;\r
 \r
@@ -659,7 +699,11 @@ int XMLTree::NewOpenTag(unsigned char *tagname)
     }\r
     \r
     // inserts a new opening parentheses in the bit sequence\r
-    par_aux = (pb *)realloc(par_aux, sizeof(pb)*(1+npar/(8*sizeof(pb))));\r
+    if (sizeof(pb)*8*parArraySize == npar) { // no space left for the new parenthesis\r
+       par_aux = (pb *)realloc(par_aux, sizeof(pb)*2*parArraySize);\r
+       parArraySize *= 2;\r
+    }\r
+    \r
     if (!par_aux) {\r
        fprintf(stderr, "Error: not enough memory\n");\r
        return NULLT;    \r
@@ -670,8 +714,13 @@ int XMLTree::NewOpenTag(unsigned char *tagname)
     // transforms the tagname into a tag identifier. If the tag is new, we insert\r
     // it in the table.\r
     for (i=0; i<ntagnames; i++)\r
-       if (strcmp((const char *)tagname,(const char *)TagName[i])==0) break;\r
+      if (strcmp((const char *)tagname,(const char *)TagName[i])==0) break;\r
  \r
+\r
+    // NewOpenTag("<@>") was called\r
+    if (i==0) \r
+      found_attributes=true;\r
+\r
     if (i==ntagnames) { // the tag is a new one, then we insert it\r
        TagName = (unsigned char **)realloc(TagName, sizeof(char *)*(ntagnames+1));\r
        \r
@@ -712,7 +761,11 @@ int XMLTree::NewClosingTag(unsigned char *tagname)
     }\r
     \r
     // inserts a new closing parentheses in the bit sequence\r
-    par_aux = (pb *)realloc(par_aux, sizeof(pb)*(1+npar/(8*sizeof(pb))));\r
+    if (sizeof(pb)*8*parArraySize == npar) { // no space left for the new parenthesis\r
+       par_aux = (pb *)realloc(par_aux, sizeof(pb)*2*parArraySize);\r
+       parArraySize *= 2;\r
+    }\r
+    \r
     if (!par_aux) {\r
        fprintf(stderr, "Error: not enough memory\n");\r
        return NULLT;    \r
@@ -764,6 +817,11 @@ int XMLTree::NewText(unsigned char *s)
        return NULLT;\r
     }\r
 \r
+    if (disable_tc) {\r
+      XMLTree::NewEmptyText();\r
+      return 1;\r
+    };\r
+\r
     if (!indexing_empty_texts) {\r
        empty_texts_aux = (unsigned int *)realloc(empty_texts_aux, sizeof(pb)*(1+(npar-1)/(8*sizeof(pb))));\r
        if (!empty_texts_aux) {\r
@@ -833,4 +891,19 @@ unsigned char *XMLTree::GetTagName(TagType tagid)
  }\r
 \r
 \r
-\r
+TagType XMLTree::RegisterTag(unsigned char *tagname)\r
+{\r
+  if (!finished)\r
+    return NULLT;\r
+  \r
+\r
+  TagType id = XMLTree::GetTagId(tagname);\r
+  if (id == NULLT){\r
+    id = ntagnames;\r
+    ntagnames = ntagnames + 1;    \r
+    TagName = (unsigned char **) realloc(TagName,ntagnames*(sizeof(unsigned char*)));\r
+    strcpy((char*)TagName[id], (const char *)tagname);  \r
+  };\r
+\r
+  return id;\r
+}\r