2015-02-26 17:05:05 +01:00
|
|
|
#include "testutils/DataTreeTest.h"
|
2015-02-25 01:31:16 +01:00
|
|
|
#include <google/gmock/gmock.h>
|
|
|
|
|
|
|
|
using ::testing::_;
|
|
|
|
|
|
|
|
using blobstore::onblocks::datanodestore::DataLeafNode;
|
|
|
|
using blobstore::onblocks::datanodestore::DataInnerNode;
|
|
|
|
using blobstore::onblocks::datanodestore::DataNode;
|
|
|
|
using blobstore::onblocks::datatreestore::DataTree;
|
|
|
|
using blockstore::Key;
|
|
|
|
|
2015-06-26 15:59:18 +02:00
|
|
|
using cpputils::unique_ref;
|
2015-02-25 16:52:17 +01:00
|
|
|
|
2015-02-25 01:31:16 +01:00
|
|
|
class TraversorMock {
|
|
|
|
public:
|
|
|
|
MOCK_METHOD2(called, void(DataLeafNode*, uint32_t));
|
|
|
|
};
|
|
|
|
|
|
|
|
MATCHER_P(KeyEq, expected, "node key equals") {
|
|
|
|
return arg->key() == expected;
|
|
|
|
}
|
|
|
|
|
|
|
|
class DataTreeTest_TraverseLeaves: public DataTreeTest {
|
|
|
|
public:
|
2015-06-26 15:59:18 +02:00
|
|
|
unique_ref<DataInnerNode> CreateThreeLevel() {
|
2015-02-25 16:52:17 +01:00
|
|
|
return CreateInner({
|
|
|
|
CreateFullTwoLevel(),
|
|
|
|
CreateFullTwoLevel(),
|
|
|
|
CreateFullTwoLevel(),
|
|
|
|
CreateFullTwoLevel(),
|
|
|
|
CreateFullTwoLevel(),
|
|
|
|
CreateInner({CreateLeaf(), CreateLeaf(), CreateLeaf()})});
|
|
|
|
}
|
|
|
|
|
2015-06-26 15:59:18 +02:00
|
|
|
unique_ref<DataInnerNode> CreateFourLevel() {
|
2015-02-25 16:52:17 +01:00
|
|
|
return CreateInner({
|
|
|
|
CreateFullThreeLevel(),
|
|
|
|
CreateFullThreeLevel(),
|
|
|
|
CreateInner({CreateFullTwoLevel(), CreateInner({CreateLeaf()})})
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2015-02-25 14:42:20 +01:00
|
|
|
void EXPECT_TRAVERSE_LEAF(const Key &key, uint32_t leafIndex) {
|
|
|
|
EXPECT_CALL(traversor, called(KeyEq(key), leafIndex)).Times(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
void EXPECT_TRAVERSE_ALL_CHILDREN_OF(const DataInnerNode &node, uint32_t firstLeafIndex) {
|
2015-05-08 02:10:40 +02:00
|
|
|
for (unsigned int i = 0; i < node.numChildren(); ++i) {
|
2015-02-25 14:42:20 +01:00
|
|
|
EXPECT_TRAVERSE_LEAF(node.getChild(i)->key(), firstLeafIndex+i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void EXPECT_DONT_TRAVERSE_ANY_LEAVES() {
|
|
|
|
EXPECT_CALL(traversor, called(_, _)).Times(0);
|
|
|
|
}
|
|
|
|
|
2015-02-25 01:31:16 +01:00
|
|
|
void TraverseLeaves(DataNode *root, uint32_t beginIndex, uint32_t endIndex) {
|
|
|
|
root->flush();
|
2015-06-26 15:59:18 +02:00
|
|
|
auto tree = std::move(treeStore.load(root->key()).get());
|
2015-02-25 01:31:16 +01:00
|
|
|
tree->traverseLeaves(beginIndex, endIndex, [this] (DataLeafNode *leaf, uint32_t nodeIndex) {
|
|
|
|
traversor.called(leaf, nodeIndex);
|
|
|
|
});
|
|
|
|
}
|
2015-02-25 16:52:17 +01:00
|
|
|
|
2015-02-25 01:31:16 +01:00
|
|
|
TraversorMock traversor;
|
|
|
|
};
|
|
|
|
|
|
|
|
TEST_F(DataTreeTest_TraverseLeaves, TraverseSingleLeafTree) {
|
|
|
|
auto root = CreateLeaf();
|
2015-02-25 14:42:20 +01:00
|
|
|
EXPECT_TRAVERSE_LEAF(root->key(), 0);
|
2015-02-25 01:31:16 +01:00
|
|
|
|
|
|
|
TraverseLeaves(root.get(), 0, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(DataTreeTest_TraverseLeaves, TraverseNothingInSingleLeafTree1) {
|
|
|
|
auto root = CreateLeaf();
|
2015-02-25 14:42:20 +01:00
|
|
|
EXPECT_DONT_TRAVERSE_ANY_LEAVES();
|
2015-02-25 01:31:16 +01:00
|
|
|
|
|
|
|
TraverseLeaves(root.get(), 0, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(DataTreeTest_TraverseLeaves, TraverseNothingInSingleLeafTree2) {
|
|
|
|
auto root = CreateLeaf();
|
2015-02-25 14:42:20 +01:00
|
|
|
EXPECT_DONT_TRAVERSE_ANY_LEAVES();
|
2015-02-25 01:31:16 +01:00
|
|
|
|
|
|
|
TraverseLeaves(root.get(), 1, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(DataTreeTest_TraverseLeaves, TraverseFirstLeafOfFullTwolevelTree) {
|
|
|
|
auto root = CreateFullTwoLevel();
|
2015-02-25 14:42:20 +01:00
|
|
|
EXPECT_TRAVERSE_LEAF(root->getChild(0)->key(), 0);
|
2015-02-25 01:31:16 +01:00
|
|
|
|
|
|
|
TraverseLeaves(root.get(), 0, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(DataTreeTest_TraverseLeaves, TraverseMiddleLeafOfFullTwolevelTree) {
|
|
|
|
auto root = CreateFullTwoLevel();
|
2015-02-25 14:42:20 +01:00
|
|
|
EXPECT_TRAVERSE_LEAF(root->getChild(5)->key(), 5);
|
2015-02-25 01:31:16 +01:00
|
|
|
|
|
|
|
TraverseLeaves(root.get(), 5, 6);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(DataTreeTest_TraverseLeaves, TraverseLastLeafOfFullTwolevelTree) {
|
|
|
|
auto root = CreateFullTwoLevel();
|
2015-02-25 22:30:48 +01:00
|
|
|
EXPECT_TRAVERSE_LEAF(root->getChild(nodeStore->layout().maxChildrenPerInnerNode()-1)->key(), nodeStore->layout().maxChildrenPerInnerNode()-1);
|
2015-02-25 01:31:16 +01:00
|
|
|
|
2015-02-25 22:30:48 +01:00
|
|
|
TraverseLeaves(root.get(), nodeStore->layout().maxChildrenPerInnerNode()-1, nodeStore->layout().maxChildrenPerInnerNode());
|
2015-02-25 01:31:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(DataTreeTest_TraverseLeaves, TraverseNothingInFullTwolevelTree1) {
|
|
|
|
auto root = CreateFullTwoLevel();
|
2015-02-25 14:42:20 +01:00
|
|
|
EXPECT_DONT_TRAVERSE_ANY_LEAVES();
|
2015-02-25 01:31:16 +01:00
|
|
|
|
|
|
|
TraverseLeaves(root.get(), 0, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(DataTreeTest_TraverseLeaves, TraverseNothingInFullTwolevelTree2) {
|
|
|
|
auto root = CreateFullTwoLevel();
|
2015-02-25 14:42:20 +01:00
|
|
|
EXPECT_DONT_TRAVERSE_ANY_LEAVES();
|
2015-02-25 01:31:16 +01:00
|
|
|
|
2015-02-25 22:30:48 +01:00
|
|
|
TraverseLeaves(root.get(), nodeStore->layout().maxChildrenPerInnerNode(), nodeStore->layout().maxChildrenPerInnerNode());
|
2015-02-25 01:31:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(DataTreeTest_TraverseLeaves, TraverseFirstLeafOfThreeLevelMinDataTree) {
|
|
|
|
auto root = CreateThreeLevelMinData();
|
2015-02-25 14:42:20 +01:00
|
|
|
EXPECT_TRAVERSE_LEAF(LoadInnerNode(root->getChild(0)->key())->getChild(0)->key(), 0);
|
2015-02-25 01:31:16 +01:00
|
|
|
|
|
|
|
TraverseLeaves(root.get(), 0, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(DataTreeTest_TraverseLeaves, TraverseMiddleLeafOfThreeLevelMinDataTree) {
|
|
|
|
auto root = CreateThreeLevelMinData();
|
2015-02-25 14:42:20 +01:00
|
|
|
EXPECT_TRAVERSE_LEAF(LoadInnerNode(root->getChild(0)->key())->getChild(5)->key(), 5);
|
2015-02-25 01:31:16 +01:00
|
|
|
|
|
|
|
TraverseLeaves(root.get(), 5, 6);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(DataTreeTest_TraverseLeaves, TraverseLastLeafOfThreeLevelMinDataTree) {
|
|
|
|
auto root = CreateThreeLevelMinData();
|
2015-02-25 22:30:48 +01:00
|
|
|
EXPECT_TRAVERSE_LEAF(LoadInnerNode(root->getChild(1)->key())->getChild(0)->key(), nodeStore->layout().maxChildrenPerInnerNode());
|
2015-02-25 01:31:16 +01:00
|
|
|
|
2015-02-25 22:30:48 +01:00
|
|
|
TraverseLeaves(root.get(), nodeStore->layout().maxChildrenPerInnerNode(), nodeStore->layout().maxChildrenPerInnerNode()+1);
|
2015-02-25 01:31:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(DataTreeTest_TraverseLeaves, TraverseAllLeavesOfFullTwolevelTree) {
|
|
|
|
auto root = CreateFullTwoLevel();
|
2015-02-25 14:42:20 +01:00
|
|
|
EXPECT_TRAVERSE_ALL_CHILDREN_OF(*root, 0);
|
2015-02-25 01:31:16 +01:00
|
|
|
|
2015-02-25 22:30:48 +01:00
|
|
|
TraverseLeaves(root.get(), 0, nodeStore->layout().maxChildrenPerInnerNode());
|
2015-02-25 01:31:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(DataTreeTest_TraverseLeaves, TraverseAllLeavesOfThreelevelMinDataTree) {
|
|
|
|
auto root = CreateThreeLevelMinData();
|
2015-02-25 14:42:20 +01:00
|
|
|
EXPECT_TRAVERSE_ALL_CHILDREN_OF(*LoadInnerNode(root->getChild(0)->key()), 0);
|
2015-02-25 22:30:48 +01:00
|
|
|
EXPECT_TRAVERSE_LEAF(LoadInnerNode(root->getChild(1)->key())->getChild(0)->key(), nodeStore->layout().maxChildrenPerInnerNode());
|
2015-02-25 01:31:16 +01:00
|
|
|
|
2015-02-25 22:30:48 +01:00
|
|
|
TraverseLeaves(root.get(), 0, nodeStore->layout().maxChildrenPerInnerNode()+1);
|
2015-02-25 01:31:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(DataTreeTest_TraverseLeaves, TraverseFirstChildOfThreelevelMinDataTree) {
|
|
|
|
auto root = CreateThreeLevelMinData();
|
2015-02-25 14:42:20 +01:00
|
|
|
EXPECT_TRAVERSE_ALL_CHILDREN_OF(*LoadInnerNode(root->getChild(0)->key()), 0);
|
2015-02-25 01:31:16 +01:00
|
|
|
|
2015-02-25 22:30:48 +01:00
|
|
|
TraverseLeaves(root.get(), 0, nodeStore->layout().maxChildrenPerInnerNode());
|
2015-02-25 01:31:16 +01:00
|
|
|
}
|
|
|
|
|
2015-02-25 16:52:17 +01:00
|
|
|
TEST_F(DataTreeTest_TraverseLeaves, TraverseFirstPartOfFullTwolevelTree) {
|
|
|
|
auto root = CreateFullTwoLevel();
|
2015-05-08 02:10:40 +02:00
|
|
|
for (unsigned int i = 0; i < 5; ++i) {
|
2015-02-25 16:52:17 +01:00
|
|
|
EXPECT_TRAVERSE_LEAF(root->getChild(i)->key(), i);
|
|
|
|
}
|
|
|
|
|
|
|
|
TraverseLeaves(root.get(), 0, 5);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(DataTreeTest_TraverseLeaves, TraverseInnerPartOfFullTwolevelTree) {
|
|
|
|
auto root = CreateFullTwoLevel();
|
2015-05-08 02:10:40 +02:00
|
|
|
for (unsigned int i = 5; i < 10; ++i) {
|
2015-02-25 16:52:17 +01:00
|
|
|
EXPECT_TRAVERSE_LEAF(root->getChild(i)->key(), i);
|
|
|
|
}
|
|
|
|
|
|
|
|
TraverseLeaves(root.get(), 5, 10);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(DataTreeTest_TraverseLeaves, TraverseLastPartOfFullTwolevelTree) {
|
|
|
|
auto root = CreateFullTwoLevel();
|
2015-05-08 02:10:40 +02:00
|
|
|
for (unsigned int i = 5; i < nodeStore->layout().maxChildrenPerInnerNode(); ++i) {
|
2015-02-25 16:52:17 +01:00
|
|
|
EXPECT_TRAVERSE_LEAF(root->getChild(i)->key(), i);
|
|
|
|
}
|
|
|
|
|
2015-02-25 22:30:48 +01:00
|
|
|
TraverseLeaves(root.get(), 5, nodeStore->layout().maxChildrenPerInnerNode());
|
2015-02-25 16:52:17 +01:00
|
|
|
}
|
|
|
|
|
2015-02-25 01:31:16 +01:00
|
|
|
TEST_F(DataTreeTest_TraverseLeaves, TraverseFirstPartOfThreelevelMinDataTree) {
|
|
|
|
auto root = CreateThreeLevelMinData();
|
|
|
|
auto node = LoadInnerNode(root->getChild(0)->key());
|
2015-05-08 02:10:40 +02:00
|
|
|
for (unsigned int i = 0; i < 5; ++i) {
|
2015-02-25 14:42:20 +01:00
|
|
|
EXPECT_TRAVERSE_LEAF(node->getChild(i)->key(), i);
|
2015-02-25 01:31:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
TraverseLeaves(root.get(), 0, 5);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(DataTreeTest_TraverseLeaves, TraverseInnerPartOfThreelevelMinDataTree) {
|
|
|
|
auto root = CreateThreeLevelMinData();
|
|
|
|
auto node = LoadInnerNode(root->getChild(0)->key());
|
2015-05-08 02:10:40 +02:00
|
|
|
for (unsigned int i = 5; i < 10; ++i) {
|
2015-02-25 14:42:20 +01:00
|
|
|
EXPECT_TRAVERSE_LEAF(node->getChild(i)->key(), i);
|
2015-02-25 01:31:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
TraverseLeaves(root.get(), 5, 10);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(DataTreeTest_TraverseLeaves, TraverseLastPartOfThreelevelMinDataTree) {
|
|
|
|
auto root = CreateThreeLevelMinData();
|
|
|
|
auto node = LoadInnerNode(root->getChild(0)->key());
|
2015-05-08 02:10:40 +02:00
|
|
|
for (unsigned int i = 5; i < nodeStore->layout().maxChildrenPerInnerNode(); ++i) {
|
2015-02-25 14:42:20 +01:00
|
|
|
EXPECT_TRAVERSE_LEAF(node->getChild(i)->key(), i);
|
2015-02-25 01:31:16 +01:00
|
|
|
}
|
2015-02-25 22:30:48 +01:00
|
|
|
EXPECT_TRAVERSE_LEAF(LoadInnerNode(root->getChild(1)->key())->getChild(0)->key(), nodeStore->layout().maxChildrenPerInnerNode());
|
2015-02-25 01:31:16 +01:00
|
|
|
|
2015-02-25 22:30:48 +01:00
|
|
|
TraverseLeaves(root.get(), 5, nodeStore->layout().maxChildrenPerInnerNode()+1);
|
2015-02-25 01:31:16 +01:00
|
|
|
}
|
|
|
|
|
2015-02-25 16:52:17 +01:00
|
|
|
TEST_F(DataTreeTest_TraverseLeaves, TraverseFirstLeafOfThreelevelTree) {
|
|
|
|
auto root = CreateThreeLevel();
|
|
|
|
EXPECT_TRAVERSE_LEAF(LoadInnerNode(root->getChild(0)->key())->getChild(0)->key(), 0);
|
|
|
|
|
|
|
|
TraverseLeaves(root.get(), 0, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(DataTreeTest_TraverseLeaves, TraverseLastLeafOfThreelevelTree) {
|
|
|
|
auto root = CreateThreeLevel();
|
2015-02-25 22:30:48 +01:00
|
|
|
uint32_t numLeaves = nodeStore->layout().maxChildrenPerInnerNode() * 5 + 3;
|
2015-02-25 16:52:17 +01:00
|
|
|
EXPECT_TRAVERSE_LEAF(LoadInnerNode(root->LastChild()->key())->LastChild()->key(), numLeaves-1);
|
|
|
|
|
|
|
|
TraverseLeaves(root.get(), numLeaves-1, numLeaves);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(DataTreeTest_TraverseLeaves, TraverseMiddleLeafOfThreelevelTree) {
|
|
|
|
auto root = CreateThreeLevel();
|
2015-02-25 22:30:48 +01:00
|
|
|
uint32_t wantedLeafIndex = nodeStore->layout().maxChildrenPerInnerNode() * 2 + 5;
|
2015-02-25 16:52:17 +01:00
|
|
|
EXPECT_TRAVERSE_LEAF(LoadInnerNode(root->getChild(2)->key())->getChild(5)->key(), wantedLeafIndex);
|
|
|
|
|
|
|
|
TraverseLeaves(root.get(), wantedLeafIndex, wantedLeafIndex+1);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(DataTreeTest_TraverseLeaves, TraverseFirstPartOfThreelevelTree) {
|
|
|
|
auto root = CreateThreeLevel();
|
|
|
|
//Traverse all leaves in the first two children of the root
|
2015-05-08 02:10:40 +02:00
|
|
|
for(unsigned int i = 0; i < 2; ++i) {
|
2015-02-25 22:30:48 +01:00
|
|
|
EXPECT_TRAVERSE_ALL_CHILDREN_OF(*LoadInnerNode(root->getChild(i)->key()), i * nodeStore->layout().maxChildrenPerInnerNode());
|
2015-02-25 16:52:17 +01:00
|
|
|
}
|
|
|
|
//Traverse some of the leaves in the third child of the root
|
|
|
|
auto child = LoadInnerNode(root->getChild(2)->key());
|
2015-05-08 02:10:40 +02:00
|
|
|
for(unsigned int i = 0; i < 5; ++i) {
|
2015-02-25 22:30:48 +01:00
|
|
|
EXPECT_TRAVERSE_LEAF(child->getChild(i)->key(), 2 * nodeStore->layout().maxChildrenPerInnerNode() + i);
|
2015-02-25 16:52:17 +01:00
|
|
|
}
|
|
|
|
|
2015-02-25 22:30:48 +01:00
|
|
|
TraverseLeaves(root.get(), 0, 2 * nodeStore->layout().maxChildrenPerInnerNode() + 5);
|
2015-02-25 16:52:17 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(DataTreeTest_TraverseLeaves, TraverseMiddlePartOfThreelevelTree_OnlyFullChildren) {
|
|
|
|
auto root = CreateThreeLevel();
|
|
|
|
//Traverse some of the leaves in the second child of the root
|
|
|
|
auto child = LoadInnerNode(root->getChild(1)->key());
|
2015-05-08 02:10:40 +02:00
|
|
|
for(unsigned int i = 5; i < nodeStore->layout().maxChildrenPerInnerNode(); ++i) {
|
2015-02-25 22:30:48 +01:00
|
|
|
EXPECT_TRAVERSE_LEAF(child->getChild(i)->key(), nodeStore->layout().maxChildrenPerInnerNode() + i);
|
2015-02-25 16:52:17 +01:00
|
|
|
}
|
|
|
|
//Traverse all leaves in the third and fourth child of the root
|
2015-05-08 02:10:40 +02:00
|
|
|
for(unsigned int i = 2; i < 4; ++i) {
|
2015-02-25 22:30:48 +01:00
|
|
|
EXPECT_TRAVERSE_ALL_CHILDREN_OF(*LoadInnerNode(root->getChild(i)->key()), i * nodeStore->layout().maxChildrenPerInnerNode());
|
2015-02-25 16:52:17 +01:00
|
|
|
}
|
|
|
|
//Traverse some of the leaves in the fifth child of the root
|
|
|
|
child = LoadInnerNode(root->getChild(4)->key());
|
2015-05-08 02:10:40 +02:00
|
|
|
for(unsigned int i = 0; i < 5; ++i) {
|
2015-02-25 22:30:48 +01:00
|
|
|
EXPECT_TRAVERSE_LEAF(child->getChild(i)->key(), 4 * nodeStore->layout().maxChildrenPerInnerNode() + i);
|
2015-02-25 16:52:17 +01:00
|
|
|
}
|
|
|
|
|
2015-02-25 22:30:48 +01:00
|
|
|
TraverseLeaves(root.get(), nodeStore->layout().maxChildrenPerInnerNode() + 5, 4 * nodeStore->layout().maxChildrenPerInnerNode() + 5);
|
2015-02-25 16:52:17 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(DataTreeTest_TraverseLeaves, TraverseMiddlePartOfThreelevelTree_AlsoLastNonfullChild) {
|
|
|
|
auto root = CreateThreeLevel();
|
|
|
|
//Traverse some of the leaves in the second child of the root
|
|
|
|
auto child = LoadInnerNode(root->getChild(1)->key());
|
2015-05-08 02:10:40 +02:00
|
|
|
for(unsigned int i = 5; i < nodeStore->layout().maxChildrenPerInnerNode(); ++i) {
|
2015-02-25 22:30:48 +01:00
|
|
|
EXPECT_TRAVERSE_LEAF(child->getChild(i)->key(), nodeStore->layout().maxChildrenPerInnerNode() + i);
|
2015-02-25 16:52:17 +01:00
|
|
|
}
|
|
|
|
//Traverse all leaves in the third, fourth and fifth child of the root
|
2015-05-08 02:10:40 +02:00
|
|
|
for(unsigned int i = 2; i < 5; ++i) {
|
2015-02-25 22:30:48 +01:00
|
|
|
EXPECT_TRAVERSE_ALL_CHILDREN_OF(*LoadInnerNode(root->getChild(i)->key()), i * nodeStore->layout().maxChildrenPerInnerNode());
|
2015-02-25 16:52:17 +01:00
|
|
|
}
|
|
|
|
//Traverse some of the leaves in the sixth child of the root
|
|
|
|
child = LoadInnerNode(root->getChild(5)->key());
|
2015-05-08 02:10:40 +02:00
|
|
|
for(unsigned int i = 0; i < 2; ++i) {
|
2015-02-25 22:30:48 +01:00
|
|
|
EXPECT_TRAVERSE_LEAF(child->getChild(i)->key(), 5 * nodeStore->layout().maxChildrenPerInnerNode() + i);
|
2015-02-25 16:52:17 +01:00
|
|
|
}
|
|
|
|
|
2015-02-25 22:30:48 +01:00
|
|
|
TraverseLeaves(root.get(), nodeStore->layout().maxChildrenPerInnerNode() + 5, 5 * nodeStore->layout().maxChildrenPerInnerNode() + 2);
|
2015-02-25 16:52:17 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(DataTreeTest_TraverseLeaves, TraverseLastPartOfThreelevelTree) {
|
|
|
|
auto root = CreateThreeLevel();
|
|
|
|
//Traverse some of the leaves in the second child of the root
|
|
|
|
auto child = LoadInnerNode(root->getChild(1)->key());
|
2015-05-08 02:10:40 +02:00
|
|
|
for(unsigned int i = 5; i < nodeStore->layout().maxChildrenPerInnerNode(); ++i) {
|
2015-02-25 22:30:48 +01:00
|
|
|
EXPECT_TRAVERSE_LEAF(child->getChild(i)->key(), nodeStore->layout().maxChildrenPerInnerNode() + i);
|
2015-02-25 16:52:17 +01:00
|
|
|
}
|
|
|
|
//Traverse all leaves in the third, fourth and fifth child of the root
|
2015-05-08 02:10:40 +02:00
|
|
|
for(unsigned int i = 2; i < 5; ++i) {
|
2015-02-25 22:30:48 +01:00
|
|
|
EXPECT_TRAVERSE_ALL_CHILDREN_OF(*LoadInnerNode(root->getChild(i)->key()), i * nodeStore->layout().maxChildrenPerInnerNode());
|
2015-02-25 16:52:17 +01:00
|
|
|
}
|
|
|
|
//Traverse all of the leaves in the sixth child of the root
|
|
|
|
child = LoadInnerNode(root->getChild(5)->key());
|
2015-05-08 02:10:40 +02:00
|
|
|
for(unsigned int i = 0; i < child->numChildren(); ++i) {
|
2015-02-25 22:30:48 +01:00
|
|
|
EXPECT_TRAVERSE_LEAF(child->getChild(i)->key(), 5 * nodeStore->layout().maxChildrenPerInnerNode() + i);
|
2015-02-25 16:52:17 +01:00
|
|
|
}
|
|
|
|
|
2015-02-25 22:30:48 +01:00
|
|
|
TraverseLeaves(root.get(), nodeStore->layout().maxChildrenPerInnerNode() + 5, 5 * nodeStore->layout().maxChildrenPerInnerNode() + child->numChildren());
|
2015-02-25 16:52:17 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(DataTreeTest_TraverseLeaves, TraverseAllLeavesOfThreelevelTree) {
|
|
|
|
auto root = CreateThreeLevel();
|
|
|
|
//Traverse all leaves in the third, fourth and fifth child of the root
|
2015-05-08 02:10:40 +02:00
|
|
|
for(unsigned int i = 0; i < 5; ++i) {
|
2015-02-25 22:30:48 +01:00
|
|
|
EXPECT_TRAVERSE_ALL_CHILDREN_OF(*LoadInnerNode(root->getChild(i)->key()), i * nodeStore->layout().maxChildrenPerInnerNode());
|
2015-02-25 16:52:17 +01:00
|
|
|
}
|
|
|
|
//Traverse all of the leaves in the sixth child of the root
|
|
|
|
auto child = LoadInnerNode(root->getChild(5)->key());
|
2015-05-08 02:10:40 +02:00
|
|
|
for(unsigned int i = 0; i < child->numChildren(); ++i) {
|
2015-02-25 22:30:48 +01:00
|
|
|
EXPECT_TRAVERSE_LEAF(child->getChild(i)->key(), 5 * nodeStore->layout().maxChildrenPerInnerNode() + i);
|
2015-02-25 16:52:17 +01:00
|
|
|
}
|
|
|
|
|
2015-02-25 22:30:48 +01:00
|
|
|
TraverseLeaves(root.get(), 0, 5 * nodeStore->layout().maxChildrenPerInnerNode() + child->numChildren());
|
2015-02-25 16:52:17 +01:00
|
|
|
}
|
|
|
|
|
2015-02-25 22:38:49 +01:00
|
|
|
TEST_F(DataTreeTest_TraverseLeaves, TraverseAllLeavesOfFourLevelTree) {
|
2015-02-25 16:52:17 +01:00
|
|
|
auto root = CreateFourLevel();
|
|
|
|
//Traverse all leaves of the full threelevel tree in the first child
|
|
|
|
auto firstChild = LoadInnerNode(root->getChild(0)->key());
|
2015-05-08 02:10:40 +02:00
|
|
|
for(unsigned int i = 0; i < firstChild->numChildren(); ++i) {
|
2015-02-25 22:30:48 +01:00
|
|
|
EXPECT_TRAVERSE_ALL_CHILDREN_OF(*LoadInnerNode(firstChild->getChild(i)->key()), i * nodeStore->layout().maxChildrenPerInnerNode());
|
2015-02-25 16:52:17 +01:00
|
|
|
}
|
|
|
|
//Traverse all leaves of the full threelevel tree in the second child
|
|
|
|
auto secondChild = LoadInnerNode(root->getChild(1)->key());
|
2015-05-08 02:10:40 +02:00
|
|
|
for(unsigned int i = 0; i < secondChild->numChildren(); ++i) {
|
2015-02-25 22:30:48 +01:00
|
|
|
EXPECT_TRAVERSE_ALL_CHILDREN_OF(*LoadInnerNode(secondChild->getChild(i)->key()), (nodeStore->layout().maxChildrenPerInnerNode() + i) * nodeStore->layout().maxChildrenPerInnerNode());
|
2015-02-25 16:52:17 +01:00
|
|
|
}
|
|
|
|
//Traverse all leaves of the non-full threelevel tree in the third child
|
|
|
|
auto thirdChild = LoadInnerNode(root->getChild(2)->key());
|
2015-02-25 22:30:48 +01:00
|
|
|
EXPECT_TRAVERSE_ALL_CHILDREN_OF(*LoadInnerNode(thirdChild->getChild(0)->key()), 2 * nodeStore->layout().maxChildrenPerInnerNode() * nodeStore->layout().maxChildrenPerInnerNode());
|
|
|
|
EXPECT_TRAVERSE_LEAF(LoadInnerNode(thirdChild->getChild(1)->key())->getChild(0)->key(), 2 * nodeStore->layout().maxChildrenPerInnerNode() * nodeStore->layout().maxChildrenPerInnerNode() + nodeStore->layout().maxChildrenPerInnerNode());
|
2015-02-25 16:52:17 +01:00
|
|
|
|
2015-02-25 22:30:48 +01:00
|
|
|
TraverseLeaves(root.get(), 0, 2*nodeStore->layout().maxChildrenPerInnerNode()*nodeStore->layout().maxChildrenPerInnerNode() + nodeStore->layout().maxChildrenPerInnerNode() + 1);
|
2015-02-25 16:52:17 +01:00
|
|
|
}
|
2015-02-25 01:31:16 +01:00
|
|
|
|
2015-02-25 22:38:49 +01:00
|
|
|
TEST_F(DataTreeTest_TraverseLeaves, TraverseMiddlePartOfFourLevelTree) {
|
|
|
|
auto root = CreateFourLevel();
|
|
|
|
//Traverse some leaves of the full threelevel tree in the first child
|
|
|
|
auto firstChild = LoadInnerNode(root->getChild(0)->key());
|
|
|
|
auto secondChildOfFirstChild = LoadInnerNode(firstChild->getChild(1)->key());
|
2015-05-08 02:10:40 +02:00
|
|
|
for(unsigned int i = 5; i < secondChildOfFirstChild->numChildren(); ++i) {
|
2015-02-25 22:38:49 +01:00
|
|
|
EXPECT_TRAVERSE_LEAF(secondChildOfFirstChild->getChild(i)->key(), nodeStore->layout().maxChildrenPerInnerNode()+i);
|
|
|
|
}
|
2015-05-08 02:10:40 +02:00
|
|
|
for(unsigned int i = 2; i < firstChild->numChildren(); ++i) {
|
2015-02-25 22:38:49 +01:00
|
|
|
EXPECT_TRAVERSE_ALL_CHILDREN_OF(*LoadInnerNode(firstChild->getChild(i)->key()), i * nodeStore->layout().maxChildrenPerInnerNode());
|
|
|
|
}
|
|
|
|
//Traverse all leaves of the full threelevel tree in the second child
|
|
|
|
auto secondChild = LoadInnerNode(root->getChild(1)->key());
|
2015-05-08 02:10:40 +02:00
|
|
|
for(unsigned int i = 0; i < secondChild->numChildren(); ++i) {
|
2015-02-25 22:38:49 +01:00
|
|
|
EXPECT_TRAVERSE_ALL_CHILDREN_OF(*LoadInnerNode(secondChild->getChild(i)->key()), (nodeStore->layout().maxChildrenPerInnerNode() + i) * nodeStore->layout().maxChildrenPerInnerNode());
|
|
|
|
}
|
|
|
|
//Traverse some leaves of the non-full threelevel tree in the third child
|
|
|
|
auto thirdChild = LoadInnerNode(root->getChild(2)->key());
|
|
|
|
auto firstChildOfThirdChild = LoadInnerNode(thirdChild->getChild(0)->key());
|
2015-05-08 02:10:40 +02:00
|
|
|
for(unsigned int i = 0; i < firstChildOfThirdChild->numChildren()-1; ++i) {
|
2015-02-25 22:38:49 +01:00
|
|
|
EXPECT_TRAVERSE_LEAF(firstChildOfThirdChild->getChild(i)->key(), 2 * nodeStore->layout().maxChildrenPerInnerNode()*nodeStore->layout().maxChildrenPerInnerNode()+i);
|
|
|
|
}
|
|
|
|
|
|
|
|
TraverseLeaves(root.get(), nodeStore->layout().maxChildrenPerInnerNode()+5, 2*nodeStore->layout().maxChildrenPerInnerNode()*nodeStore->layout().maxChildrenPerInnerNode() + nodeStore->layout().maxChildrenPerInnerNode() -1);
|
|
|
|
}
|
|
|
|
|
2015-02-25 16:52:17 +01:00
|
|
|
//TODO Refactor the test cases that are too long
|