Commit 78bc26c1 authored by Philipp Götze's avatar Philipp Götze
Browse files

Changes during DaMoN experiments

parent fc4b24c5
#!/bin/bash
### LOCATIONS ###
REPO_ROOT=$PWD
BUILD_DIR=build
DATA=/mnt/mem/test/tree_bench.data
OUTPUT_FILE=$REPO_ROOT/results/insert5.csv
### CUSTOMIZABLE PARAMETERS ###
bsize=512
depth=0
keypos=('first' 'middle' 'last')
LEAF_SIZES=( 256 512 1024 2048 4096 )
TREE="UnsortedPBP" #FP/PBP/wBP
TREE_BASE="PBP" # for namespace and numKeys determination
SUFFIX="" # in case of binary vs. linear
### Do not change anything following here!!! ###
### needs manual adaption ###
fillratio=1.0
lat=75
### adapting Tree usage ###
sed -i'' -e 's/\(.*BRANCH_SIZE = \)\([0-9]\+\)\(.*\)/\1'"$bsize"'\3/' $REPO_ROOT/src/bench/trees/common.hpp
sed -i'' -e 's/\(.*DEPTH = \)\([0-9]\+\)\(.*\)/\1'"$depth"'\3/' $REPO_ROOT/src/bench/trees/common.hpp
sed -i'' -e 's/\(.*\"\).*\(Tree.hpp\"\)/\1'"$TREE"'\2/' $REPO_ROOT/src/bench/trees/common.hpp #include
sed -i'' -e 's/\(.*dbis::\).*\(tree;\)/\1'"${TREE_BASE,,}"'\2/' $REPO_ROOT/src/bench/trees/common.hpp #namespace
sed -i'' -e 's/\(.*LEAFKEYS = getLeafKeys\).*\(Tree.*\)/\1'"$TREE_BASE"'\2/' $REPO_ROOT/src/bench/trees/common.hpp #keys
sed -i'' -e 's/\(.*BRANCHKEYS = getBranchKeys\).*\(Tree.*\)/\1'"$TREE_BASE"'\2/' $REPO_ROOT/src/bench/trees/common.hpp #keys
sed -i'' -e 's/\(.*TreeType = \).*\(Tree.*\)/\1'"$TREE"'\2/' $REPO_ROOT/src/bench/trees/common.hpp #type
echo -n "Running benchmarks for ${Tree}Tree..."
for pos in "${keypos[@]}"
do
echo -en "\nKey Position: $pos - "
KEYPOS='2'
if [ $pos == "first" ];then
KEYPOS='ELEMENTS'
elif [ $pos == "last" ]; then
KEYPOS='1'
fi
sed -i'' -e 's/\(.*KEYPOS = ELEMENTS\/\)\(.\+\)\(;.*\)/\1'"$KEYPOS"'\3/' $REPO_ROOT/src/bench/trees/common.hpp
for lsize in "${LEAF_SIZES[@]}"
do
echo -n "$lsize "
sed -i'' -e 's/\(.*LEAF_SIZE = \)\([0-9]\+\)\(.*\)/\1'"$lsize"'\3/' $REPO_ROOT/src/bench/trees/common.hpp
pushd $BUILD_DIR > /dev/null
make tree_insert > /dev/null
for r in {1..5}
do
rm -rf $DATA
OUTPUT="$(sh -c 'bench/tree_insert --benchmark_format=csv --benchmark_min_time=0.005' 2> /dev/null | tail -3)"
elements="$(echo "$OUTPUT" | head -1 | cut -d ':' -f2)"
time="$(echo "$OUTPUT" | tail -1 | cut -d ',' -f4)"
echo "${TREE}Tree$SUFFIX,$elements,$lsize,$bsize,$depth,$fillratio,$pos,$time,$lat" >> $OUTPUT_FILE
done
popd > /dev/null
done
done
echo -e "\nFinished. Results in $OUTPUT_FILE"
#!/bin/bash
### LOCATIONS ###
REPO_ROOT=$PWD
BUILD_DIR=build
DATA=/mnt/mem/test/tree_bench.data
OUTPUT_FILE=$REPO_ROOT/results/searchNoOpt.csv
### CUSTOMIZABLE PARAMETERS ###
bsize=512
depth=1
LEAF_SIZES=( 256 512 1024 2048 4096 )
TREE="FP" #FP/PBP/wBP
SUFFIX="" # in case of binary vs. linear
### Do not change anything following here!!! ###
### needs manual adaption ###
fillratio=1.0
keypos="last" #first/middle/last
### adapting Tree usage ###
sed -i'' -e 's/\(.*BRANCH_SIZE = \)\([0-9]\+\)\(.*\)/\1'"$bsize"'\3/' $REPO_ROOT/src/bench/trees/common.hpp
sed -i'' -e 's/\(.*DEPTH = \)\([0-9]\+\)\(.*\)/\1'"$depth"'\3/' $REPO_ROOT/src/bench/trees/common.hpp
sed -i'' -e 's/\(.*\"\).*\(Tree.hpp\"\)/\1'"$TREE"'\2/' $REPO_ROOT/src/bench/trees/common.hpp #include
sed -i'' -e 's/\(.*dbis::\).*\(tree;\)/\1'"${TREE,,}"'\2/' $REPO_ROOT/src/bench/trees/common.hpp #namespace
sed -i'' -e 's/\(.*LEAFKEYS = getLeafKeys\).*\(Tree.*\)/\1'"$TREE"'\2/' $REPO_ROOT/src/bench/trees/common.hpp #keys
sed -i'' -e 's/\(.*BRANCHKEYS = getBranchKeys\).*\(Tree.*\)/\1'"$TREE"'\2/' $REPO_ROOT/src/bench/trees/common.hpp #keys
sed -i'' -e 's/\(.*TreeType = \).*\(Tree.*\)/\1'"$TREE"'\2/' $REPO_ROOT/src/bench/trees/common.hpp #type
echo -n "Running benchmarks for ${Tree}Tree..."
for lsize in "${LEAF_SIZES[@]}"
do
echo -en "\nLeaf size: $lsize"
sed -i'' -e 's/\(.*LEAF_SIZE = \)\([0-9]\+\)\(.*\)/\1'"$lsize"'\3/' $REPO_ROOT/src/bench/trees/common.hpp
rm -rf $DATA
pushd $BUILD_DIR > /dev/null
make tree_get > /dev/null
for r in {1..3}
do
OUTPUT="$(sh -c 'bench/tree_get --benchmark_format=csv' 2> /dev/null | tail -3)"
elements="$(echo "$OUTPUT" | head -1 | cut -d ':' -f2)"
time="$(echo "$OUTPUT" | tail -1 | cut -d ',' -f4)"
echo "${TREE}Tree$SUFFIX,$elements,$lsize,$bsize,$depth,$fillratio,$keypos,$time" >> $OUTPUT_FILE
done
popd > /dev/null
done
echo -e "\nFinished. Results in $OUTPUT_FILE"
......@@ -17,7 +17,7 @@ option(ENABLE_LOG "enables log output for e.g. debugging" OFF)
option(ENABLE_PROFILING "enables profiling for some of the structures" OFF)
option(BUILD_TEST_CASES "build tests for functionality of structures" ON )
option(BUILD_GOOGLE_BENCH "build google benchmark" OFF)
option(BUILD_BENCHMARKS "build benchmarks for structures" OFF)
option(BUILD_BENCHMARKS "build benchmarks for structures" ON )
################################################################################
# End of customization section #
......@@ -99,7 +99,7 @@ include_directories(${PROJECT_SOURCE_DIR}
${THIRD_PARTY_DIR}/pmdk/include)
add_library(nvmDS_deps STATIC ${THIRD_PARTY_DIR}/pmdk)
add_dependencies(nvmDS_deps fmt_target catch_target pmdk_target) #< executes custom commands
target_link_libraries(nvmDS_deps ${PMDK_LIBRARIES} ndctl daxctl)
target_link_libraries(nvmDS_deps ${PMDK_LIBRARIES} stdc++fs ndctl daxctl)
set_target_properties(nvmDS_deps PROPERTIES LINKER_LANGUAGE CXX)
#################
......
......@@ -3,6 +3,7 @@ include(../../cmake/Testing.cmake.in)
if (BUILD_BENCHMARKS)
do_bench(trees/tree_get)
do_bench(trees/tree_traverse)
do_bench(trees/tree_insert)
# PTABLE
do_bench(ptable/insert ptable)
do_bench(ptable/scan ptable)
......
......@@ -27,9 +27,9 @@
#define UNIT_TESTS
#include "benchmark/benchmark.h"
#include "FPTree.hpp"
#include "UnsortedPBPTree.hpp"
using namespace dbis::fptree;
using namespace dbis::pbptree;
using pmem::obj::pool;
......@@ -37,11 +37,11 @@ using pmem::obj::pool;
/* Customization section */
using MyTuple = std::tuple <int, int, double>;
using MyKey = unsigned long long;
constexpr auto TARGET_BRANCH_SIZE = 2048;
constexpr auto TARGET_LEAF_SIZE = 512; //< 512B best performance
constexpr auto TARGET_DEPTH = 4;
constexpr auto TARGET_BRANCH_SIZE = 512;
constexpr auto TARGET_LEAF_SIZE = 4096; //< 512B best performance
constexpr auto TARGET_DEPTH = 0;
const std::string path = dbis::gPmemPath + "tree_bench.data";
constexpr auto POOL_SIZE = 1024 * 1024 * 1024; //< 128MB
constexpr auto POOL_SIZE = 1024 * 1024 * 1024 * 1ull; //< 4GB
constexpr auto LAYOUT = "Tree";
/* wBPTree pre-calculations */
......@@ -104,11 +104,12 @@ constexpr uint64_t ipow(uint64_t base, int exp, uint64_t result = 1) {
}
/* Tree relevant calculated parameters*/
constexpr auto LEAFKEYS = getLeafKeysFPTree<5>(); //< 5 iterations should be enough
constexpr auto BRANCHKEYS = getBranchKeyswBPTree<5>();
constexpr auto LEAFKEYS = getLeafKeysPBPTree<5>(); //< 5 iterations should be enough
constexpr auto BRANCHKEYS = getBranchKeysPBPTree<5>();
constexpr auto ELEMENTS = LEAFKEYS*ipow(BRANCHKEYS+1, TARGET_DEPTH);
constexpr auto KEYPOS = ELEMENTS/1;
using TreeType = FPTree<MyKey, MyTuple, BRANCHKEYS, LEAFKEYS>;
using TreeType = UnsortedPBPTree<MyKey, MyTuple, BRANCHKEYS, LEAFKEYS>;
/*=== Insert Function ===*/
void insert(persistent_ptr<TreeType> &tree) {
......@@ -145,12 +146,17 @@ void insert(persistent_ptr<TreeType> &tree) {
};
std::function<void(int)> insertLoopOtherHalf = [&](int depth) {
//tree->printBranchNode(0, tree->rootNode.branch);
if (depth == 0) {
auto otherHalf = (LEAFKEYS + 1) / 2;
for(auto i = 0; i < ipow(BRANCHKEYS+1,TARGET_DEPTH-depth); ++i)
insertLoopLeaf(otherHalf + i * LEAFKEYS);
} else {
auto otherHalf = (LEAFKEYS * ipow(BRANCHKEYS+1, depth) + 1) / 2 + LEAFKEYS * ipow(BRANCHKEYS+1, depth-1);
auto nodeRange = LEAFKEYS * ipow(BRANCHKEYS+1, depth);
auto lowerRange = LEAFKEYS * ipow(BRANCHKEYS+1, depth-1);
auto middle = (nodeRange + 1) / 2;
auto seen = middle + lowerRange;
auto otherHalf = (BRANCHKEYS%2==0)? seen - (lowerRange+1)/2 : seen;
for(auto i = 0; i < ipow(BRANCHKEYS+1,TARGET_DEPTH-depth); ++i)
insertLoopBranch(otherHalf + i * LEAFKEYS * ipow(BRANCHKEYS+1, depth), depth, true);
insertLoopOtherHalf(depth-1);
......@@ -159,7 +165,6 @@ void insert(persistent_ptr<TreeType> &tree) {
insertLoopBranch(0, TARGET_DEPTH, false);
insertLoopOtherHalf(TARGET_DEPTH);
//tree->printBranchNode(0, tree->rootNode.branch);
auto avg = std::accumulate(measures.begin(), measures.end(), 0) / measures.size();
auto minmax = std::minmax_element(std::begin(measures), std::end(measures));
......
......@@ -39,37 +39,32 @@ static void BM_TreeGet(benchmark::State &state) {
} else {
LOG("Warning: " << path << " already exists");
pop = pool<root>::open(path, LAYOUT);
pop.root()->tree->recover(); //< FPTree only
pop.root()->tree->recover(); //< hybrids only
}
auto tree = pop.root()->tree;
//tree->printBranchNode(0, tree->rootNode.branch);
/* Getting a leaf node */
auto node = tree->rootNode;
/* FPTree version */
/* hybrid versions */
auto d = tree->depth;
while ( d > 1) {
node = node.branch->children[0];
--d;
}
if(d == 1) node = node.lowestbranch->children[0];
while ( d-- > 0) node = node.branch->children[0];
/* nvm-only trees */
//auto d = tree->depth.get_ro();
//while ( d-- > 0) node = node.branch->children.get_ro()[0];
/* other trees */
/*
auto d = tree->depth.get_ro();
while ( --d > 0) node = node.branch->children.get_ro()[0];
*/
auto leaf = node.leaf;
/* BENCHMARKING */
unsigned int p;
for (auto _ : state) {
//MyTuple tp;
//auto c = 0u;
//auto func = [&](MyKey const &key, MyTuple const &val) { c++; };
//tree->scan(ELEMENTS/2, ELEMENTS/2 + 99, func);
//tree->lookup(ELEMENTS/2, &tp);
auto p = tree->lookupPositionInLeafNode(leaf, 1);
benchmark::DoNotOptimize(
p = tree->lookupPositionInLeafNode(leaf, LEAFKEYS)
);
}
//tree->printBranchNode(0, tree->rootNode.branch);
std::cout << "Elements:" << ELEMENTS << '\n';
pop.close();
......
/*
* Copyright (C) 2017-2019 DBIS Group - TU Ilmenau, All Rights Reserved.
*
* This file is part of our NVM-based Data Structure Repository.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <filesystem>
#include "common.hpp"
void prepare(const persistent_ptr<TreeType> tree);
/* Get benchmarks on Tree */
static void BM_TreeInsert(benchmark::State &state) {
std::cout << "BRANCHKEYS: " << BRANCHKEYS
<< "\nLEAFKEYS: " << LEAFKEYS
<< "\n";
struct root {
persistent_ptr<TreeType> tree;
};
pool<root> pop;
if (access(path.c_str(), F_OK) != 0) {
pop = pool<root>::create(path, LAYOUT, POOL_SIZE);
transaction::run(pop, [&] {
pop.root()->tree = make_persistent<TreeType>();
});
} else {
LOG("Warning: " << path << " already exists");
auto n = std::filesystem::remove_all(path);
pop = pool<root>::create(path, LAYOUT);
transaction::run(pop, [&] {
delete_persistent<TreeType>(pop.root()->tree);
pop.root()->tree = make_persistent<TreeType>();
});
}
auto tree = pop.root()->tree;
/* Getting the leaf node */
auto leaf = tree->rootNode.leaf;
//tree->printLeafNode(0, leaf);
const auto reqTup = MyTuple(KEYPOS, KEYPOS * 100, KEYPOS * 1.0);
TreeType::SplitInfo splitInfo;
bool split;
/* BENCHMARKING */
for (auto _ : state) {
state.PauseTiming();
tree->rootNode = tree->newLeafNode();
leaf = tree->rootNode.leaf;
prepare(tree);
//leaf->keys.getWrites();
state.ResumeTiming();
split = tree->insertInLeafNode(leaf, KEYPOS, reqTup, &splitInfo);
state.PauseTiming();
assert(split == false);
//leaf->keys.getWrites();
tree->deleteLeafNode(leaf);
state.ResumeTiming();
}
//tree->printLeafNode(0, leaf);
std::cout << "Elements:" << ELEMENTS << '\n';
pop.close();
}
BENCHMARK(BM_TreeInsert);
BENCHMARK_MAIN();
/* preparing inserts */
void prepare(const persistent_ptr<TreeType> tree) {
auto insertLoop = [&tree](int start, int end) {
for (auto j = start; j < end + 1; ++j) {
auto tup = MyTuple(j, j * 100, j * 1.0);
tree->insert(j, tup);
}
};
switch (KEYPOS) {
case 1 /*first*/: insertLoop(2, ELEMENTS); break;
case ELEMENTS /*last*/: insertLoop(1, ELEMENTS-1);break;
case ELEMENTS/2 /*middle*/: {insertLoop(1, KEYPOS-1); insertLoop(KEYPOS+1, ELEMENTS);}
}
}
......@@ -39,35 +39,33 @@ static void BM_TreeTraverse(benchmark::State &state) {
} else {
LOG("Warning: " << path << " already exists");
pop = pool<root>::open(path, LAYOUT);
pop.root()->tree->recover(); //< FPTree only
//pop.root()->tree->recover(); //< Hybrids only
}
auto tree = pop.root()->tree;
persistent_ptr<TreeType::LeafNode> leaf;
/* BENCHMARKING */
for (auto _ : state) {
/* Getting a leaf node */
auto node = tree->rootNode;
/* FPTree version */
/* hybrid versions */
auto d = tree->depth;
while ( d > 1) {
node = node.branch->children[tree->lookupPositionInBranchNode(node.branch, 1)];
--d;
}
if(d == 1) node = node.lowestbranch->children[0];
while ( --d > 0)
node = node.branch->children[tree->lookupPositionInBranchNode(node.branch, KEYPOS)];
/* NVM-only versions */
//auto d = tree->depth.get_ro();
//while ( --d > 0)
// node = node.branch->children.get_ro()[tree->lookupPositionInBranchNode(node.branch, KEYPOS)];
/* other trees */
/*
auto d = tree->depth.get_ro();
while ( --d > 0)
node = node.branch->children.get_ro()[tree->lookupPositionInBranchNode(node.branch, 1)];
*/
auto leaf = node.leaf;
benchmark::DoNotOptimize(
leaf = node.leaf
);
//auto p = tree->lookupPositionInLeafNode(leaf, 1);
}
//tree->printBranchNode(0, tree->rootNode.branch);
std::cout << "Elements:" << ELEMENTS << "\n";
std::cout << "Size" << sizeof(*tree) << "\n";
pop.close();
}
BENCHMARK(BM_TreeTraverse);
......
This diff is collapsed.
......@@ -796,24 +796,31 @@ class PBPTree {
bool insertInLeafNode(persistent_ptr<LeafNode> node, const KeyType &key,
const ValueType &val, SplitInfo *splitInfo) {
bool split = false;
const auto &numKeys = node->numKeys.get_ro();
auto pos = lookupPositionInLeafNode(node, key);
if (pos < node->numKeys && node->keys.get_ro()[pos] == key) {
if (pos < numKeys && node->keys.get_ro()[pos] == key) {
// handle insert of duplicates
std::cout << "FORBIDDEN" << std::endl;
node->values.get_rw()[pos] = val;
return false;
}
if (node->numKeys == M) {
if (numKeys == M) {
// the node is full, so we must split it
// determine the split position
unsigned int middle = (M + 1) / 2;
// move all entries behind this position to a new sibling node
persistent_ptr<LeafNode> sibling = newLeafNode();
sibling->numKeys = node->numKeys - middle;
for (auto i = 0u; i < sibling->numKeys; i++) {
sibling->keys.get_rw()[i] = node->keys.get_ro()[i + middle];
sibling->values.get_rw()[i] = node->values.get_ro()[i + middle];
sibling->numKeys = numKeys - middle;
const auto &sNumKeys = sibling->numKeys;
const auto &nKeys = node->keys.get_ro();
const auto &nValues = node->values.get_ro();
auto &sKeys = sibling->keys.get_rw();
auto &sValues = sibling->values.get_rw();
for (auto i = 0u; i < sNumKeys; i++) {
sKeys[i] = nKeys[i + middle];
sValues[i] = nValues[i + middle];
}
node->numKeys = middle;
node->numKeys.get_rw() = middle;
// insert the new entry
if (pos < middle)
......@@ -831,9 +838,10 @@ class PBPTree {
// and inform the caller about the split
split = true;
splitInfo->leftChild = node;
splitInfo->rightChild = sibling;
splitInfo->key = sibling->keys.get_ro()[0];
auto &splitInfoRef = *splitInfo;
splitInfoRef.leftChild = node;
splitInfoRef.rightChild = sibling;
splitInfoRef.key = sibling->keys.get_ro()[0];
} else {
// otherwise, we can simply insert the new entry at the given position
insertInLeafNodeAtPosition(node, pos, key, val);
......@@ -855,18 +863,19 @@ class PBPTree {
*/
void insertInLeafNodeAtPosition(persistent_ptr<LeafNode> node, unsigned int pos,
const KeyType &key, const ValueType &val) {
const auto &numKeys = node->numKeys.get_ro();
assert(pos < M);
assert(pos <= node->numKeys);
assert(node->numKeys < M);
assert(pos <= numKeys);
assert(numKeys < M);
// we move all entries behind pos by one position
for (unsigned int i = node->numKeys; i > pos; i--) {
for (unsigned int i = numKeys; i > pos; i--) {
node->keys.get_rw()[i] = node->keys.get_ro()[i - 1];
node->values.get_rw()[i] = node->values.get_ro()[i - 1];
}
// and then insert the new entry at the given position
node->keys.get_rw()[pos] = key;
node->values.get_rw()[pos] = val;
node->numKeys = node->numKeys + 1;
node->numKeys.get_rw() = numKeys + 1;
}
/**
......@@ -997,7 +1006,8 @@ class PBPTree {
const KeyType &key) const {
unsigned int pos = 0;
const unsigned int num = node->numKeys;
//for (; pos < num && node->keys.get_ro()[pos] <= key; pos++);
//const auto &keys = node->keys.get_ro();
//for (; pos < num && keys[pos] <= key; pos++);
//return pos;
return binarySearch(node, 0, num-1, key);
}
......@@ -1015,7 +1025,8 @@ class PBPTree {
const KeyType &key) const {
unsigned int pos = 0;
const unsigned int num = node->numKeys.get_ro();
//for (; pos < num && node->keys.get_ro()[pos] < key; pos++);
//const auto &keys = node->keys.get_ro();
//for (; pos < num && keys[pos] < key; pos++);
//return pos;
return binarySearch(node, 0, num-1, key);
}
......@@ -1023,10 +1034,11 @@ class PBPTree {
unsigned int binarySearch(persistent_ptr<BranchNode> node, int l, int r,
KeyType const &key) const {
auto pos = 0u;
const auto &keys = node->keys.get_ro();
while (l <= r) {
pos = (l + r) / 2;
if (node->keys.get_ro()[pos] == key) return ++pos;
if (node->keys.get_ro()[pos] < key) l = ++pos;
if (keys[pos] == key) return ++pos;
if (keys[pos] < key) l = ++pos;
else r = pos - 1;
}
return pos;
......@@ -1035,10 +1047,11 @@ class PBPTree {
unsigned int binarySearch(persistent_ptr<LeafNode> node, int l, int r,
KeyType const &key) const {
auto pos = 0u;
const auto &keys = node->keys.get_ro();
while (l <= r) {
pos = (l + r) / 2;
if (node->keys.get_ro()[pos] == key) return pos;
if (node->keys.get_ro()[pos] < key) l = ++pos;
if (keys[pos] == key) return pos;
if (keys[pos] < key) l = ++pos;
else r = pos - 1;
}
return pos;
......
......@@ -29,6 +29,7 @@
#include <libpmemobj++/transaction.hpp>
#include <libpmemobj++/utils.hpp>
#include "utils/ElementOfRankK.hpp"
#include "config.h"
#define BRANCH_PADDING 0
#define LEAF_PADDING 0
......@@ -55,8 +56,6 @@ class UnsortedPBPTree {
static_assert(N > 2, "number of branch keys has to be >2.");
// we need at least one key on a leaf node
static_assert(M > 0, "number of leaf keys should be >0.");
// there is a bug that for odd numbers the tree sometimes breaks (TODO)
static_assert(M % 2 == 0 && N % 2 == 0, "The number of keys should be even");
#ifndef UNIT_TESTS
private:
......@@ -265,10 +264,10 @@ class UnsortedPBPTree {
auto leafNode = findLeafNode(key);
auto pos = lookupPositionInLeafNode(leafNode, key);
PROFILE_READ()
PROFILE_READ(1)
if (pos < leafNode->numKeys && leafNode->keys.get_ro()[pos] == key) {
// we found it!
PROFILE_READ()
PROFILE_READ(1)
*val = leafNode->values.get_ro()[pos];
result = true;
}
......@@ -325,12 +324,12 @@ class UnsortedPBPTree {
void scan(ScanFunc func) const {
// we traverse to the leftmost leaf node
auto node = rootNode;
PROFILE_READ()
PROFILE_READ(1)
auto d = depth.get_ro();
while (d-- > 0) {
// as long as we aren't at the leaf level we follow the path down
auto n = node.branch;
PROFILE_READ()
PROFILE_READ(1)
node = n->children.get_ro()[0];
}
auto leaf = node.leaf;
......@@ -361,10 +360,10 @@ class UnsortedPBPTree {
while (leaf != nullptr) {
// for each key-value pair within the range call func
for (auto i = 0u; i < leaf->numKeys; i++) {
PROFILE_READ()
PROFILE_READ(1)
auto &key = leaf->keys.get_ro()[i];
if (key > maxKey) return;
PROFILE_READ()
PROFILE_READ(1)
auto &val = leaf->values.get_ro()[i];
func(key, val);
}
......@@ -425,13 +424,13 @@ class UnsortedPBPTree {
if (pos > 0 && leaf->prevLeaf->numKeys > middle) {
// we have a sibling at the left for rebalancing the keys
balanceLeafNodes(leaf->prevLeaf, leaf);
PROFILE_READ()
PROFILE_READ(1)
PROFILE_WRITE()
node->keys.get_rw()[pos-1] = leaf->keys.get_ro()[findMinKeyAtLeafNode(leaf)];