mirror of
https://github.com/Xahau/xahaud.git
synced 2026-04-29 15:37:46 +00:00
Squashed 'src/nudb/' content from commit 00adc6a
git-subtree-dir: src/nudb git-subtree-split: 00adc6a4f16679a376f40c967f77dfa544c179c1
This commit is contained in:
250
test/basic_store.cpp
Normal file
250
test/basic_store.cpp
Normal file
@@ -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 <nudb/basic_store.hpp>
|
||||
|
||||
#include <nudb/test/test_store.hpp>
|
||||
#include <nudb/detail/arena.hpp>
|
||||
#include <nudb/detail/cache.hpp>
|
||||
#include <nudb/detail/pool.hpp>
|
||||
#include <nudb/progress.hpp>
|
||||
#include <nudb/verify.hpp>
|
||||
#include <beast/unit_test/suite.hpp>
|
||||
#include <limits>
|
||||
#include <type_traits>
|
||||
|
||||
namespace nudb {
|
||||
|
||||
namespace detail {
|
||||
|
||||
static_assert(!std::is_copy_constructible <arena>{}, "");
|
||||
static_assert(!std::is_copy_assignable <arena>{}, "");
|
||||
static_assert( std::is_move_constructible <arena>{}, "");
|
||||
static_assert(!std::is_move_assignable <arena>{}, "");
|
||||
|
||||
static_assert(!std::is_copy_constructible <cache>{}, "");
|
||||
static_assert(!std::is_copy_assignable <cache>{}, "");
|
||||
static_assert( std::is_move_constructible <cache>{}, "");
|
||||
static_assert(!std::is_move_assignable <cache>{}, "");
|
||||
|
||||
static_assert(!std::is_copy_constructible <pool>{}, "");
|
||||
static_assert(!std::is_copy_assignable <pool>{}, "");
|
||||
static_assert( std::is_move_constructible <pool>{}, "");
|
||||
static_assert(!std::is_move_assignable <pool>{}, "");
|
||||
|
||||
} // 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<xxhasher>(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
|
||||
|
||||
Reference in New Issue
Block a user