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

Added test cases and made required changes and fixes

parent 13f3f9c9
......@@ -3,7 +3,7 @@
# 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_OBJECTS:MainTest>)
target_link_libraries( ${arg}
......@@ -11,7 +11,16 @@ macro( build_executable arg )
${NVML_LIBRARIES}
${BENCHMARK_LIB}
)
endmacro( build_executable )
endmacro( build_test )
macro( build_bench arg )
add_executable( ${arg} "${arg}.cpp")
target_link_libraries( ${arg}
ptable
${NVML_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}"
)
......@@ -104,7 +104,7 @@ 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
......
......@@ -61,7 +61,7 @@ class PBPTree {
#ifndef UNIT_TESTS
private:
#else
public:f
public:
#endif
// Forward declarations
......
......@@ -59,7 +59,7 @@ class PTable {
using ColumnIntMap = std::map<uint16_t, uint16_t>;
using IndexType = PBPTree<KeyType, PTuple<Tuple, KeyType>, BRANCHKEYS, LEAFKEYS>;
using DataNodePtr = persistent_ptr<struct DataNode<KeyType>>;
using DataNodePtr = persistent_ptr<DataNode<KeyType>>;
/************************************************************************//**
* \brief Iterator to iterate over all tuples using the blocks.
......@@ -985,7 +985,7 @@ class PTable {
}
newNode1->next = newNode2;
newNode2->next = oldNode->next;
oldNode->clear();
delete_persistent<DataNode<KeyType>>(oldNode);
return std::make_pair(newNode1, newNode2);
}
......
include(../../cmake/Testing.cmake.in)
if (BUILD_BENCHMARKS)
do_test(scan)
do_test(point)
do_bench(scan)
do_bench(point)
endif()
......@@ -107,8 +107,8 @@ void insert (pool<root> &pop, const std::string &path, size_t entries) {
{"d", Double_Type}
}, Int_Type);
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);
});
......
......@@ -24,14 +24,14 @@
#include <unordered_map>
#include "config.h"
#include <libpmemobj++/make_persistent.hpp>
#include <libpmemobj++/allocator.hpp>
#include <libpmemobj++/persistent_ptr.hpp>
namespace ptable {
using nvml::obj::allocator;
using nvml::obj::p;
using nvml::obj::persistent_ptr;
using nvml::obj::make_persistent;
using nvml::obj::delete_persistent;
/** Positions in NVM_Block */
constexpr int gBDCCRangePos1 = 0;
......@@ -86,7 +86,7 @@ struct DataNode {
std::size_t,
std::hash<uint32_t>,
std::equal_to<uint32_t>,
nvml::obj::allocator<uint32_t>>;
allocator<uint32_t>>;
DataNode() : next(nullptr) {}
......@@ -104,14 +104,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 */
......
......@@ -19,13 +19,53 @@
#include "PTableInfo.hpp"
#include <sstream>
using namespace ptable;
int PTableInfo::findColumnByName(const std::string& colName) const {
PColumnInfo::PColumnInfo(pool_base pop) : PColumnInfo(pop, "", Void_Type) {};
PColumnInfo::PColumnInfo(pool_base pop, Column col) : PColumnInfo(pop, col.first, col.second) {};
PColumnInfo::PColumnInfo(pool_base pop, const std::string &n, ColumnType ct) : type(ct) {
transaction::exec_tx(pop, [&] {
name = make_persistent<char[]>(n.length() + 1);
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));
});
}
int PTableInfo::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;
if (columns->at(i).getName() == colName) return (int) i;
}
return -1;
}
\ No newline at end of file
......@@ -44,91 +44,44 @@ using nvml::obj::transaction;
namespace ptable {
class PColumnInfo {
public:
PColumnInfo(pool_base pop) : PColumnInfo(pop, "", Void_Type) {}
persistent_ptr<char[]> name;
p<ColumnType> type;
PColumnInfo(pool_base pop, const std::string &n, ColumnType ct) : type(ct) {
transaction::exec_tx(pop, [&] {
name = make_persistent<char[]>(n.length() + 1);
strcpy(name.get(), n.c_str());
});
}
public:
PColumnInfo(pool_base pop);
PColumnInfo(pool_base pop, Column col);
PColumnInfo(pool_base pop, const std::string &n, ColumnType ct);
const std::string getName() const { return name.get(); }
const ColumnType getType() const { return type.get_ro(); }
private:
persistent_ptr<char[]> name;
p<ColumnType> type;
};
using PColumnVector = std::vector<PColumnInfo, nvml::obj::allocator<PColumnInfo>>;
using PColumnIterator = PColumnVector::const_iterator;
class PTableInfo {
PString name;
persistent_ptr<PColumnVector> columns;
p<ColumnType> keyType;
public:
using PTableInfoPtr = persistent_ptr<PTableInfo>;
using PColumnVector = std::vector<PColumnInfo, nvml::obj::allocator<PColumnInfo>>;
using PColumnIterator = PColumnVector::const_iterator;
PTableInfo() {}
PTableInfo(const VTableInfo &_tInfo, ColumnType _keyType = Void_Type);
PTableInfo(const std::string &_name, ColumnInitList _columns, ColumnType _keyType = Void_Type);
PTableInfo(const VTableInfo &_tInfo, ColumnType _keyType = Void_Type) : 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(const std::string &_name, ColumnInitList _columns, ColumnType _keyType = Void_Type) :
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));
});
}
const std::string tableName() const { return std::string(name.data()); }
std::string tableName() const { return std::string(name.data()); }
ColumnType typeOfKey() const { return keyType.get_ro(); }
int findColumnByName(const std::string &colName) const;
const PColumnInfo &columnInfo(int pos) const { return columns->at(pos); }
const std::size_t numColumns() const { return columns->size(); }
void setColumns(const PColumnVector vec) {
auto pop = pool_by_vptr(this);
transaction::exec_tx(pop, [&] {
delete_persistent<PColumnVector>(columns);
columns = make_persistent<PColumnVector>(vec.cbegin(), vec.cend());
});
}
std::size_t numColumns() const { return columns->size(); }
void setColumns(const ColumnVector vec);
PColumnIterator begin() const { return columns->begin(); }
PColumnIterator end() const { return columns->end(); }
// private:
PString name;
persistent_ptr<PColumnVector> columns;
p<ColumnType> keyType;
};
} /* namespace ptable */
using PTableInfoPtr = persistent_ptr<PTableInfo>;
namespace std {
template<>
struct hash<ptable::PColumnInfo> {
std::size_t operator()(const ptable::PColumnInfo &c) const {
return std::hash<std::string>()(c.getName());
}
};
}
} /* namespace ptable */
#endif /* PTableInfo_hpp_ */
......@@ -20,14 +20,6 @@
#ifndef PTuple_hpp_
#define PTuple_hpp_
#include <algorithm>
#include <array>
#include <cstddef>
#include <cstdint>
#include <string>
#include <libpmemobj++/persistent_ptr.hpp>
#include "DataNode.hpp"
using nvml::obj::persistent_ptr;
......@@ -197,7 +189,7 @@ struct PTuplePrinter {
static void print(std::ostream &os, persistent_ptr<DataNode<KeyType>> node, const uint16_t *offsets) {
PTuplePrinter<Tuple, CurrentIndex - 1, KeyType>::print(os, node, offsets);
auto val =
get_helper<typename Tuple::template getAttributeType<CurrentIndex - 1>::type, CurrentIndex - 1, KeyType>::apply(
get_helper<typename std::tuple_element<CurrentIndex - 1, Tuple>::type, CurrentIndex - 1, KeyType>::apply(
node,
offsets);
os << "," << val;
......@@ -215,7 +207,7 @@ struct PTuplePrinter {
template<class Tuple, typename KeyType>
struct PTuplePrinter<Tuple, 1, KeyType> {
static void print(std::ostream &os, persistent_ptr<DataNode<KeyType>> node, const uint16_t *offsets) {
os << get_helper<typename Tuple::template getAttributeType<0>::type, 0, KeyType>::apply(node, offsets);
os << get_helper<typename std::tuple_element<0, Tuple>::type, 0, KeyType>::apply(node, offsets);
}
};
......@@ -380,7 +372,7 @@ class PTuple {
std::shared_ptr<Tuple> createTuple() const {
//typename Tuple::Base tp{};
Tuple tp{};
std::shared_ptr < Tuple > tptr(new Tuple(tp));
std::shared_ptr<Tuple> tptr(new Tuple(tp));
detail::getAll_helper<Tuple, NUM_ATTRIBUTES, KeyType>::apply(tptr, node, offsets.get_ro().data());
return tptr;
}
......@@ -392,9 +384,6 @@ class PTuple {
}; /* class PTuple */
template<class Tuple, typename KeyType>
using PTuplePtr = persistent_ptr<PTuple<Tuple, KeyType>>;
/**************************************************************************//**
* \brief Get a specific attribute reference from the PTuple.
*
......
......@@ -30,7 +30,8 @@ inline void copyToByteArray(BDCC_Block &b, const T &data, const std::size_t size
}
/* ========================================================================= */
/* from https://stackoverflow.com/a/28440573 */
/* from https://stackoverflow.com/a/28440573
* calling a function on a tuple at a specified index */
template<std::size_t I = 0, typename FuncT, typename... Tp>
inline typename std::enable_if<I == sizeof...(Tp), void>::type
callForIndex(int, const std::tuple<Tp...> &, FuncT) {}
......
......@@ -24,8 +24,6 @@
#include "core/BDCCInfo.hpp"
#include "core/PTableException.hpp"
//#include <libpmemobj++/pool.hpp>
using namespace ptable;
using nvml::obj::pool;
......@@ -53,19 +51,22 @@ TEST_CASE("Testing to create a new BDCCInfo instance", "[BDCCInfo]") {
REQUIRE(bdccInfo->numBins() == 10);
std::bitset<32> expected[2] = {
0b0000000000000000001010101000,
0b0000000000000000000101010111
0b0000000000000000001010101000,
0b0000000000000000000101010111
};
auto i = 0u;
for(const auto &dim : *bdccInfo) {
for (const auto &dim : *bdccInfo) {
REQUIRE(std::get<0>(dim) == std::get<0>(dims[i]));
REQUIRE(std::get<1>(dim) == std::get<1>(dims[i]));
REQUIRE(std::get<3>(dim) == std::get<2>(dims[i]));
REQUIRE(std::get<2>(dim) == expected[i]);
++i;
}
/* Clean up */
transaction::exec_tx(pop, [&] {
delete_persistent<BDCCInfo>(bdccInfo);
delete_persistent<root>(pop.get_root());
});
pop.close();
std::remove(path.c_str());
......
......@@ -6,6 +6,11 @@ include(../../cmake/Testing.cmake.in)
if (BUILD_TEST_CASES)
add_library(MainTest OBJECT MainTest.cpp)
do_test(VTableInfoTest)
do_test(BDCCInfoTest)
do_test(DataNodeTest)
do_test(PTableInfoTest)
do_test(PTupleTest)
do_test(PBPTreeTest)
do_test(PTableTest)
endif ()
/*
* 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 <libpmemobj++/transaction.hpp>
#include <libpmemobj++/make_persistent_atomic.hpp>
#include "catch.hpp"
#include "config.h"
#include "core/DataNode.hpp"
#include "core/PTableException.hpp"
using namespace ptable;
using nvml::obj::delete_persistent_atomic;
using nvml::obj::make_persistent_atomic;
using nvml::obj::pool;
using nvml::obj::transaction;
TEST_CASE("Testing to create a new BDCCInfo instance", "[BDCCInfo]") {
using KeyType = int;
struct root {
persistent_ptr<DataNode<KeyType>> node;
};
pool<root> pop;
const std::string path = gPmemPath + "dataNode";
if (access(path.c_str(), F_OK) != 0) {
pop = pool<root>::create(path, "DataNode", 11 * 1024 * 1024);
make_persistent_atomic<DataNode<KeyType>>(pop, pop.get_root()->node, BDCC_Block());
} else throw PTableException("dataNode pool should not exist");
auto q = pop.get_root();
auto node = q->node;
transaction::exec_tx(pop, [&] {
for (auto i = 0u; i < 10; ++i) {
node->histogram.get_rw()[(i % 2) + 5]++;
node->keys.get_rw()[i] = i;
node->block.get_rw()[i] = 0xFF;
}
reinterpret_cast<uint16_t &>(node->block.get_rw()[gCountPos]) = 10;
});
REQUIRE(node->keys.get_ro().size() == 8 * 1024);
REQUIRE(node->calcAverageBDCC() == 5); /* 5.5 */
for (auto i = 0u; i < 10; ++i) {
REQUIRE(node->keys.get_ro()[i] == i);
if (i != gCountPos && i != gCountPos + 1)
REQUIRE(node->block.get_ro()[i] == 0xFF);
}
/* Clean up */
nvml::obj::delete_persistent_atomic<DataNode<KeyType>>(node);
nvml::obj::delete_persistent_atomic<root>(q);
pop.close();
std::remove(path.c_str());
}
\ No newline at end of file
This diff is collapsed.
/*
* 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 <libpmemobj++/make_persistent_atomic.hpp>
#include "catch.hpp"
#include "config.h"
#include "core/PTableInfo.hpp"
#include "core/PTableException.hpp"
using namespace ptable;
using nvml::obj::delete_persistent_atomic;
using nvml::obj::make_persistent_atomic;
using nvml::obj::pool;
using nvml::obj::transaction;
TEST_CASE("creating a new PTableInfo (persistent TableInfo) instance", "[PTableInfo]") {
struct root {
persistent_ptr<PTableInfo> tInfo;
persistent_ptr<PTableInfo> tInfo2;
};
pool<root> pop;
const std::string path = gPmemPath + "pTableInfo";
if (access(path.c_str(), F_OK) != 0) {
pop = pool<root>::create(path, "PTableInfo", 8 * 1024 * 1024);
auto vTableInfo = VTableInfo("MyTable", {Column("a", Int_Type),
Column("b", Double_Type),
Column("c", String_Type)});
transaction::exec_tx(pop, [&] {
pop.get_root()->tInfo = make_persistent<PTableInfo>(vTableInfo);
pop.get_root()->tInfo2 = make_persistent<PTableInfo>("MyTable2", ColumnInitList{Column("a", Int_Type),
Column("b", Double_Type),
Column("c", String_Type)});
});
} else throw PTableException("pTableInfo pool should not exist");
auto q = pop.get_root();
auto tInfo = q->tInfo;
auto tInfo2 = q->tInfo2;
SECTION("retrieving name and type of columns") {
REQUIRE(tInfo->columnInfo(0).getName() == "a");
REQUIRE(tInfo->columnInfo(1).getName() == "b");
REQUIRE(tInfo->columnInfo(2).getName() == "c");
REQUIRE(tInfo->columnInfo(0).getType() == Int_Type);
REQUIRE(tInfo->columnInfo(1).getType() == Double_Type);
REQUIRE(tInfo->columnInfo(2).getType() == String_Type);
REQUIRE(tInfo2->columnInfo(0).getName() == "a");
REQUIRE(tInfo2->columnInfo(1).getName() == "b");
REQUIRE(tInfo2->columnInfo(2).getName() == "c");
REQUIRE(tInfo2->columnInfo(0).getType() == Int_Type);
REQUIRE(tInfo2->columnInfo(1).getType() == Double_Type);
REQUIRE(tInfo2->columnInfo(2).getType() == String_Type);
}
SECTION("retrieving table data") {
REQUIRE(tInfo->tableName() == "MyTable");
REQUIRE(tInfo->numColumns() == 3);
REQUIRE(tInfo->typeOfKey() == Void_Type);
REQUIRE(tInfo2->tableName() == "MyTable2");
REQUIRE(tInfo2->numColumns() == 3);
REQUIRE(tInfo2->typeOfKey() == Void_Type);
}
SECTION("iterate through columns") {
auto c = 0u;
for (const auto &col : *tInfo) {
c++;
}
REQUIRE(c == 3);
for (const auto &col : *tInfo2) {
c++;
}
REQUIRE(c == 6);
}
SECTION("find column by name") {
REQUIRE(tInfo->findColumnByName("a") == 0);
REQUIRE(tInfo->findColumnByName("b") == 1);
REQUIRE(tInfo->findColumnByName("c") == 2);
REQUIRE(tInfo->findColumnByName("d") == -1);
REQUIRE(tInfo2->findColumnByName("a") == 0);
REQUIRE(tInfo2->findColumnByName("b") == 1);
REQUIRE(tInfo2->findColumnByName("c") == 2);
REQUIRE(tInfo2->findColumnByName("d") == -1);
}
SECTION("replace columns") {
ColumnVector cv = {Column("d", Double_Type), Column("e", Int_Type)};
tInfo->setColumns(cv);
REQUIRE(tInfo->columnInfo(0).getName() == "d");
REQUIRE(tInfo->columnInfo(1).getName() == "e");
REQUIRE(tInfo->columnInfo(0).getType() == Double_Type);
REQUIRE(tInfo->columnInfo(1).getType() == Int_Type);
tInfo2->setColumns(cv);
REQUIRE(tInfo2->columnInfo(0).getName() == "d");
REQUIRE(tInfo2->columnInfo(1).getName() == "e");
REQUIRE(tInfo2->columnInfo(0).getType() == Double_Type);
REQUIRE(tInfo2->columnInfo(1).getType() == Int_Type);
}
/* Clean up */
delete_persistent_atomic<PTableInfo>(tInfo);
delete_persistent_atomic<PTableInfo>(tInfo2);
delete_persistent_atomic<root>(q);