[search] Skip locality candidates that match only numbers.

This commit is contained in:
vng 2016-03-16 18:22:51 +03:00 committed by Sergey Yershov
parent bef875f01b
commit 8f4073c2ea
5 changed files with 53 additions and 13 deletions

View file

@ -126,6 +126,28 @@ SearchQueryParams::TSynonymsVector & SearchQueryParams::GetTokens(size_t i)
return i < m_tokens.size() ? m_tokens[i] : m_prefixTokens;
}
bool SearchQueryParams::IsNumberTokens(size_t start, size_t end) const
{
ASSERT_LESS(start, end, ());
do
{
bool number = false;
for (auto const & t : GetTokens(start))
{
if (feature::IsNumber(t))
{
number = true;
break;
}
}
if (!number)
return false;
} while (++start < end);
return true;
}
template <class ToDo>
void SearchQueryParams::ForEachToken(ToDo && toDo)
{

View file

@ -35,6 +35,9 @@ struct SearchQueryParams
TSynonymsVector const & GetTokens(size_t i) const;
TSynonymsVector & GetTokens(size_t i);
/// @return true if all tokens in [start, end) range has number synonym.
bool IsNumberTokens(size_t start, size_t end) const;
private:
template <class ToDo>
void ForEachToken(ToDo && toDo);

View file

@ -74,5 +74,12 @@ bool CBVPtr::IsEmpty() const
return !m_isFull && coding::CompressedBitVector::IsEmpty(m_ptr);
}
void CBVPtr::ForEach(function<void(uint32_t)> && fn)
{
ASSERT(!m_isFull, ());
if (!IsEmpty())
coding::CompressedBitVectorEnumerator::ForEach(*m_ptr, fn);
}
} // namespace v2
} // namespace search

View file

@ -2,6 +2,8 @@
#include "base/macros.hpp"
#include "std/function.hpp"
namespace coding
{
class CompressedBitVector;
@ -46,6 +48,8 @@ public:
void Union(coding::CompressedBitVector const * p);
void Intersect(coding::CompressedBitVector const * p);
void ForEach(function<void(uint32_t)> && fn);
};
} // namespace v2

View file

@ -678,16 +678,20 @@ void Geocoder::FillLocalityCandidates(coding::CompressedBitVector const * filter
for (size_t endToken = startToken + 1; endToken <= m_numTokens; ++endToken)
{
coding::CompressedBitVectorEnumerator::ForEach(*intersection.Get(),
[&](uint32_t featureId)
{
Locality l;
l.m_countryId = m_context->GetId();
l.m_featureId = featureId;
l.m_startToken = startToken;
l.m_endToken = endToken;
preLocalities.push_back(l);
});
// Skip locality candidates that match only numbers.
if (!m_params.IsNumberTokens(startToken, endToken))
{
intersection.ForEach([&](uint32_t featureId)
{
Locality l;
l.m_countryId = m_context->GetId();
l.m_featureId = featureId;
l.m_startToken = startToken;
l.m_endToken = endToken;
preLocalities.push_back(l);
});
}
if (endToken < m_numTokens)
{
intersection.Intersect(m_addressFeatures[endToken].get());
@ -1075,7 +1079,7 @@ void Geocoder::CreateStreetsLayerAndMatchLowerLayers(
vector<uint32_t> sortedFeatures;
sortedFeatures.reserve(features->PopCount());
coding::CompressedBitVectorEnumerator::ForEach(*filtered, MakeBackInsertFunctor(sortedFeatures));
filtered.ForEach(MakeBackInsertFunctor(sortedFeatures));
layer.m_sortedFeatures = &sortedFeatures;
ScopedMarkTokens mark(m_usedTokens, startToken, endToken);
@ -1146,7 +1150,7 @@ void Geocoder::MatchPOIsAndBuildings(size_t curToken)
clusters[searchType].push_back(featureId);
};
coding::CompressedBitVectorEnumerator::ForEach(*features, clusterize);
features.ForEach(clusterize);
}
else
{
@ -1358,7 +1362,7 @@ void Geocoder::MatchUnclassified(size_t curToken)
if (type == SearchModel::SEARCH_TYPE_UNCLASSIFIED)
EmitResult(m_context->GetId(), featureId, type, startToken, curToken);
};
coding::CompressedBitVectorEnumerator::ForEach(*allFeatures, emitUnclassified);
allFeatures.ForEach(emitUnclassified);
}
unique_ptr<coding::CompressedBitVector> Geocoder::LoadCategories(