+ catch (const xmlpp::internal_error& e){ CAMLRAISEMSG(e.what()); }
+ catch (const std::exception& e){ CAMLRAISEMSG(e.what()); }
+ catch (string msg){ CAMLRAISEMSG(msg.c_str()); }
+ catch (char const * msg){ CAMLRAISEMSG(msg); };
+}
+
+
+/**
+ * Interface to the TextCollection
+ */
+
+/**
+ * Utility functions
+ */
+
+extern "C" value caml_text_collection_get_text(value tree, value id){
+ CAMLparam2(tree,id);
+ CAMLlocal1(str);
+ uchar* txt = XMLTREE(tree)->GetText((DocID) Int_val(id));
+ str = caml_copy_string((const char*)txt);
+ CAMLreturn (str);
+}
+
+
+extern "C" value caml_text_collection_empty_text(value tree,value id){
+ CAMLparam2(tree,id);
+ CAMLreturn ( Val_int((XMLTREE(tree))->EmptyText((DocID) Int_val(id))));
+}
+
+bool docId_comp(DocID x, DocID y) { return x < y; };
+
+/**
+ * Existential queries
+ */
+
+extern "C" value caml_text_collection_is_prefix(value tree,value str){
+ CAMLparam2(tree,str);
+ uchar * cstr = (uchar *) String_val(str);
+ CAMLreturn (Val_bool((int) XMLTREE(tree)->IsPrefix(cstr)));
+}
+
+extern "C" value caml_text_collection_is_suffix(value tree,value str){
+ CAMLparam2(tree,str);
+ uchar * cstr = (uchar *) String_val(str);
+ CAMLreturn (Val_bool((int) XMLTREE(tree)->IsSuffix(cstr)));
+}
+extern "C" value caml_text_collection_is_equal(value tree,value str){
+ CAMLparam2(tree,str);
+ uchar * cstr = (uchar *) String_val(str);
+ CAMLreturn (Val_bool((int) XMLTREE(tree)->IsEqual(cstr)));
+}
+extern "C" value caml_text_collection_is_contains(value tree,value str){
+ CAMLparam2(tree,str);
+ uchar * cstr = (uchar *) String_val(str);
+ CAMLreturn ( Val_bool((int) XMLTREE(tree)->IsContains(cstr)));
+}
+
+extern "C" value caml_text_collection_is_lessthan(value tree,value str){
+ CAMLparam2(tree,str);
+ uchar * cstr = (uchar *) String_val(str);
+ CAMLreturn ( Val_bool((int) XMLTREE(tree)->IsLessThan(cstr)));
+}
+
+
+/**
+ * Count Queries
+ */
+
+/**
+ * Global counting
+ */
+extern "C" value caml_text_collection_count(value tree,value str){
+ CAMLparam2(tree,str);
+ uchar * cstr = (uchar *) String_val(str);
+ CAMLreturn (Val_int((XMLTREE(tree)->Count(cstr))));
+}
+
+extern "C" value caml_text_collection_count_prefix(value tree,value str){
+ CAMLparam2(tree,str);
+ uchar * cstr = (uchar *) String_val(str);
+ CAMLreturn (Val_int((XMLTREE(tree)->CountPrefix(cstr))));
+}
+
+extern "C" value caml_text_collection_count_suffix(value tree,value str){
+ CAMLparam2(tree,str);
+ uchar * cstr = (uchar *) String_val(str);
+ CAMLreturn (Val_int((XMLTREE(tree)->CountSuffix(cstr))));
+}
+
+extern "C" value caml_text_collection_count_equal(value tree,value str){
+ CAMLparam2(tree,str);
+ uchar * cstr = (uchar *) String_val(str);
+ CAMLreturn (Val_int((XMLTREE(tree)->CountEqual(cstr))));
+}
+
+extern "C" value caml_text_collection_count_contains(value tree,value str){
+ CAMLparam2(tree,str);
+ uchar * cstr = (uchar *) String_val(str);
+ CAMLreturn (Val_int((XMLTREE(tree)->CountContains(cstr))));
+}
+
+extern "C" value caml_text_collection_count_lessthan(value tree,value str){
+ CAMLparam2(tree,str);
+ uchar * cstr = (uchar *) String_val(str);
+ CAMLreturn (Val_int((XMLTREE(tree)->CountLessThan(cstr))));
+}
+
+static value sort_alloc_array(std::vector<DocID> results, value resarray){
+ std::sort(results.begin(), results.end(), docId_comp);
+ size_t s = results.size();
+ resarray = caml_alloc_tuple(s);
+ for (size_t i = 0; i < s ;i++){
+ caml_initialize(&Field(resarray,i),Val_int(results[i]));
+ };
+ return resarray;
+
+}
+
+/**
+ * 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++;
+ };