Fix traversal and add test cases
This commit is contained in:
parent
845b0b5239
commit
508766d2f2
@ -32,14 +32,15 @@ namespace blobstore {
|
|||||||
// numLeaves<beginIndex<endIndex, numLeaves<beginIndex=endIndex
|
// numLeaves<beginIndex<endIndex, numLeaves<beginIndex=endIndex
|
||||||
|
|
||||||
uint32_t maxLeavesForDepth = _maxLeavesForTreeDepth(root->depth());
|
uint32_t maxLeavesForDepth = _maxLeavesForTreeDepth(root->depth());
|
||||||
|
bool increaseTreeDepth = endIndex > maxLeavesForDepth;
|
||||||
|
|
||||||
_traverseExistingSubtree(root.get(), std::min(beginIndex, maxLeavesForDepth), std::min(endIndex, maxLeavesForDepth), 0, false, onExistingLeaf, onCreateLeaf, onBacktrackFromSubtree);
|
_traverseExistingSubtree(root.get(), std::min(beginIndex, maxLeavesForDepth), std::min(endIndex, maxLeavesForDepth), 0, increaseTreeDepth, onExistingLeaf, onCreateLeaf, onBacktrackFromSubtree);
|
||||||
|
|
||||||
// If the traversal goes too far right for a tree this depth, increase tree depth by one and continue traversal.
|
// If the traversal goes too far right for a tree this depth, increase tree depth by one and continue traversal.
|
||||||
// This is recursive, i.e. will be repeated if the tree is still not deep enough.
|
// This is recursive, i.e. will be repeated if the tree is still not deep enough.
|
||||||
// We don't increase to the full needed tree depth in one step, because we want the traversal to go as far as possible
|
// We don't increase to the full needed tree depth in one step, because we want the traversal to go as far as possible
|
||||||
// and only then increase the depth - this causes the tree to be in consistent shape (balanced) for longer.
|
// and only then increase the depth - this causes the tree to be in consistent shape (balanced) for longer.
|
||||||
if (endIndex > maxLeavesForDepth) {
|
if (increaseTreeDepth) {
|
||||||
// TODO Test cases that increase tree depth by 0, 1, 2, ... levels
|
// TODO Test cases that increase tree depth by 0, 1, 2, ... levels
|
||||||
auto newRoot = _increaseTreeDepth(std::move(root));
|
auto newRoot = _increaseTreeDepth(std::move(root));
|
||||||
return traverseAndReturnRoot(std::move(newRoot), std::max(beginIndex, maxLeavesForDepth), endIndex, onExistingLeaf, onCreateLeaf, onBacktrackFromSubtree);
|
return traverseAndReturnRoot(std::move(newRoot), std::max(beginIndex, maxLeavesForDepth), endIndex, onExistingLeaf, onCreateLeaf, onBacktrackFromSubtree);
|
||||||
|
@ -389,4 +389,30 @@ TEST_F(DataTreeTest_TraverseLeaves, TraverseMiddlePartOfFourLevelTree) {
|
|||||||
TraverseLeaves(root.get(), nodeStore->layout().maxChildrenPerInnerNode()+5, 2*nodeStore->layout().maxChildrenPerInnerNode()*nodeStore->layout().maxChildrenPerInnerNode() + nodeStore->layout().maxChildrenPerInnerNode() -1);
|
TraverseLeaves(root.get(), nodeStore->layout().maxChildrenPerInnerNode()+5, 2*nodeStore->layout().maxChildrenPerInnerNode()*nodeStore->layout().maxChildrenPerInnerNode() + nodeStore->layout().maxChildrenPerInnerNode() -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(DataTreeTest_TraverseLeaves, LastLeafIsAlreadyResizedInCallback) {
|
||||||
|
auto root = CreateLeaf();
|
||||||
|
root->flush();
|
||||||
|
auto tree = treeStore.load(root->key()).value();
|
||||||
|
tree->traverseLeaves(0, 2, [this] (uint32_t leafIndex, DataLeafNode *leaf) {
|
||||||
|
if (leafIndex == 0) {
|
||||||
|
EXPECT_EQ(nodeStore->layout().maxBytesPerLeaf(), leaf->numBytes());
|
||||||
|
} else {
|
||||||
|
EXPECT_TRUE(false) << "only two nodes";
|
||||||
|
}
|
||||||
|
}, [this] (uint32_t /*nodeIndex*/) -> Data {
|
||||||
|
return Data(1);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(DataTreeTest_TraverseLeaves, LastLeafIsAlreadyResizedInCallback_TwoLevel) {
|
||||||
|
auto root = CreateFullTwoLevelWithLastLeafSize(5);
|
||||||
|
root->flush();
|
||||||
|
auto tree = treeStore.load(root->key()).value();
|
||||||
|
tree->traverseLeaves(0, nodeStore->layout().maxChildrenPerInnerNode()+1, [this] (uint32_t leafIndex, DataLeafNode *leaf) {
|
||||||
|
EXPECT_EQ(nodeStore->layout().maxBytesPerLeaf(), leaf->numBytes());
|
||||||
|
}, [this] (uint32_t /*nodeIndex*/) -> Data {
|
||||||
|
return Data(1);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
//TODO Refactor the test cases that are too long
|
//TODO Refactor the test cases that are too long
|
||||||
|
Loading…
Reference in New Issue
Block a user