diff options
author | Anatoly Serdtcev <serdtcev@maps.me> | 2019-01-15 18:22:36 +0300 |
---|---|---|
committer | Sergey Yershov <syershov@maps.me> | 2019-01-31 14:04:45 +0300 |
commit | dee7e97a9f521f5b2c2bb37b9241ee93d3af26b4 (patch) | |
tree | 051d74dfde31115d113bce51119dcaf459e26b52 /indexer | |
parent | 4fb6770db46440bca013c89f63b9fbcd7956db73 (diff) |
[indexer] Fix for review
Diffstat (limited to 'indexer')
-rw-r--r-- | indexer/interval_index.hpp | 10 | ||||
-rw-r--r-- | indexer/locality_index.hpp | 65 |
2 files changed, 36 insertions, 39 deletions
diff --git a/indexer/interval_index.hpp b/indexer/interval_index.hpp index c63fe9e954..c418208190 100644 --- a/indexer/interval_index.hpp +++ b/indexer/interval_index.hpp @@ -66,7 +66,8 @@ public: end = KeyEnd(); --end; // end is inclusive in ForEachImpl(). ForEachNode(f, beg, end, m_Header.m_Levels, 0, - m_LevelOffsets[m_Header.m_Levels + 1] - m_LevelOffsets[m_Header.m_Levels], 0); + m_LevelOffsets[m_Header.m_Levels + 1] - m_LevelOffsets[m_Header.m_Levels], + 0 /* started nodeKey */); } } @@ -92,7 +93,7 @@ private: break; value += ReadVarInt<int64_t>(src); if (key >= beg) - Invoke(f, keyBase + key, value, 0); + Invoke(f, keyBase + key, value, 0 /* fake argument for invocation choice of |f| */); } } @@ -168,12 +169,13 @@ private: } template <typename F, typename = decltype(std::declval<F>()(uint64_t{0}, uint64_t{0}))> - static void Invoke(F const & f, uint64_t key, uint64_t storedId, int) + static void Invoke(F const & f, uint64_t key, uint64_t storedId, int /* best candidate (overload) */) { f(key, storedId); } + template <typename F> - static void Invoke(F const & f, uint64_t key, uint64_t storedId, ...) + static void Invoke(F const & f, uint64_t key, uint64_t storedId, ... /* default candidate (overload )*/) { f(storedId); } diff --git a/indexer/locality_index.hpp b/indexer/locality_index.hpp index bc72a544c9..69e3843f83 100644 --- a/indexer/locality_index.hpp +++ b/indexer/locality_index.hpp @@ -12,11 +12,6 @@ #include "base/geo_object_id.hpp" -#include <boost/multi_index_container.hpp> -#include <boost/multi_index/hashed_index.hpp> -#include <boost/multi_index/member.hpp> -#include <boost/multi_index/ordered_index.hpp> - #include <cstdint> #include <functional> #include <memory> @@ -36,7 +31,7 @@ class LocalityIndex { public: using ProcessObject = std::function<void(base::GeoObjectId const &)>; - using ProcessClosestObject = std::function<void(base::GeoObjectId const &, double distance)>; + using ProcessClosestObject = std::function<void(base::GeoObjectId const & objectId, double closenessWeight)>; LocalityIndex() = default; explicit LocalityIndex(Reader const & reader) @@ -66,6 +61,8 @@ public: // and stop after |sizeHint| objects have been processed. For stability, if an object from // an index cell has been processed, all other objects from this cell will be processed too, // thus probably overflowing the |sizeHint| limit. + // |processObject| gets object id in the first argument |objectId| and closeness weight + // in the seŃond argument |closenessWeight| (closeness weight in the range (0.0, 1.0]). void ForClosestToPoint(ProcessClosestObject const & processObject, m2::PointD const & center, double radiusM, uint32_t sizeHint) const { @@ -84,38 +81,34 @@ public: bestCell = bestCell.Parent(); } - struct ResultItem + std::map<uint64_t, double> objectWeights{}; + + auto cellRelativeWeight = [&bestCells, cellDepth, center] (int64_t cellNumber) { - uint64_t m_ObjectId; - double m_Distance; - }; - using namespace boost::multi_index; - auto result = multi_index_container<ResultItem, - indexed_by<hashed_unique<member<ResultItem, uint64_t, &ResultItem::m_ObjectId>>, - ordered_non_unique<member<ResultItem, double, &ResultItem::m_Distance>>>>{}; - - auto processAll = [&result, &bestCells, cellDepth, ¢er](int64_t cellNumber, uint64_t storedId) { - auto distance = 0.0; - if (bestCells.find(cellNumber) == bestCells.end()) - { - using Converter = CellIdConverter<MercatorBounds, m2::CellId<DEPTH_LEVELS>>; + if (bestCells.find(cellNumber) != bestCells.end()) + return 1.0; - auto cell = m2::CellId<DEPTH_LEVELS>::FromInt64(cellNumber, cellDepth); - auto cellCenter = Converter::FromCellId(cell); - distance = MercatorBounds::DistanceOnEarth(center, cellCenter); - } + using Converter = CellIdConverter<MercatorBounds, m2::CellId<DEPTH_LEVELS>>; + + auto const cell = m2::CellId<DEPTH_LEVELS>::FromInt64(cellNumber, cellDepth); + auto const cellCenter = Converter::FromCellId(cell); + auto const ratingDistance = MercatorBounds::DistanceOnEarth(center, cellCenter); + + double minCellX, minCellY, maxCellX, maxCellY; + Converter::GetCellBounds(cell, minCellX, minCellY, maxCellX, maxCellY); + auto const distanceError = (maxCellX - minCellX) / 2; + + return 1 / (ratingDistance + distanceError); + }; - auto objectId = LocalityObject::FromStoredId(storedId).GetEncodedId(); - auto resultInsert = result.insert({objectId, distance}); - if (resultInsert.second) - return; - auto const & object = *resultInsert.first; - if (distance < object.m_Distance) - result.replace(resultInsert.first, {objectId, distance}); + auto processAll = [&] (int64_t cellNumber, uint64_t storedId) { + auto const objectId = LocalityObject::FromStoredId(storedId).GetEncodedId(); + auto & objectWeight = objectWeights[objectId]; + objectWeight = max(objectWeight, cellRelativeWeight(cellNumber)); }; auto process = [&](int64_t cellNumber, uint64_t storedId) { - if (result.size() < sizeHint) + if (objectWeights.size() < sizeHint) processAll(cellNumber, storedId); }; @@ -128,13 +121,15 @@ public: else { m_intervalIndex->ForEach(process, i.first, i.second); - if (result.size() >= sizeHint) + if (objectWeights.size() >= sizeHint) return; } } - for (auto const & object : result.template get<1>()) - processObject(base::GeoObjectId(object.m_ObjectId), object.m_Distance); + std::vector<std::pair<uint64_t, double>> result(objectWeights.begin(), objectWeights.end()); + std::sort(result.begin(), result.end(), [] (auto && l, auto && r) { return l.second > r.second;}); + for (auto const & object : result) + processObject(base::GeoObjectId(object.first), object.second); } private: |