test refactoring - work in progress

This commit is contained in:
Marko Budiselic 2016-12-22 15:51:16 +01:00
parent 55a62f9640
commit c22cdf929d
36 changed files with 861 additions and 707 deletions

View File

@ -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;
};

View File

@ -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();

View File

@ -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)

View File

@ -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();
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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

View File

@ -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()
{

View File

@ -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.

View File

@ -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;
}
}

View File

@ -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]);
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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 << " ";
}

View File

@ -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;

View File

@ -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 << " ";
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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");

View File

@ -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;

View File

@ -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;

View File

@ -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();
}

View File

@ -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()

View File

@ -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();
}

View File

@ -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();
}

View File

@ -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();
}