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

Switched to PMDK (former NVML) +++ Added some switch-case alternatives +++...

Switched to PMDK (former NVML) +++ Added some switch-case alternatives +++ moved KeyType before TupleType for consistency +++ Some fixes
parent 20d943c3
...@@ -5,17 +5,18 @@ A persistent analytical table structure for non-volatile memory. ...@@ -5,17 +5,18 @@ A persistent analytical table structure for non-volatile memory.
Please see the file [COPYING](COPYING) for license information. Please see the file [COPYING](COPYING) for license information.
### TODOs: ### TODOs:
- [ ] Tests - [x] Tests
- [ ] Get rid of expensive transactions - [ ] Get rid of expensive transactions
- [x] Improve benchmarks - [x] Improve benchmarks
- [ ] Describe usage - [ ] Describe usage
- [ ] The BlockIterator currently suffers from bugs (SEGSIGV with too big structures)
### Installation ### ### 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 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 either included or downloaded during the build process. 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: After cloning and switching into the project directory, you can build the repository with with:
``` ```
...@@ -29,4 +30,7 @@ make test ...@@ -29,4 +30,7 @@ make test
### Usage ### ### 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) ...@@ -44,7 +44,7 @@ if (BUILD_GOOGLE_BENCH)
# Google Benchmark framework # Google Benchmark framework
download_project(PROJ benchmark download_project(PROJ benchmark
GIT_REPOSITORY https://github.com/google/benchmark.git GIT_REPOSITORY https://github.com/google/benchmark.git
GIT_TAG master GIT_TAG releasing
UPDATE_DISCONNECTED 1 UPDATE_DISCONNECTED 1
QUIET QUIET
) )
...@@ -64,17 +64,17 @@ add_custom_command( ...@@ -64,17 +64,17 @@ add_custom_command(
endif() endif()
#-------------------------------------------------------------------------------- #--------------------------------------------------------------------------------
# Non-Volatile Memory Library (pmem.io) # Peristent Memory Development Kit (pmem.io)
download_project(PROJ nvml download_project(PROJ pmdk
GIT_REPOSITORY https://github.com/pmem/nvml.git GIT_REPOSITORY https://github.com/pmem/pmdk.git
GIT_TAG 1.3.1-rc2 GIT_TAG master
UPDATE_DISCONNECTED 1 UPDATE_DISCONNECTED 1
QUIET QUIET
) )
add_custom_command( add_custom_command(
OUTPUT ${THIRD_PARTY_DIR}/nvml OUTPUT ${THIRD_PARTY_DIR}/pmdk
COMMAND ${CMAKE_COMMAND} -E chdir ${nvml_SOURCE_DIR} $(MAKE) COMMAND ${CMAKE_COMMAND} -E chdir ${pmdk_SOURCE_DIR} $(MAKE)
COMMAND ${CMAKE_COMMAND} -E chdir ${nvml_SOURCE_DIR} $(MAKE) install prefix=${THIRD_PARTY_DIR}/nvml COMMAND ${CMAKE_COMMAND} -E chdir ${pmdk_SOURCE_DIR} $(MAKE) install prefix=${THIRD_PARTY_DIR}/pmdk
) )
#-------------------------------------------------------------------------------- #--------------------------------------------------------------------------------
......
...@@ -8,7 +8,7 @@ macro( build_test arg ) ...@@ -8,7 +8,7 @@ macro( build_test arg )
add_executable( ${arg} "${arg}.cpp" $<TARGET_OBJECTS:MainTest>) add_executable( ${arg} "${arg}.cpp" $<TARGET_OBJECTS:MainTest>)
target_link_libraries( ${arg} target_link_libraries( ${arg}
ptable ptable
${NVML_LIBRARIES} ${PMDK_LIBRARIES}
${BENCHMARK_LIB} ${BENCHMARK_LIB}
) )
endmacro( build_test ) endmacro( build_test )
...@@ -17,7 +17,7 @@ macro( build_bench arg ) ...@@ -17,7 +17,7 @@ macro( build_bench arg )
add_executable( ${arg} "${arg}.cpp") add_executable( ${arg} "${arg}.cpp")
target_link_libraries( ${arg} target_link_libraries( ${arg}
ptable ptable
${NVML_LIBRARIES} ${PMDK_LIBRARIES}
${BENCHMARK_LIB} ${BENCHMARK_LIB}
) )
endmacro( build_bench ) endmacro( build_bench )
......
...@@ -21,7 +21,7 @@ set(PMEM_MNT_PATH "/mnt/pmem/test") ...@@ -21,7 +21,7 @@ set(PMEM_MNT_PATH "/mnt/pmem/test")
option(ENABLE_LOG "enables log output for e.g. debugging" OFF) option(ENABLE_LOG "enables log output for e.g. debugging" OFF)
option(BUILD_TEST_CASES "build tests for PTable functionality" ON ) option(BUILD_TEST_CASES "build tests for PTable functionality" ON )
option(BUILD_GOOGLE_BENCH "build google benchmark" OFF) option(BUILD_GOOGLE_BENCH "build google benchmark" OFF)
option(BUILD_BENCHMARKS "build benchmarks for Ptable" OFF) option(BUILD_BENCHMARKS "build benchmarks for Ptable" ON )
################################################################################ ################################################################################
# End of customization section # # End of customization section #
...@@ -77,18 +77,18 @@ else() ...@@ -77,18 +77,18 @@ else()
endif() endif()
######################## ########################
# Non-Volatile Memory Library # Persistent Memory Development Kit
######################## ########################
# #
set (NVML_LIBRARIES set (PMDK_LIBRARIES
"${THIRD_PARTY_DIR}/nvml/lib/libpmemblk.a" "${THIRD_PARTY_DIR}/pmdk/lib/libpmemblk.a"
"${THIRD_PARTY_DIR}/nvml/lib/libpmemlog.a" "${THIRD_PARTY_DIR}/pmdk/lib/libpmemlog.a"
"${THIRD_PARTY_DIR}/nvml/lib/libpmemobj.a" "${THIRD_PARTY_DIR}/pmdk/lib/libpmemobj.a"
"${THIRD_PARTY_DIR}/nvml/lib/libpmempool.a" "${THIRD_PARTY_DIR}/pmdk/lib/libpmempool.a"
"${THIRD_PARTY_DIR}/nvml/lib/libpmem.a" "${THIRD_PARTY_DIR}/pmdk/lib/libpmem.a"
${DYLIB_LIBRARY} ${DYLIB_LIBRARY}
) )
include_directories("${THIRD_PARTY_DIR}/nvml/include") include_directories("${THIRD_PARTY_DIR}/pmdk/include")
include_directories("${THIRD_PARTY_DIR}/variant/include") include_directories("${THIRD_PARTY_DIR}/variant/include")
#----------------------------------------------------------------------------------------- #-----------------------------------------------------------------------------------------
# #
...@@ -107,7 +107,7 @@ set(core_sources ...@@ -107,7 +107,7 @@ set(core_sources
core/PTableInfo.cpp core/PTableInfo.cpp
${THIRD_PARTY_DIR}/fmt ${THIRD_PARTY_DIR}/fmt
${THIRD_PARTY_DIR}/catch ${THIRD_PARTY_DIR}/catch
${THIRD_PARTY_DIR}/nvml ${THIRD_PARTY_DIR}/pmdk
${THIRD_PARTY_DIR}/variant ${THIRD_PARTY_DIR}/variant
) )
......
...@@ -35,11 +35,11 @@ ...@@ -35,11 +35,11 @@
namespace ptable { namespace ptable {
using nvml::obj::delete_persistent; using pmem::obj::delete_persistent;
using nvml::obj::make_persistent; using pmem::obj::make_persistent;
using nvml::obj::p; using pmem::obj::p;
using nvml::obj::persistent_ptr; using pmem::obj::persistent_ptr;
using nvml::obj::transaction; using pmem::obj::transaction;
/** /**
* A persistent memory implementation of a B+ tree. * A persistent memory implementation of a B+ tree.
...@@ -195,7 +195,7 @@ class PBPTree { ...@@ -195,7 +195,7 @@ class PBPTree {
* @param val the value that is associated with the key * @param val the value that is associated with the key
*/ */
void insert(const KeyType &key, const ValueType &val) { 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, [&] { transaction::exec_tx(pop, [&] {
SplitInfo splitInfo; SplitInfo splitInfo;
...@@ -321,6 +321,7 @@ class PBPTree { ...@@ -321,6 +321,7 @@ class PBPTree {
// for each key-value pair within the range call func // for each key-value pair within the range call func
for (auto i = 0u; i < leaf->numKeys; i++) { for (auto i = 0u; i < leaf->numKeys; i++) {
auto &key = leaf->keys.get_ro()[i]; auto &key = leaf->keys.get_ro()[i];
if (key < minKey) continue;
if (key > maxKey) return; if (key > maxKey) return;
auto &val = leaf->values.get_ro()[i]; auto &val = leaf->values.get_ro()[i];
...@@ -1028,7 +1029,7 @@ class PBPTree { ...@@ -1028,7 +1029,7 @@ class PBPTree {
* Create a new empty leaf node * Create a new empty leaf node
*/ */
persistent_ptr<LeafNode> newLeafNode() { 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; persistent_ptr<LeafNode> newNode = nullptr;
transaction::exec_tx(pop, [&] { transaction::exec_tx(pop, [&] {
newNode = make_persistent<LeafNode>(); newNode = make_persistent<LeafNode>();
...@@ -1037,7 +1038,7 @@ class PBPTree { ...@@ -1037,7 +1038,7 @@ class PBPTree {
} }
void deleteLeafNode(persistent_ptr<LeafNode> node) { 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, [&] { transaction::exec_tx(pop, [&] {
delete_persistent<LeafNode>(node); delete_persistent<LeafNode>(node);
}); });
...@@ -1047,7 +1048,7 @@ class PBPTree { ...@@ -1047,7 +1048,7 @@ class PBPTree {
* Create a new empty branch node * Create a new empty branch node
*/ */
persistent_ptr<BranchNode> newBranchNode() { 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; persistent_ptr<BranchNode> newNode = nullptr;
transaction::exec_tx(pop, [&] { transaction::exec_tx(pop, [&] {
newNode = make_persistent<BranchNode>(); newNode = make_persistent<BranchNode>();
...@@ -1056,7 +1057,7 @@ class PBPTree { ...@@ -1056,7 +1057,7 @@ class PBPTree {
} }
void deleteBranchNode(persistent_ptr<BranchNode> node) { 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, [&] { transaction::exec_tx(pop, [&] {
delete_persistent<BranchNode>(node); delete_persistent<BranchNode>(node);
}); });
......
This diff is collapsed.
...@@ -24,14 +24,15 @@ ...@@ -24,14 +24,15 @@
#include <unistd.h> #include <unistd.h>
#include "PTable.hpp" #include "PTable.hpp"
using nvml::obj::make_persistent; using pmem::obj::make_persistent;
using nvml::obj::p; using pmem::obj::p;
using nvml::obj::persistent_ptr; using pmem::obj::persistent_ptr;
using nvml::obj::pool; using pmem::obj::pool;
using nvml::obj::transaction; using pmem::obj::transaction;
using MyTuple = std::tuple<int, int, std::string, double>; 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 Vector = std::vector<int>;
using VectorVector = std::vector<Vector>; using VectorVector = std::vector<Vector>;
...@@ -45,8 +46,8 @@ struct root { ...@@ -45,8 +46,8 @@ struct root {
}; };
const std::string path = ptable::gPmemPath + "benchdb.db"; const std::string path = ptable::gPmemPath + "benchdb.db";
const auto NUM_TUPLES = 100 * 1000; const auto NUM_TUPLES = 1000 * 1000;
const auto POOL_SIZE = 1024 * 1024 * 256; const auto POOL_SIZE = 1024 * 1024 * 1024 * 1ull; // 1GB
const auto ALIGNMENT = hibit(NUM_TUPLES) + 1; const auto ALIGNMENT = hibit(NUM_TUPLES) + 1;
VectorVector pv; VectorVector pv;
...@@ -100,12 +101,7 @@ void insert (pool<root> &pop, const std::string &path, size_t entries) { ...@@ -100,12 +101,7 @@ void insert (pool<root> &pop, const std::string &path, size_t entries) {
pop = pool<root>::create(path, LAYOUT, POOL_SIZE); pop = pool<root>::create(path, LAYOUT, POOL_SIZE);
transaction::exec_tx(pop, [&] { transaction::exec_tx(pop, [&] {
const auto tInfo = ptable::VTableInfo("MyTable", { const auto tInfo = ptable::VTableInfo<MyKey, MyTuple>("MyTable", {"a","b","c","d"});
{"a", Int_Type},
{"b", Int_Type},
{"c", String_Type},
{"d", Double_Type}
}, Int_Type);
const auto dims = Dimensions({ const auto dims = Dimensions({
{0, 10, ALIGNMENT}, {0, 10, ALIGNMENT},
{3, 10, ALIGNMENT} {3, 10, ALIGNMENT}
...@@ -118,9 +114,13 @@ void insert (pool<root> &pop, const std::string &path, size_t entries) { ...@@ -118,9 +114,13 @@ void insert (pool<root> &pop, const std::string &path, size_t entries) {
for (auto i = 0u; i < entries; i++) { for (auto i = 0u; i < entries; i++) {
auto tup = MyTuple(i + 1, auto tup = MyTuple(i + 1,
(i + 1) * 100, (i + 1) * 100,
fmt::format("String #{0}", i), fmt::format("String #{0}", i % 1000),
(i + 1) * 1.0); (i + 1) * 1.0);
start = std::chrono::high_resolution_clock::now(); 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); pTable->insert(i + 1, tup);
end = std::chrono::high_resolution_clock::now(); end = std::chrono::high_resolution_clock::now();
auto diff = std::chrono::duration_cast<std::chrono::microseconds>(end - start).count(); auto diff = std::chrono::duration_cast<std::chrono::microseconds>(end - start).count();
......
...@@ -43,7 +43,7 @@ static void BM_PointQuery(benchmark::State& state) { ...@@ -43,7 +43,7 @@ static void BM_PointQuery(benchmark::State& state) {
for (auto _ : state) { for (auto _ : state) {
auto ptp = pTable->getByKey(state.range(1)); 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'; else std::cerr << "key not found" << '\n';
} }
pop.close(); pop.close();
......
...@@ -49,7 +49,7 @@ static void BM_RangeScan(benchmark::State &state) { ...@@ -49,7 +49,7 @@ static void BM_RangeScan(benchmark::State &state) {
static void KeyRangeArguments(benchmark::internal::Benchmark* b) { static void KeyRangeArguments(benchmark::internal::Benchmark* b) {
for (const auto &arg : KEY_RANGES) b->Args(arg); for (const auto &arg : KEY_RANGES) b->Args(arg);
} }
BENCHMARK(BM_RangeScan)->Apply(KeyRangeArguments); //BENCHMARK(BM_RangeScan)->Apply(KeyRangeArguments);
static void BM_NonKeyRangeScan(benchmark::State &state) { static void BM_NonKeyRangeScan(benchmark::State &state) {
...@@ -77,7 +77,30 @@ static void BM_NonKeyRangeScan(benchmark::State &state) { ...@@ -77,7 +77,30 @@ static void BM_NonKeyRangeScan(benchmark::State &state) {
static void NonKeyRangeArguments(benchmark::internal::Benchmark* b) { static void NonKeyRangeArguments(benchmark::internal::Benchmark* b) {
for (const auto &arg : NON_KEY_RANGES) b->Args(arg); for (const auto &arg : NON_KEY_RANGES) b->Args(arg);
} }
BENCHMARK(BM_NonKeyRangeScan)->Apply(NonKeyRangeArguments); //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) { static void BM_PBPTreeScan(benchmark::State &state) {
...@@ -96,18 +119,20 @@ static void BM_PBPTreeScan(benchmark::State &state) { ...@@ -96,18 +119,20 @@ static void BM_PBPTreeScan(benchmark::State &state) {
/* Scan via PTuple iterator */ /* Scan via PTuple iterator */
auto eIter = pTable->end(); auto eIter = pTable->end();
auto iter = pTable->select( auto iter = pTable->select(
[](const PTuple<MyTuple, int> &tp) { [&](const PTuple<int, MyTuple> &tp) {
return (tp.get<0>() >= KEY_RANGES[0][0]) && (tp.get<0>() <= KEY_RANGES[0][0]); 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++) { for (; iter != eIter; iter++) {
(*iter).get<0>(); iter;
//(*iter).get<0>();
} }
} }
pop.close(); pop.close();
std::remove(path.c_str()); //std::remove(path.c_str());
} }
BENCHMARK(BM_PBPTreeScan); BENCHMARK(BM_PBPTreeScan)->Apply(NonKeyRangeArguments);
BENCHMARK_MAIN(); BENCHMARK_MAIN();
...@@ -31,8 +31,8 @@ ...@@ -31,8 +31,8 @@
namespace ptable { namespace ptable {
using nvml::obj::allocator; using pmem::obj::allocator;
using nvml::obj::p; using pmem::obj::p;
/**************************************************************************//** /**************************************************************************//**
* \brief This type is used for defining the dimensions for the table. * \brief This type is used for defining the dimensions for the table.
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include <array> #include <array>
#include <unordered_map> #include <unordered_map>
#include <vector>
#include "config.h" #include "config.h"
#include <libpmemobj++/allocator.hpp> #include <libpmemobj++/allocator.hpp>
...@@ -29,9 +30,9 @@ ...@@ -29,9 +30,9 @@
namespace ptable { namespace ptable {
using nvml::obj::allocator; using pmem::obj::allocator;
using nvml::obj::p; using pmem::obj::p;
using nvml::obj::persistent_ptr; using pmem::obj::persistent_ptr;
/** Positions in NVM_Block */ /** Positions in NVM_Block */
constexpr int gBDCCRangePos1 = 0; constexpr int gBDCCRangePos1 = 0;
...@@ -48,7 +49,7 @@ constexpr int gAttrOffsetSize = 4; ...@@ -48,7 +49,7 @@ constexpr int gAttrOffsetSize = 4;
constexpr int gOffsetSize = 2; constexpr int gOffsetSize = 2;
/** The size of a single block in persistent memory */ /** 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. * \brief This type represents a byte array used for persistent structures.
...@@ -92,7 +93,7 @@ struct DataNode { ...@@ -92,7 +93,7 @@ struct DataNode {
DataNode() : next(nullptr) {} DataNode() : next(nullptr) {}
DataNode(BDCC_Block _block) : next(nullptr), block(_block) {} DataNode(BDCC_Block _block) : next(nullptr), block(_block) {}
persistent_ptr<struct DataNode> next; persistent_ptr<DataNode> next;
p<BDCC_Block> block; p<BDCC_Block> block;
p<KeyVector> keys; p<KeyVector> keys;
p<DeletedVector> deleted; p<DeletedVector> deleted;
......
...@@ -6,13 +6,12 @@ Taken from: https://pmem.io/2017/01/23/cpp-strings.html ...@@ -6,13 +6,12 @@ Taken from: https://pmem.io/2017/01/23/cpp-strings.html
#define PString_hpp_ #define PString_hpp_
#include <libpmemobj/tx_base.h> #include <libpmemobj/tx_base.h>
#include <libpmemobj++/make_persistent.hpp>
#include <libpmemobj++/make_persistent_array.hpp> #include <libpmemobj++/make_persistent_array.hpp>
#include <libpmemobj++/persistent_ptr.hpp> #include <libpmemobj++/persistent_ptr.hpp>
using nvml::obj::delete_persistent; using pmem::obj::delete_persistent;
using nvml::obj::make_persistent; using pmem::obj::make_persistent;
using nvml::obj::persistent_ptr; using pmem::obj::persistent_ptr;
namespace ptable { namespace ptable {
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
using namespace ptable; using namespace ptable;
PColumnInfo::PColumnInfo(pool_base pop) : PColumnInfo(pop, "", Void_Type) {}; PColumnInfo::PColumnInfo(pool_base pop) : PColumnInfo(pop, "", ColumnType::VoidType) {};
PColumnInfo::PColumnInfo(pool_base pop, Column col) : PColumnInfo(pop, col.first, col.second) {}; PColumnInfo::PColumnInfo(pool_base pop, Column col) : PColumnInfo(pop, col.first, col.second) {};
...@@ -30,42 +30,4 @@ PColumnInfo::PColumnInfo(pool_base pop, const std::string &n, ColumnType ct) : t ...@@ -30,42 +30,4 @@ PColumnInfo::PColumnInfo(pool_base pop, const std::string &n, ColumnType ct) : t
name = make_persistent<char[]>(n.length() + 1); name = make_persistent<char[]>(n.length() + 1);
strcpy(name.get(), n.c_str()); strcpy(name.get(), n.c_str());
}); });
}
PTableInfo::PTableInfo(const VTableInfo &_tInfo, ColumnType _keyType) : keyType(_keyType) {
auto pop = pool_by_vptr(this);
transaction::exec_tx(pop, [&] {
name.set(const_cast<std::string *>(&_tInfo.name));
columns = make_persistent<PColumnVector>();
for (const auto &c : _tInfo)
columns->push_back(PColumnInfo(pop, c.first, c.second));
});
}
PTableInfo::PTableInfo(const std::string &_name, ColumnInitList _columns, ColumnType _keyType) :
keyType(_keyType) {
auto pop = pool_by_vptr(this);
transaction::exec_tx(pop, [&] {
name.set(const_cast<std::string *>(&_name));
columns = make_persistent<PColumnVector>();
for (const auto &c : _columns)
columns->push_back(PColumnInfo(pop, c.first, c.second));
});
}
void PTableInfo::setColumns(const ColumnVector vec) {
auto pop = pool_by_vptr(this);
transaction::exec_tx(pop, [&] {
delete_persistent<PColumnVector>(columns);
columns = make_persistent<PColumnVector>();
for (const auto &c : vec)
columns->push_back(PColumnInfo(pop, c.first, c.second));
});
}