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

🔨 Moved and added new benchmarks

parent ceabcc8d
include(../../cmake/Testing.cmake.in)
include(../cmake/Testing.cmake.in)
do_bench(trees/tree_get)
do_bench(trees/tree_traverse)
do_bench(trees/tree_scan)
do_bench(trees/tree_insert)
do_bench(trees/tree_split)
do_bench(trees/tree_erase)
do_bench(trees/tree_balance)
do_bench(trees/tree_merge)
# PTABLE
#do_bench(ptable/insert ptable)
do_bench(ptable/scan ptable)
......
......@@ -18,9 +18,9 @@
#ifndef PTABLE_COMMON_H
#define PTABLE_COMMON_H
#include <chrono>
#include <libpmempool.h>
#include <unistd.h>
#include <experimental/filesystem>
#include <chrono>
#include "ptable/PTable.hpp"
using pmem::obj::make_persistent;
......@@ -35,7 +35,7 @@ using PTableType = dbis::ptable::PTable<MyKey, MyTuple>;
using Vector = std::vector<long int>;
using VectorVector = std::vector<Vector>;
const int hibit_pos(int n) noexcept;
int hibit_pos(int n) noexcept;
template <size_t SIZE>
static inline VectorVector *createPointVector(VectorVector *v);
......@@ -78,7 +78,7 @@ const VectorVector NON_KEY_RANGES = {
Vector{0, NUM_TUPLES - 1, 0, NUM_TUPLES - 1} //100,0%
};
const int hibit_pos(int n) noexcept {
int hibit_pos(int n) noexcept {
int c = 0;
while (n>>1 != 0) {
c++;
......@@ -102,13 +102,15 @@ void insert (pool<root> &pop, const std::string &path, size_t entries) {
std::vector<typename std::chrono::duration<int64_t, std::micro>::rep> measures;
pop = pool<root>::create(path, LAYOUT, POOL_SIZE);
const auto alloc_class = pop.ctl_set<struct pobj_alloc_class_desc>(
"heap.alloc_class.128.desc", PTableType::IndexType::AllocClass);
transaction::run(pop, [&] {
const auto tInfo = VTableInfo<MyKey, MyTuple>("MyTable", {"a","b","c","d"});
const auto dims = Dimensions({
{0, 10, ALIGNMENT},
{3, 10, ALIGNMENT}
});
pop.root()->pTable = make_persistent<PTableType>(tInfo, dims);
pop.root()->pTable = make_persistent<PTableType>(alloc_class, tInfo, dims);
});
auto &pTable = pop.root()->pTable;
......
......@@ -15,7 +15,6 @@
* If not, see <http://www.gnu.org/licenses/>.
*/
#include <experimental/filesystem>
#include "common.hpp"
using namespace dbis::ptable;
......@@ -23,7 +22,7 @@ using namespace dbis::ptable;
int main() {
pool<root> pop;
std::experimental::filesystem::remove_all(path);
pmempool_rm(path.c_str(), 0);
if (access(path.c_str(), F_OK) != 0) {
insert(pop, path, NUM_TUPLES);
} else {
......
......@@ -25,33 +25,34 @@
using namespace dbis::ptable;
static void BM_PointQuery(benchmark::State& state) {
pool<root> pop;
const std::string path = dbis::gPmemPath + "benchdb" + std::to_string(state.range(0)) + ".db";
//std::remove(path.c_str());
// std::remove(path.c_str());
if (access(path.c_str(), F_OK) != 0) {
insert(pop, path, state.range(0));
} else {
//std::cerr << "WARNING: Table already exists" << std::endl;
// std::cerr << "WARNING: Table already exists" << std::endl;
pop = pool<root>::open(path, LAYOUT);
}
auto &pTable = *pop.root()->pTable;
auto& pTable = *pop.root()->pTable;
for (auto _ : state) {
auto ptp = pTable.getByKey(state.range(1));
if (ptp.getNode() != nullptr) ptp;// ptp.createTuple();
else std::cerr << "key not found" << '\n';
if (ptp.getNode() != nullptr)
ptp; // ptp.createTuple();
else
std::cerr << "key not found" << '\n';
}
transaction::run(pop, [&] { delete_persistent<PTableType>(pop.root()->pTable); });
pop.close();
std::experimental::filesystem::remove_all(path);
pmempool_rm(path.c_str(), 0);
}
static void VectorArguments(benchmark::internal::Benchmark* b) {
for (const auto &arg : POINT_ACCESS) b->Args(arg);
for (const auto& arg : POINT_ACCESS) b->Args(arg);
}
BENCHMARK(BM_PointQuery)->Apply(VectorArguments);
......
......@@ -21,9 +21,7 @@
using namespace dbis::ptable;
static void BM_RangeScan(benchmark::State &state) {
pool<root> pop;
if (access(path.c_str(), F_OK) != 0) {
......@@ -37,20 +35,20 @@ static void BM_RangeScan(benchmark::State &state) {
/* RangeScan using Block iterator */
for (auto _ : state) {
auto iter = pTable->rangeScan(ColumnRangeMap({{0, {(int)state.range(0), (int)state.range(1)}}}));
for (const auto &tp: iter) {
auto iter =
pTable->rangeScan(ColumnRangeMap({{0, {(int)state.range(0), (int)state.range(1)}}}));
for (const auto &tp : iter) {
tp;
}
}
pop.close();
}
static void KeyRangeArguments(benchmark::internal::Benchmark* b) {
static void KeyRangeArguments(benchmark::internal::Benchmark *b) {
for (const auto &arg : KEY_RANGES) b->Args(arg);
}
BENCHMARK(BM_RangeScan)->Apply(KeyRangeArguments);
static void BM_NonKeyRangeScan(benchmark::State &state) {
pool<root> pop;
if (access(path.c_str(), F_OK) != 0) {
......@@ -64,21 +62,21 @@ static void BM_NonKeyRangeScan(benchmark::State &state) {
/* RangeScan using Block iterator */
for (auto _ : state) {
auto iter = pTable->rangeScan(ColumnRangeMap({{0, {(int)state.range(0), (int) state.range(1)}},
{3, {(double)state.range(2), (double)state.range(3)}}}));
for (const auto &tp: iter) {
auto iter =
pTable->rangeScan(ColumnRangeMap({{0, {(int)state.range(0), (int)state.range(1)}},
{3, {(double)state.range(2), (double)state.range(3)}}}));
for (const auto &tp : iter) {
tp;
}
}
pop.close();
}
static void NonKeyRangeArguments(benchmark::internal::Benchmark* b) {
static void NonKeyRangeArguments(benchmark::internal::Benchmark *b) {
for (const auto &arg : NON_KEY_RANGES) b->Args(arg);
}
BENCHMARK(BM_NonKeyRangeScan)->Apply(NonKeyRangeArguments);
static void BM_PBPTreeKeyScan(benchmark::State &state) {
pool<root> pop;
if (access(path.c_str(), F_OK) != 0) {
......@@ -92,7 +90,8 @@ static void BM_PBPTreeKeyScan(benchmark::State &state) {
for (auto _ : state) {
/* Scan via Index scan */
pTable->rangeScan2(state.range(0), state.range(1), [](int k, const PTuple<int, MyTuple> tp){tp;});
pTable->rangeScan2(state.range(0), state.range(1),
[](int k, const PTuple<int, MyTuple> tp) { tp; });
}
pop.close();
......@@ -100,7 +99,6 @@ static void BM_PBPTreeKeyScan(benchmark::State &state) {
BENCHMARK(BM_PBPTreeKeyScan)->Apply(KeyRangeArguments);
static void BM_PBPTreeScan(benchmark::State &state) {
pool<root> pop;
if (access(path.c_str(), F_OK) != 0) {
......@@ -115,11 +113,10 @@ static void BM_PBPTreeScan(benchmark::State &state) {
for (auto _ : state) {
/* Scan via PTuple iterator */
auto eIter = pTable.end();
auto iter = pTable.select(
[&](const PTuple<int, MyTuple> &tp) {
return (tp.get<0>() >= state.range(0)) && (tp.get<0>() <= state.range(1)) &&
(tp.get<3>() >= state.range(2)) && (tp.get<3>() <= state.range(3));
});
auto iter = pTable.select([&](const PTuple<int, MyTuple> &tp) {
return (tp.get<0>() >= state.range(0)) && (tp.get<0>() <= state.range(1)) &&
(tp.get<3>() >= state.range(2)) && (tp.get<3>() <= state.range(3));
});
for (; iter != eIter; iter++) {
iter;
//(*iter).get<0>();
......@@ -128,9 +125,8 @@ static void BM_PBPTreeScan(benchmark::State &state) {
transaction::run(pop, [&] { delete_persistent<PTableType>(pop.root()->pTable); });
pop.close();
std::experimental::filesystem::remove_all(path);
pmempool_rm(path.c_str(), 0);
}
BENCHMARK(BM_PBPTreeScan)->Apply(NonKeyRangeArguments);
BENCHMARK_MAIN();
......@@ -18,175 +18,211 @@
#ifndef DBIS_TREES_COMMON_HPP
#define DBIS_TREES_COMMON_HPP
#include <unistd.h>
#include <chrono>
#include <iostream>
#include <numeric>
#include <unistd.h>
#include <experimental/filesystem>
#include <libpmemobj++/pool.hpp>
#include <libpmemobj++/persistent_ptr.hpp>
#include <libpmempool.h>
#include <libpmemobj++/container/array.hpp>
#include <libpmemobj++/make_persistent.hpp>
#include <libpmemobj++/persistent_ptr.hpp>
#include <libpmemobj++/pool.hpp>
#include <libpmemobj++/transaction.hpp>
#include <numeric>
#define UNIT_TESTS
#include "benchmark/benchmark.h"
#include "PBPTree.hpp"
#include "benchmark/benchmark.h"
using namespace dbis::pbptrees;
using pmem::obj::delete_persistent;
using pmem::obj::make_persistent;
using pmem::obj::pool;
using pmem::obj::persistent_ptr;
using pmem::obj::pool;
using pmem::obj::transaction;
/*=== Types and constants ===*/
/* Customization section */
using MyTuple = std::tuple <int, int, double>;
using MyTuple = std::tuple<int, int, double>;
using MyKey = unsigned long long;
constexpr auto TARGET_BRANCH_SIZE = 512;
constexpr auto TARGET_LEAF_SIZE = 256; //< 512B best performance
constexpr auto TARGET_LEAF_SIZE = 512;
constexpr auto TARGET_DEPTH = 1;
constexpr auto IS_HYBRID = 0;
const std::string path = dbis::gPmemPath + "tree_benchSp.data";
constexpr auto POOL_SIZE = 1024 * 1024 * 1024 * 4ull; //< 1GB
constexpr auto MOVE_TO_RIGHT = 0; ///< for balance direction
const std::string path = dbis::gPmemPath + "tree_bench.data";
constexpr auto POOL_SIZE = 1024 * 1024 * 1024 * 4ull; //< 4GB
constexpr auto LAYOUT = "Tree";
constexpr auto NODE_PTR_SIZE = 24; ///< 24 Byte (8-tag + 16-pptr)
/* wBPTree pre-calculations */
template<unsigned int N>
template <unsigned int KEYS>
constexpr unsigned int getBranchKeyswBPTree() {
constexpr auto keys = getBranchKeyswBPTree<N-1>();
constexpr auto CL_h = keys + ((keys + 63) / 64) * 8;
constexpr auto CL = ((CL_h + 63) / 64) * 64;
constexpr auto SIZE = CL + keys * (sizeof(MyKey) + 24) + 24; //< CacheLine structure & n keys & n+1 children
return (SIZE <= TARGET_BRANCH_SIZE)? keys : ((TARGET_BRANCH_SIZE - CL - 24) / (sizeof(MyKey) + 24));
constexpr auto CL_h = ((KEYS + 1 + 7) / 8) * 8 + ((KEYS + 63) / 64) * 8;
constexpr auto CL = ((CL_h + 63) / 64) * 64; ///< rounding up
constexpr auto SIZE = CL + KEYS * (sizeof(MyKey) + NODE_PTR_SIZE) +
NODE_PTR_SIZE; ///< CacheLine structure & n keys & n+1 children
if constexpr (SIZE <= TARGET_BRANCH_SIZE)
return KEYS;
else
return getBranchKeyswBPTree<KEYS - 1>();
}
template<>
constexpr unsigned int getBranchKeyswBPTree<1>() {
return ((TARGET_BRANCH_SIZE - 64 - 24) / (sizeof(MyKey) + 24));
constexpr size_t getBranchKeyswBPTree() {
constexpr auto KEYS = ((TARGET_BRANCH_SIZE - 64 - NODE_PTR_SIZE) / (sizeof(MyKey) + NODE_PTR_SIZE));
return getBranchKeyswBPTree<KEYS>();
}
template<unsigned int N>
constexpr unsigned int getLeafKeyswBPTree() {
constexpr auto keys = getLeafKeyswBPTree<N-1>();
constexpr auto CL_h = keys + ((keys + 63) / 64) * 8;
template <size_t KEYS>
constexpr size_t getLeafKeyswBPTree() {
constexpr auto CL_h = ((KEYS + 1 + 7) / 8) * 8 + ((KEYS + 63) / 64) * 8 + 32;
constexpr auto CL = ((CL_h + 63) / 64) * 64;
constexpr auto SIZE = CL + 32 + keys * (sizeof(MyKey) + sizeof(MyTuple));
return (SIZE <= TARGET_LEAF_SIZE)? keys : ((TARGET_LEAF_SIZE - CL - 32) / (sizeof(MyKey) + sizeof(MyTuple)));
constexpr auto SIZE = CL + KEYS * (sizeof(MyKey) + sizeof(MyTuple));
if constexpr (SIZE <= TARGET_LEAF_SIZE)
return KEYS;
else
return getLeafKeyswBPTree<KEYS - 1>();
// return SIZE <= TARGET_LEAF_SIZE ? KEYS : getLeafKeyswBPTree<KEYS-1>();
}
template<>
constexpr unsigned int getLeafKeyswBPTree<1>() {
return ((TARGET_LEAF_SIZE - 64 - 32) / (sizeof(MyKey) + sizeof(MyTuple)));
constexpr size_t getLeafKeyswBPTree() {
constexpr auto KEYS = ((TARGET_LEAF_SIZE - 64) / (sizeof(MyKey) + sizeof(MyTuple)));
return getLeafKeyswBPTree<KEYS>();
}
/* PBPTree pre-calculations */
template<unsigned int N>
constexpr unsigned int getBranchKeysPBPTree() {
constexpr size_t getBranchKeysPBPTree() {
return ((TARGET_BRANCH_SIZE - 28) / (sizeof(MyKey) + 24));
}
template<unsigned int N>
constexpr unsigned int getLeafKeysPBPTree() {
return ((TARGET_LEAF_SIZE - 36) / (sizeof(MyKey) + sizeof(MyTuple)));
constexpr size_t getLeafKeysPBPTree() {
return ((TARGET_LEAF_SIZE - 64) / (sizeof(MyKey) + sizeof(MyTuple)));
}
/* FPTree pre-calculations */
template<unsigned int N>
constexpr unsigned int getBranchKeysFPTree() {
return ((TARGET_BRANCH_SIZE - 28) / (sizeof(MyKey) + 24));
constexpr size_t getBranchKeysFPTree() {
return ((TARGET_BRANCH_SIZE - 28) / (sizeof(MyKey) + NODE_PTR_SIZE));
}
template<unsigned int N>
constexpr unsigned int getLeafKeysFPTree() {
constexpr auto keys = getLeafKeysFPTree<N-1>();
constexpr auto CL_h = keys + ((keys + 63) / 64) * 8;
template <size_t KEYS>
constexpr size_t getLeafKeysFPTree() {
constexpr auto CL_h = ((KEYS + 7) / 8) * 8 + ((KEYS + 63) / 64) * 8 + 32;
constexpr auto CL = ((CL_h + 63) / 64) * 64;
constexpr auto SIZE = CL + 32 + keys * (sizeof(MyKey) + sizeof(MyTuple));
return (SIZE <= TARGET_LEAF_SIZE)? keys : ((TARGET_LEAF_SIZE - CL - 32) / (sizeof(MyKey) + sizeof(MyTuple)));
constexpr auto SIZE = CL + KEYS * (sizeof(MyKey) + sizeof(MyTuple));
if constexpr (SIZE <= TARGET_LEAF_SIZE)
return KEYS;
else
return getLeafKeysFPTree<KEYS - 1>();
}
template<>
constexpr unsigned int getLeafKeysFPTree<1>() {
return ((TARGET_LEAF_SIZE - 64 - 32) / (sizeof(MyKey) + sizeof(MyTuple)));
constexpr size_t getLeafKeysFPTree() {
constexpr auto KEYS = ((TARGET_LEAF_SIZE - 64) / (sizeof(MyKey) + sizeof(MyTuple)));
return getLeafKeysFPTree<KEYS>();
}
/* BitPBPTree pre-calculations */
template<unsigned int N>
constexpr unsigned int getBranchKeysBitPBPTree() {
constexpr auto keys = getBranchKeysBitPBPTree<N-1>();
constexpr auto word = sizeof(unsigned long) * 8;
constexpr auto BM = (keys + word - 1) / word * 8;
constexpr auto SIZE = BM + keys * (sizeof(MyKey) + 24) + 24; //< bitmap structure & n keys & n+1 children
return (SIZE <= TARGET_BRANCH_SIZE)? keys : ((TARGET_BRANCH_SIZE - BM - 24) / (sizeof(MyKey) + 24));
template <size_t KEYS>
constexpr size_t getBranchKeysBitPBPTree() {
constexpr auto wordBits = sizeof(unsigned long) * 8;
constexpr auto BM = (KEYS + wordBits - 1) / wordBits * 8; ///< round to necessary words
constexpr auto SIZE = BM + KEYS * (sizeof(MyKey) + NODE_PTR_SIZE) +
NODE_PTR_SIZE; ///< bitmap structure & n keys & n+1 children
if constexpr (SIZE <= TARGET_BRANCH_SIZE)
return KEYS;
else
return getBranchKeyswBPTree<KEYS - 1>();
}
template<>
constexpr unsigned int getBranchKeysBitPBPTree<1>() {
return ((TARGET_BRANCH_SIZE - sizeof(unsigned long) - 24) / (sizeof(MyKey) + 24));
constexpr size_t getBranchKeysBitPBPTree() {
constexpr auto KEYS = (TARGET_BRANCH_SIZE - sizeof(unsigned long) - NODE_PTR_SIZE) /
(sizeof(MyKey) + NODE_PTR_SIZE);
return getBranchKeysBitPBPTree<KEYS>();
}
template<unsigned int N>
constexpr unsigned int getLeafKeysBitPBPTree() {
constexpr auto keys = getLeafKeysBitPBPTree<N-1>();
constexpr auto word = sizeof(unsigned long) * 8;
constexpr auto BM = (keys + word - 1) / word * 8;
constexpr auto SIZE = BM + 32 + keys * (sizeof(MyKey) + sizeof(MyTuple));
return (SIZE <= TARGET_LEAF_SIZE)? keys : ((TARGET_LEAF_SIZE - BM - 32) / (sizeof(MyKey) + sizeof(MyTuple)));
template <size_t KEYS>
constexpr size_t getLeafKeysBitPBPTree() {
constexpr auto CL_h = ((KEYS + 63) / 64) * 8 + 32;
constexpr auto CL = ((CL_h + 63) / 64) * 64;
constexpr auto SIZE = CL + KEYS * (sizeof(MyKey) + sizeof(MyTuple));
if constexpr (SIZE <= TARGET_LEAF_SIZE)
return KEYS;
else
return getLeafKeysBitPBPTree<KEYS - 1>();
}
template<>
constexpr unsigned int getLeafKeysBitPBPTree<1>() {
return ((TARGET_LEAF_SIZE - sizeof(unsigned long) - 32) / (sizeof(MyKey) + sizeof(MyTuple)));
constexpr size_t getLeafKeysBitPBPTree() {
constexpr auto KEYS = ((TARGET_LEAF_SIZE - 64) / (sizeof(MyKey) + sizeof(MyTuple)));
return getLeafKeysBitPBPTree<KEYS>();
}
/* Power of function */
constexpr uint64_t ipow(uint64_t base, int exp, uint64_t result = 1) {
return exp < 1 ? result : ipow(base*base, exp/2, (exp % 2) ? result*base : result);
return exp < 1 ? result : ipow(base * base, exp / 2, (exp % 2) ? result * base : result);
}
/* Tree relevant calculated parameters*/
constexpr auto LEAFKEYS = getLeafKeysPBPTree<5>(); ///< 5 iterations should be enough
constexpr auto BRANCHKEYS = getBranchKeysPBPTree<5>() & ~1; ///< make this one even
constexpr auto ELEMENTS = LEAFKEYS*ipow(BRANCHKEYS+1, TARGET_DEPTH);
constexpr auto LEAFKEYS = getLeafKeysPBPTree();
constexpr auto BRANCHKEYS = getBranchKeysPBPTree() & ~1; ///< make this one even
constexpr auto ELEMENTS = LEAFKEYS * ipow(BRANCHKEYS + 1, TARGET_DEPTH);
constexpr auto KEYPOS = 1;
using TreeType = PBPTree<MyKey, MyTuple, BRANCHKEYS, LEAFKEYS>;
/* Helper for distinction between hybrid and NVM-only structures
http://index-of.co.uk/C++/C++%20Design%20Generic%20Programming%20and%20Design%20Patterns%20Applied.pdf
depending on variable IS_HYBRID different code is generated during compile time
*/
template <int v>
struct Int2Type { enum { value = v }; };
struct Int2Type {
enum { value = v };
};
template <typename T, size_t arrSize, bool isHybrid>
struct getTypes;
template <typename T, size_t arrSize>
struct getTypes<T, arrSize, true> {
using bNodeType = typename T::BranchNode *;
using iArrayType = std::array<bNodeType, arrSize>;
using iPtrType = std::unique_ptr<iArrayType>;
};
template <typename T, size_t arrSize>
struct getTypes<T, arrSize, false> {
using bNodeType = pptr<typename T::BranchNode>;
using iArrayType = pmem::obj::array<bNodeType, arrSize>;
using iPtrType = pptr<iArrayType>;
};
template<typename T, bool isHybrid>
template <typename T, bool isHybrid>
class HybridWrapper {
using Node = typename T::Node;
using BNode = typename T::BranchNode;
private:
inline size_t getDepth(const T &tree, Int2Type<true>) const {
return tree.depth;
}
inline size_t getDepth(const T &tree, Int2Type<false>) const {
return tree.depth.get_ro();
}
inline Node getChildAt(const Node &node, const size_t pos, Int2Type<true>) const {
inline size_t getDepth(const T &tree, Int2Type<true>) const { return tree.depth; }
inline size_t getDepth(const T &tree, Int2Type<false>) const { return tree.depth.get_ro(); }
inline Node getChildAt(const Node &node, const size_t pos, Int2Type<true>) const{
return node.branch->children[pos];
}
inline Node getChildAt(const Node &node, const size_t pos, Int2Type<false>) const {
return node.branch->children.get_ro()[pos];
}
inline void recover(T &tree, Int2Type<true>) const {
tree.recover();
inline Node &setChildAt(BNode &node, const size_t pos, Int2Type<true>) const {
return node.children[pos];
}
inline void recover(const T &tree, Int2Type<false>) const {
return;
inline Node &setChildAt(BNode &node, const size_t pos, Int2Type<false>) const {
return node.children.get_rw()[pos];
}
inline void recover(T &tree, Int2Type<true>) const { tree.recover(); }
inline void recover(const T &tree, Int2Type<false>) const { return; }
public:
inline size_t getDepth(const T &tree) const {
return getDepth(tree, Int2Type<isHybrid>());
}
inline size_t getDepth(const T &tree) const { return getDepth(tree, Int2Type<isHybrid>()); }
inline Node getFirstChild(const Node &node) const {
return getChildAt(node, 0, Int2Type<isHybrid>());
......@@ -196,28 +232,26 @@ class HybridWrapper {
return getChildAt(node, pos, Int2Type<isHybrid>());
}
inline void recover(T &tree) const {
recover(tree, Int2Type<isHybrid>());
inline Node &setChildAt(BNode &node, const size_t pos) const {
return setChildAt(node, pos, Int2Type<isHybrid>());
}
inline void recover(T &tree) const { recover(tree, Int2Type<isHybrid>()); }
};
auto hybridWrapperPtr = new HybridWrapper<TreeType, IS_HYBRID>();
auto &hybridWrapper = *hybridWrapperPtr;
/*=== Insert Function ===*/
void insert(persistent_ptr<TreeType> &tree) {
void insert(const persistent_ptr<TreeType> &tree, unsigned int target_depth = TARGET_DEPTH) {
std::chrono::high_resolution_clock::time_point t_start, t_end;
std::vector<typename std::chrono::duration<int64_t, std::micro>::rep> measures;
auto insertLoopLeaf = [&](int start) {
auto end = start + (LEAFKEYS + 1) / 2;
auto insertLoopLeaf = [&](int start, bool ohterHalf = false) {
auto end = start + (LEAFKEYS + 1) / 2 - ((LEAFKEYS % 2 == 1 && ohterHalf)? 1 : 0);
for (auto j = start; j < end && j < ELEMENTS; ++j) {
auto tup = MyTuple(j + 1, (j + 1) * 100, (j + 1) * 1.0);
/*if (i % (ELEMENTS/100) == 0) {
/*if (j % (ELEMENTS/100) == 0) {
std::cout << "Inserting tuple: " << (j+1)*100/ELEMENTS << "%\r";
std::cout.flush();
}*/
......@@ -228,47 +262,54 @@ void insert(persistent_ptr<TreeType> &tree) {
measures.push_back(diff);
}
};
std::function<void(int,int,bool)> insertLoopBranch = [&](int start, int depth, bool otherHalf) {
auto nodeRange = LEAFKEYS * ipow(BRANCHKEYS+1, depth);
auto lowerRange = LEAFKEYS * ipow(BRANCHKEYS+1, depth-1);
std::function<void(int, int, bool)> insertLoopBranch = [&](int start, int depth, bool otherHalf) {
auto nodeRange = LEAFKEYS * ipow(BRANCHKEYS + 1, depth);
auto lowerRange = LEAFKEYS * ipow(BRANCHKEYS + 1, depth - 1);
auto middle = (nodeRange + 1) / 2;
auto firstHalf = start + middle;
auto helper = start + nodeRange - middle - 1;