Commit 363e37a3 authored by Mukund Sivaraman's avatar Mukund Sivaraman
Browse files

[2811] Add a DomainTreeTest.checkDistance testcase

This is a test that verifies that the tree is balanced, and doesn't go
over the red-black theoretical limit. It constructs a random large
million+ name zone and checks that the distance from every node to its
subtree root is within limit. This is a check that was not implemented
and we should have this as performance correctness proof, as the
DomainTree is so central to our memory datasrc performance.
parent ee0e068e
......@@ -435,6 +435,21 @@ public:
/// This method never throws an exception.
const DomainTreeNode<T>* predecessor() const;
/// \brief returns the node distance from the root of its subtree
size_t getDistance() const {
size_t nodes = 1;
for (const DomainTreeNode<T>* node = this;
node != NULL;
node = node->getParent()) {
if (node->isSubTreeRoot()) {
break;
}
++nodes;
}
return (nodes);
}
private:
/// \brief private shared implementation of successor and predecessor
///
......
......@@ -17,6 +17,7 @@
#include <exceptions/exceptions.h>
#include <util/memory_segment_local.h>
#include <util/random/random_number_generator.h>
#include <dns/name.h>
#include <dns/rrclass.h>
......@@ -94,6 +95,10 @@ protected:
const char* const domain_names[] = {
"c", "b", "a", "x.d.e.f", "z.d.e.f", "g.h", "i.g.h", "o.w.y.d.e.f",
"j.z.d.e.f", "p.w.y.d.e.f", "q.w.y.d.e.f", "k.g.h"};
const int node_distances[] = {
3, 1, 2, 2, 2, 3, 1, 2, 1, 1, 2, 2
};
int name_count = sizeof(domain_names) / sizeof(domain_names[0]);
for (int i = 0; i < name_count; ++i) {
dtree.insert(mem_sgmt_, Name(domain_names[i]), &dtnode);
......@@ -103,7 +108,8 @@ protected:
dtree_expose_empty_node.insert(mem_sgmt_, Name(domain_names[i]),
&dtnode);
EXPECT_EQ(static_cast<int*>(NULL), dtnode->setData(new int(i + 1)));
EXPECT_EQ(static_cast<int*>(NULL), dtnode->setData(
new int(node_distances[i])));
}
}
......@@ -126,6 +132,74 @@ TEST_F(DomainTreeTest, nodeCount) {
EXPECT_EQ(0, dtree.getNodeCount());
}
TEST_F(DomainTreeTest, getDistance) {
TestDomainTreeNodeChain node_path;
const TestDomainTreeNode* node = NULL;
EXPECT_EQ(TestDomainTree::EXACTMATCH,
dtree_expose_empty_node.find(Name("a"),
&node,
node_path));
while (node != NULL) {
const int* distance = node->getData();
if (distance != NULL) {
EXPECT_EQ(*distance, node->getDistance());
}
node = dtree_expose_empty_node.nextNode(node_path);
}
}
TEST_F(DomainTreeTest, checkDistance) {
// This test checks an important performance-related property of the
// DomainTree (a red-black tree), which is important for us: the
// longest path from a sub-tree's root to a node is no more than
// 2log(n). This tests that the tree is balanced.
TreeHolder mytree_holder(mem_sgmt_, TestDomainTree::create(mem_sgmt_));
TestDomainTree& mytree = *mytree_holder.get();
isc::util::random::UniformRandomIntegerGenerator gen('a', 'z');
const size_t log_num_nodes = 20;
// Make a large million+ node top-level domain tree, i.e., the
// following code inserts names such as:
//
// savoucnsrkrqzpkqypbygwoiliawpbmz.
// wkadamcbbpjtundbxcmuayuycposvngx.
// wzbpznemtooxdpjecdxynsfztvnuyfao.
// yueojmhyffslpvfmgyfwioxegfhepnqq.
//
for (int i = 0; i < (1 << log_num_nodes); i++) {
string namestr;
while (true) {
for (int j = 0; j < 32; j++) {
namestr += gen();
}
namestr += '.';
if (mytree.insert(mem_sgmt_, Name(namestr), &dtnode) ==
TestDomainTree::SUCCESS) {
break;
}
namestr.clear();
}
EXPECT_EQ(static_cast<int*>(NULL), dtnode->setData(new int(i + 1)));
}
TestDomainTreeNodeChain node_path;
const TestDomainTreeNode* node = NULL;
// Try to find a node left of the left-most node, and start from its
// next node (which is the left-most node in its subtree).
EXPECT_EQ(TestDomainTree::NOTFOUND,
mytree.find<void*>(Name("0"), &node, node_path, NULL, NULL));
while ((node = mytree.nextNode(node_path)) != NULL) {
// The distance from each node to its sub-tree root must be less
// than 2 * log(n).
EXPECT_GE(2 * log_num_nodes, node->getDistance());
}
}
TEST_F(DomainTreeTest, setGetData) {
// set new data to an existing node. It should have some data.
int* newdata = new int(11);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment