raw_hash_set_test.cc 66 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180
  1. // Copyright 2018 The Abseil Authors.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // https://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #include "absl/container/internal/raw_hash_set.h"
  15. #include <atomic>
  16. #include <cmath>
  17. #include <cstdint>
  18. #include <deque>
  19. #include <functional>
  20. #include <memory>
  21. #include <numeric>
  22. #include <random>
  23. #include <string>
  24. #include <unordered_map>
  25. #include <unordered_set>
  26. #include "gmock/gmock.h"
  27. #include "gtest/gtest.h"
  28. #include "absl/base/attributes.h"
  29. #include "absl/base/config.h"
  30. #include "absl/base/internal/cycleclock.h"
  31. #include "absl/base/internal/raw_logging.h"
  32. #include "absl/container/internal/container_memory.h"
  33. #include "absl/container/internal/hash_function_defaults.h"
  34. #include "absl/container/internal/hash_policy_testing.h"
  35. #include "absl/container/internal/hashtable_debug.h"
  36. #include "absl/strings/string_view.h"
  37. namespace absl {
  38. ABSL_NAMESPACE_BEGIN
  39. namespace container_internal {
  40. struct RawHashSetTestOnlyAccess {
  41. template <typename C>
  42. static auto GetSlots(const C& c) -> decltype(c.slots_) {
  43. return c.slots_;
  44. }
  45. };
  46. namespace {
  47. using ::testing::ElementsAre;
  48. using ::testing::Eq;
  49. using ::testing::Ge;
  50. using ::testing::Lt;
  51. using ::testing::Pair;
  52. using ::testing::UnorderedElementsAre;
  53. // Convenience function to static cast to ctrl_t.
  54. ctrl_t CtrlT(int i) { return static_cast<ctrl_t>(i); }
  55. TEST(Util, NormalizeCapacity) {
  56. EXPECT_EQ(1, NormalizeCapacity(0));
  57. EXPECT_EQ(1, NormalizeCapacity(1));
  58. EXPECT_EQ(3, NormalizeCapacity(2));
  59. EXPECT_EQ(3, NormalizeCapacity(3));
  60. EXPECT_EQ(7, NormalizeCapacity(4));
  61. EXPECT_EQ(7, NormalizeCapacity(7));
  62. EXPECT_EQ(15, NormalizeCapacity(8));
  63. EXPECT_EQ(15, NormalizeCapacity(15));
  64. EXPECT_EQ(15 * 2 + 1, NormalizeCapacity(15 + 1));
  65. EXPECT_EQ(15 * 2 + 1, NormalizeCapacity(15 + 2));
  66. }
  67. TEST(Util, GrowthAndCapacity) {
  68. // Verify that GrowthToCapacity gives the minimum capacity that has enough
  69. // growth.
  70. for (size_t growth = 0; growth < 10000; ++growth) {
  71. SCOPED_TRACE(growth);
  72. size_t capacity = NormalizeCapacity(GrowthToLowerboundCapacity(growth));
  73. // The capacity is large enough for `growth`.
  74. EXPECT_THAT(CapacityToGrowth(capacity), Ge(growth));
  75. // For (capacity+1) < kWidth, growth should equal capacity.
  76. if (capacity + 1 < Group::kWidth) {
  77. EXPECT_THAT(CapacityToGrowth(capacity), Eq(capacity));
  78. } else {
  79. EXPECT_THAT(CapacityToGrowth(capacity), Lt(capacity));
  80. }
  81. if (growth != 0 && capacity > 1) {
  82. // There is no smaller capacity that works.
  83. EXPECT_THAT(CapacityToGrowth(capacity / 2), Lt(growth));
  84. }
  85. }
  86. for (size_t capacity = Group::kWidth - 1; capacity < 10000;
  87. capacity = 2 * capacity + 1) {
  88. SCOPED_TRACE(capacity);
  89. size_t growth = CapacityToGrowth(capacity);
  90. EXPECT_THAT(growth, Lt(capacity));
  91. EXPECT_LE(GrowthToLowerboundCapacity(growth), capacity);
  92. EXPECT_EQ(NormalizeCapacity(GrowthToLowerboundCapacity(growth)), capacity);
  93. }
  94. }
  95. TEST(Util, probe_seq) {
  96. probe_seq<16> seq(0, 127);
  97. auto gen = [&]() {
  98. size_t res = seq.offset();
  99. seq.next();
  100. return res;
  101. };
  102. std::vector<size_t> offsets(8);
  103. std::generate_n(offsets.begin(), 8, gen);
  104. EXPECT_THAT(offsets, ElementsAre(0, 16, 48, 96, 32, 112, 80, 64));
  105. seq = probe_seq<16>(128, 127);
  106. std::generate_n(offsets.begin(), 8, gen);
  107. EXPECT_THAT(offsets, ElementsAre(0, 16, 48, 96, 32, 112, 80, 64));
  108. }
  109. TEST(BitMask, Smoke) {
  110. EXPECT_FALSE((BitMask<uint8_t, 8>(0)));
  111. EXPECT_TRUE((BitMask<uint8_t, 8>(5)));
  112. EXPECT_THAT((BitMask<uint8_t, 8>(0)), ElementsAre());
  113. EXPECT_THAT((BitMask<uint8_t, 8>(0x1)), ElementsAre(0));
  114. EXPECT_THAT((BitMask<uint8_t, 8>(0x2)), ElementsAre(1));
  115. EXPECT_THAT((BitMask<uint8_t, 8>(0x3)), ElementsAre(0, 1));
  116. EXPECT_THAT((BitMask<uint8_t, 8>(0x4)), ElementsAre(2));
  117. EXPECT_THAT((BitMask<uint8_t, 8>(0x5)), ElementsAre(0, 2));
  118. EXPECT_THAT((BitMask<uint8_t, 8>(0x55)), ElementsAre(0, 2, 4, 6));
  119. EXPECT_THAT((BitMask<uint8_t, 8>(0xAA)), ElementsAre(1, 3, 5, 7));
  120. }
  121. TEST(BitMask, WithShift) {
  122. // See the non-SSE version of Group for details on what this math is for.
  123. uint64_t ctrl = 0x1716151413121110;
  124. uint64_t hash = 0x12;
  125. constexpr uint64_t msbs = 0x8080808080808080ULL;
  126. constexpr uint64_t lsbs = 0x0101010101010101ULL;
  127. auto x = ctrl ^ (lsbs * hash);
  128. uint64_t mask = (x - lsbs) & ~x & msbs;
  129. EXPECT_EQ(0x0000000080800000, mask);
  130. BitMask<uint64_t, 8, 3> b(mask);
  131. EXPECT_EQ(*b, 2);
  132. }
  133. TEST(BitMask, LeadingTrailing) {
  134. EXPECT_EQ((BitMask<uint32_t, 16>(0x00001a40).LeadingZeros()), 3);
  135. EXPECT_EQ((BitMask<uint32_t, 16>(0x00001a40).TrailingZeros()), 6);
  136. EXPECT_EQ((BitMask<uint32_t, 16>(0x00000001).LeadingZeros()), 15);
  137. EXPECT_EQ((BitMask<uint32_t, 16>(0x00000001).TrailingZeros()), 0);
  138. EXPECT_EQ((BitMask<uint32_t, 16>(0x00008000).LeadingZeros()), 0);
  139. EXPECT_EQ((BitMask<uint32_t, 16>(0x00008000).TrailingZeros()), 15);
  140. EXPECT_EQ((BitMask<uint64_t, 8, 3>(0x0000008080808000).LeadingZeros()), 3);
  141. EXPECT_EQ((BitMask<uint64_t, 8, 3>(0x0000008080808000).TrailingZeros()), 1);
  142. EXPECT_EQ((BitMask<uint64_t, 8, 3>(0x0000000000000080).LeadingZeros()), 7);
  143. EXPECT_EQ((BitMask<uint64_t, 8, 3>(0x0000000000000080).TrailingZeros()), 0);
  144. EXPECT_EQ((BitMask<uint64_t, 8, 3>(0x8000000000000000).LeadingZeros()), 0);
  145. EXPECT_EQ((BitMask<uint64_t, 8, 3>(0x8000000000000000).TrailingZeros()), 7);
  146. }
  147. TEST(Group, EmptyGroup) {
  148. for (h2_t h = 0; h != 128; ++h) EXPECT_FALSE(Group{EmptyGroup()}.Match(h));
  149. }
  150. TEST(Group, Match) {
  151. if (Group::kWidth == 16) {
  152. ctrl_t group[] = {ctrl_t::kEmpty, CtrlT(1), ctrl_t::kDeleted, CtrlT(3),
  153. ctrl_t::kEmpty, CtrlT(5), ctrl_t::kSentinel, CtrlT(7),
  154. CtrlT(7), CtrlT(5), CtrlT(3), CtrlT(1),
  155. CtrlT(1), CtrlT(1), CtrlT(1), CtrlT(1)};
  156. EXPECT_THAT(Group{group}.Match(0), ElementsAre());
  157. EXPECT_THAT(Group{group}.Match(1), ElementsAre(1, 11, 12, 13, 14, 15));
  158. EXPECT_THAT(Group{group}.Match(3), ElementsAre(3, 10));
  159. EXPECT_THAT(Group{group}.Match(5), ElementsAre(5, 9));
  160. EXPECT_THAT(Group{group}.Match(7), ElementsAre(7, 8));
  161. } else if (Group::kWidth == 8) {
  162. ctrl_t group[] = {ctrl_t::kEmpty, CtrlT(1), CtrlT(2),
  163. ctrl_t::kDeleted, CtrlT(2), CtrlT(1),
  164. ctrl_t::kSentinel, CtrlT(1)};
  165. EXPECT_THAT(Group{group}.Match(0), ElementsAre());
  166. EXPECT_THAT(Group{group}.Match(1), ElementsAre(1, 5, 7));
  167. EXPECT_THAT(Group{group}.Match(2), ElementsAre(2, 4));
  168. } else {
  169. FAIL() << "No test coverage for Group::kWidth==" << Group::kWidth;
  170. }
  171. }
  172. TEST(Group, MatchEmpty) {
  173. if (Group::kWidth == 16) {
  174. ctrl_t group[] = {ctrl_t::kEmpty, CtrlT(1), ctrl_t::kDeleted, CtrlT(3),
  175. ctrl_t::kEmpty, CtrlT(5), ctrl_t::kSentinel, CtrlT(7),
  176. CtrlT(7), CtrlT(5), CtrlT(3), CtrlT(1),
  177. CtrlT(1), CtrlT(1), CtrlT(1), CtrlT(1)};
  178. EXPECT_THAT(Group{group}.MatchEmpty(), ElementsAre(0, 4));
  179. } else if (Group::kWidth == 8) {
  180. ctrl_t group[] = {ctrl_t::kEmpty, CtrlT(1), CtrlT(2),
  181. ctrl_t::kDeleted, CtrlT(2), CtrlT(1),
  182. ctrl_t::kSentinel, CtrlT(1)};
  183. EXPECT_THAT(Group{group}.MatchEmpty(), ElementsAre(0));
  184. } else {
  185. FAIL() << "No test coverage for Group::kWidth==" << Group::kWidth;
  186. }
  187. }
  188. TEST(Group, MatchEmptyOrDeleted) {
  189. if (Group::kWidth == 16) {
  190. ctrl_t group[] = {ctrl_t::kEmpty, CtrlT(1), ctrl_t::kDeleted, CtrlT(3),
  191. ctrl_t::kEmpty, CtrlT(5), ctrl_t::kSentinel, CtrlT(7),
  192. CtrlT(7), CtrlT(5), CtrlT(3), CtrlT(1),
  193. CtrlT(1), CtrlT(1), CtrlT(1), CtrlT(1)};
  194. EXPECT_THAT(Group{group}.MatchEmptyOrDeleted(), ElementsAre(0, 2, 4));
  195. } else if (Group::kWidth == 8) {
  196. ctrl_t group[] = {ctrl_t::kEmpty, CtrlT(1), CtrlT(2),
  197. ctrl_t::kDeleted, CtrlT(2), CtrlT(1),
  198. ctrl_t::kSentinel, CtrlT(1)};
  199. EXPECT_THAT(Group{group}.MatchEmptyOrDeleted(), ElementsAre(0, 3));
  200. } else {
  201. FAIL() << "No test coverage for Group::kWidth==" << Group::kWidth;
  202. }
  203. }
  204. TEST(Batch, DropDeletes) {
  205. constexpr size_t kCapacity = 63;
  206. constexpr size_t kGroupWidth = container_internal::Group::kWidth;
  207. std::vector<ctrl_t> ctrl(kCapacity + 1 + kGroupWidth);
  208. ctrl[kCapacity] = ctrl_t::kSentinel;
  209. std::vector<ctrl_t> pattern = {
  210. ctrl_t::kEmpty, CtrlT(2), ctrl_t::kDeleted, CtrlT(2),
  211. ctrl_t::kEmpty, CtrlT(1), ctrl_t::kDeleted};
  212. for (size_t i = 0; i != kCapacity; ++i) {
  213. ctrl[i] = pattern[i % pattern.size()];
  214. if (i < kGroupWidth - 1)
  215. ctrl[i + kCapacity + 1] = pattern[i % pattern.size()];
  216. }
  217. ConvertDeletedToEmptyAndFullToDeleted(ctrl.data(), kCapacity);
  218. ASSERT_EQ(ctrl[kCapacity], ctrl_t::kSentinel);
  219. for (size_t i = 0; i < kCapacity + kGroupWidth; ++i) {
  220. ctrl_t expected = pattern[i % (kCapacity + 1) % pattern.size()];
  221. if (i == kCapacity) expected = ctrl_t::kSentinel;
  222. if (expected == ctrl_t::kDeleted) expected = ctrl_t::kEmpty;
  223. if (IsFull(expected)) expected = ctrl_t::kDeleted;
  224. EXPECT_EQ(ctrl[i], expected)
  225. << i << " " << static_cast<int>(pattern[i % pattern.size()]);
  226. }
  227. }
  228. TEST(Group, CountLeadingEmptyOrDeleted) {
  229. const std::vector<ctrl_t> empty_examples = {ctrl_t::kEmpty, ctrl_t::kDeleted};
  230. const std::vector<ctrl_t> full_examples = {
  231. CtrlT(0), CtrlT(1), CtrlT(2), CtrlT(3),
  232. CtrlT(5), CtrlT(9), CtrlT(127), ctrl_t::kSentinel};
  233. for (ctrl_t empty : empty_examples) {
  234. std::vector<ctrl_t> e(Group::kWidth, empty);
  235. EXPECT_EQ(Group::kWidth, Group{e.data()}.CountLeadingEmptyOrDeleted());
  236. for (ctrl_t full : full_examples) {
  237. for (size_t i = 0; i != Group::kWidth; ++i) {
  238. std::vector<ctrl_t> f(Group::kWidth, empty);
  239. f[i] = full;
  240. EXPECT_EQ(i, Group{f.data()}.CountLeadingEmptyOrDeleted());
  241. }
  242. std::vector<ctrl_t> f(Group::kWidth, empty);
  243. f[Group::kWidth * 2 / 3] = full;
  244. f[Group::kWidth / 2] = full;
  245. EXPECT_EQ(
  246. Group::kWidth / 2, Group{f.data()}.CountLeadingEmptyOrDeleted());
  247. }
  248. }
  249. }
  250. template <class T>
  251. struct ValuePolicy {
  252. using slot_type = T;
  253. using key_type = T;
  254. using init_type = T;
  255. template <class Allocator, class... Args>
  256. static void construct(Allocator* alloc, slot_type* slot, Args&&... args) {
  257. absl::allocator_traits<Allocator>::construct(*alloc, slot,
  258. std::forward<Args>(args)...);
  259. }
  260. template <class Allocator>
  261. static void destroy(Allocator* alloc, slot_type* slot) {
  262. absl::allocator_traits<Allocator>::destroy(*alloc, slot);
  263. }
  264. template <class Allocator>
  265. static void transfer(Allocator* alloc, slot_type* new_slot,
  266. slot_type* old_slot) {
  267. construct(alloc, new_slot, std::move(*old_slot));
  268. destroy(alloc, old_slot);
  269. }
  270. static T& element(slot_type* slot) { return *slot; }
  271. template <class F, class... Args>
  272. static decltype(absl::container_internal::DecomposeValue(
  273. std::declval<F>(), std::declval<Args>()...))
  274. apply(F&& f, Args&&... args) {
  275. return absl::container_internal::DecomposeValue(
  276. std::forward<F>(f), std::forward<Args>(args)...);
  277. }
  278. };
  279. using IntPolicy = ValuePolicy<int64_t>;
  280. using Uint8Policy = ValuePolicy<uint8_t>;
  281. class StringPolicy {
  282. template <class F, class K, class V,
  283. class = typename std::enable_if<
  284. std::is_convertible<const K&, absl::string_view>::value>::type>
  285. decltype(std::declval<F>()(
  286. std::declval<const absl::string_view&>(), std::piecewise_construct,
  287. std::declval<std::tuple<K>>(),
  288. std::declval<V>())) static apply_impl(F&& f,
  289. std::pair<std::tuple<K>, V> p) {
  290. const absl::string_view& key = std::get<0>(p.first);
  291. return std::forward<F>(f)(key, std::piecewise_construct, std::move(p.first),
  292. std::move(p.second));
  293. }
  294. public:
  295. struct slot_type {
  296. struct ctor {};
  297. template <class... Ts>
  298. slot_type(ctor, Ts&&... ts) : pair(std::forward<Ts>(ts)...) {}
  299. std::pair<std::string, std::string> pair;
  300. };
  301. using key_type = std::string;
  302. using init_type = std::pair<std::string, std::string>;
  303. template <class allocator_type, class... Args>
  304. static void construct(allocator_type* alloc, slot_type* slot, Args... args) {
  305. std::allocator_traits<allocator_type>::construct(
  306. *alloc, slot, typename slot_type::ctor(), std::forward<Args>(args)...);
  307. }
  308. template <class allocator_type>
  309. static void destroy(allocator_type* alloc, slot_type* slot) {
  310. std::allocator_traits<allocator_type>::destroy(*alloc, slot);
  311. }
  312. template <class allocator_type>
  313. static void transfer(allocator_type* alloc, slot_type* new_slot,
  314. slot_type* old_slot) {
  315. construct(alloc, new_slot, std::move(old_slot->pair));
  316. destroy(alloc, old_slot);
  317. }
  318. static std::pair<std::string, std::string>& element(slot_type* slot) {
  319. return slot->pair;
  320. }
  321. template <class F, class... Args>
  322. static auto apply(F&& f, Args&&... args)
  323. -> decltype(apply_impl(std::forward<F>(f),
  324. PairArgs(std::forward<Args>(args)...))) {
  325. return apply_impl(std::forward<F>(f),
  326. PairArgs(std::forward<Args>(args)...));
  327. }
  328. };
  329. struct StringHash : absl::Hash<absl::string_view> {
  330. using is_transparent = void;
  331. };
  332. struct StringEq : std::equal_to<absl::string_view> {
  333. using is_transparent = void;
  334. };
  335. struct StringTable
  336. : raw_hash_set<StringPolicy, StringHash, StringEq, std::allocator<int>> {
  337. using Base = typename StringTable::raw_hash_set;
  338. StringTable() {}
  339. using Base::Base;
  340. };
  341. struct IntTable
  342. : raw_hash_set<IntPolicy, container_internal::hash_default_hash<int64_t>,
  343. std::equal_to<int64_t>, std::allocator<int64_t>> {
  344. using Base = typename IntTable::raw_hash_set;
  345. using Base::Base;
  346. };
  347. struct Uint8Table
  348. : raw_hash_set<Uint8Policy, container_internal::hash_default_hash<uint8_t>,
  349. std::equal_to<uint8_t>, std::allocator<uint8_t>> {
  350. using Base = typename Uint8Table::raw_hash_set;
  351. using Base::Base;
  352. };
  353. template <typename T>
  354. struct CustomAlloc : std::allocator<T> {
  355. CustomAlloc() {}
  356. template <typename U>
  357. CustomAlloc(const CustomAlloc<U>& other) {}
  358. template<class U> struct rebind {
  359. using other = CustomAlloc<U>;
  360. };
  361. };
  362. struct CustomAllocIntTable
  363. : raw_hash_set<IntPolicy, container_internal::hash_default_hash<int64_t>,
  364. std::equal_to<int64_t>, CustomAlloc<int64_t>> {
  365. using Base = typename CustomAllocIntTable::raw_hash_set;
  366. using Base::Base;
  367. };
  368. struct BadFastHash {
  369. template <class T>
  370. size_t operator()(const T&) const {
  371. return 0;
  372. }
  373. };
  374. struct BadTable : raw_hash_set<IntPolicy, BadFastHash, std::equal_to<int>,
  375. std::allocator<int>> {
  376. using Base = typename BadTable::raw_hash_set;
  377. BadTable() {}
  378. using Base::Base;
  379. };
  380. TEST(Table, EmptyFunctorOptimization) {
  381. static_assert(std::is_empty<std::equal_to<absl::string_view>>::value, "");
  382. static_assert(std::is_empty<std::allocator<int>>::value, "");
  383. struct MockTable {
  384. void* ctrl;
  385. void* slots;
  386. size_t size;
  387. size_t capacity;
  388. size_t growth_left;
  389. void* infoz;
  390. };
  391. struct MockTableInfozDisabled {
  392. void* ctrl;
  393. void* slots;
  394. size_t size;
  395. size_t capacity;
  396. size_t growth_left;
  397. };
  398. struct StatelessHash {
  399. size_t operator()(absl::string_view) const { return 0; }
  400. };
  401. struct StatefulHash : StatelessHash {
  402. size_t dummy;
  403. };
  404. if (std::is_empty<HashtablezInfoHandle>::value) {
  405. EXPECT_EQ(sizeof(MockTableInfozDisabled),
  406. sizeof(raw_hash_set<StringPolicy, StatelessHash,
  407. std::equal_to<absl::string_view>,
  408. std::allocator<int>>));
  409. EXPECT_EQ(sizeof(MockTableInfozDisabled) + sizeof(StatefulHash),
  410. sizeof(raw_hash_set<StringPolicy, StatefulHash,
  411. std::equal_to<absl::string_view>,
  412. std::allocator<int>>));
  413. } else {
  414. EXPECT_EQ(sizeof(MockTable),
  415. sizeof(raw_hash_set<StringPolicy, StatelessHash,
  416. std::equal_to<absl::string_view>,
  417. std::allocator<int>>));
  418. EXPECT_EQ(sizeof(MockTable) + sizeof(StatefulHash),
  419. sizeof(raw_hash_set<StringPolicy, StatefulHash,
  420. std::equal_to<absl::string_view>,
  421. std::allocator<int>>));
  422. }
  423. }
  424. TEST(Table, Empty) {
  425. IntTable t;
  426. EXPECT_EQ(0, t.size());
  427. EXPECT_TRUE(t.empty());
  428. }
  429. TEST(Table, LookupEmpty) {
  430. IntTable t;
  431. auto it = t.find(0);
  432. EXPECT_TRUE(it == t.end());
  433. }
  434. TEST(Table, Insert1) {
  435. IntTable t;
  436. EXPECT_TRUE(t.find(0) == t.end());
  437. auto res = t.emplace(0);
  438. EXPECT_TRUE(res.second);
  439. EXPECT_THAT(*res.first, 0);
  440. EXPECT_EQ(1, t.size());
  441. EXPECT_THAT(*t.find(0), 0);
  442. }
  443. TEST(Table, Insert2) {
  444. IntTable t;
  445. EXPECT_TRUE(t.find(0) == t.end());
  446. auto res = t.emplace(0);
  447. EXPECT_TRUE(res.second);
  448. EXPECT_THAT(*res.first, 0);
  449. EXPECT_EQ(1, t.size());
  450. EXPECT_TRUE(t.find(1) == t.end());
  451. res = t.emplace(1);
  452. EXPECT_TRUE(res.second);
  453. EXPECT_THAT(*res.first, 1);
  454. EXPECT_EQ(2, t.size());
  455. EXPECT_THAT(*t.find(0), 0);
  456. EXPECT_THAT(*t.find(1), 1);
  457. }
  458. TEST(Table, InsertCollision) {
  459. BadTable t;
  460. EXPECT_TRUE(t.find(1) == t.end());
  461. auto res = t.emplace(1);
  462. EXPECT_TRUE(res.second);
  463. EXPECT_THAT(*res.first, 1);
  464. EXPECT_EQ(1, t.size());
  465. EXPECT_TRUE(t.find(2) == t.end());
  466. res = t.emplace(2);
  467. EXPECT_THAT(*res.first, 2);
  468. EXPECT_TRUE(res.second);
  469. EXPECT_EQ(2, t.size());
  470. EXPECT_THAT(*t.find(1), 1);
  471. EXPECT_THAT(*t.find(2), 2);
  472. }
  473. // Test that we do not add existent element in case we need to search through
  474. // many groups with deleted elements
  475. TEST(Table, InsertCollisionAndFindAfterDelete) {
  476. BadTable t; // all elements go to the same group.
  477. // Have at least 2 groups with Group::kWidth collisions
  478. // plus some extra collisions in the last group.
  479. constexpr size_t kNumInserts = Group::kWidth * 2 + 5;
  480. for (size_t i = 0; i < kNumInserts; ++i) {
  481. auto res = t.emplace(i);
  482. EXPECT_TRUE(res.second);
  483. EXPECT_THAT(*res.first, i);
  484. EXPECT_EQ(i + 1, t.size());
  485. }
  486. // Remove elements one by one and check
  487. // that we still can find all other elements.
  488. for (size_t i = 0; i < kNumInserts; ++i) {
  489. EXPECT_EQ(1, t.erase(i)) << i;
  490. for (size_t j = i + 1; j < kNumInserts; ++j) {
  491. EXPECT_THAT(*t.find(j), j);
  492. auto res = t.emplace(j);
  493. EXPECT_FALSE(res.second) << i << " " << j;
  494. EXPECT_THAT(*res.first, j);
  495. EXPECT_EQ(kNumInserts - i - 1, t.size());
  496. }
  497. }
  498. EXPECT_TRUE(t.empty());
  499. }
  500. TEST(Table, InsertWithinCapacity) {
  501. IntTable t;
  502. t.reserve(10);
  503. const size_t original_capacity = t.capacity();
  504. const auto addr = [&](int i) {
  505. return reinterpret_cast<uintptr_t>(&*t.find(i));
  506. };
  507. // Inserting an element does not change capacity.
  508. t.insert(0);
  509. EXPECT_THAT(t.capacity(), original_capacity);
  510. const uintptr_t original_addr_0 = addr(0);
  511. // Inserting another element does not rehash.
  512. t.insert(1);
  513. EXPECT_THAT(t.capacity(), original_capacity);
  514. EXPECT_THAT(addr(0), original_addr_0);
  515. // Inserting lots of duplicate elements does not rehash.
  516. for (int i = 0; i < 100; ++i) {
  517. t.insert(i % 10);
  518. }
  519. EXPECT_THAT(t.capacity(), original_capacity);
  520. EXPECT_THAT(addr(0), original_addr_0);
  521. // Inserting a range of duplicate elements does not rehash.
  522. std::vector<int> dup_range;
  523. for (int i = 0; i < 100; ++i) {
  524. dup_range.push_back(i % 10);
  525. }
  526. t.insert(dup_range.begin(), dup_range.end());
  527. EXPECT_THAT(t.capacity(), original_capacity);
  528. EXPECT_THAT(addr(0), original_addr_0);
  529. }
  530. TEST(Table, LazyEmplace) {
  531. StringTable t;
  532. bool called = false;
  533. auto it = t.lazy_emplace("abc", [&](const StringTable::constructor& f) {
  534. called = true;
  535. f("abc", "ABC");
  536. });
  537. EXPECT_TRUE(called);
  538. EXPECT_THAT(*it, Pair("abc", "ABC"));
  539. called = false;
  540. it = t.lazy_emplace("abc", [&](const StringTable::constructor& f) {
  541. called = true;
  542. f("abc", "DEF");
  543. });
  544. EXPECT_FALSE(called);
  545. EXPECT_THAT(*it, Pair("abc", "ABC"));
  546. }
  547. TEST(Table, ContainsEmpty) {
  548. IntTable t;
  549. EXPECT_FALSE(t.contains(0));
  550. }
  551. TEST(Table, Contains1) {
  552. IntTable t;
  553. EXPECT_TRUE(t.insert(0).second);
  554. EXPECT_TRUE(t.contains(0));
  555. EXPECT_FALSE(t.contains(1));
  556. EXPECT_EQ(1, t.erase(0));
  557. EXPECT_FALSE(t.contains(0));
  558. }
  559. TEST(Table, Contains2) {
  560. IntTable t;
  561. EXPECT_TRUE(t.insert(0).second);
  562. EXPECT_TRUE(t.contains(0));
  563. EXPECT_FALSE(t.contains(1));
  564. t.clear();
  565. EXPECT_FALSE(t.contains(0));
  566. }
  567. int decompose_constructed;
  568. int decompose_copy_constructed;
  569. int decompose_copy_assigned;
  570. int decompose_move_constructed;
  571. int decompose_move_assigned;
  572. struct DecomposeType {
  573. DecomposeType(int i = 0) : i(i) { // NOLINT
  574. ++decompose_constructed;
  575. }
  576. explicit DecomposeType(const char* d) : DecomposeType(*d) {}
  577. DecomposeType(const DecomposeType& other) : i(other.i) {
  578. ++decompose_copy_constructed;
  579. }
  580. DecomposeType& operator=(const DecomposeType& other) {
  581. ++decompose_copy_assigned;
  582. i = other.i;
  583. return *this;
  584. }
  585. DecomposeType(DecomposeType&& other) : i(other.i) {
  586. ++decompose_move_constructed;
  587. }
  588. DecomposeType& operator=(DecomposeType&& other) {
  589. ++decompose_move_assigned;
  590. i = other.i;
  591. return *this;
  592. }
  593. int i;
  594. };
  595. struct DecomposeHash {
  596. using is_transparent = void;
  597. size_t operator()(const DecomposeType& a) const { return a.i; }
  598. size_t operator()(int a) const { return a; }
  599. size_t operator()(const char* a) const { return *a; }
  600. };
  601. struct DecomposeEq {
  602. using is_transparent = void;
  603. bool operator()(const DecomposeType& a, const DecomposeType& b) const {
  604. return a.i == b.i;
  605. }
  606. bool operator()(const DecomposeType& a, int b) const { return a.i == b; }
  607. bool operator()(const DecomposeType& a, const char* b) const {
  608. return a.i == *b;
  609. }
  610. };
  611. struct DecomposePolicy {
  612. using slot_type = DecomposeType;
  613. using key_type = DecomposeType;
  614. using init_type = DecomposeType;
  615. template <typename T>
  616. static void construct(void*, DecomposeType* slot, T&& v) {
  617. ::new (slot) DecomposeType(std::forward<T>(v));
  618. }
  619. static void destroy(void*, DecomposeType* slot) { slot->~DecomposeType(); }
  620. static DecomposeType& element(slot_type* slot) { return *slot; }
  621. template <class F, class T>
  622. static auto apply(F&& f, const T& x) -> decltype(std::forward<F>(f)(x, x)) {
  623. return std::forward<F>(f)(x, x);
  624. }
  625. };
  626. template <typename Hash, typename Eq>
  627. void TestDecompose(bool construct_three) {
  628. DecomposeType elem{0};
  629. const int one = 1;
  630. const char* three_p = "3";
  631. const auto& three = three_p;
  632. const int elem_vector_count = 256;
  633. std::vector<DecomposeType> elem_vector(elem_vector_count, DecomposeType{0});
  634. std::iota(elem_vector.begin(), elem_vector.end(), 0);
  635. using DecomposeSet =
  636. raw_hash_set<DecomposePolicy, Hash, Eq, std::allocator<int>>;
  637. DecomposeSet set1;
  638. decompose_constructed = 0;
  639. int expected_constructed = 0;
  640. EXPECT_EQ(expected_constructed, decompose_constructed);
  641. set1.insert(elem);
  642. EXPECT_EQ(expected_constructed, decompose_constructed);
  643. set1.insert(1);
  644. EXPECT_EQ(++expected_constructed, decompose_constructed);
  645. set1.emplace("3");
  646. EXPECT_EQ(++expected_constructed, decompose_constructed);
  647. EXPECT_EQ(expected_constructed, decompose_constructed);
  648. { // insert(T&&)
  649. set1.insert(1);
  650. EXPECT_EQ(expected_constructed, decompose_constructed);
  651. }
  652. { // insert(const T&)
  653. set1.insert(one);
  654. EXPECT_EQ(expected_constructed, decompose_constructed);
  655. }
  656. { // insert(hint, T&&)
  657. set1.insert(set1.begin(), 1);
  658. EXPECT_EQ(expected_constructed, decompose_constructed);
  659. }
  660. { // insert(hint, const T&)
  661. set1.insert(set1.begin(), one);
  662. EXPECT_EQ(expected_constructed, decompose_constructed);
  663. }
  664. { // emplace(...)
  665. set1.emplace(1);
  666. EXPECT_EQ(expected_constructed, decompose_constructed);
  667. set1.emplace("3");
  668. expected_constructed += construct_three;
  669. EXPECT_EQ(expected_constructed, decompose_constructed);
  670. set1.emplace(one);
  671. EXPECT_EQ(expected_constructed, decompose_constructed);
  672. set1.emplace(three);
  673. expected_constructed += construct_three;
  674. EXPECT_EQ(expected_constructed, decompose_constructed);
  675. }
  676. { // emplace_hint(...)
  677. set1.emplace_hint(set1.begin(), 1);
  678. EXPECT_EQ(expected_constructed, decompose_constructed);
  679. set1.emplace_hint(set1.begin(), "3");
  680. expected_constructed += construct_three;
  681. EXPECT_EQ(expected_constructed, decompose_constructed);
  682. set1.emplace_hint(set1.begin(), one);
  683. EXPECT_EQ(expected_constructed, decompose_constructed);
  684. set1.emplace_hint(set1.begin(), three);
  685. expected_constructed += construct_three;
  686. EXPECT_EQ(expected_constructed, decompose_constructed);
  687. }
  688. decompose_copy_constructed = 0;
  689. decompose_copy_assigned = 0;
  690. decompose_move_constructed = 0;
  691. decompose_move_assigned = 0;
  692. int expected_copy_constructed = 0;
  693. int expected_move_constructed = 0;
  694. { // raw_hash_set(first, last) with random-access iterators
  695. DecomposeSet set2(elem_vector.begin(), elem_vector.end());
  696. // Expect exactly one copy-constructor call for each element if no
  697. // rehashing is done.
  698. expected_copy_constructed += elem_vector_count;
  699. EXPECT_EQ(expected_copy_constructed, decompose_copy_constructed);
  700. EXPECT_EQ(expected_move_constructed, decompose_move_constructed);
  701. EXPECT_EQ(0, decompose_move_assigned);
  702. EXPECT_EQ(0, decompose_copy_assigned);
  703. }
  704. { // raw_hash_set(first, last) with forward iterators
  705. std::list<DecomposeType> elem_list(elem_vector.begin(), elem_vector.end());
  706. expected_copy_constructed = decompose_copy_constructed;
  707. DecomposeSet set2(elem_list.begin(), elem_list.end());
  708. // Expect exactly N elements copied into set, expect at most 2*N elements
  709. // moving internally for all resizing needed (for a growth factor of 2).
  710. expected_copy_constructed += elem_vector_count;
  711. EXPECT_EQ(expected_copy_constructed, decompose_copy_constructed);
  712. expected_move_constructed += elem_vector_count;
  713. EXPECT_LT(expected_move_constructed, decompose_move_constructed);
  714. expected_move_constructed += elem_vector_count;
  715. EXPECT_GE(expected_move_constructed, decompose_move_constructed);
  716. EXPECT_EQ(0, decompose_move_assigned);
  717. EXPECT_EQ(0, decompose_copy_assigned);
  718. expected_copy_constructed = decompose_copy_constructed;
  719. expected_move_constructed = decompose_move_constructed;
  720. }
  721. { // insert(first, last)
  722. DecomposeSet set2;
  723. set2.insert(elem_vector.begin(), elem_vector.end());
  724. // Expect exactly N elements copied into set, expect at most 2*N elements
  725. // moving internally for all resizing needed (for a growth factor of 2).
  726. const int expected_new_elements = elem_vector_count;
  727. const int expected_max_element_moves = 2 * elem_vector_count;
  728. expected_copy_constructed += expected_new_elements;
  729. EXPECT_EQ(expected_copy_constructed, decompose_copy_constructed);
  730. expected_move_constructed += expected_max_element_moves;
  731. EXPECT_GE(expected_move_constructed, decompose_move_constructed);
  732. EXPECT_EQ(0, decompose_move_assigned);
  733. EXPECT_EQ(0, decompose_copy_assigned);
  734. expected_copy_constructed = decompose_copy_constructed;
  735. expected_move_constructed = decompose_move_constructed;
  736. }
  737. }
  738. TEST(Table, Decompose) {
  739. TestDecompose<DecomposeHash, DecomposeEq>(false);
  740. struct TransparentHashIntOverload {
  741. size_t operator()(const DecomposeType& a) const { return a.i; }
  742. size_t operator()(int a) const { return a; }
  743. };
  744. struct TransparentEqIntOverload {
  745. bool operator()(const DecomposeType& a, const DecomposeType& b) const {
  746. return a.i == b.i;
  747. }
  748. bool operator()(const DecomposeType& a, int b) const { return a.i == b; }
  749. };
  750. TestDecompose<TransparentHashIntOverload, DecomposeEq>(true);
  751. TestDecompose<TransparentHashIntOverload, TransparentEqIntOverload>(true);
  752. TestDecompose<DecomposeHash, TransparentEqIntOverload>(true);
  753. }
  754. // Returns the largest m such that a table with m elements has the same number
  755. // of buckets as a table with n elements.
  756. size_t MaxDensitySize(size_t n) {
  757. IntTable t;
  758. t.reserve(n);
  759. for (size_t i = 0; i != n; ++i) t.emplace(i);
  760. const size_t c = t.bucket_count();
  761. while (c == t.bucket_count()) t.emplace(n++);
  762. return t.size() - 1;
  763. }
  764. struct Modulo1000Hash {
  765. size_t operator()(int x) const { return x % 1000; }
  766. };
  767. struct Modulo1000HashTable
  768. : public raw_hash_set<IntPolicy, Modulo1000Hash, std::equal_to<int>,
  769. std::allocator<int>> {};
  770. // Test that rehash with no resize happen in case of many deleted slots.
  771. TEST(Table, RehashWithNoResize) {
  772. Modulo1000HashTable t;
  773. // Adding the same length (and the same hash) strings
  774. // to have at least kMinFullGroups groups
  775. // with Group::kWidth collisions. Then fill up to MaxDensitySize;
  776. const size_t kMinFullGroups = 7;
  777. std::vector<int> keys;
  778. for (size_t i = 0; i < MaxDensitySize(Group::kWidth * kMinFullGroups); ++i) {
  779. int k = i * 1000;
  780. t.emplace(k);
  781. keys.push_back(k);
  782. }
  783. const size_t capacity = t.capacity();
  784. // Remove elements from all groups except the first and the last one.
  785. // All elements removed from full groups will be marked as ctrl_t::kDeleted.
  786. const size_t erase_begin = Group::kWidth / 2;
  787. const size_t erase_end = (t.size() / Group::kWidth - 1) * Group::kWidth;
  788. for (size_t i = erase_begin; i < erase_end; ++i) {
  789. EXPECT_EQ(1, t.erase(keys[i])) << i;
  790. }
  791. keys.erase(keys.begin() + erase_begin, keys.begin() + erase_end);
  792. auto last_key = keys.back();
  793. size_t last_key_num_probes = GetHashtableDebugNumProbes(t, last_key);
  794. // Make sure that we have to make a lot of probes for last key.
  795. ASSERT_GT(last_key_num_probes, kMinFullGroups);
  796. int x = 1;
  797. // Insert and erase one element, before inplace rehash happen.
  798. while (last_key_num_probes == GetHashtableDebugNumProbes(t, last_key)) {
  799. t.emplace(x);
  800. ASSERT_EQ(capacity, t.capacity());
  801. // All elements should be there.
  802. ASSERT_TRUE(t.find(x) != t.end()) << x;
  803. for (const auto& k : keys) {
  804. ASSERT_TRUE(t.find(k) != t.end()) << k;
  805. }
  806. t.erase(x);
  807. ++x;
  808. }
  809. }
  810. TEST(Table, InsertEraseStressTest) {
  811. IntTable t;
  812. const size_t kMinElementCount = 250;
  813. std::deque<int> keys;
  814. size_t i = 0;
  815. for (; i < MaxDensitySize(kMinElementCount); ++i) {
  816. t.emplace(i);
  817. keys.push_back(i);
  818. }
  819. const size_t kNumIterations = 1000000;
  820. for (; i < kNumIterations; ++i) {
  821. ASSERT_EQ(1, t.erase(keys.front()));
  822. keys.pop_front();
  823. t.emplace(i);
  824. keys.push_back(i);
  825. }
  826. }
  827. TEST(Table, InsertOverloads) {
  828. StringTable t;
  829. // These should all trigger the insert(init_type) overload.
  830. t.insert({{}, {}});
  831. t.insert({"ABC", {}});
  832. t.insert({"DEF", "!!!"});
  833. EXPECT_THAT(t, UnorderedElementsAre(Pair("", ""), Pair("ABC", ""),
  834. Pair("DEF", "!!!")));
  835. }
  836. TEST(Table, LargeTable) {
  837. IntTable t;
  838. for (int64_t i = 0; i != 100000; ++i) t.emplace(i << 40);
  839. for (int64_t i = 0; i != 100000; ++i) ASSERT_EQ(i << 40, *t.find(i << 40));
  840. }
  841. // Timeout if copy is quadratic as it was in Rust.
  842. TEST(Table, EnsureNonQuadraticAsInRust) {
  843. static const size_t kLargeSize = 1 << 15;
  844. IntTable t;
  845. for (size_t i = 0; i != kLargeSize; ++i) {
  846. t.insert(i);
  847. }
  848. // If this is quadratic, the test will timeout.
  849. IntTable t2;
  850. for (const auto& entry : t) t2.insert(entry);
  851. }
  852. TEST(Table, ClearBug) {
  853. IntTable t;
  854. constexpr size_t capacity = container_internal::Group::kWidth - 1;
  855. constexpr size_t max_size = capacity / 2 + 1;
  856. for (size_t i = 0; i < max_size; ++i) {
  857. t.insert(i);
  858. }
  859. ASSERT_EQ(capacity, t.capacity());
  860. intptr_t original = reinterpret_cast<intptr_t>(&*t.find(2));
  861. t.clear();
  862. ASSERT_EQ(capacity, t.capacity());
  863. for (size_t i = 0; i < max_size; ++i) {
  864. t.insert(i);
  865. }
  866. ASSERT_EQ(capacity, t.capacity());
  867. intptr_t second = reinterpret_cast<intptr_t>(&*t.find(2));
  868. // We are checking that original and second are close enough to each other
  869. // that they are probably still in the same group. This is not strictly
  870. // guaranteed.
  871. EXPECT_LT(std::abs(original - second),
  872. capacity * sizeof(IntTable::value_type));
  873. }
  874. TEST(Table, Erase) {
  875. IntTable t;
  876. EXPECT_TRUE(t.find(0) == t.end());
  877. auto res = t.emplace(0);
  878. EXPECT_TRUE(res.second);
  879. EXPECT_EQ(1, t.size());
  880. t.erase(res.first);
  881. EXPECT_EQ(0, t.size());
  882. EXPECT_TRUE(t.find(0) == t.end());
  883. }
  884. TEST(Table, EraseMaintainsValidIterator) {
  885. IntTable t;
  886. const int kNumElements = 100;
  887. for (int i = 0; i < kNumElements; i ++) {
  888. EXPECT_TRUE(t.emplace(i).second);
  889. }
  890. EXPECT_EQ(t.size(), kNumElements);
  891. int num_erase_calls = 0;
  892. auto it = t.begin();
  893. while (it != t.end()) {
  894. t.erase(it++);
  895. num_erase_calls++;
  896. }
  897. EXPECT_TRUE(t.empty());
  898. EXPECT_EQ(num_erase_calls, kNumElements);
  899. }
  900. // Collect N bad keys by following algorithm:
  901. // 1. Create an empty table and reserve it to 2 * N.
  902. // 2. Insert N random elements.
  903. // 3. Take first Group::kWidth - 1 to bad_keys array.
  904. // 4. Clear the table without resize.
  905. // 5. Go to point 2 while N keys not collected
  906. std::vector<int64_t> CollectBadMergeKeys(size_t N) {
  907. static constexpr int kGroupSize = Group::kWidth - 1;
  908. auto topk_range = [](size_t b, size_t e,
  909. IntTable* t) -> std::vector<int64_t> {
  910. for (size_t i = b; i != e; ++i) {
  911. t->emplace(i);
  912. }
  913. std::vector<int64_t> res;
  914. res.reserve(kGroupSize);
  915. auto it = t->begin();
  916. for (size_t i = b; i != e && i != b + kGroupSize; ++i, ++it) {
  917. res.push_back(*it);
  918. }
  919. return res;
  920. };
  921. std::vector<int64_t> bad_keys;
  922. bad_keys.reserve(N);
  923. IntTable t;
  924. t.reserve(N * 2);
  925. for (size_t b = 0; bad_keys.size() < N; b += N) {
  926. auto keys = topk_range(b, b + N, &t);
  927. bad_keys.insert(bad_keys.end(), keys.begin(), keys.end());
  928. t.erase(t.begin(), t.end());
  929. EXPECT_TRUE(t.empty());
  930. }
  931. return bad_keys;
  932. }
  933. struct ProbeStats {
  934. // Number of elements with specific probe length over all tested tables.
  935. std::vector<size_t> all_probes_histogram;
  936. // Ratios total_probe_length/size for every tested table.
  937. std::vector<double> single_table_ratios;
  938. friend ProbeStats operator+(const ProbeStats& a, const ProbeStats& b) {
  939. ProbeStats res = a;
  940. res.all_probes_histogram.resize(std::max(res.all_probes_histogram.size(),
  941. b.all_probes_histogram.size()));
  942. std::transform(b.all_probes_histogram.begin(), b.all_probes_histogram.end(),
  943. res.all_probes_histogram.begin(),
  944. res.all_probes_histogram.begin(), std::plus<size_t>());
  945. res.single_table_ratios.insert(res.single_table_ratios.end(),
  946. b.single_table_ratios.begin(),
  947. b.single_table_ratios.end());
  948. return res;
  949. }
  950. // Average ratio total_probe_length/size over tables.
  951. double AvgRatio() const {
  952. return std::accumulate(single_table_ratios.begin(),
  953. single_table_ratios.end(), 0.0) /
  954. single_table_ratios.size();
  955. }
  956. // Maximum ratio total_probe_length/size over tables.
  957. double MaxRatio() const {
  958. return *std::max_element(single_table_ratios.begin(),
  959. single_table_ratios.end());
  960. }
  961. // Percentile ratio total_probe_length/size over tables.
  962. double PercentileRatio(double Percentile = 0.95) const {
  963. auto r = single_table_ratios;
  964. auto mid = r.begin() + static_cast<size_t>(r.size() * Percentile);
  965. if (mid != r.end()) {
  966. std::nth_element(r.begin(), mid, r.end());
  967. return *mid;
  968. } else {
  969. return MaxRatio();
  970. }
  971. }
  972. // Maximum probe length over all elements and all tables.
  973. size_t MaxProbe() const { return all_probes_histogram.size(); }
  974. // Fraction of elements with specified probe length.
  975. std::vector<double> ProbeNormalizedHistogram() const {
  976. double total_elements = std::accumulate(all_probes_histogram.begin(),
  977. all_probes_histogram.end(), 0ull);
  978. std::vector<double> res;
  979. for (size_t p : all_probes_histogram) {
  980. res.push_back(p / total_elements);
  981. }
  982. return res;
  983. }
  984. size_t PercentileProbe(double Percentile = 0.99) const {
  985. size_t idx = 0;
  986. for (double p : ProbeNormalizedHistogram()) {
  987. if (Percentile > p) {
  988. Percentile -= p;
  989. ++idx;
  990. } else {
  991. return idx;
  992. }
  993. }
  994. return idx;
  995. }
  996. friend std::ostream& operator<<(std::ostream& out, const ProbeStats& s) {
  997. out << "{AvgRatio:" << s.AvgRatio() << ", MaxRatio:" << s.MaxRatio()
  998. << ", PercentileRatio:" << s.PercentileRatio()
  999. << ", MaxProbe:" << s.MaxProbe() << ", Probes=[";
  1000. for (double p : s.ProbeNormalizedHistogram()) {
  1001. out << p << ",";
  1002. }
  1003. out << "]}";
  1004. return out;
  1005. }
  1006. };
  1007. struct ExpectedStats {
  1008. double avg_ratio;
  1009. double max_ratio;
  1010. std::vector<std::pair<double, double>> pecentile_ratios;
  1011. std::vector<std::pair<double, double>> pecentile_probes;
  1012. friend std::ostream& operator<<(std::ostream& out, const ExpectedStats& s) {
  1013. out << "{AvgRatio:" << s.avg_ratio << ", MaxRatio:" << s.max_ratio
  1014. << ", PercentileRatios: [";
  1015. for (auto el : s.pecentile_ratios) {
  1016. out << el.first << ":" << el.second << ", ";
  1017. }
  1018. out << "], PercentileProbes: [";
  1019. for (auto el : s.pecentile_probes) {
  1020. out << el.first << ":" << el.second << ", ";
  1021. }
  1022. out << "]}";
  1023. return out;
  1024. }
  1025. };
  1026. void VerifyStats(size_t size, const ExpectedStats& exp,
  1027. const ProbeStats& stats) {
  1028. EXPECT_LT(stats.AvgRatio(), exp.avg_ratio) << size << " " << stats;
  1029. EXPECT_LT(stats.MaxRatio(), exp.max_ratio) << size << " " << stats;
  1030. for (auto pr : exp.pecentile_ratios) {
  1031. EXPECT_LE(stats.PercentileRatio(pr.first), pr.second)
  1032. << size << " " << pr.first << " " << stats;
  1033. }
  1034. for (auto pr : exp.pecentile_probes) {
  1035. EXPECT_LE(stats.PercentileProbe(pr.first), pr.second)
  1036. << size << " " << pr.first << " " << stats;
  1037. }
  1038. }
  1039. using ProbeStatsPerSize = std::map<size_t, ProbeStats>;
  1040. // Collect total ProbeStats on num_iters iterations of the following algorithm:
  1041. // 1. Create new table and reserve it to keys.size() * 2
  1042. // 2. Insert all keys xored with seed
  1043. // 3. Collect ProbeStats from final table.
  1044. ProbeStats CollectProbeStatsOnKeysXoredWithSeed(
  1045. const std::vector<int64_t>& keys, size_t num_iters) {
  1046. const size_t reserve_size = keys.size() * 2;
  1047. ProbeStats stats;
  1048. int64_t seed = 0x71b1a19b907d6e33;
  1049. while (num_iters--) {
  1050. seed = static_cast<int64_t>(static_cast<uint64_t>(seed) * 17 + 13);
  1051. IntTable t1;
  1052. t1.reserve(reserve_size);
  1053. for (const auto& key : keys) {
  1054. t1.emplace(key ^ seed);
  1055. }
  1056. auto probe_histogram = GetHashtableDebugNumProbesHistogram(t1);
  1057. stats.all_probes_histogram.resize(
  1058. std::max(stats.all_probes_histogram.size(), probe_histogram.size()));
  1059. std::transform(probe_histogram.begin(), probe_histogram.end(),
  1060. stats.all_probes_histogram.begin(),
  1061. stats.all_probes_histogram.begin(), std::plus<size_t>());
  1062. size_t total_probe_seq_length = 0;
  1063. for (size_t i = 0; i < probe_histogram.size(); ++i) {
  1064. total_probe_seq_length += i * probe_histogram[i];
  1065. }
  1066. stats.single_table_ratios.push_back(total_probe_seq_length * 1.0 /
  1067. keys.size());
  1068. t1.erase(t1.begin(), t1.end());
  1069. }
  1070. return stats;
  1071. }
  1072. ExpectedStats XorSeedExpectedStats() {
  1073. constexpr bool kRandomizesInserts =
  1074. #ifdef NDEBUG
  1075. false;
  1076. #else // NDEBUG
  1077. true;
  1078. #endif // NDEBUG
  1079. // The effective load factor is larger in non-opt mode because we insert
  1080. // elements out of order.
  1081. switch (container_internal::Group::kWidth) {
  1082. case 8:
  1083. if (kRandomizesInserts) {
  1084. return {0.05,
  1085. 1.0,
  1086. {{0.95, 0.5}},
  1087. {{0.95, 0}, {0.99, 2}, {0.999, 4}, {0.9999, 10}}};
  1088. } else {
  1089. return {0.05,
  1090. 2.0,
  1091. {{0.95, 0.1}},
  1092. {{0.95, 0}, {0.99, 2}, {0.999, 4}, {0.9999, 10}}};
  1093. }
  1094. case 16:
  1095. if (kRandomizesInserts) {
  1096. return {0.1,
  1097. 1.0,
  1098. {{0.95, 0.1}},
  1099. {{0.95, 0}, {0.99, 1}, {0.999, 8}, {0.9999, 15}}};
  1100. } else {
  1101. return {0.05,
  1102. 1.0,
  1103. {{0.95, 0.05}},
  1104. {{0.95, 0}, {0.99, 1}, {0.999, 4}, {0.9999, 10}}};
  1105. }
  1106. }
  1107. ABSL_RAW_LOG(FATAL, "%s", "Unknown Group width");
  1108. return {};
  1109. }
  1110. TEST(Table, DISABLED_EnsureNonQuadraticTopNXorSeedByProbeSeqLength) {
  1111. ProbeStatsPerSize stats;
  1112. std::vector<size_t> sizes = {Group::kWidth << 5, Group::kWidth << 10};
  1113. for (size_t size : sizes) {
  1114. stats[size] =
  1115. CollectProbeStatsOnKeysXoredWithSeed(CollectBadMergeKeys(size), 200);
  1116. }
  1117. auto expected = XorSeedExpectedStats();
  1118. for (size_t size : sizes) {
  1119. auto& stat = stats[size];
  1120. VerifyStats(size, expected, stat);
  1121. }
  1122. }
  1123. // Collect total ProbeStats on num_iters iterations of the following algorithm:
  1124. // 1. Create new table
  1125. // 2. Select 10% of keys and insert 10 elements key * 17 + j * 13
  1126. // 3. Collect ProbeStats from final table
  1127. ProbeStats CollectProbeStatsOnLinearlyTransformedKeys(
  1128. const std::vector<int64_t>& keys, size_t num_iters) {
  1129. ProbeStats stats;
  1130. std::random_device rd;
  1131. std::mt19937 rng(rd());
  1132. auto linear_transform = [](size_t x, size_t y) { return x * 17 + y * 13; };
  1133. std::uniform_int_distribution<size_t> dist(0, keys.size()-1);
  1134. while (num_iters--) {
  1135. IntTable t1;
  1136. size_t num_keys = keys.size() / 10;
  1137. size_t start = dist(rng);
  1138. for (size_t i = 0; i != num_keys; ++i) {
  1139. for (size_t j = 0; j != 10; ++j) {
  1140. t1.emplace(linear_transform(keys[(i + start) % keys.size()], j));
  1141. }
  1142. }
  1143. auto probe_histogram = GetHashtableDebugNumProbesHistogram(t1);
  1144. stats.all_probes_histogram.resize(
  1145. std::max(stats.all_probes_histogram.size(), probe_histogram.size()));
  1146. std::transform(probe_histogram.begin(), probe_histogram.end(),
  1147. stats.all_probes_histogram.begin(),
  1148. stats.all_probes_histogram.begin(), std::plus<size_t>());
  1149. size_t total_probe_seq_length = 0;
  1150. for (size_t i = 0; i < probe_histogram.size(); ++i) {
  1151. total_probe_seq_length += i * probe_histogram[i];
  1152. }
  1153. stats.single_table_ratios.push_back(total_probe_seq_length * 1.0 /
  1154. t1.size());
  1155. t1.erase(t1.begin(), t1.end());
  1156. }
  1157. return stats;
  1158. }
  1159. ExpectedStats LinearTransformExpectedStats() {
  1160. constexpr bool kRandomizesInserts =
  1161. #ifdef NDEBUG
  1162. false;
  1163. #else // NDEBUG
  1164. true;
  1165. #endif // NDEBUG
  1166. // The effective load factor is larger in non-opt mode because we insert
  1167. // elements out of order.
  1168. switch (container_internal::Group::kWidth) {
  1169. case 8:
  1170. if (kRandomizesInserts) {
  1171. return {0.1,
  1172. 0.5,
  1173. {{0.95, 0.3}},
  1174. {{0.95, 0}, {0.99, 1}, {0.999, 8}, {0.9999, 15}}};
  1175. } else {
  1176. return {0.15,
  1177. 0.5,
  1178. {{0.95, 0.3}},
  1179. {{0.95, 0}, {0.99, 3}, {0.999, 15}, {0.9999, 25}}};
  1180. }
  1181. case 16:
  1182. if (kRandomizesInserts) {
  1183. return {0.1,
  1184. 0.4,
  1185. {{0.95, 0.3}},
  1186. {{0.95, 0}, {0.99, 1}, {0.999, 8}, {0.9999, 15}}};
  1187. } else {
  1188. return {0.05,
  1189. 0.2,
  1190. {{0.95, 0.1}},
  1191. {{0.95, 0}, {0.99, 1}, {0.999, 6}, {0.9999, 10}}};
  1192. }
  1193. }
  1194. ABSL_RAW_LOG(FATAL, "%s", "Unknown Group width");
  1195. return {};
  1196. }
  1197. TEST(Table, DISABLED_EnsureNonQuadraticTopNLinearTransformByProbeSeqLength) {
  1198. ProbeStatsPerSize stats;
  1199. std::vector<size_t> sizes = {Group::kWidth << 5, Group::kWidth << 10};
  1200. for (size_t size : sizes) {
  1201. stats[size] = CollectProbeStatsOnLinearlyTransformedKeys(
  1202. CollectBadMergeKeys(size), 300);
  1203. }
  1204. auto expected = LinearTransformExpectedStats();
  1205. for (size_t size : sizes) {
  1206. auto& stat = stats[size];
  1207. VerifyStats(size, expected, stat);
  1208. }
  1209. }
  1210. TEST(Table, EraseCollision) {
  1211. BadTable t;
  1212. // 1 2 3
  1213. t.emplace(1);
  1214. t.emplace(2);
  1215. t.emplace(3);
  1216. EXPECT_THAT(*t.find(1), 1);
  1217. EXPECT_THAT(*t.find(2), 2);
  1218. EXPECT_THAT(*t.find(3), 3);
  1219. EXPECT_EQ(3, t.size());
  1220. // 1 DELETED 3
  1221. t.erase(t.find(2));
  1222. EXPECT_THAT(*t.find(1), 1);
  1223. EXPECT_TRUE(t.find(2) == t.end());
  1224. EXPECT_THAT(*t.find(3), 3);
  1225. EXPECT_EQ(2, t.size());
  1226. // DELETED DELETED 3
  1227. t.erase(t.find(1));
  1228. EXPECT_TRUE(t.find(1) == t.end());
  1229. EXPECT_TRUE(t.find(2) == t.end());
  1230. EXPECT_THAT(*t.find(3), 3);
  1231. EXPECT_EQ(1, t.size());
  1232. // DELETED DELETED DELETED
  1233. t.erase(t.find(3));
  1234. EXPECT_TRUE(t.find(1) == t.end());
  1235. EXPECT_TRUE(t.find(2) == t.end());
  1236. EXPECT_TRUE(t.find(3) == t.end());
  1237. EXPECT_EQ(0, t.size());
  1238. }
  1239. TEST(Table, EraseInsertProbing) {
  1240. BadTable t(100);
  1241. // 1 2 3 4
  1242. t.emplace(1);
  1243. t.emplace(2);
  1244. t.emplace(3);
  1245. t.emplace(4);
  1246. // 1 DELETED 3 DELETED
  1247. t.erase(t.find(2));
  1248. t.erase(t.find(4));
  1249. // 1 10 3 11 12
  1250. t.emplace(10);
  1251. t.emplace(11);
  1252. t.emplace(12);
  1253. EXPECT_EQ(5, t.size());
  1254. EXPECT_THAT(t, UnorderedElementsAre(1, 10, 3, 11, 12));
  1255. }
  1256. TEST(Table, Clear) {
  1257. IntTable t;
  1258. EXPECT_TRUE(t.find(0) == t.end());
  1259. t.clear();
  1260. EXPECT_TRUE(t.find(0) == t.end());
  1261. auto res = t.emplace(0);
  1262. EXPECT_TRUE(res.second);
  1263. EXPECT_EQ(1, t.size());
  1264. t.clear();
  1265. EXPECT_EQ(0, t.size());
  1266. EXPECT_TRUE(t.find(0) == t.end());
  1267. }
  1268. TEST(Table, Swap) {
  1269. IntTable t;
  1270. EXPECT_TRUE(t.find(0) == t.end());
  1271. auto res = t.emplace(0);
  1272. EXPECT_TRUE(res.second);
  1273. EXPECT_EQ(1, t.size());
  1274. IntTable u;
  1275. t.swap(u);
  1276. EXPECT_EQ(0, t.size());
  1277. EXPECT_EQ(1, u.size());
  1278. EXPECT_TRUE(t.find(0) == t.end());
  1279. EXPECT_THAT(*u.find(0), 0);
  1280. }
  1281. TEST(Table, Rehash) {
  1282. IntTable t;
  1283. EXPECT_TRUE(t.find(0) == t.end());
  1284. t.emplace(0);
  1285. t.emplace(1);
  1286. EXPECT_EQ(2, t.size());
  1287. t.rehash(128);
  1288. EXPECT_EQ(2, t.size());
  1289. EXPECT_THAT(*t.find(0), 0);
  1290. EXPECT_THAT(*t.find(1), 1);
  1291. }
  1292. TEST(Table, RehashDoesNotRehashWhenNotNecessary) {
  1293. IntTable t;
  1294. t.emplace(0);
  1295. t.emplace(1);
  1296. auto* p = &*t.find(0);
  1297. t.rehash(1);
  1298. EXPECT_EQ(p, &*t.find(0));
  1299. }
  1300. TEST(Table, RehashZeroDoesNotAllocateOnEmptyTable) {
  1301. IntTable t;
  1302. t.rehash(0);
  1303. EXPECT_EQ(0, t.bucket_count());
  1304. }
  1305. TEST(Table, RehashZeroDeallocatesEmptyTable) {
  1306. IntTable t;
  1307. t.emplace(0);
  1308. t.clear();
  1309. EXPECT_NE(0, t.bucket_count());
  1310. t.rehash(0);
  1311. EXPECT_EQ(0, t.bucket_count());
  1312. }
  1313. TEST(Table, RehashZeroForcesRehash) {
  1314. IntTable t;
  1315. t.emplace(0);
  1316. t.emplace(1);
  1317. auto* p = &*t.find(0);
  1318. t.rehash(0);
  1319. EXPECT_NE(p, &*t.find(0));
  1320. }
  1321. TEST(Table, ConstructFromInitList) {
  1322. using P = std::pair<std::string, std::string>;
  1323. struct Q {
  1324. operator P() const { return {}; }
  1325. };
  1326. StringTable t = {P(), Q(), {}, {{}, {}}};
  1327. }
  1328. TEST(Table, CopyConstruct) {
  1329. IntTable t;
  1330. t.emplace(0);
  1331. EXPECT_EQ(1, t.size());
  1332. {
  1333. IntTable u(t);
  1334. EXPECT_EQ(1, u.size());
  1335. EXPECT_THAT(*u.find(0), 0);
  1336. }
  1337. {
  1338. IntTable u{t};
  1339. EXPECT_EQ(1, u.size());
  1340. EXPECT_THAT(*u.find(0), 0);
  1341. }
  1342. {
  1343. IntTable u = t;
  1344. EXPECT_EQ(1, u.size());
  1345. EXPECT_THAT(*u.find(0), 0);
  1346. }
  1347. }
  1348. TEST(Table, CopyConstructWithAlloc) {
  1349. StringTable t;
  1350. t.emplace("a", "b");
  1351. EXPECT_EQ(1, t.size());
  1352. StringTable u(t, Alloc<std::pair<std::string, std::string>>());
  1353. EXPECT_EQ(1, u.size());
  1354. EXPECT_THAT(*u.find("a"), Pair("a", "b"));
  1355. }
  1356. struct ExplicitAllocIntTable
  1357. : raw_hash_set<IntPolicy, container_internal::hash_default_hash<int64_t>,
  1358. std::equal_to<int64_t>, Alloc<int64_t>> {
  1359. ExplicitAllocIntTable() {}
  1360. };
  1361. TEST(Table, AllocWithExplicitCtor) {
  1362. ExplicitAllocIntTable t;
  1363. EXPECT_EQ(0, t.size());
  1364. }
  1365. TEST(Table, MoveConstruct) {
  1366. {
  1367. StringTable t;
  1368. t.emplace("a", "b");
  1369. EXPECT_EQ(1, t.size());
  1370. StringTable u(std::move(t));
  1371. EXPECT_EQ(1, u.size());
  1372. EXPECT_THAT(*u.find("a"), Pair("a", "b"));
  1373. }
  1374. {
  1375. StringTable t;
  1376. t.emplace("a", "b");
  1377. EXPECT_EQ(1, t.size());
  1378. StringTable u{std::move(t)};
  1379. EXPECT_EQ(1, u.size());
  1380. EXPECT_THAT(*u.find("a"), Pair("a", "b"));
  1381. }
  1382. {
  1383. StringTable t;
  1384. t.emplace("a", "b");
  1385. EXPECT_EQ(1, t.size());
  1386. StringTable u = std::move(t);
  1387. EXPECT_EQ(1, u.size());
  1388. EXPECT_THAT(*u.find("a"), Pair("a", "b"));
  1389. }
  1390. }
  1391. TEST(Table, MoveConstructWithAlloc) {
  1392. StringTable t;
  1393. t.emplace("a", "b");
  1394. EXPECT_EQ(1, t.size());
  1395. StringTable u(std::move(t), Alloc<std::pair<std::string, std::string>>());
  1396. EXPECT_EQ(1, u.size());
  1397. EXPECT_THAT(*u.find("a"), Pair("a", "b"));
  1398. }
  1399. TEST(Table, CopyAssign) {
  1400. StringTable t;
  1401. t.emplace("a", "b");
  1402. EXPECT_EQ(1, t.size());
  1403. StringTable u;
  1404. u = t;
  1405. EXPECT_EQ(1, u.size());
  1406. EXPECT_THAT(*u.find("a"), Pair("a", "b"));
  1407. }
  1408. TEST(Table, CopySelfAssign) {
  1409. StringTable t;
  1410. t.emplace("a", "b");
  1411. EXPECT_EQ(1, t.size());
  1412. t = *&t;
  1413. EXPECT_EQ(1, t.size());
  1414. EXPECT_THAT(*t.find("a"), Pair("a", "b"));
  1415. }
  1416. TEST(Table, MoveAssign) {
  1417. StringTable t;
  1418. t.emplace("a", "b");
  1419. EXPECT_EQ(1, t.size());
  1420. StringTable u;
  1421. u = std::move(t);
  1422. EXPECT_EQ(1, u.size());
  1423. EXPECT_THAT(*u.find("a"), Pair("a", "b"));
  1424. }
  1425. TEST(Table, Equality) {
  1426. StringTable t;
  1427. std::vector<std::pair<std::string, std::string>> v = {{"a", "b"},
  1428. {"aa", "bb"}};
  1429. t.insert(std::begin(v), std::end(v));
  1430. StringTable u = t;
  1431. EXPECT_EQ(u, t);
  1432. }
  1433. TEST(Table, Equality2) {
  1434. StringTable t;
  1435. std::vector<std::pair<std::string, std::string>> v1 = {{"a", "b"},
  1436. {"aa", "bb"}};
  1437. t.insert(std::begin(v1), std::end(v1));
  1438. StringTable u;
  1439. std::vector<std::pair<std::string, std::string>> v2 = {{"a", "a"},
  1440. {"aa", "aa"}};
  1441. u.insert(std::begin(v2), std::end(v2));
  1442. EXPECT_NE(u, t);
  1443. }
  1444. TEST(Table, Equality3) {
  1445. StringTable t;
  1446. std::vector<std::pair<std::string, std::string>> v1 = {{"b", "b"},
  1447. {"bb", "bb"}};
  1448. t.insert(std::begin(v1), std::end(v1));
  1449. StringTable u;
  1450. std::vector<std::pair<std::string, std::string>> v2 = {{"a", "a"},
  1451. {"aa", "aa"}};
  1452. u.insert(std::begin(v2), std::end(v2));
  1453. EXPECT_NE(u, t);
  1454. }
  1455. TEST(Table, NumDeletedRegression) {
  1456. IntTable t;
  1457. t.emplace(0);
  1458. t.erase(t.find(0));
  1459. // construct over a deleted slot.
  1460. t.emplace(0);
  1461. t.clear();
  1462. }
  1463. TEST(Table, FindFullDeletedRegression) {
  1464. IntTable t;
  1465. for (int i = 0; i < 1000; ++i) {
  1466. t.emplace(i);
  1467. t.erase(t.find(i));
  1468. }
  1469. EXPECT_EQ(0, t.size());
  1470. }
  1471. TEST(Table, ReplacingDeletedSlotDoesNotRehash) {
  1472. size_t n;
  1473. {
  1474. // Compute n such that n is the maximum number of elements before rehash.
  1475. IntTable t;
  1476. t.emplace(0);
  1477. size_t c = t.bucket_count();
  1478. for (n = 1; c == t.bucket_count(); ++n) t.emplace(n);
  1479. --n;
  1480. }
  1481. IntTable t;
  1482. t.rehash(n);
  1483. const size_t c = t.bucket_count();
  1484. for (size_t i = 0; i != n; ++i) t.emplace(i);
  1485. EXPECT_EQ(c, t.bucket_count()) << "rehashing threshold = " << n;
  1486. t.erase(0);
  1487. t.emplace(0);
  1488. EXPECT_EQ(c, t.bucket_count()) << "rehashing threshold = " << n;
  1489. }
  1490. TEST(Table, NoThrowMoveConstruct) {
  1491. ASSERT_TRUE(
  1492. std::is_nothrow_copy_constructible<absl::Hash<absl::string_view>>::value);
  1493. ASSERT_TRUE(std::is_nothrow_copy_constructible<
  1494. std::equal_to<absl::string_view>>::value);
  1495. ASSERT_TRUE(std::is_nothrow_copy_constructible<std::allocator<int>>::value);
  1496. EXPECT_TRUE(std::is_nothrow_move_constructible<StringTable>::value);
  1497. }
  1498. TEST(Table, NoThrowMoveAssign) {
  1499. ASSERT_TRUE(
  1500. std::is_nothrow_move_assignable<absl::Hash<absl::string_view>>::value);
  1501. ASSERT_TRUE(
  1502. std::is_nothrow_move_assignable<std::equal_to<absl::string_view>>::value);
  1503. ASSERT_TRUE(std::is_nothrow_move_assignable<std::allocator<int>>::value);
  1504. ASSERT_TRUE(
  1505. absl::allocator_traits<std::allocator<int>>::is_always_equal::value);
  1506. EXPECT_TRUE(std::is_nothrow_move_assignable<StringTable>::value);
  1507. }
  1508. TEST(Table, NoThrowSwappable) {
  1509. ASSERT_TRUE(
  1510. container_internal::IsNoThrowSwappable<absl::Hash<absl::string_view>>());
  1511. ASSERT_TRUE(container_internal::IsNoThrowSwappable<
  1512. std::equal_to<absl::string_view>>());
  1513. ASSERT_TRUE(container_internal::IsNoThrowSwappable<std::allocator<int>>());
  1514. EXPECT_TRUE(container_internal::IsNoThrowSwappable<StringTable>());
  1515. }
  1516. TEST(Table, HeterogeneousLookup) {
  1517. struct Hash {
  1518. size_t operator()(int64_t i) const { return i; }
  1519. size_t operator()(double i) const {
  1520. ADD_FAILURE();
  1521. return i;
  1522. }
  1523. };
  1524. struct Eq {
  1525. bool operator()(int64_t a, int64_t b) const { return a == b; }
  1526. bool operator()(double a, int64_t b) const {
  1527. ADD_FAILURE();
  1528. return a == b;
  1529. }
  1530. bool operator()(int64_t a, double b) const {
  1531. ADD_FAILURE();
  1532. return a == b;
  1533. }
  1534. bool operator()(double a, double b) const {
  1535. ADD_FAILURE();
  1536. return a == b;
  1537. }
  1538. };
  1539. struct THash {
  1540. using is_transparent = void;
  1541. size_t operator()(int64_t i) const { return i; }
  1542. size_t operator()(double i) const { return i; }
  1543. };
  1544. struct TEq {
  1545. using is_transparent = void;
  1546. bool operator()(int64_t a, int64_t b) const { return a == b; }
  1547. bool operator()(double a, int64_t b) const { return a == b; }
  1548. bool operator()(int64_t a, double b) const { return a == b; }
  1549. bool operator()(double a, double b) const { return a == b; }
  1550. };
  1551. raw_hash_set<IntPolicy, Hash, Eq, Alloc<int64_t>> s{0, 1, 2};
  1552. // It will convert to int64_t before the query.
  1553. EXPECT_EQ(1, *s.find(double{1.1}));
  1554. raw_hash_set<IntPolicy, THash, TEq, Alloc<int64_t>> ts{0, 1, 2};
  1555. // It will try to use the double, and fail to find the object.
  1556. EXPECT_TRUE(ts.find(1.1) == ts.end());
  1557. }
  1558. template <class Table>
  1559. using CallFind = decltype(std::declval<Table&>().find(17));
  1560. template <class Table>
  1561. using CallErase = decltype(std::declval<Table&>().erase(17));
  1562. template <class Table>
  1563. using CallExtract = decltype(std::declval<Table&>().extract(17));
  1564. template <class Table>
  1565. using CallPrefetch = decltype(std::declval<Table&>().prefetch(17));
  1566. template <class Table>
  1567. using CallCount = decltype(std::declval<Table&>().count(17));
  1568. template <template <typename> class C, class Table, class = void>
  1569. struct VerifyResultOf : std::false_type {};
  1570. template <template <typename> class C, class Table>
  1571. struct VerifyResultOf<C, Table, absl::void_t<C<Table>>> : std::true_type {};
  1572. TEST(Table, HeterogeneousLookupOverloads) {
  1573. using NonTransparentTable =
  1574. raw_hash_set<StringPolicy, absl::Hash<absl::string_view>,
  1575. std::equal_to<absl::string_view>, std::allocator<int>>;
  1576. EXPECT_FALSE((VerifyResultOf<CallFind, NonTransparentTable>()));
  1577. EXPECT_FALSE((VerifyResultOf<CallErase, NonTransparentTable>()));
  1578. EXPECT_FALSE((VerifyResultOf<CallExtract, NonTransparentTable>()));
  1579. EXPECT_FALSE((VerifyResultOf<CallPrefetch, NonTransparentTable>()));
  1580. EXPECT_FALSE((VerifyResultOf<CallCount, NonTransparentTable>()));
  1581. using TransparentTable = raw_hash_set<
  1582. StringPolicy,
  1583. absl::container_internal::hash_default_hash<absl::string_view>,
  1584. absl::container_internal::hash_default_eq<absl::string_view>,
  1585. std::allocator<int>>;
  1586. EXPECT_TRUE((VerifyResultOf<CallFind, TransparentTable>()));
  1587. EXPECT_TRUE((VerifyResultOf<CallErase, TransparentTable>()));
  1588. EXPECT_TRUE((VerifyResultOf<CallExtract, TransparentTable>()));
  1589. EXPECT_TRUE((VerifyResultOf<CallPrefetch, TransparentTable>()));
  1590. EXPECT_TRUE((VerifyResultOf<CallCount, TransparentTable>()));
  1591. }
  1592. // TODO(alkis): Expand iterator tests.
  1593. TEST(Iterator, IsDefaultConstructible) {
  1594. StringTable::iterator i;
  1595. EXPECT_TRUE(i == StringTable::iterator());
  1596. }
  1597. TEST(ConstIterator, IsDefaultConstructible) {
  1598. StringTable::const_iterator i;
  1599. EXPECT_TRUE(i == StringTable::const_iterator());
  1600. }
  1601. TEST(Iterator, ConvertsToConstIterator) {
  1602. StringTable::iterator i;
  1603. EXPECT_TRUE(i == StringTable::const_iterator());
  1604. }
  1605. TEST(Iterator, Iterates) {
  1606. IntTable t;
  1607. for (size_t i = 3; i != 6; ++i) EXPECT_TRUE(t.emplace(i).second);
  1608. EXPECT_THAT(t, UnorderedElementsAre(3, 4, 5));
  1609. }
  1610. TEST(Table, Merge) {
  1611. StringTable t1, t2;
  1612. t1.emplace("0", "-0");
  1613. t1.emplace("1", "-1");
  1614. t2.emplace("0", "~0");
  1615. t2.emplace("2", "~2");
  1616. EXPECT_THAT(t1, UnorderedElementsAre(Pair("0", "-0"), Pair("1", "-1")));
  1617. EXPECT_THAT(t2, UnorderedElementsAre(Pair("0", "~0"), Pair("2", "~2")));
  1618. t1.merge(t2);
  1619. EXPECT_THAT(t1, UnorderedElementsAre(Pair("0", "-0"), Pair("1", "-1"),
  1620. Pair("2", "~2")));
  1621. EXPECT_THAT(t2, UnorderedElementsAre(Pair("0", "~0")));
  1622. }
  1623. TEST(Table, IteratorEmplaceConstructibleRequirement) {
  1624. struct Value {
  1625. explicit Value(absl::string_view view) : value(view) {}
  1626. std::string value;
  1627. bool operator==(const Value& other) const { return value == other.value; }
  1628. };
  1629. struct H {
  1630. size_t operator()(const Value& v) const {
  1631. return absl::Hash<std::string>{}(v.value);
  1632. }
  1633. };
  1634. struct Table : raw_hash_set<ValuePolicy<Value>, H, std::equal_to<Value>,
  1635. std::allocator<Value>> {
  1636. using Base = typename Table::raw_hash_set;
  1637. using Base::Base;
  1638. };
  1639. std::string input[3]{"A", "B", "C"};
  1640. Table t(std::begin(input), std::end(input));
  1641. EXPECT_THAT(t, UnorderedElementsAre(Value{"A"}, Value{"B"}, Value{"C"}));
  1642. input[0] = "D";
  1643. input[1] = "E";
  1644. input[2] = "F";
  1645. t.insert(std::begin(input), std::end(input));
  1646. EXPECT_THAT(t, UnorderedElementsAre(Value{"A"}, Value{"B"}, Value{"C"},
  1647. Value{"D"}, Value{"E"}, Value{"F"}));
  1648. }
  1649. TEST(Nodes, EmptyNodeType) {
  1650. using node_type = StringTable::node_type;
  1651. node_type n;
  1652. EXPECT_FALSE(n);
  1653. EXPECT_TRUE(n.empty());
  1654. EXPECT_TRUE((std::is_same<node_type::allocator_type,
  1655. StringTable::allocator_type>::value));
  1656. }
  1657. TEST(Nodes, ExtractInsert) {
  1658. constexpr char k0[] = "Very long string zero.";
  1659. constexpr char k1[] = "Very long string one.";
  1660. constexpr char k2[] = "Very long string two.";
  1661. StringTable t = {{k0, ""}, {k1, ""}, {k2, ""}};
  1662. EXPECT_THAT(t,
  1663. UnorderedElementsAre(Pair(k0, ""), Pair(k1, ""), Pair(k2, "")));
  1664. auto node = t.extract(k0);
  1665. EXPECT_THAT(t, UnorderedElementsAre(Pair(k1, ""), Pair(k2, "")));
  1666. EXPECT_TRUE(node);
  1667. EXPECT_FALSE(node.empty());
  1668. StringTable t2;
  1669. StringTable::insert_return_type res = t2.insert(std::move(node));
  1670. EXPECT_TRUE(res.inserted);
  1671. EXPECT_THAT(*res.position, Pair(k0, ""));
  1672. EXPECT_FALSE(res.node);
  1673. EXPECT_THAT(t2, UnorderedElementsAre(Pair(k0, "")));
  1674. // Not there.
  1675. EXPECT_THAT(t, UnorderedElementsAre(Pair(k1, ""), Pair(k2, "")));
  1676. node = t.extract("Not there!");
  1677. EXPECT_THAT(t, UnorderedElementsAre(Pair(k1, ""), Pair(k2, "")));
  1678. EXPECT_FALSE(node);
  1679. // Inserting nothing.
  1680. res = t2.insert(std::move(node));
  1681. EXPECT_FALSE(res.inserted);
  1682. EXPECT_EQ(res.position, t2.end());
  1683. EXPECT_FALSE(res.node);
  1684. EXPECT_THAT(t2, UnorderedElementsAre(Pair(k0, "")));
  1685. t.emplace(k0, "1");
  1686. node = t.extract(k0);
  1687. // Insert duplicate.
  1688. res = t2.insert(std::move(node));
  1689. EXPECT_FALSE(res.inserted);
  1690. EXPECT_THAT(*res.position, Pair(k0, ""));
  1691. EXPECT_TRUE(res.node);
  1692. EXPECT_FALSE(node);
  1693. }
  1694. TEST(Nodes, HintInsert) {
  1695. IntTable t = {1, 2, 3};
  1696. auto node = t.extract(1);
  1697. EXPECT_THAT(t, UnorderedElementsAre(2, 3));
  1698. auto it = t.insert(t.begin(), std::move(node));
  1699. EXPECT_THAT(t, UnorderedElementsAre(1, 2, 3));
  1700. EXPECT_EQ(*it, 1);
  1701. EXPECT_FALSE(node);
  1702. node = t.extract(2);
  1703. EXPECT_THAT(t, UnorderedElementsAre(1, 3));
  1704. // reinsert 2 to make the next insert fail.
  1705. t.insert(2);
  1706. EXPECT_THAT(t, UnorderedElementsAre(1, 2, 3));
  1707. it = t.insert(t.begin(), std::move(node));
  1708. EXPECT_EQ(*it, 2);
  1709. // The node was not emptied by the insert call.
  1710. EXPECT_TRUE(node);
  1711. }
  1712. IntTable MakeSimpleTable(size_t size) {
  1713. IntTable t;
  1714. while (t.size() < size) t.insert(t.size());
  1715. return t;
  1716. }
  1717. std::vector<int> OrderOfIteration(const IntTable& t) {
  1718. return {t.begin(), t.end()};
  1719. }
  1720. // These IterationOrderChanges tests depend on non-deterministic behavior.
  1721. // We are injecting non-determinism from the pointer of the table, but do so in
  1722. // a way that only the page matters. We have to retry enough times to make sure
  1723. // we are touching different memory pages to cause the ordering to change.
  1724. // We also need to keep the old tables around to avoid getting the same memory
  1725. // blocks over and over.
  1726. TEST(Table, IterationOrderChangesByInstance) {
  1727. for (size_t size : {2, 6, 12, 20}) {
  1728. const auto reference_table = MakeSimpleTable(size);
  1729. const auto reference = OrderOfIteration(reference_table);
  1730. std::vector<IntTable> tables;
  1731. bool found_difference = false;
  1732. for (int i = 0; !found_difference && i < 5000; ++i) {
  1733. tables.push_back(MakeSimpleTable(size));
  1734. found_difference = OrderOfIteration(tables.back()) != reference;
  1735. }
  1736. if (!found_difference) {
  1737. FAIL()
  1738. << "Iteration order remained the same across many attempts with size "
  1739. << size;
  1740. }
  1741. }
  1742. }
  1743. TEST(Table, IterationOrderChangesOnRehash) {
  1744. std::vector<IntTable> garbage;
  1745. for (int i = 0; i < 5000; ++i) {
  1746. auto t = MakeSimpleTable(20);
  1747. const auto reference = OrderOfIteration(t);
  1748. // Force rehash to the same size.
  1749. t.rehash(0);
  1750. auto trial = OrderOfIteration(t);
  1751. if (trial != reference) {
  1752. // We are done.
  1753. return;
  1754. }
  1755. garbage.push_back(std::move(t));
  1756. }
  1757. FAIL() << "Iteration order remained the same across many attempts.";
  1758. }
  1759. // Verify that pointers are invalidated as soon as a second element is inserted.
  1760. // This prevents dependency on pointer stability on small tables.
  1761. TEST(Table, UnstablePointers) {
  1762. IntTable table;
  1763. const auto addr = [&](int i) {
  1764. return reinterpret_cast<uintptr_t>(&*table.find(i));
  1765. };
  1766. table.insert(0);
  1767. const uintptr_t old_ptr = addr(0);
  1768. // This causes a rehash.
  1769. table.insert(1);
  1770. EXPECT_NE(old_ptr, addr(0));
  1771. }
  1772. // Confirm that we assert if we try to erase() end().
  1773. TEST(TableDeathTest, EraseOfEndAsserts) {
  1774. // Use an assert with side-effects to figure out if they are actually enabled.
  1775. bool assert_enabled = false;
  1776. assert([&]() {
  1777. assert_enabled = true;
  1778. return true;
  1779. }());
  1780. if (!assert_enabled) return;
  1781. IntTable t;
  1782. // Extra simple "regexp" as regexp support is highly varied across platforms.
  1783. constexpr char kDeathMsg[] = "Invalid operation on iterator";
  1784. EXPECT_DEATH_IF_SUPPORTED(t.erase(t.end()), kDeathMsg);
  1785. }
  1786. #if defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE)
  1787. TEST(RawHashSamplerTest, Sample) {
  1788. // Enable the feature even if the prod default is off.
  1789. SetHashtablezEnabled(true);
  1790. SetHashtablezSampleParameter(100);
  1791. auto& sampler = GlobalHashtablezSampler();
  1792. size_t start_size = 0;
  1793. std::unordered_set<const HashtablezInfo*> preexisting_info;
  1794. start_size += sampler.Iterate([&](const HashtablezInfo& info) {
  1795. preexisting_info.insert(&info);
  1796. ++start_size;
  1797. });
  1798. std::vector<IntTable> tables;
  1799. for (int i = 0; i < 1000000; ++i) {
  1800. tables.emplace_back();
  1801. const bool do_reserve = (i % 10 > 5);
  1802. const bool do_rehash = !do_reserve && (i % 10 > 0);
  1803. if (do_reserve) {
  1804. // Don't reserve on all tables.
  1805. tables.back().reserve(10 * (i % 10));
  1806. }
  1807. tables.back().insert(1);
  1808. tables.back().insert(i % 5);
  1809. if (do_rehash) {
  1810. // Rehash some other tables.
  1811. tables.back().rehash(10 * (i % 10));
  1812. }
  1813. }
  1814. size_t end_size = 0;
  1815. std::unordered_map<size_t, int> observed_checksums;
  1816. std::unordered_map<ssize_t, int> reservations;
  1817. end_size += sampler.Iterate([&](const HashtablezInfo& info) {
  1818. if (preexisting_info.count(&info) == 0) {
  1819. observed_checksums[info.hashes_bitwise_xor.load(
  1820. std::memory_order_relaxed)]++;
  1821. reservations[info.max_reserve.load(std::memory_order_relaxed)]++;
  1822. }
  1823. EXPECT_EQ(info.inline_element_size, sizeof(int64_t));
  1824. ++end_size;
  1825. });
  1826. EXPECT_NEAR((end_size - start_size) / static_cast<double>(tables.size()),
  1827. 0.01, 0.005);
  1828. EXPECT_EQ(observed_checksums.size(), 5);
  1829. for (const auto& [_, count] : observed_checksums) {
  1830. EXPECT_NEAR((100 * count) / static_cast<double>(tables.size()), 0.2, 0.05);
  1831. }
  1832. EXPECT_EQ(reservations.size(), 10);
  1833. for (const auto& [reservation, count] : reservations) {
  1834. EXPECT_GE(reservation, 0);
  1835. EXPECT_LT(reservation, 100);
  1836. EXPECT_NEAR((100 * count) / static_cast<double>(tables.size()), 0.1, 0.05)
  1837. << reservation;
  1838. }
  1839. }
  1840. #endif // ABSL_INTERNAL_HASHTABLEZ_SAMPLE
  1841. TEST(RawHashSamplerTest, DoNotSampleCustomAllocators) {
  1842. // Enable the feature even if the prod default is off.
  1843. SetHashtablezEnabled(true);
  1844. SetHashtablezSampleParameter(100);
  1845. auto& sampler = GlobalHashtablezSampler();
  1846. size_t start_size = 0;
  1847. start_size += sampler.Iterate([&](const HashtablezInfo&) { ++start_size; });
  1848. std::vector<CustomAllocIntTable> tables;
  1849. for (int i = 0; i < 1000000; ++i) {
  1850. tables.emplace_back();
  1851. tables.back().insert(1);
  1852. }
  1853. size_t end_size = 0;
  1854. end_size += sampler.Iterate([&](const HashtablezInfo&) { ++end_size; });
  1855. EXPECT_NEAR((end_size - start_size) / static_cast<double>(tables.size()),
  1856. 0.00, 0.001);
  1857. }
  1858. #ifdef ABSL_HAVE_ADDRESS_SANITIZER
  1859. TEST(Sanitizer, PoisoningUnused) {
  1860. IntTable t;
  1861. t.reserve(5);
  1862. // Insert something to force an allocation.
  1863. int64_t& v1 = *t.insert(0).first;
  1864. // Make sure there is something to test.
  1865. ASSERT_GT(t.capacity(), 1);
  1866. int64_t* slots = RawHashSetTestOnlyAccess::GetSlots(t);
  1867. for (size_t i = 0; i < t.capacity(); ++i) {
  1868. EXPECT_EQ(slots + i != &v1, __asan_address_is_poisoned(slots + i));
  1869. }
  1870. }
  1871. TEST(Sanitizer, PoisoningOnErase) {
  1872. IntTable t;
  1873. int64_t& v = *t.insert(0).first;
  1874. EXPECT_FALSE(__asan_address_is_poisoned(&v));
  1875. t.erase(0);
  1876. EXPECT_TRUE(__asan_address_is_poisoned(&v));
  1877. }
  1878. #endif // ABSL_HAVE_ADDRESS_SANITIZER
  1879. TEST(Table, AlignOne) {
  1880. // We previously had a bug in which we were copying a control byte over the
  1881. // first slot when alignof(value_type) is 1. We test repeated
  1882. // insertions/erases and verify that the behavior is correct.
  1883. Uint8Table t;
  1884. std::unordered_set<uint8_t> verifier; // NOLINT
  1885. // Do repeated insertions/erases from the table.
  1886. for (int64_t i = 0; i < 100000; ++i) {
  1887. SCOPED_TRACE(i);
  1888. const uint8_t u = (i * -i) & 0xFF;
  1889. auto it = t.find(u);
  1890. auto verifier_it = verifier.find(u);
  1891. if (it == t.end()) {
  1892. ASSERT_EQ(verifier_it, verifier.end());
  1893. t.insert(u);
  1894. verifier.insert(u);
  1895. } else {
  1896. ASSERT_NE(verifier_it, verifier.end());
  1897. t.erase(it);
  1898. verifier.erase(verifier_it);
  1899. }
  1900. }
  1901. EXPECT_EQ(t.size(), verifier.size());
  1902. for (uint8_t u : t) {
  1903. EXPECT_EQ(verifier.count(u), 1);
  1904. }
  1905. }
  1906. } // namespace
  1907. } // namespace container_internal
  1908. ABSL_NAMESPACE_END
  1909. } // namespace absl