test refactoring - work in progress
This commit is contained in:
parent
55a62f9640
commit
c22cdf929d
@ -1,46 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <list>
|
||||
|
||||
#include "threading/sync/lockable.hpp"
|
||||
#include "threading/sync/spinlock.hpp"
|
||||
|
||||
template <typename value_type, typename lock_type = SpinLock>
|
||||
class LinkedList : public Lockable<lock_type>
|
||||
{
|
||||
public:
|
||||
std::size_t size() const
|
||||
{
|
||||
auto guard = this->acquire_unique();
|
||||
return data.size();
|
||||
}
|
||||
|
||||
void push_front(const value_type &value)
|
||||
{
|
||||
auto guard = this->acquire_unique();
|
||||
data.push_front(value);
|
||||
}
|
||||
|
||||
void push_front(value_type &&value)
|
||||
{
|
||||
auto guard = this->acquire_unique();
|
||||
data.push_front(std::forward<value_type>(value));
|
||||
}
|
||||
|
||||
void pop_front()
|
||||
{
|
||||
auto guard = this->acquire_unique();
|
||||
data.pop_front();
|
||||
}
|
||||
|
||||
// value_type& as return value
|
||||
// would not be concurrent
|
||||
value_type front()
|
||||
{
|
||||
auto guard = this->acquire_unique();
|
||||
return data.front();
|
||||
}
|
||||
|
||||
private:
|
||||
std::list<value_type> data;
|
||||
};
|
@ -8,13 +8,15 @@
|
||||
|
||||
#include "logging/default.hpp"
|
||||
|
||||
/** @class Timer
|
||||
* @brief The timer contains counter and handler.
|
||||
/**
|
||||
* @class Timer
|
||||
*
|
||||
* With every clock interval the counter should be decresed for
|
||||
* delta count. Delta count is one for now but it should be a variable in the
|
||||
* near future. The handler is function that will be called when counter
|
||||
* becomes zero or smaller than zero.
|
||||
* @brief The timer contains counter and handler.
|
||||
*
|
||||
* With every clock interval the counter should be decresed for
|
||||
* delta count. Delta count is one for now but it should be a variable in the
|
||||
* near future. The handler is function that will be called when counter
|
||||
* becomes zero or smaller than zero.
|
||||
*/
|
||||
struct Timer
|
||||
{
|
||||
@ -48,14 +50,16 @@ struct Timer
|
||||
* the process method.
|
||||
*/
|
||||
|
||||
/** @class TimerSet
|
||||
* @brief Trivial timer container implementation.
|
||||
/**
|
||||
* @class TimerSet
|
||||
*
|
||||
* Internal data stucture for storage of timers is std::set. So, the
|
||||
* related timer complexities are:
|
||||
* insertion: O(log(n))
|
||||
* deletion: O(log(n))
|
||||
* process: O(n)
|
||||
* @brief Trivial timer container implementation.
|
||||
*
|
||||
* Internal data stucture for storage of timers is std::set. So, the
|
||||
* related timer complexities are:
|
||||
* insertion: O(log(n))
|
||||
* deletion: O(log(n))
|
||||
* process: O(n)
|
||||
*/
|
||||
class TimerSet
|
||||
{
|
||||
@ -70,6 +74,11 @@ public:
|
||||
timers.erase(timer);
|
||||
}
|
||||
|
||||
uint64_t size() const
|
||||
{
|
||||
return timers.size();
|
||||
}
|
||||
|
||||
void process()
|
||||
{
|
||||
for (auto it = timers.begin(); it != timers.end(); ) {
|
||||
@ -87,10 +96,17 @@ private:
|
||||
std::set<std::shared_ptr<Timer>> timers;
|
||||
};
|
||||
|
||||
/** @class TimerScheduler
|
||||
* @brief TimerScheduler is a manager class and its responsibility is to
|
||||
* take care of the time and call the timer_container process method in the
|
||||
* appropriate time.
|
||||
/**
|
||||
* @class TimerScheduler
|
||||
*
|
||||
* @brief TimerScheduler is a manager class and its responsibility is to
|
||||
* take care of the time and call the timer_container process method in the
|
||||
* appropriate time.
|
||||
*
|
||||
* @tparam timer_container_type implements a strategy how the timers
|
||||
* are processed
|
||||
* @tparam delta_time_type type of a time distance between two events
|
||||
* @tparam delta_time granularity between the two events, default value is 1
|
||||
*/
|
||||
template <
|
||||
typename timer_container_type,
|
||||
@ -99,19 +115,47 @@ template <
|
||||
> class TimerScheduler
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Adds a timer.
|
||||
*
|
||||
* @param timer shared pointer to the timer object \ref Timer
|
||||
*/
|
||||
void add(Timer::sptr timer)
|
||||
{
|
||||
timer_container.add(timer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a timer.
|
||||
*
|
||||
* @param timer shared pointer to the timer object \ref Timer
|
||||
*/
|
||||
void remove(Timer::sptr timer)
|
||||
{
|
||||
timer_container.remove(timer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the number of pending timers. The exact number has to be
|
||||
* provided by a timer_container.
|
||||
*
|
||||
* @return uint64_t the number of pending timers.
|
||||
*/
|
||||
uint64_t size() const
|
||||
{
|
||||
return timer_container.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs a separate thread which responsibility is to run the process method
|
||||
* at the appropriate time (every delta_time from the beginning of
|
||||
* processing.
|
||||
*/
|
||||
void run()
|
||||
{
|
||||
is_running.store(true);
|
||||
|
||||
run_thread = std::thread([this]() {
|
||||
while (is_running.load()) {
|
||||
std::this_thread::sleep_for(delta_time_type(delta_time));
|
||||
@ -121,11 +165,17 @@ public:
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops the whole processing.
|
||||
*/
|
||||
void stop()
|
||||
{
|
||||
is_running.store(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Joins the processing thread.
|
||||
*/
|
||||
~TimerScheduler()
|
||||
{
|
||||
run_thread.join();
|
||||
|
@ -6,6 +6,8 @@ enable_testing()
|
||||
|
||||
include_directories(${catch_source_dir}/include)
|
||||
|
||||
file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/test_results)
|
||||
|
||||
# copy test data
|
||||
file(COPY ${CMAKE_SOURCE_DIR}/tests/data
|
||||
DESTINATION ${CMAKE_BINARY_DIR}/tests)
|
||||
|
@ -1,6 +1,8 @@
|
||||
#include <random>
|
||||
#include <thread>
|
||||
|
||||
#include "benchmark/benchmark_api.h"
|
||||
|
||||
#include "data_structures/bloom/bloom_filter.hpp"
|
||||
#include "logging/default.hpp"
|
||||
#include "logging/streams/stdout.hpp"
|
||||
@ -8,52 +10,49 @@
|
||||
#include "utils/hashing/fnv64.hpp"
|
||||
#include "utils/random/generator.h"
|
||||
|
||||
#include "benchmark/benchmark_api.h"
|
||||
|
||||
using utils::random::StringGenerator;
|
||||
using StringHashFunction = std::function<uint64_t(const std::string&)>;
|
||||
using StringHashFunction = std::function<uint64_t(const std::string &)>;
|
||||
|
||||
template <class Type, int Size>
|
||||
static void TestBloom(benchmark::State& state, BloomFilter<Type, Size>*
|
||||
bloom, const std::vector<Type>& elements) {
|
||||
while(state.KeepRunning()) {
|
||||
for (int start = 0; start < state.range(0); start++)
|
||||
if (start % 2) bloom->contains(elements[start]);
|
||||
else bloom->insert(elements[start]);
|
||||
}
|
||||
state.SetComplexityN(state.range(0));
|
||||
static void TestBloom(benchmark::State &state, BloomFilter<Type, Size> *bloom,
|
||||
const std::vector<Type> &elements)
|
||||
{
|
||||
while (state.KeepRunning())
|
||||
{
|
||||
for (int start = 0; start < state.range(0); start++)
|
||||
if (start % 2)
|
||||
bloom->contains(elements[start]);
|
||||
else
|
||||
bloom->insert(elements[start]);
|
||||
}
|
||||
state.SetComplexityN(state.range(0));
|
||||
}
|
||||
|
||||
auto BM_Bloom = [](benchmark::State& state, auto* bloom, const auto& elements) {
|
||||
TestBloom(state, bloom, elements);
|
||||
auto BM_Bloom = [](benchmark::State &state, auto *bloom, const auto &elements) {
|
||||
TestBloom(state, bloom, elements);
|
||||
};
|
||||
|
||||
void parse_args(int argc, char** argv) {}
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
logging::init_async();
|
||||
logging::log->pipe(std::make_unique<Stdout>());
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
logging::init_async();
|
||||
logging::log->pipe(std::make_unique<Stdout>());
|
||||
StringGenerator generator(4);
|
||||
|
||||
parse_args(argc, argv);
|
||||
auto elements = utils::random::generate_vector(generator, 1 << 16);
|
||||
|
||||
StringGenerator generator(4);
|
||||
|
||||
auto elements = utils::random::generate_vector(generator, 1 << 16);
|
||||
|
||||
StringHashFunction hash1 = fnv64<std::string>;
|
||||
StringHashFunction hash2 = fnv1a64<std::string>;
|
||||
std::vector<StringHashFunction> funcs = {
|
||||
hash1, hash2
|
||||
};
|
||||
StringHashFunction hash1 = fnv64<std::string>;
|
||||
StringHashFunction hash2 = fnv1a64<std::string>;
|
||||
std::vector<StringHashFunction> funcs = {hash1, hash2};
|
||||
|
||||
BloomFilter<std::string, 128> bloom(funcs);
|
||||
BloomFilter<std::string, 128> bloom(funcs);
|
||||
|
||||
benchmark::RegisterBenchmark("SimpleBloomFilter Benchmark Test", BM_Bloom,
|
||||
&bloom, elements)
|
||||
->RangeMultiplier(2)
|
||||
->Range(1, 1 << 16)
|
||||
->Complexity(benchmark::oN);
|
||||
benchmark::RegisterBenchmark("SimpleBloomFilter Benchmark Test", BM_Bloom,
|
||||
&bloom, elements)
|
||||
->RangeMultiplier(2)
|
||||
->Range(1, 1 << 16)
|
||||
->Complexity(benchmark::oN);
|
||||
|
||||
benchmark::Initialize(&argc, argv);
|
||||
benchmark::RunSpecifiedBenchmarks();
|
||||
benchmark::Initialize(&argc, argv);
|
||||
benchmark::RunSpecifiedBenchmarks();
|
||||
}
|
||||
|
@ -27,7 +27,7 @@
|
||||
using utils::random::NumberGenerator;
|
||||
using utils::random::PairGenerator;
|
||||
using utils::random::StringGenerator;
|
||||
using StringHashFunction = std::function<uint64_t(const std::string&)>;
|
||||
using StringHashFunction = std::function<uint64_t(const std::string &)>;
|
||||
|
||||
using IntegerGenerator = NumberGenerator<std::uniform_int_distribution<int>,
|
||||
std::default_random_engine, int>;
|
||||
@ -40,36 +40,44 @@ int THREADS, RANGE_START, RANGE_END, STRING_LENGTH;
|
||||
ConcurrentMap Insertion Benchmark Test
|
||||
*/
|
||||
template <class K, class V, class F>
|
||||
static void InsertValue(benchmark::State& state, ConcurrentBloomMap<K, V, F>* map,
|
||||
const std::vector<std::pair<K, V>>& elements) {
|
||||
while (state.KeepRunning()) {
|
||||
for (int start = 0; start < state.range(0); start++) {
|
||||
map->insert(elements[start].first, elements[start].second);
|
||||
static void InsertValue(benchmark::State &state,
|
||||
ConcurrentBloomMap<K, V, F> *map,
|
||||
const std::vector<std::pair<K, V>> &elements)
|
||||
{
|
||||
while (state.KeepRunning())
|
||||
{
|
||||
for (int start = 0; start < state.range(0); start++)
|
||||
{
|
||||
map->insert(elements[start].first, elements[start].second);
|
||||
}
|
||||
}
|
||||
}
|
||||
state.SetComplexityN(state.range(0));
|
||||
state.SetComplexityN(state.range(0));
|
||||
}
|
||||
|
||||
/*
|
||||
ConcurrentMap Contains Benchmark Test
|
||||
*/
|
||||
template <class K, class V, class F>
|
||||
static void ContainsValue(benchmark::State& state, ConcurrentBloomMap<K, V, F>* map,
|
||||
const std::vector<std::pair<K, V>> elements) {
|
||||
while (state.KeepRunning()) {
|
||||
for (int start = 0; start < state.range(0); start++) {
|
||||
map->contains(elements[start].first);
|
||||
static void ContainsValue(benchmark::State &state,
|
||||
ConcurrentBloomMap<K, V, F> *map,
|
||||
const std::vector<std::pair<K, V>> elements)
|
||||
{
|
||||
while (state.KeepRunning())
|
||||
{
|
||||
for (int start = 0; start < state.range(0); start++)
|
||||
{
|
||||
map->contains(elements[start].first);
|
||||
}
|
||||
}
|
||||
}
|
||||
state.SetComplexityN(state.range(0));
|
||||
state.SetComplexityN(state.range(0));
|
||||
}
|
||||
|
||||
auto BM_InsertValue = [](benchmark::State& state, auto* map, auto& elements) {
|
||||
InsertValue(state, map, elements);
|
||||
auto BM_InsertValue = [](benchmark::State &state, auto *map, auto &elements) {
|
||||
InsertValue(state, map, elements);
|
||||
};
|
||||
|
||||
auto BM_ContainsValue = [](benchmark::State& state, auto* map, auto elements) {
|
||||
ContainsValue(state, map, elements);
|
||||
auto BM_ContainsValue = [](benchmark::State &state, auto *map, auto elements) {
|
||||
ContainsValue(state, map, elements);
|
||||
};
|
||||
|
||||
/*
|
||||
@ -88,99 +96,98 @@ auto BM_ContainsValue = [](benchmark::State& state, auto* map, auto elements) {
|
||||
* Random String lenght
|
||||
-string-length number
|
||||
*/
|
||||
void parse_arguments(int argc, char** argv) {
|
||||
REGISTER_ARGS(argc, argv);
|
||||
void parse_arguments(int argc, char **argv)
|
||||
{
|
||||
REGISTER_ARGS(argc, argv);
|
||||
|
||||
RANGE_START = GET_ARG("-start", "0").get_int();
|
||||
RANGE_END = GET_ARG("-end", "1000000000").get_int();
|
||||
RANGE_START = GET_ARG("-start", "0").get_int();
|
||||
RANGE_END = GET_ARG("-end", "1000000000").get_int();
|
||||
|
||||
THREADS = std::min(GET_ARG("-threads", "1").get_int(),
|
||||
(int)std::thread::hardware_concurrency());
|
||||
THREADS = std::min(GET_ARG("-threads", "1").get_int(),
|
||||
(int)std::thread::hardware_concurrency());
|
||||
|
||||
STRING_LENGTH =
|
||||
ProgramArguments::instance().get_arg("-string-length", "128").get_int();
|
||||
STRING_LENGTH =
|
||||
ProgramArguments::instance().get_arg("-string-length", "128").get_int();
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
logging::init_async();
|
||||
logging::log->pipe(std::make_unique<Stdout>());
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
logging::init_async();
|
||||
logging::log->pipe(std::make_unique<Stdout>());
|
||||
|
||||
parse_arguments(argc, argv);
|
||||
parse_arguments(argc, argv);
|
||||
|
||||
StringGenerator sg(STRING_LENGTH);
|
||||
IntegerGenerator ig(RANGE_START, RANGE_END);
|
||||
StringGenerator sg(STRING_LENGTH);
|
||||
IntegerGenerator ig(RANGE_START, RANGE_END);
|
||||
|
||||
/*
|
||||
Creates RandomGenerators, ConcurentMaps and Random Element Vectors for the
|
||||
following use cases:
|
||||
/*
|
||||
Creates RandomGenerators, ConcurentMaps and Random Element Vectors for the
|
||||
following use cases:
|
||||
|
||||
Map elements contain keys and value for:
|
||||
<int, int>,
|
||||
<int, string>
|
||||
<string, int>
|
||||
<string, string>
|
||||
*/
|
||||
Map elements contain keys and value for:
|
||||
<int, int>,
|
||||
<int, string>
|
||||
<string, int>
|
||||
<string, string>
|
||||
*/
|
||||
|
||||
// random generators for tests
|
||||
PairGenerator<IntegerGenerator, IntegerGenerator> piig(&ig, &ig);
|
||||
PairGenerator<StringGenerator, StringGenerator> pssg(&sg, &sg);
|
||||
PairGenerator<StringGenerator, IntegerGenerator> psig(&sg, &ig);
|
||||
PairGenerator<IntegerGenerator, StringGenerator> pisg(&ig, &sg);
|
||||
// random generators for tests
|
||||
PairGenerator<IntegerGenerator, IntegerGenerator> piig(&ig, &ig);
|
||||
PairGenerator<StringGenerator, StringGenerator> pssg(&sg, &sg);
|
||||
PairGenerator<StringGenerator, IntegerGenerator> psig(&sg, &ig);
|
||||
PairGenerator<IntegerGenerator, StringGenerator> pisg(&ig, &sg);
|
||||
|
||||
StringHashFunction hash1 = fnv64<std::string>;
|
||||
StringHashFunction hash2 = fnv1a64<std::string>;
|
||||
std::vector<StringHashFunction> funcs = {
|
||||
hash1, hash2
|
||||
};
|
||||
StringHashFunction hash1 = fnv64<std::string>;
|
||||
StringHashFunction hash2 = fnv1a64<std::string>;
|
||||
std::vector<StringHashFunction> funcs = {hash1, hash2};
|
||||
|
||||
BloomFilter<std::string, 128> bloom_filter_(funcs);
|
||||
BloomFilter<std::string, 128> bloom_filter_(funcs);
|
||||
|
||||
// maps used for testing
|
||||
//ConcurrentBloomMap<int, int> ii_map;
|
||||
//ConcurrentBloomMap<int, std::string> is_map;
|
||||
using Filter = BloomFilter<std::string, 128>;
|
||||
ConcurrentBloomMap<std::string, int, Filter > si_map(bloom_filter_);
|
||||
ConcurrentBloomMap<std::string, std::string, Filter>
|
||||
ss_map(bloom_filter_);
|
||||
// maps used for testing
|
||||
// ConcurrentBloomMap<int, int> ii_map;
|
||||
// ConcurrentBloomMap<int, std::string> is_map;
|
||||
using Filter = BloomFilter<std::string, 128>;
|
||||
ConcurrentBloomMap<std::string, int, Filter> si_map(bloom_filter_);
|
||||
ConcurrentBloomMap<std::string, std::string, Filter> ss_map(bloom_filter_);
|
||||
|
||||
// random elements for testing
|
||||
//auto ii_elems = utils::random::generate_vector(piig, MAX_ELEMENTS);
|
||||
//auto is_elems = utils::random::generate_vector(pisg, MAX_ELEMENTS);
|
||||
auto si_elems = utils::random::generate_vector(psig, MAX_ELEMENTS);
|
||||
auto ss_elems = utils::random::generate_vector(pssg, MAX_ELEMENTS);
|
||||
// random elements for testing
|
||||
// auto ii_elems = utils::random::generate_vector(piig, MAX_ELEMENTS);
|
||||
// auto is_elems = utils::random::generate_vector(pisg, MAX_ELEMENTS);
|
||||
auto si_elems = utils::random::generate_vector(psig, MAX_ELEMENTS);
|
||||
auto ss_elems = utils::random::generate_vector(pssg, MAX_ELEMENTS);
|
||||
|
||||
/* insertion Tests */
|
||||
benchmark::RegisterBenchmark("InsertValue[String, Int]", BM_InsertValue,
|
||||
&si_map, si_elems)
|
||||
->RangeMultiplier(MULTIPLIER)
|
||||
->Range(1, MAX_ELEMENTS)
|
||||
->Complexity(benchmark::oN)
|
||||
->Threads(THREADS);
|
||||
/* insertion Tests */
|
||||
benchmark::RegisterBenchmark("InsertValue[String, Int]", BM_InsertValue,
|
||||
&si_map, si_elems)
|
||||
->RangeMultiplier(MULTIPLIER)
|
||||
->Range(1, MAX_ELEMENTS)
|
||||
->Complexity(benchmark::oN)
|
||||
->Threads(THREADS);
|
||||
|
||||
benchmark::RegisterBenchmark("InsertValue[String, String]", BM_InsertValue,
|
||||
&ss_map, ss_elems)
|
||||
->RangeMultiplier(MULTIPLIER)
|
||||
->Range(1, MAX_ELEMENTS)
|
||||
->Complexity(benchmark::oN)
|
||||
->Threads(THREADS);
|
||||
benchmark::RegisterBenchmark("InsertValue[String, String]", BM_InsertValue,
|
||||
&ss_map, ss_elems)
|
||||
->RangeMultiplier(MULTIPLIER)
|
||||
->Range(1, MAX_ELEMENTS)
|
||||
->Complexity(benchmark::oN)
|
||||
->Threads(THREADS);
|
||||
|
||||
// Contains Benchmark Tests
|
||||
benchmark::RegisterBenchmark("ContainsValue[String, Int]", BM_ContainsValue,
|
||||
&si_map, si_elems)
|
||||
->RangeMultiplier(MULTIPLIER)
|
||||
->Range(1, MAX_ELEMENTS)
|
||||
->Complexity(benchmark::oN)
|
||||
->Threads(THREADS);
|
||||
// Contains Benchmark Tests
|
||||
benchmark::RegisterBenchmark("ContainsValue[String, Int]", BM_ContainsValue,
|
||||
&si_map, si_elems)
|
||||
->RangeMultiplier(MULTIPLIER)
|
||||
->Range(1, MAX_ELEMENTS)
|
||||
->Complexity(benchmark::oN)
|
||||
->Threads(THREADS);
|
||||
|
||||
benchmark::RegisterBenchmark("ContainsValue[String, String]",
|
||||
BM_ContainsValue, &ss_map, ss_elems)
|
||||
->RangeMultiplier(MULTIPLIER)
|
||||
->Range(1, MAX_ELEMENTS)
|
||||
->Complexity(benchmark::oN)
|
||||
->Threads(THREADS);
|
||||
benchmark::RegisterBenchmark("ContainsValue[String, String]",
|
||||
BM_ContainsValue, &ss_map, ss_elems)
|
||||
->RangeMultiplier(MULTIPLIER)
|
||||
->Range(1, MAX_ELEMENTS)
|
||||
->Complexity(benchmark::oN)
|
||||
->Threads(THREADS);
|
||||
|
||||
benchmark::Initialize(&argc, argv);
|
||||
benchmark::RunSpecifiedBenchmarks();
|
||||
benchmark::Initialize(&argc, argv);
|
||||
benchmark::RunSpecifiedBenchmarks();
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
@ -37,57 +37,66 @@ int THREADS, RANGE_START, RANGE_END, STRING_LENGTH;
|
||||
ConcurrentMap Insertion Benchmark Test
|
||||
*/
|
||||
template <class K, class V>
|
||||
static void InsertValue(benchmark::State& state, ConcurrentMap<K, V>* map,
|
||||
const std::vector<std::pair<K, V>>& elements) {
|
||||
while (state.KeepRunning()) {
|
||||
auto accessor = map->access();
|
||||
for (int start = 0; start < state.range(0); start++) {
|
||||
accessor.insert(elements[start].first, elements[start].second);
|
||||
static void InsertValue(benchmark::State &state, ConcurrentMap<K, V> *map,
|
||||
const std::vector<std::pair<K, V>> &elements)
|
||||
{
|
||||
while (state.KeepRunning())
|
||||
{
|
||||
auto accessor = map->access();
|
||||
for (int start = 0; start < state.range(0); start++)
|
||||
{
|
||||
accessor.insert(elements[start].first, elements[start].second);
|
||||
}
|
||||
}
|
||||
}
|
||||
state.SetComplexityN(state.range(0));
|
||||
state.SetComplexityN(state.range(0));
|
||||
}
|
||||
|
||||
/*
|
||||
ConcurrentMap Deletion Benchmark Test
|
||||
*/
|
||||
template <class K, class V>
|
||||
static void DeleteValue(benchmark::State& state, ConcurrentMap<K, V>* map,
|
||||
const std::vector<std::pair<K, V>> elements) {
|
||||
while (state.KeepRunning()) {
|
||||
auto accessor = map->access();
|
||||
for (int start = 0; start < state.range(0); start++) {
|
||||
accessor.remove(elements[start].first);
|
||||
static void DeleteValue(benchmark::State &state, ConcurrentMap<K, V> *map,
|
||||
const std::vector<std::pair<K, V>> elements)
|
||||
{
|
||||
while (state.KeepRunning())
|
||||
{
|
||||
auto accessor = map->access();
|
||||
for (int start = 0; start < state.range(0); start++)
|
||||
{
|
||||
accessor.remove(elements[start].first);
|
||||
}
|
||||
}
|
||||
}
|
||||
state.SetComplexityN(state.range(0));
|
||||
state.SetComplexityN(state.range(0));
|
||||
}
|
||||
|
||||
/*
|
||||
ConcurrentMap Contains Benchmark Test
|
||||
*/
|
||||
template <class K, class V>
|
||||
static void ContainsValue(benchmark::State& state, ConcurrentMap<K, V>* map,
|
||||
const std::vector<std::pair<K, V>> elements) {
|
||||
while (state.KeepRunning()) {
|
||||
auto accessor = map->access();
|
||||
for (int start = 0; start < state.range(0); start++) {
|
||||
accessor.contains(elements[start].first);
|
||||
static void ContainsValue(benchmark::State &state, ConcurrentMap<K, V> *map,
|
||||
const std::vector<std::pair<K, V>> elements)
|
||||
{
|
||||
while (state.KeepRunning())
|
||||
{
|
||||
auto accessor = map->access();
|
||||
for (int start = 0; start < state.range(0); start++)
|
||||
{
|
||||
accessor.contains(elements[start].first);
|
||||
}
|
||||
}
|
||||
}
|
||||
state.SetComplexityN(state.range(0));
|
||||
state.SetComplexityN(state.range(0));
|
||||
}
|
||||
|
||||
auto BM_InsertValue = [](benchmark::State& state, auto* map, auto& elements) {
|
||||
InsertValue(state, map, elements);
|
||||
auto BM_InsertValue = [](benchmark::State &state, auto *map, auto &elements) {
|
||||
InsertValue(state, map, elements);
|
||||
};
|
||||
|
||||
auto BM_DeleteValue = [](benchmark::State& state, auto* map, auto elements) {
|
||||
DeleteValue(state, map, elements);
|
||||
auto BM_DeleteValue = [](benchmark::State &state, auto *map, auto elements) {
|
||||
DeleteValue(state, map, elements);
|
||||
};
|
||||
|
||||
auto BM_ContainsValue = [](benchmark::State& state, auto* map, auto elements) {
|
||||
ContainsValue(state, map, elements);
|
||||
auto BM_ContainsValue = [](benchmark::State &state, auto *map, auto elements) {
|
||||
ContainsValue(state, map, elements);
|
||||
};
|
||||
|
||||
/*
|
||||
@ -106,149 +115,151 @@ auto BM_ContainsValue = [](benchmark::State& state, auto* map, auto elements) {
|
||||
* Random String lenght
|
||||
-string-length number
|
||||
*/
|
||||
void parse_arguments(int argc, char** argv) {
|
||||
REGISTER_ARGS(argc, argv);
|
||||
void parse_arguments(int argc, char **argv)
|
||||
{
|
||||
REGISTER_ARGS(argc, argv);
|
||||
|
||||
RANGE_START = GET_ARG("-start", "0").get_int();
|
||||
RANGE_END = GET_ARG("-end", "1000000000").get_int();
|
||||
RANGE_START = GET_ARG("-start", "0").get_int();
|
||||
RANGE_END = GET_ARG("-end", "1000000000").get_int();
|
||||
|
||||
THREADS = std::min(GET_ARG("-threads", "1").get_int(),
|
||||
(int)std::thread::hardware_concurrency());
|
||||
THREADS = std::min(GET_ARG("-threads", "1").get_int(),
|
||||
(int)std::thread::hardware_concurrency());
|
||||
|
||||
STRING_LENGTH =
|
||||
ProgramArguments::instance().get_arg("-string-length", "128").get_int();
|
||||
STRING_LENGTH =
|
||||
ProgramArguments::instance().get_arg("-string-length", "128").get_int();
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
logging::init_async();
|
||||
logging::log->pipe(std::make_unique<Stdout>());
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
logging::init_async();
|
||||
logging::log->pipe(std::make_unique<Stdout>());
|
||||
|
||||
parse_arguments(argc, argv);
|
||||
parse_arguments(argc, argv);
|
||||
|
||||
StringGenerator sg(STRING_LENGTH);
|
||||
IntegerGenerator ig(RANGE_START, RANGE_END);
|
||||
StringGenerator sg(STRING_LENGTH);
|
||||
IntegerGenerator ig(RANGE_START, RANGE_END);
|
||||
|
||||
/*
|
||||
Creates RandomGenerators, ConcurentMaps and Random Element Vectors for the
|
||||
following use cases:
|
||||
/*
|
||||
Creates RandomGenerators, ConcurentMaps and Random Element Vectors for the
|
||||
following use cases:
|
||||
|
||||
Map elements contain keys and value for:
|
||||
<int, int>,
|
||||
<int, string>
|
||||
<string, int>
|
||||
<string, string>
|
||||
*/
|
||||
Map elements contain keys and value for:
|
||||
<int, int>,
|
||||
<int, string>
|
||||
<string, int>
|
||||
<string, string>
|
||||
*/
|
||||
|
||||
// random generators for tests
|
||||
PairGenerator<IntegerGenerator, IntegerGenerator> piig(&ig, &ig);
|
||||
PairGenerator<StringGenerator, StringGenerator> pssg(&sg, &sg);
|
||||
PairGenerator<StringGenerator, IntegerGenerator> psig(&sg, &ig);
|
||||
PairGenerator<IntegerGenerator, StringGenerator> pisg(&ig, &sg);
|
||||
// random generators for tests
|
||||
PairGenerator<IntegerGenerator, IntegerGenerator> piig(&ig, &ig);
|
||||
PairGenerator<StringGenerator, StringGenerator> pssg(&sg, &sg);
|
||||
PairGenerator<StringGenerator, IntegerGenerator> psig(&sg, &ig);
|
||||
PairGenerator<IntegerGenerator, StringGenerator> pisg(&ig, &sg);
|
||||
|
||||
// maps used for testing
|
||||
ConcurrentMap<int, int> ii_map;
|
||||
ConcurrentMap<int, std::string> is_map;
|
||||
ConcurrentMap<std::string, int> si_map;
|
||||
ConcurrentMap<std::string, std::string> ss_map;
|
||||
// maps used for testing
|
||||
ConcurrentMap<int, int> ii_map;
|
||||
ConcurrentMap<int, std::string> is_map;
|
||||
ConcurrentMap<std::string, int> si_map;
|
||||
ConcurrentMap<std::string, std::string> ss_map;
|
||||
|
||||
// random elements for testing
|
||||
auto ii_elems = utils::random::generate_vector(piig, MAX_ELEMENTS);
|
||||
auto is_elems = utils::random::generate_vector(pisg, MAX_ELEMENTS);
|
||||
auto si_elems = utils::random::generate_vector(psig, MAX_ELEMENTS);
|
||||
auto ss_elems = utils::random::generate_vector(pssg, MAX_ELEMENTS);
|
||||
// random elements for testing
|
||||
auto ii_elems = utils::random::generate_vector(piig, MAX_ELEMENTS);
|
||||
auto is_elems = utils::random::generate_vector(pisg, MAX_ELEMENTS);
|
||||
auto si_elems = utils::random::generate_vector(psig, MAX_ELEMENTS);
|
||||
auto ss_elems = utils::random::generate_vector(pssg, MAX_ELEMENTS);
|
||||
|
||||
/* insertion Tests */
|
||||
/* insertion Tests */
|
||||
|
||||
benchmark::RegisterBenchmark("InsertValue[Int, Int]", BM_InsertValue, &ii_map,
|
||||
ii_elems)
|
||||
->RangeMultiplier(MULTIPLIER)
|
||||
->Range(1, MAX_ELEMENTS)
|
||||
->Complexity(benchmark::oN)
|
||||
->Threads(THREADS);
|
||||
benchmark::RegisterBenchmark("InsertValue[Int, Int]", BM_InsertValue,
|
||||
&ii_map, ii_elems)
|
||||
->RangeMultiplier(MULTIPLIER)
|
||||
->Range(1, MAX_ELEMENTS)
|
||||
->Complexity(benchmark::oN)
|
||||
->Threads(THREADS);
|
||||
|
||||
benchmark::RegisterBenchmark("InsertValue[Int, String]", BM_InsertValue,
|
||||
&is_map, is_elems)
|
||||
->RangeMultiplier(MULTIPLIER)
|
||||
->Range(1, MAX_ELEMENTS)
|
||||
->Complexity(benchmark::oN)
|
||||
->Threads(THREADS);
|
||||
benchmark::RegisterBenchmark("InsertValue[Int, String]", BM_InsertValue,
|
||||
&is_map, is_elems)
|
||||
->RangeMultiplier(MULTIPLIER)
|
||||
->Range(1, MAX_ELEMENTS)
|
||||
->Complexity(benchmark::oN)
|
||||
->Threads(THREADS);
|
||||
|
||||
benchmark::RegisterBenchmark("InsertValue[String, Int]", BM_InsertValue,
|
||||
&si_map, si_elems)
|
||||
->RangeMultiplier(MULTIPLIER)
|
||||
->Range(1, MAX_ELEMENTS)
|
||||
->Complexity(benchmark::oN)
|
||||
->Threads(THREADS);
|
||||
benchmark::RegisterBenchmark("InsertValue[String, Int]", BM_InsertValue,
|
||||
&si_map, si_elems)
|
||||
->RangeMultiplier(MULTIPLIER)
|
||||
->Range(1, MAX_ELEMENTS)
|
||||
->Complexity(benchmark::oN)
|
||||
->Threads(THREADS);
|
||||
|
||||
benchmark::RegisterBenchmark("InsertValue[String, String]", BM_InsertValue,
|
||||
&ss_map, ss_elems)
|
||||
->RangeMultiplier(MULTIPLIER)
|
||||
->Range(1, MAX_ELEMENTS)
|
||||
->Complexity(benchmark::oN)
|
||||
->Threads(THREADS);
|
||||
benchmark::RegisterBenchmark("InsertValue[String, String]", BM_InsertValue,
|
||||
&ss_map, ss_elems)
|
||||
->RangeMultiplier(MULTIPLIER)
|
||||
->Range(1, MAX_ELEMENTS)
|
||||
->Complexity(benchmark::oN)
|
||||
->Threads(THREADS);
|
||||
|
||||
// Contains Benchmark Tests
|
||||
// Contains Benchmark Tests
|
||||
|
||||
benchmark::RegisterBenchmark("ContainsValue[Int, Int]", BM_ContainsValue,
|
||||
&ii_map, ii_elems)
|
||||
->RangeMultiplier(MULTIPLIER)
|
||||
->Range(1, MAX_ELEMENTS)
|
||||
->Complexity(benchmark::oN)
|
||||
->Threads(THREADS);
|
||||
benchmark::RegisterBenchmark("ContainsValue[Int, Int]", BM_ContainsValue,
|
||||
&ii_map, ii_elems)
|
||||
->RangeMultiplier(MULTIPLIER)
|
||||
->Range(1, MAX_ELEMENTS)
|
||||
->Complexity(benchmark::oN)
|
||||
->Threads(THREADS);
|
||||
|
||||
benchmark::RegisterBenchmark("ContainsValue[Int, String]", BM_ContainsValue,
|
||||
&is_map, is_elems)
|
||||
->RangeMultiplier(MULTIPLIER)
|
||||
->Range(1, MAX_ELEMENTS)
|
||||
->Complexity(benchmark::oN)
|
||||
->Threads(THREADS);
|
||||
benchmark::RegisterBenchmark("ContainsValue[Int, String]", BM_ContainsValue,
|
||||
&is_map, is_elems)
|
||||
->RangeMultiplier(MULTIPLIER)
|
||||
->Range(1, MAX_ELEMENTS)
|
||||
->Complexity(benchmark::oN)
|
||||
->Threads(THREADS);
|
||||
|
||||
benchmark::RegisterBenchmark("ContainsValue[String, Int]", BM_ContainsValue,
|
||||
&si_map, si_elems)
|
||||
->RangeMultiplier(MULTIPLIER)
|
||||
->Range(1, MAX_ELEMENTS)
|
||||
->Complexity(benchmark::oN)
|
||||
->Threads(THREADS);
|
||||
benchmark::RegisterBenchmark("ContainsValue[String, Int]", BM_ContainsValue,
|
||||
&si_map, si_elems)
|
||||
->RangeMultiplier(MULTIPLIER)
|
||||
->Range(1, MAX_ELEMENTS)
|
||||
->Complexity(benchmark::oN)
|
||||
->Threads(THREADS);
|
||||
|
||||
benchmark::RegisterBenchmark("ContainsValue[String, String]",
|
||||
BM_ContainsValue, &ss_map, ss_elems)
|
||||
->RangeMultiplier(MULTIPLIER)
|
||||
->Range(1, MAX_ELEMENTS)
|
||||
->Complexity(benchmark::oN)
|
||||
->Threads(THREADS);
|
||||
benchmark::RegisterBenchmark("ContainsValue[String, String]",
|
||||
BM_ContainsValue, &ss_map, ss_elems)
|
||||
->RangeMultiplier(MULTIPLIER)
|
||||
->Range(1, MAX_ELEMENTS)
|
||||
->Complexity(benchmark::oN)
|
||||
->Threads(THREADS);
|
||||
|
||||
// Deletion Banchamark Tests
|
||||
// Deletion Banchamark Tests
|
||||
|
||||
benchmark::RegisterBenchmark("DeleteValue[Int, Int]", BM_DeleteValue, &ii_map,
|
||||
ii_elems)
|
||||
->RangeMultiplier(MULTIPLIER)
|
||||
->Range(1, MAX_ELEMENTS)
|
||||
->Complexity(benchmark::oN)
|
||||
->Threads(THREADS);
|
||||
benchmark::RegisterBenchmark("DeleteValue[Int, Int]", BM_DeleteValue,
|
||||
&ii_map, ii_elems)
|
||||
->RangeMultiplier(MULTIPLIER)
|
||||
->Range(1, MAX_ELEMENTS)
|
||||
->Complexity(benchmark::oN)
|
||||
->Threads(THREADS);
|
||||
|
||||
benchmark::RegisterBenchmark("DeleteValue[Int, String]", BM_DeleteValue,
|
||||
&is_map, is_elems)
|
||||
->RangeMultiplier(MULTIPLIER)
|
||||
->Range(1, MAX_ELEMENTS)
|
||||
->Complexity(benchmark::oN)
|
||||
->Threads(THREADS);
|
||||
benchmark::RegisterBenchmark("DeleteValue[Int, String]", BM_DeleteValue,
|
||||
&is_map, is_elems)
|
||||
->RangeMultiplier(MULTIPLIER)
|
||||
->Range(1, MAX_ELEMENTS)
|
||||
->Complexity(benchmark::oN)
|
||||
->Threads(THREADS);
|
||||
|
||||
benchmark::RegisterBenchmark("DeleteValue[String, Int]", BM_DeleteValue,
|
||||
&si_map, si_elems)
|
||||
->RangeMultiplier(MULTIPLIER)
|
||||
->Range(1, MAX_ELEMENTS)
|
||||
->Complexity(benchmark::oN)
|
||||
->Threads(THREADS);
|
||||
benchmark::RegisterBenchmark("DeleteValue[String, Int]", BM_DeleteValue,
|
||||
&si_map, si_elems)
|
||||
->RangeMultiplier(MULTIPLIER)
|
||||
->Range(1, MAX_ELEMENTS)
|
||||
->Complexity(benchmark::oN)
|
||||
->Threads(THREADS);
|
||||
|
||||
benchmark::RegisterBenchmark("DeleteValue[String, String]", BM_DeleteValue,
|
||||
&ss_map, ss_elems)
|
||||
->RangeMultiplier(MULTIPLIER)
|
||||
->Range(1, MAX_ELEMENTS)
|
||||
->Complexity(benchmark::oN)
|
||||
->Threads(THREADS);
|
||||
benchmark::RegisterBenchmark("DeleteValue[String, String]", BM_DeleteValue,
|
||||
&ss_map, ss_elems)
|
||||
->RangeMultiplier(MULTIPLIER)
|
||||
->Range(1, MAX_ELEMENTS)
|
||||
->Complexity(benchmark::oN)
|
||||
->Threads(THREADS);
|
||||
|
||||
benchmark::Initialize(&argc, argv);
|
||||
benchmark::RunSpecifiedBenchmarks();
|
||||
benchmark::Initialize(&argc, argv);
|
||||
benchmark::RunSpecifiedBenchmarks();
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
@ -28,30 +28,39 @@ int THREADS, INSERT_PERC, DELETE_PERC, CONTAINS_PERC, RANGE_START, RANGE_END;
|
||||
|
||||
// ConcurrentMap Becnhmark Test using percentages for Insert, Delete, Find
|
||||
template <class K, class V>
|
||||
static void Rape(benchmark::State& state, ConcurrentMap<int, int>* map,
|
||||
const std::vector<std::pair<K, V>>& elements) {
|
||||
int number_of_elements = state.range(0);
|
||||
static void Rape(benchmark::State &state, ConcurrentMap<int, int> *map,
|
||||
const std::vector<std::pair<K, V>> &elements)
|
||||
{
|
||||
int number_of_elements = state.range(0);
|
||||
|
||||
while (state.KeepRunning()) {
|
||||
auto accessor = map->access();
|
||||
while (state.KeepRunning())
|
||||
{
|
||||
auto accessor = map->access();
|
||||
|
||||
for (int start = 0; start < state.range(0); start++) {
|
||||
float current_percentage = (float)start / (float)number_of_elements * 100;
|
||||
if (current_percentage < (float)INSERT_PERC) {
|
||||
accessor.insert(elements[start].first, elements[start].second);
|
||||
} else if (current_percentage < (float)CONTAINS_PERC + INSERT_PERC) {
|
||||
accessor.contains(elements[start].first);
|
||||
} else {
|
||||
accessor.remove(elements[start].first);
|
||||
}
|
||||
for (int start = 0; start < state.range(0); start++)
|
||||
{
|
||||
float current_percentage =
|
||||
(float)start / (float)number_of_elements * 100;
|
||||
if (current_percentage < (float)INSERT_PERC)
|
||||
{
|
||||
accessor.insert(elements[start].first, elements[start].second);
|
||||
}
|
||||
else if (current_percentage < (float)CONTAINS_PERC + INSERT_PERC)
|
||||
{
|
||||
accessor.contains(elements[start].first);
|
||||
}
|
||||
else
|
||||
{
|
||||
accessor.remove(elements[start].first);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
state.SetComplexityN(state.range(0));
|
||||
state.SetComplexityN(state.range(0));
|
||||
}
|
||||
|
||||
auto BM_Rape = [](benchmark::State& state, auto* map, auto& elements) {
|
||||
Rape(state, map, elements);
|
||||
auto BM_Rape = [](benchmark::State &state, auto *map, auto &elements) {
|
||||
Rape(state, map, elements);
|
||||
};
|
||||
|
||||
/*
|
||||
@ -76,48 +85,51 @@ auto BM_Rape = [](benchmark::State& state, auto* map, auto& elements) {
|
||||
* Number of threads
|
||||
-threads number
|
||||
*/
|
||||
void parse_arguments(int argc, char** argv) {
|
||||
REGISTER_ARGS(argc, argv);
|
||||
void parse_arguments(int argc, char **argv)
|
||||
{
|
||||
REGISTER_ARGS(argc, argv);
|
||||
|
||||
INSERT_PERC = GET_ARG("-insert", "50").get_int();
|
||||
DELETE_PERC = GET_ARG("-delete", "20").get_int();
|
||||
CONTAINS_PERC = GET_ARG("-find", "30").get_int();
|
||||
INSERT_PERC = GET_ARG("-insert", "50").get_int();
|
||||
DELETE_PERC = GET_ARG("-delete", "20").get_int();
|
||||
CONTAINS_PERC = GET_ARG("-find", "30").get_int();
|
||||
|
||||
if (INSERT_PERC + DELETE_PERC + CONTAINS_PERC != 100) {
|
||||
std::cout << "Invalid percentage" << std::endl;
|
||||
std::cout << "Percentage must sum to 100" << std::endl;
|
||||
exit(-1);
|
||||
}
|
||||
if (INSERT_PERC + DELETE_PERC + CONTAINS_PERC != 100)
|
||||
{
|
||||
std::cout << "Invalid percentage" << std::endl;
|
||||
std::cout << "Percentage must sum to 100" << std::endl;
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
RANGE_START = GET_ARG("-start", "0").get_int();
|
||||
RANGE_START = GET_ARG("-start", "0").get_int();
|
||||
|
||||
RANGE_END = GET_ARG("-end", "1000000000").get_int();
|
||||
RANGE_END = GET_ARG("-end", "1000000000").get_int();
|
||||
|
||||
THREADS = std::min(GET_ARG("-threads", "1").get_int(),
|
||||
(int)std::thread::hardware_concurrency());
|
||||
THREADS = std::min(GET_ARG("-threads", "1").get_int(),
|
||||
(int)std::thread::hardware_concurrency());
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
logging::init_async();
|
||||
logging::log->pipe(std::make_unique<Stdout>());
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
logging::init_async();
|
||||
logging::log->pipe(std::make_unique<Stdout>());
|
||||
|
||||
parse_arguments(argc, argv);
|
||||
parse_arguments(argc, argv);
|
||||
|
||||
IntegerGenerator int_gen(RANGE_START, RANGE_END);
|
||||
PairGenerator<IntegerGenerator, IntegerGenerator> pair_gen(&int_gen,
|
||||
&int_gen);
|
||||
IntegerGenerator int_gen(RANGE_START, RANGE_END);
|
||||
PairGenerator<IntegerGenerator, IntegerGenerator> pair_gen(&int_gen,
|
||||
&int_gen);
|
||||
|
||||
ConcurrentMap<int, int> map;
|
||||
auto elements = utils::random::generate_vector(pair_gen, MAX_ELEMENTS);
|
||||
ConcurrentMap<int, int> map;
|
||||
auto elements = utils::random::generate_vector(pair_gen, MAX_ELEMENTS);
|
||||
|
||||
benchmark::RegisterBenchmark("Rape", BM_Rape, &map, elements)
|
||||
->RangeMultiplier(MULTIPLIER)
|
||||
->Range(1, MAX_ELEMENTS)
|
||||
->Complexity(benchmark::oN)
|
||||
->Threads(THREADS);
|
||||
benchmark::RegisterBenchmark("Rape", BM_Rape, &map, elements)
|
||||
->RangeMultiplier(MULTIPLIER)
|
||||
->Range(1, MAX_ELEMENTS)
|
||||
->Complexity(benchmark::oN)
|
||||
->Threads(THREADS);
|
||||
|
||||
benchmark::Initialize(&argc, argv);
|
||||
benchmark::RunSpecifiedBenchmarks();
|
||||
benchmark::Initialize(&argc, argv);
|
||||
benchmark::RunSpecifiedBenchmarks();
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,44 +1,47 @@
|
||||
#include "logging/default.hpp"
|
||||
#include "logging/streams/stdout.hpp"
|
||||
#include "utils/time/timer.hpp"
|
||||
#include "query/preprocesor.hpp"
|
||||
#include "utils/time/timer.hpp"
|
||||
|
||||
#include "benchmark/benchmark_api.h"
|
||||
#include "yaml-cpp/yaml.h"
|
||||
|
||||
auto BM_Strip = [](benchmark::State& state, auto& function, std::string query) {
|
||||
while (state.KeepRunning()) {
|
||||
for (int start = 0; start < state.range(0); start++) {
|
||||
function(query);
|
||||
auto BM_Strip = [](benchmark::State &state, auto &function, std::string query) {
|
||||
while (state.KeepRunning())
|
||||
{
|
||||
for (int start = 0; start < state.range(0); start++)
|
||||
{
|
||||
function(query);
|
||||
}
|
||||
}
|
||||
}
|
||||
state.SetComplexityN(state.range(0));
|
||||
state.SetComplexityN(state.range(0));
|
||||
};
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
logging::init_async();
|
||||
logging::log->pipe(std::make_unique<Stdout>());
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
logging::init_async();
|
||||
logging::log->pipe(std::make_unique<Stdout>());
|
||||
|
||||
YAML::Node dataset = YAML::LoadFile(
|
||||
"../../tests/data/cypher_queries/stripper/query_dict.yaml");
|
||||
YAML::Node dataset = YAML::LoadFile(
|
||||
"../../tests/data/cypher_queries/stripper/query_dict.yaml");
|
||||
|
||||
QueryPreprocessor processor;
|
||||
using std::placeholders::_1;
|
||||
std::function<QueryStripped(const std::string& query)> preprocess =
|
||||
std::bind(&QueryPreprocessor::preprocess, &processor, _1);
|
||||
QueryPreprocessor processor;
|
||||
using std::placeholders::_1;
|
||||
std::function<QueryStripped(const std::string &query)> preprocess =
|
||||
std::bind(&QueryPreprocessor::preprocess, &processor, _1);
|
||||
|
||||
auto tests = dataset["benchmark_queries"].as<std::vector<std::string>>();
|
||||
for (auto& test : tests) {
|
||||
auto* benchmark =
|
||||
benchmark::RegisterBenchmark(test.c_str(), BM_Strip, preprocess, test)
|
||||
->RangeMultiplier(2)
|
||||
->Range(1, 8 << 10)
|
||||
->Complexity(benchmark::oN);
|
||||
;
|
||||
}
|
||||
auto tests = dataset["benchmark_queries"].as<std::vector<std::string>>();
|
||||
for (auto &test : tests)
|
||||
{
|
||||
auto *benchmark = benchmark::RegisterBenchmark(test.c_str(), BM_Strip,
|
||||
preprocess, test)
|
||||
->RangeMultiplier(2)
|
||||
->Range(1, 8 << 10)
|
||||
->Complexity(benchmark::oN);
|
||||
}
|
||||
|
||||
benchmark::Initialize(&argc, argv);
|
||||
benchmark::RunSpecifiedBenchmarks();
|
||||
benchmark::Initialize(&argc, argv);
|
||||
benchmark::RunSpecifiedBenchmarks();
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
@ -26,6 +26,8 @@ foreach(test_cpp ${test_type_cpps})
|
||||
set_target_properties(${target_name} PROPERTIES OUTPUT_NAME ${exec_name})
|
||||
|
||||
# link libraries
|
||||
# gtest
|
||||
target_link_libraries(${target_name} gtest gtest_main)
|
||||
# threads (cross-platform)
|
||||
target_link_libraries(${target_name} Threads::Threads)
|
||||
# memgraph lib
|
||||
|
@ -302,6 +302,7 @@ void memory_check(size_t no_threads, std::function<void()> f)
|
||||
permanent_assert(true, "Memory leak");
|
||||
}
|
||||
|
||||
// TODO: move this inside logging/default
|
||||
// Initializes loging faccilityes
|
||||
void init_log()
|
||||
{
|
||||
|
@ -8,7 +8,7 @@ constexpr size_t max_number = 10;
|
||||
constexpr size_t no_find_per_change = 2;
|
||||
constexpr size_t no_insert_for_one_delete = 1;
|
||||
|
||||
// This test simulates behavior of transactions.
|
||||
// This test simulates behavior of a transactions.
|
||||
// Each thread makes a series of finds interleaved with method which change.
|
||||
// Exact ratio of finds per change and insert per delete can be regulated with
|
||||
// no_find_per_change and no_insert_for_one_delete.
|
||||
|
@ -1,33 +1,41 @@
|
||||
#include "common.h"
|
||||
|
||||
constexpr size_t THREADS_NO = std::min(max_no_threads, 8);
|
||||
constexpr size_t op_per_thread = 1e5;
|
||||
constexpr size_t bit_part_len = 2;
|
||||
constexpr size_t no_slots = 1e4;
|
||||
constexpr size_t key_range = no_slots * THREADS_NO * bit_part_len;
|
||||
constexpr size_t THREADS_NO = std::min(max_no_threads, 8);
|
||||
constexpr size_t op_per_thread = 1e5;
|
||||
constexpr size_t bit_part_len = 2;
|
||||
constexpr size_t no_slots = 1e4;
|
||||
constexpr size_t key_range = no_slots * THREADS_NO * bit_part_len;
|
||||
constexpr size_t no_sets_per_clear = 2;
|
||||
|
||||
// TODO: document the test
|
||||
|
||||
int main()
|
||||
{
|
||||
DynamicBitset<> db;
|
||||
|
||||
auto seted =
|
||||
collect_set(run<std::vector<bool>>(THREADS_NO, [&](auto index) {
|
||||
auto rand = rand_gen(no_slots);
|
||||
auto rand = rand_gen(no_slots);
|
||||
auto clear_op = rand_gen_bool(no_sets_per_clear);
|
||||
std::vector<bool> set(key_range);
|
||||
|
||||
for (size_t i = 0; i < op_per_thread; i++) {
|
||||
for (size_t i = 0; i < op_per_thread; i++)
|
||||
{
|
||||
size_t num =
|
||||
rand() * THREADS_NO * bit_part_len + index * bit_part_len;
|
||||
|
||||
if (clear_op()) {
|
||||
if (clear_op())
|
||||
{
|
||||
db.clear(num, bit_part_len);
|
||||
for (int j = 0; j < bit_part_len; j++) {
|
||||
for (int j = 0; j < bit_part_len; j++)
|
||||
{
|
||||
set[num + j] = false;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
db.set(num, bit_part_len);
|
||||
for (int j = 0; j < bit_part_len; j++)
|
||||
for (int j = 0; j < bit_part_len; j++)
|
||||
set[num + j] = true;
|
||||
}
|
||||
}
|
||||
|
@ -1,25 +1,29 @@
|
||||
#include "common.h"
|
||||
|
||||
constexpr size_t THREADS_NO = std::min(max_no_threads, 4);
|
||||
constexpr size_t op_per_thread = 1e5;
|
||||
constexpr size_t THREADS_NO = std::min(max_no_threads, 4);
|
||||
constexpr size_t op_per_thread = 1e5;
|
||||
constexpr size_t up_border_bit_set_pow2 = 3;
|
||||
constexpr size_t key_range =
|
||||
op_per_thread * THREADS_NO * (1 << up_border_bit_set_pow2) * 2;
|
||||
|
||||
// TODO: document the test
|
||||
|
||||
int main()
|
||||
{
|
||||
DynamicBitset<> db;
|
||||
|
||||
auto seted =
|
||||
collect_set(run<std::vector<bool>>(THREADS_NO, [&](auto index) {
|
||||
auto rand = rand_gen(key_range);
|
||||
auto rand = rand_gen(key_range);
|
||||
auto rand_len = rand_gen(up_border_bit_set_pow2);
|
||||
std::vector<bool> set(key_range + (1 << up_border_bit_set_pow2));
|
||||
|
||||
for (size_t i = 0; i < op_per_thread; i++) {
|
||||
auto len = 1 << rand_len();
|
||||
for (size_t i = 0; i < op_per_thread; i++)
|
||||
{
|
||||
auto len = 1 << rand_len();
|
||||
size_t num = (rand() / len) * len;
|
||||
db.set(num, len);
|
||||
for (int j = 0; j < len; j++)
|
||||
for (int j = 0; j < len; j++)
|
||||
set[num + j] = true;
|
||||
}
|
||||
|
||||
@ -28,14 +32,16 @@ int main()
|
||||
|
||||
auto cleared =
|
||||
collect_set(run<std::vector<bool>>(THREADS_NO, [&](auto index) {
|
||||
auto rand = rand_gen(key_range);
|
||||
auto rand = rand_gen(key_range);
|
||||
auto rand_len = rand_gen(up_border_bit_set_pow2);
|
||||
std::vector<bool> set(key_range + (1 << up_border_bit_set_pow2));
|
||||
|
||||
for (size_t i = 0; i < op_per_thread; i++) {
|
||||
auto len = 1 << rand_len();
|
||||
for (size_t i = 0; i < op_per_thread; i++)
|
||||
{
|
||||
auto len = 1 << rand_len();
|
||||
size_t num = (rand() / len) * len;
|
||||
for (int j = 0; j < len; j++) {
|
||||
for (int j = 0; j < len; j++)
|
||||
{
|
||||
set[num + j] = set[num + j] | db.at(num + j);
|
||||
}
|
||||
db.clear(num, len);
|
||||
@ -44,7 +50,8 @@ int main()
|
||||
return set;
|
||||
}));
|
||||
|
||||
for (size_t i = 0; i < seted.size(); i++) {
|
||||
for (size_t i = 0; i < seted.size(); i++)
|
||||
{
|
||||
seted[i] = seted[i] & (!cleared[i]);
|
||||
}
|
||||
|
||||
|
@ -1,17 +1,21 @@
|
||||
#include "common.h"
|
||||
|
||||
constexpr size_t THREADS_NO = std::min(max_no_threads, 8);
|
||||
constexpr size_t THREADS_NO = std::min(max_no_threads, 8);
|
||||
constexpr size_t op_per_thread = 1e5;
|
||||
constexpr size_t key_range = op_per_thread * THREADS_NO * 3;
|
||||
constexpr size_t key_range = op_per_thread * THREADS_NO * 3;
|
||||
|
||||
// TODO: document the test
|
||||
|
||||
int main()
|
||||
{
|
||||
DynamicBitset<> db;
|
||||
|
||||
auto set = collect_set(run<std::vector<bool>>(THREADS_NO, [&](auto index) {
|
||||
auto rand = rand_gen(key_range);
|
||||
std::vector<bool> set(key_range);
|
||||
|
||||
for (size_t i = 0; i < op_per_thread; i++) {
|
||||
for (size_t i = 0; i < op_per_thread; i++)
|
||||
{
|
||||
size_t num = rand();
|
||||
db.set(num);
|
||||
set[num] = true;
|
||||
|
@ -1,24 +1,28 @@
|
||||
#include "common.h"
|
||||
|
||||
constexpr size_t THREADS_NO = std::min(max_no_threads, 4);
|
||||
constexpr size_t op_per_thread = 1e5;
|
||||
constexpr size_t THREADS_NO = std::min(max_no_threads, 4);
|
||||
constexpr size_t op_per_thread = 1e5;
|
||||
constexpr size_t up_border_bit_set_pow2 = 3;
|
||||
constexpr size_t key_range =
|
||||
op_per_thread * THREADS_NO * (1 << up_border_bit_set_pow2) * 2;
|
||||
|
||||
// TODO: document the test
|
||||
|
||||
int main()
|
||||
{
|
||||
DynamicBitset<> db;
|
||||
|
||||
auto set = collect_set(run<std::vector<bool>>(THREADS_NO, [&](auto index) {
|
||||
auto rand = rand_gen(key_range);
|
||||
auto rand = rand_gen(key_range);
|
||||
auto rand_len = rand_gen(up_border_bit_set_pow2);
|
||||
std::vector<bool> set(key_range + (1 << up_border_bit_set_pow2));
|
||||
|
||||
for (size_t i = 0; i < op_per_thread; i++) {
|
||||
auto len = 1 << rand_len();
|
||||
for (size_t i = 0; i < op_per_thread; i++)
|
||||
{
|
||||
auto len = 1 << rand_len();
|
||||
size_t num = (rand() / len) * len;
|
||||
db.set(num, len);
|
||||
for (int j = 0; j < len; j++)
|
||||
for (int j = 0; j < len; j++)
|
||||
set[num + j] = true;
|
||||
}
|
||||
|
||||
|
@ -1,62 +0,0 @@
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include <thread>
|
||||
|
||||
#include "common.h"
|
||||
#include "data_structures/linked_list.hpp"
|
||||
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
template <typename list_type>
|
||||
void test_concurrent_list_access(list_type &list, std::size_t size)
|
||||
{
|
||||
// test concurrent access
|
||||
for (int i = 0; i < 1000000; ++i) {
|
||||
|
||||
std::thread t1([&list] {
|
||||
list.push_front(1);
|
||||
list.pop_front();
|
||||
});
|
||||
|
||||
std::thread t2([&list] {
|
||||
list.push_front(2);
|
||||
list.pop_front();
|
||||
});
|
||||
|
||||
t1.join();
|
||||
t2.join();
|
||||
|
||||
assert(list.size() == size);
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
init_log();
|
||||
LinkedList<int> list;
|
||||
|
||||
// push & pop operations
|
||||
list.push_front(10);
|
||||
list.push_front(20);
|
||||
auto a = list.front();
|
||||
assert(a == 20);
|
||||
list.pop_front();
|
||||
a = list.front();
|
||||
assert(a == 10);
|
||||
list.pop_front();
|
||||
assert(list.size() == 0);
|
||||
|
||||
// concurrent test
|
||||
LinkedList<int> concurrent_list;
|
||||
concurrent_list.push_front(1);
|
||||
concurrent_list.push_front(1);
|
||||
std::list<int> no_concurrent_list;
|
||||
no_concurrent_list.push_front(1);
|
||||
no_concurrent_list.push_front(1);
|
||||
|
||||
test_concurrent_list_access(concurrent_list, 2);
|
||||
// test_concurrent_list_access(no_concurrent_list, 2);
|
||||
|
||||
return 0;
|
||||
}
|
@ -3,25 +3,29 @@
|
||||
constexpr size_t THREADS_NO = std::min(max_no_threads, 8);
|
||||
|
||||
constexpr size_t elems_per_thread = 100000;
|
||||
constexpr size_t key_range = elems_per_thread * THREADS_NO * 2;
|
||||
constexpr size_t key_range = elems_per_thread * THREADS_NO * 2;
|
||||
|
||||
// TODO: document the test
|
||||
|
||||
// This test checks insert_unique method under pressure.
|
||||
// Test checks for missing data and changed/overwriten data.
|
||||
int main()
|
||||
{
|
||||
init_log();
|
||||
|
||||
memory_check(THREADS_NO, [] {
|
||||
map_t skiplist;
|
||||
|
||||
auto futures = run<std::vector<size_t>>(
|
||||
THREADS_NO, skiplist, [](auto acc, auto index) {
|
||||
auto rand = rand_gen(key_range);
|
||||
auto rand = rand_gen(key_range);
|
||||
long long downcount = elems_per_thread;
|
||||
std::vector<size_t> owned;
|
||||
auto inserter =
|
||||
insert_try<size_t, size_t, map_t>(acc, downcount, owned);
|
||||
|
||||
do {
|
||||
do
|
||||
{
|
||||
inserter(rand(), index);
|
||||
} while (downcount > 0);
|
||||
|
||||
@ -30,7 +34,8 @@ int main()
|
||||
});
|
||||
|
||||
auto accessor = skiplist.access();
|
||||
for (auto &owned : collect(futures)) {
|
||||
for (auto &owned : collect(futures))
|
||||
{
|
||||
check_present_same<map_t>(accessor, owned);
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,10 @@
|
||||
#include "common.h"
|
||||
|
||||
constexpr size_t THREADS_NO = std::min(max_no_threads, 8);
|
||||
constexpr size_t THREADS_NO = std::min(max_no_threads, 8);
|
||||
constexpr size_t elems_per_thread = 100000;
|
||||
constexpr size_t key_range = elems_per_thread * THREADS_NO * 2;
|
||||
constexpr size_t key_range = elems_per_thread * THREADS_NO * 2;
|
||||
|
||||
// TODO: document the test
|
||||
|
||||
// This test checks insert_unique method under pressure.
|
||||
// Threads will try to insert keys in the same order.
|
||||
@ -11,18 +13,20 @@ constexpr size_t key_range = elems_per_thread * THREADS_NO * 2;
|
||||
int main()
|
||||
{
|
||||
init_log();
|
||||
|
||||
memory_check(THREADS_NO, [] {
|
||||
map_t skiplist;
|
||||
|
||||
auto futures = run<std::vector<size_t>>(
|
||||
THREADS_NO, skiplist, [](auto acc, auto index) {
|
||||
auto rand = rand_gen(key_range);
|
||||
auto rand = rand_gen(key_range);
|
||||
long long downcount = elems_per_thread;
|
||||
std::vector<size_t> owned;
|
||||
auto inserter =
|
||||
insert_try<size_t, size_t, map_t>(acc, downcount, owned);
|
||||
|
||||
for (int i = 0; downcount > 0; i++) {
|
||||
for (int i = 0; downcount > 0; i++)
|
||||
{
|
||||
inserter(i, index);
|
||||
}
|
||||
|
||||
@ -31,7 +35,8 @@ int main()
|
||||
});
|
||||
|
||||
auto accessor = skiplist.access();
|
||||
for (auto &owned : collect(futures)) {
|
||||
for (auto &owned : collect(futures))
|
||||
{
|
||||
check_present_same<map_t>(accessor, owned);
|
||||
}
|
||||
|
||||
|
@ -1,21 +1,26 @@
|
||||
#include "common.h"
|
||||
|
||||
constexpr size_t THREADS_NO = std::min(max_no_threads, 8);
|
||||
constexpr size_t THREADS_NO = std::min(max_no_threads, 8);
|
||||
constexpr size_t elems_per_thread = 1e5;
|
||||
|
||||
// TODO: document the test
|
||||
|
||||
int main()
|
||||
{
|
||||
init_log();
|
||||
|
||||
memory_check(THREADS_NO, [&] {
|
||||
ds::static_array<std::thread, THREADS_NO> threads;
|
||||
map_t skiplist;
|
||||
|
||||
// put THREADS_NO * elems_per_thread items to the skiplist
|
||||
for (size_t thread_i = 0; thread_i < THREADS_NO; ++thread_i) {
|
||||
for (size_t thread_i = 0; thread_i < THREADS_NO; ++thread_i)
|
||||
{
|
||||
threads[thread_i] = std::thread(
|
||||
[&skiplist](size_t start, size_t end) {
|
||||
auto accessor = skiplist.access();
|
||||
for (size_t elem_i = start; elem_i < end; ++elem_i) {
|
||||
for (size_t elem_i = start; elem_i < end; ++elem_i)
|
||||
{
|
||||
accessor.insert(elem_i, elem_i);
|
||||
}
|
||||
},
|
||||
@ -23,7 +28,8 @@ int main()
|
||||
thread_i * elems_per_thread + elems_per_thread);
|
||||
}
|
||||
// wait all threads
|
||||
for (auto &thread : threads) {
|
||||
for (auto &thread : threads)
|
||||
{
|
||||
thread.join();
|
||||
}
|
||||
|
||||
@ -34,11 +40,13 @@ int main()
|
||||
"all elements in skiplist");
|
||||
}
|
||||
|
||||
for (size_t thread_i = 0; thread_i < THREADS_NO; ++thread_i) {
|
||||
for (size_t thread_i = 0; thread_i < THREADS_NO; ++thread_i)
|
||||
{
|
||||
threads[thread_i] = std::thread(
|
||||
[&skiplist](size_t start, size_t end) {
|
||||
auto accessor = skiplist.access();
|
||||
for (size_t elem_i = start; elem_i < end; ++elem_i) {
|
||||
for (size_t elem_i = start; elem_i < end; ++elem_i)
|
||||
{
|
||||
permanent_assert(accessor.remove(elem_i) == true, "");
|
||||
}
|
||||
},
|
||||
@ -46,7 +54,8 @@ int main()
|
||||
thread_i * elems_per_thread + elems_per_thread);
|
||||
}
|
||||
// // wait all threads
|
||||
for (auto &thread : threads) {
|
||||
for (auto &thread : threads)
|
||||
{
|
||||
thread.join();
|
||||
}
|
||||
|
||||
@ -61,8 +70,9 @@ int main()
|
||||
// check count
|
||||
{
|
||||
size_t iterator_counter = 0;
|
||||
auto accessor = skiplist.access();
|
||||
for (auto elem : accessor) {
|
||||
auto accessor = skiplist.access();
|
||||
for (auto elem : accessor)
|
||||
{
|
||||
++iterator_counter;
|
||||
cout << elem.first << " ";
|
||||
}
|
||||
|
@ -1,13 +1,16 @@
|
||||
#include "common.h"
|
||||
|
||||
constexpr size_t THREADS_NO = std::min(max_no_threads, 8);
|
||||
|
||||
constexpr size_t elements = 2e6;
|
||||
|
||||
// Test for simple memory leaks
|
||||
/**
|
||||
* Put elements number of elements in the skiplist per each thread and see
|
||||
* is there any memory leak
|
||||
*/
|
||||
int main()
|
||||
{
|
||||
init_log();
|
||||
|
||||
memory_check(THREADS_NO, [] {
|
||||
map_t skiplist;
|
||||
|
||||
|
@ -1,22 +1,30 @@
|
||||
#include "common.h"
|
||||
|
||||
constexpr size_t THREADS_NO = std::min(max_no_threads, 1);
|
||||
constexpr size_t THREADS_NO = std::min(max_no_threads, 1);
|
||||
constexpr size_t elems_per_thread = 16e5;
|
||||
|
||||
// Known memory leak at 1,600,000 elements.
|
||||
// TODO: Memory leak at 1,600,000 elements (Kruno wrote this here but
|
||||
// the memory_check method had invalid implementation)
|
||||
// 1. implement valid memory_check
|
||||
// 2. analyse this code
|
||||
// 3. fix the memory leak
|
||||
// 4. write proper test
|
||||
int main()
|
||||
{
|
||||
init_log();
|
||||
|
||||
memory_check(THREADS_NO, [&] {
|
||||
ds::static_array<std::thread, THREADS_NO> threads;
|
||||
map_t skiplist;
|
||||
|
||||
// put THREADS_NO * elems_per_thread items to the skiplist
|
||||
for (size_t thread_i = 0; thread_i < THREADS_NO; ++thread_i) {
|
||||
for (size_t thread_i = 0; thread_i < THREADS_NO; ++thread_i)
|
||||
{
|
||||
threads[thread_i] = std::thread(
|
||||
[&skiplist](size_t start, size_t end) {
|
||||
auto accessor = skiplist.access();
|
||||
for (size_t elem_i = start; elem_i < end; ++elem_i) {
|
||||
for (size_t elem_i = start; elem_i < end; ++elem_i)
|
||||
{
|
||||
accessor.insert(elem_i, elem_i);
|
||||
}
|
||||
},
|
||||
@ -24,7 +32,8 @@ int main()
|
||||
thread_i * elems_per_thread + elems_per_thread);
|
||||
}
|
||||
// wait all threads
|
||||
for (auto &thread : threads) {
|
||||
for (auto &thread : threads)
|
||||
{
|
||||
thread.join();
|
||||
}
|
||||
|
||||
@ -35,11 +44,13 @@ int main()
|
||||
"all elements in skiplist");
|
||||
}
|
||||
|
||||
for (size_t thread_i = 0; thread_i < THREADS_NO; ++thread_i) {
|
||||
for (size_t thread_i = 0; thread_i < THREADS_NO; ++thread_i)
|
||||
{
|
||||
threads[thread_i] = std::thread(
|
||||
[&skiplist](size_t start, size_t end) {
|
||||
auto accessor = skiplist.access();
|
||||
for (size_t elem_i = start; elem_i < end; ++elem_i) {
|
||||
for (size_t elem_i = start; elem_i < end; ++elem_i)
|
||||
{
|
||||
permanent_assert(accessor.remove(elem_i) == true, "");
|
||||
}
|
||||
},
|
||||
@ -47,7 +58,8 @@ int main()
|
||||
thread_i * elems_per_thread + elems_per_thread);
|
||||
}
|
||||
// // wait all threads
|
||||
for (auto &thread : threads) {
|
||||
for (auto &thread : threads)
|
||||
{
|
||||
thread.join();
|
||||
}
|
||||
|
||||
@ -62,8 +74,9 @@ int main()
|
||||
// check count
|
||||
{
|
||||
size_t iterator_counter = 0;
|
||||
auto accessor = skiplist.access();
|
||||
for (auto elem : accessor) {
|
||||
auto accessor = skiplist.access();
|
||||
for (auto elem : accessor)
|
||||
{
|
||||
++iterator_counter;
|
||||
cout << elem.first << " ";
|
||||
}
|
||||
|
@ -7,13 +7,16 @@ constexpr size_t op_per_thread = 1e5;
|
||||
constexpr size_t max_number = 10;
|
||||
constexpr size_t no_insert_for_one_delete = 1;
|
||||
|
||||
// This test checks MultiIterator from multimap.
|
||||
// Each thread removes random data. So removes are joint.
|
||||
// Calls of remove method are interleaved with insert calls which always
|
||||
// succeed.
|
||||
/**
|
||||
* This test checks MultiIterator from multimap.
|
||||
* Each thread removes random data. So removes are joint.
|
||||
* Calls of remove method are interleaved with insert calls which always
|
||||
* succeed.
|
||||
*/
|
||||
int main()
|
||||
{
|
||||
init_log();
|
||||
|
||||
memory_check(THREADS_NO, [] {
|
||||
multimap_t skiplist;
|
||||
|
||||
|
@ -1,48 +1,57 @@
|
||||
#include "common.h"
|
||||
|
||||
constexpr size_t THREADS_NO = std::min(max_no_threads, 8);
|
||||
constexpr size_t key_range = 1e4;
|
||||
constexpr size_t THREADS_NO = std::min(max_no_threads, 8);
|
||||
constexpr size_t key_range = 1e4;
|
||||
constexpr size_t op_per_thread = 1e5;
|
||||
// Depending on value there is a possiblity of numerical overflow
|
||||
constexpr size_t max_number = 10;
|
||||
constexpr size_t max_number = 10;
|
||||
constexpr size_t no_insert_for_one_delete = 1;
|
||||
|
||||
// This test checks MultiIterator remove method.
|
||||
// Each thread removes random data. So removes are joint and scattered on same
|
||||
// key values.
|
||||
// Calls of remove method are interleaved with insert calls which always
|
||||
// succeed.
|
||||
/**
|
||||
* This test checks MultiIterator remove method.
|
||||
* Each thread removes random data. So removes are joint and scattered on same
|
||||
* key values. Calls of remove method are interleaved with insert calls which
|
||||
* always succeed.
|
||||
*/
|
||||
int main()
|
||||
{
|
||||
init_log();
|
||||
|
||||
memory_check(THREADS_NO, [] {
|
||||
multimap_t skiplist;
|
||||
|
||||
auto futures = run<std::pair<long long, std::vector<long long>>>(
|
||||
THREADS_NO, skiplist, [](auto acc, auto index) {
|
||||
auto rand = rand_gen(key_range);
|
||||
auto rand_op = rand_gen_bool(no_insert_for_one_delete);
|
||||
auto rand = rand_gen(key_range);
|
||||
auto rand_op = rand_gen_bool(no_insert_for_one_delete);
|
||||
long long downcount = op_per_thread;
|
||||
std::vector<long long> set(key_range, 0);
|
||||
long long sum = 0;
|
||||
|
||||
do {
|
||||
do
|
||||
{
|
||||
size_t num = rand();
|
||||
auto data = rand() % max_number;
|
||||
if (rand_op()) {
|
||||
auto data = rand() % max_number;
|
||||
if (rand_op())
|
||||
{
|
||||
|
||||
int len = 0;
|
||||
for (auto it = acc.find_multi(num); it.has_value();
|
||||
it++) {
|
||||
it++)
|
||||
{
|
||||
len++;
|
||||
}
|
||||
if (len > 0) {
|
||||
if (len > 0)
|
||||
{
|
||||
int pos = rand() % len;
|
||||
for (auto it = acc.find_multi(num); it.has_value();
|
||||
it++) {
|
||||
if (pos == 0) {
|
||||
it++)
|
||||
{
|
||||
if (pos == 0)
|
||||
{
|
||||
auto data_r = it->second;
|
||||
if (it.remove()) {
|
||||
if (it.remove())
|
||||
{
|
||||
downcount--;
|
||||
set[num]--;
|
||||
sum -= data_r;
|
||||
@ -55,7 +64,9 @@ int main()
|
||||
pos--;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
acc.insert(num, data);
|
||||
downcount--;
|
||||
set[num]++;
|
||||
@ -67,10 +78,12 @@ int main()
|
||||
});
|
||||
|
||||
long set[key_range] = {0};
|
||||
long long sums = 0;
|
||||
for (auto &data : collect(futures)) {
|
||||
long long sums = 0;
|
||||
for (auto &data : collect(futures))
|
||||
{
|
||||
sums += data.second.first;
|
||||
for (int i = 0; i < key_range; i++) {
|
||||
for (int i = 0; i < key_range; i++)
|
||||
{
|
||||
set[i] += data.second.second[i];
|
||||
}
|
||||
}
|
||||
@ -78,7 +91,8 @@ int main()
|
||||
auto accessor = skiplist.access();
|
||||
check_multi_iterator(accessor, key_range, set);
|
||||
|
||||
for (auto &e : accessor) {
|
||||
for (auto &e : accessor)
|
||||
{
|
||||
set[e.first]--;
|
||||
sums -= e.second;
|
||||
}
|
||||
|
@ -1,42 +1,48 @@
|
||||
#include "common.h"
|
||||
|
||||
constexpr size_t THREADS_NO = std::min(max_no_threads, 4);
|
||||
constexpr size_t key_range = 1e4;
|
||||
constexpr size_t THREADS_NO = std::min(max_no_threads, 4);
|
||||
constexpr size_t key_range = 1e4;
|
||||
constexpr size_t op_per_thread = 1e5;
|
||||
// Depending on value there is a possiblity of numerical overflow
|
||||
constexpr size_t max_number = 10;
|
||||
constexpr size_t max_number = 10;
|
||||
constexpr size_t no_insert_for_one_delete = 2;
|
||||
|
||||
// This test checks MultiIterator remove method ].
|
||||
// Each thread removes all duplicate data on random key. So removes are joint
|
||||
// and scattered on same
|
||||
// key values.
|
||||
// Calls of remove method are interleaved with insert calls which always
|
||||
// succeed.
|
||||
/**
|
||||
* This test checks MultiIterator remove method. Each thread removes all
|
||||
* duplicate data for a random key. So removes are joined and scattered on the
|
||||
* same key values. Calls of remove method are interleaved with insert calls
|
||||
* which always succeed.
|
||||
*/
|
||||
int main()
|
||||
{
|
||||
init_log();
|
||||
|
||||
memory_check(THREADS_NO, [] {
|
||||
multimap_t skiplist;
|
||||
|
||||
auto futures = run<std::pair<long long, std::vector<long long>>>(
|
||||
THREADS_NO, skiplist, [](auto acc, auto index) {
|
||||
auto rand = rand_gen(key_range);
|
||||
auto rand_op = rand_gen_bool(no_insert_for_one_delete);
|
||||
auto rand = rand_gen(key_range);
|
||||
auto rand_op = rand_gen_bool(no_insert_for_one_delete);
|
||||
long long downcount = op_per_thread;
|
||||
std::vector<long long> set(key_range, 0);
|
||||
long long sum = 0;
|
||||
|
||||
do {
|
||||
do
|
||||
{
|
||||
size_t num = rand();
|
||||
auto data = rand() % max_number;
|
||||
if (rand_op()) {
|
||||
auto data = rand() % max_number;
|
||||
if (rand_op())
|
||||
{
|
||||
auto it = acc.find_multi(num);
|
||||
if (it.has_value()) {
|
||||
if (it.has_value())
|
||||
{
|
||||
it++;
|
||||
while (it.has_value()) {
|
||||
while (it.has_value())
|
||||
{
|
||||
auto data_r = it->second;
|
||||
if (it.remove()) {
|
||||
if (it.remove())
|
||||
{
|
||||
downcount--;
|
||||
set[num]--;
|
||||
sum -= data_r;
|
||||
@ -47,7 +53,9 @@ int main()
|
||||
it++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
acc.insert(num, data);
|
||||
downcount--;
|
||||
set[num]++;
|
||||
@ -59,10 +67,12 @@ int main()
|
||||
});
|
||||
|
||||
long set[key_range] = {0};
|
||||
long long sums = 0;
|
||||
for (auto &data : collect(futures)) {
|
||||
long long sums = 0;
|
||||
for (auto &data : collect(futures))
|
||||
{
|
||||
sums += data.second.first;
|
||||
for (int i = 0; i < key_range; i++) {
|
||||
for (int i = 0; i < key_range; i++)
|
||||
{
|
||||
set[i] += data.second.second[i];
|
||||
}
|
||||
}
|
||||
@ -70,7 +80,8 @@ int main()
|
||||
auto accessor = skiplist.access();
|
||||
check_multi_iterator(accessor, key_range, set);
|
||||
|
||||
for (auto &e : accessor) {
|
||||
for (auto &e : accessor)
|
||||
{
|
||||
set[e.first]--;
|
||||
sums -= e.second;
|
||||
}
|
||||
|
@ -1,12 +1,14 @@
|
||||
#include "common.h"
|
||||
|
||||
constexpr size_t THREADS_NO = std::min(max_no_threads, 8);
|
||||
constexpr size_t key_range = 1e4;
|
||||
constexpr size_t THREADS_NO = std::min(max_no_threads, 8);
|
||||
constexpr size_t key_range = 1e4;
|
||||
constexpr size_t op_per_thread = 1e5;
|
||||
// Depending on value there is a possiblity of numerical overflow
|
||||
constexpr size_t max_number = 10;
|
||||
constexpr size_t max_number = 10;
|
||||
constexpr size_t no_insert_for_one_delete = 1;
|
||||
|
||||
// TODO: document the test
|
||||
|
||||
// This test checks multimap.
|
||||
// Each thread removes random data. So removes are joint.
|
||||
// Calls of remove method are interleaved with insert calls which always
|
||||
@ -14,29 +16,35 @@ constexpr size_t no_insert_for_one_delete = 1;
|
||||
int main()
|
||||
{
|
||||
init_log();
|
||||
|
||||
memory_check(THREADS_NO, [] {
|
||||
multimap_t skiplist;
|
||||
std::atomic<long long> size(0);
|
||||
|
||||
auto futures = run<std::pair<long long, std::vector<long long>>>(
|
||||
THREADS_NO, skiplist, [&size](auto acc, auto index) {
|
||||
auto rand = rand_gen(key_range);
|
||||
auto rand_op = rand_gen_bool(no_insert_for_one_delete);
|
||||
auto rand = rand_gen(key_range);
|
||||
auto rand_op = rand_gen_bool(no_insert_for_one_delete);
|
||||
long long downcount = op_per_thread;
|
||||
std::vector<long long> set(key_range, 0);
|
||||
long long sum = 0;
|
||||
|
||||
do {
|
||||
do
|
||||
{
|
||||
size_t num = rand();
|
||||
auto data = num % max_number;
|
||||
if (rand_op()) {
|
||||
if (acc.remove(num)) {
|
||||
auto data = num % max_number;
|
||||
if (rand_op())
|
||||
{
|
||||
if (acc.remove(num))
|
||||
{
|
||||
downcount--;
|
||||
set[num]--;
|
||||
sum -= data;
|
||||
size--;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
acc.insert(num, data);
|
||||
downcount--;
|
||||
set[num]++;
|
||||
@ -49,11 +57,13 @@ int main()
|
||||
});
|
||||
|
||||
long set[key_range] = {0};
|
||||
long long sums = 0;
|
||||
long long sums = 0;
|
||||
long long size_calc = 0;
|
||||
for (auto &data : collect(futures)) {
|
||||
for (auto &data : collect(futures))
|
||||
{
|
||||
sums += data.second.first;
|
||||
for (int i = 0; i < key_range; i++) {
|
||||
for (int i = 0; i < key_range; i++)
|
||||
{
|
||||
set[i] += data.second.second[i];
|
||||
size_calc += data.second.second[i];
|
||||
}
|
||||
@ -64,15 +74,18 @@ int main()
|
||||
check_order<multimap_t>(accessor);
|
||||
|
||||
auto bef_it = accessor.end();
|
||||
for (int i = 0; i < key_range; i++) {
|
||||
for (int i = 0; i < key_range; i++)
|
||||
{
|
||||
auto it = accessor.find(i);
|
||||
if (set[i] > 0) {
|
||||
if (set[i] > 0)
|
||||
{
|
||||
permanent_assert(it != accessor.end(),
|
||||
"Multimap doesn't contain necessary element "
|
||||
<< i);
|
||||
|
||||
if (bef_it == accessor.end()) bef_it = accessor.find(i);
|
||||
for (int j = 0; j < set[i]; j++) {
|
||||
for (int j = 0; j < set[i]; j++)
|
||||
{
|
||||
permanent_assert(
|
||||
bef_it != accessor.end(),
|
||||
"Previous iterator doesn't iterate through same "
|
||||
@ -89,7 +102,8 @@ int main()
|
||||
bef_it++;
|
||||
}
|
||||
|
||||
for (int j = 0; j < set[i]; j++) {
|
||||
for (int j = 0; j < set[i]; j++)
|
||||
{
|
||||
permanent_assert(it != accessor.end(),
|
||||
"Iterator doesn't iterate through same "
|
||||
"key entrys. Expected "
|
||||
@ -110,7 +124,8 @@ int main()
|
||||
}
|
||||
}
|
||||
|
||||
for (auto &e : accessor) {
|
||||
for (auto &e : accessor)
|
||||
{
|
||||
set[e.first]--;
|
||||
sums -= e.second;
|
||||
}
|
||||
|
@ -5,6 +5,8 @@ constexpr size_t key_range = 1e4;
|
||||
constexpr size_t op_per_thread = 1e5;
|
||||
constexpr size_t no_insert_for_one_delete = 1;
|
||||
|
||||
// TODO: document the test
|
||||
|
||||
// This test checks multiset.
|
||||
// Each thread removes random data. So removes are joint.
|
||||
// Calls of remove method are interleaved with insert calls which always
|
||||
@ -12,6 +14,7 @@ constexpr size_t no_insert_for_one_delete = 1;
|
||||
int main()
|
||||
{
|
||||
init_log();
|
||||
|
||||
memory_check(THREADS_NO, [] {
|
||||
multiset_t skiplist;
|
||||
|
||||
|
@ -6,6 +6,8 @@ constexpr size_t op_per_thread = 1e5;
|
||||
constexpr size_t max_number = 10;
|
||||
constexpr size_t no_insert_for_one_delete = 2;
|
||||
|
||||
// TODO: document the test
|
||||
|
||||
// This test checks remove method under pressure.
|
||||
// Threads will try to insert and remove keys aproximetly in the same order.
|
||||
// This will force threads to compete intensly with each other.
|
||||
@ -13,6 +15,7 @@ constexpr size_t no_insert_for_one_delete = 2;
|
||||
int main()
|
||||
{
|
||||
init_log();
|
||||
|
||||
memory_check(THREADS_NO, [] {
|
||||
map_t skiplist;
|
||||
|
||||
|
@ -5,12 +5,15 @@ constexpr size_t key_range = 1e5;
|
||||
constexpr size_t op_per_thread = 1e6;
|
||||
constexpr size_t no_insert_for_one_delete = 1;
|
||||
|
||||
// TODO: document the test
|
||||
|
||||
// This test checks remove method under pressure.
|
||||
// Each thread removes it's own data. So removes are disjoint.
|
||||
// Calls of remove method are interleaved with insert calls.
|
||||
int main()
|
||||
{
|
||||
init_log();
|
||||
|
||||
memory_check(THREADS_NO, [] {
|
||||
map_t skiplist;
|
||||
|
||||
|
@ -1,12 +1,14 @@
|
||||
#include "common.h"
|
||||
|
||||
constexpr size_t THREADS_NO = std::min(max_no_threads, 8);
|
||||
constexpr size_t key_range = 1e4;
|
||||
constexpr size_t THREADS_NO = std::min(max_no_threads, 8);
|
||||
constexpr size_t key_range = 1e4;
|
||||
constexpr size_t op_per_thread = 1e5;
|
||||
// Depending on value there is a possiblity of numerical overflow
|
||||
constexpr size_t max_number = 10;
|
||||
constexpr size_t max_number = 10;
|
||||
constexpr size_t no_insert_for_one_delete = 2;
|
||||
|
||||
// TODO: document the test
|
||||
|
||||
// This test checks remove method under pressure.
|
||||
// Each thread removes random data. So removes are joint.
|
||||
// Calls of remove method are interleaved with insert calls.
|
||||
@ -18,23 +20,29 @@ int main()
|
||||
|
||||
auto futures = run<std::pair<long long, long long>>(
|
||||
THREADS_NO, skiplist, [](auto acc, auto index) {
|
||||
auto rand = rand_gen(key_range);
|
||||
auto rand_op = rand_gen_bool(no_insert_for_one_delete);
|
||||
auto rand = rand_gen(key_range);
|
||||
auto rand_op = rand_gen_bool(no_insert_for_one_delete);
|
||||
long long downcount = op_per_thread;
|
||||
long long sum = 0;
|
||||
long long count = 0;
|
||||
long long sum = 0;
|
||||
long long count = 0;
|
||||
|
||||
do {
|
||||
auto num = rand();
|
||||
do
|
||||
{
|
||||
auto num = rand();
|
||||
auto data = num % max_number;
|
||||
if (rand_op()) {
|
||||
if (acc.remove(num)) {
|
||||
if (rand_op())
|
||||
{
|
||||
if (acc.remove(num))
|
||||
{
|
||||
sum -= data;
|
||||
downcount--;
|
||||
count--;
|
||||
}
|
||||
} else {
|
||||
if (acc.insert(num, data).second) {
|
||||
}
|
||||
else
|
||||
{
|
||||
if (acc.insert(num, data).second)
|
||||
{
|
||||
sum += data;
|
||||
downcount--;
|
||||
count++;
|
||||
@ -45,15 +53,17 @@ int main()
|
||||
return std::pair<long long, long long>(sum, count);
|
||||
});
|
||||
|
||||
auto accessor = skiplist.access();
|
||||
long long sums = 0;
|
||||
auto accessor = skiplist.access();
|
||||
long long sums = 0;
|
||||
long long counters = 0;
|
||||
for (auto &data : collect(futures)) {
|
||||
for (auto &data : collect(futures))
|
||||
{
|
||||
sums += data.second.first;
|
||||
counters += data.second.second;
|
||||
}
|
||||
|
||||
for (auto &e : accessor) {
|
||||
for (auto &e : accessor)
|
||||
{
|
||||
sums -= e.second;
|
||||
}
|
||||
permanent_assert(sums == 0, "Aproximetly Same values are present");
|
||||
|
@ -5,12 +5,15 @@ constexpr size_t key_range = 1e4;
|
||||
constexpr size_t op_per_thread = 1e5;
|
||||
constexpr size_t no_insert_for_one_delete = 2;
|
||||
|
||||
// TODO: document the test
|
||||
|
||||
// This test checks set.
|
||||
// Each thread removes random data. So removes are joint.
|
||||
// Calls of remove method are interleaved with insert calls.
|
||||
int main()
|
||||
{
|
||||
init_log();
|
||||
|
||||
memory_check(THREADS_NO, [] {
|
||||
set_t skiplist;
|
||||
|
||||
|
@ -8,6 +8,8 @@ constexpr size_t max_number = 10;
|
||||
constexpr size_t no_find_per_change = 5;
|
||||
constexpr size_t no_insert_for_one_delete = 1;
|
||||
|
||||
// TODO: document the test
|
||||
|
||||
// This test simulates behavior of transactions.
|
||||
// Each thread makes a series of finds interleaved with method which change.
|
||||
// Exact ratio of finds per change and insert per delete can be regulated with
|
||||
@ -15,6 +17,7 @@ constexpr size_t no_insert_for_one_delete = 1;
|
||||
int main()
|
||||
{
|
||||
init_log();
|
||||
|
||||
memory_check(THREADS_NO, [] {
|
||||
map_t skiplist;
|
||||
|
||||
|
@ -1,11 +1,21 @@
|
||||
#include <iostream>
|
||||
#include <chrono>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "logging/default.cpp"
|
||||
#include "utils/timer/timer.hpp"
|
||||
#include "utils/assert.hpp"
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
/**
|
||||
* Creates a test timer which will log timeout message at the timeout event.
|
||||
*
|
||||
* @param counter how many time units the timer has to wait
|
||||
*
|
||||
* @return shared pointer to a timer
|
||||
*/
|
||||
Timer::sptr create_test_timer(int64_t counter)
|
||||
{
|
||||
return std::make_shared<Timer>(
|
||||
@ -13,16 +23,38 @@ Timer::sptr create_test_timer(int64_t counter)
|
||||
);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
TEST(TimerSchedulerTest, TimerSchedulerExecution)
|
||||
{
|
||||
// initialize the timer
|
||||
TimerScheduler<TimerSet, std::chrono::seconds> timer_scheduler;
|
||||
|
||||
// run the timer
|
||||
timer_scheduler.run();
|
||||
|
||||
// add a couple of test timers
|
||||
for (int64_t i = 1; i <= 3; ++i) {
|
||||
timer_scheduler.add(create_test_timer(i));
|
||||
}
|
||||
|
||||
// wait for that timers
|
||||
std::this_thread::sleep_for(4s);
|
||||
|
||||
ASSERT_EQ(timer_scheduler.size(), 0);
|
||||
|
||||
// add another test timer
|
||||
timer_scheduler.add(create_test_timer(1));
|
||||
|
||||
// wait for another timer
|
||||
std::this_thread::sleep_for(2s);
|
||||
|
||||
// the test is done
|
||||
timer_scheduler.stop();
|
||||
return 0;
|
||||
|
||||
ASSERT_EQ(timer_scheduler.size(), 0);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
|
@ -44,6 +44,7 @@ foreach(test_cpp ${test_type_cpps})
|
||||
target_link_libraries(${target_name} dl)
|
||||
|
||||
# register test
|
||||
add_test(${target_name} ${exec_name})
|
||||
add_test(${target_name} ${exec_name}
|
||||
--gtest_output=xml:${CMAKE_BINARY_DIR}/test_results/${target_name}.xml)
|
||||
|
||||
endforeach()
|
||||
|
@ -1,22 +1,17 @@
|
||||
#define CATCH_CONFIG_MAIN
|
||||
#include "catch.hpp"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include "data_structures/bloom/bloom_filter.hpp"
|
||||
#include "utils/command_line/arguments.hpp"
|
||||
#include "utils/hashing/fnv64.hpp"
|
||||
|
||||
#include "data_structures/bloom/bloom_filter.hpp"
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wwritable-strings"
|
||||
|
||||
using StringHashFunction = std::function<uint64_t(const std::string &)>;
|
||||
|
||||
TEST_CASE("BloomFilter Test")
|
||||
TEST(BloomFilterTest, InsertContains)
|
||||
{
|
||||
StringHashFunction hash1 = fnv64<std::string>;
|
||||
StringHashFunction hash2 = fnv1a64<std::string>;
|
||||
|
||||
auto c = [](auto x) -> int { return x % 4; };
|
||||
std::vector<StringHashFunction> funcs = {hash1, hash2};
|
||||
|
||||
BloomFilter<std::string, 64> bloom(funcs);
|
||||
@ -24,19 +19,21 @@ TEST_CASE("BloomFilter Test")
|
||||
std::string test = "test";
|
||||
std::string kifla = "kifla";
|
||||
|
||||
std::cout << hash1(test) << std::endl;
|
||||
std::cout << hash2(test) << std::endl;
|
||||
|
||||
std::cout << hash1(kifla) << std::endl;
|
||||
std::cout << hash2(kifla) << std::endl;
|
||||
|
||||
std::cout << bloom.contains(test) << std::endl;
|
||||
bool contains_test = bloom.contains(test);
|
||||
ASSERT_EQ(contains_test, false);
|
||||
bloom.insert(test);
|
||||
std::cout << bloom.contains(test) << std::endl;
|
||||
contains_test = bloom.contains(test);
|
||||
ASSERT_EQ(contains_test, true);
|
||||
|
||||
std::cout << bloom.contains(kifla) << std::endl;
|
||||
bool contains_kifla = bloom.contains(kifla);
|
||||
ASSERT_EQ(contains_kifla, false);
|
||||
bloom.insert(kifla);
|
||||
std::cout << bloom.contains(kifla) << std::endl;
|
||||
contains_kifla = bloom.contains(kifla);
|
||||
ASSERT_EQ(contains_kifla, true);
|
||||
}
|
||||
|
||||
#pragma clang diagnostic pop
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
|
@ -5,15 +5,16 @@
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "communication/bolt/v1/transport/chunked_decoder.hpp"
|
||||
|
||||
using byte = unsigned char;
|
||||
|
||||
void print_hex(byte x) { printf("%02X ", static_cast<byte>(x)); }
|
||||
|
||||
class DummyStream
|
||||
struct DummyStream
|
||||
{
|
||||
public:
|
||||
void write(const byte *values, size_t n)
|
||||
{
|
||||
data.insert(data.end(), values, values + n);
|
||||
@ -35,25 +36,33 @@ static constexpr size_t N = std::extent<decltype(chunks)>::value;
|
||||
|
||||
std::string decoded = "A quick brown fox jumps over a lazy dog";
|
||||
|
||||
int main(void)
|
||||
TEST(ChunkedDecoderTest, WriteString)
|
||||
{
|
||||
// DummyStream stream;
|
||||
// Decoder decoder(stream);
|
||||
DummyStream stream;
|
||||
Decoder decoder(stream);
|
||||
|
||||
// for(size_t i = 0; i < N; ++i)
|
||||
// {
|
||||
// auto& chunk = chunks[i];
|
||||
// auto finished = decoder.decode(chunk.data(), chunk.size());
|
||||
for(size_t i = 0; i < N; ++i)
|
||||
{
|
||||
auto & chunk = chunks[i];
|
||||
logging::info("Chunk size: {}", chunk.size());
|
||||
|
||||
// // break early if finished
|
||||
// if(finished)
|
||||
// break;
|
||||
// }
|
||||
const byte* start = chunk.data();
|
||||
auto finished = decoder.decode(start, chunk.size());
|
||||
|
||||
// assert(decoded.size() == stream.data.size());
|
||||
// break early if finished
|
||||
if(finished)
|
||||
break;
|
||||
}
|
||||
|
||||
// for(size_t i = 0; i < decoded.size(); ++i)
|
||||
// assert(decoded[i] == stream.data[i]);
|
||||
|
||||
return 0;
|
||||
// check validity
|
||||
ASSERT_EQ(decoded.size(), stream.data.size());
|
||||
for(size_t i = 0; i < decoded.size(); ++i)
|
||||
ASSERT_EQ(decoded[i], stream.data[i]);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,8 @@
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "communication/bolt/v1/transport/chunked_encoder.hpp"
|
||||
#include "logging/default.hpp"
|
||||
#include "logging/streams/stdout.hpp"
|
||||
@ -54,61 +56,68 @@ void write_ff(Encoder &encoder, size_t n)
|
||||
void check_ff(DummyStream &stream, size_t n)
|
||||
{
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
assert(stream.pop() == byte('\xFF'));
|
||||
ASSERT_EQ(stream.pop(), byte('\xFF'));
|
||||
|
||||
(void)stream;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
using encoder_t = bolt::ChunkedEncoder<DummyStream>;
|
||||
|
||||
TEST(ChunkedEncoderTest, Encode)
|
||||
{
|
||||
// TODO: write new test
|
||||
|
||||
// logging::init_async();
|
||||
// logging::log->pipe(std::make_unique<Stdout>());
|
||||
// DummyStream stream;
|
||||
// bolt::ChunkedEncoder<DummyStream> encoder(stream);
|
||||
DummyStream stream;
|
||||
encoder_t encoder(stream);
|
||||
size_t chunk_size = encoder_t::chunk_size;
|
||||
|
||||
// write_ff(encoder, 10);
|
||||
// write_ff(encoder, 10);
|
||||
// encoder.flush();
|
||||
write_ff(encoder, 10);
|
||||
write_ff(encoder, 10);
|
||||
encoder.write_chunk();
|
||||
|
||||
// write_ff(encoder, 10);
|
||||
// write_ff(encoder, 10);
|
||||
// encoder.flush();
|
||||
write_ff(encoder, 10);
|
||||
write_ff(encoder, 10);
|
||||
encoder.write_chunk();
|
||||
|
||||
// // this should be two chunks, one of size 65533 and the other of size 1467
|
||||
// write_ff(encoder, 67000);
|
||||
// encoder.flush();
|
||||
// this should be two chunks, one of size 65533 and the other of size 1467
|
||||
write_ff(encoder, 67000);
|
||||
encoder.write_chunk();
|
||||
|
||||
// for (int i = 0; i < 10000; ++i)
|
||||
// write_ff(encoder, 1500);
|
||||
// encoder.flush();
|
||||
for (int i = 0; i < 10000; ++i)
|
||||
write_ff(encoder, 1500);
|
||||
encoder.write_chunk();
|
||||
|
||||
// assert(stream.pop_size() == 20);
|
||||
// check_ff(stream, 20);
|
||||
// assert(stream.pop_size() == 0);
|
||||
ASSERT_EQ(stream.pop_size(), 20);
|
||||
check_ff(stream, 20);
|
||||
ASSERT_EQ(stream.pop_size(), 0);
|
||||
|
||||
// assert(stream.pop_size() == 20);
|
||||
// check_ff(stream, 20);
|
||||
// assert(stream.pop_size() == 0);
|
||||
ASSERT_EQ(stream.pop_size(), 20);
|
||||
check_ff(stream, 20);
|
||||
ASSERT_EQ(stream.pop_size(), 0);
|
||||
|
||||
// assert(stream.pop_size() == encoder.chunk_size);
|
||||
// check_ff(stream, encoder.chunk_size);
|
||||
// assert(stream.pop_size() == 1467);
|
||||
// check_ff(stream, 1467);
|
||||
// assert(stream.pop_size() == 0);
|
||||
ASSERT_EQ(stream.pop_size(), chunk_size);
|
||||
check_ff(stream, chunk_size);
|
||||
ASSERT_EQ(stream.pop_size(), 0);
|
||||
|
||||
// size_t k = 10000 * 1500;
|
||||
ASSERT_EQ(stream.pop_size(), 1467);
|
||||
check_ff(stream, 1467);
|
||||
ASSERT_EQ(stream.pop_size(), 0);
|
||||
|
||||
// while (k > 0) {
|
||||
// auto size = k > encoder.chunk_size ? encoder.chunk_size : k;
|
||||
// assert(stream.pop_size() == size);
|
||||
// check_ff(stream, size);
|
||||
size_t k = 10000 * 1500;
|
||||
|
||||
// k -= size;
|
||||
// }
|
||||
|
||||
// assert(stream.pop_size() == 0);
|
||||
|
||||
return 0;
|
||||
while (k > 0) {
|
||||
auto size = k > chunk_size ? chunk_size : k;
|
||||
ASSERT_EQ(stream.pop_size(), size);
|
||||
check_ff(stream, size);
|
||||
ASSERT_EQ(stream.pop_size(), 0);
|
||||
k -= size;
|
||||
}
|
||||
ASSERT_EQ(stream.pop_size(), 0);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
logging::init_sync();
|
||||
logging::log->pipe(std::make_unique<Stdout>());
|
||||
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user