diff --git a/test/blobstore/CMakeLists.txt b/test/blobstore/CMakeLists.txt index 93ff3a70..d69290bd 100644 --- a/test/blobstore/CMakeLists.txt +++ b/test/blobstore/CMakeLists.txt @@ -14,6 +14,7 @@ set(SOURCES implementations/onblocks/datatreestore/testutils/DataTreeTest.cpp implementations/onblocks/datatreestore/impl/GetLowestRightBorderNodeWithMoreThanOneChildOrNullTest.cpp implementations/onblocks/datatreestore/impl/GetLowestInnerRightBorderNodeWithLessThanKChildrenOrNullTest.cpp + implementations/onblocks/datatreestore/DataTreeTest_Performance.cpp implementations/onblocks/datatreestore/DataTreeTest_ResizeByTraversing.cpp implementations/onblocks/datatreestore/DataTreeTest_NumStoredBytes.cpp implementations/onblocks/datatreestore/DataTreeTest_ResizeNumBytes.cpp diff --git a/test/blobstore/implementations/onblocks/datatreestore/DataTreeTest_Performance.cpp b/test/blobstore/implementations/onblocks/datatreestore/DataTreeTest_Performance.cpp new file mode 100644 index 00000000..23150d6d --- /dev/null +++ b/test/blobstore/implementations/onblocks/datatreestore/DataTreeTest_Performance.cpp @@ -0,0 +1,44 @@ +#include "testutils/DataTreeTest.h" + +#include + +using blobstore::onblocks::datanodestore::DataNodeStore; +using blobstore::onblocks::datanodestore::DataLeafNode; +using blobstore::onblocks::datanodestore::DataInnerNode; +using blobstore::onblocks::datanodestore::DataNode; +using blobstore::onblocks::datatreestore::DataTree; +using blockstore::Key; +using blockstore::testfake::FakeBlockStore; +using cpputils::Data; +using cpputils::make_unique_ref; + +class DataTreeTest_Performance: public DataTreeTest { +public: + +}; + +TEST_F(DataTreeTest_Performance, DeletingDoesntLoadLeaves_Twolevel_DeleteByTree) { + auto key = this->CreateFullTwoLevel()->key(); + auto tree = this->treeStore.load(key).value(); + this->treeStore.remove(std::move(tree)); + EXPECT_EQ(2u, blockStore->loadedBlocks.size()); +} + +TEST_F(DataTreeTest_Performance, DeletingDoesntLoadLeaves_Twolevel_DeleteByKey) { + auto key = this->CreateFullTwoLevel()->key(); + this->treeStore.remove(key); + EXPECT_EQ(1u, blockStore->loadedBlocks.size()); +} + +TEST_F(DataTreeTest_Performance, DeletingDoesntLoadLeaves_Threelevel_DeleteByTree) { + auto key = this->CreateFullThreeLevel()->key(); + auto tree = this->treeStore.load(key).value(); + this->treeStore.remove(std::move(tree)); + EXPECT_EQ(2u + nodeStore->layout().maxChildrenPerInnerNode(), blockStore->loadedBlocks.size()); +} + +TEST_F(DataTreeTest_Performance, DeletingDoesntLoadLeaves_Threelevel_DeleteByKey) { + auto key = this->CreateFullThreeLevel()->key(); + this->treeStore.remove(key); + EXPECT_EQ(1u + nodeStore->layout().maxChildrenPerInnerNode(), blockStore->loadedBlocks.size()); +} \ No newline at end of file diff --git a/test/blobstore/implementations/onblocks/datatreestore/testutils/DataTreeTest.cpp b/test/blobstore/implementations/onblocks/datatreestore/testutils/DataTreeTest.cpp index 1d749182..6b0123fd 100644 --- a/test/blobstore/implementations/onblocks/datatreestore/testutils/DataTreeTest.cpp +++ b/test/blobstore/implementations/onblocks/datatreestore/testutils/DataTreeTest.cpp @@ -21,7 +21,9 @@ using cpputils::dynamic_pointer_move; constexpr uint32_t DataTreeTest::BLOCKSIZE_BYTES; DataTreeTest::DataTreeTest() - :_nodeStore(make_unique_ref(make_unique_ref(), BLOCKSIZE_BYTES)), + :_blockStore(make_unique_ref()), + blockStore(_blockStore.get()), + _nodeStore(make_unique_ref(std::move(_blockStore), BLOCKSIZE_BYTES)), nodeStore(_nodeStore.get()), treeStore(std::move(_nodeStore)) { } diff --git a/test/blobstore/implementations/onblocks/datatreestore/testutils/DataTreeTest.h b/test/blobstore/implementations/onblocks/datatreestore/testutils/DataTreeTest.h index 0118c101..4533102c 100644 --- a/test/blobstore/implementations/onblocks/datatreestore/testutils/DataTreeTest.h +++ b/test/blobstore/implementations/onblocks/datatreestore/testutils/DataTreeTest.h @@ -3,12 +3,14 @@ #define MESSMER_BLOBSTORE_TEST_IMPLEMENTATIONS_ONBLOCKS_DATATREESTORE_DATATREETEST_H_ #include +#include #include "blobstore/implementations/onblocks/datanodestore/DataNodeStore.h" #include "blobstore/implementations/onblocks/datanodestore/DataInnerNode.h" #include "blobstore/implementations/onblocks/datanodestore/DataLeafNode.h" #include "blobstore/implementations/onblocks/datatreestore/DataTree.h" #include "blobstore/implementations/onblocks/datatreestore/DataTreeStore.h" +#include "MockBlockStore.h" class DataTreeTest: public ::testing::Test { public: @@ -44,6 +46,8 @@ public: cpputils::unique_ref CreateFullThreeLevelWithLastLeafSize(uint32_t size); cpputils::unique_ref CreateFourLevelMinDataWithLastLeafSize(uint32_t size); + cpputils::unique_ref _blockStore; + MockBlockStore *blockStore; cpputils::unique_ref _nodeStore; blobstore::onblocks::datanodestore::DataNodeStore *nodeStore; blobstore::onblocks::datatreestore::DataTreeStore treeStore; diff --git a/test/blobstore/implementations/onblocks/datatreestore/testutils/MockBlockStore.h b/test/blobstore/implementations/onblocks/datatreestore/testutils/MockBlockStore.h new file mode 100644 index 00000000..9e3a9f01 --- /dev/null +++ b/test/blobstore/implementations/onblocks/datatreestore/testutils/MockBlockStore.h @@ -0,0 +1,62 @@ +#pragma once +#ifndef MESSMER_BLOBSTORE_TEST_IMPLEMENTATIONS_ONBLOCKS_DATATREESTORE_GROWING_TESTUTILS_MOCKBLOCKSTORE_H_ +#define MESSMER_BLOBSTORE_TEST_IMPLEMENTATIONS_ONBLOCKS_DATATREESTORE_GROWING_TESTUTILS_MOCKBLOCKSTORE_H_ + +#include +#include +#include + +class MockBlockStore final : public blockstore::BlockStore { +public: + MockBlockStore(cpputils::unique_ref baseBlockStore = cpputils::make_unique_ref()) + : _baseBlockStore(std::move(baseBlockStore)) { + } + + blockstore::Key createKey() override { + return _baseBlockStore->createKey(); + } + + boost::optional> tryCreate(const blockstore::Key &key, cpputils::Data data) override { + return _baseBlockStore->tryCreate(key, std::move(data)); + } + + boost::optional> load(const blockstore::Key &key) override { + { + std::unique_lock lock(_mutex); + loadedBlocks.push_back(key); + } + return _baseBlockStore->load(key); + } + + void remove(const blockstore::Key &key) override { + return _baseBlockStore->remove(key); + } + + uint64_t numBlocks() const override { + return _baseBlockStore->numBlocks(); + } + + uint64_t estimateNumFreeBytes() const override { + return _baseBlockStore->estimateNumFreeBytes(); + } + + uint64_t blockSizeFromPhysicalBlockSize(uint64_t blockSize) const override { + return _baseBlockStore->blockSizeFromPhysicalBlockSize(blockSize); + } + + void forEachBlock(std::function callback) const override { + return _baseBlockStore->forEachBlock(callback); + } + + void remove(cpputils::unique_ref block) override { + return _baseBlockStore->remove(std::move(block)); + } + + std::vector loadedBlocks; + +private: + std::mutex _mutex; + cpputils::unique_ref _baseBlockStore; +}; + +#endif