Added some foreachSubRange
This commit is contained in:
@@ -34,13 +34,30 @@ namespace Database
|
||||
// size => results size
|
||||
struct Range
|
||||
{
|
||||
std::size_t offset {};
|
||||
std::size_t size {};
|
||||
std::size_t offset{};
|
||||
std::size_t size{};
|
||||
|
||||
// TODO remove this
|
||||
operator bool() const { return size != 0; }
|
||||
};
|
||||
|
||||
// Func must return true to continue iterating
|
||||
template <typename Func>
|
||||
void foreachSubRange(Range range, std::size_t subRangeSize, Func&& func)
|
||||
{
|
||||
assert(subRangeSize > 0);
|
||||
|
||||
Range subRange{ range.offset, std::min(range.size, subRangeSize) };
|
||||
while (subRange.size > 0)
|
||||
{
|
||||
if (!func(subRange))
|
||||
break;
|
||||
|
||||
subRange.offset += subRange.size;
|
||||
subRange.size = std::min(subRangeSize, range.size - (subRange.offset - range.offset));
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
struct RangeResults
|
||||
{
|
||||
@@ -60,8 +77,8 @@ namespace Database
|
||||
|
||||
RangeResults subResults;
|
||||
|
||||
auto itBegin {std::cbegin(results) + subRange.offset - range.offset};
|
||||
auto itEnd {itBegin + subRange.size};
|
||||
auto itBegin{ std::cbegin(results) + subRange.offset - range.offset };
|
||||
auto itEnd{ itBegin + subRange.size };
|
||||
subResults.results.reserve(std::distance(itBegin, itEnd));
|
||||
std::copy(itBegin, itEnd, std::back_inserter(subResults.results));
|
||||
|
||||
|
||||
@@ -36,9 +36,9 @@
|
||||
#include "services/database/User.hpp"
|
||||
|
||||
TmpDatabase::TmpDatabase()
|
||||
: _tmpFile {std::tmpnam(nullptr)}
|
||||
, _fileDeleter {_tmpFile}
|
||||
, _db {_tmpFile}
|
||||
: _tmpFile{ std::tmpnam(nullptr) }
|
||||
, _fileDeleter{ _tmpFile }
|
||||
, _db{ _tmpFile }
|
||||
{
|
||||
}
|
||||
|
||||
@@ -58,17 +58,17 @@ DatabaseFixture::SetUpTestCase()
|
||||
{
|
||||
_tmpDb = std::make_unique<TmpDatabase>();
|
||||
{
|
||||
Database::Session s {_tmpDb->getDb()};
|
||||
Database::Session s{ _tmpDb->getDb() };
|
||||
s.prepareTables();
|
||||
s.analyze();
|
||||
|
||||
// remove default created entries
|
||||
{
|
||||
auto transaction {s.createUniqueTransaction()};
|
||||
auto clusterTypes {Database::ClusterType::find(s, Database::Range {})};
|
||||
auto transaction{ s.createUniqueTransaction() };
|
||||
auto clusterTypes{ Database::ClusterType::find(s, Database::Range {}) };
|
||||
for (auto clusterTypeId : clusterTypes.results)
|
||||
{
|
||||
auto clusterType {Database::ClusterType::find(s, clusterTypeId)};
|
||||
auto clusterType{ Database::ClusterType::find(s, clusterTypeId) };
|
||||
clusterType.remove();
|
||||
}
|
||||
}
|
||||
@@ -86,7 +86,7 @@ DatabaseFixture::testDatabaseEmpty()
|
||||
{
|
||||
using namespace Database;
|
||||
|
||||
auto uniqueTransaction {session.createUniqueTransaction()};
|
||||
auto uniqueTransaction{ session.createUniqueTransaction() };
|
||||
|
||||
EXPECT_EQ(Artist::getCount(session), 0);
|
||||
EXPECT_EQ(Cluster::getCount(session), 0);
|
||||
@@ -107,23 +107,61 @@ TEST_F(DatabaseFixture, Common_subRangeEmpty)
|
||||
using namespace Database;
|
||||
|
||||
RangeResults<int> results;
|
||||
results.range = Range {0, 0};
|
||||
results.range = Range{ 0, 0 };
|
||||
results.results = {};
|
||||
results.moreResults = false;
|
||||
|
||||
{
|
||||
auto subRange {results.getSubRange(Range {0, 0})};
|
||||
auto subRange{ results.getSubRange(Range {0, 0}) };
|
||||
EXPECT_FALSE(subRange.moreResults);
|
||||
ASSERT_EQ(subRange.results.size(), 0);
|
||||
EXPECT_EQ(subRange.range, Range {});
|
||||
EXPECT_EQ(subRange.range, Range{});
|
||||
}
|
||||
{
|
||||
auto subRange {results.getSubRange(Range {0, 1})};
|
||||
auto subRange{ results.getSubRange(Range {0, 1}) };
|
||||
EXPECT_FALSE(subRange.moreResults);
|
||||
ASSERT_EQ(subRange.results.size(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(DatabaseFixture, Common_subRangeForeach)
|
||||
{
|
||||
using namespace Database;
|
||||
|
||||
struct TestCase
|
||||
{
|
||||
Range range;
|
||||
std::size_t subRangeSize;
|
||||
std::vector<Range> expectedSubRanges;
|
||||
};
|
||||
|
||||
TestCase testCases[]
|
||||
{
|
||||
{Range{0, 0}, 1, {}},
|
||||
{Range{1, 0}, 1, {}},
|
||||
{Range{1, 1}, 1, { Range{ 1,1 } }},
|
||||
{Range{1, 3}, 1, { Range{ 1,1 }, Range {2,1}, Range{3,1} }},
|
||||
{Range{0, 100}, 100, { Range{0,100} }},
|
||||
{Range{0, 50}, 100, { Range{0,50} }},
|
||||
{Range{100, 200}, 100, { Range{100,100}, Range{200,100} }},
|
||||
{Range{100, 101}, 100, { Range{100,100}, Range{200,1}}},
|
||||
{Range{1000, 10}, 100, { Range{1000,10} }},
|
||||
{Range{1, 100}, 50, { Range{1,50}, Range{51, 50} }},
|
||||
};
|
||||
|
||||
for (const TestCase& test : testCases)
|
||||
{
|
||||
std::vector<Range> subRanges;
|
||||
foreachSubRange(test.range, test.subRangeSize, [&](Range subRange)
|
||||
{
|
||||
subRanges.push_back(subRange);
|
||||
return true;
|
||||
});
|
||||
|
||||
EXPECT_EQ(subRanges, test.expectedSubRanges) << ", test index = " << std::distance(std::cbegin(testCases), &test);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(DatabaseFixture, Common_IdType)
|
||||
{
|
||||
using namespace Database;
|
||||
@@ -134,19 +172,19 @@ TEST_F(DatabaseFixture, Common_IdType)
|
||||
}
|
||||
|
||||
{
|
||||
const IdType id{0};
|
||||
const IdType id{ 0 };
|
||||
EXPECT_TRUE(id.isValid());
|
||||
}
|
||||
|
||||
{
|
||||
const IdType id1{0};
|
||||
const IdType id2{0};
|
||||
const IdType id1{ 0 };
|
||||
const IdType id2{ 0 };
|
||||
EXPECT_EQ(id1, id2);
|
||||
}
|
||||
|
||||
{
|
||||
const IdType id1{0};
|
||||
const IdType id2{1};
|
||||
const IdType id1{ 0 };
|
||||
const IdType id2{ 1 };
|
||||
EXPECT_NE(id1, id2);
|
||||
EXPECT_LT(id1, id2);
|
||||
EXPECT_GT(id2, id1);
|
||||
@@ -158,31 +196,31 @@ TEST_F(DatabaseFixture, Common_subRange)
|
||||
using namespace Database;
|
||||
|
||||
RangeResults<int> results;
|
||||
results.range = Range {0, 2};
|
||||
results.results = {5, 6};
|
||||
results.range = Range{ 0, 2 };
|
||||
results.results = { 5, 6 };
|
||||
results.moreResults = false;
|
||||
|
||||
{
|
||||
auto subRange {results.getSubRange(Range {0, 1})};
|
||||
auto subRange{ results.getSubRange(Range {0, 1}) };
|
||||
EXPECT_TRUE(subRange.moreResults);
|
||||
ASSERT_EQ(subRange.results.size(), 1);
|
||||
EXPECT_EQ(subRange.results.front(), 5);
|
||||
}
|
||||
{
|
||||
auto subRange {results.getSubRange(Range {1, 1})};
|
||||
auto subRange{ results.getSubRange(Range {1, 1}) };
|
||||
EXPECT_FALSE(subRange.moreResults);
|
||||
ASSERT_EQ(subRange.results.size(), 1);
|
||||
EXPECT_EQ(subRange.results.front(), 6);
|
||||
}
|
||||
{
|
||||
auto subRange {results.getSubRange(Range {0, 2})};
|
||||
auto subRange{ results.getSubRange(Range {0, 2}) };
|
||||
EXPECT_FALSE(subRange.moreResults);
|
||||
ASSERT_EQ(subRange.results.size(), 2);
|
||||
EXPECT_EQ(subRange.results.front(), 5);
|
||||
EXPECT_EQ(subRange.results.back(), 6);
|
||||
}
|
||||
{
|
||||
auto subRange {results.getSubRange(Range {})};
|
||||
auto subRange{ results.getSubRange(Range {}) };
|
||||
EXPECT_FALSE(subRange.moreResults);
|
||||
ASSERT_EQ(subRange.results.size(), 2);
|
||||
EXPECT_EQ(subRange.results.front(), 5);
|
||||
@@ -191,18 +229,18 @@ TEST_F(DatabaseFixture, Common_subRange)
|
||||
}
|
||||
|
||||
{
|
||||
auto subRange {results.getSubRange(Range {1, 0})};
|
||||
auto subRange{ results.getSubRange(Range {1, 0}) };
|
||||
EXPECT_FALSE(subRange.moreResults);
|
||||
ASSERT_EQ(subRange.results.size(), 1);
|
||||
EXPECT_EQ(subRange.results.front(), 6);
|
||||
const Range expectedRange {1, 1};
|
||||
const Range expectedRange{ 1, 1 };
|
||||
EXPECT_EQ(subRange.range, expectedRange);
|
||||
}
|
||||
{
|
||||
auto subRange {results.getSubRange(Range {3, 2})};
|
||||
auto subRange{ results.getSubRange(Range {3, 2}) };
|
||||
EXPECT_FALSE(subRange.moreResults);
|
||||
ASSERT_EQ(subRange.results.size(), 0);
|
||||
const Range expectedRange {2, 0};
|
||||
const Range expectedRange{ 2, 0 };
|
||||
EXPECT_EQ(subRange.range, expectedRange);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user