Welcome to mirror list, hosted at ThFree Co, Russian Federation.

pre_ranker.hpp « search - github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 399538872498d02d0abba0a6a74047104a131bb7 (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
115
116
117
118
119
120
121
#pragma once

#include "search/intermediate_result.hpp"
#include "search/nested_rects_cache.hpp"
#include "search/ranker.hpp"

#include "geometry/point2d.hpp"
#include "geometry/rect2d.hpp"

#include "base/macros.hpp"

#include <algorithm>
#include <cstddef>
#include <random>
#include <set>
#include <utility>
#include <vector>

#include <boost/optional.hpp>

class DataSource;

namespace search
{
// Fast and simple pre-ranker for search results.
class PreRanker
{
public:
  struct Params
  {
    // Minimal distance between search results in mercators, 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;

    boost::optional<m2::PointD> m_position;
    m2::RectD m_viewport;

    int m_scale = 0;

    size_t m_batchSize = 100;

    // The maximum total number of results to be emitted in all batches.
    size_t m_limit = 0;

    bool m_viewportSearch = false;
    bool m_categorialRequest = false;
  };

  PreRanker(DataSource const & dataSource, Ranker & ranker);

  void Init(Params const & params);

  void Finish(bool cancelled);

  template <typename... TArgs>
  void Emplace(TArgs &&... args)
  {
    if (m_numSentResults >= Limit())
      return;
    m_results.emplace_back(std::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| 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_params.m_limit; }

  template <typename TFn>
  void ForEach(TFn && fn)
  {
    std::for_each(m_results.begin(), m_results.end(), std::forward<TFn>(fn));
  }

  void ClearCaches();

private:
  void FilterForViewportSearch();

  DataSource const & m_dataSource;
  Ranker & m_ranker;
  std::vector<PreRankerResult> m_results;
  Params m_params;

  // 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.
  std::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.
  std::set<FeatureID> m_prevEmit;

  std::minstd_rand m_rng;

  DISALLOW_COPY_AND_MOVE(PreRanker);
};
}  // namespace search