Commit a2bf1c66 authored by Philipp Götze's avatar Philipp Götze

🔀 Merge branch 'wip/testcases'

parents 46ddfacb fe2a2882
......@@ -5,17 +5,18 @@ A persistent analytical table structure for non-volatile memory.
Please see the file [COPYING](COPYING) for license information.
### TODOs:
- [ ] Tests
- [x] Tests
- [ ] Get rid of expensive transactions
- [x] Improve benchmarks
- [ ] Describe usage
- [ ] The BlockIterator currently suffers from bugs (SEGSIGV with too big structures)
### Installation ###
We use the C++17 standard, thus, you need a very recent C++ compiler and CMake (3.2 or newer) build environment.
We use the C++14 standard, thus, you need a recent C++ compiler and CMake (3.2 or newer) build environment.
In addition some third party libraries such as [Catch](https://github.com/philsquared/Catch) for testing, [Google Benchmark](https://github.com/google/benchmark.git) for benchmarking, [Format](https://github.com/fmtlib/fmt.git), and [NVML](https://github.com/pmem/nvml.git) are used
These, however, are either included or downloaded during the build process.
In addition some third party libraries such as [Catch](https://github.com/philsquared/Catch) for testing, [Google Benchmark](https://github.com/google/benchmark.git) for benchmarking, [Format](https://github.com/fmtlib/fmt.git), and [PMDK](https://github.com/pmem/pmdk.git) are used.
These, however, are both downloaded and included during the build process.
After cloning and switching into the project directory, you can build the repository with with:
```
......@@ -29,4 +30,7 @@ make test
### Usage ###
The test cases and benchmarks use the directory _/mnt/pmem/test_ for storing data. Thus, make sure the pmem device is mounted at _/mnt/pmem_ and the subfolder _test_ has write permissions for everybody. Alternatively, you can change the directory in [common.h](src/bench/common.h).
The test cases and benchmarks use the directory _/mnt/pmem/test_ for storing data. Thus, make sure the pmem device is mounted at _/mnt/pmem_ and the subfolder _test_ has write permissions for everybody.
Alternatively, you can change the directory in the customization section in [CMakeLists.txt](src/CMakeLists.txt).
A detailed usage description will follow soon.
Till then the general usage can be found out by looking at test cases and benchmarks.
......@@ -44,7 +44,7 @@ if (BUILD_GOOGLE_BENCH)
# Google Benchmark framework
download_project(PROJ benchmark
GIT_REPOSITORY https://github.com/google/benchmark.git
GIT_TAG master
GIT_TAG releasing
UPDATE_DISCONNECTED 1
QUIET
)
......@@ -64,17 +64,17 @@ add_custom_command(
endif()
#--------------------------------------------------------------------------------
# Non-Volatile Memory Library (pmem.io)
download_project(PROJ nvml
GIT_REPOSITORY https://github.com/pmem/nvml.git
# Peristent Memory Development Kit (pmem.io)
download_project(PROJ pmdk
GIT_REPOSITORY https://github.com/pmem/pmdk.git
GIT_TAG master
UPDATE_DISCONNECTED 1
QUIET
)
add_custom_command(
OUTPUT ${THIRD_PARTY_DIR}/nvml
COMMAND ${CMAKE_COMMAND} -E chdir ${nvml_SOURCE_DIR} $(MAKE)
COMMAND ${CMAKE_COMMAND} -E chdir ${nvml_SOURCE_DIR} $(MAKE) install prefix=${THIRD_PARTY_DIR}/nvml
OUTPUT ${THIRD_PARTY_DIR}/pmdk
COMMAND ${CMAKE_COMMAND} -E chdir ${pmdk_SOURCE_DIR} $(MAKE)
COMMAND ${CMAKE_COMMAND} -E chdir ${pmdk_SOURCE_DIR} $(MAKE) install prefix=${THIRD_PARTY_DIR}/pmdk
)
#--------------------------------------------------------------------------------
......
......@@ -3,15 +3,24 @@
# Define a macro to simplify building and linking test executables
#
#=============================================
macro( build_executable arg )
macro( build_test arg )
include_directories("${PROJECT_SOURCE_DIR}/test")
add_executable( ${arg} "${arg}.cpp" )
target_link_libraries( ${arg}
ptable
${NVML_LIBRARIES}
${BENCHMARK_LIB}
)
endmacro( build_executable )
add_executable( ${arg} "${arg}.cpp" $<TARGET_OBJECTS:MainTest>)
target_link_libraries( ${arg}
ptable
${PMDK_LIBRARIES}
${BENCHMARK_LIB}
)
endmacro( build_test )
macro( build_bench arg )
add_executable( ${arg} "${arg}.cpp")
target_link_libraries( ${arg}
ptable
${PMDK_LIBRARIES}
${BENCHMARK_LIB}
)
endmacro( build_bench )
#=============================================
#
......@@ -23,9 +32,17 @@ macro (do_test arg)
NAME ${arg}
COMMAND "${CMAKE_CURRENT_BINARY_DIR}/${arg}"
)
build_executable( ${arg} )
build_test( ${arg} )
endmacro(do_test)
macro (do_bench arg)
add_test(
NAME ${arg}
COMMAND "${CMAKE_CURRENT_BINARY_DIR}/${arg}"
)
build_bench( ${arg} )
endmacro(do_bench)
set (CTEST_ENVIRONMENT
"DYLD_FALLBACK_LIBRARY_PATH=${DYLD_LIBRARY_PATH}"
)
......@@ -39,7 +39,7 @@ else()
endif()
# C++ compiler flags
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -Wall -Wno-deprecated -g -O2 -Wsign-compare")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -Wall -g -O2 -Wsign-compare")
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-local-typedefs -Wno-#pragma-messages")
elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
......@@ -77,18 +77,18 @@ else()
endif()
########################
# Non-Volatile Memory Library
# Persistent Memory Development Kit
########################
#
set (NVML_LIBRARIES
"${THIRD_PARTY_DIR}/nvml/lib/libpmemblk.a"
"${THIRD_PARTY_DIR}/nvml/lib/libpmemlog.a"
"${THIRD_PARTY_DIR}/nvml/lib/libpmemobj.a"
"${THIRD_PARTY_DIR}/nvml/lib/libpmempool.a"
"${THIRD_PARTY_DIR}/nvml/lib/libpmem.a"
set (PMDK_LIBRARIES
"${THIRD_PARTY_DIR}/pmdk/lib/libpmemblk.a"
"${THIRD_PARTY_DIR}/pmdk/lib/libpmemlog.a"
"${THIRD_PARTY_DIR}/pmdk/lib/libpmemobj.a"
"${THIRD_PARTY_DIR}/pmdk/lib/libpmempool.a"
"${THIRD_PARTY_DIR}/pmdk/lib/libpmem.a"
${DYLIB_LIBRARY}
)
include_directories("${THIRD_PARTY_DIR}/nvml/include")
include_directories("${THIRD_PARTY_DIR}/pmdk/include")
include_directories("${THIRD_PARTY_DIR}/variant/include")
#-----------------------------------------------------------------------------------------
#
......@@ -104,10 +104,10 @@ include_directories(${PROJECT_SOURCE_DIR}
include_directories("${THIRD_PARTY_DIR}")
set(core_sources
core/PTableInfo.cpp
core/PTableInfo.cpp
${THIRD_PARTY_DIR}/fmt
${THIRD_PARTY_DIR}/catch
${THIRD_PARTY_DIR}/nvml
${THIRD_PARTY_DIR}/pmdk
${THIRD_PARTY_DIR}/variant
)
......@@ -119,7 +119,7 @@ if(BUILD_GOOGLE_BENCH)
endif()
add_library(ptable SHARED ${core_sources})
target_link_libraries(ptable ${NVML_LIBRARIES})
target_link_libraries(ptable ${PMDK_LIBRARIES})
#-----------------------------------------------------------------------------------------
......@@ -150,7 +150,8 @@ foreach(LIB ${PTABLE_LIBS})
install(TARGETS ${LIB} DESTINATION ${PTABLE_LIB_DIR})
endforeach(LIB)
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/"
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/core"
"${CMAKE_BINARY_DIR}/generated/"
"${THIRD_PARTY_DIR}/variant/include/mpark"
"${CMAKE_BINARY_DIR}/generated/"
DESTINATION ${PTABLE_INCLUDE_DIR}
......@@ -159,5 +160,10 @@ install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/"
PATTERN "*.h"
)
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/PBPTree.hpp"
"${CMAKE_CURRENT_SOURCE_DIR}/PTable.hpp"
DESTINATION ${PTABLE_INCLUDE_DIR}
)
# show used compiler
message("Using Compiler: ${CMAKE_CXX_COMPILER_ID}.")
......@@ -35,11 +35,11 @@
namespace ptable {
using nvml::obj::delete_persistent;
using nvml::obj::make_persistent;
using nvml::obj::p;
using nvml::obj::persistent_ptr;
using nvml::obj::transaction;
using pmem::obj::delete_persistent;
using pmem::obj::make_persistent;
using pmem::obj::p;
using pmem::obj::persistent_ptr;
using pmem::obj::transaction;
/**
* A persistent memory implementation of a B+ tree.
......@@ -61,7 +61,7 @@ class PBPTree {
#ifndef UNIT_TESTS
private:
#else
public:f
public:
#endif
// Forward declarations
......@@ -195,7 +195,7 @@ class PBPTree {
* @param val the value that is associated with the key
*/
void insert(const KeyType &key, const ValueType &val) {
auto pop = nvml::obj::pool_by_vptr(this);
auto pop = pmem::obj::pool_by_vptr(this);
transaction::exec_tx(pop, [&] {
SplitInfo splitInfo;
......@@ -321,6 +321,7 @@ class PBPTree {
// for each key-value pair within the range call func
for (auto i = 0u; i < leaf->numKeys; i++) {
auto &key = leaf->keys.get_ro()[i];
if (key < minKey) continue;
if (key > maxKey) return;
auto &val = leaf->values.get_ro()[i];
......@@ -1028,7 +1029,7 @@ class PBPTree {
* Create a new empty leaf node
*/
persistent_ptr<LeafNode> newLeafNode() {
auto pop = nvml::obj::pool_by_vptr(this);
auto pop = pmem::obj::pool_by_vptr(this);
persistent_ptr<LeafNode> newNode = nullptr;
transaction::exec_tx(pop, [&] {
newNode = make_persistent<LeafNode>();
......@@ -1037,7 +1038,7 @@ class PBPTree {
}
void deleteLeafNode(persistent_ptr<LeafNode> node) {
auto pop = nvml::obj::pool_by_vptr(this);
auto pop = pmem::obj::pool_by_vptr(this);
transaction::exec_tx(pop, [&] {
delete_persistent<LeafNode>(node);
});
......@@ -1047,7 +1048,7 @@ class PBPTree {
* Create a new empty branch node
*/
persistent_ptr<BranchNode> newBranchNode() {
auto pop = nvml::obj::pool_by_vptr(this);
auto pop = pmem::obj::pool_by_vptr(this);
persistent_ptr<BranchNode> newNode = nullptr;
transaction::exec_tx(pop, [&] {
newNode = make_persistent<BranchNode>();
......@@ -1056,7 +1057,7 @@ class PBPTree {
}
void deleteBranchNode(persistent_ptr<BranchNode> node) {
auto pop = nvml::obj::pool_by_vptr(this);
auto pop = pmem::obj::pool_by_vptr(this);
transaction::exec_tx(pop, [&] {
delete_persistent<BranchNode>(node);
});
......
This diff is collapsed.
include(../../cmake/Testing.cmake.in)
if (BUILD_BENCHMARKS)
do_test(scan)
do_test(point)
do_bench(insert)
do_bench(scan)
do_bench(point)
endif()
......@@ -24,18 +24,19 @@
#include <unistd.h>
#include "PTable.hpp"
using nvml::obj::make_persistent;
using nvml::obj::p;
using nvml::obj::persistent_ptr;
using nvml::obj::pool;
using nvml::obj::transaction;
using pmem::obj::make_persistent;
using pmem::obj::p;
using pmem::obj::persistent_ptr;
using pmem::obj::pool;
using pmem::obj::transaction;
using MyTuple = std::tuple<int, int, std::string, double>;
using PTableType = ptable::PTable<MyTuple, int>;
using MyKey = int;
using PTableType = ptable::PTable<MyKey, MyTuple>;
using Vector = std::vector<int>;
using VectorVector = std::vector<Vector>;
const int hibit(int n) noexcept;
const int hibit_pos(int n) noexcept;
template <size_t SIZE>
static inline VectorVector *createPointVector(VectorVector *v);
......@@ -45,10 +46,10 @@ struct root {
};
const std::string path = ptable::gPmemPath + "benchdb.db";
const auto NUM_TUPLES = 100 * 1000;
const auto POOL_SIZE = 1024 * 1024 * 256;
const auto NUM_TUPLES = 1000 * 100;
const auto POOL_SIZE = 1024 * 1024 * 256; // * 4ull; // 1GB
const auto ALIGNMENT = hibit(NUM_TUPLES) + 1;
const auto ALIGNMENT = hibit_pos(NUM_TUPLES) + 1;
VectorVector pv;
const auto POINT_ACCESS = *createPointVector<NUM_TUPLES>(&pv);
......@@ -58,30 +59,33 @@ const VectorVector KEY_RANGES = {
Vector{NUM_TUPLES / 2 - NUM_TUPLES / 200, NUM_TUPLES / 2 + NUM_TUPLES / 200}, // 1,0%
Vector{NUM_TUPLES / 2 - NUM_TUPLES / 40, NUM_TUPLES / 2 + NUM_TUPLES / 40}, // 5,0%
Vector{NUM_TUPLES / 2 - NUM_TUPLES / 20, NUM_TUPLES / 2 + NUM_TUPLES / 20}, // 10,0%
Vector{NUM_TUPLES / 2 - NUM_TUPLES / 10, NUM_TUPLES / 2 + NUM_TUPLES / 10}, // 20,0%
Vector{0, NUM_TUPLES-1} //100,0%
};
const VectorVector NON_KEY_RANGES = {
Vector{NUM_TUPLES / 2 - NUM_TUPLES / 1000, NUM_TUPLES / 2 + NUM_TUPLES / 1000,
NUM_TUPLES / 2, NUM_TUPLES / 2 + NUM_TUPLES / 500}, // 0,1%
NUM_TUPLES / 2, NUM_TUPLES / 2 + NUM_TUPLES / 500}, // 0,1%
Vector{NUM_TUPLES / 2 - NUM_TUPLES / 200, NUM_TUPLES / 2 + NUM_TUPLES / 200,
NUM_TUPLES / 2, NUM_TUPLES / 2 + NUM_TUPLES / 100}, // 0,5%
NUM_TUPLES / 2, NUM_TUPLES / 2 + NUM_TUPLES / 100}, // 0,5%
Vector{NUM_TUPLES / 2 - NUM_TUPLES / 100, NUM_TUPLES / 2 + NUM_TUPLES / 100,
NUM_TUPLES / 2, NUM_TUPLES / 2 + NUM_TUPLES / 50}, // 1,0%
NUM_TUPLES / 2, NUM_TUPLES / 2 + NUM_TUPLES / 50}, // 1,0%
Vector{NUM_TUPLES / 2 - NUM_TUPLES / 20, NUM_TUPLES / 2 + NUM_TUPLES / 20,
NUM_TUPLES / 2, NUM_TUPLES / 2 + NUM_TUPLES / 10}, // 5,0%
NUM_TUPLES / 2, NUM_TUPLES / 2 + NUM_TUPLES / 10}, // 5,0%
Vector{NUM_TUPLES / 2 - NUM_TUPLES / 10, NUM_TUPLES / 2 + NUM_TUPLES / 10,
NUM_TUPLES / 2, NUM_TUPLES / 2 + NUM_TUPLES / 5}, // 10,0%
NUM_TUPLES / 2, NUM_TUPLES / 2 + NUM_TUPLES / 5}, // 10,0%
Vector{NUM_TUPLES / 2 - NUM_TUPLES / 5, NUM_TUPLES / 2 + NUM_TUPLES / 5,
NUM_TUPLES / 2, NUM_TUPLES / 2 + NUM_TUPLES * 2 / 5 }, // 20,0%
Vector{0, NUM_TUPLES - 1, 0, NUM_TUPLES - 1} //100,0%
};
const int hibit(int n) noexcept {
n |= (n >> 1);
n |= (n >> 2);
n |= (n >> 4);
n |= (n >> 8);
n |= (n >> 16);
return n - (n >> 1);
const int hibit_pos(int n) noexcept {
int c = 0;
while (n>>1 != 0) {
c++;
n>>=1;
}
return c;
}
template<size_t SIZE>
......@@ -100,15 +104,10 @@ void insert (pool<root> &pop, const std::string &path, size_t entries) {
pop = pool<root>::create(path, LAYOUT, POOL_SIZE);
transaction::exec_tx(pop, [&] {
const auto tInfo = ptable::VTableInfo("MyTable", {
{"a", Int_Type},
{"b", Int_Type},
{"c", String_Type},
{"d", Double_Type}
}, Int_Type);
const auto tInfo = ptable::VTableInfo<MyKey, MyTuple>("MyTable", {"a","b","c","d"});
const auto dims = Dimensions({
{0, {10, ALIGNMENT}},
{3, {10, ALIGNMENT}}
{0, 10, ALIGNMENT},
{3, 10, ALIGNMENT}
});
pop.get_root()->pTable = make_persistent<PTableType>(tInfo, dims);
});
......@@ -118,9 +117,13 @@ void insert (pool<root> &pop, const std::string &path, size_t entries) {
for (auto i = 0u; i < entries; i++) {
auto tup = MyTuple(i + 1,
(i + 1) * 100,
fmt::format("String #{0}", i),
fmt::format("String #{0}", i % 1000),
(i + 1) * 1.0);
start = std::chrono::high_resolution_clock::now();
if (i % (entries/100) == 0) {
std::cout << "Inserting tuple: " << (i+1)*100/entries << "%\r";
std::cout.flush();
}
pTable->insert(i + 1, tup);
end = std::chrono::high_resolution_clock::now();
auto diff = std::chrono::duration_cast<std::chrono::microseconds>(end - start).count();
......
/*
* Copyright (C) 2017 DBIS Group - TU Ilmenau, All Rights Reserved.
*
* This file is part of PTable.
*
* PTable 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.
*
* PTable 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 PTable. If not, see <http://www.gnu.org/licenses/>.
*/
#include <unistd.h>
#include "fmt/format.h"
#include "common.h"
using namespace ptable;
int main() {
pool<root> pop;
std::remove(path.c_str());
if (access(path.c_str(), F_OK) != 0) {
insert(pop, path, NUM_TUPLES);
} else {
std::cerr << "Table already exists" << std::endl;
}
auto pTable = pop.get_root()->pTable;
pop.close();
}
\ No newline at end of file
......@@ -30,12 +30,11 @@ static void BM_PointQuery(benchmark::State& state) {
const std::string path = ptable::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(1));
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);
}
......@@ -43,7 +42,7 @@ static void BM_PointQuery(benchmark::State& state) {
for (auto _ : state) {
auto ptp = pTable->getByKey(state.range(1));
if (ptp.getNode() != nullptr) ptp.createTuple();
if (ptp.getNode() != nullptr) ptp;// ptp.createTuple();
else std::cerr << "key not found" << '\n';
}
pop.close();
......
......@@ -79,6 +79,29 @@ static void NonKeyRangeArguments(benchmark::internal::Benchmark* b) {
}
BENCHMARK(BM_NonKeyRangeScan)->Apply(NonKeyRangeArguments);
static void BM_PBPTreeKeyScan(benchmark::State &state) {
pool<root> pop;
if (access(path.c_str(), F_OK) != 0) {
insert(pop, path, NUM_TUPLES);
} else {
PLOG("Warning: " << path << " already exists");
pop = pool<root>::open(path, LAYOUT);
}
auto pTable = pop.get_root()->pTable;
for (auto _ : state) {
/* Scan via Index scan */
pTable->rangeScan2(state.range(0), state.range(1), [](int k, const PTuple<int, MyTuple> tp){tp;});
}
pop.close();
//std::remove(path.c_str());
}
BENCHMARK(BM_PBPTreeKeyScan)->Apply(KeyRangeArguments);
static void BM_PBPTreeScan(benchmark::State &state) {
pool<root> pop;
......@@ -96,18 +119,20 @@ static void BM_PBPTreeScan(benchmark::State &state) {
/* Scan via PTuple iterator */
auto eIter = pTable->end();
auto iter = pTable->select(
[](const PTuple<MyTuple, int> &tp) {
return (tp.get<0>() >= KEY_RANGES[0][0]) && (tp.get<0>() <= KEY_RANGES[0][0]);
[&](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).get<0>();
iter;
//(*iter).get<0>();
}
}
pop.close();
std::remove(path.c_str());
//std::remove(path.c_str());
}
BENCHMARK(BM_PBPTreeScan);
BENCHMARK(BM_PBPTreeScan)->Apply(NonKeyRangeArguments);
BENCHMARK_MAIN();
......@@ -20,6 +20,7 @@
#ifndef BDCCInfo_hpp_
#define BDCCInfo_hpp_
#include <bitset>
#include <map>
#include <numeric>
......@@ -30,16 +31,15 @@
namespace ptable {
using nvml::obj::allocator;
using nvml::obj::p;
using pmem::obj::allocator;
using pmem::obj::p;
/**************************************************************************//**
* \brief This type is used for defining the dimensions for the table.
*
* key: Column ID
* value: <number of BDCC bits , bit alignment when applying mask on value>
* entry: <ColumnID, number of BDCC bits , bit alignment when applying mask on value>
*****************************************************************************/
using Dimensions = std::map<uint16_t, std::pair<uint16_t, uint16_t>>;
using Dimensions = std::vector<std::tuple<uint16_t, uint16_t, uint16_t>>;
/**************************************************************************//**
* \brief Info structure about the BDCC meta data.
......@@ -63,7 +63,7 @@ class BDCCInfo {
explicit BDCCInfo(const Dimensions &_bitMap) :
numberOfBins(std::accumulate(_bitMap.begin(), _bitMap.end(), 0,
[](const size_t sum, decltype(*_bitMap.begin()) p) {
return sum + p.second.first;
return sum + std::get<1>(p);
})),
dimensions() { deriveMasks(_bitMap); }
......@@ -77,7 +77,7 @@ class BDCCInfo {
void deriveMasks(Dimensions dims) {
/* Initialize */
for (const auto &dim: dims) {
dimensions.get_rw().emplace_back(dim.first, dim.second.first, std::bitset<32>(), dim.second.second);
dimensions.get_rw().emplace_back(std::get<0>(dim), std::get<1>(dim), std::bitset<32>(), std::get<2>(dim));
}
/* Round robin the bins for mapping */
......@@ -85,10 +85,11 @@ class BDCCInfo {
while (bdccSize > 0) {
auto i = 0ul;
for (auto &dim: dims) {
if (dim.second.first > 0) {
--dim.second.first;
std::get<2>(dimensions.get_rw()[i++])[--bdccSize] = 1;
if (std::get<1>(dim) > 0) {
--std::get<1>(dim);
std::get<2>(dimensions.get_rw()[i])[--bdccSize] = 1;
}
++i;
}
}
}
......
......@@ -22,16 +22,17 @@
#include <array>
#include <unordered_map>
#include <vector>
#include "config.h"
#include <libpmemobj++/make_persistent.hpp>
#include <libpmemobj++/allocator.hpp>
#include <libpmemobj++/persistent_ptr.hpp>
namespace ptable {
using nvml::obj::persistent_ptr;
using nvml::obj::make_persistent;
using nvml::obj::delete_persistent;
using pmem::obj::allocator;
using pmem::obj::p;
using pmem::obj::persistent_ptr;
/** Positions in NVM_Block */
constexpr int gBDCCRangePos1 = 0;
......@@ -48,7 +49,7 @@ constexpr int gAttrOffsetSize = 4;
constexpr int gOffsetSize = 2;
/** The size of a single block in persistent memory */
static constexpr std::size_t gBlockSize = 1 << 12; // 12->4KB, 15->32KB, max 16 due to data types
static constexpr std::size_t gBlockSize = 1 << 15; // 12->4KB, 15->32KB, max 16 due to data types
/**
* \brief This type represents a byte array used for persistent structures.
......@@ -81,20 +82,21 @@ using BDCC_Block = typename std::array<uint8_t, gBlockSize>;
template<typename KeyType>
struct DataNode {
using DeletedVector = std::vector<uint16_t, allocator<uint16_t>>;
using KeyVector = std::array<KeyType, 8192>;
using HistogramType = std::unordered_map<uint32_t,
std::size_t,
std::hash<uint32_t>,
std::equal_to<uint32_t>,
nvml::obj::allocator<uint32_t>>;
allocator<uint32_t>>;
DataNode() : next(nullptr) {}
DataNode(BDCC_Block _block) : next(nullptr), block(_block) {}
persistent_ptr<struct DataNode> next;
persistent_ptr<DataNode> next;
p<BDCC_Block> block;
p<KeyVector> keys;
p<DeletedVector> deleted;
p<HistogramType> histogram;
const uint32_t calcAverageBDCC() const {
......@@ -104,14 +106,6 @@ struct DataNode {
}
return sum / reinterpret_cast<const uint32_t &>(block.get_ro()[gCountPos]);
}
void clear() {
if (next) {
//delete_persistent<struct DataNode>(next);
next = nullptr;
}
delete_persistent<struct DataNode>(this);
}
};
} /* end namespace ptable */
......
......@@ -6,13 +6,12 @@ Taken from: https://pmem.io/2017/01/23/cpp-strings.html
#define PString_hpp_
#include <libpmemobj/tx_base.h>
#include <libpmemobj++/make_persistent.hpp>
#include <libpmemobj++/make_persistent_array.hpp>
#include <libpmemobj++/persistent_ptr.hpp>
using nvml::obj::delete_persistent;
using nvml::obj::make_persistent;
using nvml::obj::persistent_ptr;
using pmem::obj::delete_persistent;
using pmem::obj::make_persistent;
using pmem::obj::persistent_ptr;
namespace ptable {
......
......@@ -19,13 +19,15 @@
#include "PTableInfo.hpp"
#include <sstream>
using namespace ptable;