Added some test cases for shrinking trees

This commit is contained in:
Sebastian Messmer 2015-02-23 16:21:02 +01:00
parent ab2e789dac
commit 05b4ccae05
8 changed files with 45 additions and 14 deletions

View File

@ -47,7 +47,11 @@ unique_ptr<DataLeafNode> DataNodeStore::createNewLeafNode() {
} }
unique_ptr<DataNode> DataNodeStore::load(const Key &key) { unique_ptr<DataNode> DataNodeStore::load(const Key &key) {
return load(_blockstore->load(key)); auto block = _blockstore->load(key);
if (block == nullptr) {
return nullptr;
}
return load(std::move(block));
} }
unique_ptr<DataNode> DataNodeStore::createNewNodeAsCopyFrom(const DataNode &source) { unique_ptr<DataNode> DataNodeStore::createNewNodeAsCopyFrom(const DataNode &source) {

View File

@ -21,4 +21,31 @@ TEST_F(DataTreeShrinkingTest, ShrinkingALeafOnlyTreeCrashes) {
EXPECT_DEATH(tree->removeLastDataLeaf(), ""); EXPECT_DEATH(tree->removeLastDataLeaf(), "");
} }
//TODO Test that blocks are actually deleted TEST_F(DataTreeShrinkingTest, ShrinkATwoLeafTree_FlushingWorks) {
//Tests that after calling flush(), the complete grown tree structure is written to the blockstore
auto tree = CreateTwoLeafTree();
tree->removeLastDataLeaf();
tree->flush();
EXPECT_IS_LEAF_NODE(tree->key());
}
TEST_F(DataTreeShrinkingTest, ShrinkATwoLeafTree_LastLeafBlockIsDeleted) {
auto tree = CreateTwoLeafTree();
tree->flush();
auto lastChildKey = LoadInnerNode(tree->key())->getChild(1)->key();
tree->removeLastDataLeaf();
EXPECT_EQ(nullptr, nodeStore.load(lastChildKey));
}
TEST_F(DataTreeShrinkingTest, ShrinkATwoLeafTree_IntermediateBlocksAreDeleted) {
auto tree = CreateTwoLeafTree();
tree->flush();
auto firstChildKey = LoadInnerNode(tree->key())->getChild(0)->key();
tree->removeLastDataLeaf();
EXPECT_EQ(nullptr, nodeStore.load(firstChildKey));
}
//TODO Test Shrinking full trees down to 1-leaf-tree

View File

@ -13,7 +13,7 @@ public:
}; };
TEST_F(DataTreeShrinkingTest_KeyDoesntChange, ShrinkATwoLeafTree) { TEST_F(DataTreeShrinkingTest_KeyDoesntChange, ShrinkATwoLeafTree) {
auto key = CreateTwoLeafTree(); auto key = CreateTwoLeafTree()->key();
EXPECT_KEY_DOESNT_CHANGE_WHEN_SHRINKING(key); EXPECT_KEY_DOESNT_CHANGE_WHEN_SHRINKING(key);
} }

View File

@ -69,7 +69,7 @@ public:
}; };
TEST_F(DataTreeShrinkingTest_Structure, ShrinkATwoLeafTree) { TEST_F(DataTreeShrinkingTest_Structure, ShrinkATwoLeafTree) {
auto key = CreateTwoLeafTree(); auto key = CreateTwoLeafTree()->key();
Shrink(key); Shrink(key);
EXPECT_IS_LEAF_ONLY_TREE(key); EXPECT_IS_LEAF_ONLY_TREE(key);
} }
@ -86,11 +86,11 @@ TEST_F(DataTreeShrinkingTest_Structure, ShrinkATwoInnerNodeOneTwoLeavesTree) {
EXPECT_IS_TWO_INNER_NODE_TREE_WITH_ONE_LEAF_EACH(key); EXPECT_IS_TWO_INNER_NODE_TREE_WITH_ONE_LEAF_EACH(key);
} }
/*TEST_F(DataTreeShrinkingTest_Structure, ShrinkATwoInnerNodeTwoOneLeavesTree) { TEST_F(DataTreeShrinkingTest_Structure, ShrinkATwoInnerNodeTwoOneLeavesTree) {
auto key = CreateTwoInnerNodeTwoOneLeavesTree(); auto key = CreateTwoInnerNodeTwoOneLeavesTree();
Shrink(key); Shrink(key);
EXPECT_IS_TWO_LEAF_TREE(key); EXPECT_IS_TWO_LEAF_TREE(key);
}*/ }
TEST_F(DataTreeShrinkingTest_Structure, ShrinkAThreeLevelMinDataTree) { TEST_F(DataTreeShrinkingTest_Structure, ShrinkAThreeLevelMinDataTree) {
auto key = CreateThreeLevelMinDataTree(); auto key = CreateThreeLevelMinDataTree();

View File

@ -13,13 +13,6 @@ void DataTreeShrinkingTest::Shrink(const Key &key) {
tree.removeLastDataLeaf(); tree.removeLastDataLeaf();
} }
Key DataTreeShrinkingTest::CreateTwoLeafTree() {
auto leaf1 = nodeStore.createNewLeafNode();
auto root = nodeStore.createNewInnerNode(*leaf1);
root->addChild(*nodeStore.createNewLeafNode());
return root->key();
}
Key DataTreeShrinkingTest::CreateFourNodeThreeLeafTree() { Key DataTreeShrinkingTest::CreateFourNodeThreeLeafTree() {
auto leaf1 = nodeStore.createNewLeafNode(); auto leaf1 = nodeStore.createNewLeafNode();
auto root = nodeStore.createNewInnerNode(*leaf1); auto root = nodeStore.createNewInnerNode(*leaf1);

View File

@ -13,7 +13,6 @@ class DataTreeShrinkingTest: public DataTreeTest {
public: public:
void Shrink(const blockstore::Key &key); void Shrink(const blockstore::Key &key);
blockstore::Key CreateTwoLeafTree();
blockstore::Key CreateFourNodeThreeLeafTree(); blockstore::Key CreateFourNodeThreeLeafTree();
blockstore::Key CreateTwoInnerNodeOneTwoLeavesTree(); blockstore::Key CreateTwoInnerNodeOneTwoLeavesTree();
blockstore::Key CreateTwoInnerNodeTwoOneLeavesTree(); blockstore::Key CreateTwoInnerNodeTwoOneLeavesTree();

View File

@ -68,6 +68,13 @@ unique_ptr<DataLeafNode> DataTreeTest::LoadLeafNode(const Key &key) {
return casted; return casted;
} }
unique_ptr<DataTree> DataTreeTest::CreateTwoLeafTree() {
auto leaf1 = nodeStore.createNewLeafNode();
auto root = nodeStore.createNewInnerNode(*leaf1);
root->addChild(*nodeStore.createNewLeafNode());
return make_unique<DataTree>(&nodeStore, std::move(root));
}
void DataTreeTest::EXPECT_IS_LEAF_NODE(const Key &key) { void DataTreeTest::EXPECT_IS_LEAF_NODE(const Key &key) {
auto node = LoadLeafNode(key); auto node = LoadLeafNode(key);
EXPECT_NE(nullptr, node.get()); EXPECT_NE(nullptr, node.get());

View File

@ -14,6 +14,7 @@ public:
DataTreeTest(); DataTreeTest();
std::unique_ptr<blobstore::onblocks::datatreestore::DataTree> CreateLeafOnlyTree(); std::unique_ptr<blobstore::onblocks::datatreestore::DataTree> CreateLeafOnlyTree();
std::unique_ptr<blobstore::onblocks::datatreestore::DataTree> CreateTwoLeafTree();
void FillNode(blobstore::onblocks::datanodestore::DataInnerNode *node); void FillNode(blobstore::onblocks::datanodestore::DataInnerNode *node);
void FillNodeTwoLevel(blobstore::onblocks::datanodestore::DataInnerNode *node); void FillNodeTwoLevel(blobstore::onblocks::datanodestore::DataInnerNode *node);
blockstore::Key CreateFullTwoLevelTree(); blockstore::Key CreateFullTwoLevelTree();