proxygen
AtomicHashMapTest.cpp File Reference
#include <folly/AtomicHashMap.h>
#include <atomic>
#include <memory>
#include <thread>
#include <glog/logging.h>
#include <folly/Benchmark.h>
#include <folly/Conv.h>
#include <folly/portability/GTest.h>
#include <folly/portability/SysTime.h>

Go to the source code of this file.

Classes

struct  EqTraits
 
struct  HashTraits
 
class  Counters
 
class  Integer
 

Typedefs

typedef int32_t KeyT
 
typedef int32_t ValueT
 
typedef AtomicHashMap< KeyT, ValueTAHMapT
 
typedef AHMapT::value_type RecordT
 
typedef AtomicHashArray< KeyT, ValueTAHArrayT
 
typedef folly::QuadraticProbingAtomicHashMap< KeyT, ValueTQPAHMapT
 
typedef AtomicHashMap< const char *, int64_t, HashTraits, EqTraitsAHMCstrInt
 
typedef AtomicHashArray< int32_t, int32_tAHA
 

Functions

 DEFINE_double (targetLoadFactor, 0.75,"Target memory utilization fraction.")
 
 DEFINE_double (maxLoadFactor, 0.80,"Max before growth.")
 
 DEFINE_int32 (numThreads, 8,"Threads to use for concurrency tests.")
 
 DEFINE_int64 (numBMElements, 12 *1000 *1000,"Size of maps for benchmarks.")
 
static int64_t nowInUsec ()
 
 TEST (Ahm, BasicStrings)
 
 TEST (Ahm, BasicNoncopyable)
 
static AHArrayT::SmartPtr globalAHA (nullptr)
 
static int genVal (int key)
 
static bool legalKey (const char *a)
 
 TEST (Ahm, BasicLookup)
 
 TEST (Ahm, grow)
 
 TEST (Ahm, iterator)
 
 TEST (Ahm, counter)
 
 TEST (Ahm, map_exception_safety)
 
 TEST (Ahm, basicErase)
 
 TEST (Ahm, collision_test)
 
 TEST (Ahm, race_insert_iterate_thread_test)
 
 TEST (Ahm, thread_erase_insert_race)
 
void * atomicHashArrayInsertRaceThread (void *)
 
 TEST (Ahm, atomic_hash_array_insert_race)
 
 TEST (Ahm, erase_find_race)
 
 TEST (Ahm, erase_after_insert_race)
 
 TEST (Ahm, iterator_skips_empty_submaps)
 
 BENCHMARK (st_aha_find, iters)
 
 BENCHMARK (st_ahm_find, iters)
 
 BENCHMARK (st_qpahm_find, iters)
 
 BENCHMARK_DRAW_LINE ()
 
 BENCHMARK (mt_ahm_miss, iters)
 
 BENCHMARK (mt_qpahm_miss, iters)
 
 BENCHMARK (st_ahm_miss, iters)
 
 BENCHMARK (st_qpahm_miss, iters)
 
 BENCHMARK (mt_ahm_find_insert_mix, iters)
 
 BENCHMARK (mt_qpahm_find_insert_mix, iters)
 
 BENCHMARK (mt_aha_find, iters)
 
 BENCHMARK (mt_ahm_find, iters)
 
 BENCHMARK (mt_qpahm_find, iters)
 
 BENCHMARK (st_baseline_modulus_and_random, iters)
 
 BENCHMARK (mt_ahm_insert, iters)
 
 BENCHMARK (mt_qpahm_insert, iters)
 
 BENCHMARK (st_ahm_insert, iters)
 
 BENCHMARK (st_qpahm_insert, iters)
 
void benchmarkSetup ()
 
int main (int argc, char **argv)
 

Variables

const double LF = FLAGS_maxLoadFactor / FLAGS_targetLoadFactor
 
const int maxBMElements = int(FLAGS_numBMElements * LF)
 
AHArrayT::Config config
 
QPAHMapT::Config qpConfig
 
static std::unique_ptr< AHMapTglobalAHM
 
static std::unique_ptr< QPAHMapTglobalQPAHM
 
AHMCstrInt::Config cstrIntCfg
 
AHA::Config configRace
 
auto atomicHashArrayInsertRaceArray = AHA::create(2, configRace)
 
KeyT k
 

Typedef Documentation

Definition at line 675 of file AtomicHashMapTest.cpp.

Definition at line 105 of file AtomicHashMapTest.cpp.

Definition at line 103 of file AtomicHashMapTest.cpp.

Definition at line 153 of file AtomicHashMapTest.cpp.

typedef int32_t KeyT

Definition at line 100 of file AtomicHashMapTest.cpp.

Definition at line 104 of file AtomicHashMapTest.cpp.

typedef int32_t ValueT

Definition at line 101 of file AtomicHashMapTest.cpp.

Function Documentation

void* atomicHashArrayInsertRaceThread ( void *  )

Definition at line 678 of file AtomicHashMapTest.cpp.

References atomicHashArrayInsertRaceArray, folly::AtomicHashArray< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::end(), i, and folly::AtomicHashArray< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::insert().

Referenced by TEST().

678  {
679  AHA* arr = atomicHashArrayInsertRaceArray.get();
680  uintptr_t numInserted = 0;
681  while (!runThreadsCreatedAllThreads.load()) {
682  ;
683  }
684  for (int i = 0; i < 2; i++) {
685  if (arr->insert(RecordT(randomizeKey(i), 0)).first != arr->end()) {
686  numInserted++;
687  }
688  }
689  return (void*)numInserted;
690 }
AHMapT::value_type RecordT
std::pair< iterator, bool > insert(const value_type &r)
auto atomicHashArrayInsertRaceArray
BENCHMARK ( st_aha_find  ,
iters   
)

Definition at line 846 of file AtomicHashMapTest.cpp.

References folly::doNotOptimizeAway(), globalAHA(), and i.

846  {
847  CHECK_LE(iters, FLAGS_numBMElements);
848  for (size_t i = 0; i < iters; i++) {
849  KeyT key = randomizeKey(i);
850  folly::doNotOptimizeAway(globalAHA->find(key)->second);
851  }
852 }
int32_t KeyT
static AHArrayT::SmartPtr globalAHA(nullptr)
auto doNotOptimizeAway(const T &datum) -> typename std::enable_if< !detail::DoNotOptimizeAwayNeedsIndirect< T >::value >::type
Definition: Benchmark.h:258
BENCHMARK ( st_ahm_find  ,
iters   
)

Definition at line 854 of file AtomicHashMapTest.cpp.

References folly::doNotOptimizeAway(), folly::AtomicHashMap< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::find(), and i.

854  {
855  CHECK_LE(iters, FLAGS_numBMElements);
856  for (size_t i = 0; i < iters; i++) {
857  KeyT key = randomizeKey(i);
858  folly::doNotOptimizeAway(globalAHM->find(key)->second);
859  }
860 }
int32_t KeyT
static std::unique_ptr< AHMapT > globalAHM
auto doNotOptimizeAway(const T &datum) -> typename std::enable_if< !detail::DoNotOptimizeAwayNeedsIndirect< T >::value >::type
Definition: Benchmark.h:258
BENCHMARK ( st_qpahm_find  ,
iters   
)

