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

Adapted TableInfo and improved benchmarks a bit

parent 3717f05d
...@@ -7,10 +7,10 @@ Please see the file [COPYING](COPYING) for license information. ...@@ -7,10 +7,10 @@ Please see the file [COPYING](COPYING) for license information.
### TODOs: ### TODOs:
- [ ] Tests - [ ] Tests
- [ ] Get rid of expensive transactions - [ ] Get rid of expensive transactions
- [ ] Improve benchmarks - [x] Improve benchmarks
- [ ] Describe usage
### Installation ### ### Installation ###
For emulating a persistent memory device and further information see [http://pmem.io](http://pmem.io/2016/02/22/pm-emulation.html).
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++17 standard, thus, you need a very recent C++ compiler and CMake (3.2 or newer) build environment.
...@@ -29,4 +29,4 @@ make test ...@@ -29,4 +29,4 @@ make test
### Usage ### ### Usage ###
TODO 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).
...@@ -43,7 +43,7 @@ if (BUILD_BENCHMARKS) ...@@ -43,7 +43,7 @@ if (BUILD_BENCHMARKS)
endif() endif()
# C++ compiler flags # C++ compiler flags
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 -Wall -Wno-deprecated -g -O0 -Wsign-compare") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 -Wall -Wno-deprecated -g -O2 -Wsign-compare")
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-local-typedefs -Wno-#pragma-messages") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-local-typedefs -Wno-#pragma-messages")
elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
...@@ -108,7 +108,6 @@ include_directories("${PROJECT_SOURCE_DIR}") ...@@ -108,7 +108,6 @@ include_directories("${PROJECT_SOURCE_DIR}")
include_directories("${THIRD_PARTY_DIR}") include_directories("${THIRD_PARTY_DIR}")
set(core_sources set(core_sources
core/TableInfo.cpp
core/PTableInfo.cpp core/PTableInfo.cpp
${THIRD_PARTY_DIR}/fmt ${THIRD_PARTY_DIR}/fmt
${THIRD_PARTY_DIR}/catch ${THIRD_PARTY_DIR}/catch
......
...@@ -54,7 +54,8 @@ using ColumnRangeMap = std::unordered_map<uint16_t, std::pair<IntDoubleString, I ...@@ -54,7 +54,8 @@ using ColumnRangeMap = std::unordered_map<uint16_t, std::pair<IntDoubleString, I
template<class Tuple, typename KeyType> template<class Tuple, typename KeyType>
class PTable { class PTable {
static const auto BRANCHKEYS = ((TARGET_INDEX_NODE_SIZE - 28) / (sizeof(KeyType) + 24)) & ~1; static const auto BRANCHKEYS = ((TARGET_INDEX_NODE_SIZE - 28) / (sizeof(KeyType) + 24)) & ~1;
static const auto LEAFKEYS = ((TARGET_INDEX_NODE_SIZE - 36) / (sizeof(KeyType) + sizeof(PTuple<Tuple, KeyType>))) & ~1; static const auto
LEAFKEYS = ((TARGET_INDEX_NODE_SIZE - 36) / (sizeof(KeyType) + sizeof(PTuple<Tuple, KeyType>))) & ~1;
using ColumnIntMap = std::map<uint16_t, uint16_t>; using ColumnIntMap = std::map<uint16_t, uint16_t>;
using IndexType = PBPTree<KeyType, PTuple<Tuple, KeyType>, BRANCHKEYS, LEAFKEYS>; using IndexType = PBPTree<KeyType, PTuple<Tuple, KeyType>, BRANCHKEYS, LEAFKEYS>;
...@@ -155,15 +156,15 @@ class PTable { ...@@ -155,15 +156,15 @@ class PTable {
reinterpret_cast<const uint16_t &>((*currentNode)->block.get_ro()[gDataOffsetPos + idx * gAttrOffsetSize]); reinterpret_cast<const uint16_t &>((*currentNode)->block.get_ro()[gDataOffsetPos + idx * gAttrOffsetSize]);
uint16_t dataOffset; uint16_t dataOffset;
switch (c.getType()) { switch (c.getType()) {
case ColumnInfo::Int_Type: { case Int_Type: {
dataOffset = dataPos + (currentPos - 1) * sizeof(int); dataOffset = dataPos + (currentPos - 1) * sizeof(int);
} }
break; break;
case ColumnInfo::Double_Type: { case Double_Type: {
dataOffset = dataPos + (currentPos - 1) * sizeof(double); dataOffset = dataPos + (currentPos - 1) * sizeof(double);
} }
break; break;
case ColumnInfo::String_Type: { case String_Type: {
dataOffset = reinterpret_cast<const uint16_t &>((*currentNode)->block.get_ro()[dataPos dataOffset = reinterpret_cast<const uint16_t &>((*currentNode)->block.get_ro()[dataPos
+ (currentPos - 1) * gOffsetSize]); + (currentPos - 1) * gOffsetSize]);
} }
...@@ -268,7 +269,7 @@ class PTable { ...@@ -268,7 +269,7 @@ class PTable {
/************************************************************************//** /************************************************************************//**
* \brief Constructor for a given schema (using TableInfo) and dimension clustering. * \brief Constructor for a given schema (using TableInfo) and dimension clustering.
***************************************************************************/ ***************************************************************************/
PTable(const TableInfo &tInfo, const Dimensions &_bdccInfo = Dimensions()) { PTable(const VTableInfo &tInfo, const Dimensions &_bdccInfo = Dimensions()) {
auto pop = pool_by_vptr(this); auto pop = pool_by_vptr(this);
transaction::exec_tx(pop, [&] { init(tInfo, _bdccInfo); }); transaction::exec_tx(pop, [&] { init(tInfo, _bdccInfo); });
} }
...@@ -517,7 +518,7 @@ class PTable { ...@@ -517,7 +518,7 @@ class PTable {
const auto &dataPos = reinterpret_cast<const uint16_t &>(b[gDataOffsetPos + idx * gAttrOffsetSize]); const auto &dataPos = reinterpret_cast<const uint16_t &>(b[gDataOffsetPos + idx * gAttrOffsetSize]);
switch (c.getType()) { switch (c.getType()) {
case ColumnInfo::Int_Type: { case Int_Type: {
const auto &smaMin = reinterpret_cast<const int &>(b[smaPos]); const auto &smaMin = reinterpret_cast<const int &>(b[smaPos]);
const auto &smaMax = reinterpret_cast<const int &>(b[smaPos + sizeof(int)]); const auto &smaMax = reinterpret_cast<const int &>(b[smaPos + sizeof(int)]);
const auto &data = reinterpret_cast<const int (&)[cnt]>(b[dataPos]); const auto &data = reinterpret_cast<const int (&)[cnt]>(b[dataPos]);
...@@ -542,7 +543,7 @@ class PTable { ...@@ -542,7 +543,7 @@ class PTable {
} }
break; break;
case ColumnInfo::Double_Type: { case Double_Type: {
const auto &smaMin = reinterpret_cast<const double &>(b[smaPos]); const auto &smaMin = reinterpret_cast<const double &>(b[smaPos]);
const auto &smaMax = reinterpret_cast<const double &>(b[smaPos + sizeof(double)]); const auto &smaMax = reinterpret_cast<const double &>(b[smaPos + sizeof(double)]);
const auto &data = reinterpret_cast<const double (&)[cnt]>(b[dataPos]); const auto &data = reinterpret_cast<const double (&)[cnt]>(b[dataPos]);
...@@ -567,7 +568,7 @@ class PTable { ...@@ -567,7 +568,7 @@ class PTable {
} }
break; break;
case ColumnInfo::String_Type: { case String_Type: {
auto &smaMinPos = (uint16_t &) b[smaPos]; auto &smaMinPos = (uint16_t &) b[smaPos];
auto &smaMaxPos = (uint16_t &) b[smaPos + gOffsetSize]; auto &smaMaxPos = (uint16_t &) b[smaPos + gOffsetSize];
auto &stringPos = (uint16_t (&)[cnt]) b[dataPos]; auto &stringPos = (uint16_t (&)[cnt]) b[dataPos];
...@@ -632,11 +633,11 @@ class PTable { ...@@ -632,11 +633,11 @@ class PTable {
const auto &c = root->tInfo->columnInfo(i); const auto &c = root->tInfo->columnInfo(i);
if (customizations.find(i) == customizations.end()) { if (customizations.find(i) == customizations.end()) {
switch (c.getType()) { switch (c.getType()) {
case ColumnInfo::Int_Type:portions += 1; case Int_Type:portions += 1;
break; break;
case ColumnInfo::Double_Type:portions += 2; case Double_Type:portions += 2;
break; break;
case ColumnInfo::String_Type:portions += 4; case String_Type:portions += 4;
break; break;
default:throw PTableException("unsupported column type\n"); default:throw PTableException("unsupported column type\n");
} }
...@@ -648,11 +649,11 @@ class PTable { ...@@ -648,11 +649,11 @@ class PTable {
const auto &c = root->tInfo->columnInfo(i); const auto &c = root->tInfo->columnInfo(i);
if (customizations.find(i) == customizations.end()) { if (customizations.find(i) == customizations.end()) {
switch (c.getType()) { switch (c.getType()) {
case ColumnInfo::Int_Type:miniPageSizes[i] = 1 * totalSize / portions; case Int_Type:miniPageSizes[i] = 1 * totalSize / portions;
break; break;
case ColumnInfo::Double_Type:miniPageSizes[i] = 2 * totalSize / portions; case Double_Type:miniPageSizes[i] = 2 * totalSize / portions;
break; break;
case ColumnInfo::String_Type:miniPageSizes[i] = 4 * totalSize / portions; case String_Type:miniPageSizes[i] = 4 * totalSize / portions;
break; break;
default:throw PTableException("unsupported column type\n"); default:throw PTableException("unsupported column type\n");
} }
...@@ -689,7 +690,7 @@ class PTable { ...@@ -689,7 +690,7 @@ class PTable {
* \param[in] _bdccInfo * \param[in] _bdccInfo
* a mapping of column ids to number of BDCC bits to use * a mapping of column ids to number of BDCC bits to use
***************************************************************************/ ***************************************************************************/
void init(const TableInfo &_tInfo, const Dimensions &_bdccInfo) { void init(const VTableInfo &_tInfo, const Dimensions &_bdccInfo) {
this->root = make_persistent<struct root>(); this->root = make_persistent<struct root>();
this->root->tInfo = make_persistent<PTableInfo>(_tInfo); this->root->tInfo = make_persistent<PTableInfo>(_tInfo);
this->root->bdccInfo = make_persistent<BDCCInfo>(_bdccInfo); this->root->bdccInfo = make_persistent<BDCCInfo>(_bdccInfo);
...@@ -725,17 +726,17 @@ class PTable { ...@@ -725,17 +726,17 @@ class PTable {
uint16_t smaOffset = currentOffset; uint16_t smaOffset = currentOffset;
uint16_t dataOffset; uint16_t dataOffset;
switch (c.getType()) { switch (c.getType()) {
case ColumnInfo::Int_Type: { case Int_Type: {
dataOffset = smaOffset + 2 * sizeof(int); dataOffset = smaOffset + 2 * sizeof(int);
smaSize += 2 * sizeof(int); smaSize += 2 * sizeof(int);
} }
break; break;
case ColumnInfo::Double_Type: { case Double_Type: {
dataOffset = smaOffset + 2 * sizeof(double); dataOffset = smaOffset + 2 * sizeof(double);
smaSize += 2 * sizeof(double); smaSize += 2 * sizeof(double);
} }
break; break;
case ColumnInfo::String_Type: { case String_Type: {
dataOffset = smaOffset + gAttrOffsetSize; dataOffset = smaOffset + gAttrOffsetSize;
smaSize += gAttrOffsetSize; smaSize += gAttrOffsetSize;
} }
...@@ -785,7 +786,7 @@ class PTable { ...@@ -785,7 +786,7 @@ class PTable {
switch (c.getType()) { switch (c.getType()) {
case ColumnInfo::Int_Type: { case Int_Type: {
/* Get Record Value */ /* Get Record Value */
auto iterBegin = buf.cbegin() + recordOffset; auto iterBegin = buf.cbegin() + recordOffset;
auto iterEnd = iterBegin + sizeof(int); auto iterEnd = iterBegin + sizeof(int);
...@@ -809,7 +810,7 @@ class PTable { ...@@ -809,7 +810,7 @@ class PTable {
} }
break; break;
case ColumnInfo::Double_Type: { case Double_Type: {
/* Get Record Value */ /* Get Record Value */
auto iterBegin = buf.cbegin() + recordOffset; auto iterBegin = buf.cbegin() + recordOffset;
auto iterEnd = iterBegin + sizeof(double); auto iterEnd = iterBegin + sizeof(double);
...@@ -833,7 +834,7 @@ class PTable { ...@@ -833,7 +834,7 @@ class PTable {
} }
break; break;
case ColumnInfo::String_Type: { case String_Type: {
/* Get Record Value */ /* Get Record Value */
auto iterBegin = buf.cbegin() + recordOffset; auto iterBegin = buf.cbegin() + recordOffset;
const auto value = deserialize<std::string>(iterBegin, buf.end()); const auto value = deserialize<std::string>(iterBegin, buf.end());
...@@ -941,15 +942,15 @@ class PTable { ...@@ -941,15 +942,15 @@ class PTable {
const auto &dataPos = const auto &dataPos =
reinterpret_cast<const uint16_t &>(block0[gDataOffsetPos + attributeIdx * gAttrOffsetSize]); reinterpret_cast<const uint16_t &>(block0[gDataOffsetPos + attributeIdx * gAttrOffsetSize]);
switch (c.getType()) { switch (c.getType()) {
case ColumnInfo::Int_Type: { case Int_Type: {
pTupleOffsets[attributeIdx] = dataPos + tuplePos * sizeof(int); pTupleOffsets[attributeIdx] = dataPos + tuplePos * sizeof(int);
} }
break; break;
case ColumnInfo::Double_Type: { case Double_Type: {
pTupleOffsets[attributeIdx] = dataPos + tuplePos * sizeof(double); pTupleOffsets[attributeIdx] = dataPos + tuplePos * sizeof(double);
} }
break; break;
case ColumnInfo::String_Type: { case String_Type: {
pTupleOffsets[attributeIdx] = pTupleOffsets[attributeIdx] =
reinterpret_cast<const uint16_t &>(block0[dataPos + tuplePos * gOffsetSize]); reinterpret_cast<const uint16_t &>(block0[dataPos + tuplePos * gOffsetSize]);
} }
...@@ -1034,7 +1035,7 @@ class PTable { ...@@ -1034,7 +1035,7 @@ class PTable {
for (const auto &p: predicates) { for (const auto &p: predicates) {
const auto &smaPos = reinterpret_cast<const uint16_t &>(b.get_ro()[gSmaOffsetPos + p.first * gAttrOffsetSize]); const auto &smaPos = reinterpret_cast<const uint16_t &>(b.get_ro()[gSmaOffsetPos + p.first * gAttrOffsetSize]);
switch (tInfo.columnInfo(p.first).getType()) { switch (tInfo.columnInfo(p.first).getType()) {
case ColumnInfo::Int_Type: { case Int_Type: {
const auto &smaMin = reinterpret_cast<const int &>(b.get_ro()[smaPos]); const auto &smaMin = reinterpret_cast<const int &>(b.get_ro()[smaPos]);
const auto &smaMax = reinterpret_cast<const int &>(b.get_ro()[smaPos + sizeof(int)]); const auto &smaMax = reinterpret_cast<const int &>(b.get_ro()[smaPos + sizeof(int)]);
PLOG("predicate range: " << std::get<int>(p.second.first) << '-' PLOG("predicate range: " << std::get<int>(p.second.first) << '-'
...@@ -1046,7 +1047,7 @@ class PTable { ...@@ -1046,7 +1047,7 @@ class PTable {
} }
} }
break; break;
case ColumnInfo::Double_Type: { case Double_Type: {
const auto &smaMin = reinterpret_cast<const double &>(b.get_ro()[smaPos]); const auto &smaMin = reinterpret_cast<const double &>(b.get_ro()[smaPos]);
const auto &smaMax = reinterpret_cast<const double &>(b.get_ro()[smaPos + sizeof(double)]); const auto &smaMax = reinterpret_cast<const double &>(b.get_ro()[smaPos + sizeof(double)]);
PLOG("predicate range: " << std::get<double>(p.second.first) << '-' PLOG("predicate range: " << std::get<double>(p.second.first) << '-'
...@@ -1058,7 +1059,7 @@ class PTable { ...@@ -1058,7 +1059,7 @@ class PTable {
} }
} }
break; break;
case ColumnInfo::String_Type: { case String_Type: {
const auto &smaMinPos = (uint16_t &) b.get_ro()[smaPos]; const auto &smaMinPos = (uint16_t &) b.get_ro()[smaPos];
const auto &smaMaxPos = (uint16_t &) b.get_ro()[smaPos + gOffsetSize]; const auto &smaMaxPos = (uint16_t &) b.get_ro()[smaPos + gOffsetSize];
const auto smaMin(reinterpret_cast<const char (&)[]>(b.get_ro()[smaMinPos])); const auto smaMin(reinterpret_cast<const char (&)[]>(b.get_ro()[smaMinPos]));
...@@ -1092,21 +1093,21 @@ class PTable { ...@@ -1092,21 +1093,21 @@ class PTable {
auto offset = ptp.getOffsetAt(p.first); auto offset = ptp.getOffsetAt(p.first);
switch (tInfo.columnInfo(p.first).getType()) { switch (tInfo.columnInfo(p.first).getType()) {
case ColumnInfo::Int_Type: { case Int_Type: {
const auto &value = reinterpret_cast<const int &>(b[offset]); const auto &value = reinterpret_cast<const int &>(b[offset]);
if (std::get<int>(p.second.second) < value || std::get<int>(p.second.first) > value) { if (std::get<int>(p.second.second) < value || std::get<int>(p.second.first) > value) {
return false; return false;
} }
} }
break; break;
case ColumnInfo::Double_Type: { case Double_Type: {
const auto &value = reinterpret_cast<const double &>(b[offset]); const auto &value = reinterpret_cast<const double &>(b[offset]);
if (std::get<double>(p.second.second) < value || std::get<double>(p.second.first) > value) { if (std::get<double>(p.second.second) < value || std::get<double>(p.second.first) > value) {
return false; return false;
} }
} }
break; break;
case ColumnInfo::String_Type: { case String_Type: {
const std::string value(reinterpret_cast<const char (&)[]>(b[offset])); const std::string value(reinterpret_cast<const char (&)[]>(b[offset]));
if (std::get<std::string>(p.second.second) < value || std::get<std::string>(p.second.first) > value) { if (std::get<std::string>(p.second.second) < value || std::get<std::string>(p.second.first) > value) {
return false; return false;
...@@ -1164,7 +1165,7 @@ class PTable { ...@@ -1164,7 +1165,7 @@ class PTable {
const auto &dataPos = reinterpret_cast<const uint16_t &>(b[gDataOffsetPos + idx * gAttrOffsetSize]); const auto &dataPos = reinterpret_cast<const uint16_t &>(b[gDataOffsetPos + idx * gAttrOffsetSize]);
switch (c.getType()) { switch (c.getType()) {
case ColumnInfo::Int_Type: { case Int_Type: {
const auto nextMiniPageStart = const auto nextMiniPageStart =
(std::tuple_size<Tuple>::value == idx + 1) ? gBlockSize : reinterpret_cast<const uint16_t &>(b[gSmaOffsetPos (std::tuple_size<Tuple>::value == idx + 1) ? gBlockSize : reinterpret_cast<const uint16_t &>(b[gSmaOffsetPos
+ (idx + 1) * gAttrOffsetSize]); + (idx + 1) * gAttrOffsetSize]);
...@@ -1174,7 +1175,7 @@ class PTable { ...@@ -1174,7 +1175,7 @@ class PTable {
} }
break; break;
case ColumnInfo::Double_Type: { case Double_Type: {
const auto nextMiniPageStart = const auto nextMiniPageStart =
(std::tuple_size<Tuple>::value == idx + 1) ? gBlockSize : reinterpret_cast<const uint16_t &>(b[gSmaOffsetPos (std::tuple_size<Tuple>::value == idx + 1) ? gBlockSize : reinterpret_cast<const uint16_t &>(b[gSmaOffsetPos
+ (idx + 1) * gAttrOffsetSize]); + (idx + 1) * gAttrOffsetSize]);
...@@ -1184,7 +1185,7 @@ class PTable { ...@@ -1184,7 +1185,7 @@ class PTable {
} }
break; break;
case ColumnInfo::String_Type: { case String_Type: {
uint16_t freeSpaceMiniPage; uint16_t freeSpaceMiniPage;
auto iterBegin = buf.cbegin() + recordOffset; auto iterBegin = buf.cbegin() + recordOffset;
const auto value = deserialize<std::string>(iterBegin, buf.end()); const auto value = deserialize<std::string>(iterBegin, buf.end());
......
include(../../cmake/Testing.cmake.in) include(../../cmake/Testing.cmake.in)
if (BUILD_BENCHMARKS) if (BUILD_BENCHMARKS)
do_test(insert)
do_test(scan) do_test(scan)
do_test(point) do_test(point)
endif() endif()
...@@ -17,21 +17,65 @@ ...@@ -17,21 +17,65 @@
* along with PTable. If not, see <http://www.gnu.org/licenses/>. * along with PTable. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef PTABLE_COMMON_H
#define PTABLE_COMMON_H
#include <chrono> #include <chrono>
#include <unistd.h> #include <unistd.h>
#include "PTable.hpp" #include "PTable.hpp"
using namespace ptable;
using nvml::obj::make_persistent; using nvml::obj::make_persistent;
using nvml::obj::p;
using nvml::obj::persistent_ptr; using nvml::obj::persistent_ptr;
using nvml::obj::pool; using nvml::obj::pool;
using nvml::obj::transaction; using nvml::obj::transaction;
using MyTuple = std::tuple<int, int, std::string, double>; using MyTuple = std::tuple<int, int, std::string, double>;
using PTableType = PTable<MyTuple, int>; using PTableType = ptable::PTable<MyTuple, int>;
const auto tuples = 1000 * 1000; using Vector = std::vector<int>;
using VectorVector = std::vector<Vector>;
const int hibit(int n) noexcept;
template <size_t SIZE>
static inline VectorVector *createPointVector(VectorVector *v);
struct root {
persistent_ptr<PTableType> pTable;
};
const std::string path = "/mnt/pmem/test/benchdb.db";
const auto NUM_TUPLES = 100 * 1000;
const auto POOL_SIZE = 1024 * 1024 * 256;
const auto ALIGNMENT = hibit(NUM_TUPLES) + 1;
VectorVector pv;
const auto POINT_ACCESS = *createPointVector<NUM_TUPLES>(&pv);
const VectorVector KEY_RANGES = {
Vector{NUM_TUPLES / 2 - NUM_TUPLES / 2000, NUM_TUPLES / 2 + NUM_TUPLES / 2000}, // 0,1%
Vector{NUM_TUPLES / 2 - NUM_TUPLES / 400, NUM_TUPLES / 2 + NUM_TUPLES / 400}, // 0,5%
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{0, NUM_TUPLES-1} //100,0%
};
int hibit(int n) { 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%
Vector{NUM_TUPLES / 2 - NUM_TUPLES / 200, NUM_TUPLES / 2 + NUM_TUPLES / 200,
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%
Vector{NUM_TUPLES / 2 - NUM_TUPLES / 20, NUM_TUPLES / 2 + NUM_TUPLES / 20,
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%
Vector{0, NUM_TUPLES - 1, 0, NUM_TUPLES - 1} //100,0%
};
const int hibit(int n) noexcept {
n |= (n >> 1); n |= (n >> 1);
n |= (n >> 2); n |= (n >> 2);
n |= (n >> 4); n |= (n >> 4);
...@@ -40,41 +84,38 @@ int hibit(int n) { ...@@ -40,41 +84,38 @@ int hibit(int n) {
return n - (n >> 1); return n - (n >> 1);
} }
int main() { template<size_t SIZE>
static inline VectorVector *createPointVector(VectorVector *v) {
if (SIZE >= 100) {
createPointVector<SIZE / 10>(v);
v->emplace_back(Vector{SIZE, SIZE / 2});
}
return v;
}
void insert (pool<root> &pop, const std::string &path, size_t entries) {
using namespace ptable;
std::chrono::high_resolution_clock::time_point start, end; std::chrono::high_resolution_clock::time_point start, end;
std::vector<typename std::chrono::duration<int64_t, std::micro>::rep> measures; std::vector<typename std::chrono::duration<int64_t, std::micro>::rep> measures;
struct root { pop = pool<root>::create(path, LAYOUT, POOL_SIZE);
persistent_ptr<PTableType> pTable; transaction::exec_tx(pop, [&] {
}; const auto tInfo = ptable::VTableInfo("MyTable", {
{"a", Int_Type},
pool<root> pop; {"b", Int_Type},
{"c", String_Type},
const std::string path = "/mnt/pmem/test/benchdb.db"; {"d", Double_Type}
}, Int_Type);
std::remove(path.c_str()); const auto dims = Dimensions({
{0, {10, ALIGNMENT}},
if (access(path.c_str(), F_OK) != 0) { {3, {10, ALIGNMENT}}
pop = pool<root>::create(path, LAYOUT, 1 << 30); });
transaction::exec_tx(pop, [&] { pop.get_root()->pTable = make_persistent<PTableType>(tInfo, dims);
auto tInfo = TableInfo("MyTable", { });
ColumnInfo("a", ColumnInfo::Int_Type),
ColumnInfo("b", ColumnInfo::Int_Type),
ColumnInfo("c", ColumnInfo::String_Type),
ColumnInfo("d", ColumnInfo::Double_Type)
});
auto alignment = hibit(tuples) + 1;
pop.get_root()->pTable =
make_persistent<PTableType>(tInfo, Dimensions({{0, {10, alignment}}, {3, {10, alignment}}}));
});
} else {
std::cerr << "WARNING: Table already exists" << std::endl;
pop = pool<root>::open(path, LAYOUT);
}
auto pTable = pop.get_root()->pTable; auto &pTable = pop.get_root()->pTable;
for (unsigned int i = 0; i < tuples; 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),
...@@ -88,10 +129,11 @@ int main() { ...@@ -88,10 +129,11 @@ int main() {
auto avg = std::accumulate(measures.begin(), measures.end(), 0) / measures.size(); auto avg = std::accumulate(measures.begin(), measures.end(), 0) / measures.size();
auto minmax = std::minmax_element(std::begin(measures), std::end(measures)); auto minmax = std::minmax_element(std::begin(measures), std::end(measures));