Improve code decreasing tree depth
This commit is contained in:
parent
b1b90b8c3d
commit
582917c1f5
@ -10,6 +10,7 @@ using std::vector;
|
|||||||
using boost::none;
|
using boost::none;
|
||||||
using cpputils::Data;
|
using cpputils::Data;
|
||||||
using cpputils::unique_ref;
|
using cpputils::unique_ref;
|
||||||
|
using cpputils::dynamic_pointer_move;
|
||||||
using blobstore::onblocks::datanodestore::DataNodeStore;
|
using blobstore::onblocks::datanodestore::DataNodeStore;
|
||||||
using blobstore::onblocks::datanodestore::DataNode;
|
using blobstore::onblocks::datanodestore::DataNode;
|
||||||
using blobstore::onblocks::datanodestore::DataInnerNode;
|
using blobstore::onblocks::datanodestore::DataInnerNode;
|
||||||
@ -196,16 +197,30 @@ namespace blobstore {
|
|||||||
unique_ref<DataNode> LeafTraverser::_whileRootHasOnlyOneChildReplaceRootWithItsChild(unique_ref<DataNode> root) {
|
unique_ref<DataNode> LeafTraverser::_whileRootHasOnlyOneChildReplaceRootWithItsChild(unique_ref<DataNode> root) {
|
||||||
DataInnerNode *inner = dynamic_cast<DataInnerNode*>(root.get());
|
DataInnerNode *inner = dynamic_cast<DataInnerNode*>(root.get());
|
||||||
if (inner != nullptr && inner->numChildren() == 1) {
|
if (inner != nullptr && inner->numChildren() == 1) {
|
||||||
auto child = _nodeStore->load(inner->getChild(0)->key());
|
auto newRoot = _whileRootHasOnlyOneChildRemoveRootReturnChild(inner->getChild(0)->key());
|
||||||
ASSERT(child != none, "Couldn't load first child of root node");
|
auto result = _nodeStore->overwriteNodeWith(std::move(root), *newRoot);
|
||||||
auto newRoot = _nodeStore->overwriteNodeWith(std::move(root), **child);
|
_nodeStore->remove(std::move(newRoot));
|
||||||
_nodeStore->remove(std::move(*child));
|
return result;
|
||||||
return _whileRootHasOnlyOneChildReplaceRootWithItsChild(std::move(newRoot));
|
|
||||||
} else {
|
} else {
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unique_ref<DataNode> LeafTraverser::_whileRootHasOnlyOneChildRemoveRootReturnChild(const blockstore::Key &key) {
|
||||||
|
auto current = _nodeStore->load(key);
|
||||||
|
ASSERT(current != none, "Node not found");
|
||||||
|
auto inner = dynamic_pointer_move<DataInnerNode>(*current);
|
||||||
|
if (inner == none) {
|
||||||
|
return std::move(*current);
|
||||||
|
} else if ((*inner)->numChildren() == 1) {
|
||||||
|
auto result = _whileRootHasOnlyOneChildRemoveRootReturnChild((*inner)->getChild(0)->key());
|
||||||
|
_nodeStore->remove(std::move(*inner));
|
||||||
|
return result;
|
||||||
|
} else {
|
||||||
|
return std::move(*inner);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include <cpp-utils/macros.h>
|
#include <cpp-utils/macros.h>
|
||||||
#include <cpp-utils/pointer/unique_ref.h>
|
#include <cpp-utils/pointer/unique_ref.h>
|
||||||
#include <cpp-utils/data/Data.h>
|
#include <cpp-utils/data/Data.h>
|
||||||
|
#include <blockstore/utils/Key.h>
|
||||||
|
|
||||||
namespace blobstore {
|
namespace blobstore {
|
||||||
namespace onblocks {
|
namespace onblocks {
|
||||||
@ -50,6 +51,7 @@ namespace blobstore {
|
|||||||
uint32_t _maxLeavesForTreeDepth(uint8_t depth) const;
|
uint32_t _maxLeavesForTreeDepth(uint8_t depth) const;
|
||||||
std::function<cpputils::Data (uint32_t index)> _createMaxSizeLeaf() const;
|
std::function<cpputils::Data (uint32_t index)> _createMaxSizeLeaf() const;
|
||||||
cpputils::unique_ref<datanodestore::DataNode> _whileRootHasOnlyOneChildReplaceRootWithItsChild(cpputils::unique_ref<datanodestore::DataNode> root);
|
cpputils::unique_ref<datanodestore::DataNode> _whileRootHasOnlyOneChildReplaceRootWithItsChild(cpputils::unique_ref<datanodestore::DataNode> root);
|
||||||
|
cpputils::unique_ref<datanodestore::DataNode> _whileRootHasOnlyOneChildRemoveRootReturnChild(const blockstore::Key &key);
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(LeafTraverser);
|
DISALLOW_COPY_AND_ASSIGN(LeafTraverser);
|
||||||
};
|
};
|
||||||
|
@ -464,6 +464,6 @@ TEST_F(DataTreeTest_Performance, ResizeNumBytes_DecreaseTreeDepth_2to0) {
|
|||||||
EXPECT_EQ(5u, blockStore->loadedBlocks().size()); // load new last leaf (+inner node), load second inner node to remove its subtree, then 2x load first child of root to replace root with its child.
|
EXPECT_EQ(5u, blockStore->loadedBlocks().size()); // load new last leaf (+inner node), load second inner node to remove its subtree, then 2x load first child of root to replace root with its child.
|
||||||
EXPECT_EQ(0u, blockStore->createdBlocks());
|
EXPECT_EQ(0u, blockStore->createdBlocks());
|
||||||
EXPECT_EQ(3u + maxChildrenPerInnerNode, blockStore->removedBlocks().size());
|
EXPECT_EQ(3u + maxChildrenPerInnerNode, blockStore->removedBlocks().size());
|
||||||
EXPECT_EQ(2u, blockStore->distinctWrittenBlocks().size()); // 2x rewrite root node to be a leaf
|
EXPECT_EQ(2u, blockStore->distinctWrittenBlocks().size()); // remove children from inner node and rewrite root node to be a leaf
|
||||||
EXPECT_EQ(0u, blockStore->resizedBlocks().size());
|
EXPECT_EQ(0u, blockStore->resizedBlocks().size());
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user