+/**
+ * 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))));
+}
+
+NoAlloc extern "C" value caml_xml_tree_child(value tree, value node,value idx){
+ return (Val_int(XMLTREE(tree)->Child(TREENODEVAL(node),Int_val(idx))));
+}
+
+NoAlloc extern "C" value caml_xml_tree_first_child(value tree, value node){
+ return (Val_int(XMLTREE(tree)->FirstChild(TREENODEVAL(node))));
+}
+
+NoAlloc extern "C" value caml_xml_tree_first_element(value tree, value node){
+ return (Val_int(XMLTREE(tree)->FirstElement(TREENODEVAL(node))));
+}
+
+NoAlloc extern "C" value caml_xml_tree_last_child(value tree, value node){
+ return (Val_int(XMLTREE(tree)->LastChild(TREENODEVAL(node))));
+}
+
+NoAlloc extern "C" value caml_xml_tree_next_sibling(value tree, value node){
+ return (Val_int(XMLTREE(tree)->NextSibling(TREENODEVAL(node))));
+}
+
+NoAlloc extern "C" value caml_xml_tree_next_element(value tree, value node){
+ return (Val_int(XMLTREE(tree)->NextElement(TREENODEVAL(node))));
+}
+
+NoAlloc extern "C" value caml_xml_tree_prev_sibling(value tree, value node){
+ return (Val_int(XMLTREE(tree)->PrevSibling(TREENODEVAL(node))));
+}
+
+NoAlloc extern "C" value caml_xml_tree_tagged_child(value tree, value node,value tag){
+ return (Val_int(XMLTREE(tree)->TaggedChild(TREENODEVAL(node),TAGVAL(tag))));
+}
+
+NoAlloc extern "C" value caml_xml_tree_select_child(value tree, value node,value tags){
+ return (Val_int(XMLTREE(tree)->SelectChild(TREENODEVAL(node), HSET(tags))));
+}
+
+NoAlloc extern "C" value caml_xml_tree_tagged_following_sibling(value tree, value node,value tag){
+ return (Val_int(XMLTREE(tree)->TaggedFollowingSibling(TREENODEVAL(node),TAGVAL(tag))));
+}
+
+NoAlloc extern "C" value caml_xml_tree_select_following_sibling(value tree, value node,value tags){
+ return (Val_int(XMLTREE(tree)->SelectFollowingSibling(TREENODEVAL(node), HSET(tags))));
+}
+
+NoAlloc extern "C" value caml_xml_tree_tagged_descendant(value tree, value node, value tag){
+ return (Val_int(XMLTREE(tree)->TaggedDescendant(TREENODEVAL(node), TAGVAL(tag))));
+}
+
+NoAlloc extern "C" value caml_xml_tree_select_descendant(value tree, value node, value tags){
+ return (Val_int(XMLTREE(tree)->SelectDescendant(TREENODEVAL(node), HSET(tags))));
+}
+
+NoAlloc extern "C" value caml_xml_tree_tagged_preceding(value tree, value node, value tag){
+ return (Val_int(XMLTREE(tree)->TaggedPreceding(TREENODEVAL(node), TAGVAL(tag))));
+}
+
+NoAlloc extern "C" value caml_xml_tree_tagged_following(value tree, value node, value tag){
+ return (Val_int(XMLTREE(tree)->TaggedFollowing(TREENODEVAL(node), TAGVAL(tag))));
+}
+
+NoAlloc extern "C" value caml_xml_tree_tagged_following_below(value tree, value node, value tag, value ancestor){
+ return (Val_int(XMLTREE(tree)->TaggedFollowingBelow(TREENODEVAL(node), TAGVAL(tag), TREENODEVAL(ancestor))));
+}
+
+NoAlloc extern "C" value caml_xml_tree_select_following_below(value tree, value node, value tags, value ancestor){
+ return (Val_int(XMLTREE(tree)->SelectFollowingBelow(TREENODEVAL(node), HSET(tags), TREENODEVAL(ancestor))));
+}
+
+NoAlloc extern "C" value caml_xml_tree_tagged_following_before(value tree, value node, value tag, value closing){
+ return (Val_int(XMLTREE(tree)->TaggedFollowingBefore(TREENODEVAL(node), TAGVAL(tag), TREENODEVAL(closing))));
+}
+
+NoAlloc extern "C" value caml_xml_tree_select_following_before(value tree, value node, value tags, value closing){
+ return (Val_int(XMLTREE(tree)->SelectFollowingBefore(TREENODEVAL(node), HSET(tags), TREENODEVAL(closing))));
+}
+
+NoAlloc extern "C" value caml_xml_tree_tagged_ancestor(value tree, value node, value tag){
+ return (Val_int(XMLTREE(tree)->TaggedAncestor(TREENODEVAL(node), TAGVAL(tag))));
+}
+
+NoAlloc extern "C" value caml_xml_tree_my_text(value tree, value node){
+ return (Val_int(XMLTREE(tree)->MyText(TREENODEVAL(node))));
+}
+
+NoAlloc extern "C" value caml_xml_tree_my_text_unsafe(value tree, value node){
+ return (Val_int(XMLTREE(tree)->MyTextUnsafe(TREENODEVAL(node))));
+}
+
+NoAlloc extern "C" value caml_xml_tree_text_xml_id(value tree, value docid){
+ return (Val_int(XMLTREE(tree)->TextXMLId(Int_val(docid))));
+}
+
+NoAlloc extern "C" value caml_xml_tree_node_xml_id(value tree, value node){
+ return (Val_int(XMLTREE(tree)->NodeXMLId(TREENODEVAL(node))));
+}
+
+NoAlloc extern "C" value caml_xml_tree_parent_node(value tree, value docid){
+ return (Val_int(XMLTREE(tree)->ParentNode(Int_val(docid))));
+}
+/*
+NoAlloc extern "C" value caml_xml_tree_prev_node(value tree, value docid){
+ return (Val_int(XMLTREE(tree)->PrevNode(Int_val(docid))));
+}
+*/
+extern "C" value caml_xml_tree_get_tag_id(value tree, value tagname){
+ CAMLparam2(tree,tagname);
+ CAMLlocal1(res);
+ unsigned char* ctagname = (unsigned char*) strdup(String_val(tagname));
+ res = Val_int(XMLTREE(tree)->GetTagId(ctagname));
+ free(ctagname);
+ CAMLreturn(res);
+}
+
+extern "C" value caml_xml_tree_get_tag_name(value tree, value tag){
+ CAMLparam2(tree,tag);
+ CAMLlocal1(res);
+ res = caml_copy_string((const char*) XMLTREE(tree)->GetTagNameByRef(TAGVAL(tag)));
+ CAMLreturn(res);
+}
+
+extern "C" value caml_xml_tree_register_tag(value tree, value tagname){
+ CAMLparam2(tree,tagname);
+ CAMLlocal1(res);
+ unsigned char* ctagname = (unsigned char*) strdup(String_val(tagname));
+ res = Val_int(XMLTREE(tree)->RegisterTag(ctagname));
+ free(ctagname);
+ CAMLreturn(res);
+}
+
+
+NoAlloc extern "C" value caml_xml_tree_get_text_collection(value tree){
+ return((value) XMLTREE(tree)->getTextCollection());
+}
+
+NoAlloc extern "C" value caml_xml_tree_closing(value tree, value node){
+ return (Val_int(XMLTREE(tree)->Closing(TREENODEVAL(node))));
+}
+
+NoAlloc extern "C" value caml_xml_tree_is_open(value tree, value node){
+ return (Val_bool(XMLTREE(tree)->IsOpen(TREENODEVAL(node))));
+}
+
+
+
+NoAlloc extern "C" value caml_xml_tree_nullt(value unit){
+ return (NULLT);
+}
+
+NoAlloc extern "C" value caml_unordered_set_length(value hset){
+ return (Val_int((HSET(hset))->size()));