This commit is contained in:
kampersanda 2022-07-10 14:56:12 +09:00
parent feae2f1830
commit 1fe88b112e
2 changed files with 16 additions and 15 deletions

View file

@ -2,6 +2,7 @@
#include <algorithm> #include <algorithm>
#include <functional> #include <functional>
#include <optional>
#include <string> #include <string>
#include <string_view> #include <string_view>
#include <vector> #include <vector>
@ -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. // Returns epos-tpos+1 if TAIL[tpos..epos] is a prefix of key.
inline bool prefix_match(std::string_view key, std::uint64_t tpos) const { inline std::optional<std::uint64_t> prefix_match(std::string_view key, std::uint64_t tpos) const {
if (tpos == 0) { if (tpos == 0) {
// suffix is empty, returns true always. // suffix is empty, always matched.
return true; return 0;
} }
if (key.size() == 0) { if (key.size() == 0) {
// When key is empty, returns true iff suffix is empty. // When key is empty, match fails since the suffix is not empty here.
return false; return std::nullopt;
} }
std::uint64_t kpos = 0; std::uint64_t kpos = 0;
if (bin_mode()) { if (bin_mode()) {
do { do {
if (key[kpos] != m_chars[tpos]) { if (key[kpos] != m_chars[tpos]) {
return false; return std::nullopt;
} }
kpos += 1; kpos += 1;
if (m_terms[tpos]) { if (m_terms[tpos]) {
return true; return kpos;
} }
tpos += 1; tpos += 1;
} while (kpos < key.size()); } while (kpos < key.size());
return true; return kpos;
} else { } else {
do { do {
if (!m_chars[tpos]) { if (!m_chars[tpos]) {
return true; return kpos;
} }
if (key[kpos] != m_chars[tpos]) { if (key[kpos] != m_chars[tpos]) {
return false; return std::nullopt;
} }
kpos += 1; kpos += 1;
tpos += 1; tpos += 1;
} while (kpos < key.size()); } while (kpos < key.size());
return true; return kpos;
} }
} }

View file

@ -375,12 +375,12 @@ class trie {
itr->is_end = true; itr->is_end = true;
const std::uint64_t tpos = m_bcvec.link(itr->m_npos); 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(); itr->m_id = num_keys();
return false; return false;
} }
itr->m_kpos += matched.value();
itr->m_kpos = itr->m_key.size();
itr->m_id = npos_to_id(itr->m_npos); itr->m_id = npos_to_id(itr->m_npos);
return true; return true;
} }