Definition at line 862 of file AtomicHashMapTest.cpp.

References BENCHMARK_DRAW_LINE(), folly::doNotOptimizeAway(), folly::AtomicHashMap< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::find(), and i.

862  {
863  CHECK_LE(iters, FLAGS_numBMElements);
864  for (size_t i = 0; i < iters; i++) {
865  KeyT key = randomizeKey(i);
866  folly::doNotOptimizeAway(globalQPAHM->find(key)->second);
867  }
868 }
int32_t KeyT
static std::unique_ptr< QPAHMapT > globalQPAHM
auto doNotOptimizeAway(const T &datum) -> typename std::enable_if< !detail::DoNotOptimizeAwayNeedsIndirect< T >::value >::type
Definition: Benchmark.h:258
BENCHMARK ( mt_ahm_miss  ,
iters   
)

Definition at line 872 of file AtomicHashMapTest.cpp.

References folly::doNotOptimizeAway(), folly::AtomicHashMap< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::end(), folly::AtomicHashMap< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::find(), i, and int64_t.

872  {
873  CHECK_LE(iters, FLAGS_numBMElements);
874  numOpsPerThread = iters / FLAGS_numThreads;
875  runThreads([](void* jj) -> void* {
876  int64_t j = (int64_t)jj;
877  while (!runThreadsCreatedAllThreads.load()) {
878  ;
879  }
880  for (int i = 0; i < numOpsPerThread; ++i) {
881  KeyT key = i + j * numOpsPerThread * 100;
882  folly::doNotOptimizeAway(globalAHM->find(key) == globalAHM->end());
883  }
884  return nullptr;
885  });
886 }
int32_t KeyT
static std::unique_ptr< AHMapT > globalAHM
auto doNotOptimizeAway(const T &datum) -> typename std::enable_if< !detail::DoNotOptimizeAwayNeedsIndirect< T >::value >::type
Definition: Benchmark.h:258
BENCHMARK ( mt_qpahm_miss  ,
iters   
)

Definition at line 888 of file AtomicHashMapTest.cpp.

References folly::doNotOptimizeAway(), folly::AtomicHashMap< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::end(), folly::AtomicHashMap< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::find(), i, and int64_t.

888  {
889  CHECK_LE(iters, FLAGS_numBMElements);
890  numOpsPerThread = iters / FLAGS_numThreads;
891  runThreads([](void* jj) -> void* {
892  int64_t j = (int64_t)jj;
893  while (!runThreadsCreatedAllThreads.load()) {
894  ;
895  }
896  for (int i = 0; i < numOpsPerThread; ++i) {
897  KeyT key = i + j * numOpsPerThread * 100;
898  folly::doNotOptimizeAway(globalQPAHM->find(key) == globalQPAHM->end());
899  }
900  return nullptr;
901  });
902 }
int32_t KeyT
static std::unique_ptr< QPAHMapT > globalQPAHM
auto doNotOptimizeAway(const T &datum) -> typename std::enable_if< !detail::DoNotOptimizeAwayNeedsIndirect< T >::value >::type
Definition: Benchmark.h:258
BENCHMARK ( st_ahm_miss  ,
iters   
)

Definition at line 904 of file AtomicHashMapTest.cpp.

References folly::doNotOptimizeAway(), folly::AtomicHashMap< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::end(), folly::AtomicHashMap< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::find(), and i.

904  {
905  CHECK_LE(iters, FLAGS_numBMElements);
906  for (size_t i = 0; i < iters; i++) {
907  KeyT key = randomizeKey(i + iters * 100);
908  folly::doNotOptimizeAway(globalAHM->find(key) == globalAHM->end());
909  }
910 }
int32_t KeyT
static std::unique_ptr< AHMapT > globalAHM
auto doNotOptimizeAway(const T &datum) -> typename std::enable_if< !detail::DoNotOptimizeAwayNeedsIndirect< T >::value >::type
Definition: Benchmark.h:258
BENCHMARK ( st_qpahm_miss  ,
iters   
)

Definition at line 912 of file AtomicHashMapTest.cpp.

References folly::doNotOptimizeAway(), folly::AtomicHashMap< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::end(), folly::AtomicHashMap< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::find(), and i.

912  {
913  CHECK_LE(iters, FLAGS_numBMElements);
914  for (size_t i = 0; i < iters; i++) {
915  KeyT key = randomizeKey(i + iters * 100);
916  folly::doNotOptimizeAway(globalQPAHM->find(key) == globalQPAHM->end());
917  }
918 }
int32_t KeyT
static std::unique_ptr< QPAHMapT > globalQPAHM
auto doNotOptimizeAway(const T &datum) -> typename std::enable_if< !detail::DoNotOptimizeAwayNeedsIndirect< T >::value >::type
Definition: Benchmark.h:258
BENCHMARK ( mt_ahm_find_insert_mix  ,
iters   
)

Definition at line 920 of file AtomicHashMapTest.cpp.

References folly::doNotOptimizeAway(), folly::AtomicHashMap< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::find(), genVal(), i, folly::AtomicHashMap< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::insert(), and int64_t.

920  {
921  CHECK_LE(iters, FLAGS_numBMElements);
922  numOpsPerThread = iters / FLAGS_numThreads;
923  runThreads([](void* jj) -> void* {
924  int64_t j = (int64_t)jj;
925  while (!runThreadsCreatedAllThreads.load()) {
926  ;
927  }
928  for (int i = 0; i < numOpsPerThread; ++i) {
929  if (i % 128) { // ~1% insert mix
930  KeyT key = randomizeKey(i + j * numOpsPerThread);
931  folly::doNotOptimizeAway(globalAHM->find(key)->second);
932  } else {
933  KeyT key = randomizeKey(i + j * numOpsPerThread * 100);
934  globalAHM->insert(key, genVal(key));
935  }
936  }
937  return nullptr;
938  });
939 }
int32_t KeyT
static int genVal(int key)
static std::unique_ptr< AHMapT > globalAHM
auto doNotOptimizeAway(const T &datum) -> typename std::enable_if< !detail::DoNotOptimizeAwayNeedsIndirect< T >::value >::type
Definition: Benchmark.h:258
BENCHMARK ( mt_qpahm_find_insert_mix  ,
iters   
)

Definition at line 941 of file AtomicHashMapTest.cpp.

References folly::doNotOptimizeAway(), folly::AtomicHashMap< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::find(), genVal(), i, folly::AtomicHashMap< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::insert(), and int64_t.

941  {
942  CHECK_LE(iters, FLAGS_numBMElements);
943  numOpsPerThread = iters / FLAGS_numThreads;
944  runThreads([](void* jj) -> void* {
945  int64_t j = (int64_t)jj;
946  while (!runThreadsCreatedAllThreads.load()) {
947  ;
948  }
949  for (int i = 0; i < numOpsPerThread; ++i) {
950  if (i % 128) { // ~1% insert mix
951  KeyT key = randomizeKey(i + j * numOpsPerThread);
952  folly::doNotOptimizeAway(globalQPAHM->find(key)->second);
953  } else {
954  KeyT key = randomizeKey(i + j * numOpsPerThread * 100);
955  globalQPAHM->insert(key, genVal(key));
956  }
957  }
958  return nullptr;
959  });
960 }
int32_t KeyT
static std::unique_ptr< QPAHMapT > globalQPAHM
static int genVal(int key)
auto doNotOptimizeAway(const T &datum) -> typename std::enable_if< !detail::DoNotOptimizeAwayNeedsIndirect< T >::value >::type
Definition: Benchmark.h:258
BENCHMARK ( mt_aha_find  ,
iters   
)

Definition at line 962 of file AtomicHashMapTest.cpp.

References folly::doNotOptimizeAway(), globalAHA(), i, and int64_t.

962  {
963  CHECK_LE(iters, FLAGS_numBMElements);
964  numOpsPerThread = iters / FLAGS_numThreads;
965  runThreads([](void* jj) -> void* {
966  int64_t j = (int64_t)jj;
967  while (!runThreadsCreatedAllThreads.load()) {
968  ;
969  }
970  for (int i = 0; i < numOpsPerThread; ++i) {
971  KeyT key = randomizeKey(i + j * numOpsPerThread);
972  folly::doNotOptimizeAway(globalAHA->find(key)->second);
973  }
974  return nullptr;
975  });
976 }
int32_t KeyT
static AHArrayT::SmartPtr globalAHA(nullptr)
auto doNotOptimizeAway(const T &datum) -> typename std::enable_if< !detail::DoNotOptimizeAwayNeedsIndirect< T >::value >::type
Definition: Benchmark.h:258
BENCHMARK ( mt_ahm_find  ,
iters   
)

Definition at line 978 of file AtomicHashMapTest.cpp.

References folly::doNotOptimizeAway(), folly::AtomicHashMap< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::find(), i, and int64_t.

978  {
979  CHECK_LE(iters, FLAGS_numBMElements);
980  numOpsPerThread = iters / FLAGS_numThreads;
981  runThreads([](void* jj) -> void* {
982  int64_t j = (int64_t)jj;
983  while (!runThreadsCreatedAllThreads.load()) {
984  ;
985  }
986  for (int i = 0; i < numOpsPerThread; ++i) {
987  KeyT key = randomizeKey(i + j * numOpsPerThread);
988  folly::doNotOptimizeAway(globalAHM->find(key)->second);
989  }
990  return nullptr;
991  });
992 }
int32_t KeyT
static std::unique_ptr< AHMapT > globalAHM
auto doNotOptimizeAway(const T &datum) -> typename std::enable_if< !detail::DoNotOptimizeAwayNeedsIndirect< T >::value >::type
Definition: Benchmark.h:258
BENCHMARK ( mt_qpahm_find  ,
iters   
)

Definition at line 994 of file AtomicHashMapTest.cpp.

References folly::doNotOptimizeAway(), folly::AtomicHashMap< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::find(), i, and int64_t.

994  {
995  CHECK_LE(iters, FLAGS_numBMElements);
996  numOpsPerThread = iters / FLAGS_numThreads;
997  runThreads([](void* jj) -> void* {
998  int64_t j = (int64_t)jj;
999  while (!runThreadsCreatedAllThreads.load()) {
1000  ;
1001  }
1002  for (int i = 0; i < numOpsPerThread; ++i) {
1003  KeyT key = randomizeKey(i + j * numOpsPerThread);
1004  folly::doNotOptimizeAway(globalQPAHM->find(key)->second);
1005  }
1006  return nullptr;
1007  });
1008 }
int32_t KeyT
static std::unique_ptr< QPAHMapT > globalQPAHM
auto doNotOptimizeAway(const T &datum) -> typename std::enable_if< !detail::DoNotOptimizeAwayNeedsIndirect< T >::value >::type
Definition: Benchmark.h:258
BENCHMARK ( st_baseline_modulus_and_random  ,
iters   
)

Definition at line 1011 of file AtomicHashMapTest.cpp.

References i, and k.

1011  {
1012  for (size_t i = 0; i < iters; ++i) {
1013  k = randomizeKey(i) % iters;
1014  }
1015 }
KeyT k
BENCHMARK ( mt_ahm_insert  ,
iters   
)

Definition at line 1019 of file AtomicHashMapTest.cpp.

References BENCHMARK_SUSPEND, config, and LF.

1019  {
1021  globalAHM = std::make_unique<AHMapT>(int(iters * LF), config);
1022  numOpsPerThread = iters / FLAGS_numThreads;
1023  }
1024  runThreads(insertThread);
1025 }
#define BENCHMARK_SUSPEND
Definition: Benchmark.h:576
static std::unique_ptr< AHMapT > globalAHM
AHArrayT::Config config
const double LF
BENCHMARK ( mt_qpahm_insert  ,
iters   
)

Definition at line 1027 of file AtomicHashMapTest.cpp.

References BENCHMARK_SUSPEND, LF, and qpConfig.

1027  {
1029  globalQPAHM = std::make_unique<QPAHMapT>(int(iters * LF), qpConfig);
1030  numOpsPerThread = iters / FLAGS_numThreads;
1031  }
1032  runThreads(qpInsertThread);
1033 }
QPAHMapT::Config qpConfig
#define BENCHMARK_SUSPEND
Definition: Benchmark.h:576
static std::unique_ptr< QPAHMapT > globalQPAHM
const double LF
BENCHMARK ( st_ahm_insert  ,
iters   
)

Definition at line 1035 of file AtomicHashMapTest.cpp.

References folly::BenchmarkSuspender::dismiss(), genVal(), i, folly::AtomicHashMap< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::insert(), and LF.

1035  {
1037  std::unique_ptr<AHMapT> ahm(new AHMapT(int(iters * LF), config));
1038  susp.dismiss();
1039 
1040  for (size_t i = 0; i < iters; i++) {
1041  KeyT key = randomizeKey(i);
1042  ahm->insert(key, genVal(key));
1043  }
1044 }
int32_t KeyT
AtomicHashMap< KeyT, ValueT > AHMapT
static int genVal(int key)
AHArrayT::Config config
const double LF
BENCHMARK ( st_qpahm_insert  ,
iters   
)

Definition at line 1046 of file AtomicHashMapTest.cpp.

References folly::BenchmarkSuspender::dismiss(), genVal(), i, folly::AtomicHashMap< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::insert(), and LF.

1046  {
1048  std::unique_ptr<QPAHMapT> ahm(new QPAHMapT(int(iters * LF), qpConfig));
1049  susp.dismiss();
1050 
1051  for (size_t i = 0; i < iters; i++) {
1052  KeyT key = randomizeKey(i);
1053  ahm->insert(key, genVal(key));
1054  }
1055 }
QPAHMapT::Config qpConfig
int32_t KeyT
folly::QuadraticProbingAtomicHashMap< KeyT, ValueT > QPAHMapT
static int genVal(int key)
const double LF
BENCHMARK_DRAW_LINE ( )

