21 #include <unordered_map> 29 using namespace folly;
45 T load(std::memory_order = std::memory_order_seq_cst)
const {
56 std::memory_order = std::memory_order_seq_cst) {
62 std::memory_order = std::memory_order_seq_cst) {
71 std::memory_order = std::memory_order_seq_cst,
72 std::memory_order = std::memory_order_seq_cst) {
73 if (value == expected) {
85 std::memory_order = std::memory_order_seq_cst,
86 std::memory_order = std::memory_order_seq_cst) {
87 if (value == expected) {
105 template <
typename>
class Atom = std::atomic,
106 typename Allocator = std::allocator<char>>
119 template <
typename T>
136 m.emplace(
"abc",
"ABC");
141 auto iter = m.cbegin();
161 for (
int i = 0;
i < 10000; ++
i) {
171 for (
int i = 0;
i < 6000; ++
i) {
181 for (
int i = 0;
i < 50; ++
i) {
185 m.
find(1)->second.data++;
188 TEST(UnorderedInsertMap, value_mutation) {
191 for (
int i = 0;
i < 50; ++
i) {
195 m.
find(1)->second.data++;
202 size_t capacity = 2000000000;
204 for (
size_t i = 0;
i < capacity * 2;
i += 2) {
207 for (
size_t i = 0;
i < capacity * 3;
i += capacity / 1000 + 1) {
208 auto iter = big.
find(
i);
209 if ((
i & 1) == 0 &&
i < capacity * 2) {
218 std::unique_ptr<AtomicUnorderedInsertMap<int, size_t>>
ptr = {};
220 size_t capacity = 100000;
223 ptr = std::make_unique<AtomicUnorderedInsertMap<int, size_t>>(capacity);
224 for (
size_t i = 0;
i < capacity; ++
i) {
225 auto k = 3 * ((5641 *
i) % capacity);
226 ptr->emplace(
k,
k + 1);
231 for (
size_t i = 0;
i < iters; ++
i) {
232 size_t k = 3 * (((
i * 7919) ^ (
i * 4001)) % capacity);
233 auto iter = ptr->find(k);
234 if (iter == ptr->cend() || iter->second != k + 1) {
235 auto jter = ptr->find(k);
247 size_t operator()(
const std::pair<uint64_t, uint64_t>& pr)
const {
248 return pr.first ^ pr.second;
253 size_t itersPerThread,
256 size_t readsPerWrite) {
257 typedef std::pair<uint64_t, uint64_t>
Key;
260 std::unique_ptr<Map>
ptr = {};
261 std::atomic<bool> go{
false};
262 std::vector<std::thread>
threads;
265 ptr = std::make_unique<Map>(capacity);
266 while (threads.size() < numThreads) {
267 threads.emplace_back([&]() {
274 while (reads + writes < itersPerThread) {
276 Key key(reads + writes, r);
277 if (reads < writes * readsPerWrite ||
278 writes >= capacity / numThreads) {
281 auto iter = ptr->find(key);
283 iter == ptr->cend() ||
284 iter->second.data.load(std::memory_order_acquire) >= key.first);
288 auto pr = ptr->emplace(key, key.first);
290 pr.first->second.data++;
292 }
catch (std::bad_alloc&) {
293 LOG(
INFO) <<
"bad alloc";
303 for (
auto& thr : threads) {
354 std::unordered_map<long, long>
m;
356 for (
int i = 0;
i < 10000; ++
i) {
360 for (
int i = 0;
i < 10000; ++
i) {
368 for (
int i = 0;
i < 10000; ++
i) {
372 for (
int i = 0;
i < 10000; ++
i) {
380 for (
int i = 0;
i < 10000; ++
i) {
384 for (
int i = 0;
i < 10000; ++
i) {
392 for (
int i = 0;
i < 10000; ++
i) {
396 for (
int i = 0;
i < 10000; ++
i) {
404 for (
int i = 0;
i < 10000; ++
i) {
408 for (
int i = 0;
i < 10000; ++
i) {
416 gflags::ParseCommandLineFlags(&argc, &argv,
true);
bool compare_exchange_weak(T &expected, T desired, std::memory_order=std::memory_order_seq_cst, std::memory_order=std::memory_order_seq_cst)
void contendedRW(size_t itersPerThread, size_t capacity, size_t numThreads, size_t readsPerWrite)
#define EXPECT_THROW(statement, expected_exception)
int RUN_ALL_TESTS() GTEST_MUST_USE_RESULT_
#define EXPECT_EQ(val1, val2)
bool compare_exchange_strong(T &expected, T desired, std::memory_order=std::memory_order_seq_cst, std::memory_order=std::memory_order_seq_cst)
#define BENCHMARK_SUSPEND
T exchange(T desired, std::memory_order=std::memory_order_seq_cst)
::testing::Types< uint16_t, uint32_t, uint64_t > IndexTypesToTest
internal::KeyMatcher< M > Key(M inner_matcher)
TYPED_TEST_CASE(SynchronizedTest, SynchronizedTestTypes)
—— Concurrent Priority Queue Implementation ——
const_iterator cend() const
std::unordered_map< int64_t, VecT > Map
std::vector< std::thread::id > threads
#define BENCHMARK_NAMED_PARAM(name, param_name,...)
bool Value(const T &value, M matcher)
bool is_lock_free() const
TYPED_TEST(SynchronizedTest, Basic)
static map< string, int > m
int main(int argc, char **argv)
static const char *const value
constexpr non_atomic(T desired)
TEST(ProgramOptionsTest, Errors)
#define EXPECT_TRUE(condition)
BENCHMARK(fbFollyGlobalBenchmarkBaseline)
std::pair< const_iterator, bool > emplace(const K &key, V &&value)
bool runBenchmarksOnFlag()
T load(std::memory_order=std::memory_order_seq_cst) const
uint64_t value(const typename LockFreeRingBuffer< T, Atom >::Cursor &rbcursor)
GTEST_API_ void InitGoogleTest(int *argc, char **argv)
void store(T desired, std::memory_order=std::memory_order_seq_cst)
const_iterator find(const Key &key) const
auto doNotOptimizeAway(const T &datum) -> typename std::enable_if< !detail::DoNotOptimizeAwayNeedsIndirect< T >::value >::type
size_t operator()(const std::pair< uint64_t, uint64_t > &pr) const