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

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnatoly Serdtcev <serdtcev@maps.me>2019-01-15 18:22:36 +0300
committerSergey Yershov <syershov@maps.me>2019-01-31 14:04:45 +0300
commitdee7e97a9f521f5b2c2bb37b9241ee93d3af26b4 (patch)
tree051d74dfde31115d113bce51119dcaf459e26b52 /indexer
parent4fb6770db46440bca013c89f63b9fbcd7956db73 (diff)
[indexer] Fix for review
Diffstat (limited to 'indexer')
-rw-r--r--indexer/interval_index.hpp10
-rw-r--r--indexer/locality_index.hpp65
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, &center](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: