From 7f55285ecdf6cbca3e728a4fb8eda91b91c47059 Mon Sep 17 00:00:00 2001 From: Sebastian Messmer Date: Tue, 24 Feb 2015 22:44:10 +0100 Subject: [PATCH] Implement removing trees and write some test cases for DataTreeStore --- .../onblocks/datanodestore/DataNodeStore.cpp | 11 +++++ .../onblocks/datanodestore/DataNodeStore.h | 4 +- .../onblocks/datatreestore/DataTree.cpp | 4 ++ .../onblocks/datatreestore/DataTree.h | 4 ++ .../onblocks/datatreestore/DataTreeStore.cpp | 13 +++++- .../onblocks/datatreestore/DataTreeStore.h | 2 + .../datanodestore/DataNodeStoreTest.cpp | 4 +- .../datatreestore/DataTreeStoreTest.cpp | 44 ++++++++++++++++++ .../DataTreeGrowingTest_DataStaysIntact.cpp | 28 +++++------ .../DataTreeGrowingTest_KeyDoesntChange.cpp | 6 +-- .../growing/testutils/DataTreeGrowingTest.cpp | 3 +- ...derNodeWithLessThanKChildrenOrNullTest.cpp | 12 ++--- ...rderNodeWithMoreThanOneChildOrNullTest.cpp | 16 +++---- .../shrinking/DataTreeShrinkingTest.cpp | 6 +-- .../DataTreeShrinkingTest_DataStaysIntact.cpp | 46 ++++++++++--------- .../DataTreeShrinkingTest_KeyDoesntChange.cpp | 6 +-- .../DataTreeShrinkingTest_Structure.cpp | 4 +- .../testutils/DataTreeShrinkingTest.cpp | 3 +- .../datatreestore/testutils/DataTreeTest.cpp | 18 +++++--- .../datatreestore/testutils/DataTreeTest.h | 6 ++- 20 files changed, 164 insertions(+), 76 deletions(-) create mode 100644 test/implementations/onblocks/datatreestore/DataTreeStoreTest.cpp diff --git a/implementations/onblocks/datanodestore/DataNodeStore.cpp b/implementations/onblocks/datanodestore/DataNodeStore.cpp index dbf034aa..9629f6b7 100644 --- a/implementations/onblocks/datanodestore/DataNodeStore.cpp +++ b/implementations/onblocks/datanodestore/DataNodeStore.cpp @@ -79,6 +79,17 @@ uint64_t DataNodeStore::numNodes() const { return _blockstore->numBlocks(); } +void DataNodeStore::removeSubtree(unique_ptr node) { + DataInnerNode *inner = dynamic_cast(node.get()); + if (inner != nullptr) { + for (int i = 0; i < inner->numChildren(); ++i) { + auto child = load(inner->getChild(i)->key()); + removeSubtree(std::move(child)); + } + } + remove(std::move(node)); + } + } } } diff --git a/implementations/onblocks/datanodestore/DataNodeStore.h b/implementations/onblocks/datanodestore/DataNodeStore.h index ea747de4..81ac7779 100644 --- a/implementations/onblocks/datanodestore/DataNodeStore.h +++ b/implementations/onblocks/datanodestore/DataNodeStore.h @@ -36,8 +36,10 @@ public: void remove(std::unique_ptr node); + void removeSubtree(std::unique_ptr node); + uint64_t numNodes() const; - //TODO Test overwriteNodeWith(), createNodeAsCopyFrom() + //TODO Test overwriteNodeWith(), createNodeAsCopyFrom(), removeSubtree() private: std::unique_ptr load(std::unique_ptr block); diff --git a/implementations/onblocks/datatreestore/DataTree.cpp b/implementations/onblocks/datatreestore/DataTree.cpp index 0d0a1ec6..fa3be7e2 100644 --- a/implementations/onblocks/datatreestore/DataTree.cpp +++ b/implementations/onblocks/datatreestore/DataTree.cpp @@ -116,6 +116,10 @@ void DataTree::flush() const { _rootNode->flush(); } +unique_ptr DataTree::releaseRootNode() { + return std::move(_rootNode); +} + } } diff --git a/implementations/onblocks/datatreestore/DataTree.h b/implementations/onblocks/datatreestore/DataTree.h index 1f1399d3..8d6f0516 100644 --- a/implementations/onblocks/datatreestore/DataTree.h +++ b/implementations/onblocks/datatreestore/DataTree.h @@ -30,10 +30,14 @@ public: const blockstore::Key &key() const; void flush() const; + private: datanodestore::DataNodeStore *_nodeStore; std::unique_ptr _rootNode; + std::unique_ptr releaseRootNode(); + friend class DataTreeStore; + std::unique_ptr addDataLeafAt(datanodestore::DataInnerNode *insertPos); cpputils::optional_ownership_ptr createChainOfInnerNodes(unsigned int num, datanodestore::DataLeafNode *leaf); std::unique_ptr addDataLeafToFullTree(); diff --git a/implementations/onblocks/datatreestore/DataTreeStore.cpp b/implementations/onblocks/datatreestore/DataTreeStore.cpp index 153644d3..6a561644 100644 --- a/implementations/onblocks/datatreestore/DataTreeStore.cpp +++ b/implementations/onblocks/datatreestore/DataTreeStore.cpp @@ -21,7 +21,12 @@ DataTreeStore::~DataTreeStore() { } unique_ptr DataTreeStore::load(const blockstore::Key &key) { - return make_unique(_nodeStore.get(), _nodeStore->load(key)); + auto node = _nodeStore->load(key); + if (node.get() == nullptr) { + return nullptr; + } else { + return make_unique(_nodeStore.get(), std::move(node)); + } } unique_ptr DataTreeStore::createNewTree() { @@ -29,6 +34,12 @@ unique_ptr DataTreeStore::createNewTree() { return make_unique(_nodeStore.get(), std::move(newleaf)); } +void DataTreeStore::remove(unique_ptr tree) { + auto root = tree->releaseRootNode(); + tree.reset(); + _nodeStore->removeSubtree(std::move(root)); +} + } } } diff --git a/implementations/onblocks/datatreestore/DataTreeStore.h b/implementations/onblocks/datatreestore/DataTreeStore.h index b88d695f..b40f23b2 100644 --- a/implementations/onblocks/datatreestore/DataTreeStore.h +++ b/implementations/onblocks/datatreestore/DataTreeStore.h @@ -25,6 +25,8 @@ public: std::unique_ptr createNewTree(); + void remove(std::unique_ptr tree); + private: std::unique_ptr _nodeStore; diff --git a/test/implementations/onblocks/datanodestore/DataNodeStoreTest.cpp b/test/implementations/onblocks/datanodestore/DataNodeStoreTest.cpp index 269c6483..285157be 100644 --- a/test/implementations/onblocks/datanodestore/DataNodeStoreTest.cpp +++ b/test/implementations/onblocks/datanodestore/DataNodeStoreTest.cpp @@ -96,9 +96,9 @@ TEST_F(DataNodeStoreTest, CreatedLeafNodeIsInitialized) { TEST_F(DataNodeStoreTest, NodeIsNotLoadableAfterDeleting) { auto nodekey = nodeStore->createNewLeafNode()->key(); auto node = nodeStore->load(nodekey); - EXPECT_NE(nullptr, node); + EXPECT_NE(nullptr, node.get()); nodeStore->remove(std::move(node)); - EXPECT_EQ(nullptr, nodeStore->load(nodekey)); + EXPECT_EQ(nullptr, nodeStore->load(nodekey).get()); } TEST_F(DataNodeStoreTest, NumNodesIsCorrectOnEmptyNodestore) { diff --git a/test/implementations/onblocks/datatreestore/DataTreeStoreTest.cpp b/test/implementations/onblocks/datatreestore/DataTreeStoreTest.cpp new file mode 100644 index 00000000..5410776b --- /dev/null +++ b/test/implementations/onblocks/datatreestore/DataTreeStoreTest.cpp @@ -0,0 +1,44 @@ +#include "testutils/DataTreeTest.h" + +#include "../../../../implementations/onblocks/datanodestore/DataNodeStore.h" +#include "../../../../implementations/onblocks/datatreestore/DataTreeStore.h" +#include + +using blockstore::testfake::FakeBlockStore; +using blockstore::Key; +using blobstore::onblocks::datanodestore::DataNodeStore; +using std::make_unique; + +using namespace blobstore::onblocks::datatreestore; + +class DataTreeStoreTest: public DataTreeTest { +}; + +TEST_F(DataTreeStoreTest, NewTreeIsLeafOnly) { + auto tree = treeStore.createNewTree(); + tree->flush(); + + EXPECT_IS_LEAF_NODE(tree->key()); +} + +TEST_F(DataTreeStoreTest, TreeIsNotLoadableAfterRemove) { + Key key = treeStore.createNewTree()->key(); + auto tree = treeStore.load(key); + EXPECT_NE(nullptr, tree.get()); + treeStore.remove(std::move(tree)); + EXPECT_EQ(nullptr, treeStore.load(key).get()); +} + +TEST_F(DataTreeStoreTest, RemovingTreeRemovesAllNodesOfTheTree) { + auto key = CreateFullThreeLevel()->key(); + auto tree1 = treeStore.load(key); + auto tree2_key = treeStore.createNewTree()->key(); + + treeStore.remove(std::move(tree1)); + + //Check that the only remaining node is tree2 + EXPECT_EQ(1, nodeStore->numNodes()); + EXPECT_NE(nullptr, treeStore.load(tree2_key).get()); +} + +//TODO ... diff --git a/test/implementations/onblocks/datatreestore/growing/DataTreeGrowingTest_DataStaysIntact.cpp b/test/implementations/onblocks/datatreestore/growing/DataTreeGrowingTest_DataStaysIntact.cpp index 98cde3db..f23e9437 100644 --- a/test/implementations/onblocks/datatreestore/growing/DataTreeGrowingTest_DataStaysIntact.cpp +++ b/test/implementations/onblocks/datatreestore/growing/DataTreeGrowingTest_DataStaysIntact.cpp @@ -18,7 +18,9 @@ class DataTreeGrowingTest_DataStaysIntact: public DataTreeGrowingTest { public: unique_ptr TreeWithData(unique_ptr root, TwoLevelDataFixture *data) { data->FillInto(root.get()); - return make_unique(&nodeStore, std::move(root)); + Key key = root->key(); + root.reset(); + return treeStore.load(key); } void TestDataStaysIntactOnGrowing(unique_ptr root, TwoLevelDataFixture *data) { @@ -27,7 +29,7 @@ public: tree->addDataLeaf(); tree->flush(); - data->EXPECT_DATA_CORRECT(nodeStore.load(tree->key()).get(), numLeaves); + data->EXPECT_DATA_CORRECT(nodeStore->load(tree->key()).get(), numLeaves); } uint32_t countLeaves(DataNode *node) { @@ -37,64 +39,64 @@ public: } uint32_t result = 0; for(int i = 0; i < inner->numChildren(); ++i) { - result += countLeaves(nodeStore.load(inner->getChild(i)->key()).get()); + result += countLeaves(nodeStore->load(inner->getChild(i)->key()).get()); } return result; } }; TEST_F(DataTreeGrowingTest_DataStaysIntact, GrowAFullTwoLevelTree_FullLeaves) { - TwoLevelDataFixture data(&nodeStore, 0, true); + TwoLevelDataFixture data(nodeStore, 0, true); TestDataStaysIntactOnGrowing(CreateFullTwoLevel(), &data); } TEST_F(DataTreeGrowingTest_DataStaysIntact, GrowAFullTwoLevelTree_NonFullLeaves) { - TwoLevelDataFixture data(&nodeStore, 0, false); + TwoLevelDataFixture data(nodeStore, 0, false); TestDataStaysIntactOnGrowing(CreateFullTwoLevel(), &data); } TEST_F(DataTreeGrowingTest_DataStaysIntact, GrowAThreeLevelTreeWithLowerLevelFull_FullLeaves) { - TwoLevelDataFixture data(&nodeStore, 0, true); + TwoLevelDataFixture data(nodeStore, 0, true); auto node = CreateInner({CreateFullTwoLevel()}); TestDataStaysIntactOnGrowing(std::move(node), &data); } TEST_F(DataTreeGrowingTest_DataStaysIntact, GrowAThreeLevelTreeWithLowerLevelFull_NonFullLeaves) { - TwoLevelDataFixture data(&nodeStore, 0, false); + TwoLevelDataFixture data(nodeStore, 0, false); auto node = CreateInner({CreateFullTwoLevel()}); TestDataStaysIntactOnGrowing(std::move(node), &data); } TEST_F(DataTreeGrowingTest_DataStaysIntact, GrowAOneNodeTree_FullLeaves) { - TwoLevelDataFixture data(&nodeStore, 0, true); + TwoLevelDataFixture data(nodeStore, 0, true); TestDataStaysIntactOnGrowing(CreateLeaf(), &data); } TEST_F(DataTreeGrowingTest_DataStaysIntact, GrowAOneNodeTree_NonFullLeaves) { - TwoLevelDataFixture data(&nodeStore, 0, false); + TwoLevelDataFixture data(nodeStore, 0, false); TestDataStaysIntactOnGrowing(CreateLeaf(), &data); } TEST_F(DataTreeGrowingTest_DataStaysIntact, GrowATwoNodeTree_FullLeaves) { - TwoLevelDataFixture data(&nodeStore, 0, true); + TwoLevelDataFixture data(nodeStore, 0, true); auto node = CreateInner({CreateLeaf()}); TestDataStaysIntactOnGrowing(std::move(node), &data); } TEST_F(DataTreeGrowingTest_DataStaysIntact, GrowATwoNodeTree_NonFullLeaves) { - TwoLevelDataFixture data(&nodeStore, 0, false); + TwoLevelDataFixture data(nodeStore, 0, false); auto node = CreateInner({CreateLeaf()}); TestDataStaysIntactOnGrowing(std::move(node), &data); } TEST_F(DataTreeGrowingTest_DataStaysIntact, GrowAThreeNodeChainedTree_FullLeaves) { - TwoLevelDataFixture data(&nodeStore, 0, true); + TwoLevelDataFixture data(nodeStore, 0, true); auto node = CreateInner({CreateInner({CreateLeaf()})}); TestDataStaysIntactOnGrowing(std::move(node), &data); } TEST_F(DataTreeGrowingTest_DataStaysIntact, GrowAThreeNodeChainedTree_NonFullLeaves) { - TwoLevelDataFixture data(&nodeStore, 0, false); + TwoLevelDataFixture data(nodeStore, 0, false); auto node = CreateInner({CreateInner({CreateLeaf()})}); TestDataStaysIntactOnGrowing(std::move(node), &data); } diff --git a/test/implementations/onblocks/datatreestore/growing/DataTreeGrowingTest_KeyDoesntChange.cpp b/test/implementations/onblocks/datatreestore/growing/DataTreeGrowingTest_KeyDoesntChange.cpp index 2e2b4c1f..30f27788 100644 --- a/test/implementations/onblocks/datatreestore/growing/DataTreeGrowingTest_KeyDoesntChange.cpp +++ b/test/implementations/onblocks/datatreestore/growing/DataTreeGrowingTest_KeyDoesntChange.cpp @@ -5,9 +5,9 @@ using blobstore::onblocks::datatreestore::DataTree; class DataTreeGrowingTest_KeyDoesntChange: public DataTreeGrowingTest { public: void EXPECT_KEY_DOESNT_CHANGE_WHEN_GROWING(const blockstore::Key &key) { - DataTree tree(&nodeStore, nodeStore.load(key)); - tree.addDataLeaf(); - EXPECT_EQ(key, tree.key()); + auto tree = treeStore.load(key); + tree->addDataLeaf(); + EXPECT_EQ(key, tree->key()); } }; diff --git a/test/implementations/onblocks/datatreestore/growing/testutils/DataTreeGrowingTest.cpp b/test/implementations/onblocks/datatreestore/growing/testutils/DataTreeGrowingTest.cpp index dec032a9..b5d11ac5 100644 --- a/test/implementations/onblocks/datatreestore/growing/testutils/DataTreeGrowingTest.cpp +++ b/test/implementations/onblocks/datatreestore/growing/testutils/DataTreeGrowingTest.cpp @@ -45,8 +45,7 @@ Key DataTreeGrowingTest::CreateThreeLevelTreeWithTwoFullSubtrees() { } void DataTreeGrowingTest::AddLeafTo(const Key &key) { - DataTree tree(&nodeStore, nodeStore.load(key)); - tree.addDataLeaf(); + treeStore.load(key)->addDataLeaf(); } void DataTreeGrowingTest::EXPECT_IS_THREENODE_CHAIN(const Key &key) { diff --git a/test/implementations/onblocks/datatreestore/impl/GetLowestInnerRightBorderNodeWithLessThanKChildrenOrNullTest.cpp b/test/implementations/onblocks/datatreestore/impl/GetLowestInnerRightBorderNodeWithLessThanKChildrenOrNullTest.cpp index d2342228..a2b2f8d9 100644 --- a/test/implementations/onblocks/datatreestore/impl/GetLowestInnerRightBorderNodeWithLessThanKChildrenOrNullTest.cpp +++ b/test/implementations/onblocks/datatreestore/impl/GetLowestInnerRightBorderNodeWithLessThanKChildrenOrNullTest.cpp @@ -29,8 +29,8 @@ public: }; void check(const TestData &testData) { - auto root = nodeStore.load(testData.rootNode); - auto result = GetLowestInnerRightBorderNodeWithLessThanKChildrenOrNull(&nodeStore, root.get()); + auto root = nodeStore->load(testData.rootNode); + auto result = GetLowestInnerRightBorderNodeWithLessThanKChildrenOrNull(nodeStore, root.get()); EXPECT_EQ(testData.expectedResult, result->key()); } @@ -58,8 +58,8 @@ public: }; TEST_F(GetLowestInnerRightBorderNodeWithLessThanKChildrenOrNullTest, Leaf) { - auto leaf = nodeStore.createNewLeafNode(); - auto result = GetLowestInnerRightBorderNodeWithLessThanKChildrenOrNull(&nodeStore, leaf.get()); + auto leaf = nodeStore->createNewLeafNode(); + auto result = GetLowestInnerRightBorderNodeWithLessThanKChildrenOrNull(nodeStore, leaf.get()); EXPECT_EQ(nullptr, result.get()); } @@ -85,12 +85,12 @@ TEST_F(GetLowestInnerRightBorderNodeWithLessThanKChildrenOrNullTest, LargerTree) TEST_F(GetLowestInnerRightBorderNodeWithLessThanKChildrenOrNullTest, FullTwoLevelTree) { auto root = CreateFullTwoLevel(); - auto result = GetLowestInnerRightBorderNodeWithLessThanKChildrenOrNull(&nodeStore, root.get()); + auto result = GetLowestInnerRightBorderNodeWithLessThanKChildrenOrNull(nodeStore, root.get()); EXPECT_EQ(nullptr, result.get()); } TEST_F(GetLowestInnerRightBorderNodeWithLessThanKChildrenOrNullTest, FullThreeLevelTree) { auto root = CreateFullThreeLevel(); - auto result = GetLowestInnerRightBorderNodeWithLessThanKChildrenOrNull(&nodeStore, root.get()); + auto result = GetLowestInnerRightBorderNodeWithLessThanKChildrenOrNull(nodeStore, root.get()); EXPECT_EQ(nullptr, result.get()); } diff --git a/test/implementations/onblocks/datatreestore/impl/GetLowestRightBorderNodeWithMoreThanOneChildOrNullTest.cpp b/test/implementations/onblocks/datatreestore/impl/GetLowestRightBorderNodeWithMoreThanOneChildOrNullTest.cpp index 9a3001f3..4371630f 100644 --- a/test/implementations/onblocks/datatreestore/impl/GetLowestRightBorderNodeWithMoreThanOneChildOrNullTest.cpp +++ b/test/implementations/onblocks/datatreestore/impl/GetLowestRightBorderNodeWithMoreThanOneChildOrNullTest.cpp @@ -29,8 +29,8 @@ public: }; void check(const TestData &testData) { - auto root = nodeStore.load(testData.rootNode); - auto result = GetLowestRightBorderNodeWithMoreThanOneChildOrNull(&nodeStore, root.get()); + auto root = nodeStore->load(testData.rootNode); + auto result = GetLowestRightBorderNodeWithMoreThanOneChildOrNull(nodeStore, root.get()); EXPECT_EQ(testData.expectedResult, result->key()); } @@ -81,20 +81,20 @@ public: }; TEST_F(GetLowestRightBorderNodeWithMoreThanOneChildOrNullTest, Leaf) { - auto leaf = nodeStore.load(CreateLeafOnlyTree()); - auto result = GetLowestRightBorderNodeWithMoreThanOneChildOrNull(&nodeStore, leaf.get()); + auto leaf = nodeStore->load(CreateLeafOnlyTree()); + auto result = GetLowestRightBorderNodeWithMoreThanOneChildOrNull(nodeStore, leaf.get()); EXPECT_EQ(nullptr, result.get()); } TEST_F(GetLowestRightBorderNodeWithMoreThanOneChildOrNullTest, TwoRightBorderNodes) { - auto node = nodeStore.load(CreateTwoRightBorderNodes()); - auto result = GetLowestRightBorderNodeWithMoreThanOneChildOrNull(&nodeStore, node.get()); + auto node = nodeStore->load(CreateTwoRightBorderNodes()); + auto result = GetLowestRightBorderNodeWithMoreThanOneChildOrNull(nodeStore, node.get()); EXPECT_EQ(nullptr, result.get()); } TEST_F(GetLowestRightBorderNodeWithMoreThanOneChildOrNullTest, ThreeRightBorderNodes) { - auto node = nodeStore.load(CreateThreeRightBorderNodes()); - auto result = GetLowestRightBorderNodeWithMoreThanOneChildOrNull(&nodeStore, node.get()); + auto node = nodeStore->load(CreateThreeRightBorderNodes()); + auto result = GetLowestRightBorderNodeWithMoreThanOneChildOrNull(nodeStore, node.get()); EXPECT_EQ(nullptr, result.get()); } diff --git a/test/implementations/onblocks/datatreestore/shrinking/DataTreeShrinkingTest.cpp b/test/implementations/onblocks/datatreestore/shrinking/DataTreeShrinkingTest.cpp index 13ab346f..a78b087f 100644 --- a/test/implementations/onblocks/datatreestore/shrinking/DataTreeShrinkingTest.cpp +++ b/test/implementations/onblocks/datatreestore/shrinking/DataTreeShrinkingTest.cpp @@ -17,7 +17,7 @@ using blockstore::Key; TEST_F(DataTreeShrinkingTest, ShrinkingALeafOnlyTreeCrashes) { Key key = CreateLeafOnlyTree()->key(); - auto tree = make_unique(&nodeStore, nodeStore.load(key)); + auto tree = treeStore.load(key); EXPECT_DEATH(tree->removeLastDataLeaf(), ""); } @@ -36,7 +36,7 @@ TEST_F(DataTreeShrinkingTest, ShrinkATwoLeafTree_LastLeafBlockIsDeleted) { auto lastChildKey = LoadInnerNode(tree->key())->getChild(1)->key(); tree->removeLastDataLeaf(); - EXPECT_EQ(nullptr, nodeStore.load(lastChildKey)); + EXPECT_EQ(nullptr, nodeStore->load(lastChildKey)); } TEST_F(DataTreeShrinkingTest, ShrinkATwoLeafTree_IntermediateBlocksAreDeleted) { @@ -45,5 +45,5 @@ TEST_F(DataTreeShrinkingTest, ShrinkATwoLeafTree_IntermediateBlocksAreDeleted) { auto firstChildKey = LoadInnerNode(tree->key())->getChild(0)->key(); tree->removeLastDataLeaf(); - EXPECT_EQ(nullptr, nodeStore.load(firstChildKey)); + EXPECT_EQ(nullptr, nodeStore->load(firstChildKey)); } diff --git a/test/implementations/onblocks/datatreestore/shrinking/DataTreeShrinkingTest_DataStaysIntact.cpp b/test/implementations/onblocks/datatreestore/shrinking/DataTreeShrinkingTest_DataStaysIntact.cpp index cf65110f..c6d409c1 100644 --- a/test/implementations/onblocks/datatreestore/shrinking/DataTreeShrinkingTest_DataStaysIntact.cpp +++ b/test/implementations/onblocks/datatreestore/shrinking/DataTreeShrinkingTest_DataStaysIntact.cpp @@ -14,7 +14,9 @@ class DataTreeShrinkingTest_DataStaysIntact: public DataTreeShrinkingTest { public: unique_ptr TreeWithData(unique_ptr root, TwoLevelDataFixture *data) { data->FillInto(root.get()); - return make_unique(&nodeStore, std::move(root)); + Key key = root->key(); + root.reset(); + return treeStore.load(key); } void TestDataStaysIntactOnShrinking(unique_ptr root, TwoLevelDataFixture *data) { @@ -22,106 +24,106 @@ public: tree->removeLastDataLeaf(); tree->flush(); - data->EXPECT_DATA_CORRECT(nodeStore.load(tree->key()).get()); + data->EXPECT_DATA_CORRECT(nodeStore->load(tree->key()).get()); } }; TEST_F(DataTreeShrinkingTest_DataStaysIntact, ShrinkATwoLeafTree_FullLeaves) { - TwoLevelDataFixture data(&nodeStore, 0, true); + TwoLevelDataFixture data(nodeStore, 0, true); TestDataStaysIntactOnShrinking(CreateTwoLeaf(), &data); } TEST_F(DataTreeShrinkingTest_DataStaysIntact, ShrinkATwoLeafTree_NonFullLeaves) { - TwoLevelDataFixture data(&nodeStore, 0, false); + TwoLevelDataFixture data(nodeStore, 0, false); TestDataStaysIntactOnShrinking(CreateTwoLeaf(), &data); } TEST_F(DataTreeShrinkingTest_DataStaysIntact, ShrinkAFourNodeThreeLeafTree_FullLeaves) { - TwoLevelDataFixture data(&nodeStore, 0, true); + TwoLevelDataFixture data(nodeStore, 0, true); TestDataStaysIntactOnShrinking(CreateFourNodeThreeLeaf(), &data); } TEST_F(DataTreeShrinkingTest_DataStaysIntact, ShrinkAFourNodeThreeLeafTree_NonFullLeaves) { - TwoLevelDataFixture data(&nodeStore, 0, false); + TwoLevelDataFixture data(nodeStore, 0, false); TestDataStaysIntactOnShrinking(CreateFourNodeThreeLeaf(), &data); } TEST_F(DataTreeShrinkingTest_DataStaysIntact, ShrinkATwoInnerNodeOneTwoLeavesTree_FullLeaves) { - TwoLevelDataFixture data(&nodeStore, 0, true); + TwoLevelDataFixture data(nodeStore, 0, true); TestDataStaysIntactOnShrinking(CreateTwoInnerNodeOneTwoLeaves(), &data); } TEST_F(DataTreeShrinkingTest_DataStaysIntact, ShrinkATwoInnerNodeOneTwoLeavesTree_NonFullLeaves) { - TwoLevelDataFixture data(&nodeStore, 0, false); + TwoLevelDataFixture data(nodeStore, 0, false); TestDataStaysIntactOnShrinking(CreateTwoInnerNodeOneTwoLeaves(), &data); } TEST_F(DataTreeShrinkingTest_DataStaysIntact, ShrinkATwoInnerNodeTwoOneLeavesTree_FullLeaves) { - TwoLevelDataFixture data(&nodeStore, 0, true); + TwoLevelDataFixture data(nodeStore, 0, true); TestDataStaysIntactOnShrinking(CreateTwoInnerNodeTwoOneLeaves(), &data); } TEST_F(DataTreeShrinkingTest_DataStaysIntact, ShrinkATwoInnerNodeTwoOneLeavesTree_NonFullLeaves) { - TwoLevelDataFixture data(&nodeStore, 0, false); + TwoLevelDataFixture data(nodeStore, 0, false); TestDataStaysIntactOnShrinking(CreateTwoInnerNodeTwoOneLeaves(), &data); } TEST_F(DataTreeShrinkingTest_DataStaysIntact, ShrinkAThreeLevelMinDataTree_FullLeaves) { - TwoLevelDataFixture data(&nodeStore, 0, true); + TwoLevelDataFixture data(nodeStore, 0, true); TestDataStaysIntactOnShrinking(CreateThreeLevelMinData(), &data); } TEST_F(DataTreeShrinkingTest_DataStaysIntact, ShrinkAThreeLevelMinDataTree_NonFullLeaves) { - TwoLevelDataFixture data(&nodeStore, 0, false); + TwoLevelDataFixture data(nodeStore, 0, false); TestDataStaysIntactOnShrinking(CreateThreeLevelMinData(), &data); } TEST_F(DataTreeShrinkingTest_DataStaysIntact, ShrinkAFourLevelMinDataTree_FullLeaves) { - TwoLevelDataFixture data(&nodeStore, 0, true); + TwoLevelDataFixture data(nodeStore, 0, true); TestDataStaysIntactOnShrinking(CreateFourLevelMinData(), &data); } TEST_F(DataTreeShrinkingTest_DataStaysIntact, ShrinkAFourLevelMinDataTree_NonFullLeaves) { - TwoLevelDataFixture data(&nodeStore, 0, false); + TwoLevelDataFixture data(nodeStore, 0, false); TestDataStaysIntactOnShrinking(CreateFourLevelMinData(), &data); } TEST_F(DataTreeShrinkingTest_DataStaysIntact, ShrinkAFourLevelTreeWithTwoSiblingLeaves1_FullLeaves) { - TwoLevelDataFixture data(&nodeStore, 0, true); + TwoLevelDataFixture data(nodeStore, 0, true); TestDataStaysIntactOnShrinking(CreateFourLevelWithTwoSiblingLeaves1(), &data); } TEST_F(DataTreeShrinkingTest_DataStaysIntact, ShrinkAFourLevelTreeWithTwoSiblingLeaves1_NonFullLeaves) { - TwoLevelDataFixture data(&nodeStore, 0, false); + TwoLevelDataFixture data(nodeStore, 0, false); TestDataStaysIntactOnShrinking(CreateFourLevelWithTwoSiblingLeaves1(), &data); } TEST_F(DataTreeShrinkingTest_DataStaysIntact, ShrinkAFourLevelTreeWithTwoSiblingLeaves2_FullLeaves) { - TwoLevelDataFixture data(&nodeStore, 0, true); + TwoLevelDataFixture data(nodeStore, 0, true); TestDataStaysIntactOnShrinking(CreateFourLevelWithTwoSiblingLeaves2(), &data); } TEST_F(DataTreeShrinkingTest_DataStaysIntact, ShrinkAFourLevelTreeWithTwoSiblingLeaves2_NonFullLeaves) { - TwoLevelDataFixture data(&nodeStore, 0, false); + TwoLevelDataFixture data(nodeStore, 0, false); TestDataStaysIntactOnShrinking(CreateFourLevelWithTwoSiblingLeaves2(), &data); } TEST_F(DataTreeShrinkingTest_DataStaysIntact, ShrinkATreeWithFirstChildOfRootFullThreelevelAndSecondChildMindataThreelevel_FullLeaves) { - TwoLevelDataFixture data(&nodeStore, 0, true); + TwoLevelDataFixture data(nodeStore, 0, true); TestDataStaysIntactOnShrinking(CreateWithFirstChildOfRootFullThreelevelAndSecondChildMindataThreelevel(), &data); } TEST_F(DataTreeShrinkingTest_DataStaysIntact, ShrinkATreeWithFirstChildOfRootFullThreelevelAndSecondChildMindataThreelevel_NonFullLeaves) { - TwoLevelDataFixture data(&nodeStore, 0, false); + TwoLevelDataFixture data(nodeStore, 0, false); TestDataStaysIntactOnShrinking(CreateWithFirstChildOfRootFullThreelevelAndSecondChildMindataThreelevel(), &data); } TEST_F(DataTreeShrinkingTest_DataStaysIntact, ShrinkAThreeLevelTreeWithThreeChildrenOfRoot_FullLeaves) { - TwoLevelDataFixture data(&nodeStore, 0, true); + TwoLevelDataFixture data(nodeStore, 0, true); TestDataStaysIntactOnShrinking(CreateThreeLevelWithThreeChildrenOfRoot(), &data); } TEST_F(DataTreeShrinkingTest_DataStaysIntact, ShrinkAThreeLevelTreeWithThreeChildrenOfRoot_NonFullLeaves) { - TwoLevelDataFixture data(&nodeStore, 0, false); + TwoLevelDataFixture data(nodeStore, 0, false); TestDataStaysIntactOnShrinking(CreateThreeLevelWithThreeChildrenOfRoot(), &data); } diff --git a/test/implementations/onblocks/datatreestore/shrinking/DataTreeShrinkingTest_KeyDoesntChange.cpp b/test/implementations/onblocks/datatreestore/shrinking/DataTreeShrinkingTest_KeyDoesntChange.cpp index ec71e4b8..58e0b202 100644 --- a/test/implementations/onblocks/datatreestore/shrinking/DataTreeShrinkingTest_KeyDoesntChange.cpp +++ b/test/implementations/onblocks/datatreestore/shrinking/DataTreeShrinkingTest_KeyDoesntChange.cpp @@ -6,9 +6,9 @@ using blockstore::Key; class DataTreeShrinkingTest_KeyDoesntChange: public DataTreeShrinkingTest { public: void EXPECT_KEY_DOESNT_CHANGE_WHEN_SHRINKING(const Key &key) { - DataTree tree(&nodeStore, nodeStore.load(key)); - tree.removeLastDataLeaf(); - EXPECT_EQ(key, tree.key()); + auto tree = treeStore.load(key); + tree->removeLastDataLeaf(); + EXPECT_EQ(key, tree->key()); } }; diff --git a/test/implementations/onblocks/datatreestore/shrinking/DataTreeShrinkingTest_Structure.cpp b/test/implementations/onblocks/datatreestore/shrinking/DataTreeShrinkingTest_Structure.cpp index 87055948..61861c01 100644 --- a/test/implementations/onblocks/datatreestore/shrinking/DataTreeShrinkingTest_Structure.cpp +++ b/test/implementations/onblocks/datatreestore/shrinking/DataTreeShrinkingTest_Structure.cpp @@ -135,7 +135,7 @@ TEST_F(DataTreeShrinkingTest_Structure, ShrinkAFullTwoLevelTreeDownToOneLeaf) { Shrink(key); } EXPECT_IS_LEAF_NODE(key); - EXPECT_EQ(1, nodeStore.numNodes()); + EXPECT_EQ(1, nodeStore->numNodes()); } TEST_F(DataTreeShrinkingTest_Structure, ShrinkAFullThreeLevelTreeDownToOneLeaf) { @@ -144,5 +144,5 @@ TEST_F(DataTreeShrinkingTest_Structure, ShrinkAFullThreeLevelTreeDownToOneLeaf) Shrink(key); } EXPECT_IS_LEAF_NODE(key); - EXPECT_EQ(1, nodeStore.numNodes()); + EXPECT_EQ(1, nodeStore->numNodes()); } diff --git a/test/implementations/onblocks/datatreestore/shrinking/testutils/DataTreeShrinkingTest.cpp b/test/implementations/onblocks/datatreestore/shrinking/testutils/DataTreeShrinkingTest.cpp index 0ac30e53..9efe02ed 100644 --- a/test/implementations/onblocks/datatreestore/shrinking/testutils/DataTreeShrinkingTest.cpp +++ b/test/implementations/onblocks/datatreestore/shrinking/testutils/DataTreeShrinkingTest.cpp @@ -9,8 +9,7 @@ using blockstore::Key; using blobstore::onblocks::datatreestore::DataTree; void DataTreeShrinkingTest::Shrink(const Key &key) { - DataTree tree(&nodeStore, nodeStore.load(key)); - tree.removeLastDataLeaf(); + treeStore.load(key)->removeLastDataLeaf(); } unique_ptr DataTreeShrinkingTest::CreateFourNodeThreeLeaf() { diff --git a/test/implementations/onblocks/datatreestore/testutils/DataTreeTest.cpp b/test/implementations/onblocks/datatreestore/testutils/DataTreeTest.cpp index d29f5d15..60ca2c1f 100644 --- a/test/implementations/onblocks/datatreestore/testutils/DataTreeTest.cpp +++ b/test/implementations/onblocks/datatreestore/testutils/DataTreeTest.cpp @@ -17,11 +17,13 @@ using std::vector; using cpputils::dynamic_pointer_move; DataTreeTest::DataTreeTest() - :nodeStore(make_unique()) { + :_nodeStore(make_unique(make_unique())), + nodeStore(_nodeStore.get()), + treeStore(std::move(_nodeStore)) { } unique_ptr DataTreeTest::CreateLeaf() { - return nodeStore.createNewLeafNode(); + return nodeStore->createNewLeafNode(); } unique_ptr DataTreeTest::CreateInner(initializer_list> children) { @@ -36,7 +38,7 @@ unique_ptr DataTreeTest::CreateInner(initializer_list DataTreeTest::CreateInner(vector children) { assert(children.size() >= 1); - auto node = nodeStore.createNewInnerNode(**children.begin()); + auto node = nodeStore->createNewInnerNode(**children.begin()); for(auto child = children.begin()+1; child != children.end(); ++child) { node->addChild(**child); } @@ -44,7 +46,8 @@ unique_ptr DataTreeTest::CreateInner(vector chil } unique_ptr DataTreeTest::CreateLeafOnlyTree() { - return make_unique(&nodeStore, CreateLeaf()); + auto key = CreateLeaf()->key(); + return treeStore.load(key); } void DataTreeTest::FillNode(DataInnerNode *node) { @@ -72,14 +75,14 @@ unique_ptr DataTreeTest::CreateFullThreeLevel() { } unique_ptr DataTreeTest::LoadInnerNode(const Key &key) { - auto node = nodeStore.load(key); + auto node = nodeStore->load(key); auto casted = dynamic_pointer_move(node); EXPECT_NE(nullptr, casted.get()) << "Is not an inner node"; return casted; } unique_ptr DataTreeTest::LoadLeafNode(const Key &key) { - auto node = nodeStore.load(key); + auto node = nodeStore->load(key); auto casted = dynamic_pointer_move(node); EXPECT_NE(nullptr, casted.get()) << "Is not a leaf node"; return casted; @@ -90,7 +93,8 @@ unique_ptr DataTreeTest::CreateTwoLeaf() { } unique_ptr DataTreeTest::CreateTwoLeafTree() { - return make_unique(&nodeStore, CreateTwoLeaf()); + auto key = CreateTwoLeaf()->key(); + return treeStore.load(key); } void DataTreeTest::EXPECT_IS_LEAF_NODE(const Key &key) { diff --git a/test/implementations/onblocks/datatreestore/testutils/DataTreeTest.h b/test/implementations/onblocks/datatreestore/testutils/DataTreeTest.h index a5f88a87..1284d7f7 100644 --- a/test/implementations/onblocks/datatreestore/testutils/DataTreeTest.h +++ b/test/implementations/onblocks/datatreestore/testutils/DataTreeTest.h @@ -8,6 +8,7 @@ #include "../../../../../implementations/onblocks/datanodestore/DataInnerNode.h" #include "../../../../../implementations/onblocks/datanodestore/DataLeafNode.h" #include "../../../../../implementations/onblocks/datatreestore/DataTree.h" +#include "../../../../../implementations/onblocks/datatreestore/DataTreeStore.h" class DataTreeTest: public ::testing::Test { public: @@ -25,11 +26,14 @@ public: void FillNodeTwoLevel(blobstore::onblocks::datanodestore::DataInnerNode *node); std::unique_ptr CreateFullTwoLevel(); std::unique_ptr CreateFullThreeLevel(); - blobstore::onblocks::datanodestore::DataNodeStore nodeStore; std::unique_ptr LoadInnerNode(const blockstore::Key &key); std::unique_ptr LoadLeafNode(const blockstore::Key &key); + std::unique_ptr _nodeStore; + blobstore::onblocks::datanodestore::DataNodeStore *nodeStore; + blobstore::onblocks::datatreestore::DataTreeStore treeStore; + void EXPECT_IS_LEAF_NODE(const blockstore::Key &key); void EXPECT_IS_INNER_NODE(const blockstore::Key &key); void EXPECT_IS_TWONODE_CHAIN(const blockstore::Key &key);