29 #include <system_error>
31 #include <unordered_set>
36 template <
typename A,
typename B>
37 struct hash<tuple<A, B>> {
38 std::size_t operator()(
const tuple<A, B>& t)
const {
39 auto a = std::hash<A>()(get<0>(t));
40 auto b = std::hash<B>()(get<1>(t));
42 return a ^ (
b + 0x9e3779b9 + (a << 6) + (a >> 2));
46 template <
typename A,
typename B>
47 std::ostream&
operator<<(std::ostream& out,
const tuple<A, B>& t) {
48 return out <<
"[" << get<0>(t) <<
"," << get<1>(t) <<
"]";
56 TEST(BTreeMultiSet, Basic) {
57 const bool DEBUG =
false;
63 EXPECT_EQ(3, test_set::max_keys_per_node);
73 if (
DEBUG) t.printTree();
157 TEST(BTreeMultiSet, Duplicates) {
160 for (
int i = 0;
i < 10;
i++) {
164 std::vector<int>
data(t.begin(), t.end());
166 for (
int i = 0;
i < 10;
i++) {
171 TEST(BTreeMultiSet, Incremental) {
175 for (
int i = 0;
i < N;
i++) {
177 for (
int j = 0;
j < N;
j++) {
183 TEST(BTreeMultiSet, Decremental) {
187 for (
int i = N;
i >= 0;
i--) {
189 for (
int j = 0;
j < N;
j++) {
195 TEST(BTreeMultiSet, Shuffled) {
202 std::vector<int>
data;
203 for (
int i = 0;
i < N;
i++) {
206 std::random_device rd;
207 std::mt19937 generator(rd());
209 shuffle(
data.begin(),
data.end(), generator);
211 for (
int i = 0;
i < N;
i++) {
215 for (
int i = 0;
i < N;
i++) {
220 TEST(BTreeMultiSet, IteratorEmpty) {
227 TEST(BTreeMultiSet, IteratorBasic) {
231 for (
int i = 0;
i < 10;
i++) {
250 TEST(BTreeMultiSet, IteratorStress) {
257 std::vector<int>
data;
258 for (
int i = 0;
i < N;
i++) {
261 std::random_device rd;
262 std::mt19937 generator(rd());
264 shuffle(
data.begin(),
data.end(), generator);
266 for (
int i = 0;
i < N;
i++) {
279 TEST(BTreeMultiSet, BoundaryTest) {
284 for (
int i = 0;
i < 10;
i++) {
290 auto a = t.lower_bound(5);
293 auto b = t.upper_bound(5);
305 a = t.lower_bound(5);
308 b = t.upper_bound(5);
323 TEST(BTreeMultiSet, BoundaryEmpty) {
333 EXPECT_EQ(t.lower_bound(3), t.upper_bound(3));
334 EXPECT_EQ(t.lower_bound(5), t.upper_bound(5));
337 EXPECT_EQ(t.lower_bound(3), t.upper_bound(3));
338 EXPECT_EQ(t.lower_bound(5), t.upper_bound(5));
342 EXPECT_EQ(t.lower_bound(3), t.upper_bound(3));
343 EXPECT_NE(t.lower_bound(5), t.upper_bound(5));
349 for (
int N = 0; N < 100; N++) {
351 std::vector<int>
data;
353 for (
int i = 0;
i < N;
i++) {
356 auto t = test_set::load(
data.begin(),
data.end());
387 std::vector<Entry>
getData(
unsigned numEntries) {
388 std::vector<Entry> res(numEntries);
390 for (
unsigned i = 0;
i < numEntries;
i++) {
393 std::random_device rd;
394 std::mt19937 generator(rd());
396 shuffle(res.begin(), res.end(), generator);
407 return std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
410 template <
typename Op>
411 long time(
const std::string& name,
const Op& operation) {
412 std::cout <<
"\t" << std::setw(30) << std::setiosflags(std::ios::left) << name
413 << std::resetiosflags(std::ios::left) <<
" ... " << std::flush;
418 std::cout <<
" done [" << std::setw(5) <<
time <<
"ms]\n";
422 template <
typename C>
429 template <
typename A,
typename B,
typename C,
typename D>
436 #define checkPerformance(set_type, name, in, out) \
438 std::cout << "Testing: " << name << " ..\n"; \
440 time("filling set", [&]() { \
441 reserver<set_type>()(set, in.size()); \
442 for (const auto& cur : in) { \
447 time("full scan", [&]() { \
448 for (auto it = set.begin(); it != set.end(); ++it) { \
452 EXPECT_EQ((size_t)counter, set.size()); \
453 bool allPresent = true; \
454 time("membership in", [&]() { \
455 for (const auto& cur : in) { \
456 allPresent = (set.find(cur) != set.end()) && allPresent; \
459 EXPECT_TRUE(allPresent); \
460 bool allMissing = true; \
461 time("membership out", [&]() { \
462 for (const auto& cur : out) { \
463 allMissing = (set.find(cur) == set.end()) && allMissing; \
466 EXPECT_TRUE(allMissing); \
467 bool allFound = true; \
468 time("lower_boundaries", [&]() { \
469 for (const auto& cur : in) { \
470 allFound = (set.lower_bound(cur) == set.find(cur)) && allFound; \
473 EXPECT_TRUE(allFound); \
475 time("upper_boundaries", [&]() { \
476 for (const auto& cur : in) { \
477 allFound = (set.upper_bound(cur) == (++set.find(cur))) && allFound; \
480 EXPECT_TRUE(allFound); \
482 time("boundaries on missing elements", [&]() { \
483 for (const auto& cur : out) { \
484 allFound = (set.lower_bound(cur) == set.upper_bound(cur)) && allFound; \
487 EXPECT_TRUE(allFound); \
488 set_type a(in.begin(), in.end()); \
489 set_type b(out.begin(), out.end()); \
490 time("merge two sets", [&]() { a.insert(b.begin(), b.end()); }); \
491 std::cout << "\tDone!\n\n"; \
498 std::cout <<
"Generating Test-Data ...\n";
499 std::vector<Entry> in;
500 std::vector<Entry> out;
501 time(
"generating data", [&]() {
503 for (std::size_t
i = 0;
i <
data.size();
i += 2) {
504 in.push_back(
data[
i]);
505 out.push_back(
data[
i + 1]);
509 using t1 = std::set<Entry>;
522 std::vector<int>
data;
523 for (
int i = 0;
i < N;
i++) {