From: nvalimak Date: Tue, 10 Mar 2009 19:08:42 +0000 (+0000) Subject: Added rankLessThan X-Git-Url: http://git.nguyen.vg/gitweb/?a=commitdiff_plain;h=0412eaf977e4ef67f68db6ded4f1cee0e12cee4f;p=SXSI%2FXMLTree.git Added rankLessThan git-svn-id: svn+ssh://idea.nguyen.vg/svn/sxsi/trunk/XMLTree@237 3cdefd35-fc62-479d-8e8d-bae585ffb9ca --- diff --git a/libcds/src/static_sequence/wt_node_internal.cpp b/libcds/src/static_sequence/wt_node_internal.cpp index f5312db..50bb35f 100644 --- a/libcds/src/static_sequence/wt_node_internal.cpp +++ b/libcds/src/static_sequence/wt_node_internal.cpp @@ -159,6 +159,52 @@ uint wt_node_internal::rank(uint symbol, uint pos, uint l, wt_coder * c) { } } +// return value is rank of symbol (less or equal to the given symbol) that has rank > 0, +// the parameter symbol is updated accordinly +uint wt_node_internal::rankLessThan(uint &symbol, uint pos, uint l, wt_coder * c) +{ + bool is_set = c->is_set(symbol,l); + using std::cout; + using std::endl; +// cout << "l = " << l << ", symbol = " << (uchar)symbol << ", rank0 = " << bitmap->rank0(pos) << ", rank1 = " << bitmap->rank1(pos) << endl; + + uint result = -1; + if(!is_set) { + if(left_child==NULL) return -1; + uint rank = bitmap->rank0(pos); + if(rank != 0) + result = left_child->rankLessThan(symbol,rank-1,l+1,c); + return result; + } + + uint rank = bitmap->rank1(pos); + if (rank != 0 && right_child != NULL) + result = right_child->rankLessThan(symbol, rank-1,l+1,c); + +// cout << "recursion to leftchild at l = " << l << ", symbol = " << (uchar)symbol << ", rank0 = " << bitmap->rank0(pos) << ", rank1 = " << bitmap->rank1(pos) << endl; + // check left child for symbols <= givenSymbol + if (result != -1 || left_child == NULL) + return result; + return left_child->rankLessThan(symbol, bitmap->rank0(pos)-1); +} + +uint wt_node_internal::rankLessThan(uint &symbol, uint pos) +{ + uint result = -1; + using std::cout; + using std::endl; +// cout << "pos = " << pos << ", symbol = " << (uchar)symbol << endl; + + if (pos == -1) + return -1; + if(right_child!=NULL) + result = right_child->rankLessThan(symbol, bitmap->rank1(pos)-1); + if(result == -1 && left_child!=NULL) + return left_child->rankLessThan(symbol, bitmap->rank0(pos)-1); + return result; +} + + uint wt_node_internal::select(uint symbol, uint pos, uint l, wt_coder * c) { bool is_set = c->is_set(symbol, l); uint ret = 0; @@ -190,6 +236,45 @@ uint wt_node_internal::access(uint pos) { } } +// Returns the value at given position and its rank +uint wt_node_internal::access(uint pos, uint &rank) +{ + // p is the internal node we are pointing our finger at each step + wt_node_internal *p = this; + + while(1) + { + bool is_set = p->bitmap->access(pos); +// cout << "is_set = " << is_set << ", pos = " << pos << ", rank0 = " << bitmap->rank0(pos) << ", rank1 = " << bitmap->rank1(pos) << endl; + if(!is_set) + { + // recurse left + pos = p->bitmap->rank0(pos)-1; + wt_node_internal *tmp = dynamic_cast(p->left_child); + if (tmp == NULL) + { + // it's a leaf + rank = pos+1; + return p->left_child->access(0); + } + p = tmp; // new internal node + } + else + { + // recurse right + pos = p->bitmap->rank1(pos)-1; + wt_node_internal *tmp = dynamic_cast(p->right_child); + if (tmp == NULL) + { + // it's a leaf + rank = pos+1; + return p->right_child->access(0); + } + p = tmp; // new internal node + } + } +} + uint wt_node_internal::size() { uint s = bitmap->size()+sizeof(wt_node_internal); if(left_child!=NULL) diff --git a/libcds/src/static_sequence/wt_node_internal.h b/libcds/src/static_sequence/wt_node_internal.h index b39efbd..fed8e17 100644 --- a/libcds/src/static_sequence/wt_node_internal.h +++ b/libcds/src/static_sequence/wt_node_internal.h @@ -40,8 +40,11 @@ class wt_node_internal: public wt_node { wt_node_internal(uchar * seq, uint n, uint l, wt_coder * c, static_bitsequence_builder * bmb); virtual ~wt_node_internal(); virtual uint rank(uint symbol, uint pos, uint level, wt_coder * c); + virtual uint rankLessThan(uint &symbol, uint pos, uint level, wt_coder * c); + virtual uint rankLessThan(uint &symbol, uint pos); virtual uint select(uint symbol, uint pos, uint level, wt_coder * c); virtual uint access(uint pos); + virtual uint access(uint pos, uint &rank); virtual uint size(); virtual uint save(FILE *fp); static wt_node_internal * load(FILE *fp);