Commit 4adcc20d authored by Philipp Götze's avatar Philipp Götze
Browse files

🐞 Fixed a bug during merge by forbidding odd branch nodes sizes

parent a82ebe93
project (fptree)
include_directories(${PROJECT_SOURCE_DIR}
${THIRD_PARTY_DIR})
include_directories(${PROJECT_SOURCE_DIR})
get_property(I_DIRS DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY INCLUDE_DIRECTORIES)
set(TEST_INCLUDE_DIRS ${TEST_INCLUDE_DIRS}
${I_DIRS}
......
......@@ -53,8 +53,10 @@ using pptr = persistent_ptr<Object>;
*/
template<typename KeyType, typename ValueType, int N, int M>
class FPTree {
/// we need at least two keys on a branch node to be able to split
/// we need at least three keys on a branch node to be able to split
static_assert(N > 2, "number of branch keys has to be >2.");
/// we need an even order for branch nodes to be able to merge
static_assert(N % 2 == 0, "order of branch nodes must be even.");
/// we need at least one key on a leaf node
static_assert(M > 0, "number of leaf keys should be >0.");
......@@ -593,7 +595,7 @@ class FPTree {
* down to the leaf level starting at node @c node at depth @c depth.
*
* @param node the starting node for the insert
* @param depth the current depth of the tree (0 == leaf level)
* @param d the current depth of the tree (0 == leaf level)
* @param key the key of the element
* @param val the actual value corresponding to the key
* @param splitInfo information about the split
......@@ -887,8 +889,6 @@ class FPTree {
assert(node != nullptr);
assert(child != nullptr);
auto &nodeRef = *node;
auto &childRef = *child;
auto newChild = child;
constexpr auto middle = (N + 1) / 2;
/// 1. we check whether we can rebalance with one of the siblings
......@@ -1162,7 +1162,7 @@ class FPTree {
*
* @param leaf the leaf to insert
*/
void recoveryInsert(const pptr<LeafNode> &leaf){
void recoveryInsert(const pptr<LeafNode> &leaf) {
assert(depth > 0);
assert(leaf != nullptr);
......@@ -1194,7 +1194,7 @@ class FPTree {
* @return true if a split was performed
*/
bool recoveryInsertInBranchNode(BranchNode * const node, const int curr_depth,
const pptr<LeafNode> &leaf, SplitInfo *splitInfo){
const pptr<LeafNode> &leaf, SplitInfo *splitInfo) {
auto &nodeRef = *node;
auto &leafRef = *leaf;
auto &splitRef = *splitInfo;
......
......@@ -52,6 +52,8 @@ template<typename KeyType, typename ValueType, size_t N, size_t M>
class BitPBPTree {
/// we need at least two keys on a branch node to be able to split
static_assert(N > 2, "number of branch keys has to be >2.");
/// we need an even order for branch nodes to be able to merge
static_assert(N % 2 == 0, "order of branch nodes must be even.");
/// we need at least one key on a leaf node
static_assert(M > 0, "number of leaf keys should be >0.");
......@@ -181,7 +183,6 @@ class BitPBPTree {
currentPosition = 0;
const auto &nodeRef = *currentNode;
while(!nodeRef.bits.get_ro().test(currentPosition)) ++currentPosition;
}
iterator &operator++() {
......
project (pbptree)
include_directories(${PROJECT_SOURCE_DIR}
${THIRD_PARTY_DIR})
include_directories(${PROJECT_SOURCE_DIR})
get_property(I_DIRS DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY INCLUDE_DIRECTORIES)
set(TEST_INCLUDE_DIRS ${TEST_INCLUDE_DIRS}
${I_DIRS}
......@@ -13,6 +12,7 @@ set(TEST_INCLUDE_DIRS ${TEST_INCLUDE_DIRS}
################
#
set(PROJECT_INCLUDES_F ${PROJECT_INCLUDES_F}
${CMAKE_CURRENT_SOURCE_DIR}/BitPBPTree.hpp
${CMAKE_CURRENT_SOURCE_DIR}/PBPTree.hpp
${CMAKE_CURRENT_SOURCE_DIR}/UnsortedPBPTree.hpp
PARENT_SCOPE)
......@@ -52,6 +52,8 @@ template <typename KeyType, typename ValueType, int N, int M>
class PBPTree {
/// we need at least two keys on a branch node to be able to split
static_assert(N > 2, "number of branch keys has to be >2.");
/// we need an even order for branch nodes to be able to merge
static_assert(N % 2 == 0, "order of branch nodes must be even.");
/// we need at least one key on a leaf node
static_assert(M > 0, "number of leaf keys should be >0.");
......@@ -382,7 +384,7 @@ class PBPTree {
auto &nodeRef = *node;
assert(pos <= nodeRef.numKeys.get_ro());
const auto &leafRef = *leaf;
const auto prevNumKeys = leafRef.prevLeaf->numKeys.get_ro();
const auto prevNumKeys = pos > 0 ? leafRef.prevLeaf->numKeys.get_ro() : 0;
constexpr auto middle = (M + 1) / 2;
/// 1. we check whether we can rebalance with one of the siblings but only if both nodes have
/// the same direct parent
......@@ -573,7 +575,7 @@ class PBPTree {
sibRef.keys.get_rw()[sibRef.numKeys.get_ro() + i + 1] = nodeRef.keys.get_ro()[i];
sibRef.children.get_rw()[sibRef.numKeys.get_ro() + i + 2] = nodeRef.children.get_ro()[i + 1];
}
sibRef.numKeys.get_rw() = sibRef.numKeys.get_ro() + nodeRef.numKeys.get_ro() + 1;
sibRef.numKeys.get_rw() += nodeRef.numKeys.get_ro() + 1;
}
/**
......@@ -973,7 +975,7 @@ class PBPTree {
/// the child node was split, thus we have to add a new entry to our branch node
if (nodeRef.numKeys.get_ro() == N) {
splitBranchNode(node, childSplitInfo.key, splitInfo);
const auto splitRef = *splitInfo;
const auto &splitRef = *splitInfo;
host = (key < splitRef.key ? splitRef.leftChild: splitRef.rightChild).branch;
split = true;
pos = lookupPositionInBranchNode(host, key);
......
......@@ -52,6 +52,8 @@ template<typename KeyType, typename ValueType, int N, int M>
class UnsortedPBPTree {
/// we need at least two keys on a branch node to be able to split
static_assert(N > 2, "number of branch keys has to be >2.");
/// we need an even order for branch nodes to be able to merge
static_assert(N % 2 == 0, "order of branch nodes must be even.");
/// we need at least one key on a leaf node
static_assert(M > 0, "number of leaf keys should be >0.");
......@@ -614,7 +616,7 @@ class UnsortedPBPTree {
sibRef.keys.get_rw()[sibRef.numKeys.get_ro() + i + 1] = nodeRef.keys.get_ro()[i];
sibRef.children.get_rw()[sibRef.numKeys.get_ro() + i + 2] = nodeRef.children.get_ro()[i + 1];
}
sibRef.numKeys.get_rw() = sibRef.numKeys.get_ro() + nodeRef.numKeys.get_ro() + 1;
sibRef.numKeys.get_rw() += nodeRef.numKeys.get_ro() + 1;
}
/**
......
project (wbptree)
include_directories(${PROJECT_SOURCE_DIR}
${THIRD_PARTY_DIR})
include_directories(${PROJECT_SOURCE_DIR})
get_property(I_DIRS DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY INCLUDE_DIRECTORIES)
set(TEST_INCLUDE_DIRS ${TEST_INCLUDE_DIRS}
${I_DIRS}
......
......@@ -54,6 +54,8 @@ template<typename KeyType, typename ValueType, int N, int M>
class wBPTree {
/// we need at least two keys on a branch node to be able to split
static_assert(N > 2, "number of branch keys has to be >2.");
/// we need an even order for branch nodes to be able to merge
static_assert(N % 2 == 0, "order of branch nodes must be even.");
/// we need at least one key on a leaf node
static_assert(M > 0, "number of leaf keys should be >0.");
......@@ -268,8 +270,8 @@ class wBPTree {
*/
wBPTree() : depth(0) {
rootNode = newLeafNode();
LOG("created new wBPTree with sizeof(BranchNode) = " << sizeof(BranchNode) <<
", sizeof(LeafNode) = " << sizeof(LeafNode));
LOG("created new wBPTree with sizeof(BranchNode) = " << sizeof(BranchNode)
<< ", sizeof(LeafNode) = " << sizeof(LeafNode));
}
/**
......@@ -379,9 +381,9 @@ class wBPTree {
auto node = rootNode;
auto d = depth.get_ro();
while ( d-- > 0) node = node.branch->children.get_ro()[0];
auto leaf = *node.leaf;
auto &leafRef = *leaf;
auto leaf = node.leaf;
while (leaf != nullptr) {
auto &leafRef = *leaf;
/// for each key-value pair call func
for (auto i = 0u; i < M; i++) {
if (!leafRef.search.get_ro().b.test(i)) continue;
......@@ -403,11 +405,11 @@ class wBPTree {
* @param func the function called for each entry
*/
void scan(const KeyType &minKey, const KeyType &maxKey, ScanFunc func) const {
const auto leaf = findLeafNode(minKey);
auto &leafRef = *leaf;
auto leaf = findLeafNode(minKey);
bool higherThanMax = false;
while (!higherThanMax && leaf != nullptr) {
const auto &leafRef = *leaf;
/// for each key-value pair within the range call func
for (auto i = 0u; i < M; i++) {
if (!leafRef.search.get_ro().b.test(i)) continue;
......@@ -707,7 +709,7 @@ class wBPTree {
*/
auto lookupPositionInLeafNode(const pptr<LeafNode> &node, const KeyType &key) const {
auto pos = 1u;
auto &nodeRef = *node;
const auto &nodeRef = *node;
const auto &slotArray = nodeRef.search.get_ro().slot;
const auto &keys = nodeRef.keys.get_ro();
auto l = 1;
......
This diff is collapsed.
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment