Add test cases for tree traversal
This commit is contained in:
parent
9e9369b9ed
commit
41146282ca
@ -90,29 +90,27 @@ public:
|
|||||||
};
|
};
|
||||||
constexpr DataNodeLayout DataTreeTest_ResizeByTraversing::LAYOUT;
|
constexpr DataNodeLayout DataTreeTest_ResizeByTraversing::LAYOUT;
|
||||||
|
|
||||||
class DataTreeTest_ResizeByTraversing_P: public DataTreeTest_ResizeByTraversing, public WithParamInterface<tuple<function<unique_ref<DataTree>(DataTreeTest_ResizeByTraversing*, uint32_t)>, uint32_t, uint32_t>> {
|
class DataTreeTest_ResizeByTraversing_P: public DataTreeTest_ResizeByTraversing, public WithParamInterface<tuple<function<unique_ref<DataTree>(DataTreeTest_ResizeByTraversing*, uint32_t)>, uint32_t, uint32_t, std::function<uint32_t (uint32_t oldNumberOfLeaves, uint32_t newNumberOfLeaves)>>> {
|
||||||
public:
|
public:
|
||||||
DataTreeTest_ResizeByTraversing_P()
|
DataTreeTest_ResizeByTraversing_P()
|
||||||
: oldLastLeafSize(get<1>(GetParam())),
|
: oldLastLeafSize(get<1>(GetParam())),
|
||||||
tree(get<0>(GetParam())(this, oldLastLeafSize)),
|
tree(get<0>(GetParam())(this, oldLastLeafSize)),
|
||||||
numberOfLeavesToAdd(get<2>(GetParam())),
|
numberOfLeavesToAdd(get<2>(GetParam())),
|
||||||
newNumberOfLeaves(tree->numLeaves()+numberOfLeavesToAdd),
|
newNumberOfLeaves(tree->numLeaves()+numberOfLeavesToAdd),
|
||||||
|
traversalBeginIndex(get<3>(GetParam())(tree->numLeaves(), newNumberOfLeaves)),
|
||||||
ZEROES(LAYOUT.maxBytesPerLeaf())
|
ZEROES(LAYOUT.maxBytesPerLeaf())
|
||||||
{
|
{
|
||||||
ZEROES.FillWithZeroes();
|
ZEROES.FillWithZeroes();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GrowTree(const Key &key, uint32_t numLeavesToAdd) {
|
void GrowTree(const Key &key) {
|
||||||
auto tree = treeStore.load(key);
|
auto tree = treeStore.load(key);
|
||||||
GrowTree(tree.get().get(), numLeavesToAdd);
|
GrowTree(tree.get().get());
|
||||||
}
|
}
|
||||||
|
|
||||||
void GrowTree(DataTree *tree, uint32_t numLeavesToAdd) {
|
void GrowTree(DataTree *tree) {
|
||||||
uint32_t oldNumLeaves = tree->numLeaves();
|
|
||||||
uint32_t newNumLeaves = oldNumLeaves + numLeavesToAdd;
|
|
||||||
//TODO Test cases where beginIndex is inside of the existing leaves
|
|
||||||
uint64_t maxBytesPerLeaf = tree->maxBytesPerLeaf();
|
uint64_t maxBytesPerLeaf = tree->maxBytesPerLeaf();
|
||||||
tree->traverseLeaves(newNumLeaves-1, newNumLeaves, [] (uint32_t, DataLeafNode*){}, [maxBytesPerLeaf] (uint32_t) -> Data { return Data(maxBytesPerLeaf).FillWithZeroes();});
|
tree->traverseLeaves(traversalBeginIndex, newNumberOfLeaves, [] (uint32_t, DataLeafNode*){}, [maxBytesPerLeaf] (uint32_t) -> Data { return Data(maxBytesPerLeaf).FillWithZeroes();});
|
||||||
tree->flush();
|
tree->flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,6 +128,7 @@ public:
|
|||||||
unique_ref<DataTree> tree;
|
unique_ref<DataTree> tree;
|
||||||
uint32_t numberOfLeavesToAdd;
|
uint32_t numberOfLeavesToAdd;
|
||||||
uint32_t newNumberOfLeaves;
|
uint32_t newNumberOfLeaves;
|
||||||
|
uint32_t traversalBeginIndex;
|
||||||
Data ZEROES;
|
Data ZEROES;
|
||||||
};
|
};
|
||||||
INSTANTIATE_TEST_CASE_P(DataTreeTest_ResizeByTraversing_P, DataTreeTest_ResizeByTraversing_P,
|
INSTANTIATE_TEST_CASE_P(DataTreeTest_ResizeByTraversing_P, DataTreeTest_ResizeByTraversing_P,
|
||||||
@ -160,32 +159,42 @@ INSTANTIATE_TEST_CASE_P(DataTreeTest_ResizeByTraversing_P, DataTreeTest_ResizeBy
|
|||||||
3* DataTreeTest_ResizeByTraversing::LAYOUT.maxChildrenPerInnerNode(), //Three level tree with three children
|
3* DataTreeTest_ResizeByTraversing::LAYOUT.maxChildrenPerInnerNode(), //Three level tree with three children
|
||||||
DataTreeTest_ResizeByTraversing::LAYOUT.maxChildrenPerInnerNode() * DataTreeTest_ResizeByTraversing::LAYOUT.maxChildrenPerInnerNode(), //Full three level tree
|
DataTreeTest_ResizeByTraversing::LAYOUT.maxChildrenPerInnerNode() * DataTreeTest_ResizeByTraversing::LAYOUT.maxChildrenPerInnerNode(), //Full three level tree
|
||||||
DataTreeTest_ResizeByTraversing::LAYOUT.maxChildrenPerInnerNode() * DataTreeTest_ResizeByTraversing::LAYOUT.maxChildrenPerInnerNode() + 1 //Four level mindata tree
|
DataTreeTest_ResizeByTraversing::LAYOUT.maxChildrenPerInnerNode() * DataTreeTest_ResizeByTraversing::LAYOUT.maxChildrenPerInnerNode() + 1 //Four level mindata tree
|
||||||
|
),
|
||||||
|
//Decide the traversal begin index
|
||||||
|
Values(
|
||||||
|
[] (uint32_t /*oldNumberOfLeaves*/, uint32_t newNumberOfLeaves) {return newNumberOfLeaves;}, // Don't traverse any leaves, just resize (begin==end)
|
||||||
|
[] (uint32_t /*oldNumberOfLeaves*/, uint32_t newNumberOfLeaves) {return newNumberOfLeaves-1;}, // Traverse last leaf (begin==end-1)
|
||||||
|
[] (uint32_t oldNumberOfLeaves, uint32_t newNumberOfLeaves) {return (oldNumberOfLeaves+newNumberOfLeaves)/2;}, // Start traversal in middle of new leaves
|
||||||
|
[] (uint32_t oldNumberOfLeaves, uint32_t /*newNumberOfLeaves*/) {return oldNumberOfLeaves-1;}, // Start traversal with last old leaf
|
||||||
|
[] (uint32_t oldNumberOfLeaves, uint32_t /*newNumberOfLeaves*/) {return oldNumberOfLeaves;}, // Start traversal with first new leaf
|
||||||
|
[] (uint32_t /*oldNumberOfLeaves*/, uint32_t /*newNumberOfLeaves*/) {return 0;}, // Traverse full tree
|
||||||
|
[] (uint32_t /*oldNumberOfLeaves*/, uint32_t /*newNumberOfLeaves*/) {return 1;} // Traverse full tree except first leaf
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
TEST_P(DataTreeTest_ResizeByTraversing_P, StructureIsValid) {
|
TEST_P(DataTreeTest_ResizeByTraversing_P, StructureIsValid) {
|
||||||
GrowTree(tree.get(), numberOfLeavesToAdd);
|
GrowTree(tree.get());
|
||||||
EXPECT_IS_LEFTMAXDATA_TREE(tree->key());
|
EXPECT_IS_LEFTMAXDATA_TREE(tree->key());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(DataTreeTest_ResizeByTraversing_P, NumLeavesIsCorrect_FromCache) {
|
TEST_P(DataTreeTest_ResizeByTraversing_P, NumLeavesIsCorrect_FromCache) {
|
||||||
tree->numLeaves(); // fill cache with old value
|
tree->numLeaves(); // fill cache with old value
|
||||||
GrowTree(tree.get(), numberOfLeavesToAdd);
|
GrowTree(tree.get());
|
||||||
// tree->numLeaves() only goes down the right border nodes and expects the tree to be a left max data tree.
|
// tree->numLeaves() only goes down the right border nodes and expects the tree to be a left max data tree.
|
||||||
// This is what the StructureIsValid test case is for.
|
// This is what the StructureIsValid test case is for.
|
||||||
EXPECT_EQ(newNumberOfLeaves, tree->numLeaves());
|
EXPECT_EQ(newNumberOfLeaves, tree->numLeaves());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(DataTreeTest_ResizeByTraversing_P, NumLeavesIsCorrect) {
|
TEST_P(DataTreeTest_ResizeByTraversing_P, NumLeavesIsCorrect) {
|
||||||
GrowTree(tree.get(), numberOfLeavesToAdd);
|
GrowTree(tree.get());
|
||||||
// tree->_forceComputeNumLeaves() only goes down the right border nodes and expects the tree to be a left max data tree.
|
// tree->_forceComputeNumLeaves() only goes down the right border nodes and expects the tree to be a left max data tree.
|
||||||
// This is what the StructureIsValid test case is for.
|
// This is what the StructureIsValid test case is for.
|
||||||
EXPECT_EQ(newNumberOfLeaves, tree->_forceComputeNumLeaves());
|
EXPECT_EQ(newNumberOfLeaves, tree->_forceComputeNumLeaves());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(DataTreeTest_ResizeByTraversing_P, DepthFlagsAreCorrect) {
|
TEST_P(DataTreeTest_ResizeByTraversing_P, DepthFlagsAreCorrect) {
|
||||||
GrowTree(tree.get(), numberOfLeavesToAdd);
|
GrowTree(tree.get());
|
||||||
uint32_t depth = ceil(log(newNumberOfLeaves)/log(DataTreeTest_ResizeByTraversing::LAYOUT.maxChildrenPerInnerNode()));
|
uint32_t depth = ceil(log(newNumberOfLeaves)/log(DataTreeTest_ResizeByTraversing::LAYOUT.maxChildrenPerInnerNode()));
|
||||||
CHECK_DEPTH(depth, tree->key());
|
CHECK_DEPTH(depth, tree->key());
|
||||||
}
|
}
|
||||||
@ -193,7 +202,7 @@ TEST_P(DataTreeTest_ResizeByTraversing_P, DepthFlagsAreCorrect) {
|
|||||||
TEST_P(DataTreeTest_ResizeByTraversing_P, KeyDoesntChange) {
|
TEST_P(DataTreeTest_ResizeByTraversing_P, KeyDoesntChange) {
|
||||||
Key key = tree->key();
|
Key key = tree->key();
|
||||||
tree->flush();
|
tree->flush();
|
||||||
GrowTree(tree.get(), numberOfLeavesToAdd);
|
GrowTree(tree.get());
|
||||||
EXPECT_EQ(key, tree->key());
|
EXPECT_EQ(key, tree->key());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -204,7 +213,7 @@ TEST_P(DataTreeTest_ResizeByTraversing_P, DataStaysIntact) {
|
|||||||
cpputils::destruct(std::move(tree));
|
cpputils::destruct(std::move(tree));
|
||||||
data.FillInto(nodeStore->load(key).get().get());
|
data.FillInto(nodeStore->load(key).get().get());
|
||||||
|
|
||||||
GrowTree(key, newNumberOfLeaves);
|
GrowTree(key);
|
||||||
|
|
||||||
data.EXPECT_DATA_CORRECT(nodeStore->load(key).get().get(), oldNumberOfLeaves, oldLastLeafSize);
|
data.EXPECT_DATA_CORRECT(nodeStore->load(key).get().get(), oldNumberOfLeaves, oldLastLeafSize);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user