diff --git a/include/xcdat/tail_vector.hpp b/include/xcdat/tail_vector.hpp index 90c4f7c..b51d295 100644 --- a/include/xcdat/tail_vector.hpp +++ b/include/xcdat/tail_vector.hpp @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -166,42 +167,42 @@ class tail_vector { } } - // Returns true if TAIL[tpos..epos] is a prefix of key, where epos is the end position of the tail. - inline bool prefix_match(std::string_view key, std::uint64_t tpos) const { + // Returns epos-tpos+1 if TAIL[tpos..epos] is a prefix of key. + inline std::optional prefix_match(std::string_view key, std::uint64_t tpos) const { if (tpos == 0) { - // suffix is empty, returns true always. - return true; + // suffix is empty, always matched. + return 0; } if (key.size() == 0) { - // When key is empty, returns true iff suffix is empty. - return false; + // When key is empty, match fails since the suffix is not empty here. + return std::nullopt; } std::uint64_t kpos = 0; if (bin_mode()) { do { if (key[kpos] != m_chars[tpos]) { - return false; + return std::nullopt; } kpos += 1; if (m_terms[tpos]) { - return true; + return kpos; } tpos += 1; } while (kpos < key.size()); - return true; + return kpos; } else { do { if (!m_chars[tpos]) { - return true; + return kpos; } if (key[kpos] != m_chars[tpos]) { - return false; + return std::nullopt; } kpos += 1; tpos += 1; } while (kpos < key.size()); - return true; + return kpos; } } diff --git a/include/xcdat/trie.hpp b/include/xcdat/trie.hpp index 9c9de80..07e21bc 100644 --- a/include/xcdat/trie.hpp +++ b/include/xcdat/trie.hpp @@ -375,12 +375,12 @@ class trie { itr->is_end = true; const std::uint64_t tpos = m_bcvec.link(itr->m_npos); - if (!m_tvec.prefix_match(get_suffix(itr->m_key, itr->m_kpos), tpos)) { + const auto matched = m_tvec.prefix_match(get_suffix(itr->m_key, itr->m_kpos), tpos); + if (!matched.has_value()) { itr->m_id = num_keys(); return false; } - - itr->m_kpos = itr->m_key.size(); + itr->m_kpos += matched.value(); itr->m_id = npos_to_id(itr->m_npos); return true; }