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

🔀 Merge branch 'wip/testcases'

parents 46ddfacb fe2a2882
...@@ -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 master 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
) )
#-------------------------------------------------------------------------------- #--------------------------------------------------------------------------------
......
...@@ -3,15 +3,24 @@ ...@@ -3,15 +3,24 @@
# 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" ) 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_executable ) endmacro( build_test )
macro( build_bench arg )
add_executable( ${arg} "${arg}.cpp")
target_link_libraries( ${arg}
ptable
${PMDK_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}"
) )
...@@ -39,7 +39,7 @@ else() ...@@ -39,7 +39,7 @@ else()
endif() endif()
# C++ compiler flags # C++ compiler flags
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -Wall -Wno-deprecated -g -O2 -Wsign-compare") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -Wall -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")
...@@ -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")
#----------------------------------------------------------------------------------------- #-----------------------------------------------------------------------------------------
# #
...@@ -104,10 +104,10 @@ include_directories(${PROJECT_SOURCE_DIR} ...@@ -104,10 +104,10 @@ 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}/pmdk
${THIRD_PARTY_DIR}/variant ${THIRD_PARTY_DIR}/variant
) )
...@@ -119,7 +119,7 @@ if(BUILD_GOOGLE_BENCH) ...@@ -119,7 +119,7 @@ if(BUILD_GOOGLE_BENCH)
endif() endif()
add_library(ptable SHARED ${core_sources}) add_library(ptable SHARED ${core_sources})
target_link_libraries(ptable ${NVML_LIBRARIES}) target_link_libraries(ptable ${PMDK_LIBRARIES})
#----------------------------------------------------------------------------------------- #-----------------------------------------------------------------------------------------
...@@ -150,7 +150,8 @@ foreach(LIB ${PTABLE_LIBS}) ...@@ -150,7 +150,8 @@ foreach(LIB ${PTABLE_LIBS})
install(TARGETS ${LIB} DESTINATION ${PTABLE_LIB_DIR}) install(TARGETS ${LIB} DESTINATION ${PTABLE_LIB_DIR})
endforeach(LIB) endforeach(LIB)
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/" install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/core"
"${CMAKE_BINARY_DIR}/generated/"
"${THIRD_PARTY_DIR}/variant/include/mpark" "${THIRD_PARTY_DIR}/variant/include/mpark"
"${CMAKE_BINARY_DIR}/generated/" "${CMAKE_BINARY_DIR}/generated/"
DESTINATION ${PTABLE_INCLUDE_DIR} DESTINATION ${PTABLE_INCLUDE_DIR}
...@@ -159,5 +160,10 @@ install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/" ...@@ -159,5 +160,10 @@ install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/"
PATTERN "*.h" PATTERN "*.h"
) )
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/PBPTree.hpp"
"${CMAKE_CURRENT_SOURCE_DIR}/PTable.hpp"
DESTINATION ${PTABLE_INCLUDE_DIR}
)
# show used compiler # show used compiler
message("Using Compiler: ${CMAKE_CXX_COMPILER_ID}.") message("Using Compiler: ${CMAKE_CXX_COMPILER_ID}.")
...@@ -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.
...@@ -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
...@@ -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.
include(../../cmake/Testing.cmake.in) include(../../cmake/Testing.cmake.in)
if (BUILD_BENCHMARKS) if (BUILD_BENCHMARKS)
do_test(scan) do_bench(insert)
do_test(point) do_bench(scan)
do_bench(point)
endif() endif()
...@@ -24,18 +24,19 @@ ...@@ -24,18 +24,19 @@
#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>;
const int hibit(int n) noexcept; const int hibit_pos(int n) noexcept;
template <size_t SIZE> template <size_t SIZE>
static inline VectorVector *createPointVector(VectorVector *v); static inline VectorVector *createPointVector(VectorVector *v);
...@@ -45,10 +46,10 @@ struct root { ...@@ -45,10 +46,10 @@ 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 * 100;
const auto POOL_SIZE = 1024 * 1024 * 256; const auto POOL_SIZE = 1024 * 1024 * 256; // * 4ull; // 1GB
const auto ALIGNMENT = hibit(NUM_TUPLES) + 1; const auto ALIGNMENT = hibit_pos(NUM_TUPLES) + 1;
VectorVector pv; VectorVector pv;
const auto POINT_ACCESS = *createPointVector<NUM_TUPLES>(&pv); const auto POINT_ACCESS = *createPointVector<NUM_TUPLES>(&pv);
...@@ -58,30 +59,33 @@ const VectorVector KEY_RANGES = { ...@@ -58,30 +59,33 @@ const VectorVector KEY_RANGES = {
Vector{NUM_TUPLES / 2 - NUM_TUPLES / 200, NUM_TUPLES / 2 + NUM_TUPLES / 200}, // 1,0% 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 / 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{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% Vector{0, NUM_TUPLES-1} //100,0%
}; };
const VectorVector NON_KEY_RANGES = { const VectorVector NON_KEY_RANGES = {
Vector{NUM_TUPLES / 2 - NUM_TUPLES / 1000, NUM_TUPLES / 2 + NUM_TUPLES / 1000, Vector{NUM_TUPLES / 2 - NUM_TUPLES / 1000, NUM_TUPLES / 2 + NUM_TUPLES / 1000,
NUM_TUPLES / 2, NUM_TUPLES / 2 + NUM_TUPLES / 500}, // 0,1% NUM_TUPLES / 2, NUM_TUPLES / 2 + NUM_TUPLES / 500}, // 0,1%
Vector{NUM_TUPLES / 2 - NUM_TUPLES / 200, NUM_TUPLES / 2 + NUM_TUPLES / 200, Vector{NUM_TUPLES / 2 - NUM_TUPLES / 200, NUM_TUPLES / 2 + NUM_TUPLES / 200,
NUM_TUPLES / 2, NUM_TUPLES / 2 + NUM_TUPLES / 100}, // 0,5% NUM_TUPLES / 2, NUM_TUPLES / 2 + NUM_TUPLES / 100}, // 0,5%
Vector{NUM_TUPLES / 2 - NUM_TUPLES / 100, NUM_TUPLES / 2 + NUM_TUPLES / 100, Vector{NUM_TUPLES / 2 - NUM_TUPLES / 100, NUM_TUPLES / 2 + NUM_TUPLES / 100,
NUM_TUPLES / 2, NUM_TUPLES / 2 + NUM_TUPLES / 50}, // 1,0% NUM_TUPLES / 2, NUM_TUPLES / 2 + NUM_TUPLES / 50}, // 1,0%
Vector{NUM_TUPLES / 2 - NUM_TUPLES / 20, NUM_TUPLES / 2 + NUM_TUPLES / 20, Vector{NUM_TUPLES / 2 - NUM_TUPLES / 20, NUM_TUPLES / 2 + NUM_TUPLES / 20,
NUM_TUPLES / 2, NUM_TUPLES / 2 + NUM_TUPLES / 10}, // 5,0% NUM_TUPLES / 2, NUM_TUPLES / 2 + NUM_TUPLES / 10}, // 5,0%
Vector{NUM_TUPLES / 2 - NUM_TUPLES / 10, NUM_TUPLES / 2 + NUM_TUPLES / 10, Vector{NUM_TUPLES / 2 - NUM_TUPLES / 10, NUM_TUPLES / 2 + NUM_TUPLES / 10,
NUM_TUPLES / 2, NUM_TUPLES / 2 + NUM_TUPLES / 5}, // 10,0% NUM_TUPLES / 2, NUM_TUPLES / 2 + NUM_TUPLES / 5}, // 10,0%
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% Vector{0, NUM_TUPLES - 1, 0, NUM_TUPLES - 1} //100,0%
}; };
const int hibit(int n) noexcept { const int hibit_pos(int n) noexcept {
n |= (n >> 1); int c = 0;
n |= (n >> 2); while (n>>1 != 0) {
n |= (n >> 4); c++;
n |= (n >> 8); n>>=1;
n |= (n >> 16); }
return n - (n >> 1); return c;
} }
template<size_t SIZE> template<size_t SIZE>
...@@ -100,15 +104,10 @@ void insert (pool<root> &pop, const std::string &path, size_t entries) { ...@@ -100,15 +104,10 @@ 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}
}); });
pop.get_root()->pTable = make_persistent<PTableType>(tInfo, dims); pop.get_root()->pTable = make_persistent<PTableType>(tInfo, dims);
}); });
...@@ -118,9 +117,13 @@ void insert (pool<root> &pop, const std::string &path, size_t entries) { ...@@ -118,9 +117,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();
......
/*
* 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 "fmt/format.h"
#include "common.h"
using namespace ptable;
int main() {
pool<root> pop;
std::remove(path.c_str());
if (access(path.c_str(), F_OK) != 0) {
insert(pop, path, NUM_TUPLES);
} else {
std::cerr << "Table already exists" << std::endl;
}
auto pTable = pop.get_root()->pTable;
pop.close();
}
\ No newline at end of file
...@@ -30,12 +30,11 @@ static void BM_PointQuery(benchmark::State& state) { ...@@ -30,12 +30,11 @@ static void BM_PointQuery(benchmark::State& state) {
const std::string path = ptable::gPmemPath + "benchdb" + std::to_string(state.range(0)) + ".db"; const std::string path = ptable::gPmemPath + "benchdb" + std::to_string(state.range(0)) + ".db";
std::remove(path.c_str()); //std::remove(path.c_str());
if (access(path.c_str(), F_OK) != 0) { if (access(path.c_str(), F_OK) != 0) {
insert(pop, path, state.range(1)); insert(pop, path, state.range(0));
} else { } else {
std::cerr << "WARNING: Table already exists" << std::endl; //std::cerr << "WARNING: Table already exists" << std::endl;
pop = pool<root>::open(path, LAYOUT); pop = pool<root>::open(path, LAYOUT);
} }
...@@ -43,7 +42,7 @@ static void BM_PointQuery(benchmark::State& state) { ...@@ -43,7 +42,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();
......
...@@ -79,6 +79,29 @@ static void NonKeyRangeArguments(benchmark::internal::Benchmark* b) { ...@@ -79,6 +79,29 @@ static void NonKeyRangeArguments(benchmark::internal::Benchmark* b) {
} }
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);
}