blob: 1a3a51dad7de53eb4e2da3a1f1a84e98ba0155e1 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
|
#pragma once
#include "search/intermediate_result.hpp"
#include "search/nested_rects_cache.hpp"
#include "search/ranker.hpp"
#include "indexer/index.hpp"
#include "geometry/point2d.hpp"
#include "geometry/rect2d.hpp"
#include "base/macros.hpp"
#include "std/algorithm.hpp"
#include "std/cstdint.hpp"
#include "std/random.hpp"
#include "std/set.hpp"
#include "std/utility.hpp"
#include "std/vector.hpp"
namespace search
{
// Fast and simple pre-ranker for search results.
class PreRanker
{
public:
struct Params
{
m2::RectD m_viewport;
// A minimum distance between search results in meters, needed for
// filtering of viewport search results.
double m_minDistanceOnMapBetweenResults = 0.0;
// This is different from geocoder's pivot because pivot is
// usually a rectangle created by radius and center and, due to
// precision loss, its center may differ from
// |m_accuratePivotCenter|. Therefore the pivot should be used for
// fast filtering of features outside of the rectangle, while
// |m_accuratePivotCenter| should be used when it's needed to
// compute the distance from a feature to the pivot.
m2::PointD m_accuratePivotCenter = m2::PointD(0, 0);
int m_scale = 0;
size_t m_batchSize = 100;
};
PreRanker(Index const & index, Ranker & ranker, size_t limit);
void Init(Params const & params);
inline void SetViewportSearch(bool viewportSearch) { m_viewportSearch = viewportSearch; }
template <typename... TArgs>
void Emplace(TArgs &&... args)
{
if (m_numSentResults >= m_limit)
return;
m_results.emplace_back(forward<TArgs>(args)...);
}
// Computes missing fields for all pre-results.
void FillMissingFieldsInPreResults();
void Filter(bool viewportSearch);
// Emit a new batch of results up the pipeline (i.e. to ranker).
// Use lastUpdate in geocoder to indicate that
// no more results will be added.
void UpdateResults(bool lastUpdate);
inline size_t Size() const { return m_results.size(); }
inline size_t BatchSize() const { return m_params.m_batchSize; }
inline size_t NumSentResults() const { return m_numSentResults; }
inline size_t Limit() const { return m_limit; }
template <typename TFn>
void ForEach(TFn && fn)
{
for_each(m_results.begin(), m_results.end(), forward<TFn>(fn));
}
void ClearCaches();
private:
void FilterForViewportSearch();
Index const & m_index;
Ranker & m_ranker;
vector<PreResult1> m_results;
size_t const m_limit;
Params m_params;
bool m_viewportSearch = false;
// Amount of results sent up the pipeline.
size_t m_numSentResults = 0;
// Cache of nested rects used to estimate distance from a feature to the pivot.
NestedRectsCache m_pivotFeatures;
// A set of ids for features that are emitted during the current search session.
set<FeatureID> m_currEmit;
// A set of ids for features that were emitted during the previous
// search session. They're used for filtering of current search in
// viewport results, because we need to give more priority to
// results that were on map previously.
set<FeatureID> m_prevEmit;
minstd_rand m_rng;
DISALLOW_COPY_AND_MOVE(PreRanker);
};
} // namespace search
|