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

Updated PTable to use volatile index, some other changes and unified benchmarks

parent 94baf17f
......@@ -44,15 +44,15 @@ struct root {
persistent_ptr<PTableType> pTable;
};
const std::string path = dbis::gPmemPath + "benchdb.db";
const auto NUM_TUPLES = 1000 * 10;
const auto POOL_SIZE = 1024 * 1024 * 256; // * 4ull; // 1GB
const std::string path = dbis::gPmemPath + "benchdb" + std::to_string(dbis::ptable::gBlockSize) + "B.db";
const auto NUM_TUPLES = 1000 * 1000;
const auto POOL_SIZE = 1024 * 1024 * 1024 * 4ull; // 4GB
const auto ALIGNMENT = hibit_pos(NUM_TUPLES) + 1;
VectorVector pv;
const auto POINT_ACCESS = *createPointVector<NUM_TUPLES>(&pv);
const VectorVector KEY_RANGES = {
/*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%
......@@ -60,9 +60,21 @@ const VectorVector KEY_RANGES = {
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 = {
/// Format: (window size, max value)
const VectorVector KEY_RANGES = {
Vector{NUM_TUPLES / 1000, NUM_TUPLES - NUM_TUPLES / 1000}, // 0,1%
Vector{NUM_TUPLES / 500, NUM_TUPLES - NUM_TUPLES / 500}, // 0,2%
Vector{NUM_TUPLES / 200, NUM_TUPLES - NUM_TUPLES / 200}, // 0,5%
Vector{NUM_TUPLES / 100, NUM_TUPLES - NUM_TUPLES / 100}, // 1,0%
Vector{NUM_TUPLES / 50, NUM_TUPLES - NUM_TUPLES / 50}, // 2,0%
Vector{NUM_TUPLES / 20, NUM_TUPLES - NUM_TUPLES / 20}, // 5,0%
Vector{NUM_TUPLES / 10, NUM_TUPLES - NUM_TUPLES / 10}, // 10,0%
Vector{NUM_TUPLES / 5, NUM_TUPLES - NUM_TUPLES / 5}, // 20,0%
Vector{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%
Vector{NUM_TUPLES / 2 - NUM_TUPLES / 200, NUM_TUPLES / 2 + NUM_TUPLES / 200,
......@@ -76,8 +88,24 @@ const VectorVector NON_KEY_RANGES = {
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%
};
};*/
/// Format: (window size, max of second attribute)
const VectorVector NON_KEY_RANGES = {
Vector{NUM_TUPLES / 1000, NUM_TUPLES - NUM_TUPLES / 500}, // 0,1%
Vector{NUM_TUPLES / 500, NUM_TUPLES - NUM_TUPLES / 250}, // 0,2%
//Vector{NUM_TUPLES * 45/ 10000, NUM_TUPLES - NUM_TUPLES*45 / 500}, // 0,45%
//Vector{NUM_TUPLES / 250, NUM_TUPLES - NUM_TUPLES / 125}, // 0,4%
//Vector{NUM_TUPLES*3 / 500, NUM_TUPLES - NUM_TUPLES*3 / 250}, // 0,6%
//Vector{NUM_TUPLES / 125, NUM_TUPLES - NUM_TUPLES*2 / 125} // 0,8%
Vector{NUM_TUPLES / 200, NUM_TUPLES - NUM_TUPLES / 100}, // 0,5%
Vector{NUM_TUPLES / 100, NUM_TUPLES - NUM_TUPLES / 50}, // 1,0%
Vector{NUM_TUPLES / 50, NUM_TUPLES - NUM_TUPLES / 25}, // 2,0%
Vector{NUM_TUPLES / 20, NUM_TUPLES - NUM_TUPLES / 10}, // 5,0%
Vector{NUM_TUPLES / 10, NUM_TUPLES - NUM_TUPLES / 5}, // 10,0%
Vector{NUM_TUPLES / 5, NUM_TUPLES - NUM_TUPLES * 2 / 5},// 20,0%
Vector{NUM_TUPLES , 1} //100,0%
};
int hibit_pos(int n) noexcept {
int c = 0;
while (n>>1 != 0) {
......@@ -102,15 +130,16 @@ 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);
/// Only if index is persistent version
//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>(alloc_class, tInfo, dims);
pop.root()->pTable = make_persistent<PTableType>(/*alloc_class,*/ tInfo, dims);
});
auto &pTable = pop.root()->pTable;
......@@ -130,6 +159,7 @@ void insert (pool<root> &pop, const std::string &path, size_t entries) {
auto diff = std::chrono::duration_cast<std::chrono::microseconds>(end - start).count();
measures.push_back(diff);
}
std::cout << std::endl;
const auto avg = std::accumulate(measures.begin(), measures.end(), 0) / measures.size();
const auto minmax = std::minmax_element(std::begin(measures), std::end(measures));
......
......@@ -16,6 +16,7 @@
*/
#include <unistd.h>
#include <random>
#include "benchmark/benchmark.h"
#include "fmt/format.h"
......@@ -28,6 +29,8 @@ 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::mt19937 gen(std::random_device{}());
std::uniform_int_distribution<> dis(1, state.range(0));
// std::remove(path.c_str());
if (access(path.c_str(), F_OK) != 0) {
......@@ -40,11 +43,12 @@ static void BM_PointQuery(benchmark::State& state) {
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';
//auto ptp = pTable.getByKey(state.range(1));
auto ptp = pTable.getByKey(dis(gen));
if (ptp.getNode() != nullptr) {
ptp.createTuple();
//benchmark::DoNotOptimize(ptp);
} else std::cerr << "key not found" << '\n';
}
transaction::run(pop, [&] { delete_persistent<PTableType>(pop.root()->pTable); });
......
......@@ -15,6 +15,7 @@
* If not, see <http://www.gnu.org/licenses/>.
*/
#include <random>
#include <unistd.h>
#include "benchmark/benchmark.h"
#include "common.hpp"
......@@ -24,6 +25,9 @@ using namespace dbis::ptable;
static void BM_RangeScan(benchmark::State &state) {
pool<root> pop;
std::mt19937 gen(std::random_device{}());
std::uniform_int_distribution<> dis(1, state.range(1));
if (access(path.c_str(), F_OK) != 0) {
insert(pop, path, NUM_TUPLES);
} else {
......@@ -35,10 +39,17 @@ static void BM_RangeScan(benchmark::State &state) {
/* RangeScan using Block iterator */
for (auto _ : state) {
//PTuple<int, MyTuple> mtp;
MyTuple mtp;
const int rangeStart = dis(gen);
auto iter =
pTable->rangeScan(ColumnRangeMap({{0, {(int)state.range(0), (int)state.range(1)}}}));
pTable->rangeScan(ColumnRangeMap({{0, {rangeStart, (int) (rangeStart + state.range(0) - 1)}}}));
for (const auto &tp : iter) {
tp;
benchmark::DoNotOptimize(tp);
benchmark::DoNotOptimize(mtp);
mtp = *tp.createTuple();
//mtp = tp;
benchmark::ClobberMemory();
}
}
pop.close();
......@@ -51,6 +62,9 @@ BENCHMARK(BM_RangeScan)->Apply(KeyRangeArguments);
static void BM_NonKeyRangeScan(benchmark::State &state) {
pool<root> pop;
std::mt19937 gen(std::random_device{}());
std::uniform_int_distribution<> dis(1, state.range(1));
if (access(path.c_str(), F_OK) != 0) {
insert(pop, path, NUM_TUPLES);
} else {
......@@ -62,12 +76,22 @@ static void BM_NonKeyRangeScan(benchmark::State &state) {
/* RangeScan using Block iterator */
for (auto _ : state) {
//PTuple<int, MyTuple> mtp;
MyTuple mtp;
const auto rangeStart = dis(gen);
auto iter =
pTable->rangeScan(ColumnRangeMap({{0, {(int)state.range(0), (int)state.range(1)}},
{3, {(double)state.range(2), (double)state.range(3)}}}));
pTable->rangeScan(ColumnRangeMap({{0, {(int)(rangeStart - state.range(0)), (int)(rangeStart + state.range(0))}},
{3, {(double)rangeStart, (double)(rangeStart + 2 * state.range(0) - 1)}}}));
//auto c = 0u;
for (const auto &tp : iter) {
tp;
benchmark::DoNotOptimize(tp);
benchmark::DoNotOptimize(mtp);
mtp = *tp.createTuple();
//mtp = tp;
benchmark::ClobberMemory();
//++c;
}
//std::cout << "Tuples scanned: " << c << std::endl;
}
pop.close();
}
......@@ -79,6 +103,9 @@ BENCHMARK(BM_NonKeyRangeScan)->Apply(NonKeyRangeArguments);
static void BM_PBPTreeKeyScan(benchmark::State &state) {
pool<root> pop;
std::mt19937 gen(std::random_device{}());
std::uniform_int_distribution<> dis(1, state.range(1));
if (access(path.c_str(), F_OK) != 0) {
insert(pop, path, NUM_TUPLES);
} else {
......@@ -89,9 +116,18 @@ static void BM_PBPTreeKeyScan(benchmark::State &state) {
auto pTable = pop.root()->pTable;
for (auto _ : state) {
PTuple<int, MyTuple> mtp;
//MyTuple mtp;
const int rangeStart = dis(gen);
/* Scan via Index scan */
pTable->rangeScan2(state.range(0), state.range(1),
[](int k, const PTuple<int, MyTuple> tp) { tp; });
pTable->rangeScan2(rangeStart, rangeStart + state.range(0) - 1,
[&mtp](int k, const PTuple<int, MyTuple> tp) {
benchmark::DoNotOptimize(tp);
benchmark::DoNotOptimize(mtp);
//mtp = *tp.createTuple();
mtp = tp;
benchmark::ClobberMemory();
});
}
pop.close();
......@@ -101,6 +137,9 @@ BENCHMARK(BM_PBPTreeKeyScan)->Apply(KeyRangeArguments);
static void BM_PBPTreeScan(benchmark::State &state) {
pool<root> pop;
std::mt19937 gen(std::random_device{}());
std::uniform_int_distribution<> dis(1, state.range(1));
if (access(path.c_str(), F_OK) != 0) {
insert(pop, path, NUM_TUPLES);
} else {
......@@ -112,20 +151,29 @@ static void BM_PBPTreeScan(benchmark::State &state) {
for (auto _ : state) {
/* Scan via PTuple iterator */
PTuple<int, MyTuple> mtp;
//MyTuple mtp;
const auto rangeStart = dis(gen);
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));
return (tp.get<0>() >= rangeStart - state.range(0)/2) &&
(tp.get<0>() <= rangeStart + state.range(0)/2) &&
(tp.get<3>() >= rangeStart) &&
(tp.get<3>() <= rangeStart + state.range(0) - 1);
});
for (; iter != eIter; iter++) {
iter;
benchmark::DoNotOptimize(iter);
benchmark::DoNotOptimize(mtp);
//mtp = *(*iter).createTuple();
mtp = *iter;
//(*iter).get<0>();
benchmark::ClobberMemory();
}
}
transaction::run(pop, [&] { delete_persistent<PTableType>(pop.root()->pTable); });
//transaction::run(pop, [&] { delete_persistent<PTableType>(pop.root()->pTable); });
pop.close();
pmempool_rm(path.c_str(), 0);
//pmempool_rm(path.c_str(), 0);
}
BENCHMARK(BM_PBPTreeScan)->Apply(NonKeyRangeArguments);
......
This diff is collapsed.
......@@ -30,12 +30,15 @@
#include "core/utils.hpp"
#include "core/VTableInfo.hpp"
#include "pbptrees/PBPTree.hpp"
#include "pbptrees/BPTree.hpp"
namespace dbis::ptable {
constexpr auto LAYOUT = "PTable";
constexpr auto TARGET_INDEX_NODE_SIZE = 1 * 1024; // 1KB
constexpr auto TARGET_BRANCH_SIZE = 4096;
constexpr auto TARGET_LEAF_SIZE = 4096;
/** Abort reason codes: */
const auto NOT_ENOUGH_SPACE = 1;
......@@ -57,9 +60,11 @@ class PTable;
template<typename KeyType, class... Types>
class PTable<KeyType, std::tuple<Types...>> {
using Tuple = std::tuple<Types...>;
static constexpr auto BRANCHKEYS = ((TARGET_INDEX_NODE_SIZE - 28) / (sizeof(KeyType) + 24)) & ~1;
static constexpr auto LEAFKEYS = ((TARGET_INDEX_NODE_SIZE - 36) /
(sizeof(KeyType) + sizeof(PTuple<KeyType, Tuple>)));
//static constexpr auto BRANCHKEYS = ((TARGET_INDEX_NODE_SIZE - 28) / (sizeof(KeyType) + 24)) & ~1;
//static constexpr auto LEAFKEYS = ((TARGET_INDEX_NODE_SIZE - 36) /
// (sizeof(KeyType) + sizeof(PTuple<KeyType, Tuple>)));
static const auto BRANCHKEYS = ((TARGET_BRANCH_SIZE - 16) / (sizeof(int) + 8)) & ~1;
static const auto LEAFKEYS = ((TARGET_LEAF_SIZE - 24) / (sizeof(int) + sizeof(PTuple<KeyType,Tuple>)));
using VTableInfoType = VTableInfo<KeyType, Tuple>;
using PTableInfoType = PTableInfo<KeyType, Tuple>;
......@@ -96,6 +101,7 @@ class PTable<KeyType, std::tuple<Types...>> {
currentNode(candidates.cbegin()),
currentCnt(candidates.size() > 0 ?
reinterpret_cast<const uint32_t &>((*currentNode)->block.get_ro()[gCountPos]) : 0) {
//std::cout << "Candidates: " << candidates.size() << std::endl;
if (candidates.size() > 0) ++(*this);
else currentPos = 1; // --> setting to end()
}
......@@ -198,7 +204,8 @@ class PTable<KeyType, std::tuple<Types...>> {
};
public:
using IndexType = pbptrees::PBPTree<KeyType, PTuple<KeyType, Tuple>, BRANCHKEYS, LEAFKEYS>;
//using IndexType = pbptrees::PBPTree<KeyType, PTuple<KeyType, Tuple>, BRANCHKEYS, LEAFKEYS>;
using IndexType = pbptrees::BPTree<KeyType, PTuple<KeyType, Tuple>, BRANCHKEYS, LEAFKEYS>;
/************************************************************************//**
* \brief Public Iterator to iterate over all inserted tuples using the index.
......@@ -302,6 +309,15 @@ class PTable<KeyType, std::tuple<Types...>> {
init(tInfo, _bdccInfo);
}
}
explicit PTable(const VTableInfoType &tInfo,
const Dimensions &_bdccInfo = Dimensions()) {
auto pop = pool_by_vptr(this);
if (pmemobj_tx_stage() == TX_STAGE_NONE) {
transaction::run(pop, [&] { init(tInfo, _bdccInfo); });
} else {
init(tInfo, _bdccInfo);
}
}
/************************************************************************//**
* \brief Default Destructor.
......@@ -533,7 +549,7 @@ class PTable<KeyType, std::tuple<Types...>> {
const auto colCnt = tInfo.numColumns();
do {
auto b = currentNode->block.get_ro();
auto &b = currentNode->block.get_ro();
const auto &key1 = reinterpret_cast<const uint32_t &>(b[gBDCCRangePos1]);
const auto &key2 = reinterpret_cast<const uint32_t &>(b[gBDCCRangePos2]);
......@@ -696,11 +712,12 @@ class PTable<KeyType, std::tuple<Types...>> {
* \param[in] _bdccInfo
* a mapping of column ids to number of BDCC bits to use
***************************************************************************/
void init(const std::string &_tName, const StringInitList &_columns, const Dimensions &_bdccInfo) {
void init(const std::string &_tName, const StringInitList &_columns, const std::size_t _keyIndex,
const Dimensions &_bdccInfo) {
this->root = make_persistent<struct root>();
this->root->tInfo.get_rw() = make_persistent<PTableInfoType>(_tName, _columns);
this->root->tInfo.get_rw() = make_persistent<PTableInfoType>(_tName, _columns, _keyIndex);
this->root->bdccInfo = make_persistent<BDCCInfo>(_bdccInfo);
this->root->index = make_persistent<IndexType>(index_alloc_class);
this->root->index = make_persistent<IndexType>(/*index_alloc_class*/);
this->root->dataNodes = make_persistent<DataNode<KeyType>>();
this->root->dataNodes->block.get_rw() = initBlock(0, ((1L << this->root->bdccInfo->numBins()) - 1));
}
......@@ -717,7 +734,7 @@ class PTable<KeyType, std::tuple<Types...>> {
this->root = make_persistent<struct root>();
this->root->tInfo = make_persistent<PTableInfoType>(_tInfo);
this->root->bdccInfo = make_persistent<BDCCInfo>(_bdccInfo);
this->root->index = make_persistent<IndexType>(index_alloc_class);
this->root->index = make_persistent<IndexType>(/*index_alloc_class*/);
this->root->dataNodes = make_persistent<struct DataNode<KeyType>>();
this->root->dataNodes->block.get_rw() = initBlock(0, ((1L << this->root->bdccInfo->numBins()) - 1));
}
......@@ -927,7 +944,7 @@ class PTable<KeyType, std::tuple<Types...>> {
/* Insert into index structure */
root->index->insert(key, PTuple<KeyType, Tuple>(targetNode, pTupleOffsets));
/* Add key to KeyVector */
targetNode->keys.get_rw()[cnt - 1] = key;
//targetNode->keys.get_rw()[cnt - 1] = key;
/* Update histogram */
const auto xtr = static_cast<uint32_t>(getBDCCFromTuple(tp).to_ulong());
targetNode->bdccSum += xtr;
......@@ -937,11 +954,11 @@ class PTable<KeyType, std::tuple<Types...>> {
}; ///< end insertFun
/// Check if we are already in a transaction; if not, we need to start a new transaction
if (pmemobj_tx_stage() == TX_STAGE_NONE) {
transaction::run(pop, [&] { insertFun(); });
} else {
//if (pmemobj_tx_stage() == TX_STAGE_NONE) {
// transaction::run(pop, [&] { insertFun(); });
//} else {
insertFun();
}
//}
return 1;
}
......@@ -961,8 +978,10 @@ class PTable<KeyType, std::tuple<Types...>> {
DataNodePtr newNode2;
/* Create two new blocks */
newNode1 = make_persistent<struct DataNode<KeyType>>();
newNode2 = make_persistent<struct DataNode<KeyType>>();
transaction::run(pop, [&] {
newNode1 = make_persistent<struct DataNode<KeyType>>();
newNode2 = make_persistent<struct DataNode<KeyType>>();
});
auto &block1Ref = newNode1->block.get_rw();
auto &block2Ref = newNode2->block.get_rw();
block1Ref = initBlock(bdccMin, splitValue);
......@@ -978,18 +997,14 @@ class PTable<KeyType, std::tuple<Types...>> {
if (std::find(deleted.begin(), deleted.end(), tuplePos) != deleted.end())
continue;
/// Set all attribute offsets
std::array<uint16_t, PTuple<KeyType, Tuple>::NUM_ATTRIBUTES> pTupleOffsets;
const auto &key = oldNode->keys.get_ro()[tuplePos];
/*
auto setPTupleOffsets = [&](auto element, std::size_t idx) {
pTupleOffsets[idx] = ColumnAttributes<toColumnType<decltype(element)>()>::dataOffsetPos(
block0, gDataOffsetPos + idx * gAttrOffsetSize, tuplePos
);
};
forEachTypeInTuple<decltype(setPTupleOffsets), Types...>(setPTupleOffsets);
*/
//auto setPTupleOffsets = [&](auto element, std::size_t idx) {
// pTupleOffsets[idx] = ColumnAttributes<toColumnType<decltype(element)>()>::dataOffsetPos(
// block0, gDataOffsetPos + idx * gAttrOffsetSize, tuplePos
// );
//};
//forEachTypeInTuple<decltype(setPTupleOffsets), Types...>(setPTupleOffsets);
auto attributeIdx = 0u;
for (auto &c : tInfo) {
const auto &dataPos =
......@@ -1015,6 +1030,24 @@ class PTable<KeyType, std::tuple<Types...>> {
const auto oldPTuple = PTuple<KeyType, Tuple>(oldNode, pTupleOffsets);
/// Extract the key
//const auto &key = oldNode->keys.get_ro()[tuplePos];
const auto &keyColumn = reinterpret_cast<const uint16_t &>(block0[gDataOffsetPos + tInfo.getKeyColumnIndex() * gAttrOffsetSize]);
uint16_t keyPos;
switch (tInfo.typeOfKey()) {
case ColumnType::IntType:
keyPos = keyColumn + tuplePos * sizeof(int);
break;
case ColumnType::DoubleType:
keyPos = keyColumn + tuplePos * sizeof(double);
break;
case ColumnType::StringType:
keyPos = reinterpret_cast<const uint16_t &>(block0[keyColumn + tuplePos * gOffsetSize]);
break;
default:throw PTableException("unsupported column type\n");
}
const auto &key = reinterpret_cast<const uint16_t &>(block0[keyPos]);
/* Insert into correct new Block depending on BDCC value */
root->index->erase(key);
const auto tp = oldPTuple.createTuple();
......
......@@ -93,7 +93,7 @@ struct DataNode {
persistent_ptr<DataNode> next;
p<BDCC_Block> block;
p<KeyVector> keys;
//p<KeyVector> keys;
p<DeletedVector> deleted;
//p<HistogramType> histogram;
p<size_t> bdccSum{0};
......
......@@ -62,6 +62,7 @@ template<typename KeyType, typename TupleType>
class PTableInfo {
PString name;
persistent_ptr<PColumnVector> columns;
p<std::size_t> keyColumn;
// p<ColumnType> keyType;
public:
......@@ -91,14 +92,15 @@ class PTableInfo {
}
}
std::string tableName() const { return std::string(name.data()); }
ColumnType typeOfKey() const { return toColumnType<KeyType>(); }
const PColumnInfo &columnInfo(int pos) const { return columns->at(pos); }
std::size_t numColumns() const { return columns->size(); }
PColumnIterator begin() const { return columns->begin(); }
PColumnIterator end() const { return columns->end(); }
inline std::string tableName() const { return std::string(name.data()); }
inline ColumnType typeOfKey() const { return toColumnType<KeyType>(); }
inline std::size_t getKeyColumnIndex() const { return keyColumn.get_ro(); }
inline const PColumnInfo &columnInfo(int pos) const { return columns->at(pos); }
inline std::size_t numColumns() const { return columns->size(); }
inline PColumnIterator begin() const { return columns->begin(); }
inline PColumnIterator end() const { return columns->end(); }
void setColumns(const ColumnVector vec) {
void setColumns(const ColumnVector &vec) {
auto pop = pool_by_vptr(this);
transaction::run(pop, [&] {
delete_persistent<PColumnVector>(columns);
......@@ -108,9 +110,10 @@ class PTableInfo {
});
}
int findColumnByName(const std::string &colName) const {
for (std::size_t i = 0; i < (*columns).size(); i++) {
if (columns->at(i).getName() == colName) return (int) i;
inline int findColumnByName(const std::string &colName) const {
const auto &cols = *columns;
for (int i = 0; i < cols.size(); ++i) {
if (cols[i].getName() == colName) return i;
}
return -1;
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment