diff --git a/geometry/covering.hpp b/geometry/covering.hpp index 8da2cbd6a2..c774191275 100644 --- a/geometry/covering.hpp +++ b/geometry/covering.hpp @@ -88,14 +88,14 @@ public: m_Covering[cell.Level()].push_back(cell); } - explicit Covering(vector const & v) + explicit Covering(vector const & v, int64_t minId = 0) { for (size_t i = 0; i < v.size(); ++i) m_Covering[v[i].Level()].push_back(v[i]); Sort(); Unique(); RemoveDuplicateChildren(); - RemoveFullSquares(); + RemoveFullSquares(minId); m_Size = CalculateSize(); } @@ -160,7 +160,7 @@ public: } } RemoveDuplicateChildren(); - RemoveFullSquares(); + RemoveFullSquares(minId); m_Size = CalculateSize(); } @@ -253,7 +253,8 @@ private: { if (m_Covering[parentLevel].empty()) continue; - for (int childLevel = parentLevel + 1; childLevel < static_cast(m_Covering.size()); ++childLevel) + for (int childLevel = parentLevel + 1; childLevel < static_cast(m_Covering.size()); + ++childLevel) { vector substracted; CompareCellsAtLevel comparator(parentLevel); @@ -269,7 +270,7 @@ private: } } - void RemoveFullSquares() + void RemoveFullSquares(int64_t minId = 0) { vector cellsToAppend; for (int level = m_Covering.size() - 1; level >= 0; --level) @@ -284,7 +285,10 @@ private: if (i + 3 < a.size()) { CellId const parent = a[i].Parent(); - if (parent == a[i+1].Parent() && parent == a[i+2].Parent() && parent == a[i+3].Parent()) + if (parent == a[i+1].Parent() && + parent == a[i+2].Parent() && + parent == a[i+3].Parent() && + parent.ToInt64() >= minId) { parents.push_back(parent); i += 3; diff --git a/geometry/covering_stream_optimizer.hpp b/geometry/covering_stream_optimizer.hpp index d98bc16ab0..c167588751 100644 --- a/geometry/covering_stream_optimizer.hpp +++ b/geometry/covering_stream_optimizer.hpp @@ -46,6 +46,28 @@ public: PopFront(); } + static void Optimize(vector & ids, int64_t minId) + { + CHECK_GREATER(ids.size(), 2, (minId, ids)); + CHECK(IsSortedAndUnique(ids.begin(), ids.end()), (minId, ids)); + CHECK_GREATER_OR_EQUAL(ids[0], minId, (minId, ids)); + + vector cells(ids.size(), CellId("")); + for (size_t i = 0; i < ids.size(); ++i) + cells[i] = CellId::FromInt64(ids[i]); + covering::Covering covering(cells, minId); + covering.Simplify(minId); + + vector res; + covering.OutputToVector(res); + sort(res.begin(), res.end()); + + CHECK(IsSortedAndUnique(res.begin(), res.end()), (minId, ids, res)); + CHECK_GREATER_OR_EQUAL(res[0], minId, (minId, ids, res)); + + ids.swap(res); + } + private: void PopFront() { @@ -87,21 +109,6 @@ private: m_ValueCounts[value] = optimized.size(); } - static void Optimize(vector & ids, int64_t minId) - { - CHECK_GREATER(ids.size(), 2, ()); - CHECK_GREATER_OR_EQUAL(ids[0], minId, ()); - vector cells(ids.size(), CellId("")); - for (size_t i = 0; i < ids.size(); ++i) - cells[i] = CellId::FromInt64(ids[i]); - covering::Covering covering(cells); - covering.Simplify(minId); - ids.clear(); - covering.OutputToVector(ids); - sort(ids.begin(), ids.end()); - CHECK_GREATER_OR_EQUAL(ids[0], minId, ()); - } - SinkT & m_Sink; uint32_t const m_WindowSize; uint32_t const m_MaxDuplicates; diff --git a/geometry/geometry_tests/covering_stream_optimizer_test.cpp b/geometry/geometry_tests/covering_stream_optimizer_test.cpp index 973954cd7e..5df567c940 100644 --- a/geometry/geometry_tests/covering_stream_optimizer_test.cpp +++ b/geometry/geometry_tests/covering_stream_optimizer_test.cpp @@ -2,6 +2,7 @@ #include "../cellid.hpp" #include "../covering.hpp" #include "../covering_stream_optimizer.hpp" +#include "../../base/macros.hpp" typedef m2::CellId<5> CellId; @@ -42,3 +43,21 @@ UNIT_TEST(CoveringStreamOptimizer_Smoke) e.push_back(make_pair(CellId("02"), 1)); TEST_EQUAL(e, res, ()); } + +UNIT_TEST(CoveringStreamOptimizer_MinId1) +{ + int64_t const minId = 72200890973LL; + int64_t ids[] = { 72200890973, 72200890995, 72200891005, 72200891011, 72200891013, + 72200891014, 72200891015, 72200891036, 72200896894, 72200896902 }; + vector idsV(&ids[0], &ids[0] + ARRAY_SIZE(ids)); + covering::CoveringStreamOptimizer, int, TestSink>::Optimize(idsV, minId); +} + +UNIT_TEST(CoveringStreamOptimizer_MinId2) +{ + int64_t const minId = 72200890973LL; + int64_t ids[] = { 72200890973, 72200890994, 72200891015, 72200891036}; + vector idsV(&ids[0], &ids[0] + ARRAY_SIZE(ids)); + covering::CoveringStreamOptimizer, int, TestSink>::Optimize(idsV, minId); +} +