From 3cf089699839d1e0ddb5c3001994937bf0b3625b Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 10 Apr 2024 09:35:33 +0200 Subject: [PATCH] test/util/TestIntrusiveTreeSet: add test with large randomized tree, erasing random elements Test fails currently due to two bugs in the red-black tree implementation. --- test/util/TestIntrusiveTreeSet.cxx | 62 ++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/test/util/TestIntrusiveTreeSet.cxx b/test/util/TestIntrusiveTreeSet.cxx index 71e3fab88..06ffc537f 100644 --- a/test/util/TestIntrusiveTreeSet.cxx +++ b/test/util/TestIntrusiveTreeSet.cxx @@ -6,6 +6,8 @@ #include +#include // for std::rand() +#include #include namespace { @@ -192,3 +194,63 @@ TEST(IntrusiveTreeSet, RandomOrder) } } } + +TEST(IntrusiveTreeSet, LargeRandom) +{ + std::deque> items; + IntrusiveTreeSet> set; + + std::srand(42); + for (unsigned i = 0; i < 1024; ++i) { + items.emplace_back(std::make_unique(std::rand())); + set.insert(*items.back()); + +#ifndef NDEBUG + set.Check(); +#endif + } + + std::sort(items.begin(), items.end(), [](const auto &a, const auto &b){ + return a->value < b->value; + }); + + std::size_t idx = 0; + + for (const auto &i : set) { + EXPECT_EQ(i.value, items[idx++]->value); + } + + while (!set.empty()) { + EXPECT_FALSE(items.empty()); + EXPECT_TRUE(items.front()->is_linked()); + EXPECT_EQ(items.front()->value, set.front().value); + + // erase the front element + set.pop_front(); + EXPECT_FALSE(items.front()->is_linked()); + items.pop_front(); + +#ifndef NDEBUG + set.Check(); +#endif + + // erase a random element + const auto r = std::next(items.begin(), std::rand() % items.size()); + EXPECT_TRUE((*r)->is_linked()); + set.erase(set.iterator_to(**r)); + EXPECT_FALSE((*r)->is_linked()); + items.erase(r); + +#ifndef NDEBUG + set.Check(); +#endif + + idx = 0; + for (const auto &i : set) { + EXPECT_EQ(i.value, items[idx++]->value); + } + } + + EXPECT_TRUE(items.empty()); +}