util/IntrusiveTreeSet: add debug method Check()
Only for the unit test.
This commit is contained in:
parent
669cbcd25a
commit
e0a53d4747
|
@ -176,6 +176,16 @@ public:
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
IntrusiveTreeSet() noexcept = default;
|
IntrusiveTreeSet() noexcept = default;
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
/**
|
||||||
|
* For debugging only: check the integrity of the red-black
|
||||||
|
* tree.
|
||||||
|
*/
|
||||||
|
void Check() noexcept {
|
||||||
|
RedBlackTreeNode::BlackHeight(GetRoot());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
constexpr bool empty() const noexcept {
|
constexpr bool empty() const noexcept {
|
||||||
return GetRoot() == nullptr;
|
return GetRoot() == nullptr;
|
||||||
|
|
|
@ -173,6 +173,36 @@ struct RedBlackTreeNode {
|
||||||
return GetLeftMost(this);
|
return GetLeftMost(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
/**
|
||||||
|
* Determine the "black height" (the number of black nodes in
|
||||||
|
* any path from the root to the leaves). This is for
|
||||||
|
* debugging only. It walks the whole tree and aborts if the
|
||||||
|
* black height is not consistent.
|
||||||
|
*/
|
||||||
|
static unsigned BlackHeight(const RedBlackTreeNode *node) noexcept {
|
||||||
|
if (node == nullptr)
|
||||||
|
/* leaf nodes (NIL / nullptr) count as
|
||||||
|
black */
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
assert(node->parent != nullptr);
|
||||||
|
assert(node->color != Color::HEAD);
|
||||||
|
assert(node->color != Color::RED || node->parent->color != Color::RED);
|
||||||
|
|
||||||
|
assert(node->children[0] == nullptr || node->children[0]->parent == node);
|
||||||
|
assert(node->children[1] == nullptr || node->children[1]->parent == node);
|
||||||
|
|
||||||
|
const unsigned left_height = BlackHeight(node->children[0]);
|
||||||
|
const unsigned right_height = BlackHeight(node->children[1]);
|
||||||
|
|
||||||
|
/* the black height must be equal in all paths */
|
||||||
|
assert(left_height == right_height);
|
||||||
|
|
||||||
|
return left_height + (node->color == Color::BLACK);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
constexpr static RedBlackTreeNode *GetLeftHandedParent(RedBlackTreeNode *node) noexcept {
|
constexpr static RedBlackTreeNode *GetLeftHandedParent(RedBlackTreeNode *node) noexcept {
|
||||||
|
|
|
@ -182,6 +182,10 @@ TEST(IntrusiveTreeSet, RandomOrder)
|
||||||
set.pop_front();
|
set.pop_front();
|
||||||
EXPECT_FALSE(items[remove].is_linked());
|
EXPECT_FALSE(items[remove].is_linked());
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
set.Check();
|
||||||
|
#endif
|
||||||
|
|
||||||
expected = remove + 1;
|
expected = remove + 1;
|
||||||
for (const auto &i : set) {
|
for (const auto &i : set) {
|
||||||
EXPECT_EQ(i.value, expected++);
|
EXPECT_EQ(i.value, expected++);
|
||||||
|
|
Loading…
Reference in New Issue