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

Added test cases and made required changes and fixes

parent 13f3f9c9
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
# Define a macro to simplify building and linking test executables # Define a macro to simplify building and linking test executables
# #
#============================================= #=============================================
macro( build_executable arg ) macro( build_test arg )
include_directories("${PROJECT_SOURCE_DIR}/test") include_directories("${PROJECT_SOURCE_DIR}/test")
add_executable( ${arg} "${arg}.cpp" $<TARGET_OBJECTS:MainTest>) add_executable( ${arg} "${arg}.cpp" $<TARGET_OBJECTS:MainTest>)
target_link_libraries( ${arg} target_link_libraries( ${arg}
...@@ -11,7 +11,16 @@ macro( build_executable arg ) ...@@ -11,7 +11,16 @@ macro( build_executable arg )
${NVML_LIBRARIES} ${NVML_LIBRARIES}
${BENCHMARK_LIB} ${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) ...@@ -23,9 +32,17 @@ macro (do_test arg)
NAME ${arg} NAME ${arg}
COMMAND "${CMAKE_CURRENT_BINARY_DIR}/${arg}" COMMAND "${CMAKE_CURRENT_BINARY_DIR}/${arg}"
) )
build_executable( ${arg} ) build_test( ${arg} )
endmacro(do_test) 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 set (CTEST_ENVIRONMENT
"DYLD_FALLBACK_LIBRARY_PATH=${DYLD_LIBRARY_PATH}" "DYLD_FALLBACK_LIBRARY_PATH=${DYLD_LIBRARY_PATH}"
) )
...@@ -104,7 +104,7 @@ include_directories(${PROJECT_SOURCE_DIR} ...@@ -104,7 +104,7 @@ include_directories(${PROJECT_SOURCE_DIR}
include_directories("${THIRD_PARTY_DIR}") include_directories("${THIRD_PARTY_DIR}")
set(core_sources 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}/nvml
......
...@@ -61,7 +61,7 @@ class PBPTree { ...@@ -61,7 +61,7 @@ class PBPTree {
#ifndef UNIT_TESTS #ifndef UNIT_TESTS
private: private:
#else #else
public:f public:
#endif #endif
// Forward declarations // Forward declarations
......
...@@ -59,7 +59,7 @@ class PTable { ...@@ -59,7 +59,7 @@ class PTable {
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>;
using DataNodePtr = persistent_ptr<struct DataNode<KeyType>>; using DataNodePtr = persistent_ptr<DataNode<KeyType>>;
/************************************************************************//** /************************************************************************//**
* \brief Iterator to iterate over all tuples using the blocks. * \brief Iterator to iterate over all tuples using the blocks.
...@@ -985,7 +985,7 @@ class PTable { ...@@ -985,7 +985,7 @@ class PTable {
} }
newNode1->next = newNode2; newNode1->next = newNode2;
newNode2->next = oldNode->next; newNode2->next = oldNode->next;
oldNode->clear(); delete_persistent<DataNode<KeyType>>(oldNode);
return std::make_pair(newNode1, newNode2); return std::make_pair(newNode1, newNode2);
} }
......
include(../../cmake/Testing.cmake.in) include(../../cmake/Testing.cmake.in)
if (BUILD_BENCHMARKS) if (BUILD_BENCHMARKS)
do_test(scan) do_bench(scan)
do_test(point) do_bench(point)
endif() endif()
...@@ -107,8 +107,8 @@ void insert (pool<root> &pop, const std::string &path, size_t entries) { ...@@ -107,8 +107,8 @@ void insert (pool<root> &pop, const std::string &path, size_t entries) {
{"d", Double_Type} {"d", Double_Type}
}, Int_Type); }, Int_Type);
const auto dims = Dimensions({ const auto dims = Dimensions({
{0, {10, ALIGNMENT}}, {0, 10, ALIGNMENT},
{3, {10, ALIGNMENT}} {3, 10, ALIGNMENT}
}); });
pop.get_root()->pTable = make_persistent<PTableType>(tInfo, dims); pop.get_root()->pTable = make_persistent<PTableType>(tInfo, dims);
}); });
......
...@@ -24,14 +24,14 @@ ...@@ -24,14 +24,14 @@
#include <unordered_map> #include <unordered_map>
#include "config.h" #include "config.h"
#include <libpmemobj++/make_persistent.hpp> #include <libpmemobj++/allocator.hpp>
#include <libpmemobj++/persistent_ptr.hpp> #include <libpmemobj++/persistent_ptr.hpp>
namespace ptable { namespace ptable {
using nvml::obj::allocator;
using nvml::obj::p;
using nvml::obj::persistent_ptr; using nvml::obj::persistent_ptr;
using nvml::obj::make_persistent;
using nvml::obj::delete_persistent;
/** Positions in NVM_Block */ /** Positions in NVM_Block */
constexpr int gBDCCRangePos1 = 0; constexpr int gBDCCRangePos1 = 0;
...@@ -86,7 +86,7 @@ struct DataNode { ...@@ -86,7 +86,7 @@ struct DataNode {
std::size_t, std::size_t,
std::hash<uint32_t>, std::hash<uint32_t>,
std::equal_to<uint32_t>, std::equal_to<uint32_t>,
nvml::obj::allocator<uint32_t>>; allocator<uint32_t>>;
DataNode() : next(nullptr) {} DataNode() : next(nullptr) {}
...@@ -104,14 +104,6 @@ struct DataNode { ...@@ -104,14 +104,6 @@ struct DataNode {
} }
return sum / reinterpret_cast<const uint32_t &>(block.get_ro()[gCountPos]); 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 */ } /* end namespace ptable */
......
...@@ -19,13 +19,53 @@ ...@@ -19,13 +19,53 @@
#include "PTableInfo.hpp" #include "PTableInfo.hpp"
#include <sstream>
using namespace ptable; 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++) { 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; return -1;
} }
\ No newline at end of file
...@@ -44,91 +44,44 @@ using nvml::obj::transaction; ...@@ -44,91 +44,44 @@ using nvml::obj::transaction;
namespace ptable { namespace ptable {
class PColumnInfo { class PColumnInfo {
public: persistent_ptr<char[]> name;
PColumnInfo(pool_base pop) : PColumnInfo(pop, "", Void_Type) {} p<ColumnType> type;
PColumnInfo(pool_base pop, const std::string &n, ColumnType ct) : type(ct) { public:
transaction::exec_tx(pop, [&] { PColumnInfo(pool_base pop);
name = make_persistent<char[]>(n.length() + 1); PColumnInfo(pool_base pop, Column col);
strcpy(name.get(), n.c_str()); PColumnInfo(pool_base pop, const std::string &n, ColumnType ct);
});
}
const std::string getName() const { return name.get(); } const std::string getName() const { return name.get(); }
const ColumnType getType() const { return type.get_ro(); } 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 { class PTableInfo {
PString name;
persistent_ptr<PColumnVector> columns;
p<ColumnType> keyType;
public: public:
using PTableInfoPtr = persistent_ptr<PTableInfo>;
using PColumnVector = std::vector<PColumnInfo, nvml::obj::allocator<PColumnInfo>>;
using PColumnIterator = PColumnVector::const_iterator;
PTableInfo() {} 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) { std::string tableName() const { return std::string(name.data()); }
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()); }
ColumnType typeOfKey() const { return keyType.get_ro(); } ColumnType typeOfKey() const { return keyType.get_ro(); }
int findColumnByName(const std::string &colName) const; int findColumnByName(const std::string &colName) const;
const PColumnInfo &columnInfo(int pos) const { return columns->at(pos); } const PColumnInfo &columnInfo(int pos) const { return columns->at(pos); }
std::size_t numColumns() const { return columns->size(); }
const std::size_t numColumns() const { return columns->size(); } void setColumns(const ColumnVector vec);
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());
});
}
PColumnIterator begin() const { return columns->begin(); } PColumnIterator begin() const { return columns->begin(); }
PColumnIterator end() const { return columns->end(); } 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 { } /* namespace ptable */
template<>
struct hash<ptable::PColumnInfo> {
std::size_t operator()(const ptable::PColumnInfo &c) const {
return std::hash<std::string>()(c.getName());
}
};
}
#endif /* PTableInfo_hpp_ */ #endif /* PTableInfo_hpp_ */
...@@ -20,14 +20,6 @@ ...@@ -20,14 +20,6 @@
#ifndef PTuple_hpp_ #ifndef PTuple_hpp_
#define PTuple_hpp_ #define PTuple_hpp_
#include <algorithm>
#include <array>
#include <cstddef>
#include <cstdint>
#include <string>
#include <libpmemobj++/persistent_ptr.hpp>
#include "DataNode.hpp" #include "DataNode.hpp"
using nvml::obj::persistent_ptr; using nvml::obj::persistent_ptr;
...@@ -197,7 +189,7 @@ struct PTuplePrinter { ...@@ -197,7 +189,7 @@ struct PTuplePrinter {
static void print(std::ostream &os, persistent_ptr<DataNode<KeyType>> node, const uint16_t *offsets) { static void print(std::ostream &os, persistent_ptr<DataNode<KeyType>> node, const uint16_t *offsets) {
PTuplePrinter<Tuple, CurrentIndex - 1, KeyType>::print(os, node, offsets); PTuplePrinter<Tuple, CurrentIndex - 1, KeyType>::print(os, node, offsets);
auto val = 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, node,
offsets); offsets);
os << "," << val; os << "," << val;
...@@ -215,7 +207,7 @@ struct PTuplePrinter { ...@@ -215,7 +207,7 @@ struct PTuplePrinter {
template<class Tuple, typename KeyType> template<class Tuple, typename KeyType>
struct PTuplePrinter<Tuple, 1, KeyType> { struct PTuplePrinter<Tuple, 1, KeyType> {
static void print(std::ostream &os, persistent_ptr<DataNode<KeyType>> node, const uint16_t *offsets) { 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 { ...@@ -380,7 +372,7 @@ class PTuple {
std::shared_ptr<Tuple> createTuple() const { std::shared_ptr<Tuple> createTuple() const {
//typename Tuple::Base tp{}; //typename Tuple::Base tp{};
Tuple 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()); detail::getAll_helper<Tuple, NUM_ATTRIBUTES, KeyType>::apply(tptr, node, offsets.get_ro().data());
return tptr; return tptr;
} }
...@@ -392,9 +384,6 @@ class PTuple { ...@@ -392,9 +384,6 @@ class PTuple {
}; /* 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. * \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 ...@@ -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> template<std::size_t I = 0, typename FuncT, typename... Tp>
inline typename std::enable_if<I == sizeof...(Tp), void>::type inline typename std::enable_if<I == sizeof...(Tp), void>::type
callForIndex(int, const std::tuple<Tp...> &, FuncT) {} callForIndex(int, const std::tuple<Tp...> &, FuncT) {}
......
...@@ -24,8 +24,6 @@ ...@@ -24,8 +24,6 @@
#include "core/BDCCInfo.hpp" #include "core/BDCCInfo.hpp"
#include "core/PTableException.hpp" #include "core/PTableException.hpp"
//#include <libpmemobj++/pool.hpp>
using namespace ptable; using namespace ptable;
using nvml::obj::pool; using nvml::obj::pool;
...@@ -53,19 +51,22 @@ TEST_CASE("Testing to create a new BDCCInfo instance", "[BDCCInfo]") { ...@@ -53,19 +51,22 @@ TEST_CASE("Testing to create a new BDCCInfo instance", "[BDCCInfo]") {
REQUIRE(bdccInfo->numBins() == 10); REQUIRE(bdccInfo->numBins() == 10);
std::bitset<32> expected[2] = { std::bitset<32> expected[2] = {
0b0000000000000000001010101000, 0b0000000000000000001010101000,
0b0000000000000000000101010111 0b0000000000000000000101010111
}; };
auto i = 0u; 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<0>(dim) == std::get<0>(dims[i]));
REQUIRE(std::get<1>(dim) == std::get<1>(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<3>(dim) == std::get<2>(dims[i]));
REQUIRE(std::get<2>(dim) == expected[i]); REQUIRE(std::get<2>(dim) == expected[i]);
++i; ++i;
} }
/* Clean up */
transaction::exec_tx(pop, [&] { transaction::exec_tx(pop, [&] {
delete_persistent<BDCCInfo>(bdccInfo); delete_persistent<BDCCInfo>(bdccInfo);
delete_persistent<root>(pop.get_root());
}); });
pop.close(); pop.close();
std::remove(path.c_str()); std::remove(path.c_str());
......
...@@ -6,6 +6,11 @@ include(../../cmake/Testing.cmake.in) ...@@ -6,6 +6,11 @@ include(../../cmake/Testing.cmake.in)
if (BUILD_TEST_CASES) if (BUILD_TEST_CASES)
add_library(MainTest OBJECT MainTest.cpp) add_library(MainTest OBJECT MainTest.cpp)
do_test(VTableInfoTest)
do_test(BDCCInfoTest) do_test(BDCCInfoTest)
do_test(DataNodeTest)
do_test(PTableInfoTest)
do_test(PTupleTest)
do_test(PBPTreeTest)
do_test(PTableTest) do_test(PTableTest)
endif () 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());