Skip to content

Commit ec0715d

Browse files
committed
WIP Transactional hash_map
1 parent f8587be commit ec0715d

File tree

3 files changed

+130
-0
lines changed

3 files changed

+130
-0
lines changed
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
#pragma once
2+
3+
#include "testing/config.hpp"
4+
5+
#include "trade_v1/trade.hpp"
6+
7+
#include "polyfill_v1/memory.hpp"
8+
#include <functional>
9+
#include <utility>
10+
11+
namespace testing {
12+
13+
template <class Key,
14+
class Mapped,
15+
class Hash = std::hash<Key>,
16+
class Equal = std::equal_to<Key>>
17+
struct hash_map;
18+
19+
class hash_map_private {
20+
template <class, class, class, class> friend struct hash_map;
21+
22+
static size_t next_capacity(size_t capacity);
23+
};
24+
25+
template <class Key, class Mapped, class Hash, class Equal> struct hash_map {
26+
using size_type = size_t;
27+
28+
using key_type = Key;
29+
using mapped_type = Mapped;
30+
using value_type = std::pair<const Key, Mapped>;
31+
32+
hash_map();
33+
34+
size_t size() const;
35+
36+
bool empty() const;
37+
38+
void clear();
39+
40+
void swap(hash_map &that);
41+
42+
private:
43+
struct node {
44+
template <class ForwardableKey, class ForwardableMapped>
45+
node(ForwardableKey &&key, ForwardableMapped &&value)
46+
: m_next(nullptr), m_value(std::forward<ForwardableKey>(key),
47+
std::forward<ForwardableMapped>(value)) {}
48+
trade::atom<std::shared_ptr<node>> m_next;
49+
std::pair<const Key, Mapped> m_value;
50+
};
51+
52+
trade::atom<size_t> m_item_count;
53+
trade::atom<size_t> m_buckets_count;
54+
trade::atom<std::shared_ptr<node[]>> m_buckets;
55+
};
56+
57+
// -----------------------------------------------------------------------------
58+
59+
template <class Key, class Mapped, class Hash, class Equal>
60+
hash_map<Key, Mapped, Hash, Equal>::hash_map()
61+
: m_item_count(0), m_buckets_count(0), m_buckets(nullptr) {}
62+
63+
template <class Key, class Mapped, class Hash, class Equal>
64+
size_t hash_map<Key, Mapped, Hash, Equal>::size() const {
65+
return trade::atomically([&]() { return m_item_count.load(); });
66+
}
67+
68+
template <class Key, class Mapped, class Hash, class Equal>
69+
bool hash_map<Key, Mapped, Hash, Equal>::empty() const {
70+
return trade::atomically([&]() { return m_item_count == 0; });
71+
}
72+
73+
template <class Key, class Mapped, class Hash, class Equal>
74+
void hash_map<Key, Mapped, Hash, Equal>::clear() {
75+
trade::atomically([&]() {
76+
m_item_count = 0;
77+
m_buckets_count = 0;
78+
m_buckets = nullptr;
79+
});
80+
}
81+
82+
template <class Key, class Mapped, class Hash, class Equal>
83+
void hash_map<Key, Mapped, Hash, Equal>::swap(hash_map &that) {
84+
trade::atomically([&]() {
85+
std::swap(m_item_count.ref(), that.m_item_count.ref());
86+
std::swap(m_buckets_count.ref(), that.m_buckets_count.ref());
87+
std::swap(m_buckets.ref(), that.m_buckets.ref());
88+
});
89+
}
90+
91+
} // namespace testing

internals/library/hash_map.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#include "testing/hash_map.hpp"
2+
3+
static const size_t s_capacities[] = {
4+
3, 7, 13, 31, 61, 127,
5+
251, 509, 1021, 2039, 4093, 8191,
6+
16381, 32749, 65521, 131071, 262139, 524287,
7+
1048573, 2097143, 4194301, 8388593, 16777213, 33554393,
8+
67108859, 134217689, 268435399, 536870909, 1073741789};
9+
10+
size_t testing::hash_map_private::next_capacity(size_t capacity) {
11+
size_t n = sizeof(s_capacities) / sizeof(*s_capacities);
12+
for (size_t i = 0; i < n; ++i)
13+
if (capacity < s_capacities[i])
14+
return s_capacities[i];
15+
return capacity;
16+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#include "testing/hash_map.hpp"
2+
3+
#include "polyfill_v1/memory.hpp"
4+
5+
#include "testing_v1/test.hpp"
6+
7+
#include <string>
8+
9+
using namespace testing_v1;
10+
11+
using namespace testing;
12+
using namespace trade;
13+
14+
auto hash_map_test = test([]() {
15+
hash_map<std::string, int> map1;
16+
hash_map<std::string, int> map2;
17+
18+
map1.clear();
19+
20+
map1.swap(map2);
21+
22+
verify(map1.size() == 0);
23+
});

0 commit comments

Comments
 (0)