Referenced by BENCHMARK().

void benchmarkSetup ( )

Definition at line 1057 of file AtomicHashMapTest.cpp.

References folly::AtomicHashArray< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::Config::maxLoadFactor, and min.

Referenced by main().

1057  {
1058  config.maxLoadFactor = FLAGS_maxLoadFactor;
1059  qpConfig.maxLoadFactor = FLAGS_maxLoadFactor;
1060  configRace.maxLoadFactor = 0.5;
1061  int numCores = sysconf(_SC_NPROCESSORS_ONLN);
1062  loadGlobalAha();
1063  loadGlobalAhm();
1064  loadGlobalQPAhm();
1065  string numIters =
1066  folly::to<string>(std::min(1000000, int(FLAGS_numBMElements)));
1067 
1068  gflags::SetCommandLineOptionWithMode(
1069  "bm_max_iters", numIters.c_str(), gflags::SET_FLAG_IF_DEFAULT);
1070  gflags::SetCommandLineOptionWithMode(
1071  "bm_min_iters", numIters.c_str(), gflags::SET_FLAG_IF_DEFAULT);
1072  string numCoresStr = folly::to<string>(numCores);
1073  gflags::SetCommandLineOptionWithMode(
1074  "numThreads", numCoresStr.c_str(), gflags::SET_FLAG_IF_DEFAULT);
1075 
1076  std::cout << "\nRunning AHM benchmarks on machine with " << numCores
1077  << " logical cores.\n"
1078  " num elements per map: "
1079  << FLAGS_numBMElements << "\n"
1080  << " num threads for mt tests: " << FLAGS_numThreads << "\n"
1081  << " AHM load factor: " << FLAGS_targetLoadFactor << "\n\n";
1082 }
QPAHMapT::Config qpConfig
AHArrayT::Config config
LogLevel min
Definition: LogLevel.cpp:30
AHA::Config configRace
DEFINE_double ( targetLoadFactor  ,
0.  75,
"Target memory utilization fraction."   
)
DEFINE_double ( maxLoadFactor  ,
0.  80,
"Max before growth."   
)
DEFINE_int32 ( numThreads  ,
,
"Threads to use for concurrency tests."   
)
DEFINE_int64 ( numBMElements  ,
12 *1000 *  1000,
"Size of maps for benchmarks."   
)
static int genVal ( int  key)
static

Definition at line 114 of file AtomicHashMapTest.cpp.

References a, and legalKey().

Referenced by BENCHMARK(), and TEST().

114  {
115  return key / 3;
116 }
static AHArrayT::SmartPtr globalAHA ( nullptr  )
static

Referenced by BENCHMARK(), and TEST().

int main ( int  argc,
char **  argv 
)

Definition at line 1084 of file AtomicHashMapTest.cpp.

References benchmarkSetup(), testing::InitGoogleTest(), RUN_ALL_TESTS(), and folly::runBenchmarks().

1084  {
1085  testing::InitGoogleTest(&argc, argv);
1086  gflags::ParseCommandLineFlags(&argc, &argv, true);
1087  auto ret = RUN_ALL_TESTS();
1088  if (!ret && FLAGS_benchmark) {
1089  benchmarkSetup();
1091  }
1092  return ret;
1093 }
void benchmarkSetup()
int RUN_ALL_TESTS() GTEST_MUST_USE_RESULT_
Definition: gtest.h:2232
void runBenchmarks()
Definition: Benchmark.cpp:456
char ** argv
GTEST_API_ void InitGoogleTest(int *argc, char **argv)
Definition: gtest.cc:5370
static int64_t nowInUsec ( )
static

Definition at line 45 of file AtomicHashMapTest.cpp.

References int64_t.

Referenced by TEST().

45  {
46  timeval tv;
47  gettimeofday(&tv, nullptr);
48  return int64_t(tv.tv_sec) * 1000 * 1000 + tv.tv_usec;
49 }
TEST ( Ahm  ,
BasicStrings   
)

Definition at line 51 of file AtomicHashMapTest.cpp.

References EXPECT_EQ, EXPECT_TRUE, and i.

51  {
53  AHM myMap(1024);
54  EXPECT_TRUE(myMap.begin() == myMap.end());
55 
56  for (int i = 0; i < 100; ++i) {
57  myMap.insert(make_pair(i, folly::to<string>(i)));
58  }
59  for (int i = 0; i < 100; ++i) {
60  EXPECT_EQ(myMap.find(i)->second, folly::to<string>(i));
61  }
62 
63  myMap.insert(std::make_pair(999, "A"));
64  myMap.insert(std::make_pair(999, "B"));
65  EXPECT_EQ(myMap.find(999)->second, "A"); // shouldn't have overwritten
66  myMap.find(999)->second = "B";
67  myMap.find(999)->second = "C";
68  EXPECT_EQ(myMap.find(999)->second, "C");
69  EXPECT_EQ(myMap.find(999)->first, 999);
70 }
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
TEST ( Ahm  ,
BasicNoncopyable   
)

Definition at line 72 of file AtomicHashMapTest.cpp.

References EXPECT_EQ, EXPECT_TRUE, and i.

72  {
74  AHM myMap(1024);
75  EXPECT_TRUE(myMap.begin() == myMap.end());
76 
77  for (int i = 0; i < 50; ++i) {
78  myMap.insert(make_pair(i, std::make_unique<int>(i)));
79  }
80  for (int i = 50; i < 100; ++i) {
81  myMap.insert(i, std::make_unique<int>(i));
82  }
83  for (int i = 100; i < 150; ++i) {
84  myMap.emplace(i, new int(i));
85  }
86  for (int i = 150; i < 200; ++i) {
87  myMap.emplace(i, new int(i), std::default_delete<int>());
88  }
89  for (int i = 0; i < 200; ++i) {
90  EXPECT_EQ(*(myMap.find(i)->second), i);
91  }
92  for (int i = 0; i < 200; i += 4) {
93  myMap.erase(i);
94  }
95  for (int i = 0; i < 200; i += 4) {
96  EXPECT_EQ(myMap.find(i), myMap.end());
97  }
98 }
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
TEST ( Ahm  ,
BasicLookup   
)

Definition at line 161 of file AtomicHashMapTest.cpp.

References folly::AtomicHashMap< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::begin(), folly::AtomicHashMap< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::end(), EXPECT_EQ, EXPECT_TRUE, folly::AtomicHashMap< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::find(), and folly::AtomicHashMap< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::insert().

161  {
162  AHMCstrInt myMap(1024, cstrIntCfg);
163  EXPECT_TRUE(myMap.begin() == myMap.end());
164  myMap.insert(std::make_pair("f", 42));
165  EXPECT_EQ(42, myMap.find("f")->second);
166  {
167  // Look up a single char, successfully.
168  auto it = myMap.find<char>('f');
169  EXPECT_EQ(42, it->second);
170  }
171  {
172  // Look up a single char, unsuccessfully.
173  auto it = myMap.find<char>('g');
174  EXPECT_TRUE(it == myMap.end());
175  }
176  {
177  // Look up a string piece, successfully.
178  const StringPiece piece("f");
179  auto it = myMap.find(piece);
180  EXPECT_EQ(42, it->second);
181  }
182 }
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
Range< const char * > StringPiece
AHMCstrInt::Config cstrIntCfg
TEST ( Ahm  ,
grow   
)

Definition at line 184 of file AtomicHashMapTest.cpp.

References folly::AtomicHashMap< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::clear(), EXPECT_EQ, EXPECT_GT, EXPECT_TRUE, folly::AtomicHashMap< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::find(), folly::AtomicHashMap< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::findAt(), genVal(), folly::AtomicHashMap< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::ahm_iterator< ContT, IterVal, SubIt >::getIndex(), i, folly::AtomicHashMap< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::insert(), int32_t, m, folly::AtomicHashMap< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::numSubMaps(), folly::AtomicHashMap< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::size(), and uint64_t.

184  {
185  VLOG(1) << "Overhead: " << sizeof(AHArrayT) << " (array) "
186  << sizeof(AHMapT) + sizeof(AHArrayT) << " (map/set) Bytes.";
187  uint64_t numEntries = 10000;
188  float sizeFactor = 0.46f;
189 
190  std::unique_ptr<AHMapT> m(new AHMapT(int(numEntries * sizeFactor), config));
191 
192  // load map - make sure we succeed and the index is accurate
193  bool success = true;
194  for (uint64_t i = 0; i < numEntries; i++) {
195  auto ret = m->insert(RecordT(i, genVal(i)));
196  success &= ret.second;
197  success &= (m->findAt(ret.first.getIndex())->second == genVal(i));
198  }
199  // Overwrite vals to make sure there are no dups
200  // Every insert should fail because the keys are already in the map.
201  success = true;
202  for (uint64_t i = 0; i < numEntries; i++) {
203  auto ret = m->insert(RecordT(i, genVal(i * 2)));
204  success &= (ret.second == false); // fail on collision
205  success &= (ret.first->second == genVal(i)); // return the previous value
206  success &= (m->findAt(ret.first.getIndex())->second == genVal(i));
207  }
208  EXPECT_TRUE(success);
209 
210  // check correctness
211  EXPECT_GT(m->numSubMaps(), 1); // make sure we grew
212  success = true;
213  EXPECT_EQ(m->size(), numEntries);
214  for (size_t i = 0; i < numEntries; i++) {
215  success &= (m->find(i)->second == genVal(i));
216  }
217  EXPECT_TRUE(success);
218 
219  // Check findAt
220  success = true;
222  for (int32_t i = 0; i < int32_t(numEntries); i++) {
223  retIt = m->find(i);
224  retIt = m->findAt(retIt.getIndex());
225  success &= (retIt->second == genVal(i));
226  // We use a uint32_t index so that this comparison is between two
227  // variables of the same type.
228  success &= (retIt->first == i);
229  }
230  EXPECT_TRUE(success);
231 
232  // Try modifying value
233  m->find(8)->second = 5309;
234  EXPECT_EQ(m->find(8)->second, 5309);
235 
236  // check clear()
237  m->clear();
238  success = true;
239  for (uint64_t i = 0; i < numEntries / 2; i++) {
240  success &= m->insert(RecordT(i, genVal(i))).second;
241  }
242  EXPECT_TRUE(success);
243  EXPECT_EQ(m->size(), numEntries / 2);
244 }
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
AHMapT::value_type RecordT
AtomicHashMap< KeyT, ValueT > AHMapT
static int genVal(int key)
AHArrayT::Config config
static map< string, int > m
AtomicHashArray< KeyT, ValueT > AHArrayT
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
#define EXPECT_GT(val1, val2)
Definition: gtest.h:1934
TEST ( Ahm  ,
iterator   
)

Definition at line 246 of file AtomicHashMapTest.cpp.

References count, EXPECT_EQ, EXPECT_TRUE, FOR_EACH, genVal(), i, folly::AtomicHashMap< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::insert(), and m.

246  {
247  int numEntries = 10000;
248  float sizeFactor = .46f;
249  std::unique_ptr<AHMapT> m(new AHMapT(int(numEntries * sizeFactor), config));
250 
251  // load map - make sure we succeed and the index is accurate
252  for (int i = 0; i < numEntries; i++) {
253  m->insert(RecordT(i, genVal(i)));
254  }
255 
256  bool success = true;
257  int count = 0;
258  FOR_EACH (it, *m) {
259  success &= (it->second == genVal(it->first));
260  ++count;
261  }
262  EXPECT_TRUE(success);
263  EXPECT_EQ(count, numEntries);
264 }
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
AHMapT::value_type RecordT
AtomicHashMap< KeyT, ValueT > AHMapT
static int genVal(int key)
AHArrayT::Config config
static map< string, int > m
int * count
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
#define FOR_EACH(i, c)
Definition: Foreach.h:143
TEST ( Ahm  ,
counter   
)

Definition at line 303 of file AtomicHashMapTest.cpp.

References c, EXPECT_EQ, EXPECT_NE, FOR_EACH_RANGE, Counters::getValue(), i, Counters::increment(), folly::pushmi::detail::t, threads, Counters::toString(), and val.

303  {
304  const int numKeys = 10;
305  const int mult = 10;
306  Counters c(numKeys);
307  vector<int64_t> keys;
308  FOR_EACH_RANGE (i, 1, numKeys) { keys.push_back(i); }
309  vector<std::thread> threads;
310  for (auto key : keys) {
311  FOR_EACH_RANGE (i, 0, key * mult) {
312  threads.push_back(std::thread([&, key] { c.increment(key); }));
313  }
314  }
315  for (auto& t : threads) {
316  t.join();
317  }
318  string str = c.toString();
319  for (auto key : keys) {
320  int val = key * mult;
321  EXPECT_EQ(val, c.getValue(key));
322  EXPECT_NE(
323  string::npos, str.find(folly::to<string>("[", key, ":", val, "]")));
324  }
325 }
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
double val
Definition: String.cpp:273
std::vector< std::thread::id > threads
#define FOR_EACH_RANGE(i, begin, end)
Definition: Foreach.h:313
#define EXPECT_NE(val1, val2)
Definition: gtest.h:1926
char c
TEST ( Ahm  ,
map_exception_safety   
)

Definition at line 349 of file AtomicHashMapTest.cpp.

References count, EXPECT_EQ, EXPECT_TRUE, genVal(), i, and m.

349  {
350  typedef AtomicHashMap<KeyT, Integer> MyMapT;
351 
352  int numEntries = 10000;
353  float sizeFactor = 0.46f;
354  std::unique_ptr<MyMapT> m(new MyMapT(int(numEntries * sizeFactor)));
355 
356  bool success = true;
357  int count = 0;
358  for (int i = 0; i < numEntries; i++) {
359  try {
360  m->insert(i, Integer(genVal(i)));
361  success &= (m->find(i)->second == Integer(genVal(i)));
362  ++count;
363  } catch (...) {
364  success &= !m->count(i);
365  }
366  }
367  EXPECT_EQ(count, m->size());
368  EXPECT_TRUE(success);
369 }
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
static int genVal(int key)
static map< string, int > m
int * count
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
TEST ( Ahm  ,
basicErase   
)

Definition at line 371 of file AtomicHashMapTest.cpp.

References folly::AtomicHashMap< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::count(), folly::BenchmarkSuspender::dismiss(), folly::AtomicHashMap< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::erase(), EXPECT_EQ, EXPECT_TRUE, genVal(), globalAHA(), i, folly::AtomicHashMap< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::insert(), int64_t, folly::hash::jenkins_rev_mix32(), folly::AtomicHashMap< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::numSubMaps(), s, folly::AtomicHashMap< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::size(), and threads.

371  {
372  size_t numEntries = 3000;
373 
374  std::unique_ptr<AHMapT> s(new AHMapT(numEntries, config));
375  // Iterate filling up the map and deleting all keys a few times
376  // to test more than one subMap.
377  for (int iterations = 0; iterations < 4; ++iterations) {
378  // Testing insertion of keys
379  bool success = true;
380  for (size_t i = 0; i < numEntries; ++i) {
381  success &= !(s->count(i));
382  auto ret = s->insert(RecordT(i, i));
383  success &= s->count(i);
384  success &= ret.second;
385  }
386  EXPECT_TRUE(success);
387  EXPECT_EQ(s->size(), numEntries);
388 
389  // Delete every key in the map and verify that the key is gone and the the
390  // size is correct.
391  success = true;
392  for (size_t i = 0; i < numEntries; ++i) {
393  success &= s->erase(i);
394  success &= (s->size() == numEntries - 1 - i);
395  success &= !(s->count(i));
396  success &= !(s->erase(i));
397  }
398  EXPECT_TRUE(success);
399  }
400  VLOG(1) << "Final number of subMaps = " << s->numSubMaps();
401 }
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
AHMapT::value_type RecordT
AtomicHashMap< KeyT, ValueT > AHMapT
AHArrayT::Config config
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
static set< string > s
TEST ( Ahm  ,
collision_test   
)

Definition at line 470 of file AtomicHashMapTest.cpp.

References folly::AtomicHashMap< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::begin(), folly::AtomicHashMap< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::capacity(), config, count, folly::test::end(), folly::AtomicHashMap< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::end(), EXPECT_EQ, EXPECT_FALSE, EXPECT_TRUE, folly::AtomicHashMap< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::find(), genVal(), i, folly::AtomicHashMap< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::insert(), nowInUsec(), folly::AtomicHashMap< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::numSubMaps(), folly::AtomicHashMap< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::size(), and start.

470  {
471  const int numInserts = 1000000 / 4;
472 
473  // Doing the same number on each thread so we collide.
474  numOpsPerThread = numInserts;
475 
476  float sizeFactor = 0.46f;
477  int entrySize = sizeof(KeyT) + sizeof(ValueT);
478  VLOG(1) << "Testing " << numInserts << " unique " << entrySize
479  << " Byte entries replicated in " << FLAGS_numThreads
480  << " threads with " << FLAGS_maxLoadFactor * 100.0
481  << "% max load factor.";
482 
483  globalAHM = std::make_unique<AHMapT>(int(numInserts * sizeFactor), config);
484 
485  size_t sizeInit = globalAHM->capacity();
486  VLOG(1) << " Initial capacity: " << sizeInit;
487 
488  double start = nowInUsec();
489  runThreads([](void*) -> void* { // collisionInsertThread
490  for (int i = 0; i < numOpsPerThread; ++i) {
491  KeyT key = randomizeKey(i);
492  globalAHM->insert(key, genVal(key));
493  }
494  return nullptr;
495  });
496  double elapsed = nowInUsec() - start;
497 
498  size_t finalCap = globalAHM->capacity();
499  size_t sizeAHM = globalAHM->size();
500  VLOG(1) << elapsed / sizeAHM << " usec per " << FLAGS_numThreads
501  << " duplicate inserts (atomic).";
502  VLOG(1) << " Final capacity: " << finalCap << " in "
503  << globalAHM->numSubMaps() << " sub maps ("
504  << sizeAHM * 100 / finalCap << "% load factor, "
505  << (finalCap - sizeInit) * 100 / sizeInit << "% growth).";
506 
507  // check correctness
508  EXPECT_EQ(sizeAHM, numInserts);
509  bool success = true;
510  for (int i = 0; i < numInserts; ++i) {
511  KeyT key = randomizeKey(i);
512  success &= (globalAHM->find(key)->second == genVal(key));
513  }
514  EXPECT_TRUE(success);
515 
516  // check colliding finds
517  start = nowInUsec();
518  runThreads([](void*) -> void* { // collisionFindThread
519  KeyT key(0);
520  for (int i = 0; i < numOpsPerThread; ++i) {
521  globalAHM->find(key);
522  }
523  return nullptr;
524  });
525 
526  elapsed = nowInUsec() - start;
527 
528  VLOG(1) << elapsed / sizeAHM << " usec per " << FLAGS_numThreads
529  << " duplicate finds (atomic).";
530 }
int32_t KeyT
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
int32_t ValueT
static int genVal(int key)
static std::unique_ptr< AHMapT > globalAHM
AHArrayT::Config config
static int64_t nowInUsec()
auto start
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
TEST ( Ahm  ,
race_insert_iterate_thread_test   
)

Definition at line 564 of file AtomicHashMapTest.cpp.

References config, folly::AtomicHashMap< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::count(), folly::AtomicHashMap< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::erase(), genVal(), i, folly::AtomicHashMap< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::insert(), folly::AtomicHashMap< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::numSubMaps(), and folly::AtomicHashMap< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::size().

564  {
565  const int kInsertThreads = 20;
566  const int kIterateThreads = 20;
567  raceFinalSizeEstimate = kInsertThreads * kInsertPerThread;
568 
569  VLOG(1) << "Testing iteration and insertion with " << kInsertThreads
570  << " threads inserting and " << kIterateThreads
571  << " threads iterating.";
572 
573  globalAHM = std::make_unique<AHMapT>(raceFinalSizeEstimate / 9, config);
574 
575  vector<pthread_t> threadIds;
576  for (int j = 0; j < kInsertThreads + kIterateThreads; j++) {
577  pthread_t tid;
578  void* (*thread)(void*) =
579  (j < kInsertThreads ? raceInsertRandomThread : raceIterateThread);
580  if (pthread_create(&tid, nullptr, thread, nullptr) != 0) {
581  LOG(ERROR) << "Could not start thread";
582  } else {
583  threadIds.push_back(tid);
584  }
585  }
586  for (size_t i = 0; i < threadIds.size(); ++i) {
587  pthread_join(threadIds[i], nullptr);
588  }
589  VLOG(1) << "Ended up with " << globalAHM->numSubMaps() << " submaps";
590  VLOG(1) << "Final size of map " << globalAHM->size();
591 }
static std::unique_ptr< AHMapT > globalAHM
AHArrayT::Config config
TEST ( Ahm  ,
thread_erase_insert_race   
)

Definition at line 644 of file AtomicHashMapTest.cpp.

References config, folly::AtomicHashMap< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::empty(), EXPECT_EQ, EXPECT_TRUE, i, int64_t, folly::AtomicHashMap< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::numSubMaps(), and folly::AtomicHashMap< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::size().

644  {
645  const int kInsertThreads = 1;
646  const int kEraseThreads = 10;
647 
648  VLOG(1) << "Testing insertion and erase with " << kInsertThreads
649  << " thread inserting and " << kEraseThreads << " threads erasing.";
650 
651  globalAHM = std::make_unique<AHMapT>(kTestEraseInsertions / 4, config);
652 
653  vector<pthread_t> threadIds;
654  for (int64_t j = 0; j < kInsertThreads + kEraseThreads; j++) {
655  pthread_t tid;
656  void* (*thread)(void*) =
657  (j < kInsertThreads ? testEraseInsertThread : testEraseEraseThread);
658  if (pthread_create(&tid, nullptr, thread, (void*)j) != 0) {
659  LOG(ERROR) << "Could not start thread";
660  } else {
661  threadIds.push_back(tid);
662  }
663  }
664  for (size_t i = 0; i < threadIds.size(); i++) {
665  pthread_join(threadIds[i], nullptr);
666  }
667 
668  EXPECT_TRUE(globalAHM->empty());
669  EXPECT_EQ(globalAHM->size(), 0);
670 
671  VLOG(1) << "Ended up with " << globalAHM->numSubMaps() << " submaps";
672 }
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
static std::unique_ptr< AHMapT > globalAHM
AHArrayT::Config config
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
TEST ( Ahm  ,
atomic_hash_array_insert_race   
)

Definition at line 691 of file AtomicHashMapTest.cpp.

References atomicHashArrayInsertRaceArray, atomicHashArrayInsertRaceThread(), folly::AtomicHashArray< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::clear(), EXPECT_EQ, EXPECT_GE, i, and folly::AtomicHashArray< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::size().

691  {
692  AHA* arr = atomicHashArrayInsertRaceArray.get();
693  int numIterations = 5000;
694  constexpr int numThreads = 4;
695  void* statuses[numThreads];
696  for (int i = 0; i < numIterations; i++) {
697  arr->clear();
698  runThreads(atomicHashArrayInsertRaceThread, numThreads, statuses);
699  EXPECT_GE(arr->size(), 1);
700  for (int j = 0; j < numThreads; j++) {
701  EXPECT_EQ(arr->size(), uintptr_t(statuses[j]));
702  }
703  }
704 }
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
#define EXPECT_GE(val1, val2)
Definition: gtest.h:1932
void * atomicHashArrayInsertRaceThread(void *)
auto atomicHashArrayInsertRaceArray
TEST ( Ahm  ,
erase_find_race   
)

Definition at line 707 of file AtomicHashMapTest.cpp.

References ASSERT_EQ, folly::AtomicHashMap< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::end(), folly::AtomicHashMap< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::erase(), folly::AtomicHashMap< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::find(), folly::AtomicHashMap< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::insert(), k, map(), and uint64_t.

707  {
708  const uint64_t limit = 10000;
710  std::atomic<uint64_t> key{1};
711 
712  // Invariant: all values are equal to their keys.
713  // At any moment there is one or two consecutive keys in the map.
714 
715  std::thread write_thread([&]() {
716  while (true) {
717  uint64_t k = ++key;
718  if (k > limit) {
719  break;
720  }
721  map.insert(k + 1, k + 1);
722  map.erase(k);
723  }
724  });
725 
726  std::thread read_thread([&]() {
727  while (true) {
728  uint64_t k = key.load();
729  if (k > limit) {
730  break;
731  }
732 
733  auto it = map.find(k);
734  if (it != map.end()) {
735  ASSERT_EQ(k, it->second);
736  }
737  }
738  });
739 
740  read_thread.join();
741  write_thread.join();
742 }
#define ASSERT_EQ(val1, val2)
Definition: gtest.h:1956
static Map map(mapCap)
Definition: Traits.h:594
KeyT k
TEST ( Ahm  ,
erase_after_insert_race   
)

Definition at line 745 of file AtomicHashMapTest.cpp.

References folly::AtomicHashMap< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::erase(), i, folly::AtomicHashMap< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::insert(), map(), folly::pushmi::detail::t, and uint64_t.

745  {
746  const uint64_t limit = 10000;
747  const size_t num_threads = 100;
748  const size_t num_iters = 500;
750 
751  std::atomic<bool> go{false};
752  std::vector<std::thread> ts;
753  for (size_t i = 0; i < num_threads; ++i) {
754  ts.emplace_back([&]() {
755  while (!go) {
756  continue;
757  }
758  for (size_t n = 0; n < num_iters; ++n) {
759  map.erase(1);
760  map.insert(1, 1);
761  }
762  });
763  }
764 
765  go = true;
766 
767  for (auto& t : ts) {
768  t.join();
769  }
770 }
static Map map(mapCap)
Definition: Traits.h:594
TEST ( Ahm  ,
iterator_skips_empty_submaps   
)

Definition at line 773 of file AtomicHashMapTest.cpp.

References ASSERT_EQ, ASSERT_NE, config, folly::AtomicHashArray< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::create(), folly::AtomicHashMap< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::end(), folly::AtomicHashMap< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::erase(), EXPECT_EQ, folly::AtomicHashMap< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::find(), globalAHA(), folly::AtomicHashMap< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::insert(), map(), maxBMElements, nowInUsec(), qpConfig, folly::AtomicHashMap< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::size(), start, and uint64_t.

773  {
775  conf.growthFactor = 1;
776 
778 
779  map.insert(1, 1);
780  map.insert(2, 2);
781  map.insert(3, 3);
782 
783  map.erase(2);
784 
785  auto it = map.find(1);
786 
787  ASSERT_NE(map.end(), it);
788  ASSERT_EQ(1, it->first);
789  ASSERT_EQ(1, it->second);
790 
791  ++it;
792 
793  ASSERT_NE(map.end(), it);
794  ASSERT_EQ(3, it->first);
795  ASSERT_EQ(3, it->second);
796 
797  ++it;
798  ASSERT_EQ(map.end(), it);
799 }
#define ASSERT_EQ(val1, val2)
Definition: gtest.h:1956
static Map map(mapCap)
Definition: Traits.h:594
#define ASSERT_NE(val1, val2)
Definition: gtest.h:1960

Variable Documentation

auto atomicHashArrayInsertRaceArray = AHA::create(2, configRace)

Definition at line 677 of file AtomicHashMapTest.cpp.

Referenced by atomicHashArrayInsertRaceThread(), and TEST().

AHA::Config configRace

Definition at line 676 of file AtomicHashMapTest.cpp.

AHMCstrInt::Config cstrIntCfg

Definition at line 154 of file AtomicHashMapTest.cpp.

std::unique_ptr<AHMapT> globalAHM
static

Definition at line 110 of file AtomicHashMapTest.cpp.

std::unique_ptr<QPAHMapT> globalQPAHM
static

Definition at line 111 of file AtomicHashMapTest.cpp.

KeyT k

Definition at line 1010 of file AtomicHashMapTest.cpp.

Referenced by testing::gmock_generated_actions_test::ACTION_P3(), testing::gmock_generated_actions_test::ACTION_TEMPLATE(), folly::compression::EliasFanoEncoderV2< Value, SkipValue, kSkipQuantum, kForwardQuantum >::add(), detail::addHashBenchmark(), folly::ConcurrentSkipList< T, Comp, NodeAlloc, MAX_HEIGHT >::addOrGetData(), folly::detail::FingerprintPolynomial< BITS-1 >::addXk(), folly::ConcurrentHashMap< KeyType, ValueType, HashFn, KeyEqual, Allocator, ShardBits, Atom, Mutex >::assign(), folly::detail::ConcurrentHashMapSegment< KeyType, ValueType, ShardBits, HashFn, KeyEqual, Allocator, Atom, Mutex >::assign(), folly::ConcurrentHashMap< KeyType, ValueType, HashFn, KeyEqual, Allocator, ShardBits, Atom, Mutex >::assign_if_equal(), folly::detail::ConcurrentHashMapSegment< KeyType, ValueType, ShardBits, HashFn, KeyEqual, Allocator, Atom, Mutex >::assign_if_equal(), folly::dynamic::at(), BENCHMARK(), benchmarkSet(), detail::bmHasher(), check_select64_default(), check_select64_haswell(), checkMaybeCoercedKeys(), codeSize_bracket_F14Node(), codeSize_bracket_F14Value(), codeSize_bracket_F14Vector(), codeSize_bracket_Std(), std::tr1::gtest_internal::Get< 9 >::ConstField(), folly::DynamicConverter< Token >::convert(), std::tr1::tuple< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9 >::CopyFrom(), folly::AtomicHashMap< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::emplace(), folly::AtomicHashArray< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::emplace(), std::tr1::gtest_internal::SameSizeTuplePrefixComparator< k, k >::Eq(), folly::AtomicHashMap< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::find(), folly::detail::ConcurrentHashMapSegment< KeyType, ValueType, ShardBits, HashFn, KeyEqual, Allocator, Atom, Mutex >::find(), folly::AtomicHashMap< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::findInternal(), std::tr1::get(), folly::dynamic::get_ptr(), folly::dynamic::getDefault(), testing::gmock_generated_actions_test::GiantTemplate< T1, T2, T3, k4, k5, k6, T7, T8, T9 >::GiantTemplate(), testing::GTEST_CONCAT_TOKEN_(), folly::ConcurrentHashMap< KeyType, ValueType, HashFn, KeyEqual, Allocator, ShardBits, Atom, Mutex >::insert(), folly::AtomicHashMap< int64_t, int64_t >::insert(), folly::detail::ConcurrentHashMapSegment< KeyType, ValueType, ShardBits, HashFn, KeyEqual, Allocator, Atom, Mutex >::insert(), folly::detail::ConcurrentHashMapSegment< KeyType, ValueType, ShardBits, HashFn, KeyEqual, Allocator, Atom, Mutex >::insert_internal(), folly::ConcurrentHashMap< KeyType, ValueType, HashFn, KeyEqual, Allocator, ShardBits, Atom, Mutex >::insert_or_assign(), folly::detail::ConcurrentHashMapSegment< KeyType, ValueType, ShardBits, HashFn, KeyEqual, Allocator, Atom, Mutex >::insert_or_assign(), testing::InvokeArgument(), testing::internal::invoke_argument::InvokeArgumentAdl(), folly::AtomicHashArray< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn >::keyToAnchorIdx(), main(), testing::gmock_generated_function_mockers_test::MockFoo::MockFoo(), folly::detail::FingerprintPolynomial< BITS-1 >::mulXkmod(), folly::AsciiCaseInsensitive::operator()(), folly::F14VectorSet< Key, Hasher, KeyEqual, Alloc >::operator=(), folly::dynamic::operator[](), folly::DynamicParser::ParserStack::ParserStack(), testing::internal::InvokeMethodAction< Class, MethodPtr >::Perform(), testing::gmock_generated_actions_test::SubstractAction::Perform(), folly::ConcurrentHashMap< KeyType, ValueType, HashFn, KeyEqual, Allocator, ShardBits, Atom, Mutex >::pickSegment(), folly::DynamicParser::ParserStack::push(), folly::detail::ConcurrentHashMapSegment< KeyType, ValueType, ShardBits, HashFn, KeyEqual, Allocator, Atom, Mutex >::rehash(), folly::ConcurrentSkipList< T, Comp, NodeAlloc, MAX_HEIGHT >::remove(), folly::futures::detail::retrying(), Random::Rot64(), folly::hash::SpookyHashV1::Rot64(), folly::hash::SpookyHashV2::Rot64(), runInThreadsAndWait(), runSingleInsert(), folly::select64< compression::instructions::Haswell >(), folly::dynamic::setDefault(), testing::gmock_generated_actions_test::TenArgConstructorClass::TenArgConstructorClass(), folly::test::TEST(), TEST(), folly::detail::TEST_F(), TEST_F(), TestAlignment(), TestDeltas(), folly::ConcurrentHashMap< KeyType, ValueType, HashFn, KeyEqual, Allocator, ShardBits, Atom, Mutex >::try_emplace(), folly::detail::ConcurrentHashMapSegment< KeyType, ValueType, ShardBits, HashFn, KeyEqual, Allocator, Atom, Mutex >::try_emplace(), folly::detail::concurrenthashmap::ValueHolder< KeyType, ValueType, Allocator, std::enable_if_t< !std::is_nothrow_copy_constructible< ValueType >::value||!std::is_nothrow_copy_constructible< KeyType >::value > >::ValueHolder(), and testing::gmock_generated_function_mockers_test::FooInterface::~FooInterface().

const double LF = FLAGS_maxLoadFactor / FLAGS_targetLoadFactor

Definition at line 42 of file AtomicHashMapTest.cpp.

Referenced by BENCHMARK().

const int maxBMElements = int(FLAGS_numBMElements * LF)

Definition at line 43 of file AtomicHashMapTest.cpp.

Referenced by TEST().

QPAHMapT::Config qpConfig

Definition at line 108 of file AtomicHashMapTest.cpp.

Referenced by BENCHMARK(), and TEST().