diff options
author | Yuri Gorshenin <y@maps.me> | 2016-10-06 22:25:34 +0300 |
---|---|---|
committer | Yuri Gorshenin <y@maps.me> | 2016-10-11 17:58:27 +0300 |
commit | da69d602c568846235657a843b30c17a672320e1 (patch) | |
tree | ab172257367d683031241c75e6f95aeb3813e7f4 /search/hotels_filter.cpp | |
parent | 09566c5ca7aa761a40b0e769e4e44b85c5c3f429 (diff) |
[search] Implemented hotels filter.
Diffstat (limited to 'search/hotels_filter.cpp')
-rw-r--r-- | search/hotels_filter.cpp | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/search/hotels_filter.cpp b/search/hotels_filter.cpp new file mode 100644 index 0000000000..10f335a39f --- /dev/null +++ b/search/hotels_filter.cpp @@ -0,0 +1,105 @@ +#include "search/hotels_filter.hpp" + +#include "indexer/feature.hpp" +#include "indexer/feature_meta.hpp" + +#include "base/assert.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; + } +} + +// 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](uint32_t id) { + FeatureType ft; + + Description description; + if (context.GetFeature(id, ft)) + description.FromFeature(ft); + descriptions.emplace_back(id, description); + }); + return descriptions; +} +} // namespace hotels_filter +} // namespace search |