+/**
+ * Full reporting queries
+ */
+
+extern "C" value caml_text_collection_prefix(value tree,value str){
+ CAMLparam2(tree,str);
+ CAMLlocal1(resarray);
+ uchar * cstr = (uchar *) String_val(str);
+ std::vector<DocID> results = XMLTREE(tree)->Prefix(cstr);
+ CAMLreturn (sort_alloc_array(results,resarray));
+}
+
+extern "C" value caml_text_collection_suffix(value tree,value str){
+ CAMLparam2(tree,str);
+ CAMLlocal1(resarray);
+ uchar * cstr = (uchar *) String_val(str);
+ std::vector<DocID> results = XMLTREE(tree)->Suffix(cstr);
+ CAMLreturn (sort_alloc_array(results,resarray));
+}
+
+extern "C" value caml_text_collection_equals(value tree,value str){
+ CAMLparam2(tree,str);
+ CAMLlocal1(resarray);
+ uchar * cstr = (uchar *) strdup(String_val(str));
+ std::vector<DocID> results = XMLTREE(tree)->Equals(cstr);
+ free(cstr);
+ CAMLreturn (sort_alloc_array(results,resarray));
+}
+
+extern "C" value caml_text_collection_contains(value tree,value str){
+ CAMLparam2(tree,str);
+ CAMLlocal1(resarray);
+ uchar * cstr = (uchar *) String_val(str);
+ std::vector<DocID> results = XMLTREE(tree)->Contains(cstr);
+ CAMLreturn (sort_alloc_array(results,resarray));
+}
+
+extern "C" value caml_text_collection_lessthan(value tree,value str){
+ CAMLparam2(tree,str);
+ CAMLlocal1(resarray);
+ uchar * cstr = (uchar *) String_val(str);
+ std::vector<DocID> results = XMLTREE(tree)->LessThan(cstr);
+ CAMLreturn (sort_alloc_array(results,resarray));
+}
+
+/** Full reporting into a bit vector
+ */
+
+extern "C" value caml_text_collection_prefix_bv(value tree,value str){
+ CAMLparam2(tree,str);
+ uchar * cstr = (uchar *) strdup(String_val(str));
+ std::vector<DocID> results = XMLTREE(tree)->Prefix(cstr);
+ std::vector<bool> *bv = new std::vector<bool>(XMLTREE(tree)->Size(),false);
+ for (unsigned int i=0; i < results.size(); i++)
+ bv->at(XMLTREE(tree)->ParentNode(results[i]))=true;
+ free(cstr);
+ CAMLreturn ((value) bv);
+}
+
+extern "C" value caml_text_collection_suffix_bv(value tree,value str){
+ CAMLparam2(tree,str);
+ uchar * cstr = (uchar *) strdup(String_val(str));
+ std::vector<DocID> results = XMLTREE(tree)->Suffix(cstr);
+ std::vector<bool> *bv = new std::vector<bool>(XMLTREE(tree)->Size(),false);
+ for (unsigned int i=0; i < results.size(); i++)
+ bv->at(XMLTREE(tree)->ParentNode(results[i]))=true;
+ free(cstr);
+ CAMLreturn ((value) bv);
+}
+
+extern "C" value caml_text_collection_equals_bv(value tree,value str){
+ CAMLparam2(tree,str);
+ uchar * cstr = (uchar *) strdup(String_val(str));
+ XMLTree* xt = XMLTREE(tree);
+ std::vector<DocID> results = xt->Equals(cstr);
+ std::vector<bool> *bv = new std::vector<bool>(xt->Size(),false);
+ for (unsigned int i=0; i < results.size(); i++)
+ bv->at(xt->Parent(xt->ParentNode(results[i])))=true;
+ free(cstr);
+ CAMLreturn ((value) bv);
+}
+
+
+extern "C" value caml_text_collection_contains_bv(value tree,value str){
+ CAMLparam2(tree,str);
+ uchar * cstr = (uchar *) strdup(String_val(str));
+ XMLTree* xt = XMLTREE(tree);
+ std::vector<DocID> results = xt->Contains(cstr);
+ std::vector<bool> *bv = new std::vector<bool>(xt->Size(),false);
+ for (unsigned int i=0; i < results.size(); i++){
+ bv->at(xt->Parent(xt->ParentNode(results[i])))=true;
+ }
+ free(cstr);
+ CAMLreturn ((value) bv);
+}
+
+extern "C" value caml_text_collection_contains_bv_update(value tree,value str,value vbv){
+ CAMLparam3(tree,str,vbv);
+ uchar * cstr = (uchar *) strdup(String_val(str));
+ XMLTree* xt = XMLTREE(tree);
+ std::vector<DocID> results = xt->Contains(cstr);
+ std::vector<bool> *bv = (std::vector<bool> *) vbv;
+ for (unsigned int i=0; i < results.size(); i++){
+ /** Hack for the Techfest demo */
+ (*bv)[xt->Parent(xt->Parent(xt->ParentNode(results[i])))]=true;
+ }
+ free(cstr);
+ CAMLreturn ((value) bv);
+}
+extern "C" value caml_text_collection_contains_bv_update_list(value tree,value str,value acc,value vbv,value count){
+ CAMLparam4(tree,str,acc,vbv);
+ CAMLlocal1(head);
+ uchar * cstr = (uchar *) strdup(String_val(str));
+ XMLTree* xt = XMLTREE(tree);
+ std::vector<DocID> results = xt->Contains(cstr);
+ std::vector<bool> *bv = (std::vector<bool> *) vbv;
+ treeNode idx;
+ int acc_count = Int_val(count);
+ for (unsigned int i=0; i < results.size(); i++){
+ idx = xt->Parent(xt->Parent(xt->ParentNode(results[i])));
+ if (!(*bv)[idx]) {
+ (*bv)[idx]=true;
+ head = caml_alloc_tuple(2);
+ caml_initialize(&Field(head,0),Val_int(idx));
+ caml_initialize(&Field(head,1),acc);
+ acc=head;
+ acc_count++;
+ };
+ };
+ free(cstr);
+ head = caml_alloc_tuple(3);
+ caml_initialize(&Field(head,0),acc);
+ caml_initialize(&Field(head,1),(value) bv);
+ caml_initialize(&Field(head,2),Val_int(acc_count));
+ CAMLreturn (head);
+}
+
+extern "C" value caml_text_collection_lessthan_bv(value tree,value str){
+ CAMLparam2(tree,str);
+ uchar * cstr = (uchar *) strdup(String_val(str));
+ std::vector<DocID> results = XMLTREE(tree)->LessThan(cstr);
+ std::vector<bool> *bv = new std::vector<bool>(XMLTREE(tree)->Size(),false);
+ for (unsigned int i=0; i < results.size(); i++)
+ bv->at(XMLTREE(tree)->ParentNode(results[i]))=true;
+ free(cstr);
+ CAMLreturn ((value) bv);
+}
+
+/*************************************************************************/
+
+/**
+ * XMLTree bindings
+ * All of the functions here call the _unsafe version and implement the logics themselves
+ * (test for NULLT and so on). This avoids one indirection + one call when the tests fails.
+ */
+
+
+NoAlloc extern "C" value caml_xml_tree_root(value tree){
+ return (Val_int(XMLTREE_ROOT));
+}
+
+NoAlloc extern "C" value caml_xml_tree_size(value tree){
+ return (Val_int(XMLTREE(tree)->Size()));
+}
+
+NoAlloc extern "C" value caml_xml_tree_subtree_size(value tree, value node){
+ return (Val_int(XMLTREE(tree)->SubtreeSize(TREENODEVAL(node))));
+}
+
+NoAlloc extern "C" value caml_xml_tree_subtree_tags(value tree, value node, value tag){
+ return (Val_int(XMLTREE(tree)->SubtreeTags(TREENODEVAL(node), TAGVAL(tag))));
+}
+
+NoAlloc extern "C" value caml_xml_tree_subtree_elements(value tree, value node){
+ return (Val_int(XMLTREE(tree)->SubtreeElements(TREENODEVAL(node))));
+}
+
+NoAlloc extern "C" value caml_xml_tree_is_leaf(value tree, value node){
+ return (Val_bool(XMLTREE(tree)->IsLeaf(TREENODEVAL(node))));
+}
+
+NoAlloc extern "C" value caml_xml_tree_is_ancestor(value tree, value node1,value node2){
+ return (Val_bool(XMLTREE(tree)->IsAncestor(TREENODEVAL(node1),TREENODEVAL(node2))));
+}
+
+NoAlloc extern "C" value caml_xml_tree_is_child(value tree, value node1,value node2){
+ return (Val_bool(XMLTREE(tree)->IsChild(TREENODEVAL(node1),TREENODEVAL(node2))));
+}
+
+NoAlloc extern "C" value caml_xml_tree_is_first_child(value tree, value node){
+ return (Val_bool(XMLTREE(tree)->IsFirstChild(TREENODEVAL(node))));
+}
+
+NoAlloc extern "C" value caml_xml_tree_num_children(value tree, value node){
+ return (Val_int(XMLTREE(tree)->NumChildren(TREENODEVAL(node))));
+}
+
+NoAlloc extern "C" value caml_xml_tree_child_number(value tree, value node){
+ return (Val_int(XMLTREE(tree)->ChildNumber(TREENODEVAL(node))));
+}
+
+NoAlloc extern "C" value caml_xml_tree_depth(value tree, value node){
+ return (Val_int(XMLTREE(tree)->Depth(TREENODEVAL(node))));
+}
+
+NoAlloc extern "C" value caml_xml_tree_preorder(value tree, value node){
+ return (Val_int(XMLTREE(tree)->Preorder(TREENODEVAL(node))));
+}
+
+NoAlloc extern "C" value caml_xml_tree_postorder(value tree, value node){
+ return (Val_int(XMLTREE(tree)->Postorder(TREENODEVAL(node))));
+}
+
+NoAlloc extern "C" value caml_xml_tree_tag(value tree, value node){
+ return (Val_int(XMLTREE(tree)->Tag(TREENODEVAL(node))));
+}
+
+extern "C" value caml_xml_tree_doc_ids(value tree, value node){
+ CAMLparam2(tree,node);
+ CAMLlocal1(tuple);
+ range ids;
+ tuple = caml_alloc(2,0);
+ ids = XMLTREE(tree)->DocIds(Int_val(node));
+ Store_field(tuple,0,Val_int(ids.min));
+ Store_field(tuple,1,Val_int(ids.max));
+ CAMLreturn (tuple);
+}
+
+NoAlloc extern "C" value caml_xml_tree_parent(value tree, value node){
+ return (Val_int(XMLTREE(tree)->Parent(TREENODEVAL(node))));