diff --git a/indexer/search_string_utils.cpp b/indexer/search_string_utils.cpp index dc4adf3581..cc4771d7bc 100644 --- a/indexer/search_string_utils.cpp +++ b/indexer/search_string_utils.cpp @@ -1,18 +1,21 @@ #include "indexer/search_string_utils.hpp" + #include "indexer/string_set.hpp" +#include "coding/transliteration.hpp" + #include "base/assert.hpp" #include "base/dfa_helpers.hpp" #include "base/macros.hpp" #include "base/mem_trie.hpp" -#include "3party/utfcpp/source/utf8/unchecked.h" - #include #include #include #include +#include "3party/utfcpp/source/utf8/unchecked.h" + using namespace std; using namespace strings; @@ -251,6 +254,50 @@ public: using Trie = base::MemTrie; + static StreetsSynonymsHolder const & Instance() + { + static const StreetsSynonymsHolder holder; + return holder; + } + + bool MatchPrefix(UniString const & s) const { return m_strings.HasPrefix(s); } + bool FullMatch(UniString const & s) const { return m_strings.HasKey(s); } + + template + bool MatchWithMisprints(DFA const & dfa) const + { + using TrieIt = Trie::Iterator; + using State = pair; + + auto const trieRoot = m_strings.GetRootIterator(); + + queue q; + q.emplace(trieRoot, dfa.Begin()); + + while (!q.empty()) + { + auto const p = q.front(); + q.pop(); + + auto const & currTrieIt = p.first; + auto const & currDfaIt = p.second; + + if (currDfaIt.Accepts()) + return true; + + currTrieIt.ForEachMove([&q, &currDfaIt](UniChar const & c, TrieIt const & nextTrieIt) { + auto nextDfaIt = currDfaIt; + nextDfaIt.Move(c); + strings::DFAMove(nextDfaIt, nextTrieIt.GetLabel()); + if (!nextDfaIt.Rejects()) + q.emplace(nextTrieIt, nextDfaIt); + }); + } + + return false; + } + +private: StreetsSynonymsHolder() { char const * affics[] = @@ -344,48 +391,9 @@ public: } } - bool MatchPrefix(UniString const & s) const { return m_strings.HasPrefix(s); } - bool FullMatch(UniString const & s) const { return m_strings.HasKey(s); } - - template - bool MatchWithMisprints(DFA const & dfa) const - { - using TrieIt = Trie::Iterator; - using State = pair; - - auto const trieRoot = m_strings.GetRootIterator(); - - queue q; - q.emplace(trieRoot, dfa.Begin()); - - while (!q.empty()) - { - auto const p = q.front(); - q.pop(); - - auto const & currTrieIt = p.first; - auto const & currDfaIt = p.second; - - if (currDfaIt.Accepts()) - return true; - - currTrieIt.ForEachMove([&q, &currDfaIt](UniChar const & c, TrieIt const & nextTrieIt) { - auto nextDfaIt = currDfaIt; - nextDfaIt.Move(c); - strings::DFAMove(nextDfaIt, nextTrieIt.GetLabel()); - if (!nextDfaIt.Rejects()) - q.emplace(nextTrieIt, nextDfaIt); - }); - } - - return false; - } - -private: Trie m_strings; }; -StreetsSynonymsHolder g_streets; } // namespace string DropLastToken(string const & str) @@ -430,26 +438,23 @@ UniString GetStreetNameAsKey(string const & name, bool ignoreStreetSynonyms) return (res.empty() ? NormalizeAndSimplifyString(name) : res); } -bool IsStreetSynonym(UniString const & s) -{ - return g_streets.FullMatch(s); -} +bool IsStreetSynonym(UniString const & s) { return StreetsSynonymsHolder::Instance().FullMatch(s); } bool IsStreetSynonymPrefix(UniString const & s) { - return g_streets.MatchPrefix(s); + return StreetsSynonymsHolder::Instance().MatchPrefix(s); } bool IsStreetSynonymWithMisprints(UniString const & s) { auto const dfa = BuildLevenshteinDFA(s); - return g_streets.MatchWithMisprints(dfa); + return StreetsSynonymsHolder::Instance().MatchWithMisprints(dfa); } bool IsStreetSynonymPrefixWithMisprints(UniString const & s) { auto const dfa = strings::PrefixDFAModifier(BuildLevenshteinDFA(s)); - return g_streets.MatchWithMisprints(dfa); + return StreetsSynonymsHolder::Instance().MatchWithMisprints(dfa); } bool ContainsNormalized(string const & str, string const & substr)