From 79159ffd87bf86e92ab5af6fffd5cc93c205a630 Mon Sep 17 00:00:00 2001 From: Vinnie Falco Date: Thu, 29 Sep 2016 19:24:12 -0400 Subject: [PATCH] Squashed 'src/nudb/' content from commit 00adc6a git-subtree-dir: src/nudb git-subtree-split: 00adc6a4f16679a376f40c967f77dfa544c179c1 --- .gitignore | 2 + .gitmodules | 9 + .travis.yml | 89 +++ CHANGELOG.md | 58 ++ CMakeLists.txt | 87 +++ Jamroot | 93 +++ LICENSE_1_0.txt | 23 + README.md | 466 +++++++++++++++ TODO.txt | 2 + bench/CMakeLists.txt | 363 ++++++++++++ bench/Jamfile | 226 ++++++++ bench/README.md | 102 ++++ bench/bench.cpp | 535 +++++++++++++++++ bench/plot_bench.py | 37 ++ doc/.gitignore | 5 + doc/Jamfile.v2 | 77 +++ doc/boostbook.dtd | 439 ++++++++++++++ doc/docca | 1 + doc/images/logo.png | Bin 0 -> 153828 bytes doc/images/logo.psd | Bin 0 -> 737507 bytes doc/images/readme2.png | Bin 0 -> 106410 bytes doc/index.xml | 14 + doc/main.qbk | 342 +++++++++++ doc/makeqbk.sh | 12 + doc/quickref.xml | 82 +++ doc/reference.xsl | 14 + doc/source.dox | 333 +++++++++++ doc/types/File.qbk | 159 ++++++ doc/types/Hasher.qbk | 56 ++ doc/types/Progress.qbk | 40 ++ examples/CMakeLists.txt | 17 + examples/Jamfile | 12 + examples/example.cpp | 46 ++ extras/README.md | 5 + extras/beast | 1 + extras/nudb/basic_seconds_clock.hpp | 200 +++++++ extras/nudb/chrono_util.hpp | 58 ++ extras/nudb/test/fail_file.hpp | 343 +++++++++++ extras/nudb/test/temp_dir.hpp | 73 +++ extras/nudb/test/test_store.hpp | 451 +++++++++++++++ extras/nudb/test/xor_shift_engine.hpp | 105 ++++ extras/nudb/util.hpp | 288 ++++++++++ extras/rocksdb | 1 + include/nudb/basic_store.hpp | 436 ++++++++++++++ include/nudb/concepts.hpp | 205 +++++++ include/nudb/create.hpp | 117 ++++ include/nudb/detail/arena.hpp | 296 ++++++++++ include/nudb/detail/bucket.hpp | 473 +++++++++++++++ include/nudb/detail/buffer.hpp | 86 +++ include/nudb/detail/bulkio.hpp | 196 +++++++ include/nudb/detail/cache.hpp | 236 ++++++++ include/nudb/detail/endian.hpp | 93 +++ include/nudb/detail/field.hpp | 265 +++++++++ include/nudb/detail/format.hpp | 629 ++++++++++++++++++++ include/nudb/detail/gentex.hpp | 259 +++++++++ include/nudb/detail/mutex.hpp | 26 + include/nudb/detail/pool.hpp | 243 ++++++++ include/nudb/detail/stream.hpp | 149 +++++ include/nudb/detail/xxhash.hpp | 328 +++++++++++ include/nudb/error.hpp | 263 +++++++++ include/nudb/file.hpp | 53 ++ include/nudb/impl/basic_store.ipp | 793 ++++++++++++++++++++++++++ include/nudb/impl/create.ipp | 163 ++++++ include/nudb/impl/error.ipp | 180 ++++++ include/nudb/impl/posix_file.ipp | 259 +++++++++ include/nudb/impl/recover.ipp | 209 +++++++ include/nudb/impl/rekey.ipp | 248 ++++++++ include/nudb/impl/verify.ipp | 630 ++++++++++++++++++++ include/nudb/impl/visit.ipp | 96 ++++ include/nudb/impl/win32_file.ipp | 264 +++++++++ include/nudb/native_file.hpp | 76 +++ include/nudb/nudb.hpp | 27 + include/nudb/posix_file.hpp | 228 ++++++++ include/nudb/progress.hpp | 32 ++ include/nudb/recover.hpp | 73 +++ include/nudb/rekey.hpp | 110 ++++ include/nudb/store.hpp | 27 + include/nudb/type_traits.hpp | 63 ++ include/nudb/verify.hpp | 200 +++++++ include/nudb/version.hpp | 21 + include/nudb/visit.hpp | 63 ++ include/nudb/win32_file.hpp | 246 ++++++++ include/nudb/xxhasher.hpp | 45 ++ scripts/blacklist.supp | 38 ++ scripts/build-and-test.sh | 150 +++++ scripts/install-boost.sh | 27 + scripts/install-dependencies.sh | 90 +++ scripts/install-valgrind.sh | 20 + scripts/run-with-debugger.sh | 22 + scripts/run-with-gdb.sh | 9 + test/CMakeLists.txt | 38 ++ test/Jamfile | 30 + test/basic_store.cpp | 250 ++++++++ test/buffer.cpp | 77 +++ test/callgrind_test.cpp | 92 +++ test/concepts.cpp | 9 + test/create.cpp | 49 ++ test/error.cpp | 83 +++ test/file.cpp | 9 + test/native_file.cpp | 9 + test/posix_file.cpp | 9 + test/recover.cpp | 191 +++++++ test/rekey.cpp | 136 +++++ test/store.cpp | 9 + test/type_traits.cpp | 9 + test/verify.cpp | 94 +++ test/version.cpp | 9 + test/visit.cpp | 114 ++++ test/win32_file.cpp | 9 + test/xxhasher.cpp | 9 + tools/CMakeLists.txt | 17 + tools/Jamfile | 12 + tools/nudb.cpp | 514 +++++++++++++++++ 113 files changed, 15806 insertions(+) create mode 100644 .gitignore create mode 100644 .gitmodules create mode 100644 .travis.yml create mode 100644 CHANGELOG.md create mode 100644 CMakeLists.txt create mode 100644 Jamroot create mode 100644 LICENSE_1_0.txt create mode 100644 README.md create mode 100644 TODO.txt create mode 100644 bench/CMakeLists.txt create mode 100644 bench/Jamfile create mode 100644 bench/README.md create mode 100644 bench/bench.cpp create mode 100644 bench/plot_bench.py create mode 100644 doc/.gitignore create mode 100644 doc/Jamfile.v2 create mode 100644 doc/boostbook.dtd create mode 160000 doc/docca create mode 100644 doc/images/logo.png create mode 100644 doc/images/logo.psd create mode 100644 doc/images/readme2.png create mode 100644 doc/index.xml create mode 100644 doc/main.qbk create mode 100644 doc/makeqbk.sh create mode 100644 doc/quickref.xml create mode 100644 doc/reference.xsl create mode 100644 doc/source.dox create mode 100644 doc/types/File.qbk create mode 100644 doc/types/Hasher.qbk create mode 100644 doc/types/Progress.qbk create mode 100644 examples/CMakeLists.txt create mode 100644 examples/Jamfile create mode 100644 examples/example.cpp create mode 100644 extras/README.md create mode 160000 extras/beast create mode 100644 extras/nudb/basic_seconds_clock.hpp create mode 100644 extras/nudb/chrono_util.hpp create mode 100644 extras/nudb/test/fail_file.hpp create mode 100644 extras/nudb/test/temp_dir.hpp create mode 100644 extras/nudb/test/test_store.hpp create mode 100644 extras/nudb/test/xor_shift_engine.hpp create mode 100644 extras/nudb/util.hpp create mode 160000 extras/rocksdb create mode 100644 include/nudb/basic_store.hpp create mode 100644 include/nudb/concepts.hpp create mode 100644 include/nudb/create.hpp create mode 100644 include/nudb/detail/arena.hpp create mode 100644 include/nudb/detail/bucket.hpp create mode 100644 include/nudb/detail/buffer.hpp create mode 100644 include/nudb/detail/bulkio.hpp create mode 100644 include/nudb/detail/cache.hpp create mode 100644 include/nudb/detail/endian.hpp create mode 100644 include/nudb/detail/field.hpp create mode 100644 include/nudb/detail/format.hpp create mode 100644 include/nudb/detail/gentex.hpp create mode 100644 include/nudb/detail/mutex.hpp create mode 100644 include/nudb/detail/pool.hpp create mode 100644 include/nudb/detail/stream.hpp create mode 100644 include/nudb/detail/xxhash.hpp create mode 100644 include/nudb/error.hpp create mode 100644 include/nudb/file.hpp create mode 100644 include/nudb/impl/basic_store.ipp create mode 100644 include/nudb/impl/create.ipp create mode 100644 include/nudb/impl/error.ipp create mode 100644 include/nudb/impl/posix_file.ipp create mode 100644 include/nudb/impl/recover.ipp create mode 100644 include/nudb/impl/rekey.ipp create mode 100644 include/nudb/impl/verify.ipp create mode 100644 include/nudb/impl/visit.ipp create mode 100644 include/nudb/impl/win32_file.ipp create mode 100644 include/nudb/native_file.hpp create mode 100644 include/nudb/nudb.hpp create mode 100644 include/nudb/posix_file.hpp create mode 100644 include/nudb/progress.hpp create mode 100644 include/nudb/recover.hpp create mode 100644 include/nudb/rekey.hpp create mode 100644 include/nudb/store.hpp create mode 100644 include/nudb/type_traits.hpp create mode 100644 include/nudb/verify.hpp create mode 100644 include/nudb/version.hpp create mode 100644 include/nudb/visit.hpp create mode 100644 include/nudb/win32_file.hpp create mode 100644 include/nudb/xxhasher.hpp create mode 100644 scripts/blacklist.supp create mode 100755 scripts/build-and-test.sh create mode 100755 scripts/install-boost.sh create mode 100755 scripts/install-dependencies.sh create mode 100755 scripts/install-valgrind.sh create mode 100755 scripts/run-with-debugger.sh create mode 100755 scripts/run-with-gdb.sh create mode 100644 test/CMakeLists.txt create mode 100644 test/Jamfile create mode 100644 test/basic_store.cpp create mode 100644 test/buffer.cpp create mode 100644 test/callgrind_test.cpp create mode 100644 test/concepts.cpp create mode 100644 test/create.cpp create mode 100644 test/error.cpp create mode 100644 test/file.cpp create mode 100644 test/native_file.cpp create mode 100644 test/posix_file.cpp create mode 100644 test/recover.cpp create mode 100644 test/rekey.cpp create mode 100644 test/store.cpp create mode 100644 test/type_traits.cpp create mode 100644 test/verify.cpp create mode 100644 test/version.cpp create mode 100644 test/visit.cpp create mode 100644 test/win32_file.cpp create mode 100644 test/xxhasher.cpp create mode 100644 tools/CMakeLists.txt create mode 100644 tools/Jamfile create mode 100644 tools/nudb.cpp diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..99f984bda --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +bin/ +bin64/ diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 000000000..0115ab4e4 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,9 @@ +[submodule "extras/beast"] + path = extras/beast + url = https://github.com/vinniefalco/Beast.git +[submodule "extras/rocksdb"] + path = extras/rocksdb + url = https://github.com/facebook/rocksdb.git +[submodule "doc/docca"] + path = doc/docca + url = https://github.com/vinniefalco/docca.git diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 000000000..1900451f9 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,89 @@ +language: cpp + +env: + global: + - LLVM_VERSION=3.8.0 + # Maintenance note: to move to a new version + # of boost, update both BOOST_ROOT and BOOST_URL. + # Note that for simplicity, BOOST_ROOT's final + # namepart must match the folder name internal + # to boost's .tar.gz. + - LCOV_ROOT=$HOME/lcov + - VALGRIND_ROOT=$HOME/valgrind-install + - BOOST_ROOT=$HOME/boost_1_60_0 + - BOOST_URL='http://downloads.sourceforge.net/project/boost/boost/1.60.0/boost_1_60_0.tar.gz?r=https%3A%2F%2Fsourceforge.net%2Fprojects%2Fboost%2Ffiles%2Fboost%2F1.60.0%2Fboost_1_60_0.tar.gz&ts=1460417589&use_mirror=netix' +packages: &gcc5_pkgs + - gcc-5 + - g++-5 + - python-software-properties + - libssl-dev + - libffi-dev + - libstdc++6 + - binutils-gold + # Provides a backtrace if the unittests crash + - gdb + # Needed for installing valgrind + - subversion + - automake + - autotools-dev + - libc6-dbg + # Needed to build rocksdb + - libsnappy-dev + +matrix: + include: + # GCC/Coverage/Autobahn + - compiler: gcc + env: + - GCC_VER=5 + - VARIANT=coverage + - ADDRESS_MODEL=64 + - BUILD_SYSTEM=cmake + - PATH=$PWD/cmake/bin:$PATH + addons: &ao_gcc5 + apt: + sources: ['ubuntu-toolchain-r-test'] + packages: *gcc5_pkgs + + # Clang/UndefinedBehaviourSanitizer + - compiler: clang + env: + - GCC_VER=5 + - VARIANT=usan + - CLANG_VER=3.8 + - ADDRESS_MODEL=64 + - UBSAN_OPTIONS='print_stacktrace=1' + - BUILD_SYSTEM=cmake + - PATH=$PWD/cmake/bin:$PATH + - PATH=$PWD/llvm-$LLVM_VERSION/bin:$PATH + addons: *ao_gcc5 + + # Clang/AddressSanitizer + - compiler: clang + env: + - GCC_VER=5 + - VARIANT=asan + - CLANG_VER=3.8 + - ADDRESS_MODEL=64 + - PATH=$PWD/llvm-$LLVM_VERSION/bin:$PATH + addons: *ao_gcc5 + +cache: + directories: + - $BOOST_ROOT + - $VALGRIND_ROOT + - llvm-$LLVM_VERSION + - cmake + +before_install: + - scripts/install-dependencies.sh + +script: + - scripts/build-and-test.sh + +after_script: + - cat nohup.out || echo "nohup.out already deleted" + +notifications: + email: + false diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 000000000..d7d65c3fe --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,58 @@ +1.0.0-b6 + +* Fix incorrect file deletion in create() + +--- + +1.0.0-b5 + +* fail_file also fails on reads +* Fix bug in rekey where an error code wasn't checked +* Increase coverage +* Add buffer unit test +* Add is_File concept and checks +* Update documentation +* Add example program +* Demote exceptions to asserts in gentex +* Improved commit process +* Dynamic block size in custom allocator + +--- + +1.0.0-b4 + +* Improved test coverage +* Use master branch for codecov badge +* Throw on API calls when no database open +* Benchmarks vs. RocksDB + +### API Changes: + +* `insert` sets `error::key_exists` instead of returning `false` +* `fetch` sets `error::key_not_found` instead of returning `false` + +--- + +1.0.0-b3 + +* Tune buffer sizes for performance +* Fix large POSIX and Win32 writes +* Adjust progress indicator for nudb tool +* Document link requirements +* Add visit test +* Improved coverage + +--- + +1.0.0-b2 + +* Minor documentation and tidying +* Add CHANGELOG + +--- + +1.0.0-b1 + +* Initial source tree + + diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 000000000..af1bfc33a --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,87 @@ +cmake_minimum_required (VERSION 3.2) + +project (nudb) + +set_property (GLOBAL PROPERTY USE_FOLDERS ON) + +if (WIN32) + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP /W4 /wd4100 /D _WIN32_WINNT=0x0600 /D_SCL_SECURE_NO_WARNINGS=1 /D_CRT_SECURE_NO_WARNINGS=1") + set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SAFESEH:NO") +else () + set (Boost_USE_STATIC_LIBS ON) + set (Boost_USE_MULTITHREADED ON) + find_package (Boost REQUIRED COMPONENTS filesystem program_options system thread) + include_directories (SYSTEM ${Boost_INCLUDE_DIRS}) + link_directories (${Boost_LIBRARY_DIR}) + + set (THREADS_PREFER_PTHREAD_FLAG ON) + find_package (Threads) + + set (CMAKE_CXX_FLAGS + "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Wpedantic") +endif () + +if ("${VARIANT}" STREQUAL "coverage") + set (CMAKE_CXX_FLAGS + "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage") + set (CMAKE_BUILD_TYPE RELWITHDEBINFO) + set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lgcov") +elseif ("${VARIANT}" STREQUAL "asan") + set (CMAKE_CXX_FLAGS + "${CMAKE_CXX_FLAGS} -fsanitize=address -fno-omit-frame-pointer") + set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address") + set (CMAKE_BUILD_TYPE RELWITHDEBINFO) +elseif ("${VARIANT}" STREQUAL "usan") + set (CMAKE_CXX_FLAGS + "${CMAKE_CXX_FLAGS} -fsanitize=undefined -fno-omit-frame-pointer") + set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=undefined") + set (CMAKE_BUILD_TYPE RELWITHDEBINFO) +elseif ("${VARIANT}" STREQUAL "debug") + set (CMAKE_BUILD_TYPE DEBUG) +elseif ("${VARIANT}" STREQUAL "release") + set (CMAKE_BUILD_TYPE RELEASE) +endif () + +function (DoGroupSources curdir rootdir folder) + file (GLOB children RELATIVE ${PROJECT_SOURCE_DIR}/${curdir} ${PROJECT_SOURCE_DIR}/${curdir}/*) + foreach (child ${children}) + if (IS_DIRECTORY ${PROJECT_SOURCE_DIR}/${curdir}/${child}) + DoGroupSources (${curdir}/${child} ${rootdir} ${folder}) + elseif (${child} STREQUAL "CMakeLists.txt") + source_group ("" FILES ${PROJECT_SOURCE_DIR}/${curdir}/${child}) + else () + string (REGEX REPLACE ^${rootdir} ${folder} groupname ${curdir}) + #set (groupname ${curdir}) + string (REPLACE "/" "\\" groupname ${groupname}) + source_group (${groupname} FILES ${PROJECT_SOURCE_DIR}/${curdir}/${child}) + endif () + endforeach () +endfunction () + +function (GroupSources curdir folder) + DoGroupSources (${curdir} ${curdir} ${folder}) +endfunction () + +include_directories ( + include + extras + extras/beast/extras + ) + +file (GLOB_RECURSE BEAST_INCLUDES + ${PROJECT_SOURCE_DIR}/extras/beast/extras/beast/unit_test/*.hpp + ${PROJECT_SOURCE_DIR}/extras/beast/extras/beast/unit_test/*.ipp +) + +file (GLOB_RECURSE EXTRAS_INCLUDES + ${PROJECT_SOURCE_DIR}/extras/nudb/* +) + +file (GLOB_RECURSE NUDB_INCLUDES + ${PROJECT_SOURCE_DIR}/include/nudb/* +) + +add_subdirectory (bench) +add_subdirectory (examples) +add_subdirectory (test) +add_subdirectory (tools) diff --git a/Jamroot b/Jamroot new file mode 100644 index 000000000..7c140b811 --- /dev/null +++ b/Jamroot @@ -0,0 +1,93 @@ +# +# Copyright (c) 2013-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +# +# Distributed under the Boost Software License, Version 1.0. (See accompanying +# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +# + +import os ; +import feature ; +import boost ; + +boost.use-project ; + +variant coverage + : + debug + : + "-fprofile-arcs -ftest-coverage" + "-lgcov" + ; + +variant asan + : + release + : + "-fsanitize=address -fno-omit-frame-pointer" + "-fsanitize=address" + ; + +variant msan + : + debug + : + "-fsanitize=memory -fno-omit-frame-pointer -fsanitize-memory-track-origins=2 -fsanitize-memory-use-after-dtor" + "-fsanitize=memory" + ; + +variant usan + : + debug + : + "-fsanitize=undefined -fno-omit-frame-pointer" + "-fsanitize=undefined" + ; + +project nudb + : requirements + ./extras + ./extras/beast/extras + ./include + #/boost//headers + /boost/system//boost_system + /boost/thread//boost_thread + /boost/filesystem//boost_filesystem + /boost/program_options//boost_program_options + BOOST_ALL_NO_LIB=1 + BOOST_SYSTEM_NO_DEPRECATED=1 + multi + static + shared + on + gcc:-std=c++11 + gcc:-Wno-unused-variable + clang:-std=c++11 + msvc:_SCL_SECURE_NO_WARNINGS=1 + msvc:_CRT_SECURE_NO_WARNINGS=1 + msvc:-bigobj + LINUX:_XOPEN_SOURCE=600 + LINUX:_GNU_SOURCE=1 + SOLARIS:_XOPEN_SOURCE=500 + SOLARIS:__EXTENSIONS__ + SOLARIS:socket + SOLARIS:nsl + NT:_WIN32_WINNT=0x0601 + NT,cw:ws2_32 + NT,cw:mswsock + NT,gcc:ws2_32 + NT,gcc:mswsock + NT,gcc-cygwin:__USE_W32_SOCKETS + HPUX,gcc:_XOPEN_SOURCE_EXTENDED + HPUX:ipv6 + QNXNTO:socket + HAIKU:network + : usage-requirements + . + : + build-dir bin + ; + +build-project bench ; +build-project examples ; +build-project test ; +build-project tools ; diff --git a/LICENSE_1_0.txt b/LICENSE_1_0.txt new file mode 100644 index 000000000..36b7cd93c --- /dev/null +++ b/LICENSE_1_0.txt @@ -0,0 +1,23 @@ +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 000000000..4d3b0d7e8 --- /dev/null +++ b/README.md @@ -0,0 +1,466 @@ +NuDB + +[![Join the chat at https://gitter.im/vinniefalco/NuDB](https://badges.gitter.im/vinniefalco/NuDB.svg)](https://gitter.im/vinniefalco/NuDB?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Build Status] +(https://travis-ci.org/vinniefalco/NuDB.svg?branch=master)](https://travis-ci.org/vinniefalco/NuDB) [![codecov] +(https://codecov.io/gh/vinniefalco/NuDB/branch/master/graph/badge.svg)](https://codecov.io/gh/vinniefalco/NuDB) [![coveralls] +(https://coveralls.io/repos/github/vinniefalco/NuDB/badge.svg?branch=master)](https://coveralls.io/github/vinniefalco/NuDB?branch=master) [![Documentation] +(https://img.shields.io/badge/documentation-master-brightgreen.svg)](http://vinniefalco.github.io/nudb/) [![License] +(https://img.shields.io/badge/license-boost-brightgreen.svg)](LICENSE_1_0.txt) + +# A Key/Value Store For SSDs + +--- + +## Contents + +- [Introduction](#introduction) +- [Description](#description) +- [Requirements](#requirements) +- [Example](#example) +- [Building](#building) +- [Algorithm](#algorithm) +- [Licence](#licence) +- [Contact](#contact) + +--- + +## Introduction + +NuDB is an append-only, key/value store specifically optimized for random +read performance on modern SSDs or equivalent high-IOPS devices. The most +common application for NuDB is content addressible storage where a +cryptographic digest of the data is used as the key. The read performance +and memory usage are independent of the size of the database. These are +some other features: + +* Low memory footprint +* Database size up to 281TB +* All keys are the same size +* Append-only, no update or delete +* Value sizes from 1 to 2^32 bytes (4GB) +* Performance independent of growth +* Optimized for concurrent fetch +* Key file can be rebuilt if needed +* Inserts are atomic and consistent +* Data file may be efficiently iterated +* Key and data files may be on different devices +* Hardened against algorithmic complexity attacks +* Header-only, no separate library to build + +## Description + +This software is close to final. Interfaces are stable. +For recent changes see the [CHANGELOG](CHANGELOG.md). + +NuDB has been in use for over a year on production servers +running [rippled](https://github.com/ripple/rippled), with +database sizes over 3 terabytes. + +* [Repository](https://github.com/vinniefalco/Beast) +* [Documentation](http://vinniefalco.github.io/nudb/) + +## Requirements + +* Boost 1.58 or higher +* C++11 or greater +* SSD drive, or equivalent device with high IOPS + +## Example + +This complete program creates a database, opens the database, +inserts several key/value pairs, fetches the key/value pairs, +closes the database, then erases the database files. Source +code for this program is located in the examples directory. + +```C++ +#include +#include +#include + +int main() +{ + using namespace nudb; + std::size_t constexpr N = 1000; + using key_type = std::uint32_t; + error_code ec; + auto const dat_path = "db.dat"; + auto const key_path = "db.key"; + auto const log_path = "db.log"; + create( + dat_path, key_path, log_path, + 1, + make_salt(), + sizeof(key_type), + block_size("."), + 0.5f, + ec); + store db; + db.open(dat_path, key_path, log_path, ec); + char data = 0; + // Insert + for(key_type i = 0; i < N; ++i) + db.insert(&i, &data, sizeof(data), ec); + // Fetch + for(key_type i = 0; i < N; ++i) + db.fetch(&i, + [&](void const* buffer, std::size_t size) + { + // do something with buffer, size + }, ec); + db.close(ec); + erase_file(dat_path); + erase_file(key_path); + erase_file(log_path); +} +``` + +## Building + +NuDB is header-only so there are no libraries to build. To use it in your +project, simply copy the NuDB sources to your project's source tree +(alternatively, bring NuDB into your Git repository using the +`git subtree` or `git submodule` commands). Then, edit your build scripts +to add the `include/` directory to the list of paths checked by the C++ +compiler when searching for includes. NuDB `#include` lines will look +like this: + +``` +#include +``` + +To link your program successfully, you'll need to add the Boost.Thread and +Boost.System libraries to link with. Please visit the Boost documentation +for instructions on how to do this for your particular build system. + +NuDB tests require Beast, and the benchmarks require RocksDB. These projects +are linked to the repository using git submodules. Before building the tests +or benchmarks, these commands should be issued at the root of the repository: + +``` +git submodule init +git submodule update +``` + +For the examples and tests, NuDB provides build scripts for Boost.Build (b2) +and CMake. To generate build scripts using CMake, execute these commands at +the root of the repository (project and solution files will be generated +for Visual Studio users): + +``` +cd bin +cmake .. # for 32-bit Windows build + +cd ../bin64 +cmake .. # for Linux/Mac builds, OR +cmake -G"Visual Studio 14 2015 Win64" .. # for 64-bit Windows builds +``` + +To build with Boost.Build, it is necessary to have the b2 executable +in your path. And b2 needs to know how to find the Boost sources. The +easiest way to do this is make sure that the version of b2 in your path +is the one at the root of the Boost source tree, which is built when +running `bootstrap.sh` (or `bootstrap.bat` on Windows). + +Once b2 is in your path, simply run b2 in the root of the Beast +repository to automatically build the required Boost libraries if they +are not already built, build the examples, then build and run the unit +tests. + +On OSX it may be necessary to pass "toolset=clang" on the b2 command line. +Alternatively, this may be site in site-config.jam or user-config.jam. + +The files in the repository are laid out thusly: + +``` +./ + bench/ Holds the benchmark sources and scripts + bin/ Holds executables and project files + bin64/ Holds 64-bit Windows executables and project files + examples/ Holds example program source code + extras/ Additional APIs, may change + include/ Add this to your compiler includes + nudb/ + test/ Unit tests and benchmarks + tools/ Holds the command line tool sources +``` + +## Algorithm + +Three files are used. + +* The data file holds keys and values stored sequentially and size-prefixed. +* The key file holds a series of fixed-size bucket records forming an on-disk + hash table. +* The log file stores bookkeeping information used to restore consistency when +an external failure occurs. + +In typical cases a fetch costs one I/O cycle to consult the key file, and if the +key is present, one I/O cycle to read the value. + +### Usage + +Callers must define these parameters when _creating_ a database: + +* `KeySize`: The size of a key in bytes. +* `BlockSize`: The physical size of a key file record. + +The ideal block size matches the sector size or block size of the +underlying physical media that holds the key file. Functions are +provided to return a best estimate of this value for a particular +device, but a default of 4096 should work for typical installations. +The implementation tries to fit as many entries as possible in a key +file record, to maximize the amount of useful work performed per I/O. + +* `LoadFactor`: The desired fraction of bucket occupancy + +`LoadFactor` is chosen to make bucket overflows unlikely without +sacrificing bucket occupancy. A value of 0.50 seems to work well with +a good hash function. + +Callers must also provide these parameters when a database is _opened:_ + +* `Appnum`: An application-defined integer constant which can be retrieved +later from the database [TODO]. +* `AllocSize`: A significant multiple of the average data size. + +Memory is recycled to improve performance, so NuDB needs `AllocSize` as a +hint about the average size of the data being inserted. For an average data size +of 1KB (one kilobyte), `AllocSize` of sixteen megabytes (16MB) is sufficient. If +the `AllocSize` is too low, the memory recycler will not make efficient use of +allocated blocks. + +Two operations are defined: `fetch`, and `insert`. + +#### `fetch` + +The `fetch` operation retrieves a variable length value given the +key. The caller supplies a factory used to provide a buffer for storing +the value. This interface allows custom memory allocation strategies. + +#### `insert` + +`insert` adds a key/value pair to the store. Value data must contain at least +one byte. Duplicate keys are disallowed. Insertions are serialized, which means +[TODO]. + +### Implementation + +All insertions are buffered in memory, with inserted values becoming +immediately discoverable in subsequent or concurrent calls to fetch. +Periodically, buffered data is safely committed to disk files using +a separate dedicated thread associated with the database. This commit +process takes place at least once per second, or more often during +a detected surge in insertion activity. In the commit process the +key/value pairs receive the following treatment: + +An insertion is performed by appending a value record to the data file. +The value record has some header information including the size of the +data and a copy of the key; the data file is iteratable without the key +file. The value data follows the header. The data file is append-only +and immutable: once written, bytes are never changed. + +Initially the hash table in the key file consists of a single bucket. +After the load factor is exceeded from insertions, the hash table grows +in size by one bucket by doing a "split". The split operation is the +[linear hashing algorithm](http://en.wikipedia.org/wiki/Linear_hashing) +as described by Litwin and Larson. + +When a bucket is split, each key is rehashed, and either remains in the +original bucket or gets moved to the a bucket appended to the end of +the key file. + +An insertion on a full bucket first triggers the "spill" algorithm. + +First, a spill record is appended to the data file, containing header +information followed by the entire bucket record. Then the bucket's size is set +to zero and the offset of the spill record is stored in the bucket. At this +point the insertion may proceed normally, since the bucket is empty. Spilled +buckets in the data file are always full. + +Because every bucket holds the offset of the next spill record in the +data file, the buckets form a linked list. In practice, careful +selection of capacity and load factor will keep the percentage of +buckets with one spill record to a minimum, with no bucket requiring +two spill records. + +The implementation of fetch is straightforward: first the bucket in the +key file is checked, then each spill record in the linked list of +spill records is checked, until the key is found or there are no more +records. As almost all buckets have no spill records, the average +fetch requires one I/O (not including reading the value). + +One complication in the scheme is when a split occurs on a bucket that +has one or more spill records. In this case, both the bucket being split +and the new bucket may overflow. This is handled by performing the +spill algorithm for each overflow that occurs. The new buckets may have +one or more spill records each, depending on the number of keys that +were originally present. + +Because the data file is immutable, a bucket's original spill records +are no longer referenced after the bucket is split. These blocks of data +in the data file are unrecoverable wasted space. Correctly configured +databases can have a typical waste factor of 1%, which is acceptable. +These unused bytes can be removed by visiting each value in the value +file using an off-line process and inserting it into a new database, +then delete the old database and use the new one instead. + +### Recovery + +To provide atomicity and consistency, a log file associated with the +database stores information used to roll back partial commits. + +### Iteration + +Each record in the data file is prefixed with a header identifying +whether it is a value record or a spill record, along with the size of +the record in bytes and a copy of the key if it's a value record, so values can +be iterated by incrementing a byte counter. A key file can be regenerated from +just the data file by iterating the values and performing the key +insertion algorithm. + +### Concurrency + +Locks are never held during disk reads and writes. Fetches are fully +concurrent, while inserts are serialized. Inserts fail on duplicate +keys, and are atomic: they either succeed immediately or fail. +After an insert, the key is immediately visible to subsequent fetches. + +### Formats + +All integer values are stored as big endian. The uint48_t format +consists of 6 bytes. + +#### Key File + +The Key File contains the Header followed by one or more +fixed-length Bucket Records. + +#### Header (104 bytes) + + char[8] Type The characters "nudb.key" + uint16 Version Holds the version number + uint64 UID Unique ID generated on creation + uint64 Appnum Application defined constant + uint16 KeySize Key size in bytes + + uint64 Salt A random seed + uint64 Pepper The salt hashed + uint16 BlockSize Size of a file block in bytes + + uint16 LoadFactor Target fraction in 65536ths + + uint8[56] Reserved Zeroes + uint8[] Reserved Zero-pad to block size + +`Type` identifies the file as belonging to nudb. `UID` is +generated randomly when the database is created, and this value +is stored in the data and log files as well - it's used +to determine if files belong to the same database. `Salt` is +generated when the database is created and helps prevent +complexity attacks; it is prepended to the key material +when computing a hash, or used to initialize the state of +the hash function. `Appnum` is an application defined constant +set when the database is created. It can be used for anything, +for example to distinguish between different data formats. + +`Pepper` is computed by hashing `Salt` using a hash function +seeded with the salt. This is used to fingerprint the hash +function used. If a database is opened and the fingerprint +does not match the hash calculation performed using the template +argument provided when constructing the store, an exception +is thrown. + +The header for the key file contains the File Header followed by +the information above. The Capacity is the number of keys per +bucket, and defines the size of a bucket record. The load factor +is the target fraction of bucket occupancy. + +None of the information in the key file header or the data file +header may be changed after the database is created, including +the Appnum. + +#### Bucket Record (fixed-length) + + uint16 Count Number of keys in this bucket + uint48 Spill Offset of the next spill record or 0 + BucketEntry[] Entries The bucket entries + +#### Bucket Entry + + uint48 Offset Offset in data file of the data + uint48 Size The size of the value in bytes + uint48 Hash The hash of the key + +### Data File + +The Data File contains the Header followed by zero or more +variable-length Value Records and Spill Records. + +#### Header (92 bytes) + + char[8] Type The characters "nudb.dat" + uint16 Version Holds the version number + uint64 UID Unique ID generated on creation + uint64 Appnum Application defined constant + uint16 KeySize Key size in bytes + uint8[64] (reserved) Zeroes + +UID contains the same value as the salt in the corresponding key +file. This is placed in the data file so that key and value files +belonging to the same database can be identified. + +#### Data Record (variable-length) + + uint48 Size Size of the value in bytes + uint8[KeySize] Key The key. + uint8[Size] Data The value data. + +#### Spill Record (fixed-length) + + uint48 Zero All zero, identifies a spill record + uint16 Size Bytes in spill bucket (for skipping) + Bucket SpillBucket Bucket Record + +#### Log File + +The Log file contains the Header followed by zero or more fixed size +log records. Each log record contains a snapshot of a bucket. When a +database is not closed cleanly, the recovery process applies the log +records to the key file, overwriting data that may be only partially +updated with known good information. After the log records are applied, +the data and key files are truncated to the last known good size. + +#### Header (62 bytes) + + char[8] Type The characters "nudb.log" + uint16 Version Holds the version number + uint64 UID Unique ID generated on creation + uint64 Appnum Application defined constant + uint16 KeySize Key size in bytes + + uint64 Salt A random seed. + uint64 Pepper The salt hashed + uint16 BlockSize Size of a file block in bytes + + uint64 KeyFileSize Size of key file. + uint64 DataFileSize Size of data file. + +#### Log Record + + uint64_t Index Bucket index (0-based) + Bucket Bucket Compact Bucket record + +Compact buckets include only Size entries. These are primarily +used to minimize the volume of writes to the log file. + +## License + +Distributed under the Boost Software License, Version 1.0. +(See accompanying file [LICENSE_1_0.txt](LICENSE_1_0.txt) or copy at +http://www.boost.org/LICENSE_1_0.txt) + +## Contact + +Please report issues or questions here: +https://github.com/vinniefalco/NuDB/issues diff --git a/TODO.txt b/TODO.txt new file mode 100644 index 000000000..432f76212 --- /dev/null +++ b/TODO.txt @@ -0,0 +1,2 @@ +* Support 32/64-bit + -- xxhasher specialization for 4/8 byte size-t diff --git a/bench/CMakeLists.txt b/bench/CMakeLists.txt new file mode 100644 index 000000000..ab96d1df1 --- /dev/null +++ b/bench/CMakeLists.txt @@ -0,0 +1,363 @@ +cmake_minimum_required (VERSION 3.2) + +GroupSources(bench /) +GroupSources(include/nudb nudb) +GroupSources(extras/nudb extras) +GroupSources(extras/beast/include/beast beast) +GroupSources(extras/beast/extras/beast beast) +GroupSources(extras/rocksdb rocksdb) + +if (WIN32) + set(CMAKE_CONFIGURATION_TYPES Release) +endif () + +project (bench) + +############################################################ + +macro(append_flags name) + foreach (arg ${ARGN}) + set(${name} "${${name}} ${arg}") + endforeach() +endmacro() + +############################################################ + +set (DEPS "${PROJECT_SOURCE_DIR}/../extras") + +set (DEFAULT_WITH_ROCKSDB true) + +set (WITH_ROCKSDB ${DEFAULT_WITH_ROCKSDB} CACHE BOOL "Runs benchmarks against rocksdb") + +if (WITH_ROCKSDB) + set(ROCKSDB ${DEPS}/rocksdb) + + set(ROCKSDB_SRC + ${ROCKSDB}/db/auto_roll_logger.cc + ${ROCKSDB}/db/builder.cc + ${ROCKSDB}/db/c.cc + ${ROCKSDB}/db/column_family.cc + ${ROCKSDB}/db/compacted_db_impl.cc + ${ROCKSDB}/db/compaction.cc + ${ROCKSDB}/db/compaction_iterator.cc + ${ROCKSDB}/db/compaction_job.cc + ${ROCKSDB}/db/compaction_picker.cc + ${ROCKSDB}/db/convenience.cc + ${ROCKSDB}/db/db_filesnapshot.cc + ${ROCKSDB}/db/dbformat.cc + ${ROCKSDB}/db/db_impl.cc + ${ROCKSDB}/db/db_impl_debug.cc + ${ROCKSDB}/db/db_impl_readonly.cc + ${ROCKSDB}/db/db_impl_experimental.cc + ${ROCKSDB}/db/db_impl_add_file.cc + ${ROCKSDB}/db/db_info_dumper.cc + ${ROCKSDB}/db/db_iter.cc + ${ROCKSDB}/db/experimental.cc + ${ROCKSDB}/db/event_helpers.cc + ${ROCKSDB}/db/file_indexer.cc + ${ROCKSDB}/db/filename.cc + ${ROCKSDB}/db/flush_job.cc + ${ROCKSDB}/db/flush_scheduler.cc + ${ROCKSDB}/db/forward_iterator.cc + ${ROCKSDB}/db/internal_stats.cc + ${ROCKSDB}/db/log_reader.cc + ${ROCKSDB}/db/log_writer.cc + ${ROCKSDB}/db/managed_iterator.cc + ${ROCKSDB}/db/memtable_allocator.cc + ${ROCKSDB}/db/memtable.cc + ${ROCKSDB}/db/memtable_list.cc + ${ROCKSDB}/db/merge_helper.cc + ${ROCKSDB}/db/merge_operator.cc + ${ROCKSDB}/db/repair.cc + ${ROCKSDB}/db/snapshot_impl.cc + ${ROCKSDB}/db/table_cache.cc + ${ROCKSDB}/db/table_properties_collector.cc + ${ROCKSDB}/db/transaction_log_impl.cc + ${ROCKSDB}/db/version_builder.cc + ${ROCKSDB}/db/version_edit.cc + ${ROCKSDB}/db/version_set.cc + ${ROCKSDB}/db/wal_manager.cc + ${ROCKSDB}/db/write_batch.cc + ${ROCKSDB}/db/write_batch_base.cc + ${ROCKSDB}/db/write_controller.cc + ${ROCKSDB}/db/write_thread.cc + ${ROCKSDB}/db/xfunc_test_points.cc + ${ROCKSDB}/memtable/hash_cuckoo_rep.cc + ${ROCKSDB}/memtable/hash_linklist_rep.cc + ${ROCKSDB}/memtable/hash_skiplist_rep.cc + ${ROCKSDB}/memtable/skiplistrep.cc + ${ROCKSDB}/memtable/vectorrep.cc + ${ROCKSDB}/port/stack_trace.cc + ${ROCKSDB}/table/adaptive_table_factory.cc + ${ROCKSDB}/table/block_based_filter_block.cc + ${ROCKSDB}/table/block_based_table_builder.cc + ${ROCKSDB}/table/block_based_table_factory.cc + ${ROCKSDB}/table/block_based_table_reader.cc + ${ROCKSDB}/table/block_builder.cc + ${ROCKSDB}/table/block.cc + ${ROCKSDB}/table/block_prefix_index.cc + ${ROCKSDB}/table/bloom_block.cc + ${ROCKSDB}/table/cuckoo_table_builder.cc + ${ROCKSDB}/table/cuckoo_table_factory.cc + ${ROCKSDB}/table/cuckoo_table_reader.cc + ${ROCKSDB}/table/flush_block_policy.cc + ${ROCKSDB}/table/format.cc + ${ROCKSDB}/table/full_filter_block.cc + ${ROCKSDB}/table/get_context.cc + ${ROCKSDB}/table/iterator.cc + ${ROCKSDB}/table/merger.cc + ${ROCKSDB}/table/meta_blocks.cc + ${ROCKSDB}/table/sst_file_writer.cc + ${ROCKSDB}/table/plain_table_builder.cc + ${ROCKSDB}/table/plain_table_factory.cc + ${ROCKSDB}/table/plain_table_index.cc + ${ROCKSDB}/table/plain_table_key_coding.cc + ${ROCKSDB}/table/plain_table_reader.cc + ${ROCKSDB}/table/persistent_cache_helper.cc + ${ROCKSDB}/table/table_properties.cc + ${ROCKSDB}/table/two_level_iterator.cc + ${ROCKSDB}/tools/dump/db_dump_tool.cc + ${ROCKSDB}/util/arena.cc + ${ROCKSDB}/util/bloom.cc + # ${ROCKSDB}/util/build_version.cc + ${ROCKSDB}/util/coding.cc + ${ROCKSDB}/util/comparator.cc + ${ROCKSDB}/util/compaction_job_stats_impl.cc + ${ROCKSDB}/util/concurrent_arena.cc + ${ROCKSDB}/util/crc32c.cc + ${ROCKSDB}/util/delete_scheduler.cc + ${ROCKSDB}/util/dynamic_bloom.cc + ${ROCKSDB}/util/env.cc + ${ROCKSDB}/util/env_chroot.cc + ${ROCKSDB}/util/env_hdfs.cc + ${ROCKSDB}/util/file_util.cc + ${ROCKSDB}/util/file_reader_writer.cc + ${ROCKSDB}/util/filter_policy.cc + ${ROCKSDB}/util/hash.cc + ${ROCKSDB}/util/histogram.cc + ${ROCKSDB}/util/histogram_windowing.cc + ${ROCKSDB}/util/instrumented_mutex.cc + ${ROCKSDB}/util/iostats_context.cc + ${ROCKSDB}/util/lru_cache.cc + ${ROCKSDB}/util/threadpool.cc + ${ROCKSDB}/util/transaction_test_util.cc + ${ROCKSDB}/util/sharded_cache.cc + ${ROCKSDB}/util/sst_file_manager_impl.cc + ${ROCKSDB}/utilities/backupable/backupable_db.cc + ${ROCKSDB}/utilities/blob_db/blob_db.cc + ${ROCKSDB}/utilities/convenience/info_log_finder.cc + ${ROCKSDB}/utilities/checkpoint/checkpoint.cc + ${ROCKSDB}/utilities/compaction_filters/remove_emptyvalue_compactionfilter.cc + ${ROCKSDB}/utilities/document/document_db.cc + ${ROCKSDB}/utilities/document/json_document_builder.cc + ${ROCKSDB}/utilities/document/json_document.cc + ${ROCKSDB}/utilities/env_mirror.cc + ${ROCKSDB}/utilities/env_registry.cc + ${ROCKSDB}/utilities/flashcache/flashcache.cc + ${ROCKSDB}/utilities/geodb/geodb_impl.cc + ${ROCKSDB}/utilities/leveldb_options/leveldb_options.cc + ${ROCKSDB}/utilities/memory/memory_util.cc + ${ROCKSDB}/utilities/merge_operators/put.cc + ${ROCKSDB}/utilities/merge_operators/max.cc + ${ROCKSDB}/utilities/merge_operators/string_append/stringappend2.cc + ${ROCKSDB}/utilities/merge_operators/string_append/stringappend.cc + ${ROCKSDB}/utilities/merge_operators/uint64add.cc + ${ROCKSDB}/utilities/option_change_migration/option_change_migration.cc + ${ROCKSDB}/utilities/options/options_util.cc + ${ROCKSDB}/utilities/persistent_cache/persistent_cache_tier.cc + ${ROCKSDB}/utilities/persistent_cache/volatile_tier_impl.cc + ${ROCKSDB}/utilities/persistent_cache/block_cache_tier_file.cc + ${ROCKSDB}/utilities/persistent_cache/block_cache_tier_metadata.cc + ${ROCKSDB}/utilities/persistent_cache/block_cache_tier.cc + ${ROCKSDB}/utilities/redis/redis_lists.cc + ${ROCKSDB}/utilities/simulator_cache/sim_cache.cc + ${ROCKSDB}/utilities/spatialdb/spatial_db.cc + ${ROCKSDB}/utilities/table_properties_collectors/compact_on_deletion_collector.cc + ${ROCKSDB}/utilities/transactions/optimistic_transaction_impl.cc + ${ROCKSDB}/utilities/transactions/optimistic_transaction_db_impl.cc + ${ROCKSDB}/utilities/transactions/transaction_base.cc + ${ROCKSDB}/utilities/transactions/transaction_db_impl.cc + ${ROCKSDB}/utilities/transactions/transaction_db_mutex_impl.cc + ${ROCKSDB}/utilities/transactions/transaction_lock_mgr.cc + ${ROCKSDB}/utilities/transactions/transaction_impl.cc + ${ROCKSDB}/utilities/transactions/transaction_util.cc + ${ROCKSDB}/utilities/ttl/db_ttl_impl.cc + ${ROCKSDB}/utilities/date_tiered/date_tiered_db_impl.cc + ${ROCKSDB}/utilities/write_batch_with_index/write_batch_with_index.cc + ${ROCKSDB}/utilities/write_batch_with_index/write_batch_with_index_internal.cc + ${ROCKSDB}/util/event_logger.cc + ${ROCKSDB}/util/log_buffer.cc + ${ROCKSDB}/util/logging.cc + ${ROCKSDB}/util/memenv.cc + ${ROCKSDB}/util/murmurhash.cc + ${ROCKSDB}/util/mutable_cf_options.cc + ${ROCKSDB}/util/options.cc + ${ROCKSDB}/util/options_helper.cc + ${ROCKSDB}/util/options_parser.cc + ${ROCKSDB}/util/options_sanity_check.cc + ${ROCKSDB}/util/perf_context.cc + ${ROCKSDB}/util/perf_level.cc + ${ROCKSDB}/util/random.cc + ${ROCKSDB}/util/rate_limiter.cc + ${ROCKSDB}/util/slice.cc + ${ROCKSDB}/util/statistics.cc + ${ROCKSDB}/util/status.cc + ${ROCKSDB}/util/status_message.cc + ${ROCKSDB}/util/string_util.cc + ${ROCKSDB}/util/sync_point.cc + ${ROCKSDB}/util/thread_local.cc + ${ROCKSDB}/util/thread_status_impl.cc + ${ROCKSDB}/util/thread_status_updater.cc + ${ROCKSDB}/util/thread_status_updater_debug.cc + ${ROCKSDB}/util/thread_status_util.cc + ${ROCKSDB}/util/thread_status_util_debug.cc + ${ROCKSDB}/util/xfunc.cc + ${ROCKSDB}/util/xxhash.cc + ) + + if (WIN32) + add_definitions( + -DOS_WIN + ) + set(ROCKSDB_SRC ${ROCKSDB_SRC} + ${ROCKSDB}/port/win/io_win.cc + ${ROCKSDB}/port/win/env_default.cc + ${ROCKSDB}/port/win/env_win.cc + ${ROCKSDB}/port/win/port_win.cc + ${ROCKSDB}/port/win/win_logger.cc + ${ROCKSDB}/port/win/xpress_win.cc + ) + else () + #if (${CMAKE_SYSTEM_NAME} MATCHES Linux) + add_definitions( + -DOS_LINUX + -DROCKSDB_PLATFORM_POSIX + -DROCKSDB_LIB_IO_POSIX + ) + set(ROCKSDB_SRC ${ROCKSDB_SRC} + ${ROCKSDB}/util/io_posix.cc + ${ROCKSDB}/util/env_posix.cc + ${ROCKSDB}/port/port_posix.cc + ) + endif () + + include_directories( + SYSTEM + ${ROCKSDB} + ${ROCKSDB}/include + ${ROCKSDB}/third-party/gtest-1.7.0/fused-src + ) + + add_definitions( + -DWITH_ROCKSDB + ) +endif(WITH_ROCKSDB) + +if (NOT WIN32) + append_flags(CMAKE_CXX_FLAGS -std=c++11) +endif () + +if(WIN32) + add_compile_options( + /bigobj # Increase object file max size + /EHa # ExceptionHandling all + /fp:precise # Floating point behavior + /Gd # __cdecl calling convention + /Gm- # Minimal rebuild: disabled + /GR # Enable RTTI + /Gy- # Function level linking: disabled + /FS + /MP # Multiprocessor compilation + /openmp- # pragma omp: disabled + /Zc:forScope # Language extension: for scope + /Zi # Generate complete debug info + /errorReport:none # No error reporting to Internet + /nologo # Suppress login banner + /W3 # Warning level 3 + /WX- # Disable warnings as errors + /wd"4018" + /wd"4244" + /wd"4267" + /wd"4800" # Disable C4800(int to bool performance) + /wd"4503" # Decorated name length exceeded, name was truncated + ) + + add_definitions( + -D_WIN32_WINNT=0x6000 + -D_ITERATOR_DEBUG_LEVEL=0 + -D_SCL_SECURE_NO_WARNINGS + -D_CRT_SECURE_NO_WARNINGS + -DWIN32_CONSOLE + -DNOMINMAX) + + append_flags(CMAKE_EXE_LINKER_FLAGS + /DEBUG + /DYNAMICBASE + /ERRORREPORT:NONE + /MACHINE:X64 + /MANIFEST + /nologo + /NXCOMPAT + /SUBSYSTEM:CONSOLE + /TLBID:1) + + # There seems to be an issue using generator experssions with multiple values, + # split the expression + # /GS Buffers security check: enable + add_compile_options($<$:/GS>) + # /MTd Language: Multi-threaded Debug CRT + add_compile_options($<$:/MTd>) + # /Od Optimization: Disabled + add_compile_options($<$:/Od>) + # /RTC1 Run-time error checks: + add_compile_options($<$:/RTC1>) + + # Generator expressions are not supported in add_definitions, use set_property instead + set_property( + DIRECTORY + APPEND + PROPERTY COMPILE_DEFINITIONS + $<$:_CRTDBG_MAP_ALLOC>) + + # /MT Language: Multi-threaded CRT + add_compile_options($<$:/MT>) + add_compile_options($<$:/Ox>) + # /Ox Optimization: Full + +endif (WIN32) + + +include_directories( + ../include + ../test + . + ${DEPS} + ) + +add_executable(bench + ${BEAST_INCLUDES} + ${EXTRAS_INCLUDES} + ${NUDB_INCLUDES} + ${ROCKSDB_SRC} + bench.cpp + ) + +target_link_libraries(bench + ${Boost_LIBRARIES} + ) + +if (WITH_ROCKSDB) + if (WIN32) + target_link_libraries(bench + Rpcrt4 + ) + else () + target_link_libraries(bench + rt + Threads::Threads + z + snappy + ) + endif () +endif () + diff --git a/bench/Jamfile b/bench/Jamfile new file mode 100644 index 000000000..42e863e12 --- /dev/null +++ b/bench/Jamfile @@ -0,0 +1,226 @@ +# +# Copyright (c) 2013-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +# +# Distributed under the Boost Software License, Version 1.0. (See accompanying +# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +# + +# Properties: +# +# with-rocksdb=no|yes Select building with rocksdb support (not supported on windows) + +import feature : feature ; + +path-constant ROCKSDB : ../extras/rocksdb ; + +feature with-rocksdb : no yes : propagated optional ; + +path-constant ROCKSDB_SRC : + $(ROCKSDB)/db/auto_roll_logger.cc + $(ROCKSDB)/db/builder.cc + $(ROCKSDB)/db/c.cc + $(ROCKSDB)/db/column_family.cc + $(ROCKSDB)/db/compacted_db_impl.cc + $(ROCKSDB)/db/compaction.cc + $(ROCKSDB)/db/compaction_iterator.cc + $(ROCKSDB)/db/compaction_job.cc + $(ROCKSDB)/db/compaction_picker.cc + $(ROCKSDB)/db/convenience.cc + $(ROCKSDB)/db/db_filesnapshot.cc + $(ROCKSDB)/db/dbformat.cc + $(ROCKSDB)/db/db_impl.cc + $(ROCKSDB)/db/db_impl_debug.cc + $(ROCKSDB)/db/db_impl_readonly.cc + $(ROCKSDB)/db/db_impl_experimental.cc + $(ROCKSDB)/db/db_impl_add_file.cc + $(ROCKSDB)/db/db_info_dumper.cc + $(ROCKSDB)/db/db_iter.cc + $(ROCKSDB)/db/experimental.cc + $(ROCKSDB)/db/event_helpers.cc + $(ROCKSDB)/db/file_indexer.cc + $(ROCKSDB)/db/filename.cc + $(ROCKSDB)/db/flush_job.cc + $(ROCKSDB)/db/flush_scheduler.cc + $(ROCKSDB)/db/forward_iterator.cc + $(ROCKSDB)/db/internal_stats.cc + $(ROCKSDB)/db/log_reader.cc + $(ROCKSDB)/db/log_writer.cc + $(ROCKSDB)/db/managed_iterator.cc + $(ROCKSDB)/db/memtable_allocator.cc + $(ROCKSDB)/db/memtable.cc + $(ROCKSDB)/db/memtable_list.cc + $(ROCKSDB)/db/merge_helper.cc + $(ROCKSDB)/db/merge_operator.cc + $(ROCKSDB)/db/repair.cc + $(ROCKSDB)/db/snapshot_impl.cc + $(ROCKSDB)/db/table_cache.cc + $(ROCKSDB)/db/table_properties_collector.cc + $(ROCKSDB)/db/transaction_log_impl.cc + $(ROCKSDB)/db/version_builder.cc + $(ROCKSDB)/db/version_edit.cc + $(ROCKSDB)/db/version_set.cc + $(ROCKSDB)/db/wal_manager.cc + $(ROCKSDB)/db/write_batch.cc + $(ROCKSDB)/db/write_batch_base.cc + $(ROCKSDB)/db/write_controller.cc + $(ROCKSDB)/db/write_thread.cc + $(ROCKSDB)/db/xfunc_test_points.cc + $(ROCKSDB)/memtable/hash_cuckoo_rep.cc + $(ROCKSDB)/memtable/hash_linklist_rep.cc + $(ROCKSDB)/memtable/hash_skiplist_rep.cc + $(ROCKSDB)/memtable/skiplistrep.cc + $(ROCKSDB)/memtable/vectorrep.cc + $(ROCKSDB)/port/stack_trace.cc + $(ROCKSDB)/table/adaptive_table_factory.cc + $(ROCKSDB)/table/block_based_filter_block.cc + $(ROCKSDB)/table/block_based_table_builder.cc + $(ROCKSDB)/table/block_based_table_factory.cc + $(ROCKSDB)/table/block_based_table_reader.cc + $(ROCKSDB)/table/block_builder.cc + $(ROCKSDB)/table/block.cc + $(ROCKSDB)/table/block_prefix_index.cc + $(ROCKSDB)/table/bloom_block.cc + $(ROCKSDB)/table/cuckoo_table_builder.cc + $(ROCKSDB)/table/cuckoo_table_factory.cc + $(ROCKSDB)/table/cuckoo_table_reader.cc + $(ROCKSDB)/table/flush_block_policy.cc + $(ROCKSDB)/table/format.cc + $(ROCKSDB)/table/full_filter_block.cc + $(ROCKSDB)/table/get_context.cc + $(ROCKSDB)/table/iterator.cc + $(ROCKSDB)/table/merger.cc + $(ROCKSDB)/table/meta_blocks.cc + $(ROCKSDB)/table/sst_file_writer.cc + $(ROCKSDB)/table/plain_table_builder.cc + $(ROCKSDB)/table/plain_table_factory.cc + $(ROCKSDB)/table/plain_table_index.cc + $(ROCKSDB)/table/plain_table_key_coding.cc + $(ROCKSDB)/table/plain_table_reader.cc + $(ROCKSDB)/table/persistent_cache_helper.cc + $(ROCKSDB)/table/table_properties.cc + $(ROCKSDB)/table/two_level_iterator.cc + $(ROCKSDB)/tools/dump/db_dump_tool.cc + $(ROCKSDB)/util/arena.cc + $(ROCKSDB)/util/bloom.cc + # $(ROCKSDB)/util/build_version.cc + $(ROCKSDB)/util/coding.cc + $(ROCKSDB)/util/comparator.cc + $(ROCKSDB)/util/compaction_job_stats_impl.cc + $(ROCKSDB)/util/concurrent_arena.cc + $(ROCKSDB)/util/crc32c.cc + $(ROCKSDB)/util/delete_scheduler.cc + $(ROCKSDB)/util/dynamic_bloom.cc + $(ROCKSDB)/util/env.cc + $(ROCKSDB)/util/env_chroot.cc + $(ROCKSDB)/util/env_hdfs.cc + $(ROCKSDB)/util/file_util.cc + $(ROCKSDB)/util/file_reader_writer.cc + $(ROCKSDB)/util/filter_policy.cc + $(ROCKSDB)/util/hash.cc + $(ROCKSDB)/util/histogram.cc + $(ROCKSDB)/util/histogram_windowing.cc + $(ROCKSDB)/util/instrumented_mutex.cc + $(ROCKSDB)/util/iostats_context.cc + $(ROCKSDB)/util/lru_cache.cc + $(ROCKSDB)/util/threadpool.cc + $(ROCKSDB)/util/transaction_test_util.cc + $(ROCKSDB)/util/sharded_cache.cc + $(ROCKSDB)/util/sst_file_manager_impl.cc + $(ROCKSDB)/utilities/backupable/backupable_db.cc + $(ROCKSDB)/utilities/blob_db/blob_db.cc + $(ROCKSDB)/utilities/convenience/info_log_finder.cc + $(ROCKSDB)/utilities/checkpoint/checkpoint.cc + $(ROCKSDB)/utilities/compaction_filters/remove_emptyvalue_compactionfilter.cc + $(ROCKSDB)/utilities/document/document_db.cc + $(ROCKSDB)/utilities/document/json_document_builder.cc + $(ROCKSDB)/utilities/document/json_document.cc + $(ROCKSDB)/utilities/env_mirror.cc + $(ROCKSDB)/utilities/env_registry.cc + $(ROCKSDB)/utilities/flashcache/flashcache.cc + $(ROCKSDB)/utilities/geodb/geodb_impl.cc + $(ROCKSDB)/utilities/leveldb_options/leveldb_options.cc + $(ROCKSDB)/utilities/memory/memory_util.cc + $(ROCKSDB)/utilities/merge_operators/put.cc + $(ROCKSDB)/utilities/merge_operators/max.cc + $(ROCKSDB)/utilities/merge_operators/string_append/stringappend2.cc + $(ROCKSDB)/utilities/merge_operators/string_append/stringappend.cc + $(ROCKSDB)/utilities/merge_operators/uint64add.cc + $(ROCKSDB)/utilities/option_change_migration/option_change_migration.cc + $(ROCKSDB)/utilities/options/options_util.cc + $(ROCKSDB)/utilities/persistent_cache/persistent_cache_tier.cc + $(ROCKSDB)/utilities/persistent_cache/volatile_tier_impl.cc + $(ROCKSDB)/utilities/persistent_cache/block_cache_tier_file.cc + $(ROCKSDB)/utilities/persistent_cache/block_cache_tier_metadata.cc + $(ROCKSDB)/utilities/persistent_cache/block_cache_tier.cc + $(ROCKSDB)/utilities/redis/redis_lists.cc + $(ROCKSDB)/utilities/simulator_cache/sim_cache.cc + $(ROCKSDB)/utilities/spatialdb/spatial_db.cc + $(ROCKSDB)/utilities/table_properties_collectors/compact_on_deletion_collector.cc + $(ROCKSDB)/utilities/transactions/optimistic_transaction_impl.cc + $(ROCKSDB)/utilities/transactions/optimistic_transaction_db_impl.cc + $(ROCKSDB)/utilities/transactions/transaction_base.cc + $(ROCKSDB)/utilities/transactions/transaction_db_impl.cc + $(ROCKSDB)/utilities/transactions/transaction_db_mutex_impl.cc + $(ROCKSDB)/utilities/transactions/transaction_lock_mgr.cc + $(ROCKSDB)/utilities/transactions/transaction_impl.cc + $(ROCKSDB)/utilities/transactions/transaction_util.cc + $(ROCKSDB)/utilities/ttl/db_ttl_impl.cc + $(ROCKSDB)/utilities/date_tiered/date_tiered_db_impl.cc + $(ROCKSDB)/utilities/write_batch_with_index/write_batch_with_index.cc + $(ROCKSDB)/utilities/write_batch_with_index/write_batch_with_index_internal.cc + $(ROCKSDB)/util/event_logger.cc + $(ROCKSDB)/util/log_buffer.cc + $(ROCKSDB)/util/logging.cc + $(ROCKSDB)/util/memenv.cc + $(ROCKSDB)/util/murmurhash.cc + $(ROCKSDB)/util/mutable_cf_options.cc + $(ROCKSDB)/util/options.cc + $(ROCKSDB)/util/options_helper.cc + $(ROCKSDB)/util/options_parser.cc + $(ROCKSDB)/util/options_sanity_check.cc + $(ROCKSDB)/util/perf_context.cc + $(ROCKSDB)/util/perf_level.cc + $(ROCKSDB)/util/random.cc + $(ROCKSDB)/util/rate_limiter.cc + $(ROCKSDB)/util/slice.cc + $(ROCKSDB)/util/statistics.cc + $(ROCKSDB)/util/status.cc + $(ROCKSDB)/util/status_message.cc + $(ROCKSDB)/util/string_util.cc + $(ROCKSDB)/util/sync_point.cc + $(ROCKSDB)/util/thread_local.cc + $(ROCKSDB)/util/thread_status_impl.cc + $(ROCKSDB)/util/thread_status_updater.cc + $(ROCKSDB)/util/thread_status_updater_debug.cc + $(ROCKSDB)/util/thread_status_util.cc + $(ROCKSDB)/util/thread_status_util_debug.cc + $(ROCKSDB)/util/xfunc.cc + $(ROCKSDB)/util/xxhash.cc + ; + +path-constant ROCKSDB_POSIX_SRC : + # Posix only + $(ROCKSDB)/util/io_posix.cc + $(ROCKSDB)/util/env_posix.cc + $(ROCKSDB)/port/port_posix.cc + ; + +project bench + : requirements + yes:$(ROCKSDB_SRC) + yes:WITH_ROCKSDB + yes:$(ROCKSDB) + yes:$(ROCKSDB)/include + yes:$(ROCKSDB)/third-party/gtest-1.7.0/fused-src + # Posix only + LINUX,yes:ROCKSDB_PLATFORM_POSIX + LINUX,yes:ROCKSDB_LIB_IO_POSIX + # LINUX Only + LINUX,yes:OS_LINUX + LINUX,yes:/boost/thread//boost_thread + LINUX,yes:$(ROCKSDB_POSIX_SRC) + ; + +exe bench : + bench.cpp + ; \ No newline at end of file diff --git a/bench/README.md b/bench/README.md new file mode 100644 index 000000000..94d0dbe9b --- /dev/null +++ b/bench/README.md @@ -0,0 +1,102 @@ +# Benchmarks for NuDB + +These benchmarks time two operations: + +1. The time to insert N values into a database. The inserted keys and values are + pseudo-randomly generated. The random number generator is always seeded with + the same value for each run, so the same values are always inserted. +2. The time to fetch M existing values from a database with N values. The order + that the keys are fetched are pseudo-randomly generated. The random number + generator is always seeded with the same value on each fun, so the keys are + always looked up in the same order. + +At the end of a run, the program outputs a table of operations per second. The +tables have a row for each database size, and a column for each database (in +cases where NuDB is compared against other databases). A cell in the table is +the number of operations per second for that trial. For example, in the table +below NuDB had 340397 Ops/Sec when fetching from an existing database with +10,000,000 values. This is a summary report, and only reports samples at order +of magnitudes of ten. + +A sample output: + +``` +insert (per second) + num_db_keys nudb rocksdb + 100000 406598 231937 + 1000000 374330 258519 + 10000000 NA NA + +fetch (per second) + num_db_keys nudb rocksdb + 100000 325228 697158 + 1000000 333443 34557 + 10000000 337300 20835 +``` + +In addition to the summary report, the benchmark can collect detailed samples. +The `--raw_out` command line options is used to specify a file to output the raw +samples. The python 3 script `plot_bench.py` may be used to plot the result. For +example, if bench was run as `bench --raw_out=samples.txt`, the the python +script can be run as `python plot_bench.py -i samples.txt`. The python script +requires the `pandas` and `seaborn` packages (anaconda python is a good way to +install and manage python if these packages are not already +installed: [anaconda download](https://www.continuum.io/downloads)). + +# Building + +## Building with CMake + +Note: Building with RocksDB is currently not supported on Windows. + +1. The benchmark requires boost. If building with rocksdb, it also requires zlib + and snappy. These are popular libraries and should be available through the + package manager. +1. The benchmark and test programs require some submodules that are not + installed by default. Get these submodules by running: + `git submodule update --init` +2. From the main nudb directory, create a directory for the build and change to + that directory: `mkdir bench_build;cd bench_build` +3. Generate a project file or makefile. + * If building on Linux, generate a makefile. If building with rocksdb + support, use: `cmake -DCMAKE_BUILD_TYPE=Release ../bench` If building + without rocksdb support, use: `cmake -DCMAKE_BUILD_TYPE=Release ../bench + -DWITH_ROCKSDB=false` Replace `../bench` with the path to the `bench` + directory if the build directory is not in the suggested location. + * If building on windows, generate a project file. The CMake gui program is + useful for this. Use the `bench` directory as the `source` directory and + the `bench_build` directory as the `binaries` directory. Press the `Add + Entry` button and add a `BOOST_ROOT` variable that points to the `boost` + directory. Hit `configure`. A dialog box will pop up. Select the generator + for Win64. Select `generate` to generate the visual studio project. +4. Compile the program. + * If building on Linux, run: `make` + * If building on Windows, open the project file generated above in Visual + Studio. + +## Test the build + +Try running the benchmark with a small database: `./bench --num_batches=10`. A +report similar to sample should appear after a few seconds. + +# Command Line Options + +* `batch_size arg` : Number of elements to insert or fetch per batch. If not + specified, it defaults to 20000. +* `num_batches arg` : Number of batches to run. If not specified, it defaults to + 500. +* `db_dir arg` : Directory to place the databases. If not specified, it defaults to + boost::filesystem::temp_directory_path (likely `/tmp` on Linux) +* `raw_out arg` : File to record the raw measurements. This is useful for plotting. If + not specified the raw measurements will not be output. +* `--dbs arg` : Databases to run the benchmark on. Currently, only `nudb` and + `rocksdb` are supported. Building with `rocksdb` is optional on Linux, and + only `nudb` is supported on windows. The argument may be a list. If `dbs` is + not specified, it defaults to all the database the build supports (either + `nudb` or `nudb rocksdb`). +* `--key_size arg` : nudb key size. If not specified the default is 64. +* `--block_size arg` : nudb block size. This is an advanced argument. If not + specified the default is 4096. +* `--load_factor arg` : nudb load factor. This is an advanced argument. If not + specified the default is 0.5. + diff --git a/bench/bench.cpp b/bench/bench.cpp new file mode 100644 index 000000000..ed2c79655 --- /dev/null +++ b/bench/bench.cpp @@ -0,0 +1,535 @@ +// +// Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#include +#include +#include + +#if WITH_ROCKSDB +#include "rocksdb/db.h" + +char const* rocksdb_build_git_sha="Benchmark Dummy Sha"; +char const* rocksdb_build_compile_date="Benchmark Dummy Compile Date"; +#endif + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace nudb { +namespace test { + +beast::unit_test::dstream dout{std::cout}; +beast::unit_test::dstream derr{std::cerr}; + +struct stop_watch +{ + using clock = std::chrono::steady_clock; + using time_point = clock::time_point; + time_point start_; + + stop_watch() : start_(clock::now()) + { + } + + std::chrono::duration + elapsed() const + { + return std::chrono::duration_cast>( + clock::now() - start_); + } +}; + +class bench_progress +{ + progress p_; + std::uint64_t const total_=0; + std::uint64_t batch_start_=0; + +public: + bench_progress(std::ostream& os, std::uint64_t total) + : p_(os), total_(total) + { + p_(0, total); + } + void + update(std::uint64_t batch_amount) + { + p_(batch_start_ + batch_amount, total_); + batch_start_ += batch_amount; + } +}; + +class gen_key_value +{ + test_store& ts_; + std::uint64_t cur_; + +public: + gen_key_value(test_store& ts, std::uint64_t cur) + : ts_(ts), + cur_(cur) + { + } + item_type + operator()() + { + return ts_[cur_++]; + } +}; + +class rand_existing_key +{ + xor_shift_engine rng_; + std::uniform_int_distribution dist_; + test_store& ts_; + + public: + rand_existing_key(test_store& ts, + std::uint64_t max_index, + std::uint64_t seed = 1337) + : dist_(0, max_index), + ts_(ts) + { + rng_.seed(seed); + } + item_type + operator()() + { + return ts_[dist_(rng_)]; + } +}; + + +template +std::chrono::duration +time_block(std::uint64_t n, Generator&& g, F&& f) +{ + stop_watch timer; + for (std::uint64_t i = 0; i < n; ++i) + { + f(g()); + } + return timer.elapsed(); +} + +template +void +time_fetch_insert_interleaved( + std::uint64_t batch_size, + std::uint64_t num_batches, + test_store& ts, + Inserter&& inserter, + Fetcher&& fetcher, + AddSample&& add_sample, + PreFetchHook&& pre_fetch_hook, + bench_progress& progress) +{ + std::uint64_t next_insert_index = 0; + for (auto b = 0ull; b < num_batches; ++b) + { + auto const insert_time = time_block( + batch_size, gen_key_value{ts, next_insert_index}, inserter); + add_sample( + "insert", next_insert_index, batch_size / insert_time.count()); + next_insert_index += batch_size; + progress.update(batch_size); + pre_fetch_hook(); + auto const fetch_time = time_block( + batch_size, rand_existing_key{ts, next_insert_index - 1}, fetcher); + add_sample("fetch", next_insert_index, batch_size / fetch_time.count()); + progress.update(batch_size); + } +} + +#if WITH_ROCKSDB +template +void +do_timings_rocks( + std::string const& db_dir, + std::uint64_t batch_size, + std::uint64_t num_batches, + std::uint32_t key_size, + AddSample&& add_sample, + bench_progress& progress) +{ + temp_dir td{db_dir}; + std::unique_ptr pdb = [&td] { + rocksdb::DB* db = nullptr; + rocksdb::Options options; + options.create_if_missing = true; + auto const status = rocksdb::DB::Open(options, td.path(), &db); + if (!status.ok()) + db = nullptr; + return std::unique_ptr{db}; + }(); + + if (!pdb) + { + derr << "Failed to open rocks db.\n"; + return; + } + + auto inserter = [key_size, &pdb](item_type const& v) { + auto const s = pdb->Put(rocksdb::WriteOptions(), + rocksdb::Slice(reinterpret_cast(v.key), key_size), + rocksdb::Slice(reinterpret_cast(v.data), v.size)); + if (!s.ok()) + throw std::runtime_error("Rocks Insert: " + s.ToString()); + }; + + auto fetcher = [key_size, &pdb](item_type const& v) { + std::string value; + auto const s = pdb->Get(rocksdb::ReadOptions(), + rocksdb::Slice(reinterpret_cast(v.key), key_size), + &value); + if (!s.ok()) + throw std::runtime_error("Rocks Fetch: " + s.ToString()); + }; + + test_store ts{key_size, 0, 0}; + try + { + time_fetch_insert_interleaved(batch_size, num_batches, ts, + std::move(inserter), std::move(fetcher), + std::forward(add_sample), [] {}, progress); + } + catch (std::exception const& e) + { + derr << "Error: " << e.what() << '\n'; + } +} +#endif + +template +void +do_timings(std::string const& db_dir, + std::uint64_t batch_size, + std::uint64_t num_batches, + std::uint32_t key_size, + std::size_t block_size, + float load_factor, + AddSample&& add_sample, + bench_progress& progress) +{ + boost::system::error_code ec; + + try + { + test_store ts{db_dir, key_size, block_size, load_factor}; + ts.create(ec); + if (ec) + goto fail; + ts.open(ec); + if (ec) + goto fail; + + auto inserter = [&ts, &ec](item_type const& v) { + ts.db.insert(v.key, v.data, v.size, ec); + if (ec) + throw boost::system::system_error(ec); + }; + + auto fetcher = [&ts, &ec](item_type const& v) { + ts.db.fetch(v.key, [&](void const* data, std::size_t size) {}, ec); + if (ec) + throw boost::system::system_error(ec); + }; + + auto pre_fetch_hook = [&ts, &ec]() { + // Close then open the db otherwise the + // commit thread confounds the timings + ts.close(ec); + if (ec) + throw boost::system::system_error(ec); + ts.open(ec); + if (ec) + throw boost::system::system_error(ec); + }; + + time_fetch_insert_interleaved(batch_size, num_batches, ts, + std::move(inserter), std::move(fetcher), + std::forward(add_sample), std::move(pre_fetch_hook), + progress); + } + catch (boost::system::system_error const& e) + { + ec = e.code(); + } + catch (std::exception const& e) + { + derr << "Error: " << e.what() << '\n'; + } + +fail: + if (ec) + derr << "Error: " << ec.message() << '\n'; + + return; +} + +namespace po = boost::program_options; + +void +print_help(std::string const& prog_name, const po::options_description& desc) +{ + derr << prog_name << ' ' << desc; +} + +po::variables_map +parse_args(int argc, char** argv, po::options_description& desc) +{ + +#if WITH_ROCKSDB + std::vector const default_dbs = {"nudb", "rocksdb"}; +#else + std::vector const default_dbs = {"nudb"}; +#endif + std::vector const default_ops({100000,1000000}); + + desc.add_options() + ("help,h", "Display this message.") + ("batch_size", + po::value(), + "Batch Size Default: 20000)") + ("num_batches", + po::value(), + "Num Batches Default: 500)") + ("dbs", + po::value>()->multitoken(), + "databases (Default: nudb rocksdb)") + ("block_size", po::value(), + "nudb block size (default: 4096)") + ("key_size", po::value(), + "key size (default: 64)") + ("load_factor", po::value(), + "nudb load factor (default: 0.5)") + ("db_dir", po::value(), + "Directory to place the databases" + " (default: boost::filesystem::temp_directory_path)") + ("raw_out", po::value(), + "File to record the raw measurements (useful for plotting)" + " (default: no output)") + ; + + po::variables_map vm; + po::store(po::command_line_parser(argc, argv).options(desc).run(), vm); + po::notify(vm); + + return vm; +} + +template +T +get_opt(po::variables_map const& vm, std::string const& key, T const& default_value) +{ + return vm.count(key) ? vm[key].as() : default_value; +} + +} // test +} // nudb + +int +main(int argc, char** argv) +{ + using namespace nudb::test; + + po::variables_map vm; + + { + po::options_description desc{"Benchmark Options"}; + bool parse_error = false; + try + { + vm = parse_args(argc, argv, desc); + } + catch (std::exception const& e) + { + derr << "Incorrect command line syntax.\n"; + derr << "Exception: " << e.what() << '\n'; + parse_error = true; + } + + if (vm.count("help") || parse_error) + { + auto prog_name = boost::filesystem::path(argv[0]).stem().string(); + print_help(prog_name, desc); + return 0; + } + } + + auto const batch_size = get_opt(vm, "batch_size", 20000); + auto const num_batches = get_opt(vm, "num_batches", 500); + auto const block_size = get_opt(vm, "block_size", 4096); + auto const load_factor = get_opt(vm, "load_factor", 0.5f); + auto const key_size = get_opt(vm, "key_size", 64); + auto const db_dir = [&vm]() -> std::string { + auto r = get_opt(vm, "db_dir", ""); + if (!r.empty() && r.back() != '/' && r.back() != '\\') + { + r += '/'; + } + return r; + }(); + auto const raw_out = get_opt(vm, "raw_out", ""); +#if WITH_ROCKSDB + std::vector const default_dbs({"nudb", "rocksdb"}); +#else + std::vector const default_dbs({"nudb"}); +#endif + auto to_set = [](std::vector const& v) { + return std::set(v.begin(), v.end()); + }; + auto const dbs = to_set(get_opt>(vm, "dbs", default_dbs)); + + for (auto const& db : dbs) + { + if (db == "rocksdb") + { +#if !WITH_ROCKSDB + derr << "Benchmark was not built with rocksdb support\n"; + exit(1); +#endif + continue; + } + + if (db != "nudb" && db != "rocksdb") + { + derr << "Unsupported database: " << db << '\n'; + exit(1); + } + } + + bool const with_rocksdb = dbs.count("rocksdb") != 0; + (void) with_rocksdb; + bool const with_nudb = dbs.count("nudb") != 0; + std::uint64_t const num_db = int(with_nudb) + int(with_rocksdb); + std::uint64_t const total_ops = num_db * batch_size * num_batches * 2; + bench_progress progress(derr, total_ops); + + enum + { + db_nudb, + db_rocks, + db_last + }; + enum + { + op_insert, + op_fetch, + op_last + }; + std::array db_names{{"nudb", "rocksdb"}}; + std::array op_names{{"insert", "fetch"}}; + using result_dict = boost::container::flat_multimap; + result_dict ops_per_sec[db_last][op_last]; + // Reserve up front to database that run later don't have less memory + for (int i = 0; i < db_last; ++i) + for (int j = 0; j < op_last; ++j) + ops_per_sec[i][j].reserve(num_batches); + + std::ofstream raw_out_stream; + bool const record_raw_out = !raw_out.empty(); + if (record_raw_out) + { + raw_out_stream.open(raw_out, std::ios::trunc); + raw_out_stream << "num_db_items,db,op,ops/sec\n"; + } + for (int i = 0; i < db_last; ++i) + { + auto result = [&] + (std::string const& op_name, std::uint64_t num_items, + double sample) { + auto op_idx = op_name == "insert" ? op_insert : op_fetch; + ops_per_sec[i][op_idx].emplace(num_items, sample); + if (record_raw_out) + raw_out_stream << num_items << ',' << db_names[i] << ',' + << op_name << ',' << std::fixed << sample + << std::endl; // flush + + }; + if (with_nudb && i == db_nudb) + do_timings(db_dir, batch_size, num_batches, key_size, block_size, + load_factor, result, progress); +#if WITH_ROCKSDB + if (with_rocksdb && i == db_rocks) + do_timings_rocks( + db_dir, batch_size, num_batches, key_size, result, progress); +#endif + } + + // Write summary by sampling raw data at powers of 10 + auto const col_w = 14; + auto const iter_w = 15; + + for (int op_idx = 0; op_idx < op_last; ++op_idx) + { + auto const& t = op_names[op_idx]; + dout << '\n' << t << " (per second)\n"; + dout << std::setw(iter_w) << "num_db_keys"; + if (with_nudb) + dout << std::setw(col_w) << "nudb"; +#if WITH_ROCKSDB + if (with_rocksdb) + dout << std::setw(col_w) << "rocksdb"; +#endif + dout << '\n'; + auto const max_sample = [&ops_per_sec] { + std::uint64_t r = 0; + for (auto i = 0; i < db_last; ++i) + for (auto j = 0; j < op_last; ++j) + if (!ops_per_sec[i][j].empty()) + r = std::max(r, ops_per_sec[i][j].rbegin()->first); // no `back()` + return r; + }(); + auto const min_sample = batch_size; + + auto write_val = [&]( + result_dict const& dict, std::uint64_t key) { + dout << std::setw(col_w) << std::fixed << std::setprecision(2); + // Take the average of all the values, or "NA" if none collected + auto l = dict.lower_bound(key); + auto u = dict.upper_bound(key); + if (l == u) + dout << "NA"; + else + { + auto const total = std::accumulate(l, u, 0, + [](double a, std::pair const& b) { + return a + b.second; + }); + dout << total / std::distance(l, u); + } + }; + for (std::uint64_t n = 100; n <= max_sample; n *= 10) + { + if (n=500000], hue='db', col='op') + plt.show(p) + return d # for testing + + +def parse_args(): + parser = argparse.ArgumentParser( + description=('Plot the benchmark results')) + parser.add_argument( + '--input', + '-i', + help=('input'), ) + return parser.parse_args() + + +if __name__ == '__main__': + args = parse_args() + result_filename = args.input + if not result_filename: + print('No result file specified. Exiting') + else: + run_main(result_filename) diff --git a/doc/.gitignore b/doc/.gitignore new file mode 100644 index 000000000..fc40be018 --- /dev/null +++ b/doc/.gitignore @@ -0,0 +1,5 @@ +bin +html +temp +reference.qbk +out.txt diff --git a/doc/Jamfile.v2 b/doc/Jamfile.v2 new file mode 100644 index 000000000..6b3a8e0d2 --- /dev/null +++ b/doc/Jamfile.v2 @@ -0,0 +1,77 @@ +# +# Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +# +# Distributed under the Boost Software License, Version 1.0. (See accompanying +# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +# + +import os ; + +local broot = [ os.environ BOOST_ROOT ] ; + +project nudb/doc ; + +using boostbook ; +using quickbook ; +using doxygen ; + +path-constant out : . ; + +install stylesheets + : + $(broot)/doc/src/boostbook.css + : + $(out)/html + ; + +explicit stylesheets ; + +install images + : + [ glob $(broot)/doc/src/images/*.png ] + images/logo.png + : + $(out)/html/images + ; + +explicit images ; + +install callouts + : + [ glob $(broot)/doc/src/images/callouts/*.png ] + : + $(out)/html/images/callouts + ; + +explicit callout ; + +xml doc + : + main.qbk + : + temp + $(broot)/tools/boostbook/dtd + ; + +boostbook boostdoc + : + doc + : + chapter.autolabel=0 + boost.image.src=images/logo.png + boost.image.alt="NuDB Logo" + boost.image.w=1270 + boost.image.h=80 + boost.root=$(broot) + chapter.autolabel=0 + chunk.first.sections=1 # Chunk the first top-level section? + chunk.section.depth=8 # Depth to which sections should be chunked + generate.section.toc.level=1 # Control depth of TOC generation in sections + toc.max.depth=2 # How many levels should be created for each TOC? + toc.section.depth=2 # How deep should recursive sections appear in the TOC? + generate.toc="chapter nop section nop" + : + temp + stylesheets + images + ; diff --git a/doc/boostbook.dtd b/doc/boostbook.dtd new file mode 100644 index 000000000..bd4c3f871 --- /dev/null +++ b/doc/boostbook.dtd @@ -0,0 +1,439 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +%DocBook; diff --git a/doc/docca b/doc/docca new file mode 160000 index 000000000..335dbf9c3 --- /dev/null +++ b/doc/docca @@ -0,0 +1 @@ +Subproject commit 335dbf9c3613e997ed56d540cc8c5ff2e28cab2d diff --git a/doc/images/logo.png b/doc/images/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..8636189ae947810fac2623e58dbe0bff38d49637 GIT binary patch literal 153828 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 qf5AK4ds)ZlYR literal 0 HcmV?d00001 diff --git a/doc/images/logo.psd b/doc/images/logo.psd new file mode 100644 index 0000000000000000000000000000000000000000..8a4669aab064709e9b6629ec4d924a1d71aba3f2 GIT binary patch literal 737507 zcmeFa2Vi7nxjue+Z_{T|C%tDTWwX11U3NEHWt*F&ib^(_O~R%znQXy=AmX)LQB+h= zsaFNP;4gD;7{d1r$WYidX)~ENA z*Z%U-{-&qjddg$-SNt||(-=EfPv?$**YPJDoEaM4m&(NVq(;Z5R@MIczi+OMkB_XX zJ!RRp_0d;GnvW^#SczSOwINmTvayygS*| zok-$;Uq@GO|FXXR?&a~^t9G@4qvO*fd;52--8UvNJG5tdF0-n(mIf-k za_gF$DGW3<+sW40IXpd?I5;$u=;}-+3O(b-<3W@DfplspGo9W&Jw35HyYii5)0yen zvFVxkz+hjz`IPagk?8}oEypJgzkFf*g`QIDhccLh#RVSQ|y9vRddMUm(*U#|@ zB61PY*^Uyu4r_nD%@`Rj?8VGndV+2F$Z#Sxk(x|RWoEG-U5oc)WVnCtbb4|qvwCP| zW@3DJh_*bje`+MRku&+7IXEC+Rg+U6FU&Kg-(?_yX;Z*;?^u%-;JCs`8b9~}x z%|%e*eJ*2TAM80hO-+1J<6-Pu*#P0@8n?PquDU}o#kp;US{ zzjIkBVf(jkXmoLFeq$%b*?!IprDs#S56z@j)$U5oPS2%>Q^hiq?TPMLm^T}1`_N=+ zHFhsPIJmxevI{2{=6cLdXy(W4gq=LRlPt4NjQ{=Cw0&;V zqa*kGZzjTkylvZ#E(m!sIt`=X*G~`65f0_L9YMD%maRyxNN(uqUeULfx?Q=Vd&T`h|3VlrD}KX7l(gwAP`;Y|jLIFm?9gR-z;!_X`zp zwuAjc!vw;she=JQMvhM`YF(Jtf=FjC7(a5;o}ao$+D1a$@WJzG|7?$oZ#lf{zbzVNN6c-&?9l$dlKg9*kGcOE@-OS}THfEgEN`Lw zzac+ydUoXDv7xEa)X3^Yo?-J1|4cjf{3!S0cI>D&T{+0)aGv(j1??PXtK?AYHL;JVW=;>1>~=G(B&)d&8-_(Nx84#zWe1ZYwv$&2lL&&AkM_Gice# zb#qB>8Ghp2AUiXT-?Qw@0Iu(&9&B5IyqqExz9|qD>0}CIfG7BHJ?wOb^oY_8_*8T^y)=eCF-MaM1 z?vti68|!vW5LXml>n29xM{D0TJCR}SI}c8**;TmQ*q<84BXD@i8P9{~_-W_p&e=Ra z(J@_&cbYc0HMKX}&0)jt#)IBR8+LGbBHO+*J-p^L>Vdty;q>&(DR}y9C-L_9)M%c3 z4xQMAIjx({WTq!4rl&@8w^;czG=-veJKw%*d~~e%gqc5qxfQM_DHDH{odX!2xQ@@i zGYM>D=bYT2cst>Bx$hOQSsQ(0!9jLqtnj&t_4+&ZS!ciTi)UQgM7+syMwYv&nO*xN zYu(Hx_U^@*3H(-A3!iJb@_m;UTDs{j?sWXlU$cz05a;JwSf78uXO1Lm{-`hUr*!(L zr{@2fbBq?$HGKsGTb)E-#lYda9&#^sMUs7xc)ZwWnmx^*#KL7Q+3Q32j5c9S_J@uy zK@+>83I`m=zB7V-E~AgaQ}{*qE}#H6H8(*pM?$9U8JbNM!JN#Ul!G^%

}f!qmv@ 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

?V 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%0AepZKgrj}gG!174PWF$ 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 OyY&x2?(~-zasLOM7$)5S literal 0 HcmV?d00001 diff --git a/doc/images/readme2.png b/doc/images/readme2.png new file mode 100644 index 0000000000000000000000000000000000000000..fc130b61565ef6154763bd17ce82844fe2469ca1 GIT binary patch literal 106410 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

8u`s9;9;E#f#?1# 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 + + + + +

+ Index + +
diff --git a/doc/main.qbk b/doc/main.qbk new file mode 100644 index 000000000..8ab0d4eb0 --- /dev/null +++ b/doc/main.qbk @@ -0,0 +1,342 @@ +[/ + Copyright (c) 2013-2016 Vinnie Falco (vinnie dot falco at gmail dot com) + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +] + +[library NuDB + [quickbook 1.6] + [copyright 2015 - 2016 Vinnie Falco] + [purpose C++ Library] + [license + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + [@http://www.boost.org/LICENSE_1_0.txt]) + ] + [authors [Falco, Vinnie]] + [category template] + [category generic] +] + +[template mdash[] '''— '''] +[template indexterm1[term1] ''''''[term1]''''''] +[template indexterm2[term1 term2] ''''''[term1]''''''[term2]''''''] + +[variablelist + [[ + [link nudb.overview Overview] + ][ + An overview of features, requirements, and credits, plus + rationale and design information. + ]] + [[ + [link nudb.example Example] + ][ + An example that illustrates the use of NuDB. + ]] + [[ + [link nudb.usage Usage] + ][ + An explanation of operations on the database. + ]] + [[ + [link nudb.ref Reference] + ][ + Detailed class and function reference. + ]] + [[ + [link nudb.index Index] + ][ + Book-style text index of the documentation. + ]] +] + +[section:overview Overview] + +NuDB is an append only, key/value store specifically optimized for random +read performance on modern SSDs or equivalent high-IOPS decices. The most +common application for NuDB is content addressible storage where a +cryptographic digest of the data is used as the key. The read performance +and memory usage are independent of the size of the database. These are +some other features: + +[heading History] + +The first versions of rippled, the application behind the Ripple consensus +network, used SQLite as their back end for unstructured data. The +performance quickly became a limiting factor. + +Then rippled then went through a series of back ends including LMDB, LevelDB, and +RocksDB. Each of these databases performed well at first, but as the data +size increased, memory usage increased and performance dropped off drastically. + +The problem is caching. Each of these databases relies on some O(n) data +structure, such as a Bloom filter, to improve their performance. These work +well until the structures no longer fit in memory. In addition, many virtual +machines are memory constrained. + +To address this issue, the developers performed a thought experiment -- if +you assume the data size is so large that no O(n) caching is effective, what +is the best read performance you could expect? They reached the following +conclusions: + +1) Writes should not block reads. +2) Reads should be limited only by the SSD's IOPS limit. +3) A read for a non-present key should require one IOP. +4) A read for a present key whose data can be read in a single IOP should +only require two IOPs, one to figure out where it is and one to read it in. + +NuDB is designed to come as close to this ideal as possible. + +[heading Design] + +NuDB uses three files to hold the data and indexes. The data file is append +only and contains sufficient information to rebuild the index. The index +file is random access and contains hash buckets. When an update is in +progress, a temporary journal file is used to roll the update back if +needed. + +NuDB uses linear hashing to dynamically increase the number of buckets in +the index file as the data size grows. Bucket overflows are handled by +adding "overflow" records to the data file. Bucket overflows can be +minimized by increasing the number of buckets, leading to a size/speed +tradeoff. Typical databases keep the average bucket half full (or half +empty, depending on your point of view) resulting in spill records +accounting for less than 1% of reads. + +Inserts are buffered in memory and appended to the data file immediately. +Updates to the index file are performed as an atomic operation. Fetch +operations retrieve records in the process of being modified from memory +during the update operation so that writes do not block fetches. + +Before the index file is modified, a journal file is created to recover +consistency in the event of a crash during the update. The recovery process +will index all records written to the data file, so the aggregation of index +updates does not increase the time which a crash would result in loss of +data. + +Iteration can be performed on the data file directly. Since it is append +only, there is no risk of other operations corrupting an iteration in +progress. + +[heading Performance] + +Writes do not block reads. Read rates are typically around 90% of the SSD's +IOPS limit. An average fetch for a non-present key typically requires fewer +than 1.01 IOPs. An average fetch for a present key requires fewer than 1.01 +IOPs plus however many IOPs it takes to read the data. + +[heading Applications] + +Content addressable storage associates data with its cryptographic digest. +This type of storage is commonly used in decentralized blockchain applications. + +Often these applications require following hash chains -- where one object +contains the hash of another object that ultimately leads to the object +desired. NuDB's low latency and high speed are particularly advantageous +in these kinds of applications. + +NuDB is append only and does not support a delete operation. To support +retaining limited historical information, NuDB is often used in a dual +database configuration. One database is older and is read only, the other +is newer and is read/write. Periodically, the older database is discarded and +the newer database becomes the new read only database and a new read/write +database is created. + +[endsect] + + + +[section:example Example] + +This complete program creates a database, opens the database, inserts several +key/value pairs, fetches the key/value pairs, closes the database, then erases +the database files. Source code for this program is located in the examples +directory. + +``` +#include +#include +#include + +int main() +{ + using namespace nudb; + std::size_t constexpr N = 1000; + using key_type = std::uint32_t; + error_code ec; + auto const dat_path = "db.dat"; + auto const key_path = "db.key"; + auto const log_path = "db.log"; + create( + dat_path, key_path, log_path, + 1, + make_salt(), + sizeof(key_type), + block_size("."), + 0.5f, + ec); + store db; + db.open(dat_path, key_path, log_path, + 16 * 1024 * 1024, ec); + char data = 0; + // Insert + for(key_type i = 0; i < N; ++i) + db.insert(&i, &data, sizeof(data), ec); + // Fetch + for(key_type i = 0; i < N; ++i) + db.fetch(&i, + [&](void const* buffer, std::size_t size) + { + // do something with buffer, size + }, ec); + db.close(ec); + erase_file(dat_path); + erase_file(key_path); + erase_file(log_path); +} +``` + +[endsect] + + + +[section:usage Usage] + +[heading Files] + +A database is represented by three files: the data file, the key file, +and the log file. Each file has a distinct header in a well known format. +The data file holds all of the key/value pairs and is serially iterable. The +key file holds a hash table indexing all of the contents in the data file. +The log file holds information used to roll the database back in the event +of a failure. + +[heading Create/Open] + +The [link nudb.ref.nudb__create create] function creates a new data file and key +file for a database with the specified parameters. The caller specifies +the hash function to use as a template argument, the file paths, +and the database constants: + +[note + Sample code and identifiers mentioned in this section are written + as if the following declarations are in effect: + ``` + #include + using namespace nudb; + error_code ec; + ``` +] + +``` +create( + "nudb.dat", // Path to data file + "nudb.key", // Path to key file + "nudb.log", // Path to log file + 1, // Application-defined constant + make_salt(), // A random integer + 4, // The size of keys + block_size(".") // Block size in key file + 0.5f // The load factor + ec); +``` + +The application-defined constant is a 64-bit unsigned integer which the +caller may set to any value. This value can be retrieved from an open +database, where it will be equal to the value used at creation time. This +constant can be used for any purpose. For example, to inform the application +of what application-specific version was used to create the database. + +The salt is a 64-bit unsigned integer used to prevent algorithmic complexity +attacks. Hash functions used during database operations are constructed with +the salt, providing an opportunity to permute the hash function. This feature +is useful when inserted database keys come from untrusted sources, such as the +network. + +The key size is specified when the database is created, and cannot be changed. +All key files indexing the same data file will use the key size of the data +file. + +The block size indicates the size of buckets in the key file. The best choice +for the block size is the natural sector size of the device. For most SSDs +in production today this is 4096, or less often 8192 or 16384. The function +[link nudb.ref.nudb__block_size block_size] returns the best guess of the block +size used by the device mounted at the specified path. + +The load factor determines the target bucket occupancy fraction. There is +almost never a need to specify anything other than the recommended value of +0.5, which strikes the perfect balance of space-efficiency and fast lookup. + +An open database is represented by objects of type +[link nudb.ref.nudb__basic_store basic_store], templated on the hasher. The type +alias [link nudb.ref.nudb__store store] represents a database using +[link nudb.ref.nudb__xxhasher xxhasher], the default hash function. To open +a database, declare a database object and then call the +[link nudb.ref.nudb__basic_store.open open] member function: + +``` +store db; +db.open("nudb.dat", "nudb.key", "nudb.log", ec); +``` + +When opening a database that was previously opened by a program that was +terminated abnormally, the implementation automatically invokes the +recovery process. This process restores the integrity of the database by +replaying the log file if it is present. + +[heading Insert/Fetch] + +Once a database is open, it becomes possible to insert new key/value pairs +and look them up. Insertions are straightforward: + +``` +db.insert(key, data, bytes, ec); +``` + +If the key already exists, the error is set to +[link nudb.ref.nudb__error.key_exists error::key_exists]. All keys in a NuDB +database must be unique. Multiple threads can call insert at the same time. +Internally however, insertions are serialized to present a consistent view +of the database to callers. + +Retrieving a key/value pair if it exists is similary straightforward: + +``` +db.fetch(key, + [&](void const* buffer, std::size_t size) + { + ... + }, ec); +``` + +To give callers control over memory allocation strategies, the fetch +function takes a callback object as a parameter. The callback is invoked +with a pointer to the data and size, if the item exists in the database. +The callback can decide how to store this information, if at all. + +[endsect] + +[section Command Line Tool] + +To allow administration, NuDB comes with the "nudb" command line tool, +which may be built using b2 or CMake. Files for the tool are located in +the "tools" directory. Once the tool is built, and located in your path, +execute this command for additional instructions: + +``` +nudb help +``` + +[endsect] + +[section:ref Reference] +[xinclude quickref.xml] +[include types/File.qbk] +[include types/Hasher.qbk] +[include types/Progress.qbk] +[include reference.qbk] +[endsect] + +[xinclude index.xml] diff --git a/doc/makeqbk.sh b/doc/makeqbk.sh new file mode 100644 index 000000000..3da8c0790 --- /dev/null +++ b/doc/makeqbk.sh @@ -0,0 +1,12 @@ +#!/usr/bin/bash + +# Copyright (c) 2013-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +# +# Distributed under the Boost Software License, Version 1.0. (See accompanying +# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +mkdir -p temp +doxygen source.dox +cd temp +xsltproc combine.xslt index.xml > all.xml +xsltproc ../reference.xsl all.xml > ../reference.qbk diff --git a/doc/quickref.xml b/doc/quickref.xml new file mode 100644 index 000000000..243e57cb9 --- /dev/null +++ b/doc/quickref.xml @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + NuDB + + + + + + + Classes + + basic_store + native_file + no_progress + posix_file + store + win32_file + xxhasher + + Constants + + errc + error + file_mode + + + + Functions + + block_size + create + erase_file + make_error_code + recover + rekey + verify + visit + + Type Traits + + is_File + is_Hasher + is_Progress + + + + Types + + error_category + error_code + error_condition + path_type + system_error + verify_info + + Concepts + + File + Progress + Hasher + + + + + + diff --git a/doc/reference.xsl b/doc/reference.xsl new file mode 100644 index 000000000..ec2a22d30 --- /dev/null +++ b/doc/reference.xsl @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/doc/source.dox b/doc/source.dox new file mode 100644 index 000000000..73bff7b03 --- /dev/null +++ b/doc/source.dox @@ -0,0 +1,333 @@ +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- +DOXYFILE_ENCODING = UTF-8 +PROJECT_NAME = "NuDB" +PROJECT_NUMBER = +PROJECT_BRIEF = C++ Library +PROJECT_LOGO = +OUTPUT_DIRECTORY = +CREATE_SUBDIRS = NO +ALLOW_UNICODE_NAMES = NO +OUTPUT_LANGUAGE = English +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = YES +ABBREVIATE_BRIEF = +ALWAYS_DETAILED_SEC = NO +INLINE_INHERITED_MEMB = YES +FULL_PATH_NAMES = NO +STRIP_FROM_PATH = ../include/ +STRIP_FROM_INC_PATH = +SHORT_NAMES = NO +JAVADOC_AUTOBRIEF = YES +QT_AUTOBRIEF = NO +MULTILINE_CPP_IS_BRIEF = NO +INHERIT_DOCS = YES +SEPARATE_MEMBER_PAGES = NO +TAB_SIZE = 4 +ALIASES = +TCL_SUBST = +OPTIMIZE_OUTPUT_FOR_C = NO +OPTIMIZE_OUTPUT_JAVA = NO +OPTIMIZE_FOR_FORTRAN = NO +OPTIMIZE_OUTPUT_VHDL = NO +EXTENSION_MAPPING = +MARKDOWN_SUPPORT = YES +AUTOLINK_SUPPORT = YES +BUILTIN_STL_SUPPORT = NO +CPP_CLI_SUPPORT = NO +SIP_SUPPORT = NO +IDL_PROPERTY_SUPPORT = YES +DISTRIBUTE_GROUP_DOC = NO +GROUP_NESTED_COMPOUNDS = NO +SUBGROUPING = YES +INLINE_GROUPED_CLASSES = NO +INLINE_SIMPLE_STRUCTS = NO +TYPEDEF_HIDES_STRUCT = NO +LOOKUP_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- +EXTRACT_ALL = YES +EXTRACT_PRIVATE = YES +EXTRACT_PACKAGE = NO +EXTRACT_STATIC = YES +EXTRACT_LOCAL_CLASSES = YES +EXTRACT_LOCAL_METHODS = YES +EXTRACT_ANON_NSPACES = NO +HIDE_UNDOC_MEMBERS = NO +HIDE_UNDOC_CLASSES = NO +HIDE_FRIEND_COMPOUNDS = NO +HIDE_IN_BODY_DOCS = NO +INTERNAL_DOCS = NO +CASE_SENSE_NAMES = YES +HIDE_SCOPE_NAMES = NO +HIDE_COMPOUND_REFERENCE= NO +SHOW_INCLUDE_FILES = NO +SHOW_GROUPED_MEMB_INC = NO +FORCE_LOCAL_INCLUDES = NO +INLINE_INFO = NO +SORT_MEMBER_DOCS = NO +SORT_BRIEF_DOCS = NO +SORT_MEMBERS_CTORS_1ST = YES +SORT_GROUP_NAMES = NO +SORT_BY_SCOPE_NAME = NO +STRICT_PROTO_MATCHING = NO +GENERATE_TODOLIST = NO +GENERATE_TESTLIST = NO +GENERATE_BUGLIST = NO +GENERATE_DEPRECATEDLIST= NO +ENABLED_SECTIONS = +MAX_INITIALIZER_LINES = 30 +SHOW_USED_FILES = NO +SHOW_FILES = NO +SHOW_NAMESPACES = NO +FILE_VERSION_FILTER = +LAYOUT_FILE = +CITE_BIB_FILES = + +#--------------------------------------------------------------------------- +# Configuration options related to warning and progress messages +#--------------------------------------------------------------------------- +QUIET = NO +WARNINGS = YES +WARN_IF_UNDOCUMENTED = YES +WARN_IF_DOC_ERROR = YES +WARN_NO_PARAMDOC = NO +WARN_AS_ERROR = NO +WARN_FORMAT = "$file:$line: $text" +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# Configuration options related to the input files +#--------------------------------------------------------------------------- +INPUT = ../include/nudb/ +INPUT_ENCODING = UTF-8 +FILE_PATTERNS = +RECURSIVE = NO +EXCLUDE = +EXCLUDE_SYMLINKS = NO +EXCLUDE_PATTERNS = +EXCLUDE_SYMBOLS = +EXAMPLE_PATH = +EXAMPLE_PATTERNS = +EXAMPLE_RECURSIVE = NO +IMAGE_PATH = +INPUT_FILTER = +FILTER_PATTERNS = +FILTER_SOURCE_FILES = NO +FILTER_SOURCE_PATTERNS = +USE_MDFILE_AS_MAINPAGE = + +#--------------------------------------------------------------------------- +# Configuration options related to source browsing +#--------------------------------------------------------------------------- +SOURCE_BROWSER = NO +INLINE_SOURCES = NO +STRIP_CODE_COMMENTS = YES +REFERENCED_BY_RELATION = NO +REFERENCES_RELATION = NO +REFERENCES_LINK_SOURCE = YES +SOURCE_TOOLTIPS = YES +USE_HTAGS = NO +VERBATIM_HEADERS = YES +CLANG_ASSISTED_PARSING = NO +CLANG_OPTIONS = + +#--------------------------------------------------------------------------- +# Configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- +ALPHABETICAL_INDEX = YES +COLS_IN_ALPHA_INDEX = 5 +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the HTML output +#--------------------------------------------------------------------------- +GENERATE_HTML = NO +HTML_OUTPUT = dhtm +HTML_FILE_EXTENSION = .html +HTML_HEADER = +HTML_FOOTER = +HTML_STYLESHEET = +HTML_EXTRA_STYLESHEET = +HTML_EXTRA_FILES = +HTML_COLORSTYLE_HUE = 220 +HTML_COLORSTYLE_SAT = 100 +HTML_COLORSTYLE_GAMMA = 80 +HTML_TIMESTAMP = NO +HTML_DYNAMIC_SECTIONS = NO +HTML_INDEX_NUM_ENTRIES = 100 +GENERATE_DOCSET = NO +DOCSET_FEEDNAME = "Doxygen generated docs" +DOCSET_BUNDLE_ID = org.doxygen.Project +DOCSET_PUBLISHER_ID = org.doxygen.Publisher +DOCSET_PUBLISHER_NAME = Publisher +GENERATE_HTMLHELP = NO +CHM_FILE = +HHC_LOCATION = +GENERATE_CHI = NO +CHM_INDEX_ENCODING = +BINARY_TOC = NO +TOC_EXPAND = NO +GENERATE_QHP = NO +QCH_FILE = +QHP_NAMESPACE = org.doxygen.Project +QHP_VIRTUAL_FOLDER = doc +QHP_CUST_FILTER_NAME = +QHP_CUST_FILTER_ATTRS = +QHP_SECT_FILTER_ATTRS = +QHG_LOCATION = +GENERATE_ECLIPSEHELP = NO +ECLIPSE_DOC_ID = org.doxygen.Project +DISABLE_INDEX = NO +GENERATE_TREEVIEW = NO +ENUM_VALUES_PER_LINE = 4 +TREEVIEW_WIDTH = 250 +EXT_LINKS_IN_WINDOW = NO +FORMULA_FONTSIZE = 10 +FORMULA_TRANSPARENT = YES +USE_MATHJAX = NO +MATHJAX_FORMAT = HTML-CSS +MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest +MATHJAX_EXTENSIONS = +MATHJAX_CODEFILE = +SEARCHENGINE = YES +SERVER_BASED_SEARCH = NO +EXTERNAL_SEARCH = NO +SEARCHENGINE_URL = +SEARCHDATA_FILE = searchdata.xml +EXTERNAL_SEARCH_ID = +EXTRA_SEARCH_MAPPINGS = + +#--------------------------------------------------------------------------- +# Configuration options related to the LaTeX output +#--------------------------------------------------------------------------- +GENERATE_LATEX = NO +LATEX_OUTPUT = latex +LATEX_CMD_NAME = latex +MAKEINDEX_CMD_NAME = makeindex +COMPACT_LATEX = NO +PAPER_TYPE = a4 +EXTRA_PACKAGES = +LATEX_HEADER = +LATEX_FOOTER = +LATEX_EXTRA_STYLESHEET = +LATEX_EXTRA_FILES = +PDF_HYPERLINKS = YES +USE_PDFLATEX = YES +LATEX_BATCHMODE = NO +LATEX_HIDE_INDICES = NO +LATEX_SOURCE_CODE = NO +LATEX_BIB_STYLE = plain +LATEX_TIMESTAMP = NO + +#--------------------------------------------------------------------------- +# Configuration options related to the RTF output +#--------------------------------------------------------------------------- +GENERATE_RTF = NO +RTF_OUTPUT = rtf +COMPACT_RTF = NO +RTF_HYPERLINKS = NO +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = +RTF_SOURCE_CODE = NO + +#--------------------------------------------------------------------------- +# Configuration options related to the man page output +#--------------------------------------------------------------------------- +GENERATE_MAN = NO +MAN_OUTPUT = man +MAN_EXTENSION = .3 +MAN_SUBDIR = +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# Configuration options related to the XML output +#--------------------------------------------------------------------------- +GENERATE_XML = YES +XML_OUTPUT = temp/ +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# Configuration options related to the DOCBOOK output +#--------------------------------------------------------------------------- +GENERATE_DOCBOOK = NO +DOCBOOK_OUTPUT = docbook +DOCBOOK_PROGRAMLISTING = NO + +#--------------------------------------------------------------------------- +# Configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- +GENERATE_AUTOGEN_DEF = NO +GENERATE_PERLMOD = NO +PERLMOD_LATEX = NO +PERLMOD_PRETTY = YES +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = YES +EXPAND_ONLY_PREDEF = YES +SEARCH_INCLUDES = YES +INCLUDE_PATH = ../ +INCLUDE_FILE_PATTERNS = +PREDEFINED = DOXYGEN \ + GENERATING_DOCS \ + _MSC_VER \ + NUDB_POSIX_FILE=1 + +EXPAND_AS_DEFINED = +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration options related to external references +#--------------------------------------------------------------------------- +TAGFILES = +GENERATE_TAGFILE = +ALLEXTERNALS = NO +EXTERNAL_GROUPS = YES +EXTERNAL_PAGES = YES +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- +CLASS_DIAGRAMS = NO +MSCGEN_PATH = +DIA_PATH = +HIDE_UNDOC_RELATIONS = YES +HAVE_DOT = NO +DOT_NUM_THREADS = 0 +DOT_FONTNAME = Helvetica +DOT_FONTSIZE = 10 +DOT_FONTPATH = +CLASS_GRAPH = YES +COLLABORATION_GRAPH = YES +GROUP_GRAPHS = YES +UML_LOOK = NO +UML_LIMIT_NUM_FIELDS = 10 +TEMPLATE_RELATIONS = NO +INCLUDE_GRAPH = YES +INCLUDED_BY_GRAPH = YES +CALL_GRAPH = NO +CALLER_GRAPH = NO +GRAPHICAL_HIERARCHY = YES +DIRECTORY_GRAPH = YES +DOT_IMAGE_FORMAT = png +INTERACTIVE_SVG = NO +DOT_PATH = +DOTFILE_DIRS = +MSCFILE_DIRS = +DIAFILE_DIRS = +PLANTUML_JAR_PATH = +PLANTUML_INCLUDE_PATH = +DOT_GRAPH_MAX_NODES = 50 +MAX_DOT_GRAPH_DEPTH = 0 +DOT_TRANSPARENT = NO +DOT_MULTI_TARGETS = NO +GENERATE_LEGEND = YES +DOT_CLEANUP = YES diff --git a/doc/types/File.qbk b/doc/types/File.qbk new file mode 100644 index 000000000..f36259cdd --- /dev/null +++ b/doc/types/File.qbk @@ -0,0 +1,159 @@ +[/ + Copyright (c) 2013-2016 Vinnie Falco (vinnie dot falco at gmail dot com) + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +] + +[section:File File] + +The [*File] concept abstracts access to files in the underlying file system. +Two implementations are provided, one for the Win32 API and the other for +POSIX compliant systems. The [link nudb.ref.nudb__native_file native_file] type +alias is automatically set to either [link nudb.ref.nudb__win32_file win32_file] +or [link nudb.ref.nudb__posix_file posix_file] as appropriate. + +To support interfaces other than Win32 or POSIX, callers may provide their +own [*File] type that meets these requirements. The unit test code also provides +its own [*File] type which causes simulated operating system file failures +to exercise all failure paths in the implementation. + +In the table below: + +* `X` denotes a [*File] type +* `a` and `b` denote values of type `X` +* `c` denotes a (possibly const) value of type `X` +* `m` denotes a value of type [link nudb.ref.nudb__file_mode file_mode] +* `f` denotes a value of type [link nudb.ref.nudb__path_type path_type] +* `q` denotes a value of type `void*` +* `p` denotes a value of type `void const*` +* `ec` denotes a value of type [link nudb.ref.nudb__error_code error_code] + + +* `o` denotes a value of type `std::uint64_t` +* `n` denotes a value of type `std::size_t` + +[table File requirements +[[operation] [type] [semantics, pre/post-conditions]] +[ + [`X a{std::move(b)}`] + [ ] + [ + `X` is `MoveConstructible` + ] +] +[ + [`c.is_open()`] + [`bool`] + [ + Returns `true` if `c` refers to an open file. + ] +] +[ + [`a.close()`] + [ ] + [ + If `a` refers to an open file, closes the file. Does nothing if + `a` does not refer to an open file. After this call, `a.open()` + will return `false`. + ] +] +[ + [`a.create(m,f,ec)`] + [ ] + [ + Attempts to create a file at the path specified by `f`, and + open it with the mode specified by `m`. If an error occurs, + `ec` is set to the system specific error code. If no error + occurs, a subsequent call to `a.is_open()` will return `true`. + Undefined behavior if `a` already refers to an open file. + ] +] +[ + [`a.open(m,f,ec)`] + [ ] + [ + Attempts to open the file at the path specified by `f`. If + an error occurs, `ec` is set to the system specific error + code. If no error occurs, a subsequent call to `a.is_open()` + will return `true`. Undefined behavior if `a` already refers + to an open file. + ] +] +[ + [`X::erase(f,ec)`] + [ ] + [ + Attempts to delete the file at the path specified by `f`. + If an error occurs, `ec` is set to the system specific error + code. + ] +] +[ + [`c.size(ec)`] + [ `std::uint64_t` ] + [ + Returns the size of the file in bytes. This value is also equal to + lowest byte offset for which a read will always return a + [link nudb.ref.nudb__error short_read] error. Undefined + behavior if `a` does not refer to an open file. + ] +] +[ + [`a.read(o,p,n,ec)`] + [ ] + [ + Attempts to read `n` bytes from the open file referred to by `a`, + starting at offset `o`, and storing the results in the memory + pointed to by `p`, which must be at least of size `n` bytes. + If an error occurs, `ec` is set to the system specific error + code. Undefined behavior if `a` does not refer to an open file. + ] +] +[ + [`a.write(o,q,n,ec)`] + [ ] + [ + Attempts to write `n` bytes to the open file referred to by `a` + and opened with a write mode, starting at offset `o`, and storing + the results in the memory pointed to by `p`, which must be at + least of size `n` bytes. If an error occurs, `ec` is set to the + system specific error code. Undefined behavior if `a` does not + refer to an open file. + ] +] +[ + [`a.sync(ec)`] + [ ] + [ + Attempts to synchronize the file on disk. This instructs the + operating system to ensure that any data which resides in caches + or buffers is fully written to the underlying storage device + before this call returns. If an error occurs, `ec` is set to the + system specific error code. Undefined behavior if `a` does not + refer to an open file. + + NuDB's database integrity guarantees are only valid if the + implementation of `sync` assures that all data is fully written + to the underlying file before the call returns. + ] +] +[ + [`a.trunc(o,ec)`] + [ ] + [ + Attempts to change the size of the open file referred to by `a` + and opened with a write mode, to the size in bytes specified + by `o`. If an error occurs, `ec` is set to the system specific + error code. Undefined behavior if `a` does not refer to an open + file. After a successful call, `a.size(ec)` will return `o`. + + NuDB's database integrity guarantees are only valid if the + implementation of `trunc` assures that subsequent calls to + `size` will return `o`, even if the program is terminated or the + device is taken offline before calling `size`. + ] +] +] + +[endsect] diff --git a/doc/types/Hasher.qbk b/doc/types/Hasher.qbk new file mode 100644 index 000000000..e80955b9e --- /dev/null +++ b/doc/types/Hasher.qbk @@ -0,0 +1,56 @@ +[/ + Copyright (c) 2013-2016 Vinnie Falco (vinnie dot falco at gmail dot com) + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +] + +[section:Hasher Hasher] + +A [@Hasher] implements a hash algorithm. This is used to compute the small +digests NuDB needs to effectively implement a hash table. NuDB provides +the default implementation [link nudb.ref.nudb__xxhasher xxhasher], which is +suitable for most use cases. For advanced applications, a user supplied +hash function may be supplied which must meet these requirements. + +In the table below: + +* `X` denotes a hasher class +* `a` denotes a value of type `X const` +* `s` denotes a value of type `std::uint64_t` +* `p` denotes a value of type `void const*` +* `n` denotes a value of type `std::size_t` + +[table Hasher requirements +[[operation] [type] [semantics, pre/post-conditions]] +[ + [`X a{s}`] + [ ] + [ + `a` is constructed with a seed value integer. To achieve resistance + from algorithmic complexity attacks, an implementation of [*Hasher] + should ensure that values returned from the hash function will be + distinctly different for different values of `s` given the same + inputs. If algorithmic complexity attack resistance is not a + requirement, the seed may be ignored upon construction. + ] +] +[ + [`a(p,n)`] + [ `std::uint64_t` ] + [ + Returns the digest of the memory `n` bytes in size and pointed + to by `p`. `n` will never be zero. A good hash function will + return values with these qualities: + +* Values are uniformly distributed in the full range + +* Values for the same input are distinctly different for different seeds + +* Small changes in the input produce unpredictable output values + + ] +] +] + +[endsect] diff --git a/doc/types/Progress.qbk b/doc/types/Progress.qbk new file mode 100644 index 000000000..44a76ad51 --- /dev/null +++ b/doc/types/Progress.qbk @@ -0,0 +1,40 @@ +[/ + Copyright (c) 2013-2016 Vinnie Falco (vinnie dot falco at gmail dot com) + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +] + +[section:Progress Progress] + +A [*Progress] object provides feedback to callers on the progress of +long running operations such as calls to [link nudb.ref.nudb__verify verify] or +[link nudb.ref.nudb__rekey rekey] which can take days or weeks for database that +measure in the terabytes. These objects are used by passing them as parameters +to the appropriate functions, where the will be called periodically with +numbers that indicate the amount of work completed, versus the total amount +of work required. + +In the table below: + +* `X` denotes a progress class +* `a` denotes a value of type `X` +* `p` and `q` denote values of type `std::uint64_t` + +[table Progress requirements +[[operation] [type] [semantics, pre/post-conditions]] +[ + [`a(p, q)`] + [ ] + [ + Indicates to the progress object that work has been performed and + intermediate results calculated. `p` represents the amount of work + completed from the beginning of the operation. `q` represents the + total amount of work required. The fraction of completed work is + therefore `p/q`, with zero representing no work complete, and one + represents all work complete. `p` and `q` are unitless. + ] +] +] + +[endsect] diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt new file mode 100644 index 000000000..ab7e10061 --- /dev/null +++ b/examples/CMakeLists.txt @@ -0,0 +1,17 @@ +# Part of nudb + +GroupSources (include/nudb nudb) +GroupSources (extras/nudb extras) +GroupSources (examples/ "/") + +add_executable (example + ${NUDB_INCLUDES} + ${EXTRAS_INCLUDES} + example.cpp +) + +if (WIN32) + target_link_libraries (example ${Boost_LIBRARIES}) +else () + target_link_libraries (example ${Boost_LIBRARIES} rt Threads::Threads) +endif () diff --git a/examples/Jamfile b/examples/Jamfile new file mode 100644 index 000000000..d165cc914 --- /dev/null +++ b/examples/Jamfile @@ -0,0 +1,12 @@ +# +# Copyright (c) 2013-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +# +# Distributed under the Boost Software License, Version 1.0. (See accompanying +# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +# + +import os ; + +exe example : + example.cpp + ; diff --git a/examples/example.cpp b/examples/example.cpp new file mode 100644 index 000000000..c9a96961c --- /dev/null +++ b/examples/example.cpp @@ -0,0 +1,46 @@ +// +// Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#include +#include +#include + +int main() +{ + using namespace nudb; + std::size_t constexpr N = 1000; + using key_type = std::uint32_t; + error_code ec; + auto const dat_path = "db.dat"; + auto const key_path = "db.key"; + auto const log_path = "db.log"; + create( + dat_path, key_path, log_path, + 1, + make_salt(), + sizeof(key_type), + block_size("."), + 0.5f, + ec); + store db; + db.open(dat_path, key_path, log_path, ec); + char data = 0; + // Insert + for(key_type i = 0; i < N; ++i) + db.insert(&i, &data, sizeof(data), ec); + // Fetch + for(key_type i = 0; i < N; ++i) + db.fetch(&i, + [&](void const* buffer, std::size_t size) + { + // do something with buffer, size + }, ec); + db.close(ec); + erase_file(dat_path); + erase_file(key_path); + erase_file(log_path); +} diff --git a/extras/README.md b/extras/README.md new file mode 100644 index 000000000..eb458c169 --- /dev/null +++ b/extras/README.md @@ -0,0 +1,5 @@ +This directory contains: + +* Additional interfaces not strictly part of NuDB's public APIs + +* Git submodules of dependencies used to build the tests and benchmarks diff --git a/extras/beast b/extras/beast new file mode 160000 index 000000000..2f9a8440c --- /dev/null +++ b/extras/beast @@ -0,0 +1 @@ +Subproject commit 2f9a8440c2432d8a196571d6300404cb76314125 diff --git a/extras/nudb/basic_seconds_clock.hpp b/extras/nudb/basic_seconds_clock.hpp new file mode 100644 index 000000000..61d004cff --- /dev/null +++ b/extras/nudb/basic_seconds_clock.hpp @@ -0,0 +1,200 @@ +// +// Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef BASIC_SECONDS_CLOCK_HPP +#define BASIC_SECONDS_CLOCK_HPP + +#include "chrono_util.hpp" + +#include +#include +#include +#include +#include +#include + +namespace detail { + +class seconds_clock_worker +{ +public: + virtual void sample() = 0; +}; + +//------------------------------------------------------------------------------ + +// Updates the clocks +class seconds_clock_thread +{ +public: + using mutex = std::mutex; + using cond_var = std::condition_variable; + using lock_guard = std::lock_guard ; + using unique_lock = std::unique_lock ; + using clock_type = std::chrono::steady_clock; + using seconds = std::chrono::seconds; + using thread = std::thread; + using workers = std::vector ; + + bool stop_; + mutex m_; + cond_var cond_; + workers workers_; + thread thread_; + + seconds_clock_thread() + : stop_(false) + { + thread_ = thread{ + &seconds_clock_thread::run, this}; + } + + ~seconds_clock_thread() + { + stop(); + } + + void add(seconds_clock_worker& w) + { + lock_guard lock{m_}; + workers_.push_back(&w); + } + + void remove(seconds_clock_worker& w) + { + lock_guard lock{m_}; + workers_.erase(std::find( + workers_.begin(), workers_.end(), &w)); + } + + void stop() + { + if(thread_.joinable()) + { + { + lock_guard lock{m_}; + stop_ = true; + } + cond_.notify_all(); + thread_.join(); + } + } + + void run() + { + unique_lock lock{m_}; + for(;;) + { + for(auto iter : workers_) + iter->sample(); + + using namespace std::chrono; + clock_type::time_point const when( + floor ( + clock_type::now().time_since_epoch()) + + milliseconds(900)); + + if(cond_.wait_until(lock, when, [this]{ return stop_; })) + return; + } + } + + static seconds_clock_thread& instance() + { + static seconds_clock_thread singleton; + return singleton; + } +}; + +} // detail + +//------------------------------------------------------------------------------ + +/** Called before main exits to terminate the utility thread. + This is a workaround for Visual Studio 2013: + http://connect.microsoft.com/VisualStudio/feedback/details/786016/creating-a-global-c-object-that-used-thread-join-in-its-destructor-causes-a-lockup + http://stackoverflow.com/questions/10915233/stdthreadjoin-hangs-if-called-after-main-exits-when-using-vs2012-rc +*/ +inline +void +basic_seconds_clock_main_hook() +{ +#ifdef _MSC_VER + detail::seconds_clock_thread::instance().stop(); +#endif +} + +/** A clock whose minimum resolution is one second. + + The purpose of this class is to optimize the performance of the now() + member function call. It uses a dedicated thread that wakes up at least + once per second to sample the requested trivial clock. + + @tparam Clock A type meeting these requirements: + http://en.cppreference.com/w/cpp/concept/Clock +*/ +template +class basic_seconds_clock +{ +public: + using rep = typename Clock::rep; + using period = typename Clock::period; + using duration = typename Clock::duration; + using time_point = typename Clock::time_point; + + static bool const is_steady = Clock::is_steady; + + static time_point now() + { + // Make sure the thread is constructed before the + // worker otherwise we will crash during destruction + // of objects with static storage duration. + struct initializer + { + initializer() + { + detail::seconds_clock_thread::instance(); + } + }; + static initializer init; + + struct worker : detail::seconds_clock_worker + { + time_point m_now; + std::mutex m_; + + worker() + : m_now(Clock::now()) + { + detail::seconds_clock_thread::instance().add(*this); + } + + ~worker() + { + detail::seconds_clock_thread::instance().remove(*this); + } + + time_point now() + { + std::lock_guard lock{m_}; + return m_now; + } + + void sample() + { + std::lock_guard lock{m_}; + m_now = Clock::now(); + } + }; + + static worker w; + + return w.now(); + } +}; + +#endif diff --git a/extras/nudb/chrono_util.hpp b/extras/nudb/chrono_util.hpp new file mode 100644 index 000000000..582407aac --- /dev/null +++ b/extras/nudb/chrono_util.hpp @@ -0,0 +1,58 @@ +// +// Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef CHRONO_UTIL_HPP +#define CHRONO_UTIL_HPP + +#include + +// From Howard Hinnant +// http://home.roadrunner.com/~hinnant/duration_io/chrono_util.html + +#if !defined(_MSC_FULL_VER) || (_MSC_FULL_VER <= 190023506) +// round down +template +To floor(std::chrono::duration const& d) +{ + To t = std::chrono::duration_cast(d); + if (t > d) + --t; + return t; +} + +// round to nearest, to even on tie +template +To round (std::chrono::duration const& d) +{ + To t0 = std::chrono::duration_cast(d); + To t1 = t0; + ++t1; + auto diff0 = d - t0; + auto diff1 = t1 - d; + if (diff0 == diff1) + { + if (t0.count() & 1) + return t1; + return t0; + } + else if (diff0 < diff1) + return t0; + return t1; +} + +// round up +template +To ceil (std::chrono::duration const& d) +{ + To t = std::chrono::duration_cast(d); + if (t < d) + ++t; + return t; +} +#endif + +#endif diff --git a/extras/nudb/test/fail_file.hpp b/extras/nudb/test/fail_file.hpp new file mode 100644 index 000000000..252f2feed --- /dev/null +++ b/extras/nudb/test/fail_file.hpp @@ -0,0 +1,343 @@ +// +// Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef NUDB_TEST_FAIL_FILE_HPP +#define NUDB_TEST_FAIL_FILE_HPP + +#include +#include +#include +#include +#include +#include +#include + +namespace nudb { +namespace test { + +/// Test error codes. +enum class test_error +{ + /// No error + success = 0, + + /// Simulated failure + failure +}; + +/// Returns the error category used for test error codes. +inline +error_category const& +test_category() +{ + struct cat_t : public error_category + { + char const* + name() const noexcept override + { + return "nudb"; + } + + std::string + message(int ev) const override + { + switch(static_cast(ev)) + { + case test_error::failure: + return "test failure"; + + default: + return "test error"; + } + } + + error_condition + default_error_condition(int ev) const noexcept override + { + return error_condition{ev, *this}; + } + + bool + equivalent(int ev, + error_condition const& ec) const noexcept override + { + return ec.value() == ev && &ec.category() == this; + } + + bool + equivalent(error_code const& ec, int ev) const noexcept override + { + return ec.value() == ev && &ec.category() == this; + } + }; + static cat_t const cat{}; + return cat; +} + +/// Returns a test error code. +inline +error_code +make_error_code(test_error ev) +{ + return error_code{static_cast(ev), test_category()}; +} + +} // test +} // nudb + +namespace boost { +namespace system { +template<> +struct is_error_code_enum +{ + static bool const value = true; +}; +} // system +} // boost + +namespace nudb { +namespace test { + +/** Countdown to test failure mode. + + The counter is constructed with a target ordinal and decremented + by callers. When the count reaches zero, a simulated test failure + is generated. +*/ +class fail_counter +{ + std::size_t target_; + std::atomic count_; + +public: + fail_counter(fail_counter const&) = delete; + fail_counter& operator=(fail_counter const&) = delete; + + /// Construct the counter with a target ordinal. + explicit + fail_counter(std::size_t target = 0) + { + reset(target); + } + + /// Reset the counter to fail at the nth step, or 0 for no failure. + void + reset(std::size_t n = 0) + { + target_ = n; + count_.store(0); + } + + /// Returns `true` if a simulated failure should be generated. + bool + fail() + { + return target_ && (++count_ >= target_); + } +}; + +/** A file wrapper to simulate file system failures. + + This wraps an object meeting the requirements of File. On each call, + the fail counter is decremented. When the counter reaches zero, a simulated + failure is generated. +*/ +template +class fail_file +{ + static_assert(is_File::value, + "File requirements not met"); + + File f_; + fail_counter* c_ = nullptr; + +public: + fail_file() = default; + fail_file(fail_file const&) = delete; + fail_file& operator=(fail_file const&) = delete; + ~fail_file() = default; + + fail_file(fail_file&&); + + fail_file& + operator=(fail_file&& other); + + explicit + fail_file(fail_counter& c); + + bool + is_open() const + { + return f_.is_open(); + } + + path_type const& + path() const + { + return f_.path(); + } + + std::uint64_t + size(error_code& ec) const + { + return f_.size(ec); + } + + void + close() + { + f_.close(); + } + + void + create(file_mode mode, path_type const& path, error_code& ec) + { + return f_.create(mode, path, ec); + } + + void + open(file_mode mode, path_type const& path, error_code& ec) + { + return f_.open(mode, path, ec); + } + + static + void + erase(path_type const& path, error_code& ec) + { + File::erase(path, ec); + } + + void + read(std::uint64_t offset, + void* buffer, std::size_t bytes, error_code& ec); + + void + write(std::uint64_t offset, + void const* buffer, std::size_t bytes, error_code& ec); + + void + sync(error_code& ec); + + void + trunc(std::uint64_t length, error_code& ec); + +private: + bool + fail(); + + void + do_fail(error_code& ec) + { + ec = test_error::failure; + } +}; + +template +fail_file:: +fail_file(fail_file&& other) + : f_(std::move(other.f_)) + , c_(other.c_) +{ + other.c_ = nullptr; +} + +template +fail_file& +fail_file:: +operator=(fail_file&& other) +{ + f_ = std::move(other.f_); + c_ = other.c_; + other.c_ = nullptr; + return *this; +} + +template +fail_file:: +fail_file(fail_counter& c) + : c_(&c) +{ +} + +template +void +fail_file:: +read(std::uint64_t offset, + void* buffer, std::size_t bytes, error_code& ec) +{ + if(fail()) + { + do_fail(ec); + return; + } + f_.read(offset, buffer, bytes, ec); +} + +template +void +fail_file:: +write(std::uint64_t offset, + void const* buffer, std::size_t bytes, error_code& ec) +{ + if(fail()) + { + do_fail(ec); + return; + } + if(fail()) + { + // partial write + f_.write(offset, buffer,(bytes + 1) / 2, ec); + if(ec) + return; + do_fail(ec); + return; + } + f_.write(offset, buffer, bytes, ec); +} + +template +void +fail_file:: +sync(error_code& ec) +{ + if(fail()) + do_fail(ec); + // We don't need a real sync for + // testing, it just slows things down. + //f_.sync(); +} + +template +void +fail_file:: +trunc(std::uint64_t length, error_code& ec) +{ + if(fail()) + { + do_fail(ec); + return; + } + f_.trunc(length, ec); +} + +template +bool +fail_file:: +fail() +{ + if(c_) + return c_->fail(); + return false; +} + +} // test +} // nudb + +#endif + diff --git a/extras/nudb/test/temp_dir.hpp b/extras/nudb/test/temp_dir.hpp new file mode 100644 index 000000000..470d6603b --- /dev/null +++ b/extras/nudb/test/temp_dir.hpp @@ -0,0 +1,73 @@ +// +// Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef NUDB_TEST_TEMP_DIR_HPP +#define NUDB_TEST_TEMP_DIR_HPP + +#include +#include + +namespace nudb { +namespace test { + +/** RAII temporary directory path. + + The directory and all its contents are deleted when + the instance of `temp_dir` is destroyed. +*/ +class temp_dir +{ + boost::filesystem::path path_; + +public: + temp_dir(const temp_dir&) = delete; + temp_dir& operator=(const temp_dir&) = delete; + + /// Construct a temporary directory. + explicit + temp_dir(boost::filesystem::path dir) + { + if (dir.empty()) + dir = boost::filesystem::temp_directory_path(); + + do + { + path_ = + dir / boost::filesystem::unique_path(); + } + while(boost::filesystem::exists(path_)); + boost::filesystem::create_directory(path_); + } + + /// Destroy a temporary directory. + ~temp_dir() + { + boost::filesystem::remove_all(path_); + } + + /// Get the native path for the temporary directory + std::string + path() const + { + return path_.string(); + } + + /** Get the native path for the a file. + + The file does not need to exist. + */ + std::string + file(std::string const& name) const + { + return (path_ / name).string(); + } +}; + +} // test +} // nudb + +#endif diff --git a/extras/nudb/test/test_store.hpp b/extras/nudb/test/test_store.hpp new file mode 100644 index 000000000..a43cdda93 --- /dev/null +++ b/extras/nudb/test/test_store.hpp @@ -0,0 +1,451 @@ +// +// Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef NUDB_TEST_TEST_STORE_HPP +#define NUDB_TEST_TEST_STORE_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace nudb { +namespace test { + +template +class Buffer_t +{ + std::size_t size_ = 0; + std::size_t capacity_ = 0; + std::unique_ptr p_; + +public: + Buffer_t() = default; + + Buffer_t(Buffer_t&& other); + + Buffer_t(Buffer_t const& other); + + Buffer_t& operator=(Buffer_t&& other); + + Buffer_t& operator=(Buffer_t const& other); + + bool + empty() const + { + return size_ == 0; + } + + std::size_t + size() const + { + return size_; + } + + std::uint8_t* + data() + { + return p_.get(); + } + + std::uint8_t const* + data() const + { + return p_.get(); + } + + void + clear(); + + void + shrink_to_fit(); + + std::uint8_t* + resize(std::size_t size); + + std::uint8_t* + operator()(void const* data, std::size_t size); +}; + +template +Buffer_t<_>:: +Buffer_t(Buffer_t&& other) + : size_(other.size_) + , capacity_(other.capacity_) + , p_(std::move(other.p_)) +{ + other.size_ = 0; + other.capacity_ = 0; +} + +template +Buffer_t<_>:: +Buffer_t(Buffer_t const& other) +{ + if(! other.empty()) + std::memcpy(resize(other.size()), + other.data(), other.size()); +} + +template +auto +Buffer_t<_>:: +operator=(Buffer_t&& other) -> + Buffer_t& +{ + if(&other != this) + { + size_ = other.size_; + capacity_ = other.capacity_; + p_ = std::move(other.p_); + other.size_ = 0; + other.capacity_ = 0; + } + return *this; +} + +template +auto +Buffer_t<_>:: +operator=(Buffer_t const& other) -> + Buffer_t& +{ + if(&other != this) + { + if(other.empty()) + size_ = 0; + else + std::memcpy(resize(other.size()), + other.data(), other.size()); + } + return *this; +} + +template +void +Buffer_t<_>:: +clear() +{ + size_ = 0; + capacity_ = 0; + p_.reset(); +} + +template +void +Buffer_t<_>:: +shrink_to_fit() +{ + if(empty() || size_ == capacity_) + return; + std::unique_ptr p{ + new std::uint8_t[size_]}; + capacity_ = size_; + std::memcpy(p.get(), p_.get(), size_); + std::swap(p, p_); +} + +template +std::uint8_t* +Buffer_t<_>:: +resize(std::size_t size) +{ + if(capacity_ < size) + { + p_.reset(new std::uint8_t[size]); + capacity_ = size; + } + size_ = size; + return p_.get(); +} + +template +std::uint8_t* +Buffer_t<_>:: +operator()(void const* data, std::size_t size) +{ + if(data == nullptr || size == 0) + return resize(0); + return reinterpret_cast( + std::memcpy(resize(size), data, size)); +} + +using Buffer = Buffer_t<>; + +//------------------------------------------------------------------------------ + +/// Describes a test generated key/value pair +struct item_type +{ + std::uint8_t* key; + std::uint8_t* data; + std::size_t size; +}; + +/// Interface to facilitate tests +template +class basic_test_store +{ + using Hasher = xxhasher; + + temp_dir td_; + std::uniform_int_distribution sizef_; + std::function createf_; + std::function openf_; + Buffer buf_; + +public: + path_type const dp; + path_type const kp; + path_type const lp; + std::size_t const keySize; + std::size_t const blockSize; + float const loadFactor; + static std::uint64_t constexpr appnum = 1; + static std::uint64_t constexpr salt = 42; + basic_store db; + + template + basic_test_store(std::size_t keySize, + std::size_t blockSize, float loadFactor, + Args&&... args); + + template + basic_test_store( + boost::filesystem::path const& temp_dir, + std::size_t keySize, std::size_t blockSize, float loadFactor, + Args&&... args); + + ~basic_test_store(); + + item_type + operator[](std::uint64_t i); + + void + create(error_code& ec); + + void + open(error_code& ec); + + void + close(error_code& ec) + { + db.close(ec); + } + + void + erase(); + +private: + template + static + void + rngfill( + void* dest, std::size_t size, Generator& g); +}; + +template +template +basic_test_store::basic_test_store( + boost::filesystem::path const& temp_dir, + std::size_t keySize_, std::size_t blockSize_, + float loadFactor_, Args&&... args) + : td_(temp_dir) + , sizef_(250, 750) + , createf_( + [this, args...](error_code& ec) + { + nudb::create( + dp, kp, lp, appnum, salt, + keySize, blockSize, loadFactor, ec, + args...); + }) + , openf_( + [this, args...](error_code& ec) + { + db.open(dp, kp, lp, ec, args...); + }) + , dp(td_.file("nudb.dat")) + , kp(td_.file("nudb.key")) + , lp(td_.file("nudb.log")) + , keySize(keySize_) + , blockSize(blockSize_) + , loadFactor(loadFactor_) +{ +} + +template +template +basic_test_store::basic_test_store(std::size_t keySize_, + std::size_t blockSize_, float loadFactor_, + Args&&... args) + : basic_test_store(boost::filesystem::path{}, + keySize_, + blockSize_, + loadFactor_, + std::forward(args)...) +{ +} + +template +basic_test_store:: +~basic_test_store() +{ + erase(); +} + +template +auto +basic_test_store:: +operator[](std::uint64_t i) -> + item_type +{ + xor_shift_engine g{i + 1}; + item_type item; + item.size = sizef_(g); + auto const needed = keySize + item.size; + rngfill(buf_.resize(needed), needed, g); + // put key last so we can get some unaligned + // keys, this increases coverage of xxhash. + item.data = buf_.data(); + item.key = buf_.data() + item.size; + return item; +} + +template +void +basic_test_store:: +create(error_code& ec) +{ + createf_(ec); +} + +template +void +basic_test_store:: +open(error_code& ec) +{ + openf_(ec); + if(ec) + return; + if(db.key_size() != keySize) + ec = error::invalid_key_size; + else if(db.block_size() != blockSize) + ec = error::invalid_block_size; +} + +template +void +basic_test_store:: +erase() +{ + erase_file(dp); + erase_file(kp); + erase_file(lp); +} + +template +template +void +basic_test_store:: +rngfill( + void* dest, std::size_t size, Generator& g) +{ + using result_type = + typename Generator::result_type; + while(size >= sizeof(result_type)) + { + auto const v = g(); + std::memcpy(dest, &v, sizeof(v)); + dest = reinterpret_cast< + std::uint8_t*>(dest) + sizeof(v); + size -= sizeof(v); + } + if(size > 0) + { + auto const v = g(); + std::memcpy(dest, &v, size); + } +} + +using test_store = basic_test_store; + +//------------------------------------------------------------------------------ + +template +static +std::string +num (T t) +{ + std::string s = std::to_string(t); + std::reverse(s.begin(), s.end()); + std::string s2; + s2.reserve(s.size() + (s.size()+2)/3); + int n = 0; + for (auto c : s) + { + if (n == 3) + { + n = 0; + s2.insert (s2.begin(), ','); + } + ++n; + s2.insert(s2.begin(), c); + } + return s2; +} + +template +std::ostream& +operator<<(std::ostream& os, verify_info const& info) +{ + os << + "avg_fetch: " << std::fixed << std::setprecision(3) << info.avg_fetch << "\n" << + "waste: " << std::fixed << std::setprecision(3) << info.waste * 100 << "%" << "\n" << + "overhead: " << std::fixed << std::setprecision(1) << info.overhead * 100 << "%" << "\n" << + "actual_load: " << std::fixed << std::setprecision(0) << info.actual_load * 100 << "%" << "\n" << + "version: " << num(info.version) << "\n" << + "uid: " << fhex(info.uid) << "\n" << + "appnum: " << info.appnum << "\n" << + "key_size: " << num(info.key_size) << "\n" << + "salt: " << fhex(info.salt) << "\n" << + "pepper: " << fhex(info.pepper) << "\n" << + "block_size: " << num(info.block_size) << "\n" << + "bucket_size: " << num(info.bucket_size) << "\n" << + "load_factor: " << std::fixed << std::setprecision(0) << info.load_factor * 100 << "%" << "\n" << + "capacity: " << num(info.capacity) << "\n" << + "buckets: " << num(info.buckets) << "\n" << + "key_count: " << num(info.key_count) << "\n" << + "value_count: " << num(info.value_count) << "\n" << + "value_bytes: " << num(info.value_bytes) << "\n" << + "spill_count: " << num(info.spill_count) << "\n" << + "spill_count_tot: " << num(info.spill_count_tot) << "\n" << + "spill_bytes: " << num(info.spill_bytes) << "\n" << + "spill_bytes_tot: " << num(info.spill_bytes_tot) << "\n" << + "key_file_size: " << num(info.key_file_size) << "\n" << + "dat_file_size: " << num(info.dat_file_size) << std::endl; + + std::string s; + for (size_t i = 0; i < info.hist.size(); ++i) + s += (i==0) ? + std::to_string(info.hist[i]) : + (", " + std::to_string(info.hist[i])); + os << "hist: " << s << std::endl; + return os; +} + +} // test +} // nudb + +#endif + diff --git a/extras/nudb/test/xor_shift_engine.hpp b/extras/nudb/test/xor_shift_engine.hpp new file mode 100644 index 000000000..a6529933e --- /dev/null +++ b/extras/nudb/test/xor_shift_engine.hpp @@ -0,0 +1,105 @@ +// +// Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef NUDB_TEST_XOR_SHIFT_ENGINE_HPP +#define NUDB_TEST_XOR_SHIFT_ENGINE_HPP + +#include +#include +#include + +namespace nudb { +namespace test { + +/** XOR-shift Generator. + + Meets the requirements of UniformRandomNumberGenerator. + + Simple and fast RNG based on: + http://xorshift.di.unimi.it/xorshift128plus.c + does not accept seed==0 +*/ +class xor_shift_engine +{ +public: + using result_type = std::uint64_t; + + xor_shift_engine(xor_shift_engine const&) = default; + xor_shift_engine& operator=(xor_shift_engine const&) = default; + + explicit + xor_shift_engine(result_type val = 1977u) + { + seed(val); + } + + void + seed(result_type seed); + + result_type + operator()(); + + static + result_type constexpr + min() + { + return std::numeric_limits::min(); + } + + static + result_type constexpr + max() + { + return std::numeric_limits::max(); + } + +private: + result_type s_[2]; + + static + result_type + murmurhash3(result_type x); +}; + +inline +void +xor_shift_engine::seed(result_type seed) +{ + if(seed == 0) + throw std::domain_error("invalid seed"); + s_[0] = murmurhash3(seed); + s_[1] = murmurhash3(s_[0]); +} + +inline +auto +xor_shift_engine::operator()() -> + result_type +{ + result_type s1 = s_[0]; + result_type const s0 = s_[1]; + s_[0] = s0; + s1 ^= s1<< 23; + return(s_[1] =(s1 ^ s0 ^(s1 >> 17) ^(s0 >> 26))) + s0; +} + +inline +auto +xor_shift_engine::murmurhash3(result_type x) + -> result_type +{ + x ^= x >> 33; + x *= 0xff51afd7ed558ccdULL; + x ^= x >> 33; + x *= 0xc4ceb9fe1a85ec53ULL; + return x ^= x >> 33; +} + +} // test +} // nudb + +#endif diff --git a/extras/nudb/util.hpp b/extras/nudb/util.hpp new file mode 100644 index 000000000..c34f57407 --- /dev/null +++ b/extras/nudb/util.hpp @@ -0,0 +1,288 @@ +// +// Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef UTIL_HPP +#define UTIL_HPP + +#include "basic_seconds_clock.hpp" + +#include +#include +#include +#include + +namespace nudb { + +template +int +log2(std::uint64_t n) +{ + int i = -(n == 0); + + auto const S = + [&](int k) + { + if(n >=(std::uint64_t{1} << k)) + { + i += k; + n >>= k; + } + }; + S(32); S(16); S(8); S(4); S(2); S(1); + return i; +} + +// Format a decimal integer with comma separators +template +std::string +fdec(T t) +{ + std::string s = std::to_string(t); + std::reverse(s.begin(), s.end()); + std::string s2; + s2.reserve(s.size() +(s.size()+2)/3); + int n = 0; + for(auto c : s) + { + if(n == 3) + { + n = 0; + s2.insert(s2.begin(), ','); + } + ++n; + s2.insert(s2.begin(), c); + } + return s2; +} + +// format 64-bit unsigned as fixed width, 0 padded hex +template +std::string +fhex(T v) +{ + std::string s{"0x0000000000000000"}; + auto it = s.end(); + for(it = s.end(); v; v >>= 4) + *--it = "0123456789abcdef"[v & 0xf]; + return s; +} + +// Format an array of integers as a comma separated list +template +static +std::string +fhist(std::array const& hist) +{ + std::size_t n; + for(n = hist.size() - 1; n > 0; --n) + if(hist[n]) + break; + std::string s = std::to_string(hist[0]); + for(std::size_t i = 1; i <= n; ++i) + s += ", " + std::to_string(hist[i]); + return s; +} + +class save_stream_state +{ + std::ostream& os_; + std::streamsize precision_; + std::ios::fmtflags flags_; + std::ios::char_type fill_; + +public: + ~save_stream_state() + { + os_.precision(precision_); + os_.flags(flags_); + os_.fill(fill_); + } + save_stream_state(save_stream_state const&) = delete; + save_stream_state& operator=(save_stream_state const&) = delete; + explicit save_stream_state(std::ostream& os) + : os_(os) + , precision_(os.precision()) + , flags_(os.flags()) + , fill_(os.fill()) + { + } +}; + +template +std::ostream& +pretty_time(std::ostream& os, std::chrono::duration d) +{ + save_stream_state _(os); + using namespace std::chrono; + if(d < microseconds{1}) + { + // use nanoseconds + if(d < nanoseconds{100}) + { + // use floating + using ns = duration; + os << std::fixed << std::setprecision(1) << ns(d).count(); + } + else + { + // use integral + os << round(d).count(); + } + os << "ns"; + } + else if(d < milliseconds{1}) + { + // use microseconds + if(d < microseconds{100}) + { + // use floating + using ms = duration; + os << std::fixed << std::setprecision(1) << ms(d).count(); + } + else + { + // use integral + os << round(d).count(); + } + os << "us"; + } + else if(d < seconds{1}) + { + // use milliseconds + if(d < milliseconds{100}) + { + // use floating + using ms = duration; + os << std::fixed << std::setprecision(1) << ms(d).count(); + } + else + { + // use integral + os << round(d).count(); + } + os << "ms"; + } + else if(d < minutes{1}) + { + // use seconds + if(d < seconds{100}) + { + // use floating + using s = duration; + os << std::fixed << std::setprecision(1) << s(d).count(); + } + else + { + // use integral + os << round(d).count(); + } + os << "s"; + } + else + { + // use minutes + if(d < minutes{100}) + { + // use floating + using m = duration>; + os << std::fixed << std::setprecision(1) << m(d).count(); + } + else + { + // use integral + os << round(d).count(); + } + os << "min"; + } + return os; +} + +template +std::string +fmtdur(std::chrono::duration const& d) +{ + std::stringstream ss; + pretty_time(ss, d); + return ss.str(); +} + +//------------------------------------------------------------------------------ + +class progress +{ + using clock_type = basic_seconds_clock; + + std::ostream& os_; + clock_type::time_point start_; + clock_type::time_point now_; + clock_type::time_point report_; + std::uint64_t prev_; + bool estimate_; + +public: + explicit + progress(std::ostream& os) + : os_(os) + { + } + + void + operator()(std::uint64_t amount, std::uint64_t total) + { + using namespace std::chrono; + auto const now = clock_type::now(); + if(amount == 0) + { + now_ = clock_type::now(); + start_ = now_; + report_ = now_; + prev_ = 0; + estimate_ = false; + return; + } + if(now == now_) + return; + now_ = now; + auto const elapsed = now - start_; + if(! estimate_) + { + // Wait a bit before showing the first estimate + if(elapsed < seconds{30}) + return; + estimate_ = true; + } + else if(now - report_ < seconds{60}) + { + // Only show estimates periodically + return; + } + auto const rate = double(amount) / elapsed.count(); + auto const remain = clock_type::duration{ + static_cast( + (total - amount) / rate)}; + os_ << + "Remaining: " << fmtdur(remain) << + " (" << fdec(amount) << " of " << fdec(total) << + " in " << fmtdur(elapsed) << + ", " << fdec(amount - prev_) << + " in " << fmtdur(now - report_) << + ")\n"; + report_ = now; + prev_ = amount; + } + + clock_type::duration + elapsed() const + { + using namespace std::chrono; + return now_ - start_; + } +}; + +} // nudb + +#endif diff --git a/extras/rocksdb b/extras/rocksdb new file mode 160000 index 000000000..a297643f2 --- /dev/null +++ b/extras/rocksdb @@ -0,0 +1 @@ +Subproject commit a297643f2e327a8bc7061bfc838fdf11935a2cf2 diff --git a/include/nudb/basic_store.hpp b/include/nudb/basic_store.hpp new file mode 100644 index 000000000..0e69195fb --- /dev/null +++ b/include/nudb/basic_store.hpp @@ -0,0 +1,436 @@ +// +// Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef NUDB_BASIC_STORE_HPP +#define NUDB_BASIC_STORE_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace nudb { + +/** A high performance, insert-only key/value database for SSDs. + + To create a database first call the @ref create + free function. Then construct a @ref basic_store and + call @ref open on it: + + @code + error_code ec; + create( + "db.dat", "db.key", "db.log", + 1, make_salt(), 8, 4096, 0.5f, ec); + basic_store db; + db.open("db.dat", "db.key", "db.log", ec); + @endcode + + @tparam Hasher The hash function to use. This type + must meet the requirements of @b Hasher. + + @tparam File The type of File object to use. This type + must meet the requirements of @b File. +*/ +template +class basic_store +{ +public: + using hash_type = Hasher; + using file_type = File; + +private: + using clock_type = + std::chrono::steady_clock; + + using time_point = + typename clock_type::time_point; + + struct state + { + File df; + File kf; + File lf; + path_type dp; + path_type kp; + path_type lp; + Hasher hasher; + detail::pool p0; + detail::pool p1; + detail::cache c1; + detail::key_file_header kh; + + std::size_t rate = 0; + time_point when = clock_type::now(); + + state(state const&) = delete; + state& operator=(state const&) = delete; + + state(state&&) = default; + state& operator=(state&&) = default; + + state(File&& df_, File&& kf_, File&& lf_, + path_type const& dp_, path_type const& kp_, + path_type const& lp_, + detail::key_file_header const& kh_); + }; + + bool open_ = false; + + // Use optional because some + // members cannot be default-constructed. + // + boost::optional s_; // State of an open database + + std::size_t frac_; // accumulates load + std::size_t thresh_; // split threshold + nbuck_t buckets_; // number of buckets + nbuck_t modulus_; // hash modulus + + std::mutex u_; // serializes insert() + detail::gentex g_; + boost::shared_mutex m_; + std::thread t_; + std::condition_variable_any cv_; + + error_code ec_; + std::atomic ecb_; // `true` when ec_ set + + std::size_t dataWriteSize_; + std::size_t logWriteSize_; + +public: + /** Default constructor. + + A default constructed database is initially closed. + */ + basic_store() = default; + + /// Copy constructor (disallowed) + basic_store(basic_store const&) = delete; + + /// Copy assignment (disallowed) + basic_store& operator=(basic_store const&) = delete; + + /** Destroy the database. + + Files are closed, memory is freed, and data that has not been + committed is discarded. To ensure that all inserted data is + written, it is necessary to call @ref close before destroying + the @ref basic_store. + + This function ignores errors returned by @ref close; to receive + those errors it is necessary to call @ref close before the + @ref basic_store is destroyed. + */ + ~basic_store(); + + /** Returns `true` if the database is open. + + @par Thread safety + + Safe to call concurrently with any function + except @ref open or @ref close. + */ + bool + is_open() const + { + return open_; + } + + /** Return the path to the data file. + + @par Requirements + + The database must be open. + + @par Thread safety + + Safe to call concurrently with any function + except @ref open or @ref close. + + @return The data file path. + */ + path_type const& + dat_path() const; + + /** Return the path to the key file. + + @par Requirements + + The database must be open. + + @par Thread safety + + Safe to call concurrently with any function + except @ref open or @ref close. + + @return The key file path. + */ + path_type const& + key_path() const; + + /** Return the path to the log file. + + @par Requirements + + The database must be open. + + @par Thread safety + + Safe to call concurrently with any function + except @ref open or @ref close. + + @return The log file path. + */ + path_type const& + log_path() const; + + /** Return the appnum associated with the database. + + This is an unsigned 64-bit integer associated with the + database and defined by the application. It is set + once when the database is created in a call to + @ref create. + + @par Requirements + + The database must be open. + + @par Thread safety + + Safe to call concurrently with any function + except @ref open or @ref close. + + @return The appnum. + */ + std::uint64_t + appnum() const; + + /** Return the key size associated with the database. + + The key size is defined by the application when the + database is created in a call to @ref create. The + key size cannot be changed on an existing database. + + @par Requirements + + The database must be open. + + @par Thread safety + + Safe to call concurrently with any function + except @ref open or @ref close. + + @return The size of keys in the database. + */ + std::size_t + key_size() const; + + /** Return the block size associated with the database. + + The block size is defined by the application when the + database is created in a call to @ref create or when a + key file is regenerated in a call to @ref rekey. The + block size cannot be changed on an existing key file. + Instead, a new key file may be created with a different + block size. + + @par Requirements + + The database must be open. + + @par Thread safety + + Safe to call concurrently with any function + except @ref open or @ref close. + + @return The size of blocks in the key file. + */ + std::size_t + block_size() const; + + /** Close the database. + + All data is committed before closing. + + If an error occurs, the database is still closed. + + @par Requirements + + The database must be open. + + @par Thread safety + + Not thread safe. The caller is responsible for + ensuring that no other member functions are + called concurrently. + + @param ec Set to the error, if any occurred. + */ + void + close(error_code& ec); + + /** Open a database. + + The database identified by the specified data, key, and + log file paths is opened. If a log file is present, the + recovery mechanism is invoked to restore database integrity + before the function returns. + + @par Requirements + + The database must be not be open. + + @par Thread safety + + Not thread safe. The caller is responsible for + ensuring that no other member functions are + called concurrently. + + @param dat_path The path to the data file. + + @param key_path The path to the key file. + + @param log_path The path to the log file. + + @param ec Set to the error, if any occurred. + + @param args Optional arguments passed to @b File constructors. + + */ + template + void + open( + path_type const& dat_path, + path_type const& key_path, + path_type const& log_path, + error_code& ec, + Args&&... args); + + /** Fetch a value. + + The function checks the database for the specified + key, and invokes the callback if it is found. If + the key is not found, `ec` is set to @ref error::key_not_found. + If any other errors occur, `ec` is set to the + corresponding error. + + @par Requirements + + The database must be open. + + @par Thread safety + + Safe to call concurrently with any function except + @ref close. + + @note If the implementation encounters an error while + committing data to the database, this function will + immediately return with `ec` set to the error which + occurred. All subsequent calls to @ref fetch will + return the same error until the database is closed. + + @param key A pointer to a memory buffer of at least + @ref key_size() bytes, containing the key to be searched + for. + + @param callback A function which will be called with the + value data if the fetch is successful. The equivalent + signature must be: + @code + void callback( + void const* buffer, // A buffer holding the value + std::size_t size // The size of the value in bytes + ); + @endcode + The buffer provided to the callback remains valid + until the callback returns, ownership is not transferred. + + @param ec Set to the error, if any occurred. + */ + template + void + fetch(void const* key, Callback && callback, error_code& ec); + + /** Insert a value. + + This function attempts to insert the specified key/value + pair into the database. If the key already exists, + `ec` is set to @ref error::key_exists. If an error + occurs, `ec` is set to the corresponding error. + + @par Requirements + + The database must be open. + + @par Thread safety + + Safe to call concurrently with any function except + @ref close. + + @note If the implementation encounters an error while + committing data to the database, this function will + immediately return with `ec` set to the error which + occurred. All subsequent calls to @ref insert will + return the same error until the database is closed. + + @param key A buffer holding the key to be inserted. The + size of the buffer should be at least the `key_size` + associated with the open database. + + @param data A buffer holding the value to be inserted. + + @param bytes The size of the buffer holding the value + data. This value must be greater than 0 and no more + than 0xffffffff. + + @param ec Set to the error, if any occurred. + */ + void + insert(void const* key, void const* data, + nsize_t bytes, error_code& ec); + +private: + template + void + fetch(detail::nhash_t h, void const* key, + detail::bucket b, Callback && callback, error_code& ec); + + bool + exists(detail::nhash_t h, void const* key, + detail::shared_lock_type* lock, detail::bucket b, error_code& ec); + + void + split(detail::bucket& b1, detail::bucket& b2, + detail::bucket& tmp, nbuck_t n1, nbuck_t n2, + nbuck_t buckets, nbuck_t modulus, + detail::bulk_writer& w, error_code& ec); + + detail::bucket + load(nbuck_t n, detail::cache& c1, + detail::cache& c0, void* buf, error_code& ec); + + void + commit(detail::unique_lock_type& m, + std::size_t& work, error_code& ec); + + void + run(); +}; + +} // nudb + +#include + +#endif diff --git a/include/nudb/concepts.hpp b/include/nudb/concepts.hpp new file mode 100644 index 000000000..3d01d36a9 --- /dev/null +++ b/include/nudb/concepts.hpp @@ -0,0 +1,205 @@ +// +// Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef NUDB_CONCEPTS_HPP +#define NUDB_CONCEPTS_HPP + +#include +#include +#include +#include +#include + +namespace nudb { + +namespace detail { + +template +class check_is_File +{ + template().is_open()), + bool>> + static R check1(int); + template + static std::false_type check1(...); + using type1 = decltype(check1(0)); + + template().close(), + std::true_type{})> + static R check2(int); + template + static std::false_type check2(...); + using type2 = decltype(check2(0)); + + template().create( + std::declval(), + std::declval(), + std::declval()), + std::true_type{})> + static R check3(int); + template + static std::false_type check3(...); + using type3 = decltype(check3(0)); + + template().open( + std::declval(), + std::declval(), + std::declval()), + std::true_type{})> + static R check4(int); + template + static std::false_type check4(...); + using type4 = decltype(check4(0)); + + template(), + std::declval()), + std::true_type{})> + static R check5(int); + template + static std::false_type check5(...); + using type5 = decltype(check5(0)); + + template().size( + std::declval())), + std::uint64_t>> + static R check6(int); + template + static std::false_type check6(...); + using type6 = decltype(check6(0)); + + template().read( + std::declval(), + std::declval(), + std::declval(), + std::declval()), + std::true_type{})> + static R check7(int); + template + static std::false_type check7(...); + using type7 = decltype(check7(0)); + + template().write( + std::declval(), + std::declval(), + std::declval(), + std::declval()), + std::true_type{})> + static R check8(int); + template + static std::false_type check8(...); + using type8 = decltype(check8(0)); + + template().sync( + std::declval()), + std::true_type{})> + static R check9(int); + template + static std::false_type check9(...); + using type9 = decltype(check9(0)); + + template().trunc( + std::declval(), + std::declval()), + std::true_type{})> + static R check10(int); + template + static std::false_type check10(...); + using type10 = decltype(check10(0)); + +public: + using type = std::integral_constant::value && + type1::value && type2::value && type3::value && + type4::value && type5::value && type6::value && + type7::value && type8::value && type9::value && + type10::value + >; +}; + +template +class check_is_Hasher +{ + template> + static R check1(int); + template + static std::false_type check1(...); + using type1 = decltype(check1(0)); + + template().operator()( + std::declval(), + std::declval())), + std::uint64_t>> + static R check2(int); + template + static std::false_type check2(...); + using type2 = decltype(check2(0)); +public: + using type = std::integral_constant; +}; + +template +class check_is_Progress +{ + template().operator()( + std::declval(), + std::declval()), + std::true_type{})> + static R check1(int); + template + static std::false_type check1(...); +public: + using type = decltype(check1(0)); +}; + +} // detail + +/// Determine if `T` meets the requirements of @b `File` +template +#if GENERATING_DOCS +struct is_File : std::integral_constant{}; +#else +using is_File = typename detail::check_is_File::type; +#endif + + +/// Determine if `T` meets the requirements of @b `Hasher` +template +#if GENERATING_DOCS +struct is_Hasher : std::integral_constant{}; +#else +using is_Hasher = typename detail::check_is_Hasher::type; +#endif + +/// Determine if `T` meets the requirements of @b `Progress` +template +#if GENERATING_DOCS +struct is_Progress : std::integral_constant{}; +#else +using is_Progress = typename detail::check_is_Progress::type; +#endif + +} // nudb + +#endif diff --git a/include/nudb/create.hpp b/include/nudb/create.hpp new file mode 100644 index 000000000..cb37ecbd9 --- /dev/null +++ b/include/nudb/create.hpp @@ -0,0 +1,117 @@ +// +// Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef NUDB_CREATE_HPP +#define NUDB_CREATE_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace nudb { + +/** Return a random salt. + + This function will use the system provided random + number device to generate a uniformly distributed + 64-bit unsigned value suitable for use the salt + value in a call to @ref create. +*/ +template +std::uint64_t +make_salt(); + +/** Create a new database. + + This function creates a set of new database files with + the given parameters. The files must not already exist or + else an error is returned. + + If an error occurs while the files are being created, + the function attempts to remove the files before + returning. + + @par Example + @code + error_code ec; + create( + "db.dat", "db.key", "db.log", + 1, make_salt(), 8, 4096, 0.5f, ec); + @endcode + + @par Template Parameters + + @tparam Hasher The hash function to use. This type must + meet the requirements of @b Hasher. The same hash + function must be used every time the database is opened, + or else an error is returned. The provided @ref xxhasher + is a suitable general purpose hash function. + + @tparam File The type of file to use. Use the default of + @ref native_file unless customizing the file behavior. + + @param dat_path The path to the data file. + + @param key_path The path to the key file. + + @param log_path The path to the log file. + + @param appnum A caller-defined value stored in the file + headers. When opening the database, the same value is + preserved and returned to the caller. + + @param salt A random unsigned integer used to permute + the hash function to make it unpredictable. The return + value of @ref make_salt returns a suitable value. + + @param key_size The number of bytes in each key. + + @param blockSize The size of a key file block. Larger + blocks hold more keys but require more I/O cycles per + operation. The ideal block size the largest size that + may be read in a single I/O cycle, and device dependent. + The return value of @ref block_size returns a suitable + value for the volume of a given path. + + @param load_factor A number between zero and one + representing the average bucket occupancy (number of + items). A value of 0.5 is perfect. Lower numbers + waste space, and higher numbers produce negligible + savings at the cost of increased I/O cycles. + + @param ec Set to the error, if any occurred. + + @param args Optional arguments passed to @b File constructors. +*/ +template< + class Hasher, + class File = native_file, + class... Args +> +void +create( + path_type const& dat_path, + path_type const& key_path, + path_type const& log_path, + std::uint64_t appnum, + std::uint64_t salt, + nsize_t key_size, + nsize_t blockSize, + float load_factor, + error_code& ec, + Args&&... args); + +} // nudb + +#include + +#endif diff --git a/include/nudb/detail/arena.hpp b/include/nudb/detail/arena.hpp new file mode 100644 index 000000000..e033140e7 --- /dev/null +++ b/include/nudb/detail/arena.hpp @@ -0,0 +1,296 @@ +// +// Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef NUDB_DETAIL_ARENA_HPP +#define NUDB_DETAIL_ARENA_HPP + +#include +#include +#include +#include +#include +#include +#include + +#if NUDB_DEBUG_ARENA +#include +#include +#endif + +namespace nudb { +namespace detail { + +/* Custom memory manager that allocates in large blocks. + + The implementation measures the rate of allocations in + bytes per second and tunes the large block size to fit + one second's worth of allocations. +*/ +template +class arena_t +{ + using clock_type = + std::chrono::steady_clock; + + using time_point = + typename clock_type::time_point; + + class element; + + char const* label_; // diagnostic + std::size_t alloc_ = 0; // block size + std::size_t used_ = 0; // bytes allocated + element* list_ = nullptr; // list of blocks + time_point when_ = clock_type::now(); + +public: + arena_t(arena_t const&) = delete; + arena_t& operator=(arena_t&&) = delete; + arena_t& operator=(arena_t const&) = delete; + + ~arena_t(); + + explicit + arena_t(char const* label = ""); + + arena_t(arena_t&& other); + + // Set the allocation size + void + hint(std::size_t alloc) + { + alloc_ = alloc; + } + + // Free all memory + void + clear(); + + void + periodic_activity(); + + std::uint8_t* + alloc(std::size_t n); + + template + friend + void + swap(arena_t& lhs, arena_t& rhs); +}; + +//------------------------------------------------------------------------------ + +template +class arena_t<_>::element +{ + std::size_t const capacity_; + std::size_t used_ = 0; + element* next_; + +public: + element(std::size_t capacity, element* next) + : capacity_(capacity) + , next_(next) + { + } + + element* + next() const + { + return next_; + } + + void + clear() + { + used_ = 0; + } + + std::size_t + remain() const + { + return capacity_ - used_; + } + + std::size_t + capacity() const + { + return capacity_; + } + + std::uint8_t* + alloc(std::size_t n); +}; + +template +std::uint8_t* +arena_t<_>::element:: +alloc(std::size_t n) +{ + if(n > capacity_ - used_) + return nullptr; + auto const p = const_cast( + reinterpret_cast(this + 1) + ) + used_; + used_ += n; + return p; +} + +//------------------------------------------------------------------------------ + +template +arena_t<_>:: +arena_t(char const* label) + : label_(label) +{ +} + +template +arena_t<_>:: +~arena_t() +{ + clear(); +} + +template +arena_t<_>:: +arena_t(arena_t&& other) + : label_(other.label_) + , alloc_(other.alloc_) + , used_(other.used_) + , list_(other.list_) + , when_(other.when_) +{ + other.used_ = 0; + other.list_ = nullptr; + other.when_ = clock_type::now(); + other.alloc_ = 0; +} + +template +void +arena_t<_>:: +clear() +{ + used_ = 0; + while(list_) + { + auto const e = list_; + list_ = list_->next(); + e->~element(); + delete[] reinterpret_cast(e); + } +} + +template +void +arena_t<_>:: +periodic_activity() +{ + using namespace std::chrono; + auto const now = clock_type::now(); + auto const elapsed = now - when_; + if(elapsed < milliseconds{500}) + return; + when_ = now; + auto const rate = static_cast(std::ceil( + used_ / duration_cast>(elapsed).count())); +#if NUDB_DEBUG_ARENA + beast::unit_test::dstream dout{std::cout}; + auto const size = + [](element* e) + { + std::size_t n = 0; + while(e) + { + ++n; + e = e->next(); + } + return n; + }; +#endif + if(rate >= alloc_ * 2) + { + // adjust up + alloc_ = std::max(rate, alloc_ * 2); + #if NUDB_DEBUG_ARENA + dout << label_ << ": " + "rate=" << rate << + ", alloc=" << alloc_ << " UP" + ", nused=" << used_ << + ", used=" << size(list_) << + "\n"; + #endif + } + else if(rate <= alloc_ / 2) + { + // adjust down + alloc_ /= 2; + #if NUDB_DEBUG_ARENA + dout << label_ << ": " + "rate=" << rate << + ", alloc=" << alloc_ << " DOWN" + ", nused=" << used_ << + ", used=" << size(list_) << + "\n"; + #endif + } + else + { + #if NUDB_DEBUG_ARENA + dout << label_ << ": " + "rate=" << rate << + ", alloc=" << alloc_ << + ", nused=" << used_ << + ", used=" << size(list_) << + "\n"; + #endif + } +} + +template +std::uint8_t* +arena_t<_>:: +alloc(std::size_t n) +{ + // Undefined behavior: Zero byte allocations + BOOST_ASSERT(n != 0); + n = 8 *((n + 7) / 8); + std::uint8_t* p; + if(list_) + { + p = list_->alloc(n); + if(p) + { + used_ += n; + return p; + } + } + auto const size = std::max(alloc_, n); + auto const e = reinterpret_cast( + new std::uint8_t[sizeof(element) + size]); + list_ = ::new(e) element{size, list_}; + used_ += n; + return list_->alloc(n); +} + +template +void +swap(arena_t<_>& lhs, arena_t<_>& rhs) +{ + using std::swap; + swap(lhs.used_, rhs.used_); + swap(lhs.list_, rhs.list_); + // don't swap alloc_ or when_ +} + +using arena = arena_t<>; + +} // detail +} // nudb + +#endif diff --git a/include/nudb/detail/bucket.hpp b/include/nudb/detail/bucket.hpp new file mode 100644 index 000000000..8a8efbf61 --- /dev/null +++ b/include/nudb/detail/bucket.hpp @@ -0,0 +1,473 @@ +// +// Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef NUDB_DETAIL_BUCKET_HPP +#define NUDB_DETAIL_BUCKET_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace nudb { +namespace detail { + +// Returns bucket index given hash, buckets, and modulus +// +inline +nbuck_t +bucket_index(nhash_t h, nbuck_t buckets, std::uint64_t modulus) +{ + BOOST_ASSERT(modulus <= 0x100000000ULL); + auto n = h % modulus; + if(n >= buckets) + n -= modulus / 2; + return static_cast(n); +} + +//------------------------------------------------------------------------------ + +// Tag for constructing empty buckets +struct empty_t +{ + constexpr empty_t() = default; +}; + +static empty_t constexpr empty{}; + +// Allows inspection and manipulation of bucket blobs in memory +template +class bucket_t +{ + nsize_t block_size_; // Size of a key file block + nkey_t size_; // Current key count + noff_t spill_; // Offset of next spill record or 0 + std::uint8_t* p_; // Pointer to the bucket blob + +public: + struct value_type + { + noff_t offset; + nhash_t hash; + nsize_t size; + }; + + bucket_t() = default; + bucket_t(bucket_t const&) = default; + bucket_t& operator=(bucket_t const&) = default; + + bucket_t(nsize_t block_size, void* p); + + bucket_t(nsize_t block_size, void* p, empty_t); + + nsize_t + block_size() const + { + return block_size_; + } + + // Serialized bucket size. + // Excludes empty + nsize_t + actual_size() const + { + return bucket_size(size_); + } + + bool + empty() const + { + return size_ == 0; + } + + bool + full() const + { + return size_ >= + detail::bucket_capacity(block_size_); + } + + nkey_t + size() const + { + return size_; + } + + // Returns offset of next spill record or 0 + // + noff_t + spill() const + { + return spill_; + } + + // Set offset of next spill record + // + void + spill(noff_t offset); + + // Clear contents of the bucket + // + void + clear(); + + // Returns the record for a key + // entry without bounds checking. + // + value_type const + at(nkey_t i) const; + + value_type const + operator[](nkey_t i) const + { + return at(i); + } + + // Returns index of entry with prefix + // equal to or greater than the given prefix. + // + nkey_t + lower_bound(nhash_t h) const; + + void + insert(noff_t offset, nsize_t size, nhash_t h); + + // Erase an element by index + // + void + erase(nkey_t i); + + // Read a full bucket from the + // file at the specified offset. + // + template + void + read(File& f, noff_t, error_code& ec); + + // Read a compact bucket + // + template + void + read(bulk_reader& r, error_code& ec); + + // Write a compact bucket to the stream. + // This only writes entries that are not empty. + // + void + write(ostream& os) const; + + // Write a bucket to the file at the specified offset. + // The full block_size() bytes are written. + // + template + void + write(File& f,noff_t offset, error_code& ec) const; + +private: + // Update size and spill in the blob + void + update(); +}; + +//------------------------------------------------------------------------------ + +template +bucket_t<_>:: +bucket_t(nsize_t block_size, void* p) + : block_size_(block_size) + , p_(reinterpret_cast(p)) +{ + // Bucket Record + istream is(p_, block_size); + detail::read(is, size_); // Count + detail::read(is, spill_); // Spill +} + +template +bucket_t<_>:: +bucket_t(nsize_t block_size, void* p, empty_t) + : block_size_(block_size) + , size_(0) + , spill_(0) + , p_(reinterpret_cast(p)) +{ + clear(); +} + +template +void +bucket_t<_>:: +spill(noff_t offset) +{ + spill_ = offset; + update(); +} + +template +void +bucket_t<_>::clear() +{ + size_ = 0; + spill_ = 0; + std::memset(p_, 0, block_size_); +} + +template +auto +bucket_t<_>:: +at(nkey_t i) const -> + value_type const +{ + value_type result; + // Bucket Entry + auto const w = + field::size + // Offset + field::size + // Size + field::size; // Prefix + // Bucket Record + detail::istream is{p_ + + field::size + // Count + field::size + // Spill + i * w, w}; + // Bucket Entry + detail::read( + is, result.offset); // Offset + detail::read_size48( + is, result.size); // Size + detail::read( + is, result.hash); // Hash + return result; +} + +template +nkey_t +bucket_t<_>:: +lower_bound(nhash_t h) const +{ + // Bucket Entry + auto const w = + field::size + // Offset + field::size + // Size + field::size; // Hash + // Bucket Record + auto const p = p_ + + field::size + // Count + field::size + // Spill + // Bucket Entry + field::size + // Offset + field::size; // Size + nkey_t step; + nkey_t first = 0; + nkey_t count = size_; + while(count > 0) + { + step = count / 2; + nkey_t i = first + step; + nhash_t h1; + readp(p + i * w, h1); + if(h1 < h) + { + first = i + 1; + count -= step + 1; + } + else + { + count = step; + } + } + return first; +} + +template +void +bucket_t<_>:: +insert( + noff_t offset, nsize_t size, nhash_t h) +{ + auto const i = lower_bound(h); + // Bucket Record + auto const p = p_ + + field< + std::uint16_t>::size + // Count + field::size; // Spill + // Bucket Entry + auto const w = + field::size + // Offset + field::size + // Size + field::size; // Hash + std::memmove( + p +(i + 1) * w, + p + i * w, + (size_ - i) * w); + ++size_; + update(); + // Bucket Entry + ostream os{p + i * w, w}; + detail::write( + os, offset); // Offset + detail::write( + os, size); // Size + detail::write( + os, h); // Prefix +} + +template +void +bucket_t<_>:: +erase(nkey_t i) +{ + // Bucket Record + auto const p = p_ + + field::size + // Count + field::size; // Spill + auto const w = + field::size + // Offset + field::size + // Size + field::size; // Hash + --size_; + if(i < size_) + std::memmove( + p + i * w, + p +(i + 1) * w, + (size_ - i) * w); + std::memset(p + size_ * w, 0, w); + update(); +} + +template +template +void +bucket_t<_>:: +read(File& f, noff_t offset, error_code& ec) +{ + auto const cap = bucket_capacity(block_size_); + // Excludes padding to block size + f.read(offset, p_, bucket_size(cap), ec); + if(ec) + return; + istream is{p_, block_size_}; + detail::read(is, size_); // Count + detail::read(is, spill_); // Spill + if(size_ > cap) + { + ec = error::invalid_bucket_size; + return; + } +} + +template +template +void +bucket_t<_>:: +read(bulk_reader& r, error_code& ec) +{ + // Bucket Record(compact) + auto is = r.prepare( + detail::field::size + + detail::field::size, ec); + if(ec) + return; + detail::read(is, size_); // Count + detail::read(is, spill_); // Spill + update(); + // Excludes empty bucket entries + auto const w = size_ * ( + field::size + // Offset + field::size + // Size + field::size); // Hash + is = r.prepare(w, ec); + if(ec) + return; + std::memcpy(p_ + + field::size + // Count + field::size, // Spill + is.data(w), w); // Entries +} + +template +void +bucket_t<_>:: +write(ostream& os) const +{ + // Does not pad up to the block size. This + // is called to write to the data file. + auto const size = actual_size(); + // Bucket Record + std::memcpy(os.data(size), p_, size); +} + +template +template +void +bucket_t<_>:: +write(File& f, noff_t offset, error_code& ec) const +{ + // Includes zero pad up to the block + // size, to make the key file size always + // a multiple of the block size. + auto const size = actual_size(); + std::memset(p_ + size, 0, block_size_ - size); + // Bucket Record + f.write(offset, p_, block_size_, ec); + if(ec) + return; +} + +template +void +bucket_t<_>:: +update() +{ + // Bucket Record + ostream os{p_, block_size_}; + detail::write(os, size_); // Count + detail::write(os, spill_); // Spill +} + +using bucket = bucket_t<>; + +//------------------------------------------------------------------------------ + +// Spill bucket if full. +// The bucket is cleared after it spills. +// +template +void +maybe_spill( + bucket& b, bulk_writer& w, error_code& ec) +{ + if(b.full()) + { + // Spill Record + auto const offset = w.offset(); + auto os = w.prepare( + field::size + // Zero + field::size + // Size + b.actual_size(), ec); + if(ec) + return; + write(os, 0ULL); // Zero + write( + os, b.actual_size()); // Size + auto const spill = + offset + os.size(); + b.write(os); // Bucket + // Update bucket + b.clear(); + b.spill(spill); + } +} + +} // detail +} // nudb + +#endif diff --git a/include/nudb/detail/buffer.hpp b/include/nudb/detail/buffer.hpp new file mode 100644 index 000000000..fc9f187ff --- /dev/null +++ b/include/nudb/detail/buffer.hpp @@ -0,0 +1,86 @@ +// +// Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef NUDB_DETAIL_BUFFER_HPP +#define NUDB_DETAIL_BUFFER_HPP + +#include +#include +#include + +namespace nudb { +namespace detail { + +// Simple growable memory buffer +class buffer +{ +private: + std::size_t size_ = 0; + std::unique_ptr buf_; + +public: + ~buffer() = default; + buffer() = default; + buffer(buffer const&) = delete; + buffer& operator=(buffer const&) = delete; + + explicit + buffer(std::size_t n) + : size_(n) + , buf_(new std::uint8_t[n]) + { + } + + buffer(buffer&& other) + : size_(other.size_) + , buf_(std::move(other.buf_)) + { + other.size_ = 0; + } + + buffer& + operator=(buffer&& other) + { + size_ = other.size_; + buf_ = std::move(other.buf_); + other.size_ = 0; + return *this; + } + + std::size_t + size() const + { + return size_; + } + + std::uint8_t* + get() const + { + return buf_.get(); + } + + void + reserve(std::size_t n) + { + if(size_ < n) + buf_.reset(new std::uint8_t[n]); + size_ = n; + } + + // BufferFactory + void* + operator()(std::size_t n) + { + reserve(n); + return buf_.get(); + } +}; + +} // detail +} // nudb + +#endif diff --git a/include/nudb/detail/bulkio.hpp b/include/nudb/detail/bulkio.hpp new file mode 100644 index 000000000..22e72073a --- /dev/null +++ b/include/nudb/detail/bulkio.hpp @@ -0,0 +1,196 @@ +// +// Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef NUDB_DETAIL_BULKIO_HPP +#define NUDB_DETAIL_BULKIO_HPP + +#include +#include +#include +#include +#include +#include + +namespace nudb { +namespace detail { + +// Scans a file in sequential large reads +template +class bulk_reader +{ + File& f_; + buffer buf_; + noff_t last_; // size of file + noff_t offset_; // current position + std::size_t avail_; // bytes left to read in buf + std::size_t used_; // bytes consumed in buf + +public: + bulk_reader(File& f, noff_t offset, + noff_t last, std::size_t buffer_size); + + noff_t + offset() const + { + return offset_ - avail_; + } + + bool + eof() const + { + return offset() >= last_; + } + + istream + prepare(std::size_t needed, error_code& ec); +}; + +template +bulk_reader:: +bulk_reader(File& f, noff_t offset, + noff_t last, std::size_t buffer_size) + : f_(f) + , last_(last) + , offset_(offset) + , avail_(0) + , used_(0) +{ + buf_.reserve(buffer_size); +} + +template +istream +bulk_reader:: +prepare(std::size_t needed, error_code& ec) +{ + if(needed > avail_) + { + if(offset_ + needed - avail_ > last_) + { + ec = error::short_read; + return {}; + } + if(needed > buf_.size()) + { + buffer buf; + buf.reserve(needed); + std::memcpy(buf.get(), + buf_.get() + used_, avail_); + buf_ = std::move(buf); + } + else + { + std::memmove(buf_.get(), + buf_.get() + used_, avail_); + } + + auto const n = std::min(buf_.size() - avail_, + static_cast(last_ - offset_)); + f_.read(offset_, buf_.get() + avail_, n, ec); + if(ec) + return {}; + offset_ += n; + avail_ += n; + used_ = 0; + } + istream is{buf_.get() + used_, needed}; + used_ += needed; + avail_ -= needed; + return is; +} + +//------------------------------------------------------------------------------ + +// Buffers file writes +// Caller must call flush manually at the end +template +class bulk_writer +{ + File& f_; + buffer buf_; + noff_t offset_; // current position + std::size_t used_; // bytes written to buf + +public: + bulk_writer(File& f, noff_t offset, + std::size_t buffer_size); + + ostream + prepare(std::size_t needed, error_code& ec); + + // Returns the number of bytes buffered + std::size_t + size() + { + return used_; + } + + // Return current offset in file. This + // is advanced with each call to prepare. + noff_t + offset() const + { + return offset_ + used_; + } + + // Caller must invoke flush manually in + // order to handle any error conditions. + void + flush(error_code& ec); +}; + +template +bulk_writer:: +bulk_writer(File& f, + noff_t offset, std::size_t buffer_size) + : f_(f) + , offset_(offset) + , used_(0) + +{ + buf_.reserve(buffer_size); +} + +template +ostream +bulk_writer:: +prepare(std::size_t needed, error_code& ec) +{ + if(used_ + needed > buf_.size()) + { + flush(ec); + if(ec) + return{}; + } + if(needed > buf_.size()) + buf_.reserve(needed); + ostream os(buf_.get() + used_, needed); + used_ += needed; + return os; +} + +template +void +bulk_writer:: +flush(error_code& ec) +{ + if(used_) + { + auto const offset = offset_; + auto const used = used_; + offset_ += used_; + used_ = 0; + f_.write(offset, buf_.get(), used, ec); + if(ec) + return; + } +} + +} // detail +} // nudb + +#endif diff --git a/include/nudb/detail/cache.hpp b/include/nudb/detail/cache.hpp new file mode 100644 index 000000000..0606ae423 --- /dev/null +++ b/include/nudb/detail/cache.hpp @@ -0,0 +1,236 @@ +// +// Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef NUDB_DETAIL_CACHE_HPP +#define NUDB_DETAIL_CACHE_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace nudb { +namespace detail { + +// Associative container storing +// bucket blobs keyed by bucket index. +// +template +class cache_t +{ +public: + using value_type = std::pair; + +private: + using map_type = + std::unordered_map; + + struct transform + { + using argument_type = + typename map_type::value_type; + using result_type = value_type; + + cache_t* cache_; + + transform() + : cache_(nullptr) + { + } + + explicit + transform(cache_t& cache) + : cache_(&cache) + { + } + + value_type + operator()(argument_type const& e) const + { + return std::make_pair(e.first, + bucket{cache_->block_size_, e.second}); + } + }; + + nsize_t key_size_ = 0; + nsize_t block_size_ = 0; + arena arena_; + map_type map_; + +public: + using iterator = boost::transform_iterator< + transform, typename map_type::iterator, + value_type, value_type>; + + cache_t(cache_t const&) = delete; + cache_t& operator=(cache_t&&) = delete; + cache_t& operator=(cache_t const&) = delete; + + // Constructs a cache that will never have inserts + cache_t() = default; + + cache_t(cache_t&& other); + + explicit + cache_t(nsize_t key_size, + nsize_t block_size, char const* label); + + std::size_t + size() const + { + return map_.size(); + } + + iterator + begin() + { + return iterator{map_.begin(), transform{*this}}; + } + + iterator + end() + { + return iterator{map_.end(), transform{*this}}; + } + + bool + empty() const + { + return map_.empty(); + } + + void + clear(); + + void + reserve(std::size_t n); + + void + periodic_activity(); + + iterator + find(nbuck_t n); + + // Create an empty bucket + // + bucket + create(nbuck_t n); + + // Insert a copy of a bucket. + // + iterator + insert(nbuck_t n, bucket const& b); + + template + friend + void + swap(cache_t& lhs, cache_t& rhs); +}; + +template +cache_t<_>:: +cache_t(cache_t&& other) + : key_size_{other.key_size_} + , block_size_(other.block_size_) + , arena_(std::move(other.arena_)) + , map_(std::move(other.map_)) +{ +} + +template +cache_t<_>:: +cache_t(nsize_t key_size, + nsize_t block_size, char const* label) + : key_size_(key_size) + , block_size_(block_size) + , arena_(label) +{ +} + +template +void +cache_t<_>:: +reserve(std::size_t n) +{ + arena_.hint(n * block_size_); + map_.reserve(n); +} + +template +void +cache_t<_>:: +clear() +{ + arena_.clear(); + map_.clear(); +} + +template +void +cache_t<_>:: +periodic_activity() +{ + arena_.periodic_activity(); +} + +template +auto +cache_t<_>:: +find(nbuck_t n) -> + iterator +{ + auto const iter = map_.find(n); + if(iter == map_.end()) + return iterator{map_.end(), transform(*this)}; + return iterator{iter, transform(*this)}; +} + +template +bucket +cache_t<_>:: +create(nbuck_t n) +{ + auto const p = arena_.alloc(block_size_); + map_.emplace(n, p); + return bucket{block_size_, p, detail::empty}; +} + +template +auto +cache_t<_>:: +insert(nbuck_t n, bucket const& b) -> + iterator +{ + void* const p = arena_.alloc(b.block_size()); + ostream os{p, b.block_size()}; + b.write(os); + auto const result = map_.emplace(n, p); + return iterator{result.first, transform(*this)}; +} + +template +void +swap(cache_t& lhs, cache_t& rhs) +{ + using std::swap; + swap(lhs.key_size_, rhs.key_size_); + swap(lhs.block_size_, rhs.block_size_); + swap(lhs.arena_, rhs.arena_); + swap(lhs.map_, rhs.map_); +} + +using cache = cache_t<>; + +} // detail +} // nudb + +#endif diff --git a/include/nudb/detail/endian.hpp b/include/nudb/detail/endian.hpp new file mode 100644 index 000000000..37c0e06c9 --- /dev/null +++ b/include/nudb/detail/endian.hpp @@ -0,0 +1,93 @@ +// +// Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef NUDB_DETAIL_ENDIAN_HPP +#define NUDB_DETAIL_ENDIAN_HPP + +#include +#include + +namespace nudb { +namespace detail { + +// This is a modified work, original implementation +// by Howard Hinnant +// +// "This should be standardized" - Howard + +// Endian provides answers to the following questions: +// 1. Is this system big or little endian? +// 2. Is the "desired endian" of some class or function the same as the +// native endian? +enum class endian +{ +#ifdef _MSC_VER + big = 1, + little = 0, + native = little +#else + native = __BYTE_ORDER__, + little = __ORDER_LITTLE_ENDIAN__, + big = __ORDER_BIG_ENDIAN__ +#endif +}; + +using is_little_endian = + std::integral_constant; + +static_assert( + endian::native == endian::little || endian::native == endian::big, + "endian::native shall be one of endian::little or endian::big"); + +static_assert( + endian::big != endian::little, + "endian::big and endian::little shall have different values"); + +// The pepper got baked into the file format as +// the hash of the little endian salt so now we +// need this function. +// +template +std::uint64_t +to_little_endian(std::uint64_t v, std::false_type) +{ + union U + { + std::uint64_t vi; + std::uint8_t va[8]; + }; + U u; + u.va[0] = v & 0xff; + u.va[1] = (v >> 8) & 0xff; + u.va[2] = (v >> 16) & 0xff; + u.va[3] = (v >> 24) & 0xff; + u.va[4] = (v >> 32) & 0xff; + u.va[5] = (v >> 40) & 0xff; + u.va[6] = (v >> 48) & 0xff; + u.va[7] = (v >> 56) & 0xff; + return u.vi; +} + +inline +std::uint64_t +to_little_endian(std::uint64_t v, std::true_type) +{ + return v; +} + +inline +std::uint64_t +to_little_endian(std::uint64_t v) +{ + return to_little_endian(v, is_little_endian{}); +} + +} // detail +} // nudb + +#endif diff --git a/include/nudb/detail/field.hpp b/include/nudb/detail/field.hpp new file mode 100644 index 000000000..e3101b128 --- /dev/null +++ b/include/nudb/detail/field.hpp @@ -0,0 +1,265 @@ +// +// Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef NUDB_FIELD_HPP +#define NUDB_FIELD_HPP + +#include +#include +#include +#include +#include +#include +#include + +namespace nudb { +namespace detail { + +// A 24-bit integer +struct uint24_t; + +// A 48-bit integer +struct uint48_t; + +// These metafunctions describe the binary format of fields on disk + +template +struct field; + +template<> +struct field +{ + static std::size_t constexpr size = 1; + static std::uint64_t constexpr max = 0xff; +}; + +template<> +struct field +{ + static std::size_t constexpr size = 2; + static std::uint64_t constexpr max = 0xffff; +}; + +template<> +struct field +{ + static std::size_t constexpr size = 3; + static std::uint64_t constexpr max = 0xffffff; +}; + +template<> +struct field +{ + static std::size_t constexpr size = 4; + static std::uint64_t constexpr max = 0xffffffff; +}; + +template<> +struct field +{ + static std::size_t constexpr size = 6; + static std::uint64_t constexpr max = 0x0000ffffffffffff; +}; + +template<> +struct field +{ + static std::size_t constexpr size = 8; + static std::uint64_t constexpr max = 0xffffffffffffffff; +}; + +// read field from memory + +template::value>::type* = nullptr> +void +readp(void const* v, U& u) +{ + auto p = reinterpret_cast(v); + u = *p; +} + +template::value>::type* = nullptr> +void +readp(void const* v, U& u) +{ + auto p = reinterpret_cast(v); + T t; + t = T(*p++)<< 8; + t = T(*p ) | t; + u = t; +} + +template::value>::type* = nullptr> +void +readp(void const* v, U& u) +{ + auto p = reinterpret_cast(v); + std::uint32_t t; + t = std::uint32_t(*p++)<<16; + t = (std::uint32_t(*p++)<< 8) | t; + t = std::uint32_t(*p ) | t; + u = t; +} + +template::value>::type* = nullptr> +void +readp(void const* v, U& u) +{ + auto const* p = reinterpret_cast(v); + T t; + t = T(*p++)<<24; + t = (T(*p++)<<16) | t; + t = (T(*p++)<< 8) | t; + t = T(*p ) | t; + u = t; +} + +template::value>::type* = nullptr> +void +readp(void const* v, U& u) +{ + auto p = reinterpret_cast(v); + std::uint64_t t; + t = (std::uint64_t(*p++)<<40); + t = (std::uint64_t(*p++)<<32) | t; + t = (std::uint64_t(*p++)<<24) | t; + t = (std::uint64_t(*p++)<<16) | t; + t = (std::uint64_t(*p++)<< 8) | t; + t = std::uint64_t(*p ) | t; + u = t; +} + +template::value>::type* = nullptr> +void +readp(void const* v, U& u) +{ + auto p = reinterpret_cast(v); + T t; + t = T(*p++)<<56; + t = (T(*p++)<<48) | t; + t = (T(*p++)<<40) | t; + t = (T(*p++)<<32) | t; + t = (T(*p++)<<24) | t; + t = (T(*p++)<<16) | t; + t = (T(*p++)<< 8) | t; + t = T(*p ) | t; + u = t; +} + +// read field from istream + +template +void +read(istream& is, U& u) +{ + readp(is.data(field::size), u); +} + +inline +void +read_size48(istream& is, std::size_t& u) +{ + std::uint64_t v; + read(is, v); + BOOST_ASSERT(v <= std::numeric_limits::max()); + u = static_cast(v); +} + +// write field to ostream + +template::value>::type* = nullptr> +void +write(ostream& os, U u) +{ + BOOST_ASSERT(u <= field::max); + std::uint8_t* p = os.data(field::size); + *p = static_cast(u); +} + +template::value>::type* = nullptr> +void +write(ostream& os, U u) +{ + BOOST_ASSERT(u <= field::max); + auto const t = static_cast(u); + std::uint8_t* p = os.data(field::size); + *p++ = (t>> 8)&0xff; + *p = t &0xff; +} + +template::value>::type* = nullptr> +void +write(ostream& os, U u) +{ + BOOST_ASSERT(u <= field::max); + auto const t = static_cast(u); + std::uint8_t* p = os.data(field::size); + *p++ = (t>>16)&0xff; + *p++ = (t>> 8)&0xff; + *p = t &0xff; +} + +template::value>::type* = nullptr> +void +write(ostream& os, U u) +{ + BOOST_ASSERT(u <= field::max); + auto const t = static_cast(u); + std::uint8_t* p = os.data(field::size); + *p++ = (t>>24)&0xff; + *p++ = (t>>16)&0xff; + *p++ = (t>> 8)&0xff; + *p = t &0xff; +} + +template::value>::type* = nullptr> +void +write(ostream& os, U u) +{ + BOOST_ASSERT(u <= field::max); + auto const t = static_cast(u); + std::uint8_t* p = os.data(field::size); + *p++ = (t>>40)&0xff; + *p++ = (t>>32)&0xff; + *p++ = (t>>24)&0xff; + *p++ = (t>>16)&0xff; + *p++ = (t>> 8)&0xff; + *p = t &0xff; +} + +template::value>::type* = nullptr> +void +write(ostream& os, U u) +{ + auto const t = static_cast(u); + std::uint8_t* p = os.data(field::size); + *p++ = (t>>56)&0xff; + *p++ = (t>>48)&0xff; + *p++ = (t>>40)&0xff; + *p++ = (t>>32)&0xff; + *p++ = (t>>24)&0xff; + *p++ = (t>>16)&0xff; + *p++ = (t>> 8)&0xff; + *p = t &0xff; +} + +} // detail +} // nudb + +#endif diff --git a/include/nudb/detail/format.hpp b/include/nudb/detail/format.hpp new file mode 100644 index 000000000..c6ea314e7 --- /dev/null +++ b/include/nudb/detail/format.hpp @@ -0,0 +1,629 @@ +// +// Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef NUDB_DETAIL_FORMAT_HPP +#define NUDB_DETAIL_FORMAT_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace nudb { +namespace detail { + +// Format of the nudb files: + +/* + +Integer sizes + +block_size less than 32 bits (maybe restrict it to 16 bits) +buckets more than 32 bits +capacity (same as bucket index) +file offsets 63 bits +hash up to 64 bits (48 currently) +item index less than 32 bits (index of item in bucket) +modulus (same as buckets) +value size up to 32 bits (or 32-bit builds can't read it) + +*/ + +static std::size_t constexpr currentVersion = 2; + +struct dat_file_header +{ + static std::size_t constexpr size = + 8 + // Type + 2 + // Version + 8 + // UID + 8 + // Appnum + 2 + // KeySize + + 64; // (Reserved) + + char type[8]; + std::size_t version; + std::uint64_t uid; + std::uint64_t appnum; + nsize_t key_size; +}; + +struct key_file_header +{ + static std::size_t constexpr size = + 8 + // Type + 2 + // Version + 8 + // UID + 8 + // Appnum + 2 + // KeySize + + 8 + // Salt + 8 + // Pepper + 2 + // BlockSize + 2 + // LoadFactor + + 56; // (Reserved) + + char type[8]; + std::size_t version; + std::uint64_t uid; + std::uint64_t appnum; + nsize_t key_size; + + std::uint64_t salt; + std::uint64_t pepper; + nsize_t block_size; + std::size_t load_factor; + + // Computed values + nkey_t capacity; // Entries per bucket + nbuck_t buckets; // Number of buckets + nbuck_t modulus; // pow(2,ceil(log2(buckets))) +}; + +struct log_file_header +{ + static std::size_t constexpr size = + 8 + // Type + 2 + // Version + 8 + // UID + 8 + // Appnum + 2 + // KeySize + + 8 + // Salt + 8 + // Pepper + 2 + // BlockSize + + 8 + // KeyFileSize + 8; // DataFileSize + + char type[8]; + std::size_t version; + std::uint64_t uid; + std::uint64_t appnum; + nsize_t key_size; + std::uint64_t salt; + std::uint64_t pepper; + nsize_t block_size; + noff_t key_file_size; + noff_t dat_file_size; +}; + +// Type used to store hashes in buckets. +// This can be smaller than the output +// of the hash function. +// +using f_hash = uint48_t; + +static_assert(field::size <= + sizeof(nhash_t), ""); + +template +nhash_t +make_hash(nhash_t h); + +template<> +inline +nhash_t +make_hash(nhash_t h) +{ + return(h>>16)&0xffffffffffff; +} + +// Returns the hash of a key given the salt. +// Note: The hash is expressed in f_hash units +// +template +inline +nhash_t +hash(void const* key, nsize_t key_size, std::uint64_t salt) +{ + Hasher h{salt}; + return make_hash(h(key, key_size)); +} + +template +inline +nhash_t +hash(void const* key, nsize_t key_size, Hasher const& h) +{ + return make_hash(h(key, key_size)); +} + +// Computes pepper from salt +// +template +std::uint64_t +pepper(std::uint64_t salt) +{ + auto const v = to_little_endian(salt); + Hasher h{salt}; + return h(&v, sizeof(v)); +} + +// Returns the actual size of a bucket. +// This can be smaller than the block size. +// +template +nsize_t +bucket_size(nkey_t capacity) +{ + // Bucket Record + return + field::size + // Count + field::size + // Spill + capacity * ( + field::size + // Offset + field::size + // Size + field::size); // Hash +} + +// Returns the number of entries that fit in a bucket +// +template +nkey_t +bucket_capacity(nsize_t block_size) +{ + // Bucket Record + auto const size = + field::size + // Count + field::size; // Spill + auto const entry_size = + field::size + // Offset + field::size + // Size + field::size; // Hash + if(block_size < key_file_header::size || + block_size < size) + return 0; + auto const n = + (block_size - size) / entry_size; + BOOST_ASSERT(n <= std::numeric_limits::max()); + return static_cast(std::min( + std::numeric_limits::max(), n)); +} + +// Returns the number of bytes occupied by a value record +// VFALCO TODO Fix this +inline +std::size_t +value_size(std::size_t size, + std::size_t key_size) +{ + // Data Record + return + field::size + // Size + key_size + // Key + size; // Data +} + +// Returns the closest power of 2 not less than x +template +T +ceil_pow2(T x) +{ + static const unsigned long long t[6] = { + 0xFFFFFFFF00000000ull, + 0x00000000FFFF0000ull, + 0x000000000000FF00ull, + 0x00000000000000F0ull, + 0x000000000000000Cull, + 0x0000000000000002ull + }; + + int y =(((x &(x - 1)) == 0) ? 0 : 1); + int j = 32; + int i; + + for(i = 0; i < 6; i++) { + int k =(((x & t[i]) == 0) ? 0 : j); + y += k; + x >>= k; + j >>= 1; + } + + return T{1}< +void +read(istream& is, dat_file_header& dh) +{ + read(is, dh.type, sizeof(dh.type)); + read(is, dh.version); + read(is, dh.uid); + read(is, dh.appnum); + read(is, dh.key_size); + std::array reserved; + read(is, reserved.data(), reserved.size()); +} + +// Read data file header from file +template +void +read(File& f, dat_file_header& dh, error_code& ec) +{ + std::array buf; + f.read(0, buf.data(), buf.size(), ec); + if(ec) + return; + istream is(buf); + read(is, dh); +} + +// Write data file header to stream +template +void +write(ostream& os, dat_file_header const& dh) +{ + write(os, "nudb.dat", 8); + write(os, dh.version); + write(os, dh.uid); + write(os, dh.appnum); + write(os, dh.key_size); + std::array reserved; + reserved.fill(0); + write(os, reserved.data(), reserved.size()); +} + +// Write data file header to file +template +void +write(File& f, dat_file_header const& dh, error_code& ec) +{ + std::array buf; + ostream os(buf); + write(os, dh); + f.write(0, buf.data(), buf.size(), ec); +} + +// Read key file header from stream +template +void +read(istream& is, noff_t file_size, key_file_header& kh) +{ + read(is, kh.type, sizeof(kh.type)); + read(is, kh.version); + read(is, kh.uid); + read(is, kh.appnum); + read(is, kh.key_size); + read(is, kh.salt); + read(is, kh.pepper); + read(is, kh.block_size); + read(is, kh.load_factor); + std::array reserved; + read(is, reserved.data(), reserved.size()); + + // VFALCO These need to be checked to handle + // when the file size is too small + kh.capacity = bucket_capacity(kh.block_size); + if(file_size > kh.block_size) + { + if(kh.block_size > 0) + kh.buckets = static_cast( + (file_size - kh.block_size) / kh.block_size); + else + // VFALCO Corruption or logic error + kh.buckets = 0; + } + else + { + kh.buckets = 0; + } + kh.modulus = ceil_pow2(kh.buckets); +} + +// Read key file header from file +template +void +read(File& f, key_file_header& kh, error_code& ec) +{ + std::array buf; + f.read(0, buf.data(), buf.size(), ec); + if(ec) + return; + istream is{buf}; + auto const size = f.size(ec); + if(ec) + return; + read(is, size, kh); +} + +// Write key file header to stream +template +void +write(ostream& os, key_file_header const& kh) +{ + write(os, "nudb.key", 8); + write(os, kh.version); + write(os, kh.uid); + write(os, kh.appnum); + write(os, kh.key_size); + write(os, kh.salt); + write(os, kh.pepper); + write(os, kh.block_size); + write(os, kh.load_factor); + std::array reserved; + reserved.fill(0); + write(os, reserved.data(), reserved.size()); +} + +// Write key file header to file +template +void +write(File& f, key_file_header const& kh, error_code& ec) +{ + buffer buf; + buf.reserve(kh.block_size); + if(kh.block_size < key_file_header::size) + { + ec = error::invalid_block_size; + return; + } + std::fill(buf.get(), buf.get() + buf.size(), 0); + ostream os{buf.get(), buf.size()}; + write(os, kh); + f.write(0, buf.get(), buf.size(), ec); +} + +// Read log file header from stream +template +void +read(istream& is, log_file_header& lh) +{ + read(is, lh.type, sizeof(lh.type)); + read(is, lh.version); + read(is, lh.uid); + read(is, lh.appnum); + read(is, lh.key_size); + read(is, lh.salt); + read(is, lh.pepper); + read(is, lh.block_size); + read(is, lh.key_file_size); + read(is, lh.dat_file_size); +} + +// Read log file header from file +template +void +read(File& f, log_file_header& lh, error_code& ec) +{ + std::array buf; + f.read(0, buf.data(), buf.size(), ec); + if(ec) + return; + istream is{buf}; + read(is, lh); +} + +// Write log file header to stream +template +void +write(ostream& os, log_file_header const& lh) +{ + write(os, "nudb.log", 8); + write(os, lh.version); + write(os, lh.uid); + write(os, lh.appnum); + write(os, lh.key_size); + write(os, lh.salt); + write(os, lh.pepper); + write(os, lh.block_size); + write(os, lh.key_file_size); + write(os, lh.dat_file_size); +} + +// Write log file header to file +template +void +write(File& f, log_file_header const& lh, error_code& ec) +{ + std::array buf; + ostream os{buf}; + write(os, lh); + f.write(0, buf.data(), buf.size(), ec); +} + +// Verify contents of data file header +template +void +verify(dat_file_header const& dh, error_code& ec) +{ + std::string const type{dh.type, 8}; + if(type != "nudb.dat") + { + ec = error::not_data_file; + return; + } + if(dh.version != currentVersion) + { + ec = error::different_version; + return; + } + if(dh.key_size < 1) + { + ec = error::invalid_key_size; + return; + } +} + +// Verify contents of key file header +template +void +verify(key_file_header const& kh, error_code& ec) +{ + std::string const type{kh.type, 8}; + if(type != "nudb.key") + { + ec = error::not_key_file; + return; + } + if(kh.version != currentVersion) + { + ec = error::different_version; + return; + } + if(kh.key_size < 1) + { + ec = error::invalid_key_size; + return; + } + if(kh.pepper != pepper(kh.salt)) + { + ec = error::hash_mismatch; + return; + } + if(kh.load_factor < 1) + { + ec = error::invalid_load_factor; + return; + } + if(kh.capacity < 1) + { + ec = error::invalid_capacity; + return; + } + if(kh.buckets < 1) + { + ec = error::invalid_bucket_count; + return; + } +} + +// Verify contents of log file header +template +void +verify(log_file_header const& lh, error_code& ec) +{ + std::string const type{lh.type, 8}; + if(type != "nudb.log") + { + ec = error::not_log_file; + return; + } + if(lh.version != currentVersion) + { + ec = error::different_version; + return; + } + if(lh.pepper != pepper(lh.salt)) + { + ec = error::hash_mismatch; + return; + } + if(lh.key_size < 1) + { + ec = error::invalid_key_size; + return; + } +} + +// Make sure key file and value file headers match +template +void +verify(dat_file_header const& dh, + key_file_header const& kh, error_code& ec) +{ + verify(kh, ec); + if(ec) + return; + if(kh.uid != dh.uid) + { + ec = error::uid_mismatch; + return; + } + if(kh.appnum != dh.appnum) + { + ec = error::appnum_mismatch; + return; + } + if(kh.key_size != dh.key_size) + { + ec = error::key_size_mismatch; + return; + } +} + +// Make sure key file and log file headers match +template +void +verify(key_file_header const& kh, + log_file_header const& lh, error_code& ec) +{ + verify(lh, ec); + if(ec) + return; + if(kh.uid != lh.uid) + { + ec = error::uid_mismatch; + return; + } + if(kh.appnum != lh.appnum) + { + ec = error::appnum_mismatch; + return; + } + if(kh.key_size != lh.key_size) + { + ec = error::key_size_mismatch; + return; + } + if(kh.salt != lh.salt) + { + ec = error::salt_mismatch; + return; + } + if(kh.pepper != lh.pepper) + { + ec = error::pepper_mismatch; + return; + } + if(kh.block_size != lh.block_size) + { + ec = error::block_size_mismatch; + return; + } +} + +} // detail +} // nudb + +#endif diff --git a/include/nudb/detail/gentex.hpp b/include/nudb/detail/gentex.hpp new file mode 100644 index 000000000..9adeeb6d9 --- /dev/null +++ b/include/nudb/detail/gentex.hpp @@ -0,0 +1,259 @@ +// +// Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef NUDB_DETAIL_GENTEX_HPP +#define NUDB_DETAIL_GENTEX_HPP + +#include +#include +#include +#include +#include + +namespace nudb { +namespace detail { + +// Generation counting mutex +// +template +class gentex_t +{ +private: + std::mutex m_; + std::size_t gen_ = 0; + std::size_t cur_ = 0; + std::size_t prev_ = 0; + std::condition_variable cond_; + +public: + gentex_t() = default; + gentex_t(gentex_t const&) = delete; + gentex_t& operator=(gentex_t const&) = delete; + + void + start(); + + void + finish(); + + std::size_t + lock_gen(); + + void + unlock_gen(std::size_t gen); +}; + +template +void +gentex_t<_>:: +start() +{ + std::unique_lock l{m_}; + prev_ += cur_; + cur_ = 0; + ++gen_; +} + +template +void +gentex_t<_>:: +finish() +{ + std::unique_lock l{m_}; + while(prev_ > 0) + cond_.wait(l); +} + +template +std::size_t +gentex_t<_>:: +lock_gen() +{ + std::lock_guard< + std::mutex> l{m_}; + ++cur_; + return gen_; +} + +template +void +gentex_t<_>:: +unlock_gen(std::size_t gen) +{ + std::unique_lock l{m_}; + if(gen == gen_) + { + --cur_; + } + else + { + --prev_; + if(prev_ == 0) + cond_.notify_all(); + } +} + +using gentex = gentex_t<>; + +//------------------------------------------------------------------------------ + +template +class genlock +{ +private: + bool owned_ = false; + GenerationLockable* g_ = nullptr; + std::size_t gen_; + +public: + using mutex_type = GenerationLockable; + + genlock() = default; + genlock(genlock const&) = delete; + genlock& operator=(genlock const&) = delete; + + genlock(genlock&& other); + + genlock& operator=(genlock&& other); + + explicit + genlock(mutex_type& g); + + genlock(mutex_type& g, std::defer_lock_t); + + ~genlock(); + + mutex_type* + mutex() noexcept + { + return g_; + } + + bool + owns_lock() const noexcept + { + return g_ && owned_; + } + + explicit + operator bool() const noexcept + { + return owns_lock(); + } + + void + lock(); + + void + unlock(); + + mutex_type* + release() noexcept; + + template + friend + void + swap(genlock& lhs, genlock& rhs) noexcept; +}; + +template +genlock:: +genlock(genlock&& other) + : owned_(other.owned_) + , g_(other.g_) +{ + other.owned_ = false; + other.g_ = nullptr; +} + +template +genlock& +genlock:: +operator=(genlock&& other) +{ + if(owns_lock()) + unlock(); + owned_ = other.owned_; + g_ = other.g_; + other.owned_ = false; + other.g_ = nullptr; + return *this; +} + +template +genlock:: +genlock(mutex_type& g) + : g_(&g) +{ + lock(); +} + +template +genlock:: +genlock(mutex_type& g, std::defer_lock_t) + : g_(&g) +{ +} + +template +genlock:: +~genlock() +{ + if(owns_lock()) + unlock(); +} + +template +void +genlock:: +lock() +{ + // no associated gentex + BOOST_ASSERT(g_ != nullptr); + // gentex is already owned + BOOST_ASSERT(! owned_); + gen_ = g_->lock_gen(); + owned_ = true; +} + +template +void +genlock:: +unlock() +{ + // no associated gentex + BOOST_ASSERT(g_ != nullptr); + // gentex is not owned + BOOST_ASSERT(owned_); + g_->unlock_gen(gen_); + owned_ = false; +} + +template +auto +genlock:: +release() noexcept -> + mutex_type* +{ + mutex_type* const g = g_; + g_ = nullptr; + return g; +} + +template +void +swap(genlock& lhs, genlock& rhs) noexcept +{ + using namespace std; + swap(lhs.owned_, rhs.owned_); + swap(lhs.g_, rhs.g_); +} + +} // detail +} // nudb + +#endif diff --git a/include/nudb/detail/mutex.hpp b/include/nudb/detail/mutex.hpp new file mode 100644 index 000000000..779e39fdc --- /dev/null +++ b/include/nudb/detail/mutex.hpp @@ -0,0 +1,26 @@ +// +// Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef NUDB_DETAIL_MUTEX_HPP +#define NUDB_DETAIL_MUTEX_HPP + +#include +#include + +namespace nudb { +namespace detail { + +using shared_lock_type = + boost::shared_lock; + +using unique_lock_type = + boost::unique_lock; + +} // detail +} // nudb + +#endif diff --git a/include/nudb/detail/pool.hpp b/include/nudb/detail/pool.hpp new file mode 100644 index 000000000..0b0a5daa9 --- /dev/null +++ b/include/nudb/detail/pool.hpp @@ -0,0 +1,243 @@ +// +// Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef NUDB_DETAIL_POOL_HPP +#define NUDB_DETAIL_POOL_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace nudb { +namespace detail { + +// Buffers key/value pairs in a map, associating +// them with a modifiable data file offset. +template +class pool_t +{ +public: + struct value_type; + class compare; + +private: + using map_type = std::map< + value_type, noff_t, compare>; + + arena arena_; + nsize_t key_size_; + nsize_t data_size_ = 0; + map_type map_; + +public: + using iterator = + typename map_type::iterator; + + pool_t(pool_t const&) = delete; + pool_t& operator=(pool_t const&) = delete; + + pool_t(pool_t&& other); + + pool_t(nsize_t key_size, char const* label); + + iterator + begin() + { + return map_.begin(); + } + + iterator + end() + { + return map_.end(); + } + + bool + empty() const + { + return map_.size() == 0; + } + + // Returns the number of elements in the pool + std::size_t + size() const + { + return map_.size(); + } + + // Returns the sum of data sizes in the pool + std::size_t + data_size() const + { + return data_size_; + } + + void + clear(); + + void + periodic_activity(); + + iterator + find(void const* key); + + // Insert a value + // @param h The hash of the key + void + insert(nhash_t h, void const* key, + void const* buffer, nsize_t size); + + template + friend + void + swap(pool_t& lhs, pool_t& rhs); +}; + +template +struct pool_t<_>::value_type +{ + nhash_t hash; + nsize_t size; + void const* key; + void const* data; + + value_type(value_type const&) = default; + value_type& operator=(value_type const&) = default; + + value_type(nhash_t hash_, nsize_t size_, + void const* key_, void const* data_) + : hash(hash_) + , size(size_) + , key(key_) + , data(data_) + { + } +}; + +template +class pool_t<_>::compare +{ + std::size_t key_size_; + +public: + using result_type = bool; + using first_argument_type = value_type; + using second_argument_type = value_type; + + compare(compare const&) = default; + compare& operator=(compare const&) = default; + + explicit + compare(nsize_t key_size) + : key_size_(key_size) + { + } + + bool + operator()(value_type const& lhs, + value_type const& rhs) const + { + return std::memcmp( + lhs.key, rhs.key, key_size_) < 0; + } +}; + +//------------------------------------------------------------------------------ + +template +pool_t<_>:: +pool_t(pool_t&& other) + : arena_(std::move(other.arena_)) + , key_size_(other.key_size_) + , data_size_(other.data_size_) + , map_(std::move(other.map_)) +{ +} + +template +pool_t<_>:: +pool_t(nsize_t key_size, char const* label) + : arena_(label) + , key_size_(key_size) + , map_(compare{key_size}) +{ +} + +template +void +pool_t<_>:: +clear() +{ + arena_.clear(); + data_size_ = 0; + map_.clear(); +} + +template +void +pool_t<_>:: +periodic_activity() +{ + arena_.periodic_activity(); +} + +template +auto +pool_t<_>:: +find(void const* key) -> + iterator +{ + // VFALCO need is_transparent here + value_type tmp{0, 0, key, nullptr}; + auto const iter = map_.find(tmp); + return iter; +} + +template +void +pool_t<_>:: +insert(nhash_t h, + void const* key, void const* data, nsize_t size) +{ + auto const k = arena_.alloc(key_size_); + auto const d = arena_.alloc(size); + std::memcpy(k, key, key_size_); + std::memcpy(d, data, size); + auto const result = map_.emplace( + std::piecewise_construct, + std::make_tuple(h, size, k, d), + std::make_tuple(0)); + (void)result.second; + // Must not already exist! + BOOST_ASSERT(result.second); + data_size_ += size; +} + +template +void +swap(pool_t<_>& lhs, pool_t<_>& rhs) +{ + using std::swap; + swap(lhs.arena_, rhs.arena_); + swap(lhs.key_size_, rhs.key_size_); + swap(lhs.data_size_, rhs.data_size_); + swap(lhs.map_, rhs.map_); +} + +using pool = pool_t<>; + +} // detail +} // nudb + +#endif diff --git a/include/nudb/detail/stream.hpp b/include/nudb/detail/stream.hpp new file mode 100644 index 000000000..6c07bf11b --- /dev/null +++ b/include/nudb/detail/stream.hpp @@ -0,0 +1,149 @@ +// +// Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef NUDB_DETAIL_STREAM_HPP +#define NUDB_DETAIL_STREAM_HPP + +#include +#include +#include +#include +#include +#include + +namespace nudb { +namespace detail { + +// Input stream from bytes +template +class istream_t +{ + std::uint8_t const* buf_ = nullptr; + std::size_t size_ = 0; + +public: + istream_t() = default; + istream_t(istream_t const&) = default; + istream_t& operator=(istream_t const&) = default; + + istream_t(void const* data, std::size_t size) + : buf_(reinterpret_cast(data)) + , size_(size) + { + } + + template + istream_t(std::array const& a) + : buf_(a.data()) + , size_(a.size()) + { + } + + std::uint8_t const* + data(std::size_t bytes); + + std::uint8_t const* + operator()(std::size_t bytes) + { + return data(bytes); + } +}; + +// Precondition: bytes <= size_ +// +template +std::uint8_t const* +istream_t<_>::data(std::size_t bytes) +{ + BOOST_ASSERT(bytes <= size_); + if(size_ < bytes) + throw std::logic_error("short read from istream"); + auto const data = buf_; + buf_ = buf_ + bytes; + size_ -= bytes; + return data; +} + +using istream = istream_t<>; + +//------------------------------------------------------------------------------ + +// Output stream to bytes +// VFALCO Should this assert on overwriting the buffer? +template +class ostream_t +{ + std::uint8_t* buf_ = nullptr; + std::size_t size_ = 0; + +public: + ostream_t() = default; + ostream_t(ostream_t const&) = default; + ostream_t& operator=(ostream_t const&) = default; + + ostream_t(void* data, std::size_t) + : buf_(reinterpret_cast(data)) + { + } + + template + ostream_t(std::array& a) + : buf_(a.data()) + { + } + + // Returns the number of bytes written + std::size_t + size() const + { + return size_; + } + + std::uint8_t* + data(std::size_t bytes); + + std::uint8_t* + operator()(std::size_t bytes) + { + return data(bytes); + } +}; + +template +std::uint8_t* +ostream_t<_>::data(std::size_t bytes) +{ + auto const data = buf_; + buf_ = buf_ + bytes; + size_ += bytes; + return data; +} + +using ostream = ostream_t<>; + +//------------------------------------------------------------------------------ + +// read blob +inline +void +read(istream& is, void* buffer, std::size_t bytes) +{ + std::memcpy(buffer, is.data(bytes), bytes); +} + +// write blob +inline +void +write(ostream& os, void const* buffer, std::size_t bytes) +{ + std::memcpy(os.data(bytes), buffer, bytes); +} + +} // detail +} // nudb + +#endif diff --git a/include/nudb/detail/xxhash.hpp b/include/nudb/detail/xxhash.hpp new file mode 100644 index 000000000..648b2cf84 --- /dev/null +++ b/include/nudb/detail/xxhash.hpp @@ -0,0 +1,328 @@ +// +// Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// +// This is a derivative work based on xxHash 0.6.2, copyright below: +/* + xxHash - Extremely Fast Hash algorithm + Header File + Copyright (C) 2012-2016, Yann Collet. + + BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following disclaimer + in the documentation and/or other materials provided with the + distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + You can contact the author at : + - xxHash source repository : https://github.com/Cyan4973/xxHash +*/ + +#ifndef NUDB_DETAIL_XXHASH_HPP +#define NUDB_DETAIL_XXHASH_HPP + +#include +#include +#include +#include + +namespace nudb { +namespace detail { + +#define NUDB_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) + +// minGW _rotl gives poor performance +#if defined(_MSC_VER) +# define NUDB_XXH_rotl64(x,r) _rotl64(x,r) +#else +# define NUDB_XXH_rotl64(x,r) ((x << r) | (x >> (64 - r))) +#endif + +#if defined(_MSC_VER) +# define NUDB_XXH_swap32 _byteswap_ulong +#elif NUDB_GCC_VERSION >= 403 +# define NUDB_XXH_swap32 __builtin_bswap32 +#endif + +#if defined(_MSC_VER) +# define NUDB_XXH_swap64 _byteswap_uint64 +#elif NUDB_GCC_VERSION >= 403 +# define NUDB_XXH_swap64 __builtin_bswap64 +#endif + +#ifndef NUDB_XXH_swap32 +inline +std::uint32_t +NUDB_XXH_swap32(std::uint32_t x) +{ + return ((x << 24) & 0xff000000 ) | + ((x << 8) & 0x00ff0000 ) | + ((x >> 8) & 0x0000ff00 ) | + ((x >> 24) & 0x000000ff ); +} +#endif + +#ifndef NUDB_XXH_swap64 +inline +std::uint64_t +NUDB_XXH_swap64(std::uint64_t x) +{ + return ((x << 56) & 0xff00000000000000ULL) | + ((x << 40) & 0x00ff000000000000ULL) | + ((x << 24) & 0x0000ff0000000000ULL) | + ((x << 8) & 0x000000ff00000000ULL) | + ((x >> 8) & 0x00000000ff000000ULL) | + ((x >> 24) & 0x0000000000ff0000ULL) | + ((x >> 40) & 0x000000000000ff00ULL) | + ((x >> 56) & 0x00000000000000ffULL); +} +#endif + +static std::uint64_t constexpr prime64_1 = 11400714785074694791ULL; +static std::uint64_t constexpr prime64_2 = 14029467366897019727ULL; +static std::uint64_t constexpr prime64_3 = 1609587929392839161ULL; +static std::uint64_t constexpr prime64_4 = 9650029242287828579ULL; +static std::uint64_t constexpr prime64_5 = 2870177450012600261ULL; + +// Portable and safe solution. Generally efficient. +// see : http://stackoverflow.com/a/32095106/646947 + +inline +std::uint32_t +XXH_read32(void const* p) +{ + std::uint32_t v; + memcpy(&v, p, sizeof(v)); + return v; +} + +inline +std::uint64_t +XXH_read64(void const* p) +{ + std::uint64_t v; + memcpy(&v, p, sizeof(v)); + return v; +} + +// little endian, aligned +inline +std::uint32_t +XXH_readLE32_align(void const* p, std::true_type, std::true_type) +{ + return *reinterpret_cast(p); +} + +// little endian, unaligned +inline +std::uint32_t +XXH_readLE32_align(void const* p, std::true_type, std::false_type) +{ + return XXH_read32(p); +} + +// big endian, aligned +inline +std::uint32_t +XXH_readLE32_align(void const* p, std::false_type, std::true_type) +{ + return NUDB_XXH_swap32( + *reinterpret_cast(p)); +} + +// big endian, unaligned +inline +std::uint32_t +XXH_readLE32_align(void const* p, std::false_type, std::false_type) +{ + return NUDB_XXH_swap32(XXH_read32(p)); +} + +// little endian, aligned +inline +std::uint64_t +XXH_readLE64_align(void const* p, std::true_type, std::true_type) +{ + return *reinterpret_cast(p); +} + +// little endian, unaligned +inline +std::uint64_t +XXH_readLE64_align(void const* p, std::true_type, std::false_type) +{ + return XXH_read64(p); +} + +// big endian, aligned +inline +std::uint64_t +XXH_readLE64_align(void const* p, std::false_type, std::true_type) +{ + return NUDB_XXH_swap64( + *reinterpret_cast(p)); +} + +// big endian, unaligned +inline +std::uint64_t +XXH_readLE64_align(void const* p, std::false_type, std::false_type) +{ + return NUDB_XXH_swap64(XXH_read64(p)); +} + +inline +std::uint64_t +XXH64_round(std::uint64_t acc, std::uint64_t input) +{ + acc += input * prime64_2; + acc = NUDB_XXH_rotl64(acc, 31); + acc *= prime64_1; + return acc; +} + +inline +std::uint64_t +XXH64_mergeRound(std::uint64_t acc, std::uint64_t val) +{ + val = XXH64_round(0, val); + acc ^= val; + acc = acc * prime64_1 + prime64_4; + return acc; +} + +template +std::uint64_t +XXH64_endian_align( + void const* input, std::size_t len, std::uint64_t seed, + std::integral_constant endian, + std::integral_constant align) +{ + const std::uint8_t* p = (const std::uint8_t*)input; + const std::uint8_t* const bEnd = p + len; + std::uint64_t h64; + auto const XXH_get32bits = + [](void const* p) + { + return XXH_readLE32_align(p, + decltype(endian){}, decltype(align){}); + }; + auto const XXH_get64bits = + [](void const* p) + { + return XXH_readLE64_align(p, + decltype(endian){}, decltype(align){}); + }; + if(len>=32) + { + const std::uint8_t* const limit = bEnd - 32; + std::uint64_t v1 = seed + prime64_1 + prime64_2; + std::uint64_t v2 = seed + prime64_2; + std::uint64_t v3 = seed + 0; + std::uint64_t v4 = seed - prime64_1; + + do + { + v1 = XXH64_round(v1, XXH_get64bits(p)); p+=8; + v2 = XXH64_round(v2, XXH_get64bits(p)); p+=8; + v3 = XXH64_round(v3, XXH_get64bits(p)); p+=8; + v4 = XXH64_round(v4, XXH_get64bits(p)); p+=8; + } + while(p<=limit); + + h64 = NUDB_XXH_rotl64(v1, 1) + + NUDB_XXH_rotl64(v2, 7) + + NUDB_XXH_rotl64(v3, 12) + + NUDB_XXH_rotl64(v4, 18); + h64 = XXH64_mergeRound(h64, v1); + h64 = XXH64_mergeRound(h64, v2); + h64 = XXH64_mergeRound(h64, v3); + h64 = XXH64_mergeRound(h64, v4); + } + else + { + h64 = seed + prime64_5; + } + h64 += len; + while(p + 8 <= bEnd) + { + std::uint64_t const k1 = XXH64_round(0, XXH_get64bits(p)); + h64 ^= k1; + h64 = NUDB_XXH_rotl64(h64,27) * prime64_1 + prime64_4; + p+=8; + } + if(p+4<=bEnd) + { + h64 ^= (std::uint64_t)(XXH_get32bits(p)) * prime64_1; + h64 = NUDB_XXH_rotl64(h64, 23) * prime64_2 + prime64_3; + p+=4; + } + while(p> 33; + h64 *= prime64_2; + h64 ^= h64 >> 29; + h64 *= prime64_3; + h64 ^= h64 >> 32; + return h64; +} + +/* Calculate the 64-bit hash of a block of memory. + + @param data A pointer to the buffer to compute the hash on. + The buffer may be unaligned. + + @note This function runs faster on 64-bits systems, but slower + on 32-bits systems (see benchmark). + + @param bytes The size of the buffer in bytes. + + @param seed A value which may be used to permute the output. + Using a different seed with the same input will produce a + different value. + + @return The 64-bit hash of the input data. +*/ +template +std::uint64_t +XXH64(void const* data, size_t bytes, std::uint64_t seed) +{ + // Use faster algorithm if aligned + if((reinterpret_cast(data) & 7) == 0) + return XXH64_endian_align(data, bytes, seed, + is_little_endian{}, std::false_type{}); + return XXH64_endian_align(data, bytes, seed, + is_little_endian{}, std::true_type{}); +} + +} // detail +} // nudb + +#endif + diff --git a/include/nudb/error.hpp b/include/nudb/error.hpp new file mode 100644 index 000000000..082ff41f5 --- /dev/null +++ b/include/nudb/error.hpp @@ -0,0 +1,263 @@ +// +// Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef NUDB_ERROR_HPP +#define NUDB_ERROR_HPP + +#include +#include + +namespace nudb { + +/// The type of system-specific error code returned by the implementation +#if GENERATING_DOCS +class error_code{}; + +#else +using boost::system::error_code; + +#endif + +/// The type of cross-platform error code used by the implementation +#if GENERATING_DOCS +class error_condition{}; + +#else +using boost::system::error_condition; + +#endif + +/// The type of system-specific exception used when throwing +#if GENERATING_DOCS +class system_error{}; + +#else +using boost::system::system_error; + +#endif + +/// Returns the category used for system-specific error codes +#if GENERATING_DOCS +error_category const& +system_category(); + +#else +using boost::system::system_category; + +#endif + +/// Returns the category used for cross-platform error codes +#if GENERATING_DOCS +error_category const& +generic_category(); + +#else +using boost::system::generic_category; + +#endif + +/// The base class used for error categories +#if GENERATING_DOCS +class error_category{}; + +#else +using boost::system::error_category; + +#endif + +/// The set of constants used for cross-platform error codes +#if GENERATING_DOCS +enum errc{}; + +#else +namespace errc = boost::system::errc; + +#endif + +/// Database error codes. +enum class error +{ + /** No error. + + The operation completed successfully. + */ + success = 0, + + /** The specified key was not found. + + Returned when @ref basic_store::fetch does not + find the specified key. + */ + key_not_found, + + /** The specified key already exists. + + Returned when @ref basic_store::insert finds + the specified key already in the database. + */ + key_exists, + + /** A file read returned less data than expected. + + This can be caused by premature application + termination during a commit cycle. + */ + short_read, + + /** A log file is present. + + Indicates that the database needs to have the + associated log file applied to perform a recovery. + This error is returned by functions such as @ref rekey. + */ + log_file_exists, + + /** No key file exists. + + This error is returned by the recover process when + there is no valid key file. It happens when a + @ref rekey operation prematurely terminates. A + database without a key file cannot be opened. To + fix this error, it is necessary for an invocation of + @ref rekey to complete successfully. + */ + no_key_file, + + /// Too many buckets in key file + too_many_buckets, + + /// Not a data file + not_data_file, + + /// Not a key file + not_key_file, + + /// Not a log file + not_log_file, + + /// Different version + different_version, + + /// Invalid key size + invalid_key_size, + + /// Invalid block size + invalid_block_size, + + /// Short key file + short_key_file, + + /// Short bucket + short_bucket, + + /// Short spill + short_spill, + + /// Short record + short_data_record, + + /// Short value + short_value, + + /// Hash mismatch + hash_mismatch, + + /// Invalid load factor + invalid_load_factor, + + /// Invalid capacity + invalid_capacity, + + /// Invalid bucket count + invalid_bucket_count, + + /// Invalid bucket size + invalid_bucket_size, + + /// The data file header was incomplete + incomplete_data_file_header, + + /// The key file header was incomplete + incomplete_key_file_header, + + /// Invalid log record + invalid_log_record, + + /// Invalid spill in log record + invalid_log_spill, + + /// Invalid offset in log record + invalid_log_offset, + + /// Invalid index in log record + invalid_log_index, + + /// Invalid size in spill + invalid_spill_size, + + /// UID mismatch + uid_mismatch, + + /// appnum mismatch + appnum_mismatch, + + /// key size mismatch + key_size_mismatch, + + /// salt mismatch + salt_mismatch, + + /// pepper mismatch + pepper_mismatch, + + /// block size mismatch + block_size_mismatch, + + /// orphaned value + orphaned_value, + + /// missing value + missing_value, + + /// size mismatch + size_mismatch, + + /// duplicate value + duplicate_value +}; + +/// Returns the error category used for database error codes. +error_category const& +nudb_category(); + +/** Returns a database error code. + + This function is used by the implementation to convert + @ref error values into @ref error_code objects. +*/ +inline +error_code +make_error_code(error ev) +{ + return error_code{static_cast(ev), nudb_category()}; +} + +} // nudb + +namespace boost { +namespace system { +template<> +struct is_error_code_enum +{ + static bool const value = true; +}; +} // system +} // boost + +#include + +#endif diff --git a/include/nudb/file.hpp b/include/nudb/file.hpp new file mode 100644 index 000000000..409aa1981 --- /dev/null +++ b/include/nudb/file.hpp @@ -0,0 +1,53 @@ +// +// Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef NUDB_FILE_HPP +#define NUDB_FILE_HPP + +#include +#include + +namespace nudb { + +/// The type used to hold paths to files +using path_type = std::string; + +/** Returns the best guess at the volume's block size. + + @param path A path to a file on the device. The file does + not need to exist. +*/ +inline +std::size_t +block_size(path_type const& path) +{ + // A reasonable default for many SSD devices + return 4096; +} + +/** File create and open modes. + + These are used by @ref native_file. +*/ +enum class file_mode +{ + /// Open the file for sequential reads + scan, + + /// Open the file for random reads + read, + + /// Open the file for random reads and appending writes + append, + + /// Open the file for random reads and writes + write +}; + +} // nudb + +#endif diff --git a/include/nudb/impl/basic_store.ipp b/include/nudb/impl/basic_store.ipp new file mode 100644 index 000000000..404a4e309 --- /dev/null +++ b/include/nudb/impl/basic_store.ipp @@ -0,0 +1,793 @@ +// +// Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef NUDB_IMPL_BASIC_STORE_IPP +#define NUDB_IMPL_BASIC_STORE_IPP + +#include +#include +#include +#include +#include + +#ifndef NUDB_DEBUG_LOG +#define NUDB_DEBUG_LOG 0 +#endif +#if NUDB_DEBUG_LOG +#include +#include +#endif + +namespace nudb { + +template +basic_store::state:: +state(File&& df_, File&& kf_, File&& lf_, + path_type const& dp_, path_type const& kp_, + path_type const& lp_, + detail::key_file_header const& kh_) + : df(std::move(df_)) + , kf(std::move(kf_)) + , lf(std::move(lf_)) + , dp(dp_) + , kp(kp_) + , lp(lp_) + , hasher(kh_.salt) + , p0(kh_.key_size, "p0") + , p1(kh_.key_size, "p1") + , c1(kh_.key_size, kh_.block_size, "c1") + , kh(kh_) +{ + static_assert(is_File::value, + "File requirements not met"); +} + +//------------------------------------------------------------------------------ + +template +basic_store:: +~basic_store() +{ + error_code ec; + // We call close here to make sure data is intact + // if an exception destroys the basic_store, but callers + // should always call close manually to receive the + // error code. + close(ec); +} + +template +path_type const& +basic_store:: +dat_path() const +{ + BOOST_ASSERT(is_open()); + return s_->dp; +} + +template +path_type const& +basic_store:: +key_path() const +{ + BOOST_ASSERT(is_open()); + return s_->kp; +} + +template +path_type const& +basic_store:: +log_path() const +{ + BOOST_ASSERT(is_open()); + return s_->lp; +} + +template +std::uint64_t +basic_store:: +appnum() const +{ + BOOST_ASSERT(is_open()); + return s_->kh.appnum; +} + +template +std::size_t +basic_store:: +key_size() const +{ + BOOST_ASSERT(is_open()); + return s_->kh.key_size; +} + +template +std::size_t +basic_store:: +block_size() const +{ + BOOST_ASSERT(is_open()); + return s_->kh.block_size; +} + +template +template +void +basic_store:: +open( + path_type const& dat_path, + path_type const& key_path, + path_type const& log_path, + error_code& ec, + Args&&... args) +{ + static_assert(is_Hasher::value, + "Hasher requirements not met"); + using namespace detail; + BOOST_ASSERT(! is_open()); + ec_ = {}; + ecb_.store(false); + recover( + dat_path, key_path, log_path, ec, args...); + if(ec) + return; + File df(args...); + File kf(args...); + File lf(args...); + df.open(file_mode::append, dat_path, ec); + if(ec) + return; + kf.open(file_mode::write, key_path, ec); + if(ec) + return; + lf.create(file_mode::append, log_path, ec); + if(ec) + return; + // VFALCO TODO Erase empty log file if this + // function subsequently fails. + dat_file_header dh; + read(df, dh, ec); + if(ec) + return; + verify(dh, ec); + if(ec) + return; + key_file_header kh; + read(kf, kh, ec); + if(ec) + return; + verify(kh, ec); + if(ec) + return; + verify(dh, kh, ec); + if(ec) + return; + boost::optional s; + s.emplace(std::move(df), std::move(kf), std::move(lf), + dat_path, key_path, log_path, kh); + thresh_ = std::max(65536UL, + kh.load_factor * kh.capacity); + frac_ = thresh_ / 2; + buckets_ = kh.buckets; + modulus_ = ceil_pow2(kh.buckets); + // VFALCO TODO This could be better + if(buckets_ < 1) + { + ec = error::short_key_file; + return; + } + dataWriteSize_ = 32 * nudb::block_size(dat_path); + logWriteSize_ = 32 * nudb::block_size(log_path); + s_.emplace(std::move(*s)); + open_ = true; + t_ = std::thread(&basic_store::run, this); +} + +template +void +basic_store:: +close(error_code& ec) +{ + if(open_) + { + open_ = false; + cv_.notify_all(); + t_.join(); + if(ecb_) + { + ec = ec_; + return; + } + s_->lf.close(); + state s{std::move(*s_)}; + File::erase(s.lp, ec_); + if(ec_) + ec = ec_; + } +} + +template +template +void +basic_store:: +fetch( + void const* key, + Callback && callback, + error_code& ec) +{ + using namespace detail; + BOOST_ASSERT(is_open()); + if(ecb_) + { + ec = ec_; + return; + } + auto const h = + hash(key, s_->kh.key_size, s_->hasher); + shared_lock_type m{m_}; + { + auto iter = s_->p1.find(key); + if(iter == s_->p1.end()) + { + iter = s_->p0.find(key); + if(iter == s_->p0.end()) + goto cont; + } + callback(iter->first.data, iter->first.size); + return; + } +cont: + auto const n = bucket_index(h, buckets_, modulus_); + auto const iter = s_->c1.find(n); + if(iter != s_->c1.end()) + return fetch(h, key, iter->second, callback, ec); + genlock g{g_}; + m.unlock(); + buffer buf{s_->kh.block_size}; + // b constructs from uninitialized buf + bucket b{s_->kh.block_size, buf.get()}; + b.read(s_->kf, (n + 1) * b.block_size(), ec); + if(ec) + return; + fetch(h, key, b, callback, ec); +} + +template +void +basic_store:: +insert( + void const* key, + void const* data, + nsize_t size, + error_code& ec) +{ + using namespace detail; + using namespace std::chrono; + BOOST_ASSERT(is_open()); + if(ecb_) + { + ec = ec_; + return; + } + // Data Record + BOOST_ASSERT(size > 0); // zero disallowed + BOOST_ASSERT(size <= field::max); // too large + auto const h = + hash(key, s_->kh.key_size, s_->hasher); + std::lock_guard u{u_}; + { + shared_lock_type m{m_}; + if(s_->p1.find(key) != s_->p1.end() || + s_->p0.find(key) != s_->p0.end()) + { + ec = error::key_exists; + return; + } + auto const n = bucket_index(h, buckets_, modulus_); + auto const iter = s_->c1.find(n); + if(iter != s_->c1.end()) + { + auto const found = exists( + h, key, &m, iter->second, ec); + if(ec) + return; + if(found) + { + ec = error::key_exists; + return; + } + // m is now unlocked + } + else + { + // VFALCO Audit for concurrency + genlock g{g_}; + m.unlock(); + buffer buf; + buf.reserve(s_->kh.block_size); + bucket b{s_->kh.block_size, buf.get()}; + b.read(s_->kf, + static_cast(n + 1) * s_->kh.block_size, ec); + if(ec) + return; + auto const found = exists(h, key, nullptr, b, ec); + if(ec) + return; + if(found) + { + ec = error::key_exists; + return; + } + } + } + // Perform insert + unique_lock_type m{m_}; + s_->p1.insert(h, key, data, size); + auto const now = clock_type::now(); + auto const elapsed = duration_cast>( + now > s_->when ? now - s_->when : clock_type::duration{1}); + auto const work = s_->p1.data_size() + + 3 * s_->p1.size() * s_->kh.block_size; + auto const rate = static_cast( + std::ceil(work / elapsed.count())); + auto const sleep = + s_->rate && rate > s_->rate; + m.unlock(); + if(sleep) + std::this_thread::sleep_for(milliseconds{25}); +} + +// Fetch key in loaded bucket b or its spills. +// +template +template +void +basic_store:: +fetch( + detail::nhash_t h, + void const* key, + detail::bucket b, + Callback&& callback, + error_code& ec) +{ + using namespace detail; + buffer buf0; + buffer buf1; + for(;;) + { + for(auto i = b.lower_bound(h); i < b.size(); ++i) + { + auto const item = b[i]; + if(item.hash != h) + break; + // Data Record + auto const len = + s_->kh.key_size + // Key + item.size; // Value + buf0.reserve(len); + s_->df.read(item.offset + + field::size, // Size + buf0.get(), len, ec); + if(ec) + return; + if(std::memcmp(buf0.get(), key, + s_->kh.key_size) == 0) + { + callback( + buf0.get() + s_->kh.key_size, item.size); + return; + } + } + auto const spill = b.spill(); + if(! spill) + break; + buf1.reserve(s_->kh.block_size); + b = bucket(s_->kh.block_size, + buf1.get()); + b.read(s_->df, spill, ec); + if(ec) + return; + } + ec = error::key_not_found; +} + +// Returns `true` if the key exists +// lock is unlocked after the first bucket processed +// +template +bool +basic_store:: +exists( + detail::nhash_t h, + void const* key, + detail::shared_lock_type* lock, + detail::bucket b, + error_code& ec) +{ + using namespace detail; + buffer buf{s_->kh.key_size + s_->kh.block_size}; + void* pk = buf.get(); + void* pb = buf.get() + s_->kh.key_size; + for(;;) + { + for(auto i = b.lower_bound(h); i < b.size(); ++i) + { + auto const item = b[i]; + if(item.hash != h) + break; + // Data Record + s_->df.read(item.offset + + field::size, // Size + pk, s_->kh.key_size, ec); // Key + if(ec) + return false; + if(std::memcmp(pk, key, s_->kh.key_size) == 0) + return true; + } + auto spill = b.spill(); + if(lock && lock->owns_lock()) + lock->unlock(); + if(! spill) + break; + b = bucket(s_->kh.block_size, pb); + b.read(s_->df, spill, ec); + if(ec) + return false; + } + return false; +} + +// Split the bucket in b1 to b2 +// b1 must be loaded +// tmp is used as a temporary buffer +// splits are written but not the new buckets +// +template +void +basic_store:: +split( + detail::bucket& b1, + detail::bucket& b2, + detail::bucket& tmp, + nbuck_t n1, + nbuck_t n2, + nbuck_t buckets, + nbuck_t modulus, + detail::bulk_writer& w, + error_code& ec) +{ + using namespace detail; + // Trivial case: split empty bucket + if(b1.empty()) + return; + // Split + for(std::size_t i = 0; i < b1.size();) + { + auto const e = b1[i]; + auto const n = bucket_index(e.hash, buckets, modulus); + (void)n1; + (void)n2; + BOOST_ASSERT(n==n1 || n==n2); + if(n == n2) + { + b2.insert(e.offset, e.size, e.hash); + b1.erase(i); + } + else + { + ++i; + } + } + noff_t spill = b1.spill(); + if(spill) + { + b1.spill(0); + do + { + // If any part of the spill record is + // in the write buffer then flush first + if(spill + bucket_size(s_->kh.capacity) > + w.offset() - w.size()) + { + w.flush(ec); + if(ec) + return; + } + tmp.read(s_->df, spill, ec); + if(ec) + return; + for(std::size_t i = 0; i < tmp.size(); ++i) + { + auto const e = tmp[i]; + auto const n = bucket_index( + e.hash, buckets, modulus); + BOOST_ASSERT(n==n1 || n==n2); + if(n == n2) + { + maybe_spill(b2, w, ec); + if(ec) + return; + b2.insert(e.offset, e.size, e.hash); + } + else + { + maybe_spill(b1, w, ec); + if(ec) + return; + b1.insert(e.offset, e.size, e.hash); + } + } + spill = tmp.spill(); + } + while(spill); + } +} + +template +detail::bucket +basic_store:: +load( + nbuck_t n, + detail::cache& c1, + detail::cache& c0, + void* buf, + error_code& ec) +{ + using namespace detail; + auto iter = c1.find(n); + if(iter != c1.end()) + return iter->second; + iter = c0.find(n); + if(iter != c0.end()) + return c1.insert(n, iter->second)->second; + bucket tmp{s_->kh.block_size, buf}; + tmp.read(s_->kf, + static_cast(n + 1) * s_->kh.block_size, ec); + if(ec) + return {}; + c0.insert(n, tmp); + return c1.insert(n, tmp)->second; +} + +template +void +basic_store:: +commit(detail::unique_lock_type& m, + std::size_t& work, error_code& ec) +{ + using namespace detail; + BOOST_ASSERT(m.owns_lock()); + BOOST_ASSERT(! s_->p1.empty()); + swap(s_->p0, s_->p1); + m.unlock(); + work = s_->p0.data_size(); + cache c0(s_->kh.key_size, s_->kh.block_size, "c0"); + cache c1(s_->kh.key_size, s_->kh.block_size, "c1"); + // 0.63212 ~= 1 - 1/e + { + auto const size = static_cast( + std::ceil(0.63212 * s_->p0.size())); + c0.reserve(size); + c1.reserve(size); + } + buffer buf1{s_->kh.block_size}; + buffer buf2{s_->kh.block_size}; + bucket tmp{s_->kh.block_size, buf1.get()}; + // Prepare rollback information + log_file_header lh; + lh.version = currentVersion; // Version + lh.uid = s_->kh.uid; // UID + lh.appnum = s_->kh.appnum; // Appnum + lh.key_size = s_->kh.key_size; // Key Size + lh.salt = s_->kh.salt; // Salt + lh.pepper = pepper(lh.salt); // Pepper + lh.block_size = s_->kh.block_size; // Block Size + lh.key_file_size = s_->kf.size(ec); // Key File Size + if(ec) + return; + lh.dat_file_size = s_->df.size(ec); // Data File Size + if(ec) + return; + write(s_->lf, lh, ec); + if(ec) + return; + // Checkpoint + s_->lf.sync(ec); + if(ec) + return; + // Append data and spills to data file + auto modulus = modulus_; + auto buckets = buckets_; + { + // Bulk write to avoid write amplification + auto const size = s_->df.size(ec); + if(ec) + return; + bulk_writer w{s_->df, size, dataWriteSize_}; + // Write inserted data to the data file + for(auto& e : s_->p0) + { + // VFALCO This could be UB since other + // threads are reading other data members + // of this object in memory + e.second = w.offset(); + auto os = w.prepare(value_size( + e.first.size, s_->kh.key_size), ec); + if(ec) + return; + // Data Record + write(os, e.first.size); // Size + write(os, e.first.key, s_->kh.key_size); // Key + write(os, e.first.data, e.first.size); // Data + } + // Do inserts, splits, and build view + // of original and modified buckets + for(auto const e : s_->p0) + { + // VFALCO Should this be >= or > ? + if((frac_ += 65536) >= thresh_) + { + // split + frac_ -= thresh_; + if(buckets == modulus) + modulus *= 2; + auto const n1 = buckets - (modulus / 2); + auto const n2 = buckets++; + auto b1 = load(n1, c1, c0, buf2.get(), ec); + if(ec) + return; + auto b2 = c1.create(n2); + // If split spills, the writer is + // flushed which can amplify writes. + split(b1, b2, tmp, n1, n2, + buckets, modulus, w, ec); + if(ec) + return; + } + // Insert + auto const n = bucket_index( + e.first.hash, buckets, modulus); + auto b = load(n, c1, c0, buf2.get(), ec); + if(ec) + return; + // This can amplify writes if it spills. + maybe_spill(b, w, ec); + if(ec) + return; + b.insert(e.second, e.first.size, e.first.hash); + } + w.flush(ec); + if(ec) + return; + } + work += s_->kh.block_size * (2 * c0.size() + c1.size()); + // Give readers a view of the new buckets. + // This might be slightly better than the old + // view since there could be fewer spills. + m.lock(); + swap(c1, s_->c1); + s_->p0.clear(); + buckets_ = buckets; + modulus_ = modulus; + g_.start(); + m.unlock(); + // Write clean buckets to log file + { + auto const size = s_->lf.size(ec); + if(ec) + return; + bulk_writer w{s_->lf, size, logWriteSize_}; + for(auto const e : c0) + { + // Log Record + auto os = w.prepare( + field::size + // Index + e.second.actual_size(), ec); // Bucket + if(ec) + return; + // Log Record + write(os, e.first); // Index + e.second.write(os); // Bucket + } + c0.clear(); + w.flush(ec); + if(ec) + return; + s_->lf.sync(ec); + if(ec) + return; + } + g_.finish(); + // Write new buckets to key file + for(auto const e : s_->c1) + { + e.second.write(s_->kf, + (e.first + 1) * s_->kh.block_size, ec); + if(ec) + return; + } + // Finalize the commit + s_->df.sync(ec); + if(ec) + return; + s_->kf.sync(ec); + if(ec) + return; + s_->lf.trunc(0, ec); + if(ec) + return; + s_->lf.sync(ec); + if(ec) + return; + // Cache is no longer needed, all fetches will go straight + // to disk again. Do this after the sync, otherwise readers + // might get blocked longer due to the extra I/O. + m.lock(); + s_->c1.clear(); +} + +template +void +basic_store:: +run() +{ + using namespace std::chrono; + using namespace detail; + +#if NUDB_DEBUG_LOG + beast::unit_test::dstream dout{std::cout}; +#endif + for(;;) + { + unique_lock_type m{m_}; + if(! s_->p1.empty()) + { + std::size_t work; + commit(m, work, ec_); + if(ec_) + { + ecb_.store(true); + return; + } + BOOST_ASSERT(m.owns_lock()); + auto const now = clock_type::now(); + auto const elapsed = duration_cast>( + now > s_->when ? now - s_->when : clock_type::duration{1}); + s_->rate = static_cast( + std::ceil(work / elapsed.count())); + #if NUDB_DEBUG_LOG + dout << + "work=" << work << + ", time=" << elapsed.count() << + ", rate=" << s_->rate << + "\n"; + #endif + } + s_->p1.periodic_activity(); + + cv_.wait_until(m, s_->when + seconds{1}, + [this]{ return ! open_; }); + if(! open_) + break; + s_->when = clock_type::now(); + } + { + unique_lock_type m{m_}; + std::size_t work; + if(! s_->p1.empty()) + commit(m, work, ec_); + } + if(ec_) + { + ecb_.store(true); + return; + } +} + +} // nudb + +#endif diff --git a/include/nudb/impl/create.ipp b/include/nudb/impl/create.ipp new file mode 100644 index 000000000..b0b8511ff --- /dev/null +++ b/include/nudb/impl/create.ipp @@ -0,0 +1,163 @@ +// +// Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef NUDB_IMPL_CREATE_IPP +#define NUDB_IMPL_CREATE_IPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace nudb { + +namespace detail { + +template +std::uint64_t +make_uid() +{ + std::random_device rng; + std::mt19937_64 gen {rng()}; + std::uniform_int_distribution dist; + return dist(gen); +} + +} // detail + +template +std::uint64_t +make_salt() +{ + std::random_device rng; + std::mt19937_64 gen {rng()}; + std::uniform_int_distribution dist; + return dist(gen); +} + +template< + class Hasher, + class File, + class... Args +> +void +create( + path_type const& dat_path, + path_type const& key_path, + path_type const& log_path, + std::uint64_t appnum, + std::uint64_t salt, + nsize_t key_size, + nsize_t blockSize, + float load_factor, + error_code& ec, + Args&&... args) +{ + static_assert(is_File::value, + "File requirements not met"); + + using namespace detail; + if(key_size < 1) + { + ec = error::invalid_key_size; + return; + } + if(blockSize > field::max) + { + ec = error::invalid_block_size; + return; + } + if(load_factor <= 0.f || load_factor >= 1.f) + { + ec = error::invalid_load_factor; + return; + } + auto const capacity = + bucket_capacity(blockSize); + if(capacity < 1) + { + ec = error::invalid_block_size; + return; + } + bool edf = false; + bool ekf = false; + bool elf = false; + { + File df(args...); + File kf(args...); + File lf(args...); + df.create(file_mode::append, dat_path, ec); + if(ec) + goto fail; + edf = true; + kf.create(file_mode::append, key_path, ec); + if(ec) + goto fail; + ekf = true; + lf.create(file_mode::append, log_path, ec); + if(ec) + goto fail; + elf = true; + dat_file_header dh; + dh.version = currentVersion; + dh.uid = make_uid(); + dh.appnum = appnum; + dh.key_size = key_size; + + key_file_header kh; + kh.version = currentVersion; + kh.uid = dh.uid; + kh.appnum = appnum; + kh.key_size = key_size; + kh.salt = salt; + kh.pepper = pepper(salt); + kh.block_size = blockSize; + kh.load_factor = std::min( + static_cast( + 65536.0 * load_factor), 65535); + write(df, dh, ec); + if(ec) + goto fail; + write(kf, kh, ec); + if(ec) + goto fail; + buffer buf{blockSize}; + std::memset(buf.get(), 0, blockSize); + bucket b(blockSize, buf.get(), empty); + b.write(kf, blockSize, ec); + if(ec) + goto fail; + // VFALCO Leave log file empty? + df.sync(ec); + if(ec) + goto fail; + kf.sync(ec); + if(ec) + goto fail; + lf.sync(ec); + if(ec) + goto fail; + // Success + return; + } +fail: + if(edf) + erase_file(dat_path); + if(ekf) + erase_file(key_path); + if(elf) + erase_file(log_path); +} + +} // nudb + +#endif diff --git a/include/nudb/impl/error.ipp b/include/nudb/impl/error.ipp new file mode 100644 index 000000000..9409a779e --- /dev/null +++ b/include/nudb/impl/error.ipp @@ -0,0 +1,180 @@ +// +// Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef NUDB_IMPL_ERROR_IPP +#define NUDB_IMPL_ERROR_IPP + +namespace nudb { + +inline +error_category const& +nudb_category() +{ + struct cat_t : public error_category + { + char const* + name() const noexcept override + { + return "nudb"; + } + + std::string + message(int ev) const override + { + switch(static_cast(ev)) + { + case error::success: + return "the operation completed successfully"; + + case error::key_not_found: + return "key not found"; + + case error::key_exists: + return "key already exists"; + + case error::short_read: + return "short read"; + + case error::log_file_exists: + return "a log file exists"; + + case error::no_key_file: + return "no key file"; + + case error::too_many_buckets: + return "too many buckets"; + + case error::not_data_file: + return "not a data file"; + + case error::not_key_file: + return "not a key file"; + + case error::not_log_file: + return "not a log file"; + + case error::different_version: + return "different version"; + + case error::invalid_key_size: + return "invalid key size"; + + case error::invalid_block_size: + return "invalid block size"; + + case error::short_key_file: + return "short key file"; + + case error::short_bucket: + return "short bucket"; + + case error::short_spill: + return "short spill"; + + case error::short_data_record: + return "short data record"; + + case error::short_value: + return "short value"; + + case error::hash_mismatch: + return "hash mismatch"; + + case error::invalid_load_factor: + return "invalid load factor"; + + case error::invalid_capacity: + return "invalid capacity"; + + case error::invalid_bucket_count: + return "invalid bucket count"; + + case error::invalid_bucket_size: + return "invalid_bucket_size"; + + case error::incomplete_data_file_header: + return "incomplete data file header"; + + case error::incomplete_key_file_header: + return "incomplete key file header"; + + case error::invalid_log_record: + return "invalid log record"; + + case error::invalid_log_spill: + return "invalid spill in log"; + + case error::invalid_log_offset: + return "invalid offset in log"; + + case error::invalid_log_index: + return "invalid index in log"; + + case error::invalid_spill_size: + return "invalid size in spill"; + + case error::uid_mismatch: + return "uid mismatch"; + + case error::appnum_mismatch: + return "appnum mismatch"; + + case error::key_size_mismatch: + return "key size mismatch"; + + case error::salt_mismatch: + return "salt mismatch"; + + case error::pepper_mismatch: + return "pepper mismatch"; + + case error::block_size_mismatch: + return "block size mismatch"; + + case error::orphaned_value: + return "orphaned value"; + + case error::missing_value: + return "missing value"; + + case error::size_mismatch: + return "size mismatch"; + + case error::duplicate_value: + return "duplicate value"; + + default: + return "nudb error"; + } + } + + error_condition + default_error_condition(int ev) const noexcept override + { + return error_condition{ev, *this}; + } + + bool + equivalent(int ev, + error_condition const& ec) const noexcept override + { + return ec.value() == ev && &ec.category() == this; + } + + bool + equivalent(error_code const& ec, int ev) const noexcept override + { + return ec.value() == ev && &ec.category() == this; + } + }; + static cat_t const cat{}; + return cat; +} + +} // nudb + +#endif diff --git a/include/nudb/impl/posix_file.ipp b/include/nudb/impl/posix_file.ipp new file mode 100644 index 000000000..a03262a30 --- /dev/null +++ b/include/nudb/impl/posix_file.ipp @@ -0,0 +1,259 @@ +// +// Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef NUDB_IMPL_POSIX_FILE_IPP +#define NUDB_IMPL_POSIX_FILE_IPP + +#include +#include + +namespace nudb { + +inline +posix_file:: +~posix_file() +{ + close(); +} + +inline +posix_file:: +posix_file(posix_file &&other) + : fd_(other.fd_) +{ + other.fd_ = -1; +} + +inline +posix_file& +posix_file:: +operator=(posix_file&& other) +{ + if(&other == this) + return *this; + close(); + fd_ = other.fd_; + other.fd_ = -1; + return *this; +} + +inline +void +posix_file:: +close() +{ + if(fd_ != -1) + { + ::close(fd_); + fd_ = -1; + } +} + +inline +void +posix_file:: +create(file_mode mode, path_type const& path, error_code& ec) +{ + auto const result = flags(mode); + BOOST_ASSERT(! is_open()); + fd_ = ::open(path.c_str(), result.first); + if(fd_ != -1) + { + ::close(fd_); + fd_ = -1; + ec = error_code{errc::file_exists, generic_category()}; + return ; + } + int errnum = errno; + if(errnum != ENOENT) + return err(errnum, ec); + fd_ = ::open(path.c_str(), result.first | O_CREAT, 0644); + if(fd_ == -1) + return last_err(ec); +#ifndef __APPLE__ + if(::posix_fadvise(fd_, 0, 0, result.second) != 0) + return last_err(ec); +#endif +} + +inline +void +posix_file:: +open(file_mode mode, path_type const& path, error_code& ec) +{ + BOOST_ASSERT(! is_open()); + auto const result = flags(mode); + fd_ = ::open(path.c_str(), result.first); + if(fd_ == -1) + return last_err(ec); +#ifndef __APPLE__ + if(::posix_fadvise(fd_, 0, 0, result.second) != 0) + return last_err(ec); +#endif +} + +inline +void +posix_file:: +erase(path_type const& path, error_code& ec) +{ + if(::unlink(path.c_str()) != 0) + { + int const ev = errno; + return err(ev, ec); + } +} + +inline +std::uint64_t +posix_file:: +size(error_code& ec) const +{ + static_assert(sizeof(stat::st_size) == sizeof(std::uint64_t), ""); + struct stat st; + if(::fstat(fd_, &st) != 0) + { + last_err(ec); + return 0; + } + return st.st_size; +} +inline +void +posix_file:: +read(std::uint64_t offset, + void* buffer, std::size_t bytes, error_code& ec) +{ + static_assert(sizeof(off_t) >= sizeof(offset), ""); + while(bytes > 0) + { + auto const amount = static_cast( + std::min(bytes, static_cast(SSIZE_MAX))); + auto const n = ::pread(fd_, buffer, amount, offset); + if(n == -1) + { + auto const ev = errno; + if(ev == EINTR) + continue; + return err(ev, ec); + } + if(n == 0) + { + ec = error::short_read; + return; + } + offset += n; + bytes -= n; + buffer = reinterpret_cast(buffer) + n; + } +} + +inline +void +posix_file:: +write(std::uint64_t offset, + void const* buffer, std::size_t bytes, error_code& ec) +{ + static_assert(sizeof(off_t) >= sizeof(offset), ""); + while(bytes > 0) + { + auto const amount = static_cast( + std::min(bytes, static_cast(SSIZE_MAX))); + auto const n = ::pwrite(fd_, buffer, amount, offset); + if(n == -1) + { + auto const ev = errno; + if(ev == EINTR) + continue; + return err(ev, ec); + } + offset += n; + bytes -= n; + buffer = reinterpret_cast(buffer) + n; + } +} + +inline +void +posix_file:: +sync(error_code& ec) +{ + for(;;) + { + if(::fsync(fd_) == 0) + break; + auto const ev = errno; + if(ev == EINTR) + continue; + return err(ev, ec); + } +} + +inline +void +posix_file:: +trunc(std::uint64_t length, error_code& ec) +{ + for(;;) + { + if(::ftruncate(fd_, length) == 0) + break; + auto const ev = errno; + if(ev == EINTR) + continue; + return err(ev, ec); + } +} + +inline +std::pair +posix_file:: +flags(file_mode mode) +{ + std::pair result; + switch(mode) + { + case file_mode::scan: + result.first = + O_RDONLY; + #ifndef __APPLE__ + result.second = + POSIX_FADV_SEQUENTIAL; + #endif + break; + case file_mode::read: + result.first = + O_RDONLY; + #ifndef __APPLE__ + result.second = + POSIX_FADV_RANDOM; + #endif + break; + case file_mode::append: + result.first = + O_RDWR | + O_APPEND; + #ifndef __APPLE__ + result.second = + POSIX_FADV_RANDOM; + #endif + break; + case file_mode::write: + result.first = + O_RDWR; + #ifndef __APPLE__ + result.second = + POSIX_FADV_NORMAL; + #endif + break; + } + return result; +} + +} // nudb + +#endif diff --git a/include/nudb/impl/recover.ipp b/include/nudb/impl/recover.ipp new file mode 100644 index 000000000..e449c36f2 --- /dev/null +++ b/include/nudb/impl/recover.ipp @@ -0,0 +1,209 @@ +// +// Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef NUDB_IMPL_RECOVER_IPP +#define NUDB_IMPL_RECOVER_IPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace nudb { + +template< + class Hasher, + class File, + class... Args> +void +recover( + path_type const& dat_path, + path_type const& key_path, + path_type const& log_path, + error_code& ec, + Args&&... args) +{ + static_assert(is_File::value, + "File requirements not met"); + static_assert(is_Hasher::value, + "Hasher requirements not met"); + using namespace detail; + + // Open data file + File df{args...}; + df.open(file_mode::write, dat_path, ec); + if(ec) + return; + auto const dataFileSize = df.size(ec); + if(ec) + return; + dat_file_header dh; + read(df, dh, ec); + if(ec) + return; + verify(dh, ec); + if(ec) + return; + + // Open key file + File kf{args...}; + kf.open(file_mode::write, key_path, ec); + if(ec) + return; + auto const keyFileSize = kf.size(ec); + if(ec) + return; + if(keyFileSize <= key_file_header::size) + { + kf.close(); + erase_file(log_path, ec); + if(ec) + return; + File::erase(key_path, ec); + if(ec) + return; + ec = error::no_key_file; + return; + } + + // Open log file + File lf{args...}; + lf.open(file_mode::append, log_path, ec); + if(ec == errc::no_such_file_or_directory) + { + ec = {}; + return; + } + if(ec) + return; + auto const logFileSize = lf.size(ec); + if(ec) + return; + // Read log file header + log_file_header lh; + read(lf, lh, ec); + if(ec == error::short_read) + { + BOOST_ASSERT(keyFileSize > key_file_header::size); + ec = {}; + goto clear_log; + } + if(ec) + return; + verify(lh, ec); + if(ec) + return; + if(lh.key_file_size == 0) + goto trunc_files; + { + // Read key file header + key_file_header kh; + read(kf, kh, ec); + if(ec) + return; + verify(kh, ec); + if(ec) + return; + verify(dh, kh, ec); + if(ec) + return; + verify(kh, lh, ec); + if(ec) + return; + + auto const readSize = 1024 * kh.block_size; + auto const bucketSize = bucket_size(kh.capacity); + buffer buf{kh.block_size}; + bucket b{kh.block_size, buf.get()}; + bulk_reader r{lf, + log_file_header::size, logFileSize, readSize}; + while(! r.eof()) + { + // Log Record + auto is = r.prepare(field::size, ec); + // Log file is incomplete, so roll back. + if(ec == error::short_read) + { + ec = {}; + break; + } + if(ec) + return; + nsize_t n; + { + std::uint64_t v; + // VFALCO This should have been a uint32_t + read(is, v); // Index + BOOST_ASSERT(v <= std::numeric_limits::max()); + n = static_cast(v); + } + b.read(r, ec); // Bucket + if(ec == error::short_read) + { + ec = {}; + break; + } + if(b.spill() && b.spill() + bucketSize > dataFileSize) + { + ec = error::invalid_log_spill; + return; + } + if(n > kh.buckets) + { + ec = error::invalid_log_index; + return; + } + b.write(kf, static_cast(n + 1) * kh.block_size, ec); + if(ec) + return; + } + } +trunc_files: + df.trunc(lh.dat_file_size, ec); + if(ec) + return; + df.sync(ec); + if(ec) + return; + if(lh.key_file_size != 0) + { + kf.trunc(lh.key_file_size, ec); + if(ec) + return; + kf.sync(ec); + if(ec) + return; + } + else + { + kf.close(); + File::erase(key_path, ec); + if(ec) + return; + } +clear_log: + lf.trunc(0, ec); + if(ec) + return; + lf.sync(ec); + if(ec) + return; + lf.close(); + File::erase(log_path, ec); + if(ec) + return; +} + +} // nudb + +#endif diff --git a/include/nudb/impl/rekey.ipp b/include/nudb/impl/rekey.ipp new file mode 100644 index 000000000..ab247c77d --- /dev/null +++ b/include/nudb/impl/rekey.ipp @@ -0,0 +1,248 @@ +// +// Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef NUDB_IMPL_REKEY_IPP +#define NUDB_IMPL_REKEY_IPP + +#include +#include +#include +#include +#include +#include + +namespace nudb { + +// VFALCO Should this delete the key file on an error? +template< + class Hasher, + class File, + class Progress, + class... Args +> +void +rekey( + path_type const& dat_path, + path_type const& key_path, + path_type const& log_path, + std::size_t blockSize, + float loadFactor, + std::uint64_t itemCount, + std::size_t bufferSize, + error_code& ec, + Progress&& progress, + Args&&... args) +{ + static_assert(is_File::value, + "File requirements not met"); + static_assert(is_Hasher::value, + "Hasher requirements not met"); + static_assert(is_Progress::value, + "Progress requirements not met"); + using namespace detail; + auto const readSize = 1024 * block_size(dat_path); + auto const writeSize = 16 * block_size(key_path); + + // Open data file for reading and appending + File df{args...}; + df.open(file_mode::append, dat_path, ec); + if(ec) + return; + dat_file_header dh; + read(df, dh, ec); + if(ec) + return; + verify(dh, ec); + if(ec) + return; + auto const dataFileSize = df.size(ec); + if(ec) + return; + + // Make sure log file doesn't exist + File lf{args...}; + lf.open(file_mode::read, log_path, ec); + if(! ec) + ec = error::log_file_exists; + if(ec != errc::no_such_file_or_directory) + return; + ec = {}; + + // Set up key file header + key_file_header kh; + kh.version = currentVersion; + kh.uid = dh.uid; + kh.appnum = dh.appnum; + kh.key_size = dh.key_size; + kh.salt = make_salt(); + kh.pepper = pepper(kh.salt); + kh.block_size = blockSize; + kh.load_factor = std::min( + static_cast(65536.0 * loadFactor), 65535); + kh.buckets = static_cast( + std::ceil(itemCount /( + bucket_capacity(kh.block_size) * loadFactor))); + kh.modulus = ceil_pow2(kh.buckets); + // Create key file + File kf{args...}; + kf.create(file_mode::write, key_path, ec); + if(ec) + return; + // Write key file header + // Note, file size is less than any valid block_size here + { + std::array buf; + ostream os{buf.data(), buf.size()}; + write(os, kh); + kf.write(0, buf.data(), buf.size(), ec); + if(ec) + return; + kf.sync(ec); + if(ec) + return; + } + + // Create log file + lf.create(file_mode::append, log_path, ec); + if(ec) + return; + // Write log file header + { + log_file_header lh; + lh.version = currentVersion; // Version + lh.uid = kh.uid; // UID + lh.appnum = kh.appnum; // Appnum + lh.key_size = kh.key_size; // Key Size + lh.salt = kh.salt; // Salt + lh.pepper = pepper(kh.salt); // Pepper + lh.block_size = kh.block_size; // Block Size + lh.key_file_size = 0; // Key File Size + lh.dat_file_size = dataFileSize; // Data File Size + write(lf, lh, ec); + if(ec) + return; + lf.sync(ec); + if(ec) + return; + } + + // Create full key file + buffer buf{kh.block_size}; + { + // Write key file header + std::memset(buf.get(), 0, kh.block_size); + ostream os{buf.get(), kh.block_size}; + write(os, kh); + kf.write(0, buf.get(), buf.size(), ec); + if(ec) + return; + kf.sync(ec); + if(ec) + return; + // Pre-allocate space for the entire key file + std::uint8_t zero = 0; + kf.write( + static_cast(kh.buckets + 1) * kh.block_size - 1, + &zero, 1, ec); + if(ec) + return; + kf.sync(ec); + if(ec) + return; + } + + // Build contiguous sequential sections of the + // key file using multiple passes over the data. + // + auto const chunkSize = std::max(1, + bufferSize / kh.block_size); + // Calculate work required + auto const passes = + (kh.buckets + chunkSize - 1) / chunkSize; + auto const nwork = passes * dataFileSize; + progress(0, nwork); + + buf.reserve(chunkSize * kh.block_size); + bulk_writer dw{df, dataFileSize, writeSize}; + for(nbuck_t b0 = 0; b0 < kh.buckets; b0 += chunkSize) + { + auto const b1 = std::min(b0 + chunkSize, kh.buckets); + // Buffered range is [b0, b1) + auto const bn = b1 - b0; + // Create empty buckets + for(std::size_t i = 0; i < bn; ++i) + bucket b{kh.block_size, + buf.get() + i * kh.block_size, empty}; + // Insert all keys into buckets + // Iterate Data File + bulk_reader r{df, + dat_file_header::size, dataFileSize, readSize}; + while(! r.eof()) + { + auto const offset = r.offset(); + // Data Record or Spill Record + nsize_t size; + auto is = r.prepare( + field::size, ec); // Size + if(ec) + return; + progress((b0 / chunkSize) * dataFileSize + r.offset(), nwork); + read_size48(is, size); + if(size > 0) + { + // Data Record + is = r.prepare( + dh.key_size + // Key + size, ec); // Data + if(ec) + return; + std::uint8_t const* const key = + is.data(dh.key_size); + auto const h = hash( + key, dh.key_size, kh.salt); + auto const n = bucket_index( + h, kh.buckets, kh.modulus); + if(n < b0 || n >= b1) + continue; + bucket b{kh.block_size, buf.get() + + (n - b0) * kh.block_size}; + maybe_spill(b, dw, ec); + if(ec) + return; + b.insert(offset, size, h); + } + else + { + // VFALCO Should never get here + // Spill Record + is = r.prepare( + field::size, ec); + if(ec) + return; + read(is, size); // Size + r.prepare(size, ec); // skip + if(ec) + return; + } + } + kf.write((b0 + 1) * kh.block_size, buf.get(), + static_cast(bn * kh.block_size), ec); + if(ec) + return; + } + dw.flush(ec); + if(ec) + return; + lf.close(); + File::erase(log_path, ec); + if(ec) + return; +} + +} // nudb + +#endif diff --git a/include/nudb/impl/verify.ipp b/include/nudb/impl/verify.ipp new file mode 100644 index 000000000..c1d221eeb --- /dev/null +++ b/include/nudb/impl/verify.ipp @@ -0,0 +1,630 @@ +// +// Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef NUDB_IMPL_VERIFY_IPP +#define NUDB_IMPL_VERIFY_IPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace nudb { + +namespace detail { + +// Normal verify that does not require a buffer +// +template< + class Hasher, + class File, + class Progress> +void +verify_normal( + verify_info& info, + File& df, + File& kf, + dat_file_header& dh, + key_file_header& kh, + Progress&& progress, + error_code& ec) +{ + static_assert(is_File::value, + "File requirements not met"); + static_assert(is_Hasher::value, + "Hasher requirements not met"); + static_assert(is_Progress::value, + "Progress requirements not met"); + info.algorithm = 0; + auto const readSize = 1024 * kh.block_size; + + // This ratio balances the 2 work phases. + // The number is determined empirically. + auto const adjust = 1.75; + + // Calculate the work required + auto const keys = static_cast( + double(kh.load_factor) / 65536.0 * kh.buckets * kh.capacity); + std::uint64_t const nwork = static_cast( + info.dat_file_size + keys * kh.block_size + + adjust * (info.key_file_size + keys * kh.block_size)); + std::uint64_t work = 0; + progress(0, nwork); + + // Iterate Data File + // Data Record + auto const dh_len = + field::size + // Size + kh.key_size; // Key + std::uint64_t fetches = 0; + buffer buf{kh.block_size + dh_len}; + bucket b{kh.block_size, buf.get()}; + std::uint8_t* pd = buf.get() + kh.block_size; + { + bulk_reader r{df, dat_file_header::size, + info.dat_file_size, readSize}; + while(! r.eof()) + { + auto const offset = r.offset(); + // Data Record or Spill Record + auto is = r.prepare( + field::size, ec); // Size + if(ec) + return; + nsize_t size; + read_size48(is, size); + if(size > 0) + { + // Data Record + is = r.prepare( + kh.key_size + // Key + size, ec); // Data + if(ec) + return; + std::uint8_t const* const key = + is.data(kh.key_size); + std::uint8_t const* const data = + is.data(size); + (void)data; + auto const h = hash( + key, kh.key_size, kh.salt); + // Check bucket and spills + auto const n = bucket_index( + h, kh.buckets, kh.modulus); + b.read(kf, + static_cast(n + 1) * kh.block_size, ec); + if(ec) + return; + work += kh.block_size; + ++fetches; + for(;;) + { + for(auto i = b.lower_bound(h); + i < b.size(); ++i) + { + auto const item = b[i]; + if(item.hash != h) + break; + if(item.offset == offset) + goto found; + ++fetches; + } + auto const spill = b.spill(); + if(! spill) + { + ec = error::orphaned_value; + return; + } + b.read(df, spill, ec); + if(ec == error::short_read) + { + ec = error::short_spill; + return; + } + if(ec) + return; + ++fetches; + } + found: + // Update + ++info.value_count; + info.value_bytes += size; + } + else + { + // Spill Record + is = r.prepare( + field::size, ec); + if(ec == error::short_read) + { + ec = error::short_spill; + return; + } + if(ec) + return; + read(is, size); // Size + if(size != info.bucket_size) + { + ec = error::invalid_spill_size; + return; + } + if(ec) + return; + b.read(r, ec); // Bucket + if(ec == error::short_read) + { + ec = error::short_spill; + return; + } + if(ec) + return; + ++info.spill_count_tot; + info.spill_bytes_tot += + field::size + // Zero + field::size + // Size + b.actual_size(); // Bucket + } + progress(work + offset, nwork); + } + work += info.dat_file_size; + } + + // Iterate Key File + { + for(std::size_t n = 0; n < kh.buckets; ++n) + { + std::size_t nspill = 0; + b.read(kf, static_cast( + n + 1) * kh.block_size, ec); + if(ec) + return; + work += static_cast( + adjust * kh.block_size); + bool spill = false; + for(;;) + { + info.key_count += b.size(); + for(nkey_t i = 0; i < b.size(); ++i) + { + auto const e = b[i]; + df.read(e.offset, pd, dh_len, ec); + if(ec == error::short_read) + { + ec = error::missing_value; + return; + } + if(ec) + return; + if(! spill) + work += static_cast( + adjust * kh.block_size); + // Data Record + istream is{pd, dh_len}; + std::uint64_t size; + // VFALCO This should really be a 32-bit field + read(is, size); // Size + void const* key = + is.data(kh.key_size); // Key + if(size != e.size) + { + ec = error::size_mismatch; + return; + } + auto const h = hash(key, + kh.key_size, kh.salt); + if(h != e.hash) + { + ec = error::hash_mismatch; + return; + } + } + if(! b.spill()) + break; + b.read(df, b.spill(), ec); + if(ec) + return; + spill = true; + ++nspill; + ++info.spill_count; + info.spill_bytes += + field::size + // Zero + field::size + // Size + b.actual_size(); // SpillBucket + } + if(nspill >= info.hist.size()) + nspill = info.hist.size() - 1; + ++info.hist[nspill]; + progress(work, nwork); + } + } + float sum = 0; + for(size_t i = 0; i < info.hist.size(); ++i) + sum += info.hist[i] * (i + 1); + if(info.value_count) + info.avg_fetch = + float(fetches) / info.value_count; + else + info.avg_fetch = 0; + info.waste = (info.spill_bytes_tot - info.spill_bytes) / + float(info.dat_file_size); + if(info.value_count) + info.overhead = + float(info.key_file_size + info.dat_file_size) / + ( + info.value_bytes + + info.key_count * + (info.key_size + + // Data Record + field::size) // Size + ) - 1; + else + info.overhead = 0; + info.actual_load = info.key_count / float( + info.capacity * info.buckets); +} + +// Fast version of verify that uses a buffer +// +template +void +verify_fast( + verify_info& info, + File& df, + File& kf, + dat_file_header& dh, + key_file_header& kh, + std::size_t bufferSize, + Progress&& progress, + error_code& ec) +{ + info.algorithm = 1; + auto const readSize = 1024 * kh.block_size; + + // Counts unverified keys per bucket + if(kh.buckets > std::numeric_limits::max()) + { + ec = error::too_many_buckets; + return; + } + std::unique_ptr nkeys( + new nkey_t[kh.buckets]); + + // Verify contiguous sequential sections of the + // key file using multiple passes over the data. + // + if(bufferSize < 2 * kh.block_size + sizeof(nkey_t)) + throw std::logic_error("invalid buffer size"); + auto chunkSize = std::min(kh.buckets, + (bufferSize - kh.block_size) / + (kh.block_size + sizeof(nkey_t))); + auto const passes = + (kh.buckets + chunkSize - 1) / chunkSize; + + // Calculate the work required + std::uint64_t work = 0; + std::uint64_t const nwork = + passes * info.dat_file_size + info.key_file_size; + progress(0, nwork); + + std::uint64_t fetches = 0; + buffer buf{(chunkSize + 1) * kh.block_size}; + bucket tmp{kh.block_size, + buf.get() + chunkSize * kh.block_size}; + for(nsize_t b0 = 0; b0 < kh.buckets; b0 += chunkSize) + { + // Load key file chunk to buffer + auto const b1 = std::min(b0 + chunkSize, kh.buckets); + // Buffered range is [b0, b1) + auto const bn = b1 - b0; + kf.read( + static_cast(b0 + 1) * kh.block_size, + buf.get(), + static_cast(bn * kh.block_size), + ec); + if(ec) + return; + work += bn * kh.block_size; + progress(work, nwork); + // Count keys in buckets, including spills + for(nbuck_t i = 0 ; i < bn; ++i) + { + bucket b{kh.block_size, + buf.get() + i * kh.block_size}; + nkeys[i] = b.size(); + std::size_t nspill = 0; + auto spill = b.spill(); + while(spill != 0) + { + tmp.read(df, spill, ec); + if(ec == error::short_read) + { + ec = error::short_spill; + return; + } + if(ec) + return; + nkeys[i] += tmp.size(); + spill = tmp.spill(); + ++nspill; + ++info.spill_count; + info.spill_bytes += + field::size + // Zero + field::size + // Size + tmp.actual_size(); // SpillBucket + } + if(nspill >= info.hist.size()) + nspill = info.hist.size() - 1; + ++info.hist[nspill]; + info.key_count += nkeys[i]; + } + // Iterate Data File + bulk_reader r(df, dat_file_header::size, + info.dat_file_size, readSize); + while(! r.eof()) + { + auto const offset = r.offset(); + // Data Record or Spill Record + auto is = r.prepare( + field::size, ec); // Size + if(ec == error::short_read) + { + ec = error::short_data_record; + return; + } + if(ec) + return; + nsize_t size; + detail::read_size48(is, size); + if(size > 0) + { + // Data Record + is = r.prepare( + kh.key_size + // Key + size, ec); // Data + if(ec == error::short_read) + { + ec = error::short_value; + return; + } + if(ec) + return; + std::uint8_t const* const key = + is.data(kh.key_size); + std::uint8_t const* const data = + is.data(size); + (void)data; + auto const h = hash( + key, kh.key_size, kh.salt); + auto const n = bucket_index( + h, kh.buckets, kh.modulus); + if(n < b0 || n >= b1) + continue; + // Check bucket and spills + bucket b{kh.block_size, buf.get() + + (n - b0) * kh.block_size}; + ++fetches; + for(;;) + { + for(auto i = b.lower_bound(h); + i < b.size(); ++i) + { + auto const item = b[i]; + if(item.hash != h) + break; + if(item.offset == offset) + goto found; + ++fetches; + } + auto const spill = b.spill(); + if(! spill) + { + ec = error::orphaned_value; + return; + } + b = tmp; + b.read(df, spill, ec); + if(ec == error::short_read) + { + ec = error::short_spill; + return; + } + if(ec) + return; + ++fetches; + } + found: + // Update + ++info.value_count; + info.value_bytes += size; + if(nkeys[n - b0]-- == 0) + { + ec = error::orphaned_value; + return; + } + } + else + { + // Spill Record + is = r.prepare( + field::size, ec); + if(ec == error::short_read) + { + ec = error::short_spill; + return; + } + if(ec) + return; + read(is, size); // Size + if(bucket_size( + bucket_capacity(size)) != size) + { + ec = error::invalid_spill_size; + return; + } + r.prepare(size, ec); // Bucket + if(ec == error::short_read) + { + ec = error::short_spill; + return; + } + if(ec) + return; + if(b0 == 0) + { + ++info.spill_count_tot; + info.spill_bytes_tot += + field::size + // Zero + field::size + // Size + tmp.actual_size(); // Bucket + } + } + progress(work + offset, nwork); + } + // Make sure every key in every bucket was visited + for(std::size_t i = 0; i < bn; ++i) + { + if(nkeys[i] != 0) + { + ec = error::missing_value; + return; + } + } + work += info.dat_file_size; + } + + float sum = 0; + for(std::size_t i = 0; i < info.hist.size(); ++i) + sum += info.hist[i] * (i + 1); + if(info.value_count) + info.avg_fetch = + float(fetches) / info.value_count; + else + info.avg_fetch = 0; + info.waste = (info.spill_bytes_tot - info.spill_bytes) / + float(info.dat_file_size); + if(info.value_count) + info.overhead = + float(info.key_file_size + info.dat_file_size) / + ( + info.value_bytes + + info.key_count * + (info.key_size + + // Data Record + field::size) // Size + ) - 1; + else + info.overhead = 0; + info.actual_load = info.key_count / float( + info.capacity * info.buckets); +} + +} // detail + +template +void +verify( + verify_info& info, + path_type const& dat_path, + path_type const& key_path, + std::size_t bufferSize, + Progress&& progress, + error_code& ec) +{ + static_assert(is_Hasher::value, + "Hasher requirements not met"); + static_assert(is_Progress::value, + "Progress requirements not met"); + info = {}; + using namespace detail; + using File = native_file; + File df; + df.open(file_mode::scan, dat_path, ec); + if(ec) + return; + File kf; + kf.open (file_mode::read, key_path, ec); + if(ec) + return; + dat_file_header dh; + read(df, dh, ec); + if(ec) + return; + verify(dh, ec); + if(ec) + return; + key_file_header kh; + read(kf, kh, ec); + if(ec) + return; + verify(kh, ec); + if(ec) + return; + verify(dh, kh, ec); + if(ec) + return; + info.dat_path = dat_path; + info.key_path = key_path; + info.version = dh.version; + info.uid = dh.uid; + info.appnum = dh.appnum; + info.key_size = dh.key_size; + info.salt = kh.salt; + info.pepper = kh.pepper; + info.block_size = kh.block_size; + info.load_factor = kh.load_factor / 65536.f; + info.capacity = kh.capacity; + info.buckets = kh.buckets; + info.bucket_size = bucket_size(kh.capacity); + info.key_file_size = kf.size(ec); + if(ec) + return; + info.dat_file_size = df.size(ec); + if(ec) + return; + + // Determine which algorithm requires the least amount + // of file I/O given the available buffer size + std::size_t chunkSize; + if(bufferSize >= 2 * kh.block_size + sizeof(nkey_t)) + chunkSize = std::min(kh.buckets, + (bufferSize - kh.block_size) / + (kh.block_size + sizeof(nkey_t))); + else + chunkSize = 0; + std::size_t passes; + if(chunkSize > 0) + passes = (kh.buckets + chunkSize - 1) / chunkSize; + else + passes = 0; + if(! chunkSize || + (( + info.dat_file_size + + (kh.buckets * kh.load_factor * kh.capacity * kh.block_size) + + info.key_file_size + ) < ( + passes * info.dat_file_size + info.key_file_size + ))) + { + detail::verify_normal(info, + df, kf, dh, kh, progress, ec); + } + else + { + detail::verify_fast(info, + df, kf, dh, kh, bufferSize, progress, ec); + } +} + +} // nudb + +#endif diff --git a/include/nudb/impl/visit.ipp b/include/nudb/impl/visit.ipp new file mode 100644 index 000000000..4d57b9595 --- /dev/null +++ b/include/nudb/impl/visit.ipp @@ -0,0 +1,96 @@ +// +// Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef NUDB_IMPL_VISIT_IPP +#define NUDB_IMPL_VISIT_IPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace nudb { + +template< + class Callback, + class Progress> +void +visit( + path_type const& path, + Callback&& callback, + Progress&& progress, + error_code& ec) +{ + // VFALCO Need concept check for Callback + static_assert(is_Progress::value, + "Progress requirements not met"); + using namespace detail; + using File = native_file; + auto const readSize = 1024 * block_size(path); + File df; + df.open(file_mode::scan, path, ec); + if(ec) + return; + dat_file_header dh; + read(df, dh, ec); + if(ec) + return; + verify(dh, ec); + if(ec) + return; + auto const fileSize = df.size(ec); + if(ec) + return; + bulk_reader r(df, + dat_file_header::size, fileSize, readSize); + progress(0, fileSize); + while(! r.eof()) + { + // Data Record or Spill Record + nsize_t size; + auto is = r.prepare( + field::size, ec); // Size + if(ec) + return; + detail::read_size48(is, size); + if(size > 0) + { + // Data Record + is = r.prepare( + dh.key_size + // Key + size, ec); // Data + std::uint8_t const* const key = + is.data(dh.key_size); + callback(key, dh.key_size, + is.data(size), size, ec); + if(ec) + return; + } + else + { + // Spill Record + is = r.prepare( + field::size, ec); + if(ec) + return; + read(is, size); // Size + r.prepare(size, ec); // skip bucket + if(ec) + return; + } + progress(r.offset(), fileSize); + } +} + +} // nudb + +#endif diff --git a/include/nudb/impl/win32_file.ipp b/include/nudb/impl/win32_file.ipp new file mode 100644 index 000000000..c0e5cdae6 --- /dev/null +++ b/include/nudb/impl/win32_file.ipp @@ -0,0 +1,264 @@ +// +// Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef NUDB_IMPL_WIN32_FILE_IPP +#define NUDB_IMPL_WIN32_FILE_IPP + +#include + +namespace nudb { + +inline +win32_file:: +~win32_file() +{ + close(); +} + +inline +win32_file:: +win32_file(win32_file&& other) + : hf_(other.hf_) +{ + other.hf_ = INVALID_HANDLE_VALUE; +} + +inline +win32_file& +win32_file:: +operator=(win32_file&& other) +{ + if(&other == this) + return *this; + close(); + hf_ = other.hf_; + other.hf_ = INVALID_HANDLE_VALUE; + return *this; +} + +inline +void +win32_file:: +close() +{ + if(hf_ != INVALID_HANDLE_VALUE) + { + ::CloseHandle(hf_); + hf_ = INVALID_HANDLE_VALUE; + } +} + +inline +void +win32_file:: +create(file_mode mode, path_type const& path, error_code& ec) +{ + BOOST_ASSERT(! is_open()); + auto const f = flags(mode); + hf_ = ::CreateFileA(path.c_str(), + f.first, + 0, + NULL, + CREATE_NEW, + f.second, + NULL); + if(hf_ == INVALID_HANDLE_VALUE) + return last_err(ec); +} + +inline +void +win32_file:: +open(file_mode mode, path_type const& path, error_code& ec) +{ + BOOST_ASSERT(! is_open()); + auto const f = flags(mode); + hf_ = ::CreateFileA(path.c_str(), + f.first, + 0, + NULL, + OPEN_EXISTING, + f.second, + NULL); + if(hf_ == INVALID_HANDLE_VALUE) + return last_err(ec); +} + +inline +void +win32_file:: +erase(path_type const& path, error_code& ec) +{ + BOOL const bSuccess = + ::DeleteFileA(path.c_str()); + if(! bSuccess) + return last_err(ec); +} + +inline +std::uint64_t +win32_file:: +size(error_code& ec) const +{ + BOOST_ASSERT(is_open()); + LARGE_INTEGER fileSize; + if(! ::GetFileSizeEx(hf_, &fileSize)) + { + last_err(ec); + return 0; + } + return fileSize.QuadPart; +} + +inline +void +win32_file:: +read(std::uint64_t offset, void* buffer, std::size_t bytes, error_code& ec) +{ + while(bytes > 0) + { + DWORD bytesRead; + LARGE_INTEGER li; + li.QuadPart = static_cast(offset); + OVERLAPPED ov; + ov.Offset = li.LowPart; + ov.OffsetHigh = li.HighPart; + ov.hEvent = NULL; + DWORD amount; + if(bytes > std::numeric_limits::max()) + amount = std::numeric_limits::max(); + else + amount = static_cast(bytes); + BOOL const bSuccess = ::ReadFile( + hf_, buffer, amount, &bytesRead, &ov); + if(! bSuccess) + { + DWORD const dwError = ::GetLastError(); + if(dwError != ERROR_HANDLE_EOF) + return err(dwError, ec); + ec = make_error_code(error::short_read); + return; + } + if(bytesRead == 0) + { + ec = make_error_code(error::short_read); + return; + } + offset += bytesRead; + bytes -= bytesRead; + buffer = reinterpret_cast( + buffer) + bytesRead; + } +} + +inline +void +win32_file:: +write(std::uint64_t offset, + void const* buffer, std::size_t bytes, error_code& ec) +{ + while(bytes > 0) + { + LARGE_INTEGER li; + li.QuadPart = static_cast(offset); + OVERLAPPED ov; + ov.Offset = li.LowPart; + ov.OffsetHigh = li.HighPart; + ov.hEvent = NULL; + DWORD amount; + if(bytes > std::numeric_limits::max()) + amount = std::numeric_limits::max(); + else + amount = static_cast(bytes); + DWORD bytesWritten; + BOOL const bSuccess = ::WriteFile( + hf_, buffer, amount, &bytesWritten, &ov); + if(! bSuccess) + return last_err(ec); + if(bytesWritten == 0) + { + ec = error_code{errc::no_space_on_device, + generic_category()};; + return; + } + offset += bytesWritten; + bytes -= bytesWritten; + buffer = reinterpret_cast( + buffer) + bytesWritten; + } +} + +inline +void +win32_file:: +sync(error_code& ec) +{ + if(! ::FlushFileBuffers(hf_)) + return last_err(ec); +} + +inline +void +win32_file:: +trunc(std::uint64_t length, error_code& ec) +{ + LARGE_INTEGER li; + li.QuadPart = length; + BOOL bSuccess; + bSuccess = ::SetFilePointerEx( + hf_, li, NULL, FILE_BEGIN); + if(bSuccess) + bSuccess = ::SetEndOfFile(hf_); + if(! bSuccess) + return last_err(ec); +} + +inline +std::pair +win32_file:: +flags(file_mode mode) +{ + std::pair result{0, 0}; + switch(mode) + { + case file_mode::scan: + result.first = + GENERIC_READ; + result.second = + FILE_FLAG_SEQUENTIAL_SCAN; + break; + + case file_mode::read: + result.first = + GENERIC_READ; + result.second = + FILE_FLAG_RANDOM_ACCESS; + break; + + case file_mode::append: + result.first = + GENERIC_READ | GENERIC_WRITE; + result.second = + FILE_FLAG_RANDOM_ACCESS + //| FILE_FLAG_NO_BUFFERING + //| FILE_FLAG_WRITE_THROUGH + ; + break; + + case file_mode::write: + result.first = + GENERIC_READ | GENERIC_WRITE; + result.second = + FILE_FLAG_RANDOM_ACCESS; + break; + } + return result; +} + +} // nudb + +#endif diff --git a/include/nudb/native_file.hpp b/include/nudb/native_file.hpp new file mode 100644 index 000000000..241119ab6 --- /dev/null +++ b/include/nudb/native_file.hpp @@ -0,0 +1,76 @@ +// +// Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef NUDB_NATIVE_FILE_HPP +#define NUDB_NATIVE_FILE_HPP + +#include +#include +#include +#include +#include + +namespace nudb { + +/** A native file handle. + + This type is set to the appropriate platform-specific + implementation to meet the file wrapper requirements. +*/ +using native_file = +#ifdef _MSC_VER + win32_file; +#else + posix_file; +#endif + +/** Erase a file if it exists. + + This function attempts to erase the specified file. + No error is generated if the file does not already + exist. + + @param path The path to the file to erase. + + @param ec Set to the error, if any occurred. + + @tparam File A type meeting the requirements of @b File. + If this type is unspecified, @ref native_file is used. +*/ +template +inline +void +erase_file(path_type const& path, error_code& ec) +{ + native_file::erase(path, ec); + if(ec == errc::no_such_file_or_directory) + ec = {}; +} + +/** Erase a file without returnign an error. + + This function attempts to erase the specified file. + Any errors are ignored, including if the file does + not exist. + + @param path The path to the file to erase. + + @tparam File A type meeting the requirements of @b File. + If this type is unspecified, @ref native_file is used. +*/ +template +inline +void +erase_file(path_type const& path) +{ + error_code ec; + File::erase(path, ec); +} + +} // nudb + +#endif diff --git a/include/nudb/nudb.hpp b/include/nudb/nudb.hpp new file mode 100644 index 000000000..d62801d2d --- /dev/null +++ b/include/nudb/nudb.hpp @@ -0,0 +1,27 @@ +// +// Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef NUDB_HPP +#define NUDB_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif diff --git a/include/nudb/posix_file.hpp b/include/nudb/posix_file.hpp new file mode 100644 index 000000000..8d3b8e5b7 --- /dev/null +++ b/include/nudb/posix_file.hpp @@ -0,0 +1,228 @@ +// +// Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef NUDB_DETAIL_POSIX_FILE_HPP +#define NUDB_DETAIL_POSIX_FILE_HPP + +#include +#include +#include +#include +#include +#include + +#ifndef NUDB_POSIX_FILE +# ifdef _MSC_VER +# define NUDB_POSIX_FILE 0 +# else +# define NUDB_POSIX_FILE 1 +# endif +#endif + +#if NUDB_POSIX_FILE +# include +# include +# include +# include +# include +#endif + +#if NUDB_POSIX_FILE + +namespace nudb { + +class posix_file +{ + int fd_ = -1; + +public: + /// Constructor + posix_file() = default; + + /// Copy constructor (disallowed) + posix_file(posix_file const&) = delete; + + // Copy assignment (disallowed) + posix_file& operator=(posix_file const&) = delete; + + /** Destructor. + + If open, the file is closed. + */ + ~posix_file(); + + /** Move constructor. + + @note The state of the moved-from object is as if default constructed. + */ + posix_file(posix_file&&); + + /** Move assignment. + + @note The state of the moved-from object is as if default constructed. + */ + posix_file& + operator=(posix_file&& other); + + /// Returns `true` if the file is open. + bool + is_open() const + { + return fd_ != -1; + } + + /// Close the file if it is open. + void + close(); + + /** Create a new file. + + After the file is created, it is opened as if by `open(mode, path, ec)`. + + @par Requirements + + The file must not already exist, or else `errc::file_exists` + is returned. + + @param mode The open mode, which must be a valid @ref file_mode. + + @param path The path of the file to create. + + @param ec Set to the error, if any occurred. + */ + void + create(file_mode mode, path_type const& path, error_code& ec); + + /** Open a file. + + @par Requirements + + The file must not already be open. + + @param mode The open mode, which must be a valid @ref file_mode. + + @param path The path of the file to open. + + @param ec Set to the error, if any occurred. + */ + void + open(file_mode mode, path_type const& path, error_code& ec); + + /** Remove a file from the file system. + + It is not an error to attempt to erase a file that does not exist. + + @param path The path of the file to remove. + + @param ec Set to the error, if any occurred. + */ + static + void + erase(path_type const& path, error_code& ec); + + /** Return the size of the file. + + @par Requirements + + The file must be open. + + @param ec Set to the error, if any occurred. + + @return The size of the file, in bytes. + */ + std::uint64_t + size(error_code& ec) const; + + /** Read data from a location in the file. + + @par Requirements + + The file must be open. + + @param offset The position in the file to read from, + expressed as a byte offset from the beginning. + + @param buffer The location to store the data. + + @param bytes The number of bytes to read. + + @param ec Set to the error, if any occurred. + */ + void + read(std::uint64_t offset, + void* buffer, std::size_t bytes, error_code& ec); + + /** Write data to a location in the file. + + @par Requirements + + The file must be open with a mode allowing writes. + + @param offset The position in the file to write from, + expressed as a byte offset from the beginning. + + @param buffer The data the write. + + @param bytes The number of bytes to write. + + @param ec Set to the error, if any occurred. + */ + void + write(std::uint64_t offset, + void const* buffer, std::size_t bytes, error_code& ec); + + /** Perform a low level file synchronization. + + @par Requirements + + The file must be open with a mode allowing writes. + + @param ec Set to the error, if any occurred. + */ + void + sync(error_code& ec); + + /** Truncate the file at a specific size. + + @par Requirements + + The file must be open with a mode allowing writes. + + @param length The new file size. + + @param ec Set to the error, if any occurred. + */ + void + trunc(std::uint64_t length, error_code& ec); + +private: + static + void + err(int ev, error_code& ec) + { + ec = error_code{ev, system_category()}; + } + + static + void + last_err(error_code& ec) + { + err(errno, ec); + } + + static + std::pair + flags(file_mode mode); +}; + +} // nudb + +#include + +#endif + +#endif diff --git a/include/nudb/progress.hpp b/include/nudb/progress.hpp new file mode 100644 index 000000000..df417a0b2 --- /dev/null +++ b/include/nudb/progress.hpp @@ -0,0 +1,32 @@ +// +// Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef NUDB_PROGRESS_HPP +#define NUDB_PROGRESS_HPP + +namespace nudb { + +/** Progress function that does nothing. + + This type meets the requirements of @b Progress, + and does nothing when invoked. +*/ +struct +no_progress +{ + no_progress() = default; + + /// Called to indicate progress + void + operator()(std::uint64_t, std::uint64_t) const noexcept + { + }; +}; + +} // nudb + +#endif diff --git a/include/nudb/recover.hpp b/include/nudb/recover.hpp new file mode 100644 index 000000000..b6b69c1df --- /dev/null +++ b/include/nudb/recover.hpp @@ -0,0 +1,73 @@ +// +// Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef NUDB_RECOVER_HPP +#define NUDB_RECOVER_HPP + +#include +#include + +namespace nudb { + +/** Perform recovery on a database. + + This implements the recovery algorithm by rolling back + any partially committed data. If no log file is present, + the function does nothing. + + During the commit phase of a NuDB database, a log file + is generated with information that may be used to roll + back the results of a partial commit. This function + checks for the presence of a log file. If present, the + log file is replayed on the key and data files belonging + to the database, restoring the database to its state + before the partial commit. When @ref recover is + successful, it erases the log file. + + It is normally not necessary to call this function + directly, it is called automatically when a database is + opened in a call to @ref basic_store::open. Callers may + use this function to implement auxiliary tools for + manipulating the database. + + @par Template Parameters + + @tparam Hasher The hash function to use. This type must + meet the requirements of @b Hasher. The hash function + must be the same as that used to create the database, or + else an error is returned. + + @tparam File The type of file to use. Use the default of + @ref native_file unless customizing the file behavior. + + @param dat_path The path to the data file. + + @param key_path The path to the key file. + + @param log_path The path to the log file. + + @param args Optional parameters passed to File constructors. + + @param ec Set to the error, if any occurred. +*/ +template< + class Hasher, + class File = native_file, + class... Args> +void +recover( + path_type const& dat_path, + path_type const& key_path, + path_type const& log_path, + error_code& ec, + Args&&... args); + +} // nudb + +#include + +#endif diff --git a/include/nudb/rekey.hpp b/include/nudb/rekey.hpp new file mode 100644 index 000000000..429cd1ac8 --- /dev/null +++ b/include/nudb/rekey.hpp @@ -0,0 +1,110 @@ +// +// Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef NUDB_REKEY_HPP +#define NUDB_REKEY_HPP + +#include +#include +#include +#include + +namespace nudb { + +/** Create a new key file from a data file. + + This algorithm rebuilds a key file for the given data file. + It works efficiently by iterating the data file multiple times. + During the iteration, a contiguous block of the key file is + rendered in memory, then flushed to disk when the iteration is + complete. The size of this memory buffer is controlled by the + `bufferSize` parameter, larger is better. The algorithm works + the fastest when `bufferSize` is large enough to hold the entire + key file in memory; only a single iteration of the data file + is needed in this case. + + During the rekey, spill records may be appended to the data + file. If the rekey operation is abnormally terminated, this + would normally result in a corrupted data file. To prevent this, + the function creates a log file using the specified path so + that the database can be fixed in a subsequent call to + @ref recover. + + @note If a log file is already present, this function will + fail with @ref error::log_file_exists. + + @par Template Parameters + + @tparam Hasher The hash function to use. This type must + meet the requirements of @b Hasher. The hash function + must be the same as that used to create the database, or + else an error is returned. + + @tparam File The type of file to use. This type must meet + the requirements of @b File. + + @param dat_path The path to the data file. + + @param key_path The path to the key file. + + @param log_path The path to the log file. + + @param blockSize The size of a key file block. Larger + blocks hold more keys but require more I/O cycles per + operation. The ideal block size the largest size that + may be read in a single I/O cycle, and device dependent. + The return value of @ref block_size returns a suitable + value for the volume of a given path. + + @param loadFactor A number between zero and one + representing the average bucket occupancy (number of + items). A value of 0.5 is perfect. Lower numbers + waste space, and higher numbers produce negligible + savings at the cost of increased I/O cycles. + + @param itemCount The number of items in the data file. + + @param bufferSize The number of bytes to allocate for the buffer. + + @param ec Set to the error if any occurred. + + @param progress A function which will be called periodically + as the algorithm proceeds. The equivalent signature of the + progress function must be: + @code + void progress( + std::uint64_t amount, // Amount of work done so far + std::uint64_t total // Total amount of work to do + ); + @endcode + + @param args Optional arguments passed to @b File constructors. +*/ +template< + class Hasher, + class File, + class Progress, + class... Args +> +void +rekey( + path_type const& dat_path, + path_type const& key_path, + path_type const& log_path, + std::size_t blockSize, + float loadFactor, + std::uint64_t itemCount, + std::size_t bufferSize, + error_code& ec, + Progress&& progress, + Args&&... args); + +} // nudb + +#include + +#endif diff --git a/include/nudb/store.hpp b/include/nudb/store.hpp new file mode 100644 index 000000000..5853c7bea --- /dev/null +++ b/include/nudb/store.hpp @@ -0,0 +1,27 @@ +// +// Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef NUDB_STORE_HPP +#define NUDB_STORE_HPP + +#include +#include +#include + +namespace nudb { + +/** A key/value database. + + The @b Hasher used is is @ref xxhasher, which works very + well for almost all cases. The @b File is @ref native_file which + works on Windows and POSIX platforms. +*/ +using store = basic_store; + +} // nudb + +#endif diff --git a/include/nudb/type_traits.hpp b/include/nudb/type_traits.hpp new file mode 100644 index 000000000..f20c4d4c9 --- /dev/null +++ b/include/nudb/type_traits.hpp @@ -0,0 +1,63 @@ +// +// Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef NUDB_TYPE_TRAITS_HPP +#define NUDB_TYPE_TRAITS_HPP + +#include +#include + +namespace nudb { + +#if ! GENERATING_DOCS + +namespace detail { + +// Holds a full digest +using nhash_t = std::uint64_t; + +} // detail + +/** Holds a bucket index or bucket count. + + The maximum number of buckets in a key file is 2^32-1. +*/ +//using nbuck_t = std::uint32_t; +using nbuck_t = std::size_t; + +/** Holds a key index or count in bucket. + + A bucket is limited to 2^16-1 items. The practical + limit is lower, since a bucket cannot be larger than + the block size. +*/ +//using nkey_t = std::uint16_t; +using nkey_t = std::size_t; + +/** Holds a file size or offset. + + Operating system support for large files is required. + Practically, data files cannot exceed 2^48 since offsets + are stored as 48 bit unsigned values. +*/ +using noff_t = std::uint64_t; + +/** Holds a block, key, or value size. + + Block size is limited to 2^16 + + Key file blocks are limited to the block size. + + Value sizes are limited to 2^31-1. +*/ +using nsize_t = std::size_t; + +#endif + +} // nudb + +#endif diff --git a/include/nudb/verify.hpp b/include/nudb/verify.hpp new file mode 100644 index 000000000..23b12604d --- /dev/null +++ b/include/nudb/verify.hpp @@ -0,0 +1,200 @@ +// +// Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef NUDB_VERIFY_HPP +#define NUDB_VERIFY_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace nudb { + +/// Describes database statistics calculated by @ref verify. +struct verify_info +{ + /** Indicates the verify algorithm used. + + @li @b 0 Normal algorithm + @li @b 1 Fast algorith + */ + int algorithm; // 0 = normal, 1 = fast + + /// The path to the data file + path_type dat_path; + + /// The path to the key file + path_type key_path; + + /// The API version used to create the database + std::size_t version = 0; + + /// The unique identifier + std::uint64_t uid = 0; + + /// The application-defined constant + std::uint64_t appnum = 0; + + /// The size of each key, in bytes + nsize_t key_size = 0; + + /// The salt used in the key file + std::uint64_t salt = 0; + + /// The salt fingerprint + std::uint64_t pepper = 0; + + /// The block size used in the key file + nsize_t block_size = 0; + + /// The target load factor used in the key file + float load_factor = 0; + + /// The maximum number of keys each bucket can hold + nkey_t capacity = 0; + + /// The number of buckets in the key file + nbuck_t buckets = 0; + + /// The size of a bucket in bytes + nsize_t bucket_size = 0; + + /// The size of the key file + noff_t key_file_size = 0; + + /// The size of the data file + noff_t dat_file_size = 0; + + /// The number of keys found + std::uint64_t key_count = 0; + + /// The number of values found + std::uint64_t value_count = 0; + + /// The total number of bytes occupied by values + std::uint64_t value_bytes = 0; + + /// The number of spill records in use + std::uint64_t spill_count = 0; + + /// The total number of spill records + std::uint64_t spill_count_tot = 0; + + /// The number of bytes occupied by spill records in use + std::uint64_t spill_bytes = 0; + + /// The number of bytes occupied by all spill records + std::uint64_t spill_bytes_tot = 0; + + /// Average number of key file reads per fetch + float avg_fetch = 0; + + /// The fraction of the data file that is wasted + float waste = 0; + + /// The data amplification ratio + float overhead = 0; + + /// The measured bucket load fraction + float actual_load = 0; + + /// A histogram of the number of buckets having N spill records + std::array hist; + + /// Default constructor + verify_info() + { + hist.fill(0); + } +}; + +/** Verify consistency of the key and data files. + + This function opens the key and data files, and + performs the following checks on the contents: + + @li Data file header validity + + @li Key file header validity + + @li Data and key file header agreements + + @li Check that each value is contained in a bucket + + @li Check that each bucket item reflects a value + + @li Ensure no values with duplicate keys + + Undefined behavior results when verifying a database + that still has a log file. Use @ref recover on such + databases first. + + This function selects one of two algorithms to use, the + normal version, and a faster version that can take advantage + of a buffer of sufficient size. Depending on the value of + the bufferSize argument, the appropriate algorithm is chosen. + + A good value of bufferSize is one that is a large fraction + of the key file size. For example, 20% of the size of the + key file. Larger is better, with the highest usable value + depending on the size of the key file. If presented with + a buffer size that is too large to be of extra use, the + fast algorithm will simply allocate what it needs. + + @par Template Parameters + + @tparam Hasher The hash function to use. This type must + meet the requirements of @b HashFunction. The hash function + must be the same as that used to create the database, or + else an error is returned. + + @param info A structure which will be default constructed + inside this function, and filled in if the operation completes + successfully. If an error is indicated, the contents of this + variable are undefined. + + @param dat_path The path to the data file. + + @param key_path The path to the key file. + + @param bufferSize The number of bytes to allocate for the buffer. + If this number is too small, or zero, a slower algorithm will be + used that does not require a buffer. + + @param progress A function which will be called periodically + as the algorithm proceeds. The equivalent signature of the + progress function must be: + @code + void progress( + std::uint64_t amount, // Amount of work done so far + std::uint64_t total // Total amount of work to do + ); + @endcode + + @param ec Set to the error, if any occurred. +*/ +template +void +verify( + verify_info& info, + path_type const& dat_path, + path_type const& key_path, + std::size_t bufferSize, + Progress&& progress, + error_code& ec); + +} // nudb + +#include + +#endif diff --git a/include/nudb/version.hpp b/include/nudb/version.hpp new file mode 100644 index 000000000..9ccab1063 --- /dev/null +++ b/include/nudb/version.hpp @@ -0,0 +1,21 @@ +// +// Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef NUDB_VERSION_HPP +#define NUDB_VERSION_HPP + +// follows http://semver.org + +// NUDB_VERSION % 100 is the patch level +// NUDB_VERSION / 100 % 1000 is the minor version +// NUDB_VERSION / 100000 is the major version +// +#define NUDB_VERSION 100000 + +#define NUDB_VERSION_STRING "1.0.0-b6" + +#endif diff --git a/include/nudb/visit.hpp b/include/nudb/visit.hpp new file mode 100644 index 000000000..abb0c91a9 --- /dev/null +++ b/include/nudb/visit.hpp @@ -0,0 +1,63 @@ +// +// Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef NUDB_VISIT_HPP +#define NUDB_VISIT_HPP + +#include +#include + +namespace nudb { + +/** Visit each key/data pair in a data file. + + This function will open and iterate the contents of a + data file, invoking the callback for each key/value + pair found. Only a data file is necessary, the key + file may be omitted. + + @param path The path to the data file. + + @param callback A function which will be called with + each item found in the data file. The equivalent signature + of the callback must be: + @code + void callback( + void const* key, // A pointer to the item key + std::size_t key_size, // The size of the key (always the same) + void const* data, // A pointer to the item data + std::size_t data_size, // The size of the item data + error_code& ec // Indicates an error (out parameter) + ); + @endcode + If the callback sets ec to an error, the visit is terminated. + + @param progress A function which will be called periodically + as the algorithm proceeds. The equivalent signature of the + progress function must be: + @code + void progress( + std::uint64_t amount, // Amount of work done so far + std::uint64_t total // Total amount of work to do + ); + @endcode + + @param ec Set to the error, if any occurred. +*/ +template +void +visit( + path_type const& path, + Callback&& callback, + Progress&& progress, + error_code& ec); + +} // nudb + +#include + +#endif diff --git a/include/nudb/win32_file.hpp b/include/nudb/win32_file.hpp new file mode 100644 index 000000000..d225ae942 --- /dev/null +++ b/include/nudb/win32_file.hpp @@ -0,0 +1,246 @@ +// +// Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef NUDB_DETAIL_WIN32_FILE_HPP +#define NUDB_DETAIL_WIN32_FILE_HPP + +#include +#include +#include +#include +#include + +#ifndef NUDB_WIN32_FILE +# ifdef _MSC_VER +# define NUDB_WIN32_FILE 1 +# else +# define NUDB_WIN32_FILE 0 +# endif +#endif + +#if NUDB_WIN32_FILE +#pragma push_macro("NOMINMAX") +#pragma push_macro("UNICODE") +#pragma push_macro("STRICT") +# ifndef NOMINMAX +# define NOMINMAX +# endif +# ifndef UNICODE +# define UNICODE +# endif +# ifndef STRICT +# define STRICT +# endif +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +# endif +# include +#pragma pop_macro("STRICT") +#pragma pop_macro("UNICODE") +#pragma pop_macro("NOMINMAX") +#endif + +#if NUDB_WIN32_FILE + +namespace nudb { + +/** A descriptor to a Win32 file. + + This class provides a Win32 implementation of the @b File + concept. +*/ +class win32_file +{ + HANDLE hf_ = INVALID_HANDLE_VALUE; + +public: + /// Constructor + win32_file() = default; + + /// Copy constructor (disallowed) + win32_file(win32_file const&) = delete; + + // Copy assignment (disallowed) + win32_file& operator=(win32_file const&) = delete; + + /** Destructor. + + If open, the file is closed. + */ + ~win32_file(); + + /** Move constructor. + + @note The state of the moved-from object is as if default constructed. + */ + win32_file(win32_file&&); + + /** Move assignment. + + @note The state of the moved-from object is as if default constructed. + */ + win32_file& + operator=(win32_file&& other); + + /// Returns `true` if the file is open. + bool + is_open() const + { + return hf_ != INVALID_HANDLE_VALUE; + } + + /// Close the file if it is open. + void + close(); + + /** Create a new file. + + After the file is created, it is opened as if by `open(mode, path, ec)`. + + @par Requirements + + The file must not already exist, or else `errc::file_exists` + is returned. + + @param mode The open mode, which must be a valid @ref file_mode. + + @param path The path of the file to create. + + @param ec Set to the error, if any occurred. + */ + void + create(file_mode mode, path_type const& path, error_code& ec); + + /** Open a file. + + @par Requirements + + The file must not already be open. + + @param mode The open mode, which must be a valid @ref file_mode. + + @param path The path of the file to open. + + @param ec Set to the error, if any occurred. + */ + void + open(file_mode mode, path_type const& path, error_code& ec); + + /** Remove a file from the file system. + + It is not an error to attempt to erase a file that does not exist. + + @param path The path of the file to remove. + + @param ec Set to the error, if any occurred. + */ + static + void + erase(path_type const& path, error_code& ec); + + /** Return the size of the file. + + @par Requirements + + The file must be open. + + @param ec Set to the error, if any occurred. + + @return The size of the file, in bytes. + */ + std::uint64_t + size(error_code& ec) const; + + /** Read data from a location in the file. + + @par Requirements + + The file must be open. + + @param offset The position in the file to read from, + expressed as a byte offset from the beginning. + + @param buffer The location to store the data. + + @param bytes The number of bytes to read. + + @param ec Set to the error, if any occurred. + */ + void + read(std::uint64_t offset, + void* buffer, std::size_t bytes, error_code& ec); + + /** Write data to a location in the file. + + @par Requirements + + The file must be open with a mode allowing writes. + + @param offset The position in the file to write from, + expressed as a byte offset from the beginning. + + @param buffer The data the write. + + @param bytes The number of bytes to write. + + @param ec Set to the error, if any occurred. + */ + void + write(std::uint64_t offset, + void const* buffer, std::size_t bytes, error_code& ec); + + /** Perform a low level file synchronization. + + @par Requirements + + The file must be open with a mode allowing writes. + + @param ec Set to the error, if any occurred. + */ + void + sync(error_code& ec); + + /** Truncate the file at a specific size. + + @par Requirements + + The file must be open with a mode allowing writes. + + @param length The new file size. + + @param ec Set to the error, if any occurred. + */ + void + trunc(std::uint64_t length, error_code& ec); + +private: + static + void + err(DWORD dwError, error_code& ec) + { + ec = error_code{static_cast(dwError), system_category()}; + } + + static + void + last_err(error_code& ec) + { + err(::GetLastError(), ec); + } + + static + std::pair + flags(file_mode mode); +}; + +} // nudb + +#include + +#endif + +#endif diff --git a/include/nudb/xxhasher.hpp b/include/nudb/xxhasher.hpp new file mode 100644 index 000000000..5fe1e93c2 --- /dev/null +++ b/include/nudb/xxhasher.hpp @@ -0,0 +1,45 @@ +// +// Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef NUDB_XXHASHER_HPP +#define NUDB_XXHASHER_HPP + +#include +#include +#include +#include + +namespace nudb { + +/** A Hasher that uses xxHash. + + This object meets the requirements of @b Hasher. It is + the default hash function unless otherwise specified. +*/ +class xxhasher +{ + std::uint64_t seed_; + +public: + using result_type = std::uint64_t; + + explicit + xxhasher(std::uint64_t seed) + : seed_(seed) + { + } + + result_type + operator()(void const* data, std::size_t bytes) const noexcept + { + return detail::XXH64(data, bytes, seed_); + } +}; + +} // nudb + +#endif diff --git a/scripts/blacklist.supp b/scripts/blacklist.supp new file mode 100644 index 000000000..e161cb10c --- /dev/null +++ b/scripts/blacklist.supp @@ -0,0 +1,38 @@ +# Remember that this blacklist file is GLOBAL to all sanitizers +# Be therefore extremely careful when considering to add a sanitizer +# filter here instead of using a runtime suppression +# +# Remember also that filters here quite literally completely +# remove instrumentation altogether, so filtering here means +# that sanitizers such as tsan will false positive on problems +# introduced by code filtered here. +# +# The main use for this file is ubsan, as it's the only sanitizer +# without a runtime suppression facility. +# +# Be ESPECIALLY careful when filtering out entire source files! +# Try if at all possible to filter only functions using fun:regex +# Remember you must use mangled symbol names with fun:regex + +#### Compile time filters for ubsan #### + +## The well known ubsan failure in libstdc++ extant for years :) +# Line 96:24: runtime error: load of value 4294967221, which is not a valid value for type 'std::_Ios_Fmtflags' +fun:*_Ios_Fmtflags* + +# boost/any.hpp:259:16: runtime error: downcast of address 0x000004392e70 which does not point to an object of type 'any::holder' +fun:*any_cast* + +# boost/lexical_cast.hpp:1625:43: runtime error: downcast of address 0x7fbb4fffbce8 which does not point to an object of type 'buffer_t' (aka 'parser_buf >, char>') +fun:*shl_input_streamable* + + + + +#### Compile time filters for asan #### + + +#### Compile time filters for msan #### + + +#### Compile time filters for tsan #### diff --git a/scripts/build-and-test.sh b/scripts/build-and-test.sh new file mode 100755 index 000000000..c7aa08a71 --- /dev/null +++ b/scripts/build-and-test.sh @@ -0,0 +1,150 @@ +#!/usr/bin/env bash + +set -euxo pipefail +# The above bash options do the following: + +# -e When this option is on, if a simple command fails for any of the reasons +# listed in Consequences of Shell Errors or returns an exit status value >0, +# and is not part of the compound list following a while, until, or if +# keyword, and is not a part of an AND or OR list, and is not a pipeline +# preceded by the ! reserved word, then the shell shall immediately exit. +# -u The shell shall write a message to standard error when it tries to expand a +# variable that is not set and immediately exit. An interactive shell shall +# not exit. +# -x The shell shall write to standard error a trace for each command after it +# expands the command and before it executes it. It is unspecified +# whether the command that turns tracing off is traced. +# -o pipefail +# Pipelines fail on the first command which fails instead of dying later on +# down the pipeline. + +shopt -s globstar + +################################## ENVIRONMENT ################################# + +# If not CI, then set some defaults +if [[ -z ${CI:-} ]]; then + : ${TRAVIS_BRANCH:=feature} + : ${CC:=gcc} + : ${ADDRESS_MODEL:=64} + : ${VARIANT:=debug} + # If running locally we assume we have lcov/valgrind on PATH +else + export PATH=${VALGRIND_ROOT}/bin:${LCOV_ROOT}/usr/bin:${PATH} +fi + +MAIN_BRANCH=0 +# For builds not triggered by a pull request TRAVIS_BRANCH is the name of the +# branch currently being built; whereas for builds triggered by a pull request +# it is the name of the branch targeted by the pull request (in many cases this +# will be master). +if [[ ${TRAVIS_BRANCH} == master || ${TRAVIS_BRANCH} == develop ]]; then + MAIN_BRANCH=1 +fi + +num_jobs=1 +if [[ $(uname) == Darwin ]]; then + num_jobs=$(sysctl -n hw.physicalcpu) +elif [[ $(uname -s) == Linux ]]; then + # CircleCI returns 32 phys procs, but 2 virt proc + num_proc_units=$(nproc) + # Physical cores + num_jobs=$(lscpu -p | grep -v '^#' | sort -u -t, -k 2,4 | wc -l) + if ((${num_proc_units} < ${num_jobs})); then + num_jobs=${num_proc_units} + fi +fi + +echo "using toolset: ${CC}" +echo "using variant: ${VARIANT}" +echo "using address-model: ${ADDRESS_MODEL}" +echo "using PATH: ${PATH}" +echo "using MAIN_BRANCH: ${MAIN_BRANCH}" +echo "using BOOST_ROOT: ${BOOST_ROOT}" + +#################################### HELPERS ################################### + +function run_tests_with_debugger { + for x in bin/**/${VARIANT}/**/test-all; do + scripts/run-with-debugger.sh "${x}" + done +} + +function run_tests { + for x in bin/**/${VARIANT}/**/test-all; do + ${x} + done +} + +function run_benchmark { + for x in bin/**/${VARIANT}/**/bench; do + ${x} --inserts=10000 + done +} + +function run_tests_with_valgrind { + for x in bin/**/${VARIANT}/**/test-all; do + # TODO --max-stackframe=8388608 + # see: https://travis-ci.org/vinniefalco/Beast/jobs/132486245 + valgrind --error-exitcode=1 "${x}" + done +} + +function build_bjam { + ${BOOST_ROOT}/bjam toolset=${CC} \ + variant=${VARIANT} \ + address-model=${ADDRESS_MODEL} \ + -j${num_jobs} +} + +function build_cmake { + mkdir -p build + pushd build > /dev/null + cmake -DVARIANT=${VARIANT} .. + make -j${num_jobs} + mkdir -p ../bin/${VARIANT} + find . -executable -type f -exec cp {} ../bin/${VARIANT}/. \; + popd > /dev/null +} + +##################################### BUILD #################################### + +if [[ ${BUILD_SYSTEM:-} == cmake ]]; then + build_cmake +else + build_bjam +fi + +##################################### TESTS #################################### + +if [[ ${VARIANT} == coverage ]]; then + find . -name "*.gcda" | xargs rm -f + rm *.info -f + # Create baseline coverage data file + lcov --no-external -c -i -d . -o baseline.info > /dev/null + + # Perform test + if [[ ${MAIN_BRANCH} == 1 ]]; then + run_tests_with_valgrind + else + run_tests + fi + + # Create test coverage data file + lcov --no-external -c -d . -o testrun.info > /dev/null + + # Combine baseline and test coverage data + lcov -a baseline.info -a testrun.info -o lcov-all.info > /dev/null + + # Extract only include/*, and don\'t report on examples or test + lcov -e "lcov-all.info" "${PWD}/include/nudb/*" -o lcov.info > /dev/null + + ~/.local/bin/codecov -X gcov + cat lcov.info | node_modules/.bin/coveralls + + # Clean up these stragglers so BOOST_ROOT cache is clean + find ${BOOST_ROOT}/bin.v2 -name "*.gcda" | xargs rm -f +else + run_tests_with_debugger + run_benchmark +fi diff --git a/scripts/install-boost.sh b/scripts/install-boost.sh new file mode 100755 index 000000000..8365c2d54 --- /dev/null +++ b/scripts/install-boost.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash +# Assumptions: +# 1) BOOST_ROOT and BOOST_URL are already defined, +# and contain valid values. +# 2) The last namepart of BOOST_ROOT matches the +# folder name internal to boost's .tar.gz +# When testing you can force a boost build by clearing travis caches: +# https://travis-ci.org/ripple/rippled/caches +set -eu +if [ ! -d "$BOOST_ROOT/lib" ] +then + wget $BOOST_URL -O /tmp/boost.tar.gz + cd `dirname $BOOST_ROOT` + rm -fr ${BOOST_ROOT} + tar xzf /tmp/boost.tar.gz + + params="define=_GLIBCXX_USE_CXX11_ABI=0 \ + address-model=$ADDRESS_MODEL --with-program_options \ + --with-system --with-coroutine --with-filesystem" + cd $BOOST_ROOT && \ + ./bootstrap.sh --prefix=$BOOST_ROOT && \ + ./b2 -d1 $params && \ + ./b2 -d0 $params install +else + echo "Using cached boost at $BOOST_ROOT" +fi + diff --git a/scripts/install-dependencies.sh b/scripts/install-dependencies.sh new file mode 100755 index 000000000..5c26b26a3 --- /dev/null +++ b/scripts/install-dependencies.sh @@ -0,0 +1,90 @@ +#!/usr/bin/env bash + +set -euxo pipefail +# The above bash options do the following: + +# -e When this option is on, if a simple command fails for any of the reasons +# listed in Consequences of Shell Errors or returns an exit status value >0, +# and is not part of the compound list following a while, until, or if +# keyword, and is not a part of an AND or OR list, and is not a pipeline +# preceded by the ! reserved word, then the shell shall immediately exit. +# -u The shell shall write a message to standard error when it tries to expand a +# variable that is not set and immediately exit. An interactive shell shall +# not exit. +# -x The shell shall write to standard error a trace for each command after it +# expands the command and before it executes it. It is unspecified +# whether the command that turns tracing off is traced. +# -o pipefail +# Pipelines fail on the first command which fails instead of dying later on +# down the pipeline. + +HERE=${PWD} + +# Override gcc version to $GCC_VER. +# Put an appropriate symlink at the front of the path. +mkdir -v ${HOME}/bin +for g in gcc g++ gcov gcc-ar gcc-nm gcc-ranlib +do + test -x $( type -p ${g}-${GCC_VER} ) + ln -sv $(type -p ${g}-${GCC_VER}) $HOME/bin/${g} +done + +if [[ -n ${CLANG_VER:-} ]]; then + # There are cases where the directory exists, but the exe is not available. + # Use this workaround for now. + if [[ ! -x llvm-${LLVM_VERSION}/bin/llvm-config ]] && [[ -d llvm-${LLVM_VERSION} ]]; then + rm -fr llvm-${LLVM_VERSION} + fi + if [[ ! -d llvm-${LLVM_VERSION} ]]; then + mkdir llvm-${LLVM_VERSION} + LLVM_URL="http://llvm.org/releases/${LLVM_VERSION}/clang+llvm-${LLVM_VERSION}-x86_64-linux-gnu-ubuntu-14.04.tar.xz" + wget -O - ${LLVM_URL} | tar -Jxvf - --strip 1 -C llvm-${LLVM_VERSION} + fi + llvm-${LLVM_VERSION}/bin/llvm-config --version; + export LLVM_CONFIG="llvm-${LLVM_VERSION}/bin/llvm-config"; +fi + +# There are cases where the directory exists, but the exe is not available. +# Use this workaround for now. +if [[ ! -x cmake/bin/cmake && -d cmake ]]; then + rm -fr cmake +fi +if [[ ! -d cmake && ${BUILD_SYSTEM:-} == cmake ]]; then + CMAKE_URL="http://www.cmake.org/files/v3.5/cmake-3.5.2-Linux-x86_64.tar.gz" + mkdir cmake && wget --no-check-certificate -O - ${CMAKE_URL} | tar --strip-components=1 -xz -C cmake +fi + +# NOTE, changed from PWD -> HOME +export PATH=${HOME}/bin:${PATH} + +# What versions are we ACTUALLY running? +if [ -x $HOME/bin/g++ ]; then + ${HOME}/bin/g++ -v +fi +if [ -x ${HOME}/bin/clang ]; then + ${HOME}/bin/clang -v +fi +# Avoid `spurious errors` caused by ~/.npm permission issues +# Does it already exist? Who owns? What permissions? +ls -lah ~/.npm || mkdir ~/.npm +# Make sure we own it +chown -Rc ${USER} ~/.npm +# We use this so we can filter the subtrees from our coverage report +pip install --user https://github.com/codecov/codecov-python/archive/master.zip + +bash scripts/install-boost.sh +bash scripts/install-valgrind.sh + +# Install lcov +# Download the archive +wget http://downloads.sourceforge.net/ltp/lcov-1.12.tar.gz +# Extract to ~/lcov-1.12 +tar xfvz lcov-1.12.tar.gz -C ${HOME} +# Set install path +mkdir -p ${LCOV_ROOT} +cd ${HOME}/lcov-1.12 && make install PREFIX=${LCOV_ROOT} + +# Install coveralls reporter +cd ${HERE} +mkdir -p node_modules +npm install coveralls diff --git a/scripts/install-valgrind.sh b/scripts/install-valgrind.sh new file mode 100755 index 000000000..943eb8673 --- /dev/null +++ b/scripts/install-valgrind.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash +# Assumptions: +# 1) VALGRIND_ROOT is already defined, and contains a valid values +set -eu +if [ ! -d "$VALGRIND_ROOT/bin" ] +then + # These are specified in the addons/apt section of .travis.yml + # sudo apt-get install subversion automake autotools-dev libc6-dbg + export PATH=$PATH:$VALGRIND_ROOT/bin + svn co svn://svn.valgrind.org/valgrind/trunk valgrind-co + cd valgrind-co + ./autogen.sh + ./configure --prefix=$VALGRIND_ROOT + make + make install + # test it + valgrind ls -l +else + echo "Using cached valgrind at $VALGRIND_ROOT" +fi diff --git a/scripts/run-with-debugger.sh b/scripts/run-with-debugger.sh new file mode 100755 index 000000000..6a8b55d85 --- /dev/null +++ b/scripts/run-with-debugger.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash +set -eu + +if [[ $(uname) == "Darwin" ]]; then + # -o runs after loading the binary + # -k runs after any crash + # We use a ghetto appromixation of --return-child-result, exiting with + # 1 on a crash + lldb --batch \ + -o 'run' \ + -k 'thread backtrace all' \ + -k 'script import os; os._exit(1)' \ + $@ +else + gdb --silent \ + --batch \ + --return-child-result \ + -ex="set print thread-events off" \ + -ex=run \ + -ex="thread apply all bt full" \ + --args $@ +fi diff --git a/scripts/run-with-gdb.sh b/scripts/run-with-gdb.sh new file mode 100755 index 000000000..f7ff0bc72 --- /dev/null +++ b/scripts/run-with-gdb.sh @@ -0,0 +1,9 @@ +#!/bin/bash -u +set -e +gdb --silent \ + --batch \ + --return-child-result \ + -ex="set print thread-events off" \ + -ex=run \ + -ex="thread apply all bt full" \ + --args $@ diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100644 index 000000000..628c618f2 --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,38 @@ +# Part of nudb + +GroupSources(test "/") +GroupSources(include/nudb nudb) +GroupSources(extras/nudb extras) +GroupSources(extras/beast/include/beast beast) +GroupSources(extras/beast/extras/beast beast) + +add_executable(test-all + ${EXTRAS_INCLUDES} + ${NUDB_INCLUDES} + ${BEAST_INCLUDES} + ../extras/beast/extras/beast/unit_test/main.cpp + basic_store.cpp + buffer.cpp + callgrind_test.cpp + concepts.cpp + create.cpp + error.cpp + file.cpp + native_file.cpp + posix_file.cpp + recover.cpp + rekey.cpp + store.cpp + type_traits.cpp + verify.cpp + version.cpp + visit.cpp + win32_file.cpp + xxhasher.cpp +) + +if (WIN32) + target_link_libraries(test-all ${Boost_LIBRARIES}) +else () + target_link_libraries(test-all ${Boost_LIBRARIES} rt Threads::Threads) +endif () diff --git a/test/Jamfile b/test/Jamfile new file mode 100644 index 000000000..41bfa9736 --- /dev/null +++ b/test/Jamfile @@ -0,0 +1,30 @@ +# +# Copyright (c) 2013-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +# +# Distributed under the Boost Software License, Version 1.0. (See accompanying +# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +# + +import os ; + +unit-test test-all : + ../extras/beast/extras/beast/unit_test/main.cpp + basic_store.cpp + buffer.cpp + callgrind_test.cpp + concepts.cpp + create.cpp + error.cpp + file.cpp + native_file.cpp + posix_file.cpp + recover.cpp + rekey.cpp + store.cpp + type_traits.cpp + verify.cpp + version.cpp + visit.cpp + win32_file.cpp + xxhasher.cpp + ; diff --git a/test/basic_store.cpp b/test/basic_store.cpp new file mode 100644 index 000000000..38892ee37 --- /dev/null +++ b/test/basic_store.cpp @@ -0,0 +1,250 @@ +// +// Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +// Test that header file is self-contained +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace nudb { + +namespace detail { + +static_assert(!std::is_copy_constructible {}, ""); +static_assert(!std::is_copy_assignable {}, ""); +static_assert( std::is_move_constructible {}, ""); +static_assert(!std::is_move_assignable {}, ""); + +static_assert(!std::is_copy_constructible {}, ""); +static_assert(!std::is_copy_assignable {}, ""); +static_assert( std::is_move_constructible {}, ""); +static_assert(!std::is_move_assignable {}, ""); + +static_assert(!std::is_copy_constructible {}, ""); +static_assert(!std::is_copy_assignable {}, ""); +static_assert( std::is_move_constructible {}, ""); +static_assert(!std::is_move_assignable {}, ""); + +} // detail + +namespace test { + +class basic_store_test : public beast::unit_test::suite +{ +public: + void + test_members() + { + std::size_t const keySize = 4; + std::size_t const blockSize = 4096; + float loadFactor = 0.5f; + + error_code ec; + test_store ts{keySize, blockSize, loadFactor}; + + // Files not found + ts.open(ec); + if(! BEAST_EXPECTS(ec == + errc::no_such_file_or_directory, ec.message())) + return; + ec = {}; + ts.create(ec); + if(! BEAST_EXPECTS(! ec, ec.message())) + return; + ts.open(ec); + if(! BEAST_EXPECTS(! ec, ec.message())) + return; + BEAST_EXPECT(ts.db.dat_path() == ts.dp); + BEAST_EXPECT(ts.db.key_path() == ts.kp); + BEAST_EXPECT(ts.db.log_path() == ts.lp); + BEAST_EXPECT(ts.db.appnum() == ts.appnum); + BEAST_EXPECT(ts.db.key_size() == ts.keySize); + BEAST_EXPECT(ts.db.block_size() == ts.blockSize); + } + + // Inserts a bunch of values then fetches them + void + do_insert_fetch( + std::size_t N, + std::size_t keySize, + std::size_t blockSize, + float loadFactor, + bool sleep) + { + testcase << + "N=" << N << ", " + "keySize=" << keySize << ", " + "blockSize=" << blockSize; + error_code ec; + test_store ts{keySize, blockSize, loadFactor}; + ts.create(ec); + if(! BEAST_EXPECTS(! ec, ec.message())) + return; + ts.open(ec); + if(! BEAST_EXPECTS(! ec, ec.message())) + return; + // Insert + for(std::size_t n = 0; n < N; ++n) + { + auto const item = ts[n]; + ts.db.insert(item.key, item.data, item.size, ec); + if(! BEAST_EXPECTS(! ec, ec.message())) + return; + } + // Fetch + for(std::size_t n = 0; n < N; ++n) + { + auto const item = ts[n]; + ts.db.fetch(item.key, + [&](void const* data, std::size_t size) + { + if(! BEAST_EXPECT(size == item.size)) + return; + BEAST_EXPECT( + std::memcmp(data, item.data, size) == 0); + }, ec); + if(! BEAST_EXPECTS(! ec, ec.message())) + return; + } + // Insert Duplicate + for(std::size_t n = 0; n < N; ++n) + { + auto const item = ts[n]; + ts.db.insert(item.key, item.data, item.size, ec); + if(! BEAST_EXPECTS( + ec == error::key_exists, ec.message())) + return; + ec = {}; + } + // Insert and Fetch + if(keySize > 1) + { + for(std::size_t n = 0; n < N; ++n) + { + auto item = ts[n]; + ts.db.fetch(item.key, + [&](void const* data, std::size_t size) + { + if(! BEAST_EXPECT(size == item.size)) + return; + BEAST_EXPECT( + std::memcmp(data, item.data, size) == 0); + }, ec); + if(! BEAST_EXPECTS(! ec, ec.message())) + return; + item = ts[N + n]; + ts.db.insert(item.key, item.data, item.size, ec); + if(! BEAST_EXPECTS(! ec, ec.message())) + return; + ts.db.fetch(item.key, + [&](void const* data, std::size_t size) + { + if(! BEAST_EXPECT(size == item.size)) + return; + BEAST_EXPECT( + std::memcmp(data, item.data, size) == 0); + }, ec); + if(! BEAST_EXPECTS(! ec, ec.message())) + return; + } + } + if(sleep) + { + // Make sure we run periodic activity + std::this_thread::sleep_for( + std::chrono::milliseconds{3000}); + } + ts.close(ec); + if(! BEAST_EXPECTS(! ec, ec.message())) + return; + } + + // Perform insert/fetch test across a range of parameters + void + test_insert_fetch() + { + for(auto const keySize : { + 1, 2, 3, 31, 32, 33, 63, 64, 65, 95, 96, 97 }) + { + std::size_t N; + std::size_t constexpr blockSize = 4096; + float loadFactor = 0.95f; + switch(keySize) + { + case 1: N = 10; break; + case 2: N = 100; break; + case 3: N = 250; break; + default: + N = 5000; + break; + }; + do_insert_fetch(N, keySize, blockSize, loadFactor, + keySize == 97); + } + } + + void + test_bulk_insert(std::size_t N, std::size_t keySize, + std::size_t blockSize, float loadFactor) + { + testcase << + "bulk_insert N=" << N << ", " + "keySize=" << keySize << ", " + "blockSize=" << blockSize; + error_code ec; + test_store ts{keySize, blockSize, loadFactor}; + ts.create(ec); + if(! BEAST_EXPECTS(! ec, ec.message())) + return; + ts.open(ec); + if(! BEAST_EXPECTS(! ec, ec.message())) + return; + // Insert + for(std::size_t n = 0; n < N; ++n) + { + auto const item = ts[n]; + ts.db.insert(item.key, item.data, item.size, ec); + if(! BEAST_EXPECTS(! ec, ec.message())) + return; + } + ts.close(ec); + if(! BEAST_EXPECTS(! ec, ec.message())) + return; + verify_info info; + verify(info, ts.dp, ts.kp, + 64 * 1024 * 1024 , no_progress{}, ec); + if(! BEAST_EXPECTS(! ec, ec.message())) + return; + log << info; + } + + void + run() override + { +#if 1 + test_members(); + test_insert_fetch(); +#else + // bulk-insert performance test + test_bulk_insert(10000000, 8, 4096, 0.5f); +#endif + } +}; + +BEAST_DEFINE_TESTSUITE(basic_store, test, nudb); + +} // test +} // nudb + diff --git a/test/buffer.cpp b/test/buffer.cpp new file mode 100644 index 000000000..e86a5688e --- /dev/null +++ b/test/buffer.cpp @@ -0,0 +1,77 @@ +// +// Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +// Test that header file is self-contained +#include + +#include +#include + +namespace nudb { +namespace test { + +class buffer_test : public beast::unit_test::suite +{ +public: + void + run() + { + using buffer = nudb::detail::buffer; + static_assert(std::is_default_constructible::value, ""); +#if 0 + static_assert(std::is_copy_constructible::value, ""); + static_assert(std::is_copy_assignable::value, ""); +#else + static_assert(! std::is_copy_constructible::value, ""); + static_assert(! std::is_copy_assignable::value, ""); +#endif + static_assert(std::is_move_constructible::value, ""); + static_assert(std::is_move_assignable::value, ""); + + { + buffer b; + } + { + buffer b1(1024); + BEAST_EXPECT(b1.size() == 1024); + buffer b2(std::move(b1)); + BEAST_EXPECT(b1.size() == 0); + BEAST_EXPECT(b2.size() == 1024); + } + { + buffer b1(1024); + BEAST_EXPECT(b1.size() == 1024); + buffer b2; + b2 = std::move(b1); + BEAST_EXPECT(b1.size() == 0); + BEAST_EXPECT(b2.size() == 1024); + } + +#if 0 + { + buffer b1(1024); + BEAST_EXPECT(b1.size() == 1024); + buffer b2(b1); + BEAST_EXPECT(b1.size() == 1024); + BEAST_EXPECT(b2.size() == 1024); + } + { + buffer b1(1024); + BEAST_EXPECT(b1.size() == 1024); + buffer b2; + b2 = b1; + BEAST_EXPECT(b1.size() == 1024); + BEAST_EXPECT(b2.size() == 1024); + } +#endif + } +}; + +BEAST_DEFINE_TESTSUITE(buffer, test, nudb); + +} // test +} // nudb diff --git a/test/callgrind_test.cpp b/test/callgrind_test.cpp new file mode 100644 index 000000000..c10644ea9 --- /dev/null +++ b/test/callgrind_test.cpp @@ -0,0 +1,92 @@ +// +// Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#include +#include +#include +#include +#include +#include +#include + +namespace nudb { +namespace test { + +// This test is designed for callgrind runs to find hotspots + +class callgrind_test : public beast::unit_test::suite +{ +public: + // Creates and opens a database, performs a bunch + // of inserts, then alternates fetching all the keys + // with keys not present. + // + void + testCallgrind(std::size_t N) + { + using key_type = std::uint64_t; + std::size_t const blockSize = 4096; + float const loadFactor = 0.5; + + error_code ec; + test_store ts{sizeof(key_type), blockSize, loadFactor}; + ts.create(ec); + if(! BEAST_EXPECTS(! ec, ec.message())) + return; + ts.open(ec); + if(! BEAST_EXPECTS(! ec, ec.message())) + return; + for(std::size_t i = 0; i < N; ++i) + { + auto const item = ts[i]; + ts.db.insert(item.key, item.data, item.size, ec); + if(! BEAST_EXPECTS(! ec, ec.message())) + return; + } + Buffer b; + for(std::size_t i = 0; i < N * 2; ++i) + { + if(! (i%2)) + { + auto const item = ts[i/2]; + ts.db.fetch(item.key, b, ec); + if(! BEAST_EXPECTS(! ec, ec.message())) + return; + if(! BEAST_EXPECT(b.size() == item.size)) + return; + if(! BEAST_EXPECT(std::memcmp(b.data(), + item.data, item.size) == 0)) + return; + } + else + { + auto const item = ts[N + i/2]; + ts.db.fetch(item.key, b, ec); + if(! BEAST_EXPECTS(ec == + error::key_not_found, ec.message())) + return; + ec = {}; + } + } + ts.close(ec); + if(! BEAST_EXPECTS(! ec, ec.message())) + return; + } + + void run() + { + // higher numbers, more pain + std::size_t constexpr N = 100000; + + testCallgrind(N); + } +}; + +BEAST_DEFINE_TESTSUITE(callgrind, test, nudb); + +} // test +} // nudb diff --git a/test/concepts.cpp b/test/concepts.cpp new file mode 100644 index 000000000..34dbd74ab --- /dev/null +++ b/test/concepts.cpp @@ -0,0 +1,9 @@ +// +// Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +// Test that header file is self-contained +#include diff --git a/test/create.cpp b/test/create.cpp new file mode 100644 index 000000000..2762908c9 --- /dev/null +++ b/test/create.cpp @@ -0,0 +1,49 @@ +// +// Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +// Test that header file is self-contained +#include + +#include +#include +#include + +namespace nudb { +namespace test { + +class create_test : public beast::unit_test::suite +{ +public: + void + test_create() + { + std::size_t const keySize = 8; + std::size_t const blockSize = 256; + float const loadFactor = 0.5f; + + error_code ec; + test_store ts{keySize, blockSize, loadFactor}; + ts.create(ec); + if(! BEAST_EXPECTS(! ec, ec.message())) + return; + ts.create(ec); + if(! BEAST_EXPECTS( + ec == errc::file_exists, ec.message())) + return; + } + + void + run() override + { + test_create(); + } +}; + +BEAST_DEFINE_TESTSUITE(create, test, nudb); + +} // test +} // nudb diff --git a/test/error.cpp b/test/error.cpp new file mode 100644 index 000000000..ba73bc96f --- /dev/null +++ b/test/error.cpp @@ -0,0 +1,83 @@ +// +// Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +// Test that header file is self-contained +#include + +#include + +namespace nudb { +namespace test { + +class error_test : public beast::unit_test::suite +{ +public: + void check(char const* name, error ev) + { + auto const ec = make_error_code(ev); + BEAST_EXPECT(std::string{ec.category().name()} == name); + BEAST_EXPECT(! ec.message().empty()); + BEAST_EXPECT(std::addressof(ec.category()) == + std::addressof(nudb_category())); + BEAST_EXPECT(nudb_category().equivalent(static_cast(ev), + ec.category().default_error_condition(static_cast(ev)))); + BEAST_EXPECT(nudb_category().equivalent( + ec, static_cast(ev))); + } + + void run() override + { + nudb_category().message(0); + nudb_category().message(99999); + check("nudb", error::success); + check("nudb", error::key_not_found); + check("nudb", error::key_exists); + check("nudb", error::short_read); + check("nudb", error::log_file_exists); + check("nudb", error::no_key_file); + check("nudb", error::too_many_buckets); + check("nudb", error::not_data_file); + check("nudb", error::not_key_file); + check("nudb", error::not_log_file); + check("nudb", error::different_version); + check("nudb", error::invalid_key_size); + check("nudb", error::invalid_block_size); + check("nudb", error::short_key_file); + check("nudb", error::short_bucket); + check("nudb", error::short_spill); + check("nudb", error::short_data_record); + check("nudb", error::short_value); + check("nudb", error::hash_mismatch); + check("nudb", error::invalid_load_factor); + check("nudb", error::invalid_capacity); + check("nudb", error::invalid_bucket_count); + check("nudb", error::invalid_bucket_size); + check("nudb", error::incomplete_data_file_header); + check("nudb", error::incomplete_key_file_header); + check("nudb", error::invalid_log_record); + check("nudb", error::invalid_log_spill); + check("nudb", error::invalid_log_offset); + check("nudb", error::invalid_log_index); + check("nudb", error::invalid_spill_size); + check("nudb", error::uid_mismatch); + check("nudb", error::appnum_mismatch); + check("nudb", error::key_size_mismatch); + check("nudb", error::salt_mismatch); + check("nudb", error::pepper_mismatch); + check("nudb", error::block_size_mismatch); + check("nudb", error::orphaned_value); + check("nudb", error::missing_value); + check("nudb", error::size_mismatch); + check("nudb", error::duplicate_value); + } +}; + +BEAST_DEFINE_TESTSUITE(error, test, nudb); + +} // test +} // nudb + diff --git a/test/file.cpp b/test/file.cpp new file mode 100644 index 000000000..2a5f07577 --- /dev/null +++ b/test/file.cpp @@ -0,0 +1,9 @@ +// +// Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +// Test that header file is self-contained +#include diff --git a/test/native_file.cpp b/test/native_file.cpp new file mode 100644 index 000000000..726d2bbbe --- /dev/null +++ b/test/native_file.cpp @@ -0,0 +1,9 @@ +// +// Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +// Test that header file is self-contained +#include diff --git a/test/posix_file.cpp b/test/posix_file.cpp new file mode 100644 index 000000000..eff0d831a --- /dev/null +++ b/test/posix_file.cpp @@ -0,0 +1,9 @@ +// +// Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +// Test that header file is self-contained +#include diff --git a/test/recover.cpp b/test/recover.cpp new file mode 100644 index 000000000..fbd481959 --- /dev/null +++ b/test/recover.cpp @@ -0,0 +1,191 @@ +// +// Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +// Test that header file is self-contained +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace nudb { +namespace test { + +class basic_recover_test : public beast::unit_test::suite +{ +public: + using key_type = std::uint32_t; + + void + test_ok() + { + std::size_t const keySize = 8; + std::size_t const blockSize = 256; + float const loadFactor = 0.5f; + + error_code ec; + test_store ts{keySize, blockSize, loadFactor}; + ts.create(ec); + if(! BEAST_EXPECTS(! ec, ec.message())) + return; + recover(ts.dp, ts.kp, ts.lp, ec); + if(! BEAST_EXPECTS(! ec, ec.message())) + return; + } + + // Creates and opens a database, performs a bunch + // of inserts, then fetches all of them to make sure + // they are there. Uses a fail_file that causes the n-th + // I/O to fail, causing an exception. + void + do_work( + test_store& ts, + std::size_t N, + fail_counter& c, + error_code& ec) + { + ts.create(ec); + if(ec) + return; + basic_store> db; + db.open(ts.dp, ts.kp, ts.lp, ec, c); + if(ec) + return; + if(! BEAST_EXPECT(db.appnum() == ts.appnum)) + return; + // Insert + for(std::size_t i = 0; i < N; ++i) + { + auto const item = ts[i]; + db.insert(item.key, item.data, item.size, ec); + if(ec == test_error::failure) + return; + if(! BEAST_EXPECTS(! ec, ec.message())) + return; + } + // Fetch + Buffer b; + for(std::size_t i = 0; i < N; ++i) + { + auto const item = ts[i]; + db.fetch(item.key, b, ec); + if(ec == test_error::failure) + return; + if(! BEAST_EXPECTS(! ec, ec.message())) + return; + if(! BEAST_EXPECT(b.size() == item.size)) + return; + if(! BEAST_EXPECT(std::memcmp(b.data(), + item.data, item.size) == 0)) + return; + } + db.close(ec); + if(ec == test_error::failure) + return; + if(! BEAST_EXPECTS(! ec, ec.message())) + return; + // Verify + verify_info info; + verify(info, ts.dp, ts.kp, + 0, no_progress{}, ec); + if(ec) + { + log << info; + return; + } + } + + void + do_recover( + test_store& ts, fail_counter& c, error_code& ec) + { + recover>( + ts.dp, ts.kp, ts.lp, ec, c); + if(ec) + return; + // Verify + verify_info info; + verify(info, ts.dp, ts.kp, + 0, no_progress{}, ec); + if(ec) + return; + ts.erase(); + } + + void + test_recover(std::size_t blockSize, + float loadFactor, std::size_t N) + { + testcase(std::to_string(N) + " inserts", + beast::unit_test::abort_on_fail); + test_store ts{sizeof(key_type), blockSize, loadFactor}; + for(std::size_t n = 1;; ++n) + { + { + error_code ec; + fail_counter c{n}; + do_work(ts, N, c, ec); + if(! ec) + { + ts.close(ec); + ts.erase(); + break; + } + if(! BEAST_EXPECTS(ec == + test::test_error::failure, ec.message())) + return; + } + for(std::size_t m = 1;; ++m) + { + error_code ec; + fail_counter c{m}; + do_recover(ts, c, ec); + if(! ec) + break; + if(! BEAST_EXPECTS(ec == + test::test_error::failure, ec.message())) + return; + } + } + } +}; + +class recover_test : public basic_recover_test +{ +public: + void + run() override + { + test_ok(); + test_recover(128, 0.55f, 0); + test_recover(128, 0.55f, 10); + test_recover(128, 0.55f, 100); + } +}; + +class recover_big_test : public basic_recover_test +{ +public: + void + run() override + { + test_recover(256, 0.55f, 1000); + test_recover(256, 0.90f, 10000); + } +}; + +BEAST_DEFINE_TESTSUITE(recover, test, nudb); +//BEAST_DEFINE_TESTSUITE_MANUAL(recover_big, test, nudb); + +} // test +} // nudb diff --git a/test/rekey.cpp b/test/rekey.cpp new file mode 100644 index 000000000..8b333ec2a --- /dev/null +++ b/test/rekey.cpp @@ -0,0 +1,136 @@ +// +// Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +// Test that header file is self-contained +#include + +#include +#include +#include +#include +#include + +namespace nudb { +namespace test { + +// Simple test to check that rekey works, and +// also to exercise all its failure paths. +// +class rekey_test : public beast::unit_test::suite +{ +public: + void + do_recover( + std::size_t N, nsize_t blockSize, float loadFactor) + { + using key_type = std::uint32_t; + + auto const keys = static_cast( + loadFactor * detail::bucket_capacity(blockSize)); + std::size_t const bufferSize = + (blockSize * (1 + ((N + keys - 1) / keys))) + / 2; + error_code ec; + test_store ts{sizeof(key_type), blockSize, loadFactor}; + ts.create(ec); + if(! BEAST_EXPECTS(! ec, ec.message())) + return; + ts.open(ec); + if(! BEAST_EXPECTS(! ec, ec.message())) + return; + // Insert + for(std::size_t i = 0; i < N; ++i) + { + auto const item = ts[i]; + ts.db.insert(item.key, item.data, item.size, ec); + if(! BEAST_EXPECTS(! ec, ec.message())) + return; + } + ts.close(ec); + if(! BEAST_EXPECTS(! ec, ec.message())) + return; + // Verify + verify_info info; + verify( + info, ts.dp, ts.kp, bufferSize, no_progress{}, ec); + if(! BEAST_EXPECTS(! ec, ec.message())) + return; + if(! BEAST_EXPECT(info.value_count == N)) + return; + if(! BEAST_EXPECT(info.spill_count > 0)) + return; + // Rekey + auto const kp2 = ts.kp + "2"; + for(std::size_t n = 1;; ++n) + { + fail_counter fc{n}; + rekey>( + ts.dp, kp2, ts.lp, blockSize, loadFactor, + N, bufferSize, ec, no_progress{}, fc); + if(! ec) + break; + if(! BEAST_EXPECTS(ec == + test::test_error::failure, ec.message())) + return; + ec = {}; + recover( + ts.dp, kp2, ts.lp, ec); + if(ec == error::no_key_file || + ec == errc::no_such_file_or_directory) + { + ec = {}; + continue; + } + if(! BEAST_EXPECTS(! ec, ec.message())) + return; + native_file::erase(kp2, ec); + if(ec == errc::no_such_file_or_directory) + ec = {}; + if(! BEAST_EXPECTS(! ec, ec.message())) + return; + // Verify + verify(info, ts.dp, ts.kp, + bufferSize, no_progress{}, ec); + if(! BEAST_EXPECTS(! ec, ec.message())) + return; + if(! BEAST_EXPECT(info.value_count == N)) + return; + } + // Verify + verify(info, ts.dp, ts.kp, + bufferSize, no_progress{}, ec); + if(! BEAST_EXPECTS(! ec, ec.message())) + return; + if(! BEAST_EXPECT(info.value_count == N)) + return; + verify(info, ts.dp, kp2, + bufferSize, no_progress{}, ec); + if(! BEAST_EXPECTS(! ec, ec.message())) + return; + if(! BEAST_EXPECT(info.value_count == N)) + return; + } + + void + run() override + { + enum + { + N = 50000, + blockSize = 256 + }; + + float const loadFactor = 0.95f; + + do_recover(N, blockSize, loadFactor); + } +}; + +BEAST_DEFINE_TESTSUITE(rekey, test, nudb); + +} // test +} // nudb diff --git a/test/store.cpp b/test/store.cpp new file mode 100644 index 000000000..e0016e0c2 --- /dev/null +++ b/test/store.cpp @@ -0,0 +1,9 @@ +// +// Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +// Test that header file is self-contained +#include diff --git a/test/type_traits.cpp b/test/type_traits.cpp new file mode 100644 index 000000000..050ee72e1 --- /dev/null +++ b/test/type_traits.cpp @@ -0,0 +1,9 @@ +// +// Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +// Test that header file is self-contained +#include diff --git a/test/verify.cpp b/test/verify.cpp new file mode 100644 index 000000000..e3a6f1c8c --- /dev/null +++ b/test/verify.cpp @@ -0,0 +1,94 @@ +// +// Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +// Test that header file is self-contained +#include + +#include +#include +#include +#include + +namespace nudb { +namespace test { + +class verify_test : public beast::unit_test::suite +{ +public: + // File doesn't exist + void + test_missing() + { + error_code ec; + test_store ts{4, 4096, 0.5f}; + verify_info info; + verify(info, + ts.dp, ts.kp, 0, no_progress{}, ec); + BEAST_EXPECTS(ec == + errc::no_such_file_or_directory, ec.message()); + } + + void + test_verify( + std::size_t N, + std::size_t keySize, + std::size_t blockSize, + float loadFactor) + { + testcase << + "N=" << N << ", " + "keySize=" << keySize << ", " + "blockSize=" << blockSize; + error_code ec; + test_store ts{keySize, blockSize, loadFactor}; + ts.create(ec); + if(! BEAST_EXPECTS(! ec, ec.message())) + return; + ts.open(ec); + if(! BEAST_EXPECTS(! ec, ec.message())) + return; + // Insert + for(std::size_t n = 0; n < N; ++n) + { + auto const item = ts[n]; + ts.db.insert(item.key, item.data, item.size, ec); + if(! BEAST_EXPECTS(! ec, ec.message())) + return; + } + ts.close(ec); + if(! BEAST_EXPECTS(! ec, ec.message())) + return; + + // Verify + verify_info info; + verify(info, ts.dp, ts.kp, + 0, no_progress{}, ec); + if(! BEAST_EXPECTS(! ec, ec.message())) + return; + BEAST_EXPECT(info.hist[1] > 0); + + // Verify fast + verify(info, ts.dp, ts.kp, + 10 * 1024 * 1024, no_progress{}, ec); + if(! BEAST_EXPECTS(! ec, ec.message())) + return; + BEAST_EXPECT(info.hist[1] > 0); + } + + void + run() override + { + float const loadFactor = 0.95f; + test_missing(); + test_verify(5000, 4, 256, loadFactor); + } +}; + +BEAST_DEFINE_TESTSUITE(verify, test, nudb); + +} // test +} // nudb diff --git a/test/version.cpp b/test/version.cpp new file mode 100644 index 000000000..7604c89a2 --- /dev/null +++ b/test/version.cpp @@ -0,0 +1,9 @@ +// +// Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +// Test that header file is self-contained +#include diff --git a/test/visit.cpp b/test/visit.cpp new file mode 100644 index 000000000..405710382 --- /dev/null +++ b/test/visit.cpp @@ -0,0 +1,114 @@ +// +// Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +// Test that header file is self-contained +#include + +#include +#include +#include +#include + +namespace nudb { +namespace test { + +class visit_test : public beast::unit_test::suite +{ +public: + void + do_visit( + std::size_t N, + std::size_t blockSize, + float loadFactor) + { + using key_type = std::uint32_t; + + error_code ec; + test_store ts{sizeof(key_type), blockSize, loadFactor}; + + // File not present + visit(ts.dp, + [&](void const* key, std::size_t keySize, + void const* data, std::size_t dataSize, + error_code& ec) + { + }, no_progress{}, ec); + if(! BEAST_EXPECTS(ec == + errc::no_such_file_or_directory, ec.message())) + return; + ec = {}; + + ts.create(ec); + if(! BEAST_EXPECTS(! ec, ec.message())) + return; + ts.open(ec); + if(! BEAST_EXPECTS(! ec, ec.message())) + return; + std::unordered_map map; + // Insert + for(std::size_t i = 0; i < N; ++i) + { + auto const item = ts[i]; + key_type const k = item.key[0] + + (static_cast(item.key[1]) << 8) + + (static_cast(item.key[2]) << 16) + + (static_cast(item.key[3]) << 24); + map[k] = i; + ts.db.insert(item.key, item.data, item.size, ec); + if(! BEAST_EXPECTS(! ec, ec.message())) + return; + } + ts.close(ec); + if(! BEAST_EXPECTS(! ec, ec.message())) + return; + // Visit + visit(ts.dp, + [&](void const* key, std::size_t keySize, + void const* data, std::size_t dataSize, + error_code& ec) + { + auto const fail = + [&ec] + { + ec = error_code{ + errc::invalid_argument, generic_category()}; + }; + if(! BEAST_EXPECT(keySize == sizeof(key_type))) + return fail(); + auto const p = + reinterpret_cast(key); + key_type const k = p[0] + + (static_cast(p[1]) << 8) + + (static_cast(p[2]) << 16) + + (static_cast(p[3]) << 24); + auto const it = map.find(k); + if(it == map.end()) + return fail(); + auto const item = ts[it->second]; + if(! BEAST_EXPECT(dataSize == item.size)) + return fail(); + auto const result = + std::memcmp(data, item.data, item.size); + if(result != 0) + return fail(); + }, no_progress{}, ec); + if(! BEAST_EXPECTS(! ec, ec.message())) + return; + } + + void + run() override + { + float const loadFactor = 0.95f; + do_visit(5000, 4096, loadFactor); + } +}; + +BEAST_DEFINE_TESTSUITE(visit, test, nudb); + +} // test +} // nudb diff --git a/test/win32_file.cpp b/test/win32_file.cpp new file mode 100644 index 000000000..ca6d9337e --- /dev/null +++ b/test/win32_file.cpp @@ -0,0 +1,9 @@ +// +// Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +// Test that header file is self-contained +#include diff --git a/test/xxhasher.cpp b/test/xxhasher.cpp new file mode 100644 index 000000000..6c4c9b960 --- /dev/null +++ b/test/xxhasher.cpp @@ -0,0 +1,9 @@ +// +// Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +// Test that header file is self-contained +#include diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt new file mode 100644 index 000000000..8a82003ff --- /dev/null +++ b/tools/CMakeLists.txt @@ -0,0 +1,17 @@ +# Part of nudb + +GroupSources (include/nudb nudb) +GroupSources (extras/nudb extras) +GroupSources (tools "/") + +add_executable (nudb + ${NUDB_INCLUDES} + ${EXTRAS_INCLUDES} + nudb.cpp +) + +if (WIN32) + target_link_libraries (nudb ${Boost_LIBRARIES}) +else () + target_link_libraries (nudb ${Boost_LIBRARIES} rt Threads::Threads) +endif () diff --git a/tools/Jamfile b/tools/Jamfile new file mode 100644 index 000000000..384c33f34 --- /dev/null +++ b/tools/Jamfile @@ -0,0 +1,12 @@ +# +# Copyright (c) 2013-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +# +# Distributed under the Boost Software License, Version 1.0. (See accompanying +# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +# + +import os ; + +exe nudb : + nudb.cpp + ; diff --git a/tools/nudb.cpp b/tools/nudb.cpp new file mode 100644 index 000000000..5a06a03a3 --- /dev/null +++ b/tools/nudb.cpp @@ -0,0 +1,514 @@ +// +// Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#include +#include +#include +#include +#include +#include +#include + +namespace nudb { + +namespace detail { + +std::ostream& +operator<<(std::ostream& os, dat_file_header const h) +{ + os << + "type: '" << std::string{h.type, h.type + sizeof(h.type)} << "'\n" + "version: " << h.version << "\n" + "uid: " << fhex(h.uid) << "\n" + "appnum: " << fhex(h.appnum) << "\n" + "key_size: " << h.key_size << "\n" + ; + return os; +} + +std::ostream& +operator<<(std::ostream& os, key_file_header const h) +{ + os << + "type: '" << std::string{h.type, h.type + sizeof(h.type)} << "'\n" + "version: " << h.version << "\n" + "uid: " << fhex(h.uid) << "\n" + "appnum: " << fhex(h.appnum) << "\n" + "key_size: " << h.key_size << "\n" + "salt: " << fhex(h.salt) << "\n" + "pepper: " << fhex(h.pepper) << "\n" + "block_size: " << fdec(h.block_size) << "\n" + ; + return os; +} + +std::ostream& +operator<<(std::ostream& os, log_file_header const h) +{ + os << std::setfill('0') << std::internal << std::showbase << + "type: '" << std::string{h.type, h.type + sizeof(h.type)} << "'\n" + "version: " << h.version << "\n" + "uid: " << fhex(h.uid) << "\n" + "appnum: " << fhex(h.appnum) << "\n" + "key_size: " << h.key_size << "\n" + "salt: " << fhex(h.salt) << "\n" + "pepper: " << fhex(h.pepper) << "\n" + "block_size: " << fdec(h.block_size) << "\n" + "key_file_size: " << fdec(h.key_file_size) << "\n" + "dat_file_size: " << fdec(h.dat_file_size) << "\n" + ; + return os; +} + +} // detail + +std::ostream& +operator<<(std::ostream& os, verify_info const& info) +{ + os << + "dat_path " << info.dat_path << "\n" + "key_path " << info.key_path << "\n" + "algorithm " <<(info.algorithm ? "fast" : "normal") << "\n" + "avg_fetch: " << std::fixed << std::setprecision(3) << info.avg_fetch << "\n" << + "waste: " << std::fixed << std::setprecision(3) << info.waste * 100 << "%" << "\n" << + "overhead: " << std::fixed << std::setprecision(1) << info.overhead * 100 << "%" << "\n" << + "actual_load: " << std::fixed << std::setprecision(0) << info.actual_load * 100 << "%" << "\n" << + "version: " << fdec(info.version) << "\n" << + "uid: " << fhex(info.uid) << "\n" << + "appnum: " << fhex(info.appnum) << "\n" << + "key_size: " << fdec(info.key_size) << "\n" << + "salt: " << fhex(info.salt) << "\n" << + "pepper: " << fhex(info.pepper) << "\n" << + "block_size: " << fdec(info.block_size) << "\n" << + "bucket_size: " << fdec(info.bucket_size) << "\n" << + "load_factor: " << std::fixed << std::setprecision(0) << info.load_factor * 100 << "%" << "\n" << + "capacity: " << fdec(info.capacity) << "\n" << + "buckets: " << fdec(info.buckets) << "\n" << + "key_count: " << fdec(info.key_count) << "\n" << + "value_count: " << fdec(info.value_count) << "\n" << + "value_bytes: " << fdec(info.value_bytes) << "\n" << + "spill_count: " << fdec(info.spill_count) << "\n" << + "spill_count_tot: " << fdec(info.spill_count_tot) << "\n" << + "spill_bytes: " << fdec(info.spill_bytes) << "\n" << + "spill_bytes_tot: " << fdec(info.spill_bytes_tot) << "\n" << + "key_file_size: " << fdec(info.key_file_size) << "\n" << + "dat_file_size: " << fdec(info.dat_file_size) << "\n" << + "hist: " << fhist(info.hist) << "\n" + ; + return os; +} + +template +class admin_tool +{ + int ac_ = 0; + char const* const* av_ = nullptr; + boost::program_options::options_description desc_; + +public: + admin_tool() + : desc_("Options") + { + namespace po = boost::program_options; + desc_.add_options() + ("buffer,b", po::value(), + "Set the buffer size in bytes (larger is faster).") + ("dat,d", po::value(), + "Path to data file.") + ("key,k", po::value(), + "Path to key file.") + ("log,l", po::value(), + "Path to log file.") + ("count,n", po::value(), + "The number of items in the data file.") + ("command", "Command to run.") + ; + } + + std::string + progname() const + { + using namespace boost::filesystem; + return path{av_[0]}.stem().string(); + } + + std::string + filename(std::string const& s) + { + using namespace boost::filesystem; + return path{s}.filename().string(); + } + + void + help() + { + std::cout << + "usage: " << progname() << " [file...] \n"; + std::cout << + "\n" + "Commands:\n" + "\n" + " help\n" + "\n" + " Print this help information.\n" + "\n" + " info [ []]\n" + "\n" + " Show metadata and header information for database files.\n" + "\n" + " recover \n" + "\n" + " Perform a database recovery. A recovery is necessary if a log\n" + " file is present. Running commands on an unrecovered database\n" + " may result in lost or corrupted data.\n" + "\n" + " rekey --count= --buffer=\n" + "\n" + " Generate the key file for a data file. The buffer option is\n" + " required, larger buffers process faster. A buffer equal to\n" + " the size of the key file processes the fastest. This command\n" + " must be passed the count of items in the data file, which\n" + " can be calculated with the 'visit' command.\n" + "\n" + " If the rekey is aborted before completion, the database must\n" + " be subsequently restored by running the 'recover' command.\n" + "\n" + " verify [--buffer=]\n" + "\n" + " Verify the integrity of a database. The buffer option is\n" + " optional, if omitted a slow algorithm is used. When a buffer\n" + " size is provided, a fast algorithm is used with larger\n" + " buffers resulting in bigger speedups. A buffer equal to the\n" + " size of the key file provides the fastest speedup.\n" + "\n" + " visit \n" + "\n" + " Iterate a data file and show information, including the count\n" + " of items in the file and a histogram of their log base2 size.\n" + "\n" + "Notes:\n" + "\n" + " Paths may be full or relative, and should include the extension.\n" + " The recover algorithm should be invoked before running any\n" + " operation which can modify the database.\n" + "\n" + ; + desc_.print(std::cout); + }; + + int + error(std::string const& why) + { + std::cerr << + progname() << ": " << why << ".\n" + "Use '" << progname() << " help' for usage.\n"; + return EXIT_FAILURE; + }; + + int + operator()(int ac, char const* const* av) + { + namespace po = boost::program_options; + + ac_ = ac; + av_ = av; + + try + { + po::positional_options_description pod; + pod.add("command", 1); + pod.add("dat", 1); + pod.add("key", 1); + pod.add("log", 1); + + po::variables_map vm; + po::store(po::command_line_parser(ac, av) + .options(desc_) + .positional(pod) + .run() + ,vm); + po::notify(vm); + + std::string cmd; + + if(vm.count("command")) + cmd = vm["command"].as(); + + if(cmd == "help") + { + help(); + return EXIT_SUCCESS; + } + + if(cmd == "info") + return do_info(vm); + + if(cmd == "recover") + return do_recover(vm); + + if(cmd == "rekey") + return do_rekey(vm); + + if(cmd == "verify") + return do_verify(vm); + + if(cmd == "visit") + return do_visit(vm); + + return error("Unknown command '" + cmd + "'"); + } + catch(std::exception const& e) + { + return error(e.what()); + } + } + +private: + int + do_info(boost::program_options::variables_map const& vm) + { + if(! vm.count("dat") && ! vm.count("key") && ! vm.count("log")) + return error("No files specified"); + if(vm.count("dat")) + do_info(vm["dat"].as()); + if(vm.count("key")) + do_info(vm["key"].as()); + if(vm.count("log")) + do_info(vm["log"].as()); + return EXIT_SUCCESS; + } + + void + do_info(path_type const& path) + { + error_code ec; + auto const err = + [&] + { + std::cout << path << ": " << ec.message() << "\n"; + }; + native_file f; + f.open(file_mode::read, path, ec); + if(ec) + return err(); + auto const size = f.size(ec); + if(ec) + return err(); + if(size < 8) + { + std::cout << "File " << path << " is too small to be a database file.\n"; + return; + } + std::array ta; + f.read(0, ta.data(), ta.size(), ec); + if(ec) + return err(); + std::string ts{ta.data(), ta.size()}; + + if(ts == "nudb.dat") + { + detail::dat_file_header h; + detail::read(f, h, ec); + if(ec) + return err(); + f.close(); + std::cout << + "data file: " << path << "\n" + "file size: " << fdec(size) << "\n" << + h << "\n"; + return; + } + + if(ts == "nudb.key") + { + detail::key_file_header h; + detail::read(f, h, ec); + if(ec) + return err(); + f.close(); + std::cout << + "key file: " << path << "\n" + "file size: " << fdec(size) << "\n" << + h << "\n"; + return; + } + + if(ts == "nudb.log") + { + detail::log_file_header h; + detail::read(f, h, ec); + if(ec) + return err(); + f.close(); + std::cout << + "log file: " << path << "\n" + "file size: " << fdec(size) << "\n" << + h << "\n"; + return; + } + + std::cout << "File " << path << " has unknown type '" << ts << "'.\n"; + } + + int + do_recover(boost::program_options::variables_map const& vm) + { + if(! vm.count("dat") || ! vm.count("key") || ! vm.count("log")) + return error("Missing file specifications"); + error_code ec; + recover( + vm["dat"].as(), + vm["key"].as(), + vm["log"].as(), + ec); + if(ec) + { + std::cerr << "recover: " << ec.message() << "\n"; + return EXIT_FAILURE; + } + return EXIT_SUCCESS; + } + + int + do_rekey(boost::program_options::variables_map const& vm) + { + if(! vm.count("dat")) + return error("Missing data file path"); + if(! vm.count("key")) + return error("Missing key file path"); + if(! vm.count("log")) + return error("Missing log file path"); + if(! vm.count("count")) + return error("Missing item count"); + if(! vm.count("buffer")) + return error("Missing buffer size"); + auto const dp = vm["dat"].as(); + auto const kp = vm["key"].as(); + auto const lp = vm["log"].as(); + auto const itemCount = vm["count"].as(); + auto const bufferSize = vm["buffer"].as(); + error_code ec; + progress p{std::cout}; + rekey(dp, kp, lp, + block_size(kp), 0.5f, itemCount, + bufferSize, ec, p); + if(ec) + { + std::cerr << "rekey: " << ec.message() << "\n"; + return EXIT_FAILURE; + } + return EXIT_SUCCESS; + } + + int + do_verify(boost::program_options::variables_map const& vm) + { + if(! vm.count("dat")) + return error("Missing data file path"); + if(! vm.count("key")) + return error("Missing key file path"); + + auto const bufferSize = vm.count("buffer") ? + vm["buffer"].as() : 0; + auto const dp = vm["dat"].as(); + auto const kp = vm.count("key") ? + vm["key"].as() : std::string{}; + + if(! vm.count("key")) + { + // todo + std::cerr << "unimplemented: dat-only verify\n"; + return EXIT_FAILURE; + } + + error_code ec; + progress p(std::cout); + { + verify_info info; + verify(info, dp, kp, bufferSize, p, ec); + if(! ec) + std::cout << info; + } + if(ec) + { + std::cerr << "verify: " << ec.message() << "\n"; + return EXIT_FAILURE; + } + return EXIT_SUCCESS; + } + + int + do_visit(boost::program_options::variables_map const& vm) + { + if(! vm.count("dat")) + return error("Missing dat path"); + auto const path = vm["dat"].as(); + error_code ec; + auto const err = + [&] + { + std::cout << path << ": " << ec.message() << "\n"; + return EXIT_FAILURE; + }; + { + native_file f; + f.open(file_mode::read, path, ec); + if(ec) + return err(); + auto const fileSize = f.size(ec); + if(ec) + return err(); + detail::dat_file_header h; + detail::read(f, h, ec); + if(ec) + return err(); + f.close(); + std::cout << + "data file: " << path << "\n" + "file size: " << fdec(fileSize) << "\n" << + h; + std::cout.flush(); + } + + std::uint64_t n = 0; + std::array hist; + hist.fill(0); + progress p{std::cout}; + visit(path, + [&](void const*, std::size_t, + void const*, std::size_t data_size, + error_code& ec) + { + ++n; + ++hist[log2(data_size)]; + //std::this_thread::sleep_for(std::chrono::milliseconds{1}); + }, p, ec); + if(! ec) + std::cout << + "value_count " << fdec(n) << "\n" << + "sizes: " << fhist(hist) << "\n"; + if(ec) + { + std::cerr << "visit: " << ec.message() << "\n"; + return EXIT_FAILURE; + } + return EXIT_SUCCESS; + } +}; + +} // nudb + +int +main(int ac, char const* const* av) +{ + using namespace nudb; + admin_tool t; + auto const rv = t(ac, av); + std::cout.flush(); + basic_seconds_clock_main_hook(); + return rv; +}

-8OQq)QIAR_0Pdw-h$!wpBl9KA_0!MhIV1$}XevD# z7g1GAV%%7-okUNhT7{pB#T)32q#~}2&2tGq-Bz<7Iq<320n%7VHKC^zLP^;WBC81# zuCI$6~eGHVM+Rs525;*)T*4Uwv}5rJ(U>Q0f1g>U~z}?-#p`Wb6dcXprcF z*z@Km#EIQzwg{%9OLl2!3ZK46A1bBK|4`3JjtW<)?Zo@R?e9uztYqqc-G*WGr9WIu z%UbWt|B1~hAs0?ntJ|kbuMUBA78t)gNllAwvnis^ zfmv%bc(}X>yt4B1l(KD>nm>k=3yV&`L;}q)4|}tnv2)&cNdjV|cn;yHg(6j@Oc@3X z!`cmRAUjK+rWFpA$q=oW^aLA%W`Zo~T+1>_4m}}a$E0^K7Kj@V3*3wHu*lILG43Ze zhZV8yCqLVj-uK<<=@R2MnwfeI`J>psH&}l@;iwXAGakzcV(KzZy1?L*|ohP*w=L?EWa3Pv2;{|4; zp~eTft){5!!-7fGQNKAEuPMt#a>;Gp*7URfxM?I$i#&KpaXdp!poxgOw0Rw*^|{nR z(`bUq>uUk$135~zgXs(d^~F;U9DQe{t*U0`7dbfJ_lvRKA=v7m_I$PXSizde-p@5{q!0TANQ*|xZ<&FAwk0Bs-B zT`_aMVJ1!TdrZWG;7gzR#86*v0JQkg+7+9WY_Q()O6pZMW~dxQWL(#2=sB0Hour9<+u zHrvv<;}mQv*$2zpf7HwW)M~_$ThbM5h@c4gM4l-U&dI)NJ>*UGW{!6Azbuz(Og+rF zs(lTsz8^|Ye^Z-i=qAo|(=n~m`t{&YGRvbAk7#>a` zo5wqsNvo7_`_WaWV;;U<0mRr_c?x5*RlDWxdFw3DWDv!2_O=Y_{jXoI%!{G+Ss{`W zRWsrCgvoFAQ*c5{SjSAR@l=3|dgYUx{?MOh&=Teo%3g?9&sh}lj;sZ%0&MsIu?frN zBA(H24sH=WDaapa5W86G?1e{8@td6|qH`R#PD;_3yT;xqZ9f{d_qn5(#15wpgpvN9 z(t^(0X!Nu1JQ}+or2_o$)VyR1guz8Wq$vpV?yw-B1X>fajvA!Qs^#lY|tC`=sM zm%q)LktFF?)ywDcb*X^7Au&jYG^>+?U(`UI{}gl1c|dePGFjuzajPxek2%ltmh~U%}*NX?=g{)mUD7pii|S zC^;GmBg|Iby}Z7S)Gen{jz$5Ne>>}GQ0u;*^#P4>?t^#Z!CPjf(0A@-xI`buLJ1|i z#E2k;KpZs&T;lVibibx#!C*4H%;_;9_JY&&+n~F+?R%U_c}WFeJJ|xxB&Ugb35d?M z)~+{m9@k{1MewQ&7F zzd5KAodd;*o0Nb?bs&qG~t1HkyD z7`682yME$3AKhe8|H!=Ml-J035taB@)U(SC#D^z31g^eR5n0qc@&}yGN_b|d!Emk3Xd;t^mG9< zwhr54@_s#Epdg*kU86J#t?0ASAxW=`ND`lHDltX7ntrgw)7+fsvRmVj6vll4UiK&B zvfGj9I{){jKfBF<8q7rc8|UxZSfk(Tt=&;hf6d`lpaCPq&@7B$;UOXc?dcB@ z4h;-St82U};1V+3=3&HgbkyJRoo%Hsoxb3jIcHW0iyfMGupOR^4NJ-R2oHieXfrrGgsczMphAm-qKu(Ie6-kKjgbS>RNUfWWF|d!hminQo(Cuv|NpqkJbL zqbH*^l&B3yP?Cnz^4c>|Q#wuYq~uo!Fc5b7qr5scALtK43%{GC-QR1?KlkF>L>(=T zxQ(uhJr`yo7m%<)1K7R7G)Y;Ax7jG`b~H)Ds^;%q>G+2V5mP5+gb{0g>fL{=YbJTJ z+|H)S_7dwi7z@T@f*K+eIXd2RMcc64)Wge2&kn8E4(eBkz5&K17Z1R>#ypO0lLkhi zmAbp#+y*D0up2H=AeNAcUZjZx0!U0@hGYXsp6;Lasd2GTJO*x^LXg2?+%8L4)1^58 zL_f&!j$0~{;Ifc8DSLP*{ze+^_*TJm5jhKxiR$Dab`$PjZdv%r7F$qMSk!)u4cDq% zx81wudBX;Ak5*~N`FL4~u7q|dXryA!+Rx|ROH&P7+yRC)svznk-Zw+kYoYNj+sJWJ zQa_S3GgL-NNY&r*?21Hq;N*l*E;3Pjo3+`Bd8~H-a9gA8YNfkxPBI~#0ECMc-3>2n zQJU7G6^hER;SHSuS;KiSGaWi@!6h5gM|5>scKq|w=>BaNCV&s5n?P4#gVa)MFHd~< z`b$oH`1`mYcoNH6FD)O~&!$l0w9(_sC;jf`zn34^kRQs$g@g4oSU2F>_&ZGUrjb zl6wndNn3*E&qICp-mH!Xg#nKV(~hzDlx|*Q-BIlV8Y-8FXC~pH-Q%J&)4m*zDbK+UOnQv~5qPkRT9a>@ zR6-$0t*mE!+6@*z$K~F5zvJ)C!zA%~*bnXLOZQ>cjBW($dSot%hM6O7JkY3g85Xy|aY(Lx*}h@^05p{YnC?>KGf`rB*GL486v%#zi016eIX{13tz<(}R2bx}$@ z6KXjF9s|AQoiaRsbd)`BQr!1TfAF1SJG!#nfJ2d6^y^YO|GQr*Eu88ZTc54lC@=om zZp{8IimWHd?EXXFdx76<&Uh|B+cdB#{IxJGqd&BjAdSa+HIa5uV8yNKm9%f6siGhY zdzJ|0C52?cfpYF8pC^Py46~Rd`7yjnES0GUW~1Xq&eFy8V}+XK-uqQ%RlU6WbZQB+ zo1qhb0?NifOP;T0cmm3Gt|{BsW4l`p&hW4J8A>b)+#|v?ig$7I_76SgZ@yoUa&5d( zh%kC?`0yYzD{9;Io2B_*wc77_Dd+VO4;Rm-_R8L9&F|Mv2o~7pUyP;_u#De?i5{0l zz()GlmTJG(rPUA33WK6C!K1w@hyUF#FP`NY=L|@ZAxRZdz7vz?lfa`4p2%XZ0GdYv zdMUBy0yOF;i3I7m6^qD0DIi4i5}Vy^yRlLGS~4DvTLyP=1Y|+wgE3tnBq>rc0V4Ez ztfufCFhLOmo{1`VBME|f4mc2_uh+ro;B4J!d=Jdz|TBZFc1^2T0960%^W-Q@T`AS+|}NlJ3@tXkYzXagjj(H(Sj<}Gsz@N%3aYtYsUf@qQ0 zT0T##uAov3I}A6QW}2cgG^i7;QE{m?HEOIQt^1PF!Dc{#Od{0(f3KY4D8|OAV888<=${ zx_$p~W7^SKz@0CErpz^>@c@53L_AErD_2>R0fa4f$Mf+39)vVJFY$0_R?*TEaJHK3 zeF;=hARd70sWb_4i*S=46gySuDuq`1QYsu8{!3B{A*$|U?|0u9whx^UL)>m)#}ph- z5Wv>qfK~6_YahRxmD2du(71^JLF4k`53S1ot-)ifJb7Lm88?*}*2!pON!rK;;R>;d zfefVMk>FBlr+dk@5l#jMIznMZ((pofKG!9G=XmJqxbeSY4-)FOC5n{;)jDvBU z1t-LccvEyXfjVU7u*B2)!-H(aO7-&G<$uJ4$=Nu0K`QtUYHQWg3g5|JQN(sy{9I zEyxu#2fCI(IbZwn@=b1v#8oFEjwZU*a)8W{W_V>J?CRXO>WK z{ztE}_~{%$Obwpdu_10xV`TL7$Jf(EdlWNSTokd80EHd}$@xmon%x<9EPBKSi5G@a z^M;7x>9VB~wL(oISyV>sHToNnM?8y>_%n;ja|a2IMUOHdGi*h3TB}R0m$Gi)$j3y+ zQ^aVO^G%xd?Ol5PQD^i9y<6#S6ws)VFV>}qI?;W+K{kN}@nyFJYcY=57eS7gJ+bh{ z{fz@?UoJ{#+*~p9&+Xi~%Y=iXY7d0vrrYh*mXxiDAY&7S@bn?yGE)X(JaK>)TSpbL zw4<6W&v>x8%tSjuX$TtQPtLBe5|3s&-aNg`k%e)3ig2|j6Zw;{&|IJQVzB&=kaSd- z494+nO_5IEyI#C5mbPn?4i(03!)?1v3@$dciv;1b>o}_d`V!Q-&IEA7?8US`5az1?Qo8Nv0J}YYf;dEQ1-%fn83O251reX0J}+v%ruRj(%7vix?4SKo?+=-G zgrHa2y=X;HXFyQgzojXMiiB?v~Tuf1n^_nMAP{b$Eg zIG@HUN!j(8!ZN25!CHC#K0W-@9>7d_YTeq-|9Ft2L>$vvIOLVex?2C_%n#oUY0ohB zQ_3YXsKBrC#We(?a=S;PAH&^+&k;#vb`>@0MD z#y?^mmmA=I+E;B-9{+fGwS=ZI3PdQ5cBroY)h#VQ+sfQUI3=gaBWtxU&W;oyGdMcY znBjJzB;#1H=Xj*a)hX}3YnvbMHX}{bWeJ>sm6;KgW<&R?4c3>_QpPhQgpqMucRhOu9qAuC$=7>mhnlc?B^Od=Wv~RaI&ks6tD7cOr z9|xZOq~cB3TCi3fmTc=zt%QY07Yi1g!_b9%?Cox4{P$+>&#okI4UX>6_8^%kY}+hcv$Xvqr%b8%|Jl>P(qsZy^6aM^g#vfn z%91u~ZR(%IcucDtbh)qZ^sbp4ZfE{Wwefx_J>GM>u`}akNF_1_e33)b<68LSKVAoX z3*g89i2i_`afup_r&9Mo0=u=%s3H@ruN4G$!UON)y+>g}QdGl8x|4-9oiu`oTV{jLM4K{`RC+|8GvFHa#VPtDd9($PC&x;|A+8T+Z&f76F-cn0 z`R(p-xvk}xhJN71TXfQEMEq#2$ zHjI{QdLn&I3iaXcJBb?!%wet!*@NOJEM&30iJv;rX7&EAdAAjiCzgFFu}n9c3j6Wx zft8&kgrpL%2M3emeo*Be^6*72x-C|iO&9Vo*abVSMRFE7-2`;GS&ew`JVRu&ZCf5Z zmTp_UnL{5y9Um#$Z`t>OhUCd`{G09B{(>Z*JvLM#3FhkbULF1KyV~j9o~yHm%BK%n zp;UWO|6!=u4&M&yeCdyP>J+aiMY(*q_eo}uX|oaVMcu*u)3-@k=1T!4(H}9|9oe~_ z2t~1|qp(8BK-1z!v4RzQl?V6ZYUe>(i5vF1cyZs0mhb^>};id*bBxGO#%tLFrrxCNk(9 zoWfd{y`8-D_+50=-2R6A(Y%0L}wwL2u$`n zYWK>kxO_!)l%&?%FHf&?o! zGR*fd@pKd5AiG4l@*4eNqks}cItGz-F6{ZR6<$SlWMIG0zBW1tV|UkEAA3zS+w`Fi z=|tCA+#Pgt6?0;|C%ohV?B8fRn*Zs?F1}3+{jfq5nr>;M1kIVJV$aLxg9N6K+q@P2 zhspw&oi$|kw=3H}SNg@*YUj7Muyyp0q5@u#aIq5pQPX|ZAp8qIxaIjJtL zyQ7Z5F#fM)>F^ytK3lKWyVSJB_SLYp)4pT2mz_A1T)vDjs>AAW7-GQNt_1%4tu#L) zIogf6#6vCi92gW!c2GOFs#1@l#e$?-7L6f6z9ZEqLo8Hp3iskqof4Ox z#RSVz#V^VHFiY(8_3aq_@#U9fA-L-8-N(zu_$2(1%@iBb z`o(pLBVmM;gbiqW#nOlw?a_A+DS~{u63=Hu>}{?;ppjq|4skhSl!)L`J#!L+U(hD!pjV{U}v5uoPCoTB;sS z2??aE>rHDcy%Z1&U56r{H~mVbtS5-s5;coJMt{WrGTv|6H9Rng5*<(0K)ZbR#>=M| zs0IXPvPf&~Ykjv;|6u~yo{rw|tQ2dk{Y3nGsG$~66?w!YEtk#?j6xBdP}1o^3Lnch z_`fef@9wwz8y#91&zeX>COoexyqL0h`$IlFSCD=iY_@7C@KR=RssPjwE4M!$zF+54 zz>mqZ=E^h6PC82lQ-+kzLB^$Zh`9?Pq$*n0i!I7G#c8Mm2q5;`u*E{au)VV zO|15~xv|_jPQ6e?0vHHo^!Uo=PXr;lo>ixwBr_jVpg#U_U@Djj*%z}JVc~Na0@XN{ zC=akqVSbudt@gMmS1!&(iFT5A*=dx{dUeI=u#i+uR-n<}R`xR)1yP$2p}<@?8kh~ftb`?uw! ze4qa;wSO-d8HbJBE7>la^>WrYT}tI&j4B#bu(seH2AT>)^RYitE#b=!>#V$f*99zb zC9G3{OC&uCgbwo?PP5$-F=quEYK-!<{iDYEA2foLao7TK?L`W;CKW`kQP4#$a`Z~n zcr+x0wsN4N&>uj9Ygg%9jw|MID!6y|3(+)tCJv$_PP*y5pD{qpVYfQ}>m>Y9Zr(pQ zfCbBC%D9;GRV>9q-@22(Ah3W(;k-p;87-~GRXliq7-N7`iPjpzG`G)Y5N5sI&Wgc@ z{u#Eq@2%5=DsW0UPwB?6%}QA^xJ1T?P;LHweVXbv<~Fv5kUncIS-kD)&ExPktcbe` z*$fx)_4sv}Mk9+Bi6>|N;600=(Kx&~CRG>W$@8_Hs_+=kjQt=ppC^t_9xYBLPl*c> z6CG&kEE(t>+7M!z+thyLg>(Hb{cZN5wf+mRb(4FNL!(eCW-PxJ?Ww(vhRPRCme z|Gb|6HcKsJA*0>;uj7ix5QY2wY~uE>tqQDebgu*g_sWS==;w7R(kKb<(ePKL@4F0|+8o zMTSn`yfS*@jeb{aSL7S}8pCRSJ{<3+X-{F95^;(y@@Y%vuW@-YOerSHP32{yVlPXv8`evQd)`!nsA6BvL1xJvFynXSupcp_gPJyJ zjzHmuCfvwIh5gv0^7Of%MxAj#*yN3eo8!F?50Fvql_SuqwlDWs0}z>DvWb-^wG&ng z9~n9~$_K_qZ+&z0)uXd-ebdELe{uh;WFz_{74IG&&oVt!HhT@3q&vAECk44hznDv5 zVf#sqd}q1Pt9^>Ka_E384d>+QV@A($!ZZ^zY-0jC=7W}T?8CEAcD*{?4AN^vGgmOA z)v!CKO@)4P6f?W)xOcJ#ooR_vHXg&i*4~Y(>5=aMA^+G>LgvPY}8%3WH{Y)zK0b zl7_SRHdqxyKn2W3SS9LHyQ{yRtLuL{G%aOy<}xIZ1enA9hA}J6p&2{h#?h~M^)aS* zi!9IVMy6tXBGQ`WJDil#q%ghGoX_Gzm^qPiROMvZp%1yOU+Tkbw;$K#@>N?WLnRD! zMdc=J7k8=P6$`E093M)DU7c2q9coww21eSxAPMwFs)wV48X)~IB|O`HX=gQMXT@gm z!+5;GoK9o$@$+n3qzp-}HHn@$AyDuk}dZ9lGp`?1FrZe`usodL!jx8KB zD^{N*yV-TzU)MUj{oa(-Yv1n6ulE(AT%1*vXY$+dJMGun_EDv-Ns2A*k91J?S5GXm z5VdJ%>Cens#4?B(hIzDy^u`%gdpBLVbr1-7M3`H><2jZ{fX{lOw5%-M;&B4GYzZCj z?jBV0)|;jNx7Pt9JxKlV`LT`$^noaA2pwBo`OtE_T;(4yUJzxdPm54Vdd6TT_%ljz zs9ry@1EnD8Gmwca++NS(5t&b{)y?(TKo|-<1XSU8x8JzEmaA{~RW~IVRZq1c+625)yn)ZZ8$tUEyRon@Uptq)2c2Jru6;gMkDSdc*Z_q z_6}s=Opa>P@2=t6STh*JiZP?t3dKn6M9t=Eg|ZdBPdbP;W!4fCWyU;_aWpG`J(p%b zWJ(#NDTaQ&QKNm=j*7IsQ(~7OZL2i>`M+dOhY!noAWg%~vkQ2r!(MIg01p!{+?7Tt ziSg6RVmfI=#h5o`#u=4uDwI;qh_J8I2))d=a9fjx9v-__jZSUN6vWdUmW zWw=vMK!}-%04^N3=}_!VmgSTG+%p6nFyhvsFq{>j*3Wzw0Q8}^J? zOMBbBoO4zeRCid?ALqLlK3ASms%xpSR=(VF9B=){83EB3fUuW5L#wk+(pJn=UVmmR zB;3<0_dj+smFHKy)Pl5!N3kfw_IZ+m<_TmJ`a{5!Vf4Oe(|Uk9N&-s*mBMJq4q#rA z6crv?&$EP~%XGR6VFpHWkpKp^v{GK4SHoI)p!2qH0`4$&qcK#^FL&S9l{Cb&PVyVu zyKlEnxm;U34l#y>W|rbI5DZHCRelA^jGG&7&$@cHm+eh%M-qaZ)p>V4#n!9MKhAFh zbhWh80$B42_jLy6YG#Yd21D0(9pYgyfs1>wl@QLi+9x|a;)9Jt2yW1i;qz2^LH)5EW( zq$3XiAd7lS-x$cSlZ71@8WcohXg(;BW&fUokRocJ5Ygk;bEWT?hXf9l+-M{O}5J!6TUttYCeAC+SVlu;G~ z48j%021#YW1U#FS-DP^y1>fFhQ7H?snOfD=TdTHyi+vw8FGSsJo%hVp#{IF@;ayZCL}ygClm^OGgZs+gJ7A?c;TVkAv4~{DuXivKKQZ z04%XriFl(_-#vZxI(Kj~m6MxOFNsZ2ir7P81Ik;6AjOQ);3SUim4~sRcBfLUa(Xlz z$tzfN4SvsO)e4@CEA63}&|!j#-wZf-Gr3qE1Yi}jJcwA7earDA{|Gzx_hk9d2(k*Did+$9!0Q9bkWz~{e z=bQhZXJ+pIhUQ(Hn!{F0RU`=H&Wv0UvBE{_f`*gMwLAXMD=Q|5BI^4~524_VEAyv2 z-J$^ZOl!N@-9`6m$~^{@#`w`6wUc_gAJgzxnV3wWTK46y8L_R75Q`I+M+ALkJ*8 zFWoqLNP~nB{3Zod7}0RT<=O3lH`hsZj6P}}!Oy_x>_3Cj>6;ckQSb~u*yQ-9ddsE`m!9#A8Qaj(31y@Hi-Gi|0VqbGBEV-tqQLWGR%a?(W2l>qMJK06aW^s}v5TK*A%kTwLB!r@pwH z^fJn$M1A;_(X9RYrQW!Gs(EdpKe}4QAPft0ZSkx}GV~SA6 z`2hTRvOW9C1AnXBk@sY;YXuID9)$` z(W82MeY>rzjKdUoI4O55b`!JOmBT{{*CHJ%0PFqpdN(gsPIom9Nc4xG7Z)ousPnV7 z`154Ezf*u!)6;ytU^J|&3qtBwo(&1m}XAY z+z41Lgm3*jm>#CDC4VG?Q{`FT{%*Gj0R(sRRD@vl?!NF9aA3&|#-IMNwNVoSfh5t*YEMP3;2(?nM^1&8*czVYvFER^?qlrFe4Wv0hGzM*8%+;qy zM4AcU+Vn$VDyPFOVRaByP4(F?e5O1p(W}oMj9<)o*IM(__c8VfLCsK`Z|3pC16G#O zZQm)7VpyTi6SLHMoY-k^pb|~uYC#8}$R9SFuXK{DDve@%e`xB~#nLHF(k&{5VE8+3 zr_wgpB?=@nR@Nq;R!84XPk$sUjTOsha6h^Re6JN1l6(luq3FpV+X0fzgU|!p-!+M! z=%9+-itoXH)p=_1b!cFYhwzd@f0$O%+aK>v+i?O`0ESwJxl6?}yn1~}I65lhD2!n$ z2)%Ll?FaFlF6@7yKeC`krFFYzN2G0@jZ4f64y7II?yqrq`yb7+!-~l7>{nXv-T8KH z&P#=P#8FBxZL{4yI4ZvqV?D|KZW>sTB$D^qB=GO1N)GJ?~_3FzP=C3mN{-kwMy*&A{mGfrtwCn7)xi}YL-Otlb0EcwMsb}!y zf;$D@y8brq(PM^1YS&lSo69IqmRb$Z@^9LgEXmn><+@BVx}p$|h#V|Zq@aI}&OXDt zR$`muC7FcJXad($T&eYNU47Z0`*M>IrFAnd2IF0+w0__@5EvI9H@+|~#e+uxNL--1 zGSEzgb=X`Vwo{!_O+=bq3;wEr&p@cdVhDDdMPx&MA7`H#4*V3;5B_-idtXi8UyMln zfrJpcViWx_j39FD(&kxdV1?RBPY)sFW%LIz473$8z^G)>;KIe(Q(z+qvOlCLj(+75 z{;Cp-`0hX`6o<+tk=|5Sdmh)9buN#9R{kGl$AC5E1w!72XVpg6VTpa{1pH=#l7;?& zdNHFq#4vlB5RU(V#_(lH7gBeZU~kNvC=J@e<4P^@(Hv_Egi8XFWiL}s63hC#8#)U1 z%VOU0Q?(@>i^z6XeVoe55Od-)Q@drJ#iF$R6d7(i_hn%kb;~t4l-?1{7jy9 zpuzdlH3_Bgv@9%%lhivf>KG9*ed<P3qX2z2o<>k%=NdEF2!|>c=ZV zt#_0jr+Y+}N9@{*AK&(}?g)}f@$nt~kzF%3@$q$;ad*jImRL2}ZOE~O1&!+K#6K#F zyX#t!V+?*?THMEOi@pAN8n(xvhiW~(zSg*SMpDmuCF{i08#yspNNVeoU!&67q3w=) zkAL+CwrqGkA1}8v;#T-F-oB{-CE(pEkMH!HW=bI$BCMhUo&NEcPE83(!)y3Ow@AwF zzTMDV&Hjl17RgJ6d)Y1@e$Q&#KMd=!S_!W!jP8HBYAtnQc9L|k_w6;W?e3d~niduP zkz72$9}uI@0@ozKQ-BgJ5?G0{guC5JTb0}tparp#zY~+!a{MBa4Vn#g39x6WP}a&O z$QY~K3lR8)GtkwBhW}VtlEi`;h&oV3nnEP3X`w(6(FU3<2v4k7l5dfbK#PkeDr#~& zrTOzwA5|`3W&2(A2r;NXe3S;?l~}9QroIc9|Cea8#$-|#Duumq6qhbnCx1-D&t!*< z#Yenrw4$t^=KhfdN$r>g;^|_>Cb58Tw#8pb68(&2bFcU^<-wQP?Dwo%s1G-&UE2Qq zIx{4qJbhcqFNZ)0onLx;gJ^SA+#Qcm2zC4fCz?%ned5v&RG!ciaoi%bGX zsTXld{M=7F{fGBk1K{jVLg%*Rl28U1Jfxw7$g~!dVG0uJlfyx$pClP% zzyZH;_N6!2l*$`Z9+5_*%XJ&;KK!{VDqqVK&)yoEHkYY)i|uBdfcO2O#EAnfxw`QxNK5W|AW(33Z=54>5Cl2g4 zyfPVtJP9(GC`w=>DGWFhag)?1<`Mh*6_%r1>1lk01By0I5>fPpwWLt$itLgpgMI6nWDze#WU_f+yB0a@CC6dXt0(EdQ);!Gu2to{L(U#OY z<|!0LvY_at%ckVVhQxqZ;HSpL1aMZ6h|x;ye_tL>Kwwu>8?9j7}9RJPn}`E1hts{{zFclC^2I+?H{)n)qT9A1)^o7m?~Q)$>f+XsWAf~&#K<`3 zC_|fIl&A^iao25j@Xo(HLv`^-ul{=N#x`}YWPJW7BH?D?U7K+&$wpy#dpX-RS zdTD=FYA&9_+wU*u#(I#~@kes@!Cx2#@XVPsBv_M$h7ofn!7z$LUIl*J<>Sw0X+?T+ zW(K6|5z_f?OdLB{c6h))N6@~V4xV*JiTqgJ6w`j5=~`~()dgrv*#rG z^1t~{g;DJDb&)4aYzdp~S_EepE!j^d4{I17tzp3YSw)JwBJbnJCRX~iKL0&EzG)HQ zuh!R^x{%RkKsQWk5%znE-^ z2*(>htjR0aN02AQ+~b5M&=50GE7J;1I~)khWo9$7}IDQVRI|>$@OY_MH&_!eu!Jw+G^vqJkQ;LD7Hco z+l6^qk)Om-N~`wz?l-?qzL(apPJrDitkL+jEnWZH6$>d0`A_|U{@XuJsN?6pCXJy^NN$jYw}JBh<|Fm{7m$@Na}G2 zluGC-V`adyk0(^XBpVPF>FhY5svmrK|I4T%C#{g1#c`V&`t-%xRk)-y*(d#t&@82F=Bz42bmA*yI?$Lag-s(8dG?>QZM-fd2SkWJ1 zB8h)=-p9Zc@z>*(`qz1>1yK4#IB=O~;0&-Q2lrd!FsH{kwZI=$KjCBOq9h^3SMled7UQM4-YM7&Utho> zRtwk%YeUgMB!b<#dwiTl&S(<-Js?BO4z6`$Py~B;z`odiGJyQV1AN|Sk5%BBXS93D z?}nP_z26AF3m8^*AL~j;_d#d>bic?m%Wx>1grdJ-5ZAK7ZsImJ-T}70Z!6`|$Ecbz zI$;O=6`qtGPqdU9GQNeY63dRl4`s;EtTuL!pZX)=bFpkcp>k+rk1EUAC&$iID5Fa`hyDuQ*jRH}XtS zxUsTaTBXs;c6(@-b`Kr?hc^HQ^hfHvqGRHKr>S<{HQmZ8?d@(kZb~41K9y!cVYfT+ zP4^-A8ngd&uM7e&LFdLW*B`pl{C!h8{N&I#K2v-B8nh@MzC8UY(#VMpv6BdD`SkJi zDcQ7QHd3L2-5i@(xd0QTL@)Y4$^&roF8sxG?yApD z31EybCg1tb@4pWT;72*dgV7(X(B(ZrfriQ3>CYcyDz3Ng{D^_##Y6_v6?Tm%6iV85QT&^uwvMg7k<>Jw>Db`xhKG(TzWh~Ns#B}xK+kK z$*TJEP&)t0WUCl3#j}d5mY=@gem||Znf{_{Gd)u`^XloYE?SfJWoZVS+SnG~BAn~A_gTli`Gy|iRYUW8X64cQln{U*8j{87BksCMUR z3P31G83fhA$5>gcYi5=6!#b0ott+OQhEn2!ej`xs18S>BNx#kRX4=wEf|19-hO_Gs z!orG>rCFI?WzzO-I)E%DrskLv)aGD=;-~QS?UYXbYtk zl@9l^+$4&*Db^eIBj@D1pLUm*z^Qus%SxhntFZMr5b@zGEOuQea4t~j9&B|c&D@H& zD5be95KqT>8+g$Ex0=PdcXXd>v>V|PkSZ@ud&(yorbYJHWB30BFf=$7~2 zzkN(?BS7>ygZk`xJ@gtGAmgfkX2f*mdC81@%Zhg45P2# zHAiJxac@==ayuNaH{0~U4NaaxV14BFM&I_%`^+0nE$wj+iMhCO14tIbzf<0RR4-5X zP@z6h#%W;#rA2qU4auwmeAz@P?RsQkEee}9{;5-rKg8biX%bzr`|1Qvb^KLLCc^in zdN$LF1vXlpd?KOA#18;T|Fcsl6JHh@M&FS)+rLcy7=51$*n`02`^!Rl)`C{at+5>(%h!bQ;xIO4X zdLsly{$3W78%9Yr%9X)RotqA7MetoHKns$3W%;_`nhft18zw9OD>AuBcTz-p($upz z>S(;{zd5^=+vg`uh4K{HMycEYOtd3_XVhW=aCuDGLS94xHapr2f;XRQd5yumUmG3I z+Q_DpVz8GTkB@_PAgWy6KDJ9nbm+EwzsB21rmAhXo#nn`kP}a(B>40AsGU9js&x5= zO{z9!o9HMPBG+x8L+Yi*?yOm#qRC2UJCnXxVxESnjyVFMp&3TFs^07Vhr-M}N=${Y zI<@})Oe?2%aUw??(-9a8ptiuOQ@`SWB$H`S=xa3v(kgO8`C{_< zG@2&DzT$-G^}#9wg~RoJj)(B=C=iU0eP#ezx^K`LJ|c({U}`tEmy3MdJXzi&N=w9f zeX|)FWG6nJEsUL>Txhw+$<<>xP}uAeF$|?OOGc}7J9%kV?B(DDgBSfRJLKl9_;r-?0_()TPu~L_+qj*JgkEJ*Fz*++EjzIu+*(@|+~KNj@TjW&b=32eYWt>`B#MR}j z;-0jJ)%l;D`t+}USsPml)Fx|^|27{z8)fdA$vZ?!>2T}y-WN8YNBCG^Em4|Wu>id= zdab7qO+HV&b&FgxnG=nv^GJ?0;?t?r z*0SHoY zOSF|c2~5Z!!5`4DkUw$(Phf>ef!``PfZjv>cr2U$33!~NPozHNJ(HPM6)(a}hhk_Q+m3mqt_=&cp9QayM(I_wcV6KrLx|mrW z^(|OKePGt3pkbA-s9)K5!Os}}apxd*=jm%q7OgJVh@$c!EpsdK2Iea6x*9e4jhOM_ zRQ#hlq*hwJ&A7hz7g9y@_rd%;Z)|+A7#oWuDiQW?*`tf_=L|I2)4}PsPIwIFYwF zBc3Ez2rw~1wSwqBKF)=48|CqrFCsiJg;xqhl}H5o6NOG3fgTy@BMtPzWG2nQJgD{i z*O!~+e1CIJoBITk)42ocCYhHv&Vr?;osCucv_M;zwYa_>$gRawE6LBI_w1jbo%}OB zMrbTG5~J4S;r@8ojSW_$pmSR&556N20^T68dpJ)Se1wEsp{=9Cvq8aU&k!Aw?Meh^ zwEI4V&4cxBGK&9ExK@k@`XlsN@sJrE)$N05C=uVx{UA>IEmTkE!FlD~Tl60GWc+Bt zJ-mz$hmII2N?lGEho$A0Wt}akfRkW_7IMoH8T|xVs*N%$-csh2pu%dmnqXd(?eOIz zu~wK^b_73a0n2`BJEU0LhFeRGSWLJ--KA(Rf27Ty@aUG+s7$_g%CmnkO(7p#B6H2v z(mcGVtF}3uqwTMMuHqVWts7F18}x@Hry{>LK4~~-B@ZS@M}qZEJN76PG55fwo#@awml@j=!l;k1hQbO~+k7t#Q*L znAP2`JKHh;tXpYdb@X^Q&8{_Y0QsEOXn`Q5bD6F%N7&40#I$d(HmmjJ%~(=Qv-$NF z_iwwX7nG9jI=X5!q+4Qvqd&k90Hi<4hyM;M)AT_U_{Ewaed^`?@p!}`vC*i;@$Gq5 z2jm49t4x%yFaIhrB1WROqenwYV5`U9kIlHekqaye!d*pI!>P_z;{gA^_J-W9M9+ej zh5kq2Lz}p&cMO6>KxFvr>63I+PR&XBN98lQs0~Zyay$x7zTMIn<~2 zl`oa)vk~zaFN!alB`npLvSMSJB};s89Y?EDUm~3QjaYc$+>>Z<%)|9Ye1Ifa;QunX zTj?12ik%M?VYJKb#rY%euzfh(KC3v>C}#b76_%ETFI#r=XQ}+^hz9 z)$~vX@TC4+%s5cDn(&O$tIt9C5K>m;XykMu;@qa>gADDp)K_Bydh)bFLRAF+l%AUPH1P9lp>(Z*3XysA#nY>=jGyj zFW#ueJ)z#<5VKqV)Txm|2^;g4AiRykC3MUM!Cj|5m)?+mI{jCD0JdVK$v0804{%u| zg>$Dva<4X6t)Tz%G9~A&j$|iKx!exSk}Bd%g(uZ)aE8i_QvYM0Fs(@6<$ES^g&uPR z2_Z}dwflQIk5tQT_erFiRoAGW*R}aYb|H|6Vsr}S!)eG`1xI)jK^x~w-v%A?hTij7Lu-Mi9wG7@%h1F4fX1&a$lDJHrg-(ZQf4o4IhkZK9DE@Ds@~jOm1DSlP9f0_hcKCMcH`cBS%f2eGcA~zs`P|t zWkD7?6-o?S7rQ4JrOnl0wq2;DVO$wjoe`jRH_lQNR_r_HOlYB_CR&nQd;Qf8vt0CV zk2@C;puUn3P&irAyRQFBoA+pF*RQXX~~2*hl>r% zDC2`GQWiG`2!T^hlG>7!|?);>tFJ!6s|M5dD#N_GX4tweL^T#p<2a7um^n zF;-oE?$<<5T-jVy14V!ylw<++DqprQS3{gI97eaQ0Cr(TMD@Rt?4!=gDe!%$S@D$9}idhgN^~)v5%Q0xCyhZ7$HIK96;}M)IG9X>h8Bi0O0cRv6UDdqZBWi zHhU~Yy&fiW`%ox#s6!rG<^4bH(o%QIDBjPMr>Rx^}8v(}av;8NaXBucMN@9lC?- zFOHvxO44`{Uhpn}8A71mefsY;#SQT+tPKokQIr35=2&fZz^5Eqk!5B6?x+5c%s2N= z#EUoHAH6T1cBRZa^3!+;nAZ6lZ*p=;qcG~gW{2v;P$4!a*H-^AwQpY5Qr)=b5~NOllskW{s@|3U4mG-FNUAG(c#&;KvJ!_) z6tY>n{rW6|5dD!nCHNYzH7-yLgM25=Dy+3|tc$dOXg7x^l_mCEp+Cq0#UvZ9HCnGi z5$1zQbfs~8`M5Rrm;QK`k8aka{>=2pX`^3HvuN=Ouwqpg=puL2H5hJgj^-3%{R+0G z&>z|puZM%Bw&DzGWev7VdocCCT}{AsO22^r6s zx0M89wt%h_Y|~Ev*Ty%7+v9MkrEMZoMUi5o@pLbfrqug5DAIIjo$DJNkx(|HpWPC} zygYlKJlq16x@vC4e=;T56TPQVx%u3$0EI|8S!!4AX5C8{U*_Z`+yJJ`>Ij4CafT)g zu7;IT|7ylmqcOQVA}g3w8XwO1Lk_Gk8K7(IbqtSy7@nxmtkBmFl}9AvZE^N8Ey5-ojUwC0W(RC`@^|r9@jj>z_Lq-BcT$gXZ3|VUNyN?ld7%TS zEl$EmESXTji4;OwN76vWa+4gL0C63`;?1Oe*m z`DeNG{!&7Wqao-IA#8QT?bJN6eF8b06d8CL&$bT+l0k~XrDeV86Z(8sVk^OjM5@&F z0dbEcAxfEqtL&FpNE6yOmR=s9ar*JnugmiZNOo$K=@xU;sY-&RjE#LGqAjH~=m*;eKKYe&-sIaD*MO~s<*sqHo+ z;L|$-1eEL3+tbACy_ynOmPBB;*myRDb1BvVVy&JyXstpkO2zbQlU}uO6D8rIXe0eHYZr7!vAB(k92O@8N zlP)nT0m_6z&e_4x`-hD66|Rp@kA1H9);H(vsMc}zKrc7dDfOjwNaM&FTwLF!KSGS7 zaBS%I%T>D{R!a8YUGH@(n>Pt;;~P6%q?FmjVjqcbSc_znT7UC*W7y95lE_TiB^k!92H7W4Yzqci!ttDrRq z0$BM=x^MQ_k>s9h5qET2<-Yw!H3#?5q2?z0w$o4h7V>;HoPW@=e{jy6%yB z4B=%0R@OS0Z0G5%>#1S4P&bW+1+O2D1IA|mu4JLLi9ELlayDQbUjia5P1ka44Bf_)&tSlDa zdRlcJPZGlIR;#}JD8=qC3NX+V#)NTkjG~u1Nm}U(Bur(n=$y7?jG8xg@d_fL^K_y= zv^M#&FAMEJ%g_ag9O*g!koEe9ZRHwc`TUL`C!g5%Y3L=xY%|?Tb0*sxpaS32grL8Z?0b7D%0D>;X!f%#u>)JUCnFtgQYMz4yFC8Q783`$hf_z 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 xk0~xWbPHd%|zGlO=F+Vo`GdviW{}xS^)4Q9K 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%0D`MTDTy*oYS(Z-moX3W$*cqHX6P$qN8P*ivJo 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