Merge branch 'tests' into dev

This commit is contained in:
Kruno Tomola Fabro 2016-08-19 18:48:48 +01:00
commit a1fc3244ef
8 changed files with 255 additions and 18 deletions

View File

@ -352,11 +352,13 @@ public:
return succs[0]->value(); return succs[0]->value();
} }
bool has_next() // WRONG THIS CAN POSSIBLY NOT BE TRUE IF SOMEONE JUST AFTER THIS REMOVE
{ // ELEMENT AFTER THIS ONE.
assert(succs[0] != nullptr); // bool has_next()
return succs[0].forward(0) != nullptr; // {
} // assert(succs[0] != nullptr);
// return succs[0].forward(0) != nullptr;
// }
bool has_value() { return succs[0] != nullptr; } bool has_value() { return succs[0] != nullptr; }

View File

@ -7,6 +7,7 @@
#include <random> #include <random>
#include <thread> #include <thread>
#include "data_structures/bitset/dynamic_bitset.hpp"
#include "data_structures/concurrent/concurrent_map.hpp" #include "data_structures/concurrent/concurrent_map.hpp"
#include "data_structures/concurrent/concurrent_multimap.hpp" #include "data_structures/concurrent/concurrent_multimap.hpp"
#include "data_structures/concurrent/concurrent_multiset.hpp" #include "data_structures/concurrent/concurrent_multiset.hpp"
@ -106,6 +107,14 @@ void check_zero(size_t key_range, long array[], const char *str)
} }
} }
void check_set(DynamicBitset<> &db, std::vector<bool> &set)
{
for (int i = 0; i < set.size(); i++) {
permanent_assert(!(set[i] ^ db.at(i)),
"Set constraints aren't fullfilled.");
}
}
// Checks multiIterator and iterator guarantees // Checks multiIterator and iterator guarantees
void check_multi_iterator(multimap_t::Accessor &accessor, size_t key_range, void check_multi_iterator(multimap_t::Accessor &accessor, size_t key_range,
long set[]) long set[])
@ -164,6 +173,25 @@ run(size_t threads_no, S &skiplist,
return futures; return futures;
} }
// Runs given function in threads_no threads and returns vector of futures for
// there
// results.
template <class R>
std::vector<std::future<std::pair<size_t, R>>> run(size_t threads_no,
std::function<R(size_t)> f)
{
std::vector<std::future<std::pair<size_t, R>>> futures;
for (size_t thread_i = 0; thread_i < threads_no; ++thread_i) {
std::packaged_task<std::pair<size_t, R>()> task([f, thread_i]() {
return std::pair<size_t, R>(thread_i, f(thread_i));
}); // wrap the function
futures.push_back(task.get_future()); // get a future
std::thread(std::move(task)).detach();
}
return futures;
}
// Collects all data from futures. // Collects all data from futures.
template <class R> template <class R>
auto collect(std::vector<std::future<R>> &collect) auto collect(std::vector<std::future<R>> &collect)
@ -175,6 +203,19 @@ auto collect(std::vector<std::future<R>> &collect)
return collection; return collection;
} }
std::vector<bool> collect_set(
std::vector<std::future<std::pair<size_t, std::vector<bool>>>> &&futures)
{
std::vector<bool> set;
for (auto &data : collect(futures)) {
set.resize(data.second.size());
for (int i = 0; i < data.second.size(); i++) {
set[i] = set[i] | data.second[i];
}
}
return set;
}
// Returns object which tracs in owned which (key,data) where added and // Returns object which tracs in owned which (key,data) where added and
// downcounts. // downcounts.
template <class K, class D, class S> template <class K, class D, class S>

View File

@ -0,0 +1,39 @@
#include "common.h"
#define THREADS_NO 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;
int main()
{
DynamicBitset<> db;
auto seted =
collect_set(run<std::vector<bool>>(THREADS_NO, [&](auto index) {
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++) {
size_t num =
rand() * THREADS_NO * bit_part_len + index * bit_part_len;
if (clear_op()) {
db.clear(num, bit_part_len);
for (int j = 0; j < bit_part_len; j++) {
set[num + j] = false;
}
} else {
db.set(num, bit_part_len);
for (int j = 0; j < bit_part_len; j++)
set[num + j] = true;
}
}
return set;
}));
check_set(db, seted);
}

View File

@ -0,0 +1,52 @@
#include "common.h"
#define THREADS_NO 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;
int main()
{
DynamicBitset<> db;
auto seted =
collect_set(run<std::vector<bool>>(THREADS_NO, [&](auto index) {
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();
size_t num = (rand() / len) * len;
db.set(num, len);
for (int j = 0; j < len; j++)
set[num + j] = true;
}
return set;
}));
auto cleared =
collect_set(run<std::vector<bool>>(THREADS_NO, [&](auto index) {
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();
size_t num = (rand() / len) * len;
for (int j = 0; j < len; j++) {
set[num + j] = set[num + j] | db.at(num + j);
}
db.clear(num, len);
}
return set;
}));
for (size_t i = 0; i < seted.size(); i++) {
seted[i] = seted[i] & (!cleared[i]);
}
check_set(db, seted);
}

View File

@ -0,0 +1,24 @@
#include "common.h"
#define THREADS_NO 8
constexpr size_t op_per_thread = 1e5;
constexpr size_t key_range = op_per_thread * THREADS_NO * 3;
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++) {
size_t num = rand();
db.set(num);
set[num] = true;
}
return set;
}));
check_set(db, set);
}

View File

@ -0,0 +1,29 @@
#include "common.h"
#define THREADS_NO 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;
int main()
{
DynamicBitset<> db;
auto set = collect_set(run<std::vector<bool>>(THREADS_NO, [&](auto index) {
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();
size_t num = (rand() / len) * len;
db.set(num, len);
for (int j = 0; j < len; j++)
set[num + j] = true;
}
return set;
}));
check_set(db, set);
}

View File

@ -1,23 +1,20 @@
#include <iostream> #include <array>
#include <deque>
#include <cassert> #include <cassert>
#include <cstring> #include <cstring>
#include <array> #include <deque>
#include <iostream>
#include <vector> #include <vector>
#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) void print_hex(byte x) { printf("%02X ", static_cast<byte>(x)); }
{
printf("%02X ", static_cast<byte>(x));
}
class DummyStream class DummyStream
{ {
public: 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);
} }
@ -28,11 +25,11 @@ public:
using Decoder = bolt::ChunkedDecoder<DummyStream>; using Decoder = bolt::ChunkedDecoder<DummyStream>;
std::vector<byte> chunks[] = { std::vector<byte> chunks[] = {
{0x00,0x08,'A',' ','q','u','i','c','k',' ',0x00,0x06,'b','r','o','w','n',' '}, {0x00, 0x08, 'A', ' ', 'q', 'u', 'i', 'c', 'k', ' ', 0x00, 0x06, 'b', 'r',
{0x00,0x0A,'f','o','x',' ','j','u','m','p','s',' '}, 'o', 'w', 'n', ' '},
{0x00,0x07,'o','v','e','r',' ','a',' '}, {0x00, 0x0A, 'f', 'o', 'x', ' ', 'j', 'u', 'm', 'p', 's', ' '},
{0x00,0x08,'l','a','z','y',' ','d','o','g',0x00,0x00} {0x00, 0x07, 'o', 'v', 'e', 'r', ' ', 'a', ' '},
}; {0x00, 0x08, 'l', 'a', 'z', 'y', ' ', 'd', 'o', 'g', 0x00, 0x00}};
static constexpr size_t N = std::extent<decltype(chunks)>::value; static constexpr size_t N = std::extent<decltype(chunks)>::value;

View File

@ -0,0 +1,53 @@
#include <iostream>
#include "data_structures/concurrent/concurrent_set.hpp"
using std::cout;
using std::endl;
void print_skiplist(const ConcurrentSet<int>::Accessor &skiplist)
{
cout << "---- skiplist set now has: ";
for (auto &item : skiplist)
cout << item << ", ";
cout << "----" << endl;
}
int main(void)
{
ConcurrentSet<int> set;
auto accessor = set.access();
cout << std::boolalpha;
cout << "added non-existing 1? (true) " << accessor.insert(1).second
<< endl;
cout << "added already existing 1? (false) " << accessor.insert(1).second
<< endl;
accessor.insert(2);
print_skiplist(accessor);
cout << "item 3 doesn't exist? (true) "
<< (accessor.find(3) == accessor.end()) << endl;
cout << "item 3 exists? (false) " << accessor.contains(3) << endl;
cout << "item 2 exists? (true) " << (accessor.find(2) != accessor.end())
<< endl;
cout << "at item 2 is? 2 " << *accessor.find(2) << endl;
cout << "removed existing 1? (true) " << accessor.remove(1) << endl;
cout << "removed non-existing 3? (false) " << accessor.remove(3) << endl;
accessor.insert(1);
accessor.insert(4);
print_skiplist(accessor);
return 0;
}