Trie.hh

Go to the documentation of this file.
00001 #ifndef BIT_TRIE_HH
00002 #define BIT_TRIE_HH
00003 
00004 #include "bit/algo.hh"
00005 #include "bit/CompressedArray.hh"
00006 
00007 namespace bit {
00008 
00037   template <class Array>
00038   class Trie {
00039 
00040   public:
00041 
00043     class Iterator {
00044     public:
00045 
00048 
00050       Iterator()
00051         : m_trie(NULL)
00052       {
00053       }
00054 
00059       Iterator(const Trie<Array> &trie)
00060         : m_trie(&trie)
00061       {
00062       }
00063 
00069       Iterator(const Iterator &it, unsigned int length)
00070         : m_trie(it.m_trie)
00071       {
00072         if (length > it.length())
00073           length = it.length();
00074         m_symbol_stack.resize(length);
00075         m_child_limit_stack.resize(length);
00076         for (size_t i = 0; i < length; i++) {
00077           m_symbol_stack[i] = it.m_symbol_stack[i];
00078           m_child_limit_stack[i] = it.m_child_limit_stack[i];
00079         }
00080       }
00081       
00083 
00084 
00085 
00088 
00093       unsigned int length() const
00094       {
00095         return m_symbol_stack.size();
00096       }
00097 
00102       u32 symbol_index(unsigned int level) const
00103       {
00104         if (level >= length())
00105           throw bit::out_of_range(
00106             "bit::Trie::Iterator::symbol_index() level out of range");
00107         assert(!m_symbol_stack.empty());
00108         return m_symbol_stack[level];
00109       }
00110 
00115       u32 symbol_index() const
00116       {
00117         if (is_root())
00118           throw bit::out_of_range(
00119             "bit::Trie::Iterator::symbol_index() called at root node");
00120         return symbol_index(length() - 1);
00121       }
00122 
00128       u32 child_limit_index(unsigned int level) const
00129       {
00130         if (level >= length())
00131           throw bit::out_of_range(
00132             "bit::Trie::Iterator::child_limit_index() level out of range");
00133         assert(!m_child_limit_stack.empty());
00134         return m_child_limit_stack[level];
00135       }
00136 
00142       u32 child_limit_index() const
00143       {
00144         if (is_root())
00145           throw bit::out_of_range(
00146             "bit::Trie::Iterator::child_limit_index() called at root node");
00147         return child_limit_index(length() - 1);
00148       }
00149 
00154       u32 symbol(unsigned int level) const
00155       {
00156         u32 index = symbol_index(level);
00157         return m_trie->symbol_array(level).get(index);
00158       }
00159 
00164       u32 symbol() const
00165       {
00166         if (is_root())
00167           throw bit::out_of_range(
00168             "bit::Trie::Iterator::symbol() called at root node");
00169         u32 index = symbol_index(length() - 1);
00170         return m_trie->symbol_array(length() - 1).get(index);
00171       }
00172 
00174       std::vector<u32> symbol_vec() const
00175       {
00176         std::vector<u32> vec(length());
00177         for (unsigned int l = 0; l < length(); l++)
00178           vec[l] = symbol(l);
00179         return vec;
00180       }
00181 
00188       u32 child_limit(unsigned int level) const
00189       {
00190         u32 index = child_limit_index(level);
00191         if (index == max_u32)
00192           throw bit::invalid_call(
00193             "bit::Trie::child_limit() leaf-node in separated array");
00194 
00195         const Array &array = m_trie->child_limit_array(level);
00196         if (array.num_elems() == 0)
00197           return 0;
00198         if (index >= array.num_elems())
00199           return array.get(array.num_elems() - 1);
00200         return m_trie->child_limit_array(level).get(index);
00201       }
00202 
00207       u32 child_limit() const
00208       {
00209         if (is_root())
00210           return m_trie->num_nodes(0);
00211         return child_limit(length() - 1);
00212       }
00213 
00221       u32 first_child(unsigned int level) const
00222       {
00223         u32 index = child_limit_index(level);
00224         if (index == 0)
00225           return 0;
00226         if (index == max_u32)
00227           throw bit::invalid_call(
00228             "bit::Trie::child_limit() leaf-node in separated array");
00229         const Array &array = m_trie->child_limit_array(level);
00230         if (index > array.num_elems())
00231           return array.get(array.num_elems() - 1);
00232         return array.get(index - 1);
00233       }
00234 
00239       u32 first_child() const
00240       {
00241         if (is_root())
00242           return 0;
00243         return first_child(length() - 1);
00244       }
00245 
00250       u32 first_sibling(unsigned int level) const
00251       {
00252         if (level >= length())
00253           throw bit::out_of_range(
00254             "bit::Trie::first_sibling(): level out of range");
00255         if (level == 0)
00256           return 0;
00257         return first_child(level - 1);
00258       }
00259 
00264       u32 first_sibling() const
00265       {
00266         if (is_root())
00267           throw bit::out_of_range(
00268             "bit::Trie::first_sibling(): called for root");
00269         return first_sibling(length() - 1);
00270       }
00271 
00276       u32 sibling_limit(unsigned int level) const
00277       {
00278         if (level >= length())
00279           throw bit::out_of_range(
00280             "bit::Trie::sibling_limit(): level out of range");
00281         if (level == 0)
00282           return m_trie->num_nodes(0);
00283         return child_limit(level - 1);
00284       }
00285 
00290       u32 sibling_limit() const
00291       {
00292         if (is_root())
00293           throw bit::out_of_range(
00294             "bit::Trie::sibling_limit() called for root");
00295         return sibling_limit(length() - 1);
00296       }
00297 
00299       bool is_root() const 
00300       {
00301         return length() == 0;
00302       }
00303 
00305       bool is_separated_leaf() const
00306       {
00307         return (!is_root() && m_child_limit_stack.back() == max_u32);
00308       }
00309 
00312       u32 num_children(unsigned int level) const
00313       {
00314         if (is_separated_leaf())
00315           return 0;
00316 
00317         u32 child_limit = this->child_limit(level);
00318         if (child_limit == 0)
00319           return 0;
00320         return child_limit - first_child(level);
00321       }
00322 
00324       u32 num_children() const
00325       {
00326         if (is_root())
00327           return m_trie->num_nodes(0);
00328         return num_children(length() - 1);
00329       }
00330 
00332 
00333 
00334 
00337 
00341       Iterator parent() const
00342       {
00343         Iterator it(*this);
00344         if (!it.goto_parent())
00345           throw bit::invalid_call("Trie::Iterator::parent() failed");
00346         return it;
00347       }
00348 
00350       void goto_root()
00351       {
00352         m_symbol_stack.clear();
00353         m_child_limit_stack.clear();
00354       }
00355 
00359       bool goto_parent()
00360       {
00361         if (is_root())
00362           return false;
00363         m_symbol_stack.pop_back();
00364         m_child_limit_stack.pop_back();
00365         return true;
00366       }
00367 
00371       bool goto_first_child()
00372       {
00373         if (is_separated_leaf())
00374           return false;
00375 
00376         u32 child_limit = this->child_limit();
00377         if (child_limit == 0)
00378           return false;
00379         u32 first_child = this->first_child();
00380         assert(first_child <= child_limit);
00381         if (first_child == child_limit)
00382           return false;
00383         
00384         m_symbol_stack.push_back(first_child);
00385         m_child_limit_stack.push_back(
00386           m_trie->compute_non_leaf_index(length() - 1, first_child));
00387         return true;
00388       }
00389 
00394       bool goto_next_sibling()
00395       {
00396         if (is_root())
00397           throw bit::out_of_range(
00398             "bit::Trie::Iterator::goto_next_sibling() called for root");
00399         u32 limit = sibling_limit();
00400         assert(limit > 0);
00401         assert(m_symbol_stack.back() < limit);
00402         if (m_symbol_stack.back() == limit - 1)
00403           return false;
00404         m_symbol_stack.back()++;
00405         m_child_limit_stack.back() =
00406           m_trie->compute_non_leaf_index(length() - 1, m_symbol_stack.back());
00407         return true;
00408       }
00409 
00414       bool goto_child(u32 symbol)
00415       {
00416         if (is_separated_leaf())
00417           return false;
00418 
00419         u32 limit = child_limit();
00420         if (limit == 0)
00421           return false;
00422         u32 first = first_child();
00423         assert(first <= limit);
00424         if (first == limit)
00425           return false;
00426 
00427         const Array &array = m_trie->symbol_array(length());
00428         u64 index = binary_search(array, symbol, first, limit);
00429         if (index == limit)
00430           return false;
00431         m_symbol_stack.push_back(index);
00432         m_child_limit_stack.push_back(
00433           m_trie->compute_non_leaf_index(length() - 1, index));
00434         return true;
00435       }
00436 
00440       bool goto_next_depth_first()
00441       {
00442         if (goto_first_child())
00443           return true;
00444         
00445         while (1) {
00446           if (goto_next_sibling())
00447             return true;
00448           bool ret = goto_parent();
00449           assert(ret);
00450           if (is_root())
00451             return false;
00452         }
00453       }
00454 
00459       bool goto_leaf()
00460       {
00461         bool did_move = false;
00462         while (goto_first_child())
00463           did_move = true;
00464         return did_move;
00465       }
00466 
00474       bool goto_next_depth_first_post()
00475       {
00476         if (is_root())
00477           return goto_leaf();
00478 
00479         if (goto_next_sibling()) {
00480           goto_leaf();
00481           return true;
00482         }
00483 
00484         goto_parent();
00485         if (is_root())
00486           return false;
00487         return true;
00488       }
00489 
00497       bool goto_next_on_level(unsigned int level)
00498       {
00499         Iterator it(*this);
00500 
00501         while (it.length() > level + 1)
00502           it.goto_parent();
00503 
00504         if (it.length() == level + 1) {
00505           if (it.goto_next_sibling())
00506             goto ok;
00507           while (1) {
00508             it.goto_parent();
00509             if (it.is_root())
00510               return false;
00511             if (it.goto_next_sibling())
00512               break;
00513           }
00514         }
00515 
00516         while (it.goto_next_depth_first())
00517           if (it.length() == level + 1)
00518             goto ok;
00519 
00520         return false;
00521 
00522       ok:
00523         *this = it;
00524         return true;
00525       }
00526 
00532       void goto_backoff_full()
00533       {
00534         if (is_root())
00535           throw bit::invalid_call(
00536             "bit::Trie::Iterator::goto_backoff_full() called at root");
00537 
00538         std::vector<u32> vec(symbol_vec());
00539         while (!vec.empty()) {
00540           vec.erase(vec.begin());
00541           Iterator it(*m_trie);
00542           bool failed = false;
00543           for (size_t i = 0; i < vec.size(); i++) {
00544             if (!it.goto_child(vec[i])) {
00545               failed = true;
00546               break;
00547             }
00548           }
00549           if (!failed) {
00550             *this = it;
00551             break;
00552           }
00553         }
00554       }
00555 
00564       bool goto_backoff_once()
00565       {
00566         if (is_root())
00567           throw bit::invalid_call(
00568             "bit::Trie::Iterator::goto_backoff_once() called at root");
00569 
00570         std::vector<u32> vec(symbol_vec());
00571         vec.erase(vec.begin());
00572         Iterator it(*m_trie);
00573         for (size_t i = 0; i < vec.size(); i++)
00574           if (!it.goto_child(vec[i]))
00575             return false;
00576         *this = it;
00577         return true;
00578       }
00579 
00581 
00582 
00583 
00586 
00588       bool operator==(const Iterator it)
00589       {
00590         return m_symbol_stack == it.m_symbol_stack;
00591       }
00592 
00594       bool operator!=(const Iterator it)
00595       {
00596         return m_symbol_stack != it.m_symbol_stack;
00597       }
00598 
00600 
00601     private:
00602       
00604       const Trie<Array> *m_trie;
00605 
00608       std::vector<u32> m_symbol_stack;
00609 
00613       std::vector<u32> m_child_limit_stack;
00614 
00615       friend class Trie;
00616     
00617     };
00618 
00619   public:
00620 
00624     void reserve_levels(unsigned int num_levels)
00625     {
00626       m_symbol_arrays.reserve(num_levels);
00627       m_pointer_arrays.reserve(num_levels);
00628       m_child_limit_arrays.reserve(num_levels);
00629     }
00630   
00633     u32 num_nodes(unsigned int level) const 
00634     {
00635       if (level >= m_symbol_arrays.size())
00636         return 0;
00637       return m_symbol_arrays.at(level).num_elems();
00638     }
00639 
00645     u64 size() const {
00646       u64 ret = 0;
00647       for (size_t a = 0; a < m_symbol_arrays.size(); a++)
00648         ret += m_symbol_arrays[a].compressed_size();
00649       for (size_t a = 0; a < m_child_limit_arrays.size(); a++)
00650         ret += m_child_limit_arrays[a].compressed_size();
00651       for (size_t a = 0; a < m_pointer_arrays.size(); a++)
00652         ret += m_pointer_arrays[a].compressed_size();
00653       return ret;
00654     }
00655 
00659     const Array &symbol_array(unsigned int level) const
00660     {
00661       return m_symbol_arrays.at(level);
00662     }
00663 
00667     const Array &child_limit_array(unsigned int level) const
00668     {
00669       return m_child_limit_arrays.at(level);
00670     }
00671 
00675     const Array &pointer_array(unsigned int level) const
00676     {
00677       return m_pointer_arrays.at(level);
00678     }
00679 
00680     
00695     Iterator insert(Iterator it, u32 symbol)
00696     {
00697       if (it.goto_child(symbol))
00698         return it;
00699       return insert_new(it, symbol);
00700     }
00701 
00712     template <class T>
00713     Iterator insert(const std::vector<T> &vec)
00714     {
00715       if (vec.empty())
00716         throw bit::invalid_argument(
00717           "bit::Trie::insert_new(): trying to add an empty string");
00718       
00719       Iterator it(*this);
00720       for (size_t i = 0; i < vec.size() - 1; i++)
00721         if (!it.goto_child(vec[i]))
00722           throw bit::invalid_argument("bit::Trie::insert(): prefix not found");
00723 
00724       if (it.goto_child(vec.back()))
00725         return it;
00726       return insert_new(it, vec.back());
00727     }
00728 
00743     Iterator insert_new(Iterator it, u32 symbol)
00744     {
00745       unsigned int len = it.length();
00746       if (len > m_symbol_arrays.size())
00747         throw bit::invalid_argument(
00748           "bit::Trie::insert_new(): too long iterator argument");
00749       
00750       if (it.goto_child(symbol))
00751         throw bit::invalid_argument("bit::Trie::insert_new(): duplicate");
00752 
00753       // Update target arrays
00754       //
00755       assert(m_symbol_arrays.size() == m_child_limit_arrays.size());
00756       if (len == m_symbol_arrays.size()) {
00757         Array empty_array;
00758 
00759         if (m_symbol_arrays.size() == m_symbol_arrays.capacity())
00760           fprintf(stderr, "DEBUG WARNING: growing array vectors!\n");
00761 
00762         m_symbol_arrays.push_back(empty_array);
00763         m_child_limit_arrays.push_back(empty_array);
00764         m_pointer_arrays.push_back(empty_array);
00765       }
00766       Array &tgt_symbol_array = m_symbol_arrays.at(len);
00767       int tgt_symbol_index = tgt_symbol_array.num_elems();
00768       tgt_symbol_array.set_grow_widen(tgt_symbol_index, symbol);
00769 
00770       // Update child limits on the source level (if not at the first
00771       // level).
00772       //
00773       if (len > 0) {
00774         Array &src_child_limit_array = m_child_limit_arrays.at(len - 1);
00775         u32 limit = it.child_limit_index();
00776 
00777         for (u32 i = src_child_limit_array.num_elems(); i < limit; i++)
00778           src_child_limit_array.set_grow_widen(i, tgt_symbol_index);
00779         src_child_limit_array.set_grow_widen(limit, tgt_symbol_index + 1);
00780       }
00781 
00782       // Create the return value
00783       //
00784       Iterator tgt_it(it);
00785       tgt_it.m_symbol_stack.push_back(tgt_symbol_index);
00786       tgt_it.m_child_limit_stack.push_back(
00787         compute_non_leaf_index(tgt_it.length() - 1, tgt_symbol_index));
00788 
00789       assert(m_symbol_arrays.size() == m_child_limit_arrays.size());
00790       assert(m_symbol_arrays.size() == m_pointer_arrays.size());
00791 
00792       return tgt_it;
00793     }
00794 
00806     template <class T>
00807     Iterator insert_new(const std::vector<T> &vec)
00808     {
00809       if (vec.empty())
00810         throw bit::invalid_argument(
00811           "bit::Trie::insert_new(): trying to add an empty string");
00812       
00813       Iterator it(*this);
00814       for (size_t i = 0; i < vec.size() - 1; i++)
00815         if (!it.goto_child(vec[i]))
00816           throw bit::invalid_argument("bit::Trie::insert(): prefix not found");
00817       return insert_new(it, vec.back());
00818     }
00819 
00825     template <class T>
00826     Iterator find(const std::vector<T> &vec) const
00827     {
00828       if (vec.empty())
00829         throw bit::invalid_argument(
00830           "bit::Trie::Iterator::find() called at root");
00831       Iterator it(*this);
00832       for (size_t i = 0; i < vec.size(); i++)
00833         if (!it.goto_child(vec[i]))
00834           return Iterator();
00835       return it;
00836     }
00837 
00844     void compress(unsigned int level)
00845     {
00846       if (level >= m_child_limit_arrays.size())
00847         throw bit::out_of_range("bit::Trie::compress() level out of bounds");
00848       m_child_limit_arrays.at(level).recursive_optimal_compress();
00849       m_pointer_arrays.at(level).recursive_optimal_compress();
00850     }
00851 
00853     void compress()
00854     {
00855       for (size_t l = 0; l < m_child_limit_arrays.size(); l++) {
00856         m_child_limit_arrays.at(l).recursive_optimal_compress();
00857         m_pointer_arrays.at(l).recursive_optimal_compress();
00858       }
00859     }
00860 
00866     void uncompress(unsigned int level)
00867     {
00868       if (level >= m_child_limit_arrays.size())
00869         throw bit::out_of_range("bit::Trie::compress() level out of bounds");
00870       m_child_limit_arrays.at(level).uncompress();
00871       m_pointer_arrays.at(level).uncompress();
00872     }
00873 
00876     void uncompress()
00877     {
00878       for (size_t l = 0; l < m_child_limit_arrays.size(); l++) {
00879         m_child_limit_arrays.at(l).uncompress();
00880         m_pointer_arrays.at(l).uncompress();
00881       }
00882     }
00883 
00890     bool is_separated(unsigned int level)
00891     {
00892       if (level + 1 >= m_pointer_arrays.size())
00893         throw bit::out_of_range(
00894           "bit::Trie::separate_leafs() level out of range");
00895       return pointer_array(level).num_elems() > 0;
00896     }
00897 
00915     void separate_leafs(unsigned int level)
00916     {
00917       if (level + 1 >= m_pointer_arrays.size())
00918         throw bit::out_of_range(
00919           "bit::Trie::separate_leafs() level out of range");
00920       
00921       Array &pointer_array = m_pointer_arrays.at(level);
00922       Array &limit_array = m_child_limit_arrays.at(level);
00923       Array new_limit_array;
00924 
00925       if (pointer_array.num_elems() != 0)
00926         throw bit::invalid_call(
00927           "bit::Trie::separate_leafs() already separated");
00928 
00929       u64 tgt = 0;
00930       u64 prev_limit = 0;
00931       for (u64 src = 0; src < limit_array.num_elems(); src++) {
00932         u32 limit = limit_array.get(src);
00933         if (limit > prev_limit) {
00934           new_limit_array.set_grow_widen(tgt, limit);
00935           tgt++;
00936         }
00937         pointer_array.set_grow_widen(src, tgt);
00938         prev_limit = limit;
00939       }
00940       limit_array = new_limit_array;
00941     }
00942 
00950     void unseparate_leafs(unsigned int level)
00951     {
00952       if (level + 1 >= m_pointer_arrays.size())
00953         throw bit::out_of_range(
00954           "bit::Trie::separate_leafs() level out of range");
00955       
00956       CompressedArray &pointer_array = m_pointer_arrays.at(level);
00957       CompressedArray &limit_array = m_child_limit_arrays.at(level);
00958 
00959       if (pointer_array.num_elems() == 0)
00960         return;
00961       
00962       CompressedArray new_limit_array;
00963       u32 limit = 0;
00964       u32 prev_index = 0;
00965       for (u64 i = 0; i < pointer_array.num_elems(); i++) {
00966         u32 index = pointer_array.get(i);
00967         if (index > prev_index) {
00968           limit = limit_array.get(index - 1);
00969           prev_index = index;
00970         }
00971         new_limit_array.set_grow_widen(i, limit);
00972       }
00973       limit_array = new_limit_array;
00974       pointer_array = CompressedArray();
00975     }
00976 
00978     std::string debug_child_limit_arrays_str() const
00979     {
00980       std::string ret;
00981       for (size_t a = 0; a < m_child_limit_arrays.size(); a++) {
00982         ret.append(str::fmt(256, "===== %d =====\n", a));
00983         const Array &array = m_child_limit_arrays.at(a);
00984         ret.append(array.debug_str());
00985       }
00986       return ret;
00987     }
00988 
00990     std::string debug_str() const
00991     {
00992       std::string ret;
00993       for (size_t a = 0; a < m_child_limit_arrays.size(); a++) {
00994         ret.append(str::fmt(256, "===== %d =====\n", a));
00995         const Array &symbol_array = m_symbol_arrays.at(a);
00996         const Array &limit_array = m_child_limit_arrays.at(a);
00997         const Array &pointer_array = m_pointer_arrays.at(a);
00998         for (u64 i = 0; i < symbol_array.num_elems(); i++) {
00999           ret.append(str::fmt(64, "%d:\t%d\t", (int)i, symbol_array.get(i)));
01000           if (i < pointer_array.num_elems())
01001             ret.append(str::fmt(64, "%d", pointer_array.get(i)));
01002           else
01003             ret.append("-");
01004           ret.append("\t");
01005           if (i < limit_array.num_elems())
01006             ret.append(str::fmt(64, "%d", limit_array.get(i)));
01007           ret.append("\n");
01008         }
01009       }
01010       return ret;
01011     }
01012 
01017     void write(FILE *file) const
01018     {
01019       fputs("TRIE1:", file);
01020       fprintf(file, "%d:%d:%d:", 
01021               (int)m_symbol_arrays.size(), 
01022               (int)m_child_limit_arrays.size(),
01023               (int)m_pointer_arrays.size());
01024       if (ferror(file))
01025         throw bit::io_error(std::string("bit::Trie::write() failed: ") +
01026                             strerror(errno));
01027       try {
01028         for (size_t i = 0; i < m_symbol_arrays.size(); i++)
01029           m_symbol_arrays[i].write(file);
01030         for (size_t i = 0; i < m_child_limit_arrays.size(); i++)
01031           m_child_limit_arrays[i].write(file);
01032         for (size_t i = 0; i < m_pointer_arrays.size(); i++)
01033           m_pointer_arrays[i].write(file);
01034       }
01035       catch (bit::io_error &e) {
01036         throw bit::io_error(std::string("bit::Trie::write() failed: ") +
01037                             e.what());
01038       }
01039     }
01040 
01047     void read(FILE *file)
01048     {
01049       int symbol_levels;
01050       int child_limit_levels;
01051       int pointer_levels;
01052       int version;
01053       int ret = fscanf(file, "TRIE%d:%d:%d:%d:", &version,
01054                        &symbol_levels, &child_limit_levels, &pointer_levels);
01055       if (ret != 4 || version != 1)
01056         throw bit::io_error(
01057           "bit::Trie::read() error while reading header");
01058 
01059       try {
01060         m_symbol_arrays.resize(symbol_levels);
01061         m_child_limit_arrays.resize(child_limit_levels);
01062         m_pointer_arrays.resize(pointer_levels);
01063 
01064         for (size_t a = 0; a < m_symbol_arrays.size(); a++)
01065           m_symbol_arrays[a].read(file);
01066         for (size_t a = 0; a < m_child_limit_arrays.size(); a++)
01067           m_child_limit_arrays[a].read(file);
01068         for (size_t a = 0; a < m_pointer_arrays.size(); a++)
01069           m_pointer_arrays[a].read(file);
01070       }
01071       catch (bit::io_error &e) {
01072         throw bit::io_error(
01073           std::string("bit::CompressedArray::read() read failed") + e.what());
01074       }
01075     }
01076 
01077   private:
01078 
01087     u32 compute_non_leaf_index(unsigned int level, u32 symbol_index) const
01088     {
01089       assert(symbol_index < symbol_array(level).num_elems());
01090       const Array &pointer_array = this->pointer_array(level);
01091 
01092       // Level is not separated?
01093       //
01094       if (pointer_array.num_elems() == 0)
01095         return symbol_index;
01096 
01097       // Pointer array may be short to omit trailing leaf-nodes.n
01098       //
01099       if (symbol_index >= pointer_array.num_elems())
01100         return max_u32;
01101 
01102       u64 index = pointer_array.get(symbol_index);
01103       if (index == 0)
01104         return max_u32;
01105 
01106       u64 prev_index = 0;
01107       if (symbol_index > 0)
01108         prev_index = pointer_array.get(symbol_index - 1);
01109       if (index == prev_index)
01110         return max_u32;
01111 
01112       return index - 1;
01113     }
01114 
01115 
01116   private:
01117 
01119     std::vector<Array> m_symbol_arrays;
01120 
01122     std::vector<Array> m_child_limit_arrays;
01123 
01136     std::vector<Array> m_pointer_arrays;
01137 
01138   };
01139 
01140 };
01141 
01142 #endif /* BIT_TRIE_HH */

Generated on Mon Jan 8 15:51:03 2007 for bit by  doxygen 1.4.6