Fix bug in covering optimizer. Convert some ASSERTs to CHECKs. Add unit test.

This commit is contained in:
Yury Melnichek 2011-04-22 23:51:34 +02:00 committed by Alex Zolotarev
parent 0a2731965d
commit 03380f110d
3 changed files with 51 additions and 21 deletions

View file

@ -88,14 +88,14 @@ public:
m_Covering[cell.Level()].push_back(cell);
}
explicit Covering(vector<CellId> const & v)
explicit Covering(vector<CellId> 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<int>(m_Covering.size()); ++childLevel)
for (int childLevel = parentLevel + 1; childLevel < static_cast<int>(m_Covering.size());
++childLevel)
{
vector<CellId> substracted;
CompareCellsAtLevel<LessQueueOrder> comparator(parentLevel);
@ -269,7 +270,7 @@ private:
}
}
void RemoveFullSquares()
void RemoveFullSquares(int64_t minId = 0)
{
vector<CellId> 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;

View file

@ -46,6 +46,28 @@ public:
PopFront();
}
static void Optimize(vector<int64_t> & 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<CellId> cells(ids.size(), CellId(""));
for (size_t i = 0; i < ids.size(); ++i)
cells[i] = CellId::FromInt64(ids[i]);
covering::Covering<CellId> covering(cells, minId);
covering.Simplify(minId);
vector<int64_t> 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<int64_t> & ids, int64_t minId)
{
CHECK_GREATER(ids.size(), 2, ());
CHECK_GREATER_OR_EQUAL(ids[0], minId, ());
vector<CellId> cells(ids.size(), CellId(""));
for (size_t i = 0; i < ids.size(); ++i)
cells[i] = CellId::FromInt64(ids[i]);
covering::Covering<CellId> 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;

View file

@ -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<int64_t> idsV(&ids[0], &ids[0] + ARRAY_SIZE(ids));
covering::CoveringStreamOptimizer<m2::CellId<19>, int, TestSink>::Optimize(idsV, minId);
}
UNIT_TEST(CoveringStreamOptimizer_MinId2)
{
int64_t const minId = 72200890973LL;
int64_t ids[] = { 72200890973, 72200890994, 72200891015, 72200891036};
vector<int64_t> idsV(&ids[0], &ids[0] + ARRAY_SIZE(ids));
covering::CoveringStreamOptimizer<m2::CellId<19>, int, TestSink>::Optimize(idsV, minId);
}