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

hotels_filter.cpp « search - github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 84cb6bf7e7847a5e96b002318967355557dbd09d (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
122
123
124
125
126
127
#include "search/hotels_filter.hpp"

#include "indexer/feature.hpp"
#include "indexer/feature_meta.hpp"
#include "indexer/ftypes_matcher.hpp"

#include "base/assert.hpp"
#include "base/checked_cast.hpp"

#include "std/algorithm.hpp"

namespace search
{
namespace hotels_filter
{
// static
typename Rating::Value const Rating::kDefault = 0;

// static
typename PriceRate::Value const PriceRate::kDefault = 0;

// Description -------------------------------------------------------------------------------------
void Description::FromFeature(FeatureType & ft)
{
  m_rating = Rating::kDefault;
  m_priceRate = PriceRate::kDefault;

  auto const & metadata = ft.GetMetadata();

  if (metadata.Has(feature::Metadata::FMD_RATING))
  {
    string const rating = metadata.Get(feature::Metadata::FMD_RATING);
    float r;
    if (strings::to_float(rating, r))
      m_rating = r;
  }

  if (metadata.Has(feature::Metadata::FMD_PRICE_RATE))
  {
    string const priceRate = metadata.Get(feature::Metadata::FMD_PRICE_RATE);
    int pr;
    if (strings::to_int(priceRate, pr))
      m_priceRate = pr;
  }

  m_types = ftypes::IsHotelChecker::Instance().GetHotelTypesMask(ft);
}

// Rule --------------------------------------------------------------------------------------------
// static
bool Rule::IsIdentical(shared_ptr<Rule> const & lhs, shared_ptr<Rule> const & rhs)
{
  if (lhs && !rhs)
    return false;
  if (!lhs && rhs)
    return false;

  if (lhs && rhs && !lhs->IdenticalTo(*rhs))
    return false;

  return true;
}

string DebugPrint(Rule const & rule) { return rule.ToString(); }

// HotelsFilter::ScopedFilter ----------------------------------------------------------------------
HotelsFilter::ScopedFilter::ScopedFilter(MwmSet::MwmId const & mwmId,
                                         Descriptions const & descriptions, shared_ptr<Rule> rule)
  : m_mwmId(mwmId), m_descriptions(descriptions), m_rule(rule)
{
  CHECK(m_rule.get(), ());
}

bool HotelsFilter::ScopedFilter::Matches(FeatureID const & fid) const
{
  if (fid.m_mwmId != m_mwmId)
    return false;

  auto it =
      lower_bound(m_descriptions.begin(), m_descriptions.end(),
                  make_pair(fid.m_index, Description{}),
                  [](pair<uint32_t, Description> const & lhs,
                     pair<uint32_t, Description> const & rhs) { return lhs.first < rhs.first; });
  if (it == m_descriptions.end() || it->first != fid.m_index)
    return false;

  return m_rule->Matches(it->second);
}

// HotelsFilter ------------------------------------------------------------------------------------
HotelsFilter::HotelsFilter(HotelsCache & hotels): m_hotels(hotels) {}

unique_ptr<HotelsFilter::ScopedFilter> HotelsFilter::MakeScopedFilter(MwmContext const & context,
                                                                      shared_ptr<Rule> rule)
{
  if (!rule)
    return {};
  return make_unique<ScopedFilter>(context.GetId(), GetDescriptions(context), rule);
}

void HotelsFilter::ClearCaches()
{
  m_descriptions.clear();
}

HotelsFilter::Descriptions const & HotelsFilter::GetDescriptions(MwmContext const & context)
{
  auto const & mwmId = context.GetId();
  auto const it = m_descriptions.find(mwmId);
  if (it != m_descriptions.end())
    return it->second;

  auto const hotels = m_hotels.Get(context);
  auto & descriptions = m_descriptions[mwmId];
  hotels.ForEach([&descriptions, &context](uint64_t bit) {
    auto const id = base::asserted_cast<uint32_t>(bit);
    FeatureType ft;

    Description description;
    if (context.GetFeature(id, ft))
      description.FromFeature(ft);
    descriptions.emplace_back(id, description);
  });
  return descriptions;
}
}  // namespace hotels_filter
}  // namespace search