1// Copyright (C) 2023 Christian Mazakas
2// Copyright (C) 2023 Joaquin M Lopez Munoz
3// Distributed under the Boost Software License, Version 1.0. (See accompanying
4// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5
6#include "helpers.hpp"
7
8#include <boost/unordered/concurrent_flat_map.hpp>
9#include <boost/unordered/concurrent_flat_set.hpp>
10
11test::seed_t initialize_seed{1634048962};
12
13using test::default_generator;
14using test::limited_range;
15using test::sequential;
16
17using hasher = stateful_hash;
18using key_equal = stateful_key_equal;
19
20using map_type = boost::unordered::concurrent_flat_map<raii, raii, hasher,
21 key_equal, stateful_allocator<std::pair<raii const, raii> > >;
22
23using set_type = boost::unordered::concurrent_flat_set<raii, hasher,
24 key_equal, stateful_allocator<raii> >;
25
26map_type* test_map;
27set_type* test_set;
28
29namespace {
30
31 UNORDERED_AUTO_TEST (simple_map_equality) {
32 using allocator_type = map_type::allocator_type;
33
34 {
35 map_type x1(
36 {{1, 11}, {2, 22}}, 0, hasher(1), key_equal(2), allocator_type(3));
37
38 map_type x2(
39 {{1, 11}, {2, 22}}, 0, hasher(2), key_equal(2), allocator_type(3));
40
41 map_type x3(
42 {{1, 11}, {2, 23}}, 0, hasher(2), key_equal(2), allocator_type(3));
43
44 map_type x4({{1, 11}}, 0, hasher(2), key_equal(2), allocator_type(3));
45
46 BOOST_TEST_EQ(x1.size(), x2.size());
47 BOOST_TEST(x1 == x2);
48 BOOST_TEST(!(x1 != x2));
49
50 BOOST_TEST_EQ(x1.size(), x3.size());
51 BOOST_TEST(!(x1 == x3));
52 BOOST_TEST(x1 != x3);
53
54 BOOST_TEST(x1.size() != x4.size());
55 BOOST_TEST(!(x1 == x4));
56 BOOST_TEST(x1 != x4);
57 }
58 }
59
60 UNORDERED_AUTO_TEST (simple_set_equality) {
61 using allocator_type = set_type::allocator_type;
62
63 {
64 set_type x1(
65 {1, 2}, 0, hasher(1), key_equal(2), allocator_type(3));
66
67 set_type x2(
68 {1, 2}, 0, hasher(2), key_equal(2), allocator_type(3));
69
70 set_type x3({1}, 0, hasher(2), key_equal(2), allocator_type(3));
71
72 BOOST_TEST_EQ(x1.size(), x2.size());
73 BOOST_TEST(x1 == x2);
74 BOOST_TEST(!(x1 != x2));
75
76 BOOST_TEST(x1.size() != x3.size());
77 BOOST_TEST(!(x1 == x3));
78 BOOST_TEST(x1 != x3);
79 }
80 }
81
82 template <class X, class GF>
83 void insert_and_compare(X*, GF gen_factory, test::random_generator rg)
84 {
85 using allocator_type = typename X::allocator_type;
86
87 auto gen = gen_factory.template get<X>();
88 auto vals1 = make_random_values(1024 * 8, [&] { return gen(rg); });
89 auto reference_cont = reference_container<X>(vals1.begin(), vals1.end());
90
91 {
92 raii::reset_counts();
93
94 X x1(vals1.size(), hasher(1), key_equal(2), allocator_type(3));
95 X x2(vals1.begin(), vals1.end(), vals1.size(), hasher(2),
96 key_equal(2), allocator_type(3));
97
98 std::thread t1, t2;
99
100 std::mutex m;
101 std::condition_variable cv;
102 std::atomic_bool done{false};
103 std::atomic<unsigned> num_compares{0};
104 bool ready = false;
105
106 BOOST_TEST(x1.empty());
107
108 t1 = std::thread([&x1, &m, &cv, &vals1, &done, &ready] {
109 for (std::size_t idx = 0; idx < vals1.size(); ++idx) {
110 auto const& v = vals1[idx];
111 x1.insert(v);
112
113 if (idx % (vals1.size() / 128) == 0) {
114 {
115 std::unique_lock<std::mutex> lk(m);
116 ready = true;
117 }
118 cv.notify_all();
119 }
120 std::this_thread::yield();
121 }
122
123 done = true;
124 {
125 std::unique_lock<std::mutex> lk(m);
126 ready = true;
127 }
128 cv.notify_all();
129 });
130
131 t2 = std::thread([&x1, &x2, &m, &cv, &done, &num_compares, &ready] {
132 do {
133 {
134 std::unique_lock<std::mutex> lk(m);
135 cv.wait(lk, [&ready] { return ready; });
136 ready = false;
137 }
138
139 volatile bool b = false;
140
141 b = x1 == x2;
142 b = x1 != x2;
143
144 b;
145
146 ++num_compares;
147 std::this_thread::yield();
148 } while (!done);
149
150 BOOST_TEST(done);
151 });
152
153 t1.join();
154 t2.join();
155
156 BOOST_TEST_GE(num_compares, 1u);
157
158 BOOST_TEST(x1 == x2);
159 BOOST_TEST(!(x1 != x2));
160
161 test_matches_reference(x1, reference_cont);
162 }
163 check_raii_counts();
164 }
165} // namespace
166
167// clang-format off
168UNORDERED_TEST(
169 insert_and_compare,
170 ((test_map)(test_set))
171 ((value_type_generator_factory))
172 ((default_generator)(sequential)(limited_range)))
173// clang-format on
174
175RUN_TESTS()
176

source code of boost/libs/unordered/test/cfoa/equality_tests.cpp