| 90 | {} |
| 91 | |
| 92 | void LocalityScorer::GetTopLocalities(MwmSet::MwmId const & countryId, BaseContext const & ctx, CBV const & filter, |
| 93 | size_t limit, vector<Locality> & localities) |
| 94 | { |
| 95 | double constexpr kUnknownIdf = 1.0; |
| 96 | size_t const numTokens = ctx.NumTokens(); |
| 97 | ASSERT_EQUAL(numTokens, m_params.GetNumTokens(), ()); |
| 98 | |
| 99 | localities.clear(); |
| 100 | |
| 101 | vector<Retrieval::ExtendedFeatures> intersections(numTokens); |
| 102 | vector<pair<LevenshteinDFA, uint64_t>> tokensToDf; |
| 103 | vector<pair<PrefixDFA, uint64_t>> prefixToDf; |
| 104 | bool const havePrefix = numTokens > 0 && m_params.LastTokenIsPrefix(); |
| 105 | size_t const nonPrefixTokens = havePrefix ? numTokens - 1 : numTokens; |
| 106 | for (size_t i = 0; i < nonPrefixTokens; ++i) |
| 107 | { |
| 108 | intersections[i] = ctx.m_features[i].Intersect(filter); |
| 109 | auto const df = intersections[i].m_features.PopCount(); |
| 110 | if (df != 0) |
| 111 | { |
| 112 | auto const & token = m_params.GetToken(i); |
| 113 | tokensToDf.emplace_back(BuildLevenshteinDFA(token.GetOriginal()), df); |
| 114 | token.ForEachSynonym([&tokensToDf, &df](UniString const & s) |
| 115 | { tokensToDf.emplace_back(strings::LevenshteinDFA(s, 0 /* maxErrors */), df); }); |
| 116 | } |
| 117 | } |
| 118 | |
| 119 | if (havePrefix) |
| 120 | { |
| 121 | auto const count = numTokens - 1; |
| 122 | intersections[count] = ctx.m_features[count].Intersect(filter); |
| 123 | auto const prefixDf = intersections[count].m_features.PopCount(); |
| 124 | if (prefixDf != 0) |
| 125 | { |
| 126 | auto const & token = m_params.GetToken(count); |
| 127 | prefixToDf.emplace_back(PrefixDFA(BuildLevenshteinDFA(token.GetOriginal())), prefixDf); |
| 128 | token.ForEachSynonym([&prefixToDf, &prefixDf](UniString const & s) |
| 129 | { prefixToDf.emplace_back(PrefixDFA(strings::LevenshteinDFA(s, 0 /* maxErrors */)), prefixDf); }); |
| 130 | } |
| 131 | } |
| 132 | |
| 133 | IdfMapDelegate delegate(tokensToDf, prefixToDf); |
| 134 | IdfMap idfs(delegate, kUnknownIdf); |
| 135 | |
| 136 | for (size_t startToken = 0; startToken < numTokens; ++startToken) |
| 137 | { |
| 138 | auto intersection = intersections[startToken]; |
| 139 | QueryVec::Builder builder; |
| 140 | |
| 141 | for (size_t endToken = startToken + 1; endToken <= numTokens && !intersection.m_features.IsEmpty(); ++endToken) |
| 142 | { |
| 143 | auto const curToken = endToken - 1; |
| 144 | auto const & token = m_params.GetToken(curToken).GetOriginal(); |
| 145 | if (m_params.IsPrefixToken(curToken)) |
| 146 | builder.SetPrefix(token); |
| 147 | else |
| 148 | builder.AddFull(token); |
| 149 |
no test coverage detected