86 lines
2.0 KiB
C++
86 lines
2.0 KiB
C++
#include <cassert>
|
|
#include <iostream>
|
|
#include <map>
|
|
|
|
#include "UnorderedParallelMap.h"
|
|
#include <random>
|
|
|
|
constexpr int THREADS = 8;
|
|
constexpr int OPS_PER_THREAD = 10000;
|
|
|
|
void worker(LockFreeMap<int, int>& map, int thread_id)
|
|
{
|
|
std::mt19937 rng(thread_id);
|
|
std::uniform_int_distribution<int> dist(0, 99999);
|
|
|
|
for (int i = 0; i < OPS_PER_THREAD; ++i)
|
|
{
|
|
int op = dist(rng) % 4;
|
|
int key = dist(rng);
|
|
int value = thread_id * 1000 + i;
|
|
|
|
switch (op)
|
|
{
|
|
case 0:
|
|
map.insert(key, value);
|
|
break;
|
|
case 1:
|
|
map.find(key);
|
|
break;
|
|
case 2:
|
|
map.update(key, value + 1);
|
|
break;
|
|
case 3:
|
|
map.erase(key);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void verify_map(LockFreeMap<int, int>& map)
|
|
{
|
|
std::cout << "Final size: " << map.size() << "\n";
|
|
|
|
auto s = map.size();
|
|
auto k = map.keys().size();
|
|
auto e = map.entries().size();
|
|
|
|
std::cout << "Verifying invariants...\n";
|
|
std::cout << " size() = " << s << "\n";
|
|
std::cout << " keys() = " << k << "\n";
|
|
std::cout << " entries() = " << e << "\n";
|
|
|
|
assert(e <= k);
|
|
assert(k <= s);
|
|
std::cout << "✓ Invariants OK\n\n";
|
|
}
|
|
|
|
int main()
|
|
{
|
|
LockFreeMap<int, int> simple_test_map;
|
|
simple_test_map.insert(1, 1);
|
|
simple_test_map.insert(2, 44);
|
|
assert(simple_test_map.size() == 2);
|
|
assert(simple_test_map.find(2) == 44);
|
|
simple_test_map.update(2, 55);
|
|
assert(simple_test_map.find(2) == 55);
|
|
std::cout << "✓ Single-thread test finished\n" << std::endl;
|
|
verify_map(simple_test_map);
|
|
|
|
LockFreeMap<int, int> map(1024);
|
|
|
|
std::vector<std::thread> threads;
|
|
threads.reserve(THREADS);
|
|
for (int i = 0; i < THREADS; ++i)
|
|
threads.emplace_back(worker, std::ref(map), i);
|
|
|
|
for (auto& t : threads)
|
|
t.join();
|
|
|
|
std::cout << "✓ Multi-thread test finished\n" << std::endl;
|
|
|
|
verify_map(map);
|
|
|
|
return 0;
|
|
}
|