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,7 +8,9 @@
|
|||||||
|
|
||||||
#include "logging/default.hpp"
|
#include "logging/default.hpp"
|
||||||
|
|
||||||
/** @class Timer
|
/**
|
||||||
|
* @class Timer
|
||||||
|
*
|
||||||
* @brief The timer contains counter and handler.
|
* @brief The timer contains counter and handler.
|
||||||
*
|
*
|
||||||
* With every clock interval the counter should be decresed for
|
* With every clock interval the counter should be decresed for
|
||||||
@ -48,7 +50,9 @@ struct Timer
|
|||||||
* the process method.
|
* the process method.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @class TimerSet
|
/**
|
||||||
|
* @class TimerSet
|
||||||
|
*
|
||||||
* @brief Trivial timer container implementation.
|
* @brief Trivial timer container implementation.
|
||||||
*
|
*
|
||||||
* Internal data stucture for storage of timers is std::set. So, the
|
* Internal data stucture for storage of timers is std::set. So, the
|
||||||
@ -70,6 +74,11 @@ public:
|
|||||||
timers.erase(timer);
|
timers.erase(timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint64_t size() const
|
||||||
|
{
|
||||||
|
return timers.size();
|
||||||
|
}
|
||||||
|
|
||||||
void process()
|
void process()
|
||||||
{
|
{
|
||||||
for (auto it = timers.begin(); it != timers.end(); ) {
|
for (auto it = timers.begin(); it != timers.end(); ) {
|
||||||
@ -87,10 +96,17 @@ private:
|
|||||||
std::set<std::shared_ptr<Timer>> timers;
|
std::set<std::shared_ptr<Timer>> timers;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** @class TimerScheduler
|
/**
|
||||||
|
* @class TimerScheduler
|
||||||
|
*
|
||||||
* @brief TimerScheduler is a manager class and its responsibility is to
|
* @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
|
* take care of the time and call the timer_container process method in the
|
||||||
* appropriate time.
|
* 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 <
|
template <
|
||||||
typename timer_container_type,
|
typename timer_container_type,
|
||||||
@ -99,19 +115,47 @@ template <
|
|||||||
> class TimerScheduler
|
> class TimerScheduler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a timer.
|
||||||
|
*
|
||||||
|
* @param timer shared pointer to the timer object \ref Timer
|
||||||
|
*/
|
||||||
void add(Timer::sptr timer)
|
void add(Timer::sptr timer)
|
||||||
{
|
{
|
||||||
timer_container.add(timer);
|
timer_container.add(timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes a timer.
|
||||||
|
*
|
||||||
|
* @param timer shared pointer to the timer object \ref Timer
|
||||||
|
*/
|
||||||
void remove(Timer::sptr timer)
|
void remove(Timer::sptr timer)
|
||||||
{
|
{
|
||||||
timer_container.remove(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()
|
void run()
|
||||||
{
|
{
|
||||||
is_running.store(true);
|
is_running.store(true);
|
||||||
|
|
||||||
run_thread = std::thread([this]() {
|
run_thread = std::thread([this]() {
|
||||||
while (is_running.load()) {
|
while (is_running.load()) {
|
||||||
std::this_thread::sleep_for(delta_time_type(delta_time));
|
std::this_thread::sleep_for(delta_time_type(delta_time));
|
||||||
@ -121,11 +165,17 @@ public:
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stops the whole processing.
|
||||||
|
*/
|
||||||
void stop()
|
void stop()
|
||||||
{
|
{
|
||||||
is_running.store(false);
|
is_running.store(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Joins the processing thread.
|
||||||
|
*/
|
||||||
~TimerScheduler()
|
~TimerScheduler()
|
||||||
{
|
{
|
||||||
run_thread.join();
|
run_thread.join();
|
||||||
|
@ -6,6 +6,8 @@ enable_testing()
|
|||||||
|
|
||||||
include_directories(${catch_source_dir}/include)
|
include_directories(${catch_source_dir}/include)
|
||||||
|
|
||||||
|
file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/test_results)
|
||||||
|
|
||||||
# copy test data
|
# copy test data
|
||||||
file(COPY ${CMAKE_SOURCE_DIR}/tests/data
|
file(COPY ${CMAKE_SOURCE_DIR}/tests/data
|
||||||
DESTINATION ${CMAKE_BINARY_DIR}/tests)
|
DESTINATION ${CMAKE_BINARY_DIR}/tests)
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
#include <random>
|
#include <random>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
|
#include "benchmark/benchmark_api.h"
|
||||||
|
|
||||||
#include "data_structures/bloom/bloom_filter.hpp"
|
#include "data_structures/bloom/bloom_filter.hpp"
|
||||||
#include "logging/default.hpp"
|
#include "logging/default.hpp"
|
||||||
#include "logging/streams/stdout.hpp"
|
#include "logging/streams/stdout.hpp"
|
||||||
@ -8,43 +10,40 @@
|
|||||||
#include "utils/hashing/fnv64.hpp"
|
#include "utils/hashing/fnv64.hpp"
|
||||||
#include "utils/random/generator.h"
|
#include "utils/random/generator.h"
|
||||||
|
|
||||||
#include "benchmark/benchmark_api.h"
|
|
||||||
|
|
||||||
using utils::random::StringGenerator;
|
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>
|
template <class Type, int Size>
|
||||||
static void TestBloom(benchmark::State& state, BloomFilter<Type, Size>*
|
static void TestBloom(benchmark::State &state, BloomFilter<Type, Size> *bloom,
|
||||||
bloom, const std::vector<Type>& elements) {
|
const std::vector<Type> &elements)
|
||||||
while(state.KeepRunning()) {
|
{
|
||||||
|
while (state.KeepRunning())
|
||||||
|
{
|
||||||
for (int start = 0; start < state.range(0); start++)
|
for (int start = 0; start < state.range(0); start++)
|
||||||
if (start % 2) bloom->contains(elements[start]);
|
if (start % 2)
|
||||||
else bloom->insert(elements[start]);
|
bloom->contains(elements[start]);
|
||||||
|
else
|
||||||
|
bloom->insert(elements[start]);
|
||||||
}
|
}
|
||||||
state.SetComplexityN(state.range(0));
|
state.SetComplexityN(state.range(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto BM_Bloom = [](benchmark::State& state, auto* bloom, const auto& elements) {
|
auto BM_Bloom = [](benchmark::State &state, auto *bloom, const auto &elements) {
|
||||||
TestBloom(state, bloom, elements);
|
TestBloom(state, bloom, elements);
|
||||||
};
|
};
|
||||||
|
|
||||||
void parse_args(int argc, char** argv) {}
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
int main(int argc, char** argv) {
|
|
||||||
logging::init_async();
|
logging::init_async();
|
||||||
logging::log->pipe(std::make_unique<Stdout>());
|
logging::log->pipe(std::make_unique<Stdout>());
|
||||||
|
|
||||||
parse_args(argc, argv);
|
|
||||||
|
|
||||||
StringGenerator generator(4);
|
StringGenerator generator(4);
|
||||||
|
|
||||||
auto elements = utils::random::generate_vector(generator, 1 << 16);
|
auto elements = utils::random::generate_vector(generator, 1 << 16);
|
||||||
|
|
||||||
StringHashFunction hash1 = fnv64<std::string>;
|
StringHashFunction hash1 = fnv64<std::string>;
|
||||||
StringHashFunction hash2 = fnv1a64<std::string>;
|
StringHashFunction hash2 = fnv1a64<std::string>;
|
||||||
std::vector<StringHashFunction> funcs = {
|
std::vector<StringHashFunction> funcs = {hash1, hash2};
|
||||||
hash1, hash2
|
|
||||||
};
|
|
||||||
|
|
||||||
BloomFilter<std::string, 128> bloom(funcs);
|
BloomFilter<std::string, 128> bloom(funcs);
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
using utils::random::NumberGenerator;
|
using utils::random::NumberGenerator;
|
||||||
using utils::random::PairGenerator;
|
using utils::random::PairGenerator;
|
||||||
using utils::random::StringGenerator;
|
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>,
|
using IntegerGenerator = NumberGenerator<std::uniform_int_distribution<int>,
|
||||||
std::default_random_engine, int>;
|
std::default_random_engine, int>;
|
||||||
@ -40,10 +40,14 @@ int THREADS, RANGE_START, RANGE_END, STRING_LENGTH;
|
|||||||
ConcurrentMap Insertion Benchmark Test
|
ConcurrentMap Insertion Benchmark Test
|
||||||
*/
|
*/
|
||||||
template <class K, class V, class F>
|
template <class K, class V, class F>
|
||||||
static void InsertValue(benchmark::State& state, ConcurrentBloomMap<K, V, F>* map,
|
static void InsertValue(benchmark::State &state,
|
||||||
const std::vector<std::pair<K, V>>& elements) {
|
ConcurrentBloomMap<K, V, F> *map,
|
||||||
while (state.KeepRunning()) {
|
const std::vector<std::pair<K, V>> &elements)
|
||||||
for (int start = 0; start < state.range(0); start++) {
|
{
|
||||||
|
while (state.KeepRunning())
|
||||||
|
{
|
||||||
|
for (int start = 0; start < state.range(0); start++)
|
||||||
|
{
|
||||||
map->insert(elements[start].first, elements[start].second);
|
map->insert(elements[start].first, elements[start].second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -54,21 +58,25 @@ static void InsertValue(benchmark::State& state, ConcurrentBloomMap<K, V, F>* ma
|
|||||||
ConcurrentMap Contains Benchmark Test
|
ConcurrentMap Contains Benchmark Test
|
||||||
*/
|
*/
|
||||||
template <class K, class V, class F>
|
template <class K, class V, class F>
|
||||||
static void ContainsValue(benchmark::State& state, ConcurrentBloomMap<K, V, F>* map,
|
static void ContainsValue(benchmark::State &state,
|
||||||
const std::vector<std::pair<K, V>> elements) {
|
ConcurrentBloomMap<K, V, F> *map,
|
||||||
while (state.KeepRunning()) {
|
const std::vector<std::pair<K, V>> elements)
|
||||||
for (int start = 0; start < state.range(0); start++) {
|
{
|
||||||
|
while (state.KeepRunning())
|
||||||
|
{
|
||||||
|
for (int start = 0; start < state.range(0); start++)
|
||||||
|
{
|
||||||
map->contains(elements[start].first);
|
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) {
|
auto BM_InsertValue = [](benchmark::State &state, auto *map, auto &elements) {
|
||||||
InsertValue(state, map, elements);
|
InsertValue(state, map, elements);
|
||||||
};
|
};
|
||||||
|
|
||||||
auto BM_ContainsValue = [](benchmark::State& state, auto* map, auto elements) {
|
auto BM_ContainsValue = [](benchmark::State &state, auto *map, auto elements) {
|
||||||
ContainsValue(state, map, elements);
|
ContainsValue(state, map, elements);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -88,7 +96,8 @@ auto BM_ContainsValue = [](benchmark::State& state, auto* map, auto elements) {
|
|||||||
* Random String lenght
|
* Random String lenght
|
||||||
-string-length number
|
-string-length number
|
||||||
*/
|
*/
|
||||||
void parse_arguments(int argc, char** argv) {
|
void parse_arguments(int argc, char **argv)
|
||||||
|
{
|
||||||
REGISTER_ARGS(argc, argv);
|
REGISTER_ARGS(argc, argv);
|
||||||
|
|
||||||
RANGE_START = GET_ARG("-start", "0").get_int();
|
RANGE_START = GET_ARG("-start", "0").get_int();
|
||||||
@ -101,7 +110,8 @@ void parse_arguments(int argc, char** argv) {
|
|||||||
ProgramArguments::instance().get_arg("-string-length", "128").get_int();
|
ProgramArguments::instance().get_arg("-string-length", "128").get_int();
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
logging::init_async();
|
logging::init_async();
|
||||||
logging::log->pipe(std::make_unique<Stdout>());
|
logging::log->pipe(std::make_unique<Stdout>());
|
||||||
|
|
||||||
@ -129,23 +139,20 @@ int main(int argc, char** argv) {
|
|||||||
|
|
||||||
StringHashFunction hash1 = fnv64<std::string>;
|
StringHashFunction hash1 = fnv64<std::string>;
|
||||||
StringHashFunction hash2 = fnv1a64<std::string>;
|
StringHashFunction hash2 = fnv1a64<std::string>;
|
||||||
std::vector<StringHashFunction> funcs = {
|
std::vector<StringHashFunction> funcs = {hash1, hash2};
|
||||||
hash1, hash2
|
|
||||||
};
|
|
||||||
|
|
||||||
BloomFilter<std::string, 128> bloom_filter_(funcs);
|
BloomFilter<std::string, 128> bloom_filter_(funcs);
|
||||||
|
|
||||||
// maps used for testing
|
// maps used for testing
|
||||||
//ConcurrentBloomMap<int, int> ii_map;
|
// ConcurrentBloomMap<int, int> ii_map;
|
||||||
//ConcurrentBloomMap<int, std::string> is_map;
|
// ConcurrentBloomMap<int, std::string> is_map;
|
||||||
using Filter = BloomFilter<std::string, 128>;
|
using Filter = BloomFilter<std::string, 128>;
|
||||||
ConcurrentBloomMap<std::string, int, Filter > si_map(bloom_filter_);
|
ConcurrentBloomMap<std::string, int, Filter> si_map(bloom_filter_);
|
||||||
ConcurrentBloomMap<std::string, std::string, Filter>
|
ConcurrentBloomMap<std::string, std::string, Filter> ss_map(bloom_filter_);
|
||||||
ss_map(bloom_filter_);
|
|
||||||
|
|
||||||
// random elements for testing
|
// random elements for testing
|
||||||
//auto ii_elems = utils::random::generate_vector(piig, MAX_ELEMENTS);
|
// auto ii_elems = utils::random::generate_vector(piig, MAX_ELEMENTS);
|
||||||
//auto is_elems = utils::random::generate_vector(pisg, MAX_ELEMENTS);
|
// auto is_elems = utils::random::generate_vector(pisg, MAX_ELEMENTS);
|
||||||
auto si_elems = utils::random::generate_vector(psig, MAX_ELEMENTS);
|
auto si_elems = utils::random::generate_vector(psig, MAX_ELEMENTS);
|
||||||
auto ss_elems = utils::random::generate_vector(pssg, MAX_ELEMENTS);
|
auto ss_elems = utils::random::generate_vector(pssg, MAX_ELEMENTS);
|
||||||
|
|
||||||
|
@ -37,11 +37,14 @@ int THREADS, RANGE_START, RANGE_END, STRING_LENGTH;
|
|||||||
ConcurrentMap Insertion Benchmark Test
|
ConcurrentMap Insertion Benchmark Test
|
||||||
*/
|
*/
|
||||||
template <class K, class V>
|
template <class K, class V>
|
||||||
static void InsertValue(benchmark::State& state, ConcurrentMap<K, V>* map,
|
static void InsertValue(benchmark::State &state, ConcurrentMap<K, V> *map,
|
||||||
const std::vector<std::pair<K, V>>& elements) {
|
const std::vector<std::pair<K, V>> &elements)
|
||||||
while (state.KeepRunning()) {
|
{
|
||||||
|
while (state.KeepRunning())
|
||||||
|
{
|
||||||
auto accessor = map->access();
|
auto accessor = map->access();
|
||||||
for (int start = 0; start < state.range(0); start++) {
|
for (int start = 0; start < state.range(0); start++)
|
||||||
|
{
|
||||||
accessor.insert(elements[start].first, elements[start].second);
|
accessor.insert(elements[start].first, elements[start].second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -52,11 +55,14 @@ static void InsertValue(benchmark::State& state, ConcurrentMap<K, V>* map,
|
|||||||
ConcurrentMap Deletion Benchmark Test
|
ConcurrentMap Deletion Benchmark Test
|
||||||
*/
|
*/
|
||||||
template <class K, class V>
|
template <class K, class V>
|
||||||
static void DeleteValue(benchmark::State& state, ConcurrentMap<K, V>* map,
|
static void DeleteValue(benchmark::State &state, ConcurrentMap<K, V> *map,
|
||||||
const std::vector<std::pair<K, V>> elements) {
|
const std::vector<std::pair<K, V>> elements)
|
||||||
while (state.KeepRunning()) {
|
{
|
||||||
|
while (state.KeepRunning())
|
||||||
|
{
|
||||||
auto accessor = map->access();
|
auto accessor = map->access();
|
||||||
for (int start = 0; start < state.range(0); start++) {
|
for (int start = 0; start < state.range(0); start++)
|
||||||
|
{
|
||||||
accessor.remove(elements[start].first);
|
accessor.remove(elements[start].first);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -67,26 +73,29 @@ static void DeleteValue(benchmark::State& state, ConcurrentMap<K, V>* map,
|
|||||||
ConcurrentMap Contains Benchmark Test
|
ConcurrentMap Contains Benchmark Test
|
||||||
*/
|
*/
|
||||||
template <class K, class V>
|
template <class K, class V>
|
||||||
static void ContainsValue(benchmark::State& state, ConcurrentMap<K, V>* map,
|
static void ContainsValue(benchmark::State &state, ConcurrentMap<K, V> *map,
|
||||||
const std::vector<std::pair<K, V>> elements) {
|
const std::vector<std::pair<K, V>> elements)
|
||||||
while (state.KeepRunning()) {
|
{
|
||||||
|
while (state.KeepRunning())
|
||||||
|
{
|
||||||
auto accessor = map->access();
|
auto accessor = map->access();
|
||||||
for (int start = 0; start < state.range(0); start++) {
|
for (int start = 0; start < state.range(0); start++)
|
||||||
|
{
|
||||||
accessor.contains(elements[start].first);
|
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) {
|
auto BM_InsertValue = [](benchmark::State &state, auto *map, auto &elements) {
|
||||||
InsertValue(state, map, elements);
|
InsertValue(state, map, elements);
|
||||||
};
|
};
|
||||||
|
|
||||||
auto BM_DeleteValue = [](benchmark::State& state, auto* map, auto elements) {
|
auto BM_DeleteValue = [](benchmark::State &state, auto *map, auto elements) {
|
||||||
DeleteValue(state, map, elements);
|
DeleteValue(state, map, elements);
|
||||||
};
|
};
|
||||||
|
|
||||||
auto BM_ContainsValue = [](benchmark::State& state, auto* map, auto elements) {
|
auto BM_ContainsValue = [](benchmark::State &state, auto *map, auto elements) {
|
||||||
ContainsValue(state, map, elements);
|
ContainsValue(state, map, elements);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -106,7 +115,8 @@ auto BM_ContainsValue = [](benchmark::State& state, auto* map, auto elements) {
|
|||||||
* Random String lenght
|
* Random String lenght
|
||||||
-string-length number
|
-string-length number
|
||||||
*/
|
*/
|
||||||
void parse_arguments(int argc, char** argv) {
|
void parse_arguments(int argc, char **argv)
|
||||||
|
{
|
||||||
REGISTER_ARGS(argc, argv);
|
REGISTER_ARGS(argc, argv);
|
||||||
|
|
||||||
RANGE_START = GET_ARG("-start", "0").get_int();
|
RANGE_START = GET_ARG("-start", "0").get_int();
|
||||||
@ -119,7 +129,8 @@ void parse_arguments(int argc, char** argv) {
|
|||||||
ProgramArguments::instance().get_arg("-string-length", "128").get_int();
|
ProgramArguments::instance().get_arg("-string-length", "128").get_int();
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
logging::init_async();
|
logging::init_async();
|
||||||
logging::log->pipe(std::make_unique<Stdout>());
|
logging::log->pipe(std::make_unique<Stdout>());
|
||||||
|
|
||||||
@ -159,8 +170,8 @@ int main(int argc, char** argv) {
|
|||||||
|
|
||||||
/* insertion Tests */
|
/* insertion Tests */
|
||||||
|
|
||||||
benchmark::RegisterBenchmark("InsertValue[Int, Int]", BM_InsertValue, &ii_map,
|
benchmark::RegisterBenchmark("InsertValue[Int, Int]", BM_InsertValue,
|
||||||
ii_elems)
|
&ii_map, ii_elems)
|
||||||
->RangeMultiplier(MULTIPLIER)
|
->RangeMultiplier(MULTIPLIER)
|
||||||
->Range(1, MAX_ELEMENTS)
|
->Range(1, MAX_ELEMENTS)
|
||||||
->Complexity(benchmark::oN)
|
->Complexity(benchmark::oN)
|
||||||
@ -219,8 +230,8 @@ int main(int argc, char** argv) {
|
|||||||
|
|
||||||
// Deletion Banchamark Tests
|
// Deletion Banchamark Tests
|
||||||
|
|
||||||
benchmark::RegisterBenchmark("DeleteValue[Int, Int]", BM_DeleteValue, &ii_map,
|
benchmark::RegisterBenchmark("DeleteValue[Int, Int]", BM_DeleteValue,
|
||||||
ii_elems)
|
&ii_map, ii_elems)
|
||||||
->RangeMultiplier(MULTIPLIER)
|
->RangeMultiplier(MULTIPLIER)
|
||||||
->Range(1, MAX_ELEMENTS)
|
->Range(1, MAX_ELEMENTS)
|
||||||
->Complexity(benchmark::oN)
|
->Complexity(benchmark::oN)
|
||||||
|
@ -28,20 +28,29 @@ int THREADS, INSERT_PERC, DELETE_PERC, CONTAINS_PERC, RANGE_START, RANGE_END;
|
|||||||
|
|
||||||
// ConcurrentMap Becnhmark Test using percentages for Insert, Delete, Find
|
// ConcurrentMap Becnhmark Test using percentages for Insert, Delete, Find
|
||||||
template <class K, class V>
|
template <class K, class V>
|
||||||
static void Rape(benchmark::State& state, ConcurrentMap<int, int>* map,
|
static void Rape(benchmark::State &state, ConcurrentMap<int, int> *map,
|
||||||
const std::vector<std::pair<K, V>>& elements) {
|
const std::vector<std::pair<K, V>> &elements)
|
||||||
|
{
|
||||||
int number_of_elements = state.range(0);
|
int number_of_elements = state.range(0);
|
||||||
|
|
||||||
while (state.KeepRunning()) {
|
while (state.KeepRunning())
|
||||||
|
{
|
||||||
auto accessor = map->access();
|
auto accessor = map->access();
|
||||||
|
|
||||||
for (int start = 0; start < state.range(0); start++) {
|
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) {
|
float current_percentage =
|
||||||
|
(float)start / (float)number_of_elements * 100;
|
||||||
|
if (current_percentage < (float)INSERT_PERC)
|
||||||
|
{
|
||||||
accessor.insert(elements[start].first, elements[start].second);
|
accessor.insert(elements[start].first, elements[start].second);
|
||||||
} else if (current_percentage < (float)CONTAINS_PERC + INSERT_PERC) {
|
}
|
||||||
|
else if (current_percentage < (float)CONTAINS_PERC + INSERT_PERC)
|
||||||
|
{
|
||||||
accessor.contains(elements[start].first);
|
accessor.contains(elements[start].first);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
accessor.remove(elements[start].first);
|
accessor.remove(elements[start].first);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -50,7 +59,7 @@ static void Rape(benchmark::State& state, ConcurrentMap<int, int>* map,
|
|||||||
state.SetComplexityN(state.range(0));
|
state.SetComplexityN(state.range(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto BM_Rape = [](benchmark::State& state, auto* map, auto& elements) {
|
auto BM_Rape = [](benchmark::State &state, auto *map, auto &elements) {
|
||||||
Rape(state, map, elements);
|
Rape(state, map, elements);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -76,14 +85,16 @@ auto BM_Rape = [](benchmark::State& state, auto* map, auto& elements) {
|
|||||||
* Number of threads
|
* Number of threads
|
||||||
-threads number
|
-threads number
|
||||||
*/
|
*/
|
||||||
void parse_arguments(int argc, char** argv) {
|
void parse_arguments(int argc, char **argv)
|
||||||
|
{
|
||||||
REGISTER_ARGS(argc, argv);
|
REGISTER_ARGS(argc, argv);
|
||||||
|
|
||||||
INSERT_PERC = GET_ARG("-insert", "50").get_int();
|
INSERT_PERC = GET_ARG("-insert", "50").get_int();
|
||||||
DELETE_PERC = GET_ARG("-delete", "20").get_int();
|
DELETE_PERC = GET_ARG("-delete", "20").get_int();
|
||||||
CONTAINS_PERC = GET_ARG("-find", "30").get_int();
|
CONTAINS_PERC = GET_ARG("-find", "30").get_int();
|
||||||
|
|
||||||
if (INSERT_PERC + DELETE_PERC + CONTAINS_PERC != 100) {
|
if (INSERT_PERC + DELETE_PERC + CONTAINS_PERC != 100)
|
||||||
|
{
|
||||||
std::cout << "Invalid percentage" << std::endl;
|
std::cout << "Invalid percentage" << std::endl;
|
||||||
std::cout << "Percentage must sum to 100" << std::endl;
|
std::cout << "Percentage must sum to 100" << std::endl;
|
||||||
exit(-1);
|
exit(-1);
|
||||||
@ -97,7 +108,8 @@ void parse_arguments(int argc, char** argv) {
|
|||||||
(int)std::thread::hardware_concurrency());
|
(int)std::thread::hardware_concurrency());
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
logging::init_async();
|
logging::init_async();
|
||||||
logging::log->pipe(std::make_unique<Stdout>());
|
logging::log->pipe(std::make_unique<Stdout>());
|
||||||
|
|
||||||
|
@ -1,21 +1,24 @@
|
|||||||
#include "logging/default.hpp"
|
#include "logging/default.hpp"
|
||||||
#include "logging/streams/stdout.hpp"
|
#include "logging/streams/stdout.hpp"
|
||||||
#include "utils/time/timer.hpp"
|
|
||||||
#include "query/preprocesor.hpp"
|
#include "query/preprocesor.hpp"
|
||||||
|
#include "utils/time/timer.hpp"
|
||||||
|
|
||||||
#include "benchmark/benchmark_api.h"
|
#include "benchmark/benchmark_api.h"
|
||||||
#include "yaml-cpp/yaml.h"
|
#include "yaml-cpp/yaml.h"
|
||||||
|
|
||||||
auto BM_Strip = [](benchmark::State& state, auto& function, std::string query) {
|
auto BM_Strip = [](benchmark::State &state, auto &function, std::string query) {
|
||||||
while (state.KeepRunning()) {
|
while (state.KeepRunning())
|
||||||
for (int start = 0; start < state.range(0); start++) {
|
{
|
||||||
|
for (int start = 0; start < state.range(0); start++)
|
||||||
|
{
|
||||||
function(query);
|
function(query);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
state.SetComplexityN(state.range(0));
|
state.SetComplexityN(state.range(0));
|
||||||
};
|
};
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
logging::init_async();
|
logging::init_async();
|
||||||
logging::log->pipe(std::make_unique<Stdout>());
|
logging::log->pipe(std::make_unique<Stdout>());
|
||||||
|
|
||||||
@ -24,17 +27,17 @@ int main(int argc, char** argv) {
|
|||||||
|
|
||||||
QueryPreprocessor processor;
|
QueryPreprocessor processor;
|
||||||
using std::placeholders::_1;
|
using std::placeholders::_1;
|
||||||
std::function<QueryStripped(const std::string& query)> preprocess =
|
std::function<QueryStripped(const std::string &query)> preprocess =
|
||||||
std::bind(&QueryPreprocessor::preprocess, &processor, _1);
|
std::bind(&QueryPreprocessor::preprocess, &processor, _1);
|
||||||
|
|
||||||
auto tests = dataset["benchmark_queries"].as<std::vector<std::string>>();
|
auto tests = dataset["benchmark_queries"].as<std::vector<std::string>>();
|
||||||
for (auto& test : tests) {
|
for (auto &test : tests)
|
||||||
auto* benchmark =
|
{
|
||||||
benchmark::RegisterBenchmark(test.c_str(), BM_Strip, preprocess, test)
|
auto *benchmark = benchmark::RegisterBenchmark(test.c_str(), BM_Strip,
|
||||||
|
preprocess, test)
|
||||||
->RangeMultiplier(2)
|
->RangeMultiplier(2)
|
||||||
->Range(1, 8 << 10)
|
->Range(1, 8 << 10)
|
||||||
->Complexity(benchmark::oN);
|
->Complexity(benchmark::oN);
|
||||||
;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
benchmark::Initialize(&argc, argv);
|
benchmark::Initialize(&argc, argv);
|
||||||
|
@ -26,6 +26,8 @@ foreach(test_cpp ${test_type_cpps})
|
|||||||
set_target_properties(${target_name} PROPERTIES OUTPUT_NAME ${exec_name})
|
set_target_properties(${target_name} PROPERTIES OUTPUT_NAME ${exec_name})
|
||||||
|
|
||||||
# link libraries
|
# link libraries
|
||||||
|
# gtest
|
||||||
|
target_link_libraries(${target_name} gtest gtest_main)
|
||||||
# threads (cross-platform)
|
# threads (cross-platform)
|
||||||
target_link_libraries(${target_name} Threads::Threads)
|
target_link_libraries(${target_name} Threads::Threads)
|
||||||
# memgraph lib
|
# memgraph lib
|
||||||
|
@ -302,6 +302,7 @@ void memory_check(size_t no_threads, std::function<void()> f)
|
|||||||
permanent_assert(true, "Memory leak");
|
permanent_assert(true, "Memory leak");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: move this inside logging/default
|
||||||
// Initializes loging faccilityes
|
// Initializes loging faccilityes
|
||||||
void init_log()
|
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_find_per_change = 2;
|
||||||
constexpr size_t no_insert_for_one_delete = 1;
|
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.
|
// 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
|
// Exact ratio of finds per change and insert per delete can be regulated with
|
||||||
// no_find_per_change and no_insert_for_one_delete.
|
// no_find_per_change and no_insert_for_one_delete.
|
||||||
|
@ -7,25 +7,33 @@ constexpr size_t no_slots = 1e4;
|
|||||||
constexpr size_t key_range = no_slots * THREADS_NO * bit_part_len;
|
constexpr size_t key_range = no_slots * THREADS_NO * bit_part_len;
|
||||||
constexpr size_t no_sets_per_clear = 2;
|
constexpr size_t no_sets_per_clear = 2;
|
||||||
|
|
||||||
|
// TODO: document the test
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
DynamicBitset<> db;
|
DynamicBitset<> db;
|
||||||
|
|
||||||
auto seted =
|
auto seted =
|
||||||
collect_set(run<std::vector<bool>>(THREADS_NO, [&](auto index) {
|
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);
|
auto clear_op = rand_gen_bool(no_sets_per_clear);
|
||||||
std::vector<bool> set(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 =
|
size_t num =
|
||||||
rand() * THREADS_NO * bit_part_len + index * bit_part_len;
|
rand() * THREADS_NO * bit_part_len + index * bit_part_len;
|
||||||
|
|
||||||
if (clear_op()) {
|
if (clear_op())
|
||||||
|
{
|
||||||
db.clear(num, bit_part_len);
|
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;
|
set[num + j] = false;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
db.set(num, bit_part_len);
|
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;
|
set[num + j] = true;
|
||||||
|
@ -6,16 +6,20 @@ constexpr size_t up_border_bit_set_pow2 = 3;
|
|||||||
constexpr size_t key_range =
|
constexpr size_t key_range =
|
||||||
op_per_thread * THREADS_NO * (1 << up_border_bit_set_pow2) * 2;
|
op_per_thread * THREADS_NO * (1 << up_border_bit_set_pow2) * 2;
|
||||||
|
|
||||||
|
// TODO: document the test
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
DynamicBitset<> db;
|
DynamicBitset<> db;
|
||||||
|
|
||||||
auto seted =
|
auto seted =
|
||||||
collect_set(run<std::vector<bool>>(THREADS_NO, [&](auto index) {
|
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);
|
auto rand_len = rand_gen(up_border_bit_set_pow2);
|
||||||
std::vector<bool> set(key_range + (1 << 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++) {
|
for (size_t i = 0; i < op_per_thread; i++)
|
||||||
|
{
|
||||||
auto len = 1 << rand_len();
|
auto len = 1 << rand_len();
|
||||||
size_t num = (rand() / len) * len;
|
size_t num = (rand() / len) * len;
|
||||||
db.set(num, len);
|
db.set(num, len);
|
||||||
@ -32,10 +36,12 @@ int main()
|
|||||||
auto rand_len = rand_gen(up_border_bit_set_pow2);
|
auto rand_len = rand_gen(up_border_bit_set_pow2);
|
||||||
std::vector<bool> set(key_range + (1 << 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++) {
|
for (size_t i = 0; i < op_per_thread; i++)
|
||||||
|
{
|
||||||
auto len = 1 << rand_len();
|
auto len = 1 << rand_len();
|
||||||
size_t num = (rand() / len) * 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);
|
set[num + j] = set[num + j] | db.at(num + j);
|
||||||
}
|
}
|
||||||
db.clear(num, len);
|
db.clear(num, len);
|
||||||
@ -44,7 +50,8 @@ int main()
|
|||||||
return set;
|
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]);
|
seted[i] = seted[i] & (!cleared[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,14 +4,18 @@ constexpr size_t THREADS_NO = std::min(max_no_threads, 8);
|
|||||||
constexpr size_t op_per_thread = 1e5;
|
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()
|
int main()
|
||||||
{
|
{
|
||||||
DynamicBitset<> db;
|
DynamicBitset<> db;
|
||||||
|
|
||||||
auto set = collect_set(run<std::vector<bool>>(THREADS_NO, [&](auto index) {
|
auto set = collect_set(run<std::vector<bool>>(THREADS_NO, [&](auto index) {
|
||||||
auto rand = rand_gen(key_range);
|
auto rand = rand_gen(key_range);
|
||||||
std::vector<bool> set(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();
|
size_t num = rand();
|
||||||
db.set(num);
|
db.set(num);
|
||||||
set[num] = true;
|
set[num] = true;
|
||||||
|
@ -6,15 +6,19 @@ constexpr size_t up_border_bit_set_pow2 = 3;
|
|||||||
constexpr size_t key_range =
|
constexpr size_t key_range =
|
||||||
op_per_thread * THREADS_NO * (1 << up_border_bit_set_pow2) * 2;
|
op_per_thread * THREADS_NO * (1 << up_border_bit_set_pow2) * 2;
|
||||||
|
|
||||||
|
// TODO: document the test
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
DynamicBitset<> db;
|
DynamicBitset<> db;
|
||||||
|
|
||||||
auto set = collect_set(run<std::vector<bool>>(THREADS_NO, [&](auto index) {
|
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);
|
auto rand_len = rand_gen(up_border_bit_set_pow2);
|
||||||
std::vector<bool> set(key_range + (1 << 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++) {
|
for (size_t i = 0; i < op_per_thread; i++)
|
||||||
|
{
|
||||||
auto len = 1 << rand_len();
|
auto len = 1 << rand_len();
|
||||||
size_t num = (rand() / len) * len;
|
size_t num = (rand() / len) * len;
|
||||||
db.set(num, len);
|
db.set(num, len);
|
||||||
|
@ -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;
|
|
||||||
}
|
|
@ -5,11 +5,14 @@ constexpr size_t THREADS_NO = std::min(max_no_threads, 8);
|
|||||||
constexpr size_t elems_per_thread = 100000;
|
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.
|
// This test checks insert_unique method under pressure.
|
||||||
// Test checks for missing data and changed/overwriten data.
|
// Test checks for missing data and changed/overwriten data.
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
init_log();
|
init_log();
|
||||||
|
|
||||||
memory_check(THREADS_NO, [] {
|
memory_check(THREADS_NO, [] {
|
||||||
map_t skiplist;
|
map_t skiplist;
|
||||||
|
|
||||||
@ -21,7 +24,8 @@ int main()
|
|||||||
auto inserter =
|
auto inserter =
|
||||||
insert_try<size_t, size_t, map_t>(acc, downcount, owned);
|
insert_try<size_t, size_t, map_t>(acc, downcount, owned);
|
||||||
|
|
||||||
do {
|
do
|
||||||
|
{
|
||||||
inserter(rand(), index);
|
inserter(rand(), index);
|
||||||
} while (downcount > 0);
|
} while (downcount > 0);
|
||||||
|
|
||||||
@ -30,7 +34,8 @@ int main()
|
|||||||
});
|
});
|
||||||
|
|
||||||
auto accessor = skiplist.access();
|
auto accessor = skiplist.access();
|
||||||
for (auto &owned : collect(futures)) {
|
for (auto &owned : collect(futures))
|
||||||
|
{
|
||||||
check_present_same<map_t>(accessor, owned);
|
check_present_same<map_t>(accessor, owned);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,6 +4,8 @@ constexpr size_t THREADS_NO = std::min(max_no_threads, 8);
|
|||||||
constexpr size_t elems_per_thread = 100000;
|
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.
|
// This test checks insert_unique method under pressure.
|
||||||
// Threads will try to insert keys in the same order.
|
// Threads will try to insert keys in the same order.
|
||||||
// This will force threads to compete intensly with each other.
|
// This will force threads to compete intensly with each other.
|
||||||
@ -11,6 +13,7 @@ constexpr size_t key_range = elems_per_thread * THREADS_NO * 2;
|
|||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
init_log();
|
init_log();
|
||||||
|
|
||||||
memory_check(THREADS_NO, [] {
|
memory_check(THREADS_NO, [] {
|
||||||
map_t skiplist;
|
map_t skiplist;
|
||||||
|
|
||||||
@ -22,7 +25,8 @@ int main()
|
|||||||
auto inserter =
|
auto inserter =
|
||||||
insert_try<size_t, size_t, map_t>(acc, downcount, owned);
|
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);
|
inserter(i, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31,7 +35,8 @@ int main()
|
|||||||
});
|
});
|
||||||
|
|
||||||
auto accessor = skiplist.access();
|
auto accessor = skiplist.access();
|
||||||
for (auto &owned : collect(futures)) {
|
for (auto &owned : collect(futures))
|
||||||
|
{
|
||||||
check_present_same<map_t>(accessor, owned);
|
check_present_same<map_t>(accessor, owned);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,19 +3,24 @@
|
|||||||
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;
|
constexpr size_t elems_per_thread = 1e5;
|
||||||
|
|
||||||
|
// TODO: document the test
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
init_log();
|
init_log();
|
||||||
|
|
||||||
memory_check(THREADS_NO, [&] {
|
memory_check(THREADS_NO, [&] {
|
||||||
ds::static_array<std::thread, THREADS_NO> threads;
|
ds::static_array<std::thread, THREADS_NO> threads;
|
||||||
map_t skiplist;
|
map_t skiplist;
|
||||||
|
|
||||||
// put THREADS_NO * elems_per_thread items to the 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(
|
threads[thread_i] = std::thread(
|
||||||
[&skiplist](size_t start, size_t end) {
|
[&skiplist](size_t start, size_t end) {
|
||||||
auto accessor = skiplist.access();
|
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);
|
accessor.insert(elem_i, elem_i);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -23,7 +28,8 @@ int main()
|
|||||||
thread_i * elems_per_thread + elems_per_thread);
|
thread_i * elems_per_thread + elems_per_thread);
|
||||||
}
|
}
|
||||||
// wait all threads
|
// wait all threads
|
||||||
for (auto &thread : threads) {
|
for (auto &thread : threads)
|
||||||
|
{
|
||||||
thread.join();
|
thread.join();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,11 +40,13 @@ int main()
|
|||||||
"all elements in skiplist");
|
"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(
|
threads[thread_i] = std::thread(
|
||||||
[&skiplist](size_t start, size_t end) {
|
[&skiplist](size_t start, size_t end) {
|
||||||
auto accessor = skiplist.access();
|
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, "");
|
permanent_assert(accessor.remove(elem_i) == true, "");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -46,7 +54,8 @@ int main()
|
|||||||
thread_i * elems_per_thread + elems_per_thread);
|
thread_i * elems_per_thread + elems_per_thread);
|
||||||
}
|
}
|
||||||
// // wait all threads
|
// // wait all threads
|
||||||
for (auto &thread : threads) {
|
for (auto &thread : threads)
|
||||||
|
{
|
||||||
thread.join();
|
thread.join();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,7 +71,8 @@ int main()
|
|||||||
{
|
{
|
||||||
size_t iterator_counter = 0;
|
size_t iterator_counter = 0;
|
||||||
auto accessor = skiplist.access();
|
auto accessor = skiplist.access();
|
||||||
for (auto elem : accessor) {
|
for (auto elem : accessor)
|
||||||
|
{
|
||||||
++iterator_counter;
|
++iterator_counter;
|
||||||
cout << elem.first << " ";
|
cout << elem.first << " ";
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,16 @@
|
|||||||
#include "common.h"
|
#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 elements = 2e6;
|
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()
|
int main()
|
||||||
{
|
{
|
||||||
init_log();
|
init_log();
|
||||||
|
|
||||||
memory_check(THREADS_NO, [] {
|
memory_check(THREADS_NO, [] {
|
||||||
map_t skiplist;
|
map_t skiplist;
|
||||||
|
|
||||||
|
@ -3,20 +3,28 @@
|
|||||||
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;
|
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()
|
int main()
|
||||||
{
|
{
|
||||||
init_log();
|
init_log();
|
||||||
|
|
||||||
memory_check(THREADS_NO, [&] {
|
memory_check(THREADS_NO, [&] {
|
||||||
ds::static_array<std::thread, THREADS_NO> threads;
|
ds::static_array<std::thread, THREADS_NO> threads;
|
||||||
map_t skiplist;
|
map_t skiplist;
|
||||||
|
|
||||||
// put THREADS_NO * elems_per_thread items to the 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(
|
threads[thread_i] = std::thread(
|
||||||
[&skiplist](size_t start, size_t end) {
|
[&skiplist](size_t start, size_t end) {
|
||||||
auto accessor = skiplist.access();
|
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);
|
accessor.insert(elem_i, elem_i);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -24,7 +32,8 @@ int main()
|
|||||||
thread_i * elems_per_thread + elems_per_thread);
|
thread_i * elems_per_thread + elems_per_thread);
|
||||||
}
|
}
|
||||||
// wait all threads
|
// wait all threads
|
||||||
for (auto &thread : threads) {
|
for (auto &thread : threads)
|
||||||
|
{
|
||||||
thread.join();
|
thread.join();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,11 +44,13 @@ int main()
|
|||||||
"all elements in skiplist");
|
"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(
|
threads[thread_i] = std::thread(
|
||||||
[&skiplist](size_t start, size_t end) {
|
[&skiplist](size_t start, size_t end) {
|
||||||
auto accessor = skiplist.access();
|
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, "");
|
permanent_assert(accessor.remove(elem_i) == true, "");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -47,7 +58,8 @@ int main()
|
|||||||
thread_i * elems_per_thread + elems_per_thread);
|
thread_i * elems_per_thread + elems_per_thread);
|
||||||
}
|
}
|
||||||
// // wait all threads
|
// // wait all threads
|
||||||
for (auto &thread : threads) {
|
for (auto &thread : threads)
|
||||||
|
{
|
||||||
thread.join();
|
thread.join();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,7 +75,8 @@ int main()
|
|||||||
{
|
{
|
||||||
size_t iterator_counter = 0;
|
size_t iterator_counter = 0;
|
||||||
auto accessor = skiplist.access();
|
auto accessor = skiplist.access();
|
||||||
for (auto elem : accessor) {
|
for (auto elem : accessor)
|
||||||
|
{
|
||||||
++iterator_counter;
|
++iterator_counter;
|
||||||
cout << elem.first << " ";
|
cout << elem.first << " ";
|
||||||
}
|
}
|
||||||
|
@ -7,13 +7,16 @@ constexpr size_t op_per_thread = 1e5;
|
|||||||
constexpr size_t max_number = 10;
|
constexpr size_t max_number = 10;
|
||||||
constexpr size_t no_insert_for_one_delete = 1;
|
constexpr size_t no_insert_for_one_delete = 1;
|
||||||
|
|
||||||
// This test checks MultiIterator from multimap.
|
/**
|
||||||
// Each thread removes random data. So removes are joint.
|
* This test checks MultiIterator from multimap.
|
||||||
// Calls of remove method are interleaved with insert calls which always
|
* Each thread removes random data. So removes are joint.
|
||||||
// succeed.
|
* Calls of remove method are interleaved with insert calls which always
|
||||||
|
* succeed.
|
||||||
|
*/
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
init_log();
|
init_log();
|
||||||
|
|
||||||
memory_check(THREADS_NO, [] {
|
memory_check(THREADS_NO, [] {
|
||||||
multimap_t skiplist;
|
multimap_t skiplist;
|
||||||
|
|
||||||
|
@ -7,14 +7,16 @@ constexpr size_t op_per_thread = 1e5;
|
|||||||
constexpr size_t max_number = 10;
|
constexpr size_t max_number = 10;
|
||||||
constexpr size_t no_insert_for_one_delete = 1;
|
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
|
* This test checks MultiIterator remove method.
|
||||||
// key values.
|
* Each thread removes random data. So removes are joint and scattered on same
|
||||||
// Calls of remove method are interleaved with insert calls which always
|
* key values. Calls of remove method are interleaved with insert calls which
|
||||||
// succeed.
|
* always succeed.
|
||||||
|
*/
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
init_log();
|
init_log();
|
||||||
|
|
||||||
memory_check(THREADS_NO, [] {
|
memory_check(THREADS_NO, [] {
|
||||||
multimap_t skiplist;
|
multimap_t skiplist;
|
||||||
|
|
||||||
@ -26,23 +28,30 @@ int main()
|
|||||||
std::vector<long long> set(key_range, 0);
|
std::vector<long long> set(key_range, 0);
|
||||||
long long sum = 0;
|
long long sum = 0;
|
||||||
|
|
||||||
do {
|
do
|
||||||
|
{
|
||||||
size_t num = rand();
|
size_t num = rand();
|
||||||
auto data = rand() % max_number;
|
auto data = rand() % max_number;
|
||||||
if (rand_op()) {
|
if (rand_op())
|
||||||
|
{
|
||||||
|
|
||||||
int len = 0;
|
int len = 0;
|
||||||
for (auto it = acc.find_multi(num); it.has_value();
|
for (auto it = acc.find_multi(num); it.has_value();
|
||||||
it++) {
|
it++)
|
||||||
|
{
|
||||||
len++;
|
len++;
|
||||||
}
|
}
|
||||||
if (len > 0) {
|
if (len > 0)
|
||||||
|
{
|
||||||
int pos = rand() % len;
|
int pos = rand() % len;
|
||||||
for (auto it = acc.find_multi(num); it.has_value();
|
for (auto it = acc.find_multi(num); it.has_value();
|
||||||
it++) {
|
it++)
|
||||||
if (pos == 0) {
|
{
|
||||||
|
if (pos == 0)
|
||||||
|
{
|
||||||
auto data_r = it->second;
|
auto data_r = it->second;
|
||||||
if (it.remove()) {
|
if (it.remove())
|
||||||
|
{
|
||||||
downcount--;
|
downcount--;
|
||||||
set[num]--;
|
set[num]--;
|
||||||
sum -= data_r;
|
sum -= data_r;
|
||||||
@ -55,7 +64,9 @@ int main()
|
|||||||
pos--;
|
pos--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
acc.insert(num, data);
|
acc.insert(num, data);
|
||||||
downcount--;
|
downcount--;
|
||||||
set[num]++;
|
set[num]++;
|
||||||
@ -68,9 +79,11 @@ int main()
|
|||||||
|
|
||||||
long set[key_range] = {0};
|
long set[key_range] = {0};
|
||||||
long long sums = 0;
|
long long sums = 0;
|
||||||
for (auto &data : collect(futures)) {
|
for (auto &data : collect(futures))
|
||||||
|
{
|
||||||
sums += data.second.first;
|
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];
|
set[i] += data.second.second[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -78,7 +91,8 @@ int main()
|
|||||||
auto accessor = skiplist.access();
|
auto accessor = skiplist.access();
|
||||||
check_multi_iterator(accessor, key_range, set);
|
check_multi_iterator(accessor, key_range, set);
|
||||||
|
|
||||||
for (auto &e : accessor) {
|
for (auto &e : accessor)
|
||||||
|
{
|
||||||
set[e.first]--;
|
set[e.first]--;
|
||||||
sums -= e.second;
|
sums -= e.second;
|
||||||
}
|
}
|
||||||
|
@ -7,15 +7,16 @@ constexpr size_t op_per_thread = 1e5;
|
|||||||
constexpr size_t max_number = 10;
|
constexpr size_t max_number = 10;
|
||||||
constexpr size_t no_insert_for_one_delete = 2;
|
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
|
* This test checks MultiIterator remove method. Each thread removes all
|
||||||
// and scattered on same
|
* duplicate data for a random key. So removes are joined and scattered on the
|
||||||
// key values.
|
* same key values. Calls of remove method are interleaved with insert calls
|
||||||
// Calls of remove method are interleaved with insert calls which always
|
* which always succeed.
|
||||||
// succeed.
|
*/
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
init_log();
|
init_log();
|
||||||
|
|
||||||
memory_check(THREADS_NO, [] {
|
memory_check(THREADS_NO, [] {
|
||||||
multimap_t skiplist;
|
multimap_t skiplist;
|
||||||
|
|
||||||
@ -27,16 +28,21 @@ int main()
|
|||||||
std::vector<long long> set(key_range, 0);
|
std::vector<long long> set(key_range, 0);
|
||||||
long long sum = 0;
|
long long sum = 0;
|
||||||
|
|
||||||
do {
|
do
|
||||||
|
{
|
||||||
size_t num = rand();
|
size_t num = rand();
|
||||||
auto data = rand() % max_number;
|
auto data = rand() % max_number;
|
||||||
if (rand_op()) {
|
if (rand_op())
|
||||||
|
{
|
||||||
auto it = acc.find_multi(num);
|
auto it = acc.find_multi(num);
|
||||||
if (it.has_value()) {
|
if (it.has_value())
|
||||||
|
{
|
||||||
it++;
|
it++;
|
||||||
while (it.has_value()) {
|
while (it.has_value())
|
||||||
|
{
|
||||||
auto data_r = it->second;
|
auto data_r = it->second;
|
||||||
if (it.remove()) {
|
if (it.remove())
|
||||||
|
{
|
||||||
downcount--;
|
downcount--;
|
||||||
set[num]--;
|
set[num]--;
|
||||||
sum -= data_r;
|
sum -= data_r;
|
||||||
@ -47,7 +53,9 @@ int main()
|
|||||||
it++;
|
it++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
acc.insert(num, data);
|
acc.insert(num, data);
|
||||||
downcount--;
|
downcount--;
|
||||||
set[num]++;
|
set[num]++;
|
||||||
@ -60,9 +68,11 @@ int main()
|
|||||||
|
|
||||||
long set[key_range] = {0};
|
long set[key_range] = {0};
|
||||||
long long sums = 0;
|
long long sums = 0;
|
||||||
for (auto &data : collect(futures)) {
|
for (auto &data : collect(futures))
|
||||||
|
{
|
||||||
sums += data.second.first;
|
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];
|
set[i] += data.second.second[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -70,7 +80,8 @@ int main()
|
|||||||
auto accessor = skiplist.access();
|
auto accessor = skiplist.access();
|
||||||
check_multi_iterator(accessor, key_range, set);
|
check_multi_iterator(accessor, key_range, set);
|
||||||
|
|
||||||
for (auto &e : accessor) {
|
for (auto &e : accessor)
|
||||||
|
{
|
||||||
set[e.first]--;
|
set[e.first]--;
|
||||||
sums -= e.second;
|
sums -= e.second;
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,8 @@ constexpr size_t op_per_thread = 1e5;
|
|||||||
constexpr size_t max_number = 10;
|
constexpr size_t max_number = 10;
|
||||||
constexpr size_t no_insert_for_one_delete = 1;
|
constexpr size_t no_insert_for_one_delete = 1;
|
||||||
|
|
||||||
|
// TODO: document the test
|
||||||
|
|
||||||
// This test checks multimap.
|
// This test checks multimap.
|
||||||
// Each thread removes random data. So removes are joint.
|
// Each thread removes random data. So removes are joint.
|
||||||
// Calls of remove method are interleaved with insert calls which always
|
// Calls of remove method are interleaved with insert calls which always
|
||||||
@ -14,6 +16,7 @@ constexpr size_t no_insert_for_one_delete = 1;
|
|||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
init_log();
|
init_log();
|
||||||
|
|
||||||
memory_check(THREADS_NO, [] {
|
memory_check(THREADS_NO, [] {
|
||||||
multimap_t skiplist;
|
multimap_t skiplist;
|
||||||
std::atomic<long long> size(0);
|
std::atomic<long long> size(0);
|
||||||
@ -26,17 +29,22 @@ int main()
|
|||||||
std::vector<long long> set(key_range, 0);
|
std::vector<long long> set(key_range, 0);
|
||||||
long long sum = 0;
|
long long sum = 0;
|
||||||
|
|
||||||
do {
|
do
|
||||||
|
{
|
||||||
size_t num = rand();
|
size_t num = rand();
|
||||||
auto data = num % max_number;
|
auto data = num % max_number;
|
||||||
if (rand_op()) {
|
if (rand_op())
|
||||||
if (acc.remove(num)) {
|
{
|
||||||
|
if (acc.remove(num))
|
||||||
|
{
|
||||||
downcount--;
|
downcount--;
|
||||||
set[num]--;
|
set[num]--;
|
||||||
sum -= data;
|
sum -= data;
|
||||||
size--;
|
size--;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
acc.insert(num, data);
|
acc.insert(num, data);
|
||||||
downcount--;
|
downcount--;
|
||||||
set[num]++;
|
set[num]++;
|
||||||
@ -51,9 +59,11 @@ int main()
|
|||||||
long set[key_range] = {0};
|
long set[key_range] = {0};
|
||||||
long long sums = 0;
|
long long sums = 0;
|
||||||
long long size_calc = 0;
|
long long size_calc = 0;
|
||||||
for (auto &data : collect(futures)) {
|
for (auto &data : collect(futures))
|
||||||
|
{
|
||||||
sums += data.second.first;
|
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];
|
set[i] += data.second.second[i];
|
||||||
size_calc += data.second.second[i];
|
size_calc += data.second.second[i];
|
||||||
}
|
}
|
||||||
@ -64,15 +74,18 @@ int main()
|
|||||||
check_order<multimap_t>(accessor);
|
check_order<multimap_t>(accessor);
|
||||||
|
|
||||||
auto bef_it = accessor.end();
|
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);
|
auto it = accessor.find(i);
|
||||||
if (set[i] > 0) {
|
if (set[i] > 0)
|
||||||
|
{
|
||||||
permanent_assert(it != accessor.end(),
|
permanent_assert(it != accessor.end(),
|
||||||
"Multimap doesn't contain necessary element "
|
"Multimap doesn't contain necessary element "
|
||||||
<< i);
|
<< i);
|
||||||
|
|
||||||
if (bef_it == accessor.end()) bef_it = accessor.find(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(
|
permanent_assert(
|
||||||
bef_it != accessor.end(),
|
bef_it != accessor.end(),
|
||||||
"Previous iterator doesn't iterate through same "
|
"Previous iterator doesn't iterate through same "
|
||||||
@ -89,7 +102,8 @@ int main()
|
|||||||
bef_it++;
|
bef_it++;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int j = 0; j < set[i]; j++) {
|
for (int j = 0; j < set[i]; j++)
|
||||||
|
{
|
||||||
permanent_assert(it != accessor.end(),
|
permanent_assert(it != accessor.end(),
|
||||||
"Iterator doesn't iterate through same "
|
"Iterator doesn't iterate through same "
|
||||||
"key entrys. Expected "
|
"key entrys. Expected "
|
||||||
@ -110,7 +124,8 @@ int main()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto &e : accessor) {
|
for (auto &e : accessor)
|
||||||
|
{
|
||||||
set[e.first]--;
|
set[e.first]--;
|
||||||
sums -= e.second;
|
sums -= e.second;
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,8 @@ constexpr size_t key_range = 1e4;
|
|||||||
constexpr size_t op_per_thread = 1e5;
|
constexpr size_t op_per_thread = 1e5;
|
||||||
constexpr size_t no_insert_for_one_delete = 1;
|
constexpr size_t no_insert_for_one_delete = 1;
|
||||||
|
|
||||||
|
// TODO: document the test
|
||||||
|
|
||||||
// This test checks multiset.
|
// This test checks multiset.
|
||||||
// Each thread removes random data. So removes are joint.
|
// Each thread removes random data. So removes are joint.
|
||||||
// Calls of remove method are interleaved with insert calls which always
|
// 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()
|
int main()
|
||||||
{
|
{
|
||||||
init_log();
|
init_log();
|
||||||
|
|
||||||
memory_check(THREADS_NO, [] {
|
memory_check(THREADS_NO, [] {
|
||||||
multiset_t skiplist;
|
multiset_t skiplist;
|
||||||
|
|
||||||
|
@ -6,6 +6,8 @@ constexpr size_t op_per_thread = 1e5;
|
|||||||
constexpr size_t max_number = 10;
|
constexpr size_t max_number = 10;
|
||||||
constexpr size_t no_insert_for_one_delete = 2;
|
constexpr size_t no_insert_for_one_delete = 2;
|
||||||
|
|
||||||
|
// TODO: document the test
|
||||||
|
|
||||||
// This test checks remove method under pressure.
|
// This test checks remove method under pressure.
|
||||||
// Threads will try to insert and remove keys aproximetly in the same order.
|
// Threads will try to insert and remove keys aproximetly in the same order.
|
||||||
// This will force threads to compete intensly with each other.
|
// 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()
|
int main()
|
||||||
{
|
{
|
||||||
init_log();
|
init_log();
|
||||||
|
|
||||||
memory_check(THREADS_NO, [] {
|
memory_check(THREADS_NO, [] {
|
||||||
map_t skiplist;
|
map_t skiplist;
|
||||||
|
|
||||||
|
@ -5,12 +5,15 @@ constexpr size_t key_range = 1e5;
|
|||||||
constexpr size_t op_per_thread = 1e6;
|
constexpr size_t op_per_thread = 1e6;
|
||||||
constexpr size_t no_insert_for_one_delete = 1;
|
constexpr size_t no_insert_for_one_delete = 1;
|
||||||
|
|
||||||
|
// TODO: document the test
|
||||||
|
|
||||||
// This test checks remove method under pressure.
|
// This test checks remove method under pressure.
|
||||||
// Each thread removes it's own data. So removes are disjoint.
|
// Each thread removes it's own data. So removes are disjoint.
|
||||||
// Calls of remove method are interleaved with insert calls.
|
// Calls of remove method are interleaved with insert calls.
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
init_log();
|
init_log();
|
||||||
|
|
||||||
memory_check(THREADS_NO, [] {
|
memory_check(THREADS_NO, [] {
|
||||||
map_t skiplist;
|
map_t skiplist;
|
||||||
|
|
||||||
|
@ -7,6 +7,8 @@ constexpr size_t op_per_thread = 1e5;
|
|||||||
constexpr size_t max_number = 10;
|
constexpr size_t max_number = 10;
|
||||||
constexpr size_t no_insert_for_one_delete = 2;
|
constexpr size_t no_insert_for_one_delete = 2;
|
||||||
|
|
||||||
|
// TODO: document the test
|
||||||
|
|
||||||
// This test checks remove method under pressure.
|
// This test checks remove method under pressure.
|
||||||
// Each thread removes random data. So removes are joint.
|
// Each thread removes random data. So removes are joint.
|
||||||
// Calls of remove method are interleaved with insert calls.
|
// Calls of remove method are interleaved with insert calls.
|
||||||
@ -24,17 +26,23 @@ int main()
|
|||||||
long long sum = 0;
|
long long sum = 0;
|
||||||
long long count = 0;
|
long long count = 0;
|
||||||
|
|
||||||
do {
|
do
|
||||||
|
{
|
||||||
auto num = rand();
|
auto num = rand();
|
||||||
auto data = num % max_number;
|
auto data = num % max_number;
|
||||||
if (rand_op()) {
|
if (rand_op())
|
||||||
if (acc.remove(num)) {
|
{
|
||||||
|
if (acc.remove(num))
|
||||||
|
{
|
||||||
sum -= data;
|
sum -= data;
|
||||||
downcount--;
|
downcount--;
|
||||||
count--;
|
count--;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
if (acc.insert(num, data).second) {
|
else
|
||||||
|
{
|
||||||
|
if (acc.insert(num, data).second)
|
||||||
|
{
|
||||||
sum += data;
|
sum += data;
|
||||||
downcount--;
|
downcount--;
|
||||||
count++;
|
count++;
|
||||||
@ -48,12 +56,14 @@ int main()
|
|||||||
auto accessor = skiplist.access();
|
auto accessor = skiplist.access();
|
||||||
long long sums = 0;
|
long long sums = 0;
|
||||||
long long counters = 0;
|
long long counters = 0;
|
||||||
for (auto &data : collect(futures)) {
|
for (auto &data : collect(futures))
|
||||||
|
{
|
||||||
sums += data.second.first;
|
sums += data.second.first;
|
||||||
counters += data.second.second;
|
counters += data.second.second;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto &e : accessor) {
|
for (auto &e : accessor)
|
||||||
|
{
|
||||||
sums -= e.second;
|
sums -= e.second;
|
||||||
}
|
}
|
||||||
permanent_assert(sums == 0, "Aproximetly Same values are present");
|
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 op_per_thread = 1e5;
|
||||||
constexpr size_t no_insert_for_one_delete = 2;
|
constexpr size_t no_insert_for_one_delete = 2;
|
||||||
|
|
||||||
|
// TODO: document the test
|
||||||
|
|
||||||
// This test checks set.
|
// This test checks set.
|
||||||
// Each thread removes random data. So removes are joint.
|
// Each thread removes random data. So removes are joint.
|
||||||
// Calls of remove method are interleaved with insert calls.
|
// Calls of remove method are interleaved with insert calls.
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
init_log();
|
init_log();
|
||||||
|
|
||||||
memory_check(THREADS_NO, [] {
|
memory_check(THREADS_NO, [] {
|
||||||
set_t skiplist;
|
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_find_per_change = 5;
|
||||||
constexpr size_t no_insert_for_one_delete = 1;
|
constexpr size_t no_insert_for_one_delete = 1;
|
||||||
|
|
||||||
|
// TODO: document the test
|
||||||
|
|
||||||
// This test simulates behavior of transactions.
|
// This test simulates behavior of transactions.
|
||||||
// Each thread makes a series of finds interleaved with method which change.
|
// 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
|
// 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()
|
int main()
|
||||||
{
|
{
|
||||||
init_log();
|
init_log();
|
||||||
|
|
||||||
memory_check(THREADS_NO, [] {
|
memory_check(THREADS_NO, [] {
|
||||||
map_t skiplist;
|
map_t skiplist;
|
||||||
|
|
||||||
|
@ -1,11 +1,21 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
|
||||||
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
#include "logging/default.cpp"
|
#include "logging/default.cpp"
|
||||||
#include "utils/timer/timer.hpp"
|
#include "utils/timer/timer.hpp"
|
||||||
|
#include "utils/assert.hpp"
|
||||||
|
|
||||||
using namespace std::chrono_literals;
|
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)
|
Timer::sptr create_test_timer(int64_t counter)
|
||||||
{
|
{
|
||||||
return std::make_shared<Timer>(
|
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;
|
TimerScheduler<TimerSet, std::chrono::seconds> timer_scheduler;
|
||||||
|
|
||||||
|
// run the timer
|
||||||
timer_scheduler.run();
|
timer_scheduler.run();
|
||||||
|
|
||||||
|
// add a couple of test timers
|
||||||
for (int64_t i = 1; i <= 3; ++i) {
|
for (int64_t i = 1; i <= 3; ++i) {
|
||||||
timer_scheduler.add(create_test_timer(i));
|
timer_scheduler.add(create_test_timer(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// wait for that timers
|
||||||
std::this_thread::sleep_for(4s);
|
std::this_thread::sleep_for(4s);
|
||||||
|
|
||||||
|
ASSERT_EQ(timer_scheduler.size(), 0);
|
||||||
|
|
||||||
|
// add another test timer
|
||||||
timer_scheduler.add(create_test_timer(1));
|
timer_scheduler.add(create_test_timer(1));
|
||||||
|
|
||||||
|
// wait for another timer
|
||||||
std::this_thread::sleep_for(2s);
|
std::this_thread::sleep_for(2s);
|
||||||
|
|
||||||
|
// the test is done
|
||||||
timer_scheduler.stop();
|
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)
|
target_link_libraries(${target_name} dl)
|
||||||
|
|
||||||
# register test
|
# 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()
|
endforeach()
|
||||||
|
@ -1,22 +1,17 @@
|
|||||||
#define CATCH_CONFIG_MAIN
|
#include "gtest/gtest.h"
|
||||||
#include "catch.hpp"
|
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
#include "data_structures/bloom/bloom_filter.hpp"
|
||||||
#include "utils/command_line/arguments.hpp"
|
#include "utils/command_line/arguments.hpp"
|
||||||
#include "utils/hashing/fnv64.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 &)>;
|
using StringHashFunction = std::function<uint64_t(const std::string &)>;
|
||||||
|
|
||||||
TEST_CASE("BloomFilter Test")
|
TEST(BloomFilterTest, InsertContains)
|
||||||
{
|
{
|
||||||
StringHashFunction hash1 = fnv64<std::string>;
|
StringHashFunction hash1 = fnv64<std::string>;
|
||||||
StringHashFunction hash2 = fnv1a64<std::string>;
|
StringHashFunction hash2 = fnv1a64<std::string>;
|
||||||
|
|
||||||
auto c = [](auto x) -> int { return x % 4; };
|
|
||||||
std::vector<StringHashFunction> funcs = {hash1, hash2};
|
std::vector<StringHashFunction> funcs = {hash1, hash2};
|
||||||
|
|
||||||
BloomFilter<std::string, 64> bloom(funcs);
|
BloomFilter<std::string, 64> bloom(funcs);
|
||||||
@ -24,19 +19,21 @@ TEST_CASE("BloomFilter Test")
|
|||||||
std::string test = "test";
|
std::string test = "test";
|
||||||
std::string kifla = "kifla";
|
std::string kifla = "kifla";
|
||||||
|
|
||||||
std::cout << hash1(test) << std::endl;
|
bool contains_test = bloom.contains(test);
|
||||||
std::cout << hash2(test) << std::endl;
|
ASSERT_EQ(contains_test, false);
|
||||||
|
|
||||||
std::cout << hash1(kifla) << std::endl;
|
|
||||||
std::cout << hash2(kifla) << std::endl;
|
|
||||||
|
|
||||||
std::cout << bloom.contains(test) << std::endl;
|
|
||||||
bloom.insert(test);
|
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);
|
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 <iostream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
#include "communication/bolt/v1/transport/chunked_decoder.hpp"
|
#include "communication/bolt/v1/transport/chunked_decoder.hpp"
|
||||||
|
|
||||||
using byte = unsigned char;
|
using byte = unsigned char;
|
||||||
|
|
||||||
void print_hex(byte x) { printf("%02X ", static_cast<byte>(x)); }
|
void print_hex(byte x) { printf("%02X ", static_cast<byte>(x)); }
|
||||||
|
|
||||||
class DummyStream
|
struct DummyStream
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
void write(const byte *values, size_t n)
|
void write(const byte *values, size_t n)
|
||||||
{
|
{
|
||||||
data.insert(data.end(), values, values + 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";
|
std::string decoded = "A quick brown fox jumps over a lazy dog";
|
||||||
|
|
||||||
int main(void)
|
TEST(ChunkedDecoderTest, WriteString)
|
||||||
{
|
{
|
||||||
// DummyStream stream;
|
DummyStream stream;
|
||||||
// Decoder decoder(stream);
|
Decoder decoder(stream);
|
||||||
|
|
||||||
// for(size_t i = 0; i < N; ++i)
|
for(size_t i = 0; i < N; ++i)
|
||||||
// {
|
{
|
||||||
// auto& chunk = chunks[i];
|
auto & chunk = chunks[i];
|
||||||
// auto finished = decoder.decode(chunk.data(), chunk.size());
|
logging::info("Chunk size: {}", chunk.size());
|
||||||
|
|
||||||
// // break early if finished
|
const byte* start = chunk.data();
|
||||||
// if(finished)
|
auto finished = decoder.decode(start, chunk.size());
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// assert(decoded.size() == stream.data.size());
|
// break early if finished
|
||||||
|
if(finished)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// for(size_t i = 0; i < decoded.size(); ++i)
|
// check validity
|
||||||
// assert(decoded[i] == stream.data[i]);
|
ASSERT_EQ(decoded.size(), stream.data.size());
|
||||||
|
for(size_t i = 0; i < decoded.size(); ++i)
|
||||||
return 0;
|
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 <iostream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
#include "communication/bolt/v1/transport/chunked_encoder.hpp"
|
#include "communication/bolt/v1/transport/chunked_encoder.hpp"
|
||||||
#include "logging/default.hpp"
|
#include "logging/default.hpp"
|
||||||
#include "logging/streams/stdout.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)
|
void check_ff(DummyStream &stream, size_t n)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < n; ++i)
|
for (size_t i = 0; i < n; ++i)
|
||||||
assert(stream.pop() == byte('\xFF'));
|
ASSERT_EQ(stream.pop(), byte('\xFF'));
|
||||||
|
|
||||||
(void)stream;
|
(void)stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(void)
|
using encoder_t = bolt::ChunkedEncoder<DummyStream>;
|
||||||
|
|
||||||
|
TEST(ChunkedEncoderTest, Encode)
|
||||||
{
|
{
|
||||||
// TODO: write new test
|
DummyStream stream;
|
||||||
|
encoder_t encoder(stream);
|
||||||
|
size_t chunk_size = encoder_t::chunk_size;
|
||||||
|
|
||||||
// logging::init_async();
|
write_ff(encoder, 10);
|
||||||
// logging::log->pipe(std::make_unique<Stdout>());
|
write_ff(encoder, 10);
|
||||||
// DummyStream stream;
|
encoder.write_chunk();
|
||||||
// bolt::ChunkedEncoder<DummyStream> encoder(stream);
|
|
||||||
|
|
||||||
// write_ff(encoder, 10);
|
write_ff(encoder, 10);
|
||||||
// write_ff(encoder, 10);
|
write_ff(encoder, 10);
|
||||||
// encoder.flush();
|
encoder.write_chunk();
|
||||||
|
|
||||||
// write_ff(encoder, 10);
|
// this should be two chunks, one of size 65533 and the other of size 1467
|
||||||
// write_ff(encoder, 10);
|
write_ff(encoder, 67000);
|
||||||
// encoder.flush();
|
encoder.write_chunk();
|
||||||
|
|
||||||
// // this should be two chunks, one of size 65533 and the other of size 1467
|
for (int i = 0; i < 10000; ++i)
|
||||||
// write_ff(encoder, 67000);
|
write_ff(encoder, 1500);
|
||||||
// encoder.flush();
|
encoder.write_chunk();
|
||||||
|
|
||||||
// for (int i = 0; i < 10000; ++i)
|
ASSERT_EQ(stream.pop_size(), 20);
|
||||||
// write_ff(encoder, 1500);
|
check_ff(stream, 20);
|
||||||
// encoder.flush();
|
ASSERT_EQ(stream.pop_size(), 0);
|
||||||
|
|
||||||
// assert(stream.pop_size() == 20);
|
ASSERT_EQ(stream.pop_size(), 20);
|
||||||
// check_ff(stream, 20);
|
check_ff(stream, 20);
|
||||||
// assert(stream.pop_size() == 0);
|
ASSERT_EQ(stream.pop_size(), 0);
|
||||||
|
|
||||||
// assert(stream.pop_size() == 20);
|
ASSERT_EQ(stream.pop_size(), chunk_size);
|
||||||
// check_ff(stream, 20);
|
check_ff(stream, chunk_size);
|
||||||
// assert(stream.pop_size() == 0);
|
ASSERT_EQ(stream.pop_size(), 0);
|
||||||
|
|
||||||
// assert(stream.pop_size() == encoder.chunk_size);
|
ASSERT_EQ(stream.pop_size(), 1467);
|
||||||
// check_ff(stream, encoder.chunk_size);
|
check_ff(stream, 1467);
|
||||||
// assert(stream.pop_size() == 1467);
|
ASSERT_EQ(stream.pop_size(), 0);
|
||||||
// check_ff(stream, 1467);
|
|
||||||
// assert(stream.pop_size() == 0);
|
|
||||||
|
|
||||||
// size_t k = 10000 * 1500;
|
size_t k = 10000 * 1500;
|
||||||
|
|
||||||
// while (k > 0) {
|
while (k > 0) {
|
||||||
// auto size = k > encoder.chunk_size ? encoder.chunk_size : k;
|
auto size = k > chunk_size ? chunk_size : k;
|
||||||
// assert(stream.pop_size() == size);
|
ASSERT_EQ(stream.pop_size(), size);
|
||||||
// check_ff(stream, size);
|
check_ff(stream, size);
|
||||||
|
ASSERT_EQ(stream.pop_size(), 0);
|
||||||
// k -= size;
|
k -= size;
|
||||||
// }
|
}
|
||||||
|
ASSERT_EQ(stream.pop_size(), 0);
|
||||||
// assert(stream.pop_size() == 0);
|
}
|
||||||
|
|
||||||
return 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