raw_hash_set.h 75 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034
  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. //
  15. // An open-addressing
  16. // hashtable with quadratic probing.
  17. //
  18. // This is a low level hashtable on top of which different interfaces can be
  19. // implemented, like flat_hash_set, node_hash_set, string_hash_set, etc.
  20. //
  21. // The table interface is similar to that of std::unordered_set. Notable
  22. // differences are that most member functions support heterogeneous keys when
  23. // BOTH the hash and eq functions are marked as transparent. They do so by
  24. // providing a typedef called `is_transparent`.
  25. //
  26. // When heterogeneous lookup is enabled, functions that take key_type act as if
  27. // they have an overload set like:
  28. //
  29. // iterator find(const key_type& key);
  30. // template <class K>
  31. // iterator find(const K& key);
  32. //
  33. // size_type erase(const key_type& key);
  34. // template <class K>
  35. // size_type erase(const K& key);
  36. //
  37. // std::pair<iterator, iterator> equal_range(const key_type& key);
  38. // template <class K>
  39. // std::pair<iterator, iterator> equal_range(const K& key);
  40. //
  41. // When heterogeneous lookup is disabled, only the explicit `key_type` overloads
  42. // exist.
  43. //
  44. // find() also supports passing the hash explicitly:
  45. //
  46. // iterator find(const key_type& key, size_t hash);
  47. // template <class U>
  48. // iterator find(const U& key, size_t hash);
  49. //
  50. // In addition the pointer to element and iterator stability guarantees are
  51. // weaker: all iterators and pointers are invalidated after a new element is
  52. // inserted.
  53. //
  54. // IMPLEMENTATION DETAILS
  55. //
  56. // The table stores elements inline in a slot array. In addition to the slot
  57. // array the table maintains some control state per slot. The extra state is one
  58. // byte per slot and stores empty or deleted marks, or alternatively 7 bits from
  59. // the hash of an occupied slot. The table is split into logical groups of
  60. // slots, like so:
  61. //
  62. // Group 1 Group 2 Group 3
  63. // +---------------+---------------+---------------+
  64. // | | | | | | | | | | | | | | | | | | | | | | | | |
  65. // +---------------+---------------+---------------+
  66. //
  67. // On lookup the hash is split into two parts:
  68. // - H2: 7 bits (those stored in the control bytes)
  69. // - H1: the rest of the bits
  70. // The groups are probed using H1. For each group the slots are matched to H2 in
  71. // parallel. Because H2 is 7 bits (128 states) and the number of slots per group
  72. // is low (8 or 16) in almost all cases a match in H2 is also a lookup hit.
  73. //
  74. // On insert, once the right group is found (as in lookup), its slots are
  75. // filled in order.
  76. //
  77. // On erase a slot is cleared. In case the group did not have any empty slots
  78. // before the erase, the erased slot is marked as deleted.
  79. //
  80. // Groups without empty slots (but maybe with deleted slots) extend the probe
  81. // sequence. The probing algorithm is quadratic. Given N the number of groups,
  82. // the probing function for the i'th probe is:
  83. //
  84. // P(0) = H1 % N
  85. //
  86. // P(i) = (P(i - 1) + i) % N
  87. //
  88. // This probing function guarantees that after N probes, all the groups of the
  89. // table will be probed exactly once.
  90. //
  91. // The control state and slot array are stored contiguously in a shared heap
  92. // allocation. The layout of this allocation is: `capacity()` control bytes,
  93. // one sentinel control byte, `Group::kWidth - 1` cloned control bytes,
  94. // <possible padding>, `capacity()` slots. The sentinel control byte is used in
  95. // iteration so we know when we reach the end of the table. The cloned control
  96. // bytes at the end of the table are cloned from the beginning of the table so
  97. // groups that begin near the end of the table can see a full group. In cases in
  98. // which there are more than `capacity()` cloned control bytes, the extra bytes
  99. // are `kEmpty`, and these ensure that we always see at least one empty slot and
  100. // can stop an unsuccessful search.
  101. #ifndef ABSL_CONTAINER_INTERNAL_RAW_HASH_SET_H_
  102. #define ABSL_CONTAINER_INTERNAL_RAW_HASH_SET_H_
  103. #include <algorithm>
  104. #include <cmath>
  105. #include <cstdint>
  106. #include <cstring>
  107. #include <iterator>
  108. #include <limits>
  109. #include <memory>
  110. #include <tuple>
  111. #include <type_traits>
  112. #include <utility>
  113. #include "absl/base/internal/endian.h"
  114. #include "absl/base/optimization.h"
  115. #include "absl/base/port.h"
  116. #include "absl/container/internal/common.h"
  117. #include "absl/container/internal/compressed_tuple.h"
  118. #include "absl/container/internal/container_memory.h"
  119. #include "absl/container/internal/hash_policy_traits.h"
  120. #include "absl/container/internal/hashtable_debug_hooks.h"
  121. #include "absl/container/internal/hashtablez_sampler.h"
  122. #include "absl/container/internal/have_sse.h"
  123. #include "absl/memory/memory.h"
  124. #include "absl/meta/type_traits.h"
  125. #include "absl/numeric/bits.h"
  126. #include "absl/utility/utility.h"
  127. namespace absl {
  128. ABSL_NAMESPACE_BEGIN
  129. namespace container_internal {
  130. template <typename AllocType>
  131. void SwapAlloc(AllocType& lhs, AllocType& rhs,
  132. std::true_type /* propagate_on_container_swap */) {
  133. using std::swap;
  134. swap(lhs, rhs);
  135. }
  136. template <typename AllocType>
  137. void SwapAlloc(AllocType& /*lhs*/, AllocType& /*rhs*/,
  138. std::false_type /* propagate_on_container_swap */) {}
  139. template <size_t Width>
  140. class probe_seq {
  141. public:
  142. probe_seq(size_t hash, size_t mask) {
  143. assert(((mask + 1) & mask) == 0 && "not a mask");
  144. mask_ = mask;
  145. offset_ = hash & mask_;
  146. }
  147. size_t offset() const { return offset_; }
  148. size_t offset(size_t i) const { return (offset_ + i) & mask_; }
  149. void next() {
  150. index_ += Width;
  151. offset_ += index_;
  152. offset_ &= mask_;
  153. }
  154. // 0-based probe index. The i-th probe in the probe sequence.
  155. size_t index() const { return index_; }
  156. private:
  157. size_t mask_;
  158. size_t offset_;
  159. size_t index_ = 0;
  160. };
  161. template <class ContainerKey, class Hash, class Eq>
  162. struct RequireUsableKey {
  163. template <class PassedKey, class... Args>
  164. std::pair<
  165. decltype(std::declval<const Hash&>()(std::declval<const PassedKey&>())),
  166. decltype(std::declval<const Eq&>()(std::declval<const ContainerKey&>(),
  167. std::declval<const PassedKey&>()))>*
  168. operator()(const PassedKey&, const Args&...) const;
  169. };
  170. template <class E, class Policy, class Hash, class Eq, class... Ts>
  171. struct IsDecomposable : std::false_type {};
  172. template <class Policy, class Hash, class Eq, class... Ts>
  173. struct IsDecomposable<
  174. absl::void_t<decltype(
  175. Policy::apply(RequireUsableKey<typename Policy::key_type, Hash, Eq>(),
  176. std::declval<Ts>()...))>,
  177. Policy, Hash, Eq, Ts...> : std::true_type {};
  178. // TODO(alkis): Switch to std::is_nothrow_swappable when gcc/clang supports it.
  179. template <class T>
  180. constexpr bool IsNoThrowSwappable(std::true_type = {} /* is_swappable */) {
  181. using std::swap;
  182. return noexcept(swap(std::declval<T&>(), std::declval<T&>()));
  183. }
  184. template <class T>
  185. constexpr bool IsNoThrowSwappable(std::false_type /* is_swappable */) {
  186. return false;
  187. }
  188. template <typename T>
  189. uint32_t TrailingZeros(T x) {
  190. ABSL_INTERNAL_ASSUME(x != 0);
  191. return countr_zero(x);
  192. }
  193. // An abstraction over a bitmask. It provides an easy way to iterate through the
  194. // indexes of the set bits of a bitmask. When Shift=0 (platforms with SSE),
  195. // this is a true bitmask. On non-SSE, platforms the arithematic used to
  196. // emulate the SSE behavior works in bytes (Shift=3) and leaves each bytes as
  197. // either 0x00 or 0x80.
  198. //
  199. // For example:
  200. // for (int i : BitMask<uint32_t, 16>(0x5)) -> yields 0, 2
  201. // for (int i : BitMask<uint64_t, 8, 3>(0x0000000080800000)) -> yields 2, 3
  202. template <class T, int SignificantBits, int Shift = 0>
  203. class BitMask {
  204. static_assert(std::is_unsigned<T>::value, "");
  205. static_assert(Shift == 0 || Shift == 3, "");
  206. public:
  207. // These are useful for unit tests (gunit).
  208. using value_type = int;
  209. using iterator = BitMask;
  210. using const_iterator = BitMask;
  211. explicit BitMask(T mask) : mask_(mask) {}
  212. BitMask& operator++() {
  213. mask_ &= (mask_ - 1);
  214. return *this;
  215. }
  216. explicit operator bool() const { return mask_ != 0; }
  217. int operator*() const { return LowestBitSet(); }
  218. uint32_t LowestBitSet() const {
  219. return container_internal::TrailingZeros(mask_) >> Shift;
  220. }
  221. uint32_t HighestBitSet() const {
  222. return static_cast<uint32_t>((bit_width(mask_) - 1) >> Shift);
  223. }
  224. BitMask begin() const { return *this; }
  225. BitMask end() const { return BitMask(0); }
  226. uint32_t TrailingZeros() const {
  227. return container_internal::TrailingZeros(mask_) >> Shift;
  228. }
  229. uint32_t LeadingZeros() const {
  230. constexpr int total_significant_bits = SignificantBits << Shift;
  231. constexpr int extra_bits = sizeof(T) * 8 - total_significant_bits;
  232. return countl_zero(mask_ << extra_bits) >> Shift;
  233. }
  234. private:
  235. friend bool operator==(const BitMask& a, const BitMask& b) {
  236. return a.mask_ == b.mask_;
  237. }
  238. friend bool operator!=(const BitMask& a, const BitMask& b) {
  239. return a.mask_ != b.mask_;
  240. }
  241. T mask_;
  242. };
  243. using h2_t = uint8_t;
  244. // The values here are selected for maximum performance. See the static asserts
  245. // below for details. We use an enum class so that when strict aliasing is
  246. // enabled, the compiler knows ctrl_t doesn't alias other types.
  247. enum class ctrl_t : int8_t {
  248. kEmpty = -128, // 0b10000000
  249. kDeleted = -2, // 0b11111110
  250. kSentinel = -1, // 0b11111111
  251. };
  252. static_assert(
  253. (static_cast<int8_t>(ctrl_t::kEmpty) &
  254. static_cast<int8_t>(ctrl_t::kDeleted) &
  255. static_cast<int8_t>(ctrl_t::kSentinel) & 0x80) != 0,
  256. "Special markers need to have the MSB to make checking for them efficient");
  257. static_assert(
  258. ctrl_t::kEmpty < ctrl_t::kSentinel && ctrl_t::kDeleted < ctrl_t::kSentinel,
  259. "ctrl_t::kEmpty and ctrl_t::kDeleted must be smaller than "
  260. "ctrl_t::kSentinel to make the SIMD test of IsEmptyOrDeleted() efficient");
  261. static_assert(
  262. ctrl_t::kSentinel == static_cast<ctrl_t>(-1),
  263. "ctrl_t::kSentinel must be -1 to elide loading it from memory into SIMD "
  264. "registers (pcmpeqd xmm, xmm)");
  265. static_assert(ctrl_t::kEmpty == static_cast<ctrl_t>(-128),
  266. "ctrl_t::kEmpty must be -128 to make the SIMD check for its "
  267. "existence efficient (psignb xmm, xmm)");
  268. static_assert(
  269. (~static_cast<int8_t>(ctrl_t::kEmpty) &
  270. ~static_cast<int8_t>(ctrl_t::kDeleted) &
  271. static_cast<int8_t>(ctrl_t::kSentinel) & 0x7F) != 0,
  272. "ctrl_t::kEmpty and ctrl_t::kDeleted must share an unset bit that is not "
  273. "shared by ctrl_t::kSentinel to make the scalar test for "
  274. "MatchEmptyOrDeleted() efficient");
  275. static_assert(ctrl_t::kDeleted == static_cast<ctrl_t>(-2),
  276. "ctrl_t::kDeleted must be -2 to make the implementation of "
  277. "ConvertSpecialToEmptyAndFullToDeleted efficient");
  278. // A single block of empty control bytes for tables without any slots allocated.
  279. // This enables removing a branch in the hot path of find().
  280. ABSL_DLL extern const ctrl_t kEmptyGroup[16];
  281. inline ctrl_t* EmptyGroup() {
  282. return const_cast<ctrl_t*>(kEmptyGroup);
  283. }
  284. // Mixes a randomly generated per-process seed with `hash` and `ctrl` to
  285. // randomize insertion order within groups.
  286. bool ShouldInsertBackwards(size_t hash, const ctrl_t* ctrl);
  287. // Returns a hash seed.
  288. //
  289. // The seed consists of the ctrl_ pointer, which adds enough entropy to ensure
  290. // non-determinism of iteration order in most cases.
  291. inline size_t HashSeed(const ctrl_t* ctrl) {
  292. // The low bits of the pointer have little or no entropy because of
  293. // alignment. We shift the pointer to try to use higher entropy bits. A
  294. // good number seems to be 12 bits, because that aligns with page size.
  295. return reinterpret_cast<uintptr_t>(ctrl) >> 12;
  296. }
  297. inline size_t H1(size_t hash, const ctrl_t* ctrl) {
  298. return (hash >> 7) ^ HashSeed(ctrl);
  299. }
  300. inline h2_t H2(size_t hash) { return hash & 0x7F; }
  301. inline bool IsEmpty(ctrl_t c) { return c == ctrl_t::kEmpty; }
  302. inline bool IsFull(ctrl_t c) { return c >= static_cast<ctrl_t>(0); }
  303. inline bool IsDeleted(ctrl_t c) { return c == ctrl_t::kDeleted; }
  304. inline bool IsEmptyOrDeleted(ctrl_t c) { return c < ctrl_t::kSentinel; }
  305. #if ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSE2
  306. // https://github.com/abseil/abseil-cpp/issues/209
  307. // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87853
  308. // _mm_cmpgt_epi8 is broken under GCC with -funsigned-char
  309. // Work around this by using the portable implementation of Group
  310. // when using -funsigned-char under GCC.
  311. inline __m128i _mm_cmpgt_epi8_fixed(__m128i a, __m128i b) {
  312. #if defined(__GNUC__) && !defined(__clang__)
  313. if (std::is_unsigned<char>::value) {
  314. const __m128i mask = _mm_set1_epi8(0x80);
  315. const __m128i diff = _mm_subs_epi8(b, a);
  316. return _mm_cmpeq_epi8(_mm_and_si128(diff, mask), mask);
  317. }
  318. #endif
  319. return _mm_cmpgt_epi8(a, b);
  320. }
  321. struct GroupSse2Impl {
  322. static constexpr size_t kWidth = 16; // the number of slots per group
  323. explicit GroupSse2Impl(const ctrl_t* pos) {
  324. ctrl = _mm_loadu_si128(reinterpret_cast<const __m128i*>(pos));
  325. }
  326. // Returns a bitmask representing the positions of slots that match hash.
  327. BitMask<uint32_t, kWidth> Match(h2_t hash) const {
  328. auto match = _mm_set1_epi8(hash);
  329. return BitMask<uint32_t, kWidth>(
  330. _mm_movemask_epi8(_mm_cmpeq_epi8(match, ctrl)));
  331. }
  332. // Returns a bitmask representing the positions of empty slots.
  333. BitMask<uint32_t, kWidth> MatchEmpty() const {
  334. #if ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSSE3
  335. // This only works because ctrl_t::kEmpty is -128.
  336. return BitMask<uint32_t, kWidth>(
  337. _mm_movemask_epi8(_mm_sign_epi8(ctrl, ctrl)));
  338. #else
  339. return Match(static_cast<h2_t>(ctrl_t::kEmpty));
  340. #endif
  341. }
  342. // Returns a bitmask representing the positions of empty or deleted slots.
  343. BitMask<uint32_t, kWidth> MatchEmptyOrDeleted() const {
  344. auto special = _mm_set1_epi8(static_cast<int8_t>(ctrl_t::kSentinel));
  345. return BitMask<uint32_t, kWidth>(
  346. _mm_movemask_epi8(_mm_cmpgt_epi8_fixed(special, ctrl)));
  347. }
  348. // Returns the number of trailing empty or deleted elements in the group.
  349. uint32_t CountLeadingEmptyOrDeleted() const {
  350. auto special = _mm_set1_epi8(static_cast<int8_t>(ctrl_t::kSentinel));
  351. return TrailingZeros(static_cast<uint32_t>(
  352. _mm_movemask_epi8(_mm_cmpgt_epi8_fixed(special, ctrl)) + 1));
  353. }
  354. void ConvertSpecialToEmptyAndFullToDeleted(ctrl_t* dst) const {
  355. auto msbs = _mm_set1_epi8(static_cast<char>(-128));
  356. auto x126 = _mm_set1_epi8(126);
  357. #if ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSSE3
  358. auto res = _mm_or_si128(_mm_shuffle_epi8(x126, ctrl), msbs);
  359. #else
  360. auto zero = _mm_setzero_si128();
  361. auto special_mask = _mm_cmpgt_epi8_fixed(zero, ctrl);
  362. auto res = _mm_or_si128(msbs, _mm_andnot_si128(special_mask, x126));
  363. #endif
  364. _mm_storeu_si128(reinterpret_cast<__m128i*>(dst), res);
  365. }
  366. __m128i ctrl;
  367. };
  368. #endif // ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSE2
  369. struct GroupPortableImpl {
  370. static constexpr size_t kWidth = 8;
  371. explicit GroupPortableImpl(const ctrl_t* pos)
  372. : ctrl(little_endian::Load64(pos)) {}
  373. BitMask<uint64_t, kWidth, 3> Match(h2_t hash) const {
  374. // For the technique, see:
  375. // http://graphics.stanford.edu/~seander/bithacks.html##ValueInWord
  376. // (Determine if a word has a byte equal to n).
  377. //
  378. // Caveat: there are false positives but:
  379. // - they only occur if there is a real match
  380. // - they never occur on ctrl_t::kEmpty, ctrl_t::kDeleted, ctrl_t::kSentinel
  381. // - they will be handled gracefully by subsequent checks in code
  382. //
  383. // Example:
  384. // v = 0x1716151413121110
  385. // hash = 0x12
  386. // retval = (v - lsbs) & ~v & msbs = 0x0000000080800000
  387. constexpr uint64_t msbs = 0x8080808080808080ULL;
  388. constexpr uint64_t lsbs = 0x0101010101010101ULL;
  389. auto x = ctrl ^ (lsbs * hash);
  390. return BitMask<uint64_t, kWidth, 3>((x - lsbs) & ~x & msbs);
  391. }
  392. BitMask<uint64_t, kWidth, 3> MatchEmpty() const {
  393. constexpr uint64_t msbs = 0x8080808080808080ULL;
  394. return BitMask<uint64_t, kWidth, 3>((ctrl & (~ctrl << 6)) & msbs);
  395. }
  396. BitMask<uint64_t, kWidth, 3> MatchEmptyOrDeleted() const {
  397. constexpr uint64_t msbs = 0x8080808080808080ULL;
  398. return BitMask<uint64_t, kWidth, 3>((ctrl & (~ctrl << 7)) & msbs);
  399. }
  400. uint32_t CountLeadingEmptyOrDeleted() const {
  401. constexpr uint64_t gaps = 0x00FEFEFEFEFEFEFEULL;
  402. return (TrailingZeros(((~ctrl & (ctrl >> 7)) | gaps) + 1) + 7) >> 3;
  403. }
  404. void ConvertSpecialToEmptyAndFullToDeleted(ctrl_t* dst) const {
  405. constexpr uint64_t msbs = 0x8080808080808080ULL;
  406. constexpr uint64_t lsbs = 0x0101010101010101ULL;
  407. auto x = ctrl & msbs;
  408. auto res = (~x + (x >> 7)) & ~lsbs;
  409. little_endian::Store64(dst, res);
  410. }
  411. uint64_t ctrl;
  412. };
  413. #if ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSE2
  414. using Group = GroupSse2Impl;
  415. #else
  416. using Group = GroupPortableImpl;
  417. #endif
  418. // The number of cloned control bytes that we copy from the beginning to the
  419. // end of the control bytes array.
  420. constexpr size_t NumClonedBytes() { return Group::kWidth - 1; }
  421. template <class Policy, class Hash, class Eq, class Alloc>
  422. class raw_hash_set;
  423. inline bool IsValidCapacity(size_t n) { return ((n + 1) & n) == 0 && n > 0; }
  424. // PRECONDITION:
  425. // IsValidCapacity(capacity)
  426. // ctrl[capacity] == ctrl_t::kSentinel
  427. // ctrl[i] != ctrl_t::kSentinel for all i < capacity
  428. // Applies mapping for every byte in ctrl:
  429. // DELETED -> EMPTY
  430. // EMPTY -> EMPTY
  431. // FULL -> DELETED
  432. void ConvertDeletedToEmptyAndFullToDeleted(ctrl_t* ctrl, size_t capacity);
  433. // Rounds up the capacity to the next power of 2 minus 1, with a minimum of 1.
  434. inline size_t NormalizeCapacity(size_t n) {
  435. return n ? ~size_t{} >> countl_zero(n) : 1;
  436. }
  437. // General notes on capacity/growth methods below:
  438. // - We use 7/8th as maximum load factor. For 16-wide groups, that gives an
  439. // average of two empty slots per group.
  440. // - For (capacity+1) >= Group::kWidth, growth is 7/8*capacity.
  441. // - For (capacity+1) < Group::kWidth, growth == capacity. In this case, we
  442. // never need to probe (the whole table fits in one group) so we don't need a
  443. // load factor less than 1.
  444. // Given `capacity` of the table, returns the size (i.e. number of full slots)
  445. // at which we should grow the capacity.
  446. inline size_t CapacityToGrowth(size_t capacity) {
  447. assert(IsValidCapacity(capacity));
  448. // `capacity*7/8`
  449. if (Group::kWidth == 8 && capacity == 7) {
  450. // x-x/8 does not work when x==7.
  451. return 6;
  452. }
  453. return capacity - capacity / 8;
  454. }
  455. // From desired "growth" to a lowerbound of the necessary capacity.
  456. // Might not be a valid one and requires NormalizeCapacity().
  457. inline size_t GrowthToLowerboundCapacity(size_t growth) {
  458. // `growth*8/7`
  459. if (Group::kWidth == 8 && growth == 7) {
  460. // x+(x-1)/7 does not work when x==7.
  461. return 8;
  462. }
  463. return growth + static_cast<size_t>((static_cast<int64_t>(growth) - 1) / 7);
  464. }
  465. template <class InputIter>
  466. size_t SelectBucketCountForIterRange(InputIter first, InputIter last,
  467. size_t bucket_count) {
  468. if (bucket_count != 0) {
  469. return bucket_count;
  470. }
  471. using InputIterCategory =
  472. typename std::iterator_traits<InputIter>::iterator_category;
  473. if (std::is_base_of<std::random_access_iterator_tag,
  474. InputIterCategory>::value) {
  475. return GrowthToLowerboundCapacity(
  476. static_cast<size_t>(std::distance(first, last)));
  477. }
  478. return 0;
  479. }
  480. inline void AssertIsFull(ctrl_t* ctrl) {
  481. ABSL_HARDENING_ASSERT((ctrl != nullptr && IsFull(*ctrl)) &&
  482. "Invalid operation on iterator. The element might have "
  483. "been erased, or the table might have rehashed.");
  484. }
  485. inline void AssertIsValid(ctrl_t* ctrl) {
  486. ABSL_HARDENING_ASSERT((ctrl == nullptr || IsFull(*ctrl)) &&
  487. "Invalid operation on iterator. The element might have "
  488. "been erased, or the table might have rehashed.");
  489. }
  490. struct FindInfo {
  491. size_t offset;
  492. size_t probe_length;
  493. };
  494. // The representation of the object has two modes:
  495. // - small: For capacities < kWidth-1
  496. // - large: For the rest.
  497. //
  498. // Differences:
  499. // - In small mode we are able to use the whole capacity. The extra control
  500. // bytes give us at least one "empty" control byte to stop the iteration.
  501. // This is important to make 1 a valid capacity.
  502. //
  503. // - In small mode only the first `capacity()` control bytes after the
  504. // sentinel are valid. The rest contain dummy ctrl_t::kEmpty values that do not
  505. // represent a real slot. This is important to take into account on
  506. // find_first_non_full(), where we never try ShouldInsertBackwards() for
  507. // small tables.
  508. inline bool is_small(size_t capacity) { return capacity < Group::kWidth - 1; }
  509. inline probe_seq<Group::kWidth> probe(const ctrl_t* ctrl, size_t hash,
  510. size_t capacity) {
  511. return probe_seq<Group::kWidth>(H1(hash, ctrl), capacity);
  512. }
  513. // Probes the raw_hash_set with the probe sequence for hash and returns the
  514. // pointer to the first empty or deleted slot.
  515. // NOTE: this function must work with tables having both ctrl_t::kEmpty and
  516. // ctrl_t::kDeleted in one group. Such tables appears during
  517. // drop_deletes_without_resize.
  518. //
  519. // This function is very useful when insertions happen and:
  520. // - the input is already a set
  521. // - there are enough slots
  522. // - the element with the hash is not in the table
  523. template <typename = void>
  524. inline FindInfo find_first_non_full(const ctrl_t* ctrl, size_t hash,
  525. size_t capacity) {
  526. auto seq = probe(ctrl, hash, capacity);
  527. while (true) {
  528. Group g{ctrl + seq.offset()};
  529. auto mask = g.MatchEmptyOrDeleted();
  530. if (mask) {
  531. #if !defined(NDEBUG)
  532. // We want to add entropy even when ASLR is not enabled.
  533. // In debug build we will randomly insert in either the front or back of
  534. // the group.
  535. // TODO(kfm,sbenza): revisit after we do unconditional mixing
  536. if (!is_small(capacity) && ShouldInsertBackwards(hash, ctrl)) {
  537. return {seq.offset(mask.HighestBitSet()), seq.index()};
  538. }
  539. #endif
  540. return {seq.offset(mask.LowestBitSet()), seq.index()};
  541. }
  542. seq.next();
  543. assert(seq.index() <= capacity && "full table!");
  544. }
  545. }
  546. // Extern template for inline function keep possibility of inlining.
  547. // When compiler decided to not inline, no symbols will be added to the
  548. // corresponding translation unit.
  549. extern template FindInfo find_first_non_full(const ctrl_t*, size_t, size_t);
  550. // Reset all ctrl bytes back to ctrl_t::kEmpty, except the sentinel.
  551. inline void ResetCtrl(size_t capacity, ctrl_t* ctrl, const void* slot,
  552. size_t slot_size) {
  553. std::memset(ctrl, static_cast<int8_t>(ctrl_t::kEmpty),
  554. capacity + 1 + NumClonedBytes());
  555. ctrl[capacity] = ctrl_t::kSentinel;
  556. SanitizerPoisonMemoryRegion(slot, slot_size * capacity);
  557. }
  558. // Sets the control byte, and if `i < NumClonedBytes()`, set the cloned byte
  559. // at the end too.
  560. inline void SetCtrl(size_t i, ctrl_t h, size_t capacity, ctrl_t* ctrl,
  561. const void* slot, size_t slot_size) {
  562. assert(i < capacity);
  563. auto* slot_i = static_cast<const char*>(slot) + i * slot_size;
  564. if (IsFull(h)) {
  565. SanitizerUnpoisonMemoryRegion(slot_i, slot_size);
  566. } else {
  567. SanitizerPoisonMemoryRegion(slot_i, slot_size);
  568. }
  569. ctrl[i] = h;
  570. ctrl[((i - NumClonedBytes()) & capacity) + (NumClonedBytes() & capacity)] = h;
  571. }
  572. inline void SetCtrl(size_t i, h2_t h, size_t capacity, ctrl_t* ctrl,
  573. const void* slot, size_t slot_size) {
  574. SetCtrl(i, static_cast<ctrl_t>(h), capacity, ctrl, slot, slot_size);
  575. }
  576. // The allocated block consists of `capacity + 1 + NumClonedBytes()` control
  577. // bytes followed by `capacity` slots, which must be aligned to `slot_align`.
  578. // SlotOffset returns the offset of the slots into the allocated block.
  579. inline size_t SlotOffset(size_t capacity, size_t slot_align) {
  580. assert(IsValidCapacity(capacity));
  581. const size_t num_control_bytes = capacity + 1 + NumClonedBytes();
  582. return (num_control_bytes + slot_align - 1) & (~slot_align + 1);
  583. }
  584. // Returns the size of the allocated block. See also above comment.
  585. inline size_t AllocSize(size_t capacity, size_t slot_size, size_t slot_align) {
  586. return SlotOffset(capacity, slot_align) + capacity * slot_size;
  587. }
  588. // Policy: a policy defines how to perform different operations on
  589. // the slots of the hashtable (see hash_policy_traits.h for the full interface
  590. // of policy).
  591. //
  592. // Hash: a (possibly polymorphic) functor that hashes keys of the hashtable. The
  593. // functor should accept a key and return size_t as hash. For best performance
  594. // it is important that the hash function provides high entropy across all bits
  595. // of the hash.
  596. //
  597. // Eq: a (possibly polymorphic) functor that compares two keys for equality. It
  598. // should accept two (of possibly different type) keys and return a bool: true
  599. // if they are equal, false if they are not. If two keys compare equal, then
  600. // their hash values as defined by Hash MUST be equal.
  601. //
  602. // Allocator: an Allocator
  603. // [https://en.cppreference.com/w/cpp/named_req/Allocator] with which
  604. // the storage of the hashtable will be allocated and the elements will be
  605. // constructed and destroyed.
  606. template <class Policy, class Hash, class Eq, class Alloc>
  607. class raw_hash_set {
  608. using PolicyTraits = hash_policy_traits<Policy>;
  609. using KeyArgImpl =
  610. KeyArg<IsTransparent<Eq>::value && IsTransparent<Hash>::value>;
  611. public:
  612. using init_type = typename PolicyTraits::init_type;
  613. using key_type = typename PolicyTraits::key_type;
  614. // TODO(sbenza): Hide slot_type as it is an implementation detail. Needs user
  615. // code fixes!
  616. using slot_type = typename PolicyTraits::slot_type;
  617. using allocator_type = Alloc;
  618. using size_type = size_t;
  619. using difference_type = ptrdiff_t;
  620. using hasher = Hash;
  621. using key_equal = Eq;
  622. using policy_type = Policy;
  623. using value_type = typename PolicyTraits::value_type;
  624. using reference = value_type&;
  625. using const_reference = const value_type&;
  626. using pointer = typename absl::allocator_traits<
  627. allocator_type>::template rebind_traits<value_type>::pointer;
  628. using const_pointer = typename absl::allocator_traits<
  629. allocator_type>::template rebind_traits<value_type>::const_pointer;
  630. // Alias used for heterogeneous lookup functions.
  631. // `key_arg<K>` evaluates to `K` when the functors are transparent and to
  632. // `key_type` otherwise. It permits template argument deduction on `K` for the
  633. // transparent case.
  634. template <class K>
  635. using key_arg = typename KeyArgImpl::template type<K, key_type>;
  636. private:
  637. // Give an early error when key_type is not hashable/eq.
  638. auto KeyTypeCanBeHashed(const Hash& h, const key_type& k) -> decltype(h(k));
  639. auto KeyTypeCanBeEq(const Eq& eq, const key_type& k) -> decltype(eq(k, k));
  640. using AllocTraits = absl::allocator_traits<allocator_type>;
  641. using SlotAlloc = typename absl::allocator_traits<
  642. allocator_type>::template rebind_alloc<slot_type>;
  643. using SlotAllocTraits = typename absl::allocator_traits<
  644. allocator_type>::template rebind_traits<slot_type>;
  645. static_assert(std::is_lvalue_reference<reference>::value,
  646. "Policy::element() must return a reference");
  647. template <typename T>
  648. struct SameAsElementReference
  649. : std::is_same<typename std::remove_cv<
  650. typename std::remove_reference<reference>::type>::type,
  651. typename std::remove_cv<
  652. typename std::remove_reference<T>::type>::type> {};
  653. // An enabler for insert(T&&): T must be convertible to init_type or be the
  654. // same as [cv] value_type [ref].
  655. // Note: we separate SameAsElementReference into its own type to avoid using
  656. // reference unless we need to. MSVC doesn't seem to like it in some
  657. // cases.
  658. template <class T>
  659. using RequiresInsertable = typename std::enable_if<
  660. absl::disjunction<std::is_convertible<T, init_type>,
  661. SameAsElementReference<T>>::value,
  662. int>::type;
  663. // RequiresNotInit is a workaround for gcc prior to 7.1.
  664. // See https://godbolt.org/g/Y4xsUh.
  665. template <class T>
  666. using RequiresNotInit =
  667. typename std::enable_if<!std::is_same<T, init_type>::value, int>::type;
  668. template <class... Ts>
  669. using IsDecomposable = IsDecomposable<void, PolicyTraits, Hash, Eq, Ts...>;
  670. public:
  671. static_assert(std::is_same<pointer, value_type*>::value,
  672. "Allocators with custom pointer types are not supported");
  673. static_assert(std::is_same<const_pointer, const value_type*>::value,
  674. "Allocators with custom pointer types are not supported");
  675. class iterator {
  676. friend class raw_hash_set;
  677. public:
  678. using iterator_category = std::forward_iterator_tag;
  679. using value_type = typename raw_hash_set::value_type;
  680. using reference =
  681. absl::conditional_t<PolicyTraits::constant_iterators::value,
  682. const value_type&, value_type&>;
  683. using pointer = absl::remove_reference_t<reference>*;
  684. using difference_type = typename raw_hash_set::difference_type;
  685. iterator() {}
  686. // PRECONDITION: not an end() iterator.
  687. reference operator*() const {
  688. AssertIsFull(ctrl_);
  689. return PolicyTraits::element(slot_);
  690. }
  691. // PRECONDITION: not an end() iterator.
  692. pointer operator->() const { return &operator*(); }
  693. // PRECONDITION: not an end() iterator.
  694. iterator& operator++() {
  695. AssertIsFull(ctrl_);
  696. ++ctrl_;
  697. ++slot_;
  698. skip_empty_or_deleted();
  699. return *this;
  700. }
  701. // PRECONDITION: not an end() iterator.
  702. iterator operator++(int) {
  703. auto tmp = *this;
  704. ++*this;
  705. return tmp;
  706. }
  707. friend bool operator==(const iterator& a, const iterator& b) {
  708. AssertIsValid(a.ctrl_);
  709. AssertIsValid(b.ctrl_);
  710. return a.ctrl_ == b.ctrl_;
  711. }
  712. friend bool operator!=(const iterator& a, const iterator& b) {
  713. return !(a == b);
  714. }
  715. private:
  716. iterator(ctrl_t* ctrl, slot_type* slot) : ctrl_(ctrl), slot_(slot) {
  717. // This assumption helps the compiler know that any non-end iterator is
  718. // not equal to any end iterator.
  719. ABSL_INTERNAL_ASSUME(ctrl != nullptr);
  720. }
  721. void skip_empty_or_deleted() {
  722. while (IsEmptyOrDeleted(*ctrl_)) {
  723. uint32_t shift = Group{ctrl_}.CountLeadingEmptyOrDeleted();
  724. ctrl_ += shift;
  725. slot_ += shift;
  726. }
  727. if (ABSL_PREDICT_FALSE(*ctrl_ == ctrl_t::kSentinel)) ctrl_ = nullptr;
  728. }
  729. ctrl_t* ctrl_ = nullptr;
  730. // To avoid uninitialized member warnings, put slot_ in an anonymous union.
  731. // The member is not initialized on singleton and end iterators.
  732. union {
  733. slot_type* slot_;
  734. };
  735. };
  736. class const_iterator {
  737. friend class raw_hash_set;
  738. public:
  739. using iterator_category = typename iterator::iterator_category;
  740. using value_type = typename raw_hash_set::value_type;
  741. using reference = typename raw_hash_set::const_reference;
  742. using pointer = typename raw_hash_set::const_pointer;
  743. using difference_type = typename raw_hash_set::difference_type;
  744. const_iterator() {}
  745. // Implicit construction from iterator.
  746. const_iterator(iterator i) : inner_(std::move(i)) {}
  747. reference operator*() const { return *inner_; }
  748. pointer operator->() const { return inner_.operator->(); }
  749. const_iterator& operator++() {
  750. ++inner_;
  751. return *this;
  752. }
  753. const_iterator operator++(int) { return inner_++; }
  754. friend bool operator==(const const_iterator& a, const const_iterator& b) {
  755. return a.inner_ == b.inner_;
  756. }
  757. friend bool operator!=(const const_iterator& a, const const_iterator& b) {
  758. return !(a == b);
  759. }
  760. private:
  761. const_iterator(const ctrl_t* ctrl, const slot_type* slot)
  762. : inner_(const_cast<ctrl_t*>(ctrl), const_cast<slot_type*>(slot)) {}
  763. iterator inner_;
  764. };
  765. using node_type = node_handle<Policy, hash_policy_traits<Policy>, Alloc>;
  766. using insert_return_type = InsertReturnType<iterator, node_type>;
  767. raw_hash_set() noexcept(
  768. std::is_nothrow_default_constructible<hasher>::value&&
  769. std::is_nothrow_default_constructible<key_equal>::value&&
  770. std::is_nothrow_default_constructible<allocator_type>::value) {}
  771. explicit raw_hash_set(size_t bucket_count, const hasher& hash = hasher(),
  772. const key_equal& eq = key_equal(),
  773. const allocator_type& alloc = allocator_type())
  774. : ctrl_(EmptyGroup()),
  775. settings_(0, HashtablezInfoHandle(), hash, eq, alloc) {
  776. if (bucket_count) {
  777. capacity_ = NormalizeCapacity(bucket_count);
  778. initialize_slots();
  779. }
  780. }
  781. raw_hash_set(size_t bucket_count, const hasher& hash,
  782. const allocator_type& alloc)
  783. : raw_hash_set(bucket_count, hash, key_equal(), alloc) {}
  784. raw_hash_set(size_t bucket_count, const allocator_type& alloc)
  785. : raw_hash_set(bucket_count, hasher(), key_equal(), alloc) {}
  786. explicit raw_hash_set(const allocator_type& alloc)
  787. : raw_hash_set(0, hasher(), key_equal(), alloc) {}
  788. template <class InputIter>
  789. raw_hash_set(InputIter first, InputIter last, size_t bucket_count = 0,
  790. const hasher& hash = hasher(), const key_equal& eq = key_equal(),
  791. const allocator_type& alloc = allocator_type())
  792. : raw_hash_set(SelectBucketCountForIterRange(first, last, bucket_count),
  793. hash, eq, alloc) {
  794. insert(first, last);
  795. }
  796. template <class InputIter>
  797. raw_hash_set(InputIter first, InputIter last, size_t bucket_count,
  798. const hasher& hash, const allocator_type& alloc)
  799. : raw_hash_set(first, last, bucket_count, hash, key_equal(), alloc) {}
  800. template <class InputIter>
  801. raw_hash_set(InputIter first, InputIter last, size_t bucket_count,
  802. const allocator_type& alloc)
  803. : raw_hash_set(first, last, bucket_count, hasher(), key_equal(), alloc) {}
  804. template <class InputIter>
  805. raw_hash_set(InputIter first, InputIter last, const allocator_type& alloc)
  806. : raw_hash_set(first, last, 0, hasher(), key_equal(), alloc) {}
  807. // Instead of accepting std::initializer_list<value_type> as the first
  808. // argument like std::unordered_set<value_type> does, we have two overloads
  809. // that accept std::initializer_list<T> and std::initializer_list<init_type>.
  810. // This is advantageous for performance.
  811. //
  812. // // Turns {"abc", "def"} into std::initializer_list<std::string>, then
  813. // // copies the strings into the set.
  814. // std::unordered_set<std::string> s = {"abc", "def"};
  815. //
  816. // // Turns {"abc", "def"} into std::initializer_list<const char*>, then
  817. // // copies the strings into the set.
  818. // absl::flat_hash_set<std::string> s = {"abc", "def"};
  819. //
  820. // The same trick is used in insert().
  821. //
  822. // The enabler is necessary to prevent this constructor from triggering where
  823. // the copy constructor is meant to be called.
  824. //
  825. // absl::flat_hash_set<int> a, b{a};
  826. //
  827. // RequiresNotInit<T> is a workaround for gcc prior to 7.1.
  828. template <class T, RequiresNotInit<T> = 0, RequiresInsertable<T> = 0>
  829. raw_hash_set(std::initializer_list<T> init, size_t bucket_count = 0,
  830. const hasher& hash = hasher(), const key_equal& eq = key_equal(),
  831. const allocator_type& alloc = allocator_type())
  832. : raw_hash_set(init.begin(), init.end(), bucket_count, hash, eq, alloc) {}
  833. raw_hash_set(std::initializer_list<init_type> init, size_t bucket_count = 0,
  834. const hasher& hash = hasher(), const key_equal& eq = key_equal(),
  835. const allocator_type& alloc = allocator_type())
  836. : raw_hash_set(init.begin(), init.end(), bucket_count, hash, eq, alloc) {}
  837. template <class T, RequiresNotInit<T> = 0, RequiresInsertable<T> = 0>
  838. raw_hash_set(std::initializer_list<T> init, size_t bucket_count,
  839. const hasher& hash, const allocator_type& alloc)
  840. : raw_hash_set(init, bucket_count, hash, key_equal(), alloc) {}
  841. raw_hash_set(std::initializer_list<init_type> init, size_t bucket_count,
  842. const hasher& hash, const allocator_type& alloc)
  843. : raw_hash_set(init, bucket_count, hash, key_equal(), alloc) {}
  844. template <class T, RequiresNotInit<T> = 0, RequiresInsertable<T> = 0>
  845. raw_hash_set(std::initializer_list<T> init, size_t bucket_count,
  846. const allocator_type& alloc)
  847. : raw_hash_set(init, bucket_count, hasher(), key_equal(), alloc) {}
  848. raw_hash_set(std::initializer_list<init_type> init, size_t bucket_count,
  849. const allocator_type& alloc)
  850. : raw_hash_set(init, bucket_count, hasher(), key_equal(), alloc) {}
  851. template <class T, RequiresNotInit<T> = 0, RequiresInsertable<T> = 0>
  852. raw_hash_set(std::initializer_list<T> init, const allocator_type& alloc)
  853. : raw_hash_set(init, 0, hasher(), key_equal(), alloc) {}
  854. raw_hash_set(std::initializer_list<init_type> init,
  855. const allocator_type& alloc)
  856. : raw_hash_set(init, 0, hasher(), key_equal(), alloc) {}
  857. raw_hash_set(const raw_hash_set& that)
  858. : raw_hash_set(that, AllocTraits::select_on_container_copy_construction(
  859. that.alloc_ref())) {}
  860. raw_hash_set(const raw_hash_set& that, const allocator_type& a)
  861. : raw_hash_set(0, that.hash_ref(), that.eq_ref(), a) {
  862. reserve(that.size());
  863. // Because the table is guaranteed to be empty, we can do something faster
  864. // than a full `insert`.
  865. for (const auto& v : that) {
  866. const size_t hash = PolicyTraits::apply(HashElement{hash_ref()}, v);
  867. auto target = find_first_non_full(ctrl_, hash, capacity_);
  868. SetCtrl(target.offset, H2(hash), capacity_, ctrl_, slots_,
  869. sizeof(slot_type));
  870. emplace_at(target.offset, v);
  871. infoz().RecordInsert(hash, target.probe_length);
  872. }
  873. size_ = that.size();
  874. growth_left() -= that.size();
  875. }
  876. raw_hash_set(raw_hash_set&& that) noexcept(
  877. std::is_nothrow_copy_constructible<hasher>::value&&
  878. std::is_nothrow_copy_constructible<key_equal>::value&&
  879. std::is_nothrow_copy_constructible<allocator_type>::value)
  880. : ctrl_(absl::exchange(that.ctrl_, EmptyGroup())),
  881. slots_(absl::exchange(that.slots_, nullptr)),
  882. size_(absl::exchange(that.size_, 0)),
  883. capacity_(absl::exchange(that.capacity_, 0)),
  884. // Hash, equality and allocator are copied instead of moved because
  885. // `that` must be left valid. If Hash is std::function<Key>, moving it
  886. // would create a nullptr functor that cannot be called.
  887. settings_(absl::exchange(that.growth_left(), 0),
  888. absl::exchange(that.infoz(), HashtablezInfoHandle()),
  889. that.hash_ref(), that.eq_ref(), that.alloc_ref()) {}
  890. raw_hash_set(raw_hash_set&& that, const allocator_type& a)
  891. : ctrl_(EmptyGroup()),
  892. slots_(nullptr),
  893. size_(0),
  894. capacity_(0),
  895. settings_(0, HashtablezInfoHandle(), that.hash_ref(), that.eq_ref(),
  896. a) {
  897. if (a == that.alloc_ref()) {
  898. std::swap(ctrl_, that.ctrl_);
  899. std::swap(slots_, that.slots_);
  900. std::swap(size_, that.size_);
  901. std::swap(capacity_, that.capacity_);
  902. std::swap(growth_left(), that.growth_left());
  903. std::swap(infoz(), that.infoz());
  904. } else {
  905. reserve(that.size());
  906. // Note: this will copy elements of dense_set and unordered_set instead of
  907. // moving them. This can be fixed if it ever becomes an issue.
  908. for (auto& elem : that) insert(std::move(elem));
  909. }
  910. }
  911. raw_hash_set& operator=(const raw_hash_set& that) {
  912. raw_hash_set tmp(that,
  913. AllocTraits::propagate_on_container_copy_assignment::value
  914. ? that.alloc_ref()
  915. : alloc_ref());
  916. swap(tmp);
  917. return *this;
  918. }
  919. raw_hash_set& operator=(raw_hash_set&& that) noexcept(
  920. absl::allocator_traits<allocator_type>::is_always_equal::value&&
  921. std::is_nothrow_move_assignable<hasher>::value&&
  922. std::is_nothrow_move_assignable<key_equal>::value) {
  923. // TODO(sbenza): We should only use the operations from the noexcept clause
  924. // to make sure we actually adhere to that contract.
  925. return move_assign(
  926. std::move(that),
  927. typename AllocTraits::propagate_on_container_move_assignment());
  928. }
  929. ~raw_hash_set() { destroy_slots(); }
  930. iterator begin() {
  931. auto it = iterator_at(0);
  932. it.skip_empty_or_deleted();
  933. return it;
  934. }
  935. iterator end() { return {}; }
  936. const_iterator begin() const {
  937. return const_cast<raw_hash_set*>(this)->begin();
  938. }
  939. const_iterator end() const { return {}; }
  940. const_iterator cbegin() const { return begin(); }
  941. const_iterator cend() const { return end(); }
  942. bool empty() const { return !size(); }
  943. size_t size() const { return size_; }
  944. size_t capacity() const { return capacity_; }
  945. size_t max_size() const { return (std::numeric_limits<size_t>::max)(); }
  946. ABSL_ATTRIBUTE_REINITIALIZES void clear() {
  947. // Iterating over this container is O(bucket_count()). When bucket_count()
  948. // is much greater than size(), iteration becomes prohibitively expensive.
  949. // For clear() it is more important to reuse the allocated array when the
  950. // container is small because allocation takes comparatively long time
  951. // compared to destruction of the elements of the container. So we pick the
  952. // largest bucket_count() threshold for which iteration is still fast and
  953. // past that we simply deallocate the array.
  954. if (capacity_ > 127) {
  955. destroy_slots();
  956. infoz().RecordClearedReservation();
  957. } else if (capacity_) {
  958. for (size_t i = 0; i != capacity_; ++i) {
  959. if (IsFull(ctrl_[i])) {
  960. PolicyTraits::destroy(&alloc_ref(), slots_ + i);
  961. }
  962. }
  963. size_ = 0;
  964. ResetCtrl(capacity_, ctrl_, slots_, sizeof(slot_type));
  965. reset_growth_left();
  966. }
  967. assert(empty());
  968. infoz().RecordStorageChanged(0, capacity_);
  969. }
  970. // This overload kicks in when the argument is an rvalue of insertable and
  971. // decomposable type other than init_type.
  972. //
  973. // flat_hash_map<std::string, int> m;
  974. // m.insert(std::make_pair("abc", 42));
  975. // TODO(cheshire): A type alias T2 is introduced as a workaround for the nvcc
  976. // bug.
  977. template <class T, RequiresInsertable<T> = 0,
  978. class T2 = T,
  979. typename std::enable_if<IsDecomposable<T2>::value, int>::type = 0,
  980. T* = nullptr>
  981. std::pair<iterator, bool> insert(T&& value) {
  982. return emplace(std::forward<T>(value));
  983. }
  984. // This overload kicks in when the argument is a bitfield or an lvalue of
  985. // insertable and decomposable type.
  986. //
  987. // union { int n : 1; };
  988. // flat_hash_set<int> s;
  989. // s.insert(n);
  990. //
  991. // flat_hash_set<std::string> s;
  992. // const char* p = "hello";
  993. // s.insert(p);
  994. //
  995. // TODO(romanp): Once we stop supporting gcc 5.1 and below, replace
  996. // RequiresInsertable<T> with RequiresInsertable<const T&>.
  997. // We are hitting this bug: https://godbolt.org/g/1Vht4f.
  998. template <
  999. class T, RequiresInsertable<T> = 0,
  1000. typename std::enable_if<IsDecomposable<const T&>::value, int>::type = 0>
  1001. std::pair<iterator, bool> insert(const T& value) {
  1002. return emplace(value);
  1003. }
  1004. // This overload kicks in when the argument is an rvalue of init_type. Its
  1005. // purpose is to handle brace-init-list arguments.
  1006. //
  1007. // flat_hash_map<std::string, int> s;
  1008. // s.insert({"abc", 42});
  1009. std::pair<iterator, bool> insert(init_type&& value) {
  1010. return emplace(std::move(value));
  1011. }
  1012. // TODO(cheshire): A type alias T2 is introduced as a workaround for the nvcc
  1013. // bug.
  1014. template <class T, RequiresInsertable<T> = 0, class T2 = T,
  1015. typename std::enable_if<IsDecomposable<T2>::value, int>::type = 0,
  1016. T* = nullptr>
  1017. iterator insert(const_iterator, T&& value) {
  1018. return insert(std::forward<T>(value)).first;
  1019. }
  1020. // TODO(romanp): Once we stop supporting gcc 5.1 and below, replace
  1021. // RequiresInsertable<T> with RequiresInsertable<const T&>.
  1022. // We are hitting this bug: https://godbolt.org/g/1Vht4f.
  1023. template <
  1024. class T, RequiresInsertable<T> = 0,
  1025. typename std::enable_if<IsDecomposable<const T&>::value, int>::type = 0>
  1026. iterator insert(const_iterator, const T& value) {
  1027. return insert(value).first;
  1028. }
  1029. iterator insert(const_iterator, init_type&& value) {
  1030. return insert(std::move(value)).first;
  1031. }
  1032. template <class InputIt>
  1033. void insert(InputIt first, InputIt last) {
  1034. for (; first != last; ++first) emplace(*first);
  1035. }
  1036. template <class T, RequiresNotInit<T> = 0, RequiresInsertable<const T&> = 0>
  1037. void insert(std::initializer_list<T> ilist) {
  1038. insert(ilist.begin(), ilist.end());
  1039. }
  1040. void insert(std::initializer_list<init_type> ilist) {
  1041. insert(ilist.begin(), ilist.end());
  1042. }
  1043. insert_return_type insert(node_type&& node) {
  1044. if (!node) return {end(), false, node_type()};
  1045. const auto& elem = PolicyTraits::element(CommonAccess::GetSlot(node));
  1046. auto res = PolicyTraits::apply(
  1047. InsertSlot<false>{*this, std::move(*CommonAccess::GetSlot(node))},
  1048. elem);
  1049. if (res.second) {
  1050. CommonAccess::Reset(&node);
  1051. return {res.first, true, node_type()};
  1052. } else {
  1053. return {res.first, false, std::move(node)};
  1054. }
  1055. }
  1056. iterator insert(const_iterator, node_type&& node) {
  1057. auto res = insert(std::move(node));
  1058. node = std::move(res.node);
  1059. return res.position;
  1060. }
  1061. // This overload kicks in if we can deduce the key from args. This enables us
  1062. // to avoid constructing value_type if an entry with the same key already
  1063. // exists.
  1064. //
  1065. // For example:
  1066. //
  1067. // flat_hash_map<std::string, std::string> m = {{"abc", "def"}};
  1068. // // Creates no std::string copies and makes no heap allocations.
  1069. // m.emplace("abc", "xyz");
  1070. template <class... Args, typename std::enable_if<
  1071. IsDecomposable<Args...>::value, int>::type = 0>
  1072. std::pair<iterator, bool> emplace(Args&&... args) {
  1073. return PolicyTraits::apply(EmplaceDecomposable{*this},
  1074. std::forward<Args>(args)...);
  1075. }
  1076. // This overload kicks in if we cannot deduce the key from args. It constructs
  1077. // value_type unconditionally and then either moves it into the table or
  1078. // destroys.
  1079. template <class... Args, typename std::enable_if<
  1080. !IsDecomposable<Args...>::value, int>::type = 0>
  1081. std::pair<iterator, bool> emplace(Args&&... args) {
  1082. alignas(slot_type) unsigned char raw[sizeof(slot_type)];
  1083. slot_type* slot = reinterpret_cast<slot_type*>(&raw);
  1084. PolicyTraits::construct(&alloc_ref(), slot, std::forward<Args>(args)...);
  1085. const auto& elem = PolicyTraits::element(slot);
  1086. return PolicyTraits::apply(InsertSlot<true>{*this, std::move(*slot)}, elem);
  1087. }
  1088. template <class... Args>
  1089. iterator emplace_hint(const_iterator, Args&&... args) {
  1090. return emplace(std::forward<Args>(args)...).first;
  1091. }
  1092. // Extension API: support for lazy emplace.
  1093. //
  1094. // Looks up key in the table. If found, returns the iterator to the element.
  1095. // Otherwise calls `f` with one argument of type `raw_hash_set::constructor`.
  1096. //
  1097. // `f` must abide by several restrictions:
  1098. // - it MUST call `raw_hash_set::constructor` with arguments as if a
  1099. // `raw_hash_set::value_type` is constructed,
  1100. // - it MUST NOT access the container before the call to
  1101. // `raw_hash_set::constructor`, and
  1102. // - it MUST NOT erase the lazily emplaced element.
  1103. // Doing any of these is undefined behavior.
  1104. //
  1105. // For example:
  1106. //
  1107. // std::unordered_set<ArenaString> s;
  1108. // // Makes ArenaStr even if "abc" is in the map.
  1109. // s.insert(ArenaString(&arena, "abc"));
  1110. //
  1111. // flat_hash_set<ArenaStr> s;
  1112. // // Makes ArenaStr only if "abc" is not in the map.
  1113. // s.lazy_emplace("abc", [&](const constructor& ctor) {
  1114. // ctor(&arena, "abc");
  1115. // });
  1116. //
  1117. // WARNING: This API is currently experimental. If there is a way to implement
  1118. // the same thing with the rest of the API, prefer that.
  1119. class constructor {
  1120. friend class raw_hash_set;
  1121. public:
  1122. template <class... Args>
  1123. void operator()(Args&&... args) const {
  1124. assert(*slot_);
  1125. PolicyTraits::construct(alloc_, *slot_, std::forward<Args>(args)...);
  1126. *slot_ = nullptr;
  1127. }
  1128. private:
  1129. constructor(allocator_type* a, slot_type** slot) : alloc_(a), slot_(slot) {}
  1130. allocator_type* alloc_;
  1131. slot_type** slot_;
  1132. };
  1133. template <class K = key_type, class F>
  1134. iterator lazy_emplace(const key_arg<K>& key, F&& f) {
  1135. auto res = find_or_prepare_insert(key);
  1136. if (res.second) {
  1137. slot_type* slot = slots_ + res.first;
  1138. std::forward<F>(f)(constructor(&alloc_ref(), &slot));
  1139. assert(!slot);
  1140. }
  1141. return iterator_at(res.first);
  1142. }
  1143. // Extension API: support for heterogeneous keys.
  1144. //
  1145. // std::unordered_set<std::string> s;
  1146. // // Turns "abc" into std::string.
  1147. // s.erase("abc");
  1148. //
  1149. // flat_hash_set<std::string> s;
  1150. // // Uses "abc" directly without copying it into std::string.
  1151. // s.erase("abc");
  1152. template <class K = key_type>
  1153. size_type erase(const key_arg<K>& key) {
  1154. auto it = find(key);
  1155. if (it == end()) return 0;
  1156. erase(it);
  1157. return 1;
  1158. }
  1159. // Erases the element pointed to by `it`. Unlike `std::unordered_set::erase`,
  1160. // this method returns void to reduce algorithmic complexity to O(1). The
  1161. // iterator is invalidated, so any increment should be done before calling
  1162. // erase. In order to erase while iterating across a map, use the following
  1163. // idiom (which also works for standard containers):
  1164. //
  1165. // for (auto it = m.begin(), end = m.end(); it != end;) {
  1166. // // `erase()` will invalidate `it`, so advance `it` first.
  1167. // auto copy_it = it++;
  1168. // if (<pred>) {
  1169. // m.erase(copy_it);
  1170. // }
  1171. // }
  1172. void erase(const_iterator cit) { erase(cit.inner_); }
  1173. // This overload is necessary because otherwise erase<K>(const K&) would be
  1174. // a better match if non-const iterator is passed as an argument.
  1175. void erase(iterator it) {
  1176. AssertIsFull(it.ctrl_);
  1177. PolicyTraits::destroy(&alloc_ref(), it.slot_);
  1178. erase_meta_only(it);
  1179. }
  1180. iterator erase(const_iterator first, const_iterator last) {
  1181. while (first != last) {
  1182. erase(first++);
  1183. }
  1184. return last.inner_;
  1185. }
  1186. // Moves elements from `src` into `this`.
  1187. // If the element already exists in `this`, it is left unmodified in `src`.
  1188. template <typename H, typename E>
  1189. void merge(raw_hash_set<Policy, H, E, Alloc>& src) { // NOLINT
  1190. assert(this != &src);
  1191. for (auto it = src.begin(), e = src.end(); it != e;) {
  1192. auto next = std::next(it);
  1193. if (PolicyTraits::apply(InsertSlot<false>{*this, std::move(*it.slot_)},
  1194. PolicyTraits::element(it.slot_))
  1195. .second) {
  1196. src.erase_meta_only(it);
  1197. }
  1198. it = next;
  1199. }
  1200. }
  1201. template <typename H, typename E>
  1202. void merge(raw_hash_set<Policy, H, E, Alloc>&& src) {
  1203. merge(src);
  1204. }
  1205. node_type extract(const_iterator position) {
  1206. AssertIsFull(position.inner_.ctrl_);
  1207. auto node =
  1208. CommonAccess::Transfer<node_type>(alloc_ref(), position.inner_.slot_);
  1209. erase_meta_only(position);
  1210. return node;
  1211. }
  1212. template <
  1213. class K = key_type,
  1214. typename std::enable_if<!std::is_same<K, iterator>::value, int>::type = 0>
  1215. node_type extract(const key_arg<K>& key) {
  1216. auto it = find(key);
  1217. return it == end() ? node_type() : extract(const_iterator{it});
  1218. }
  1219. void swap(raw_hash_set& that) noexcept(
  1220. IsNoThrowSwappable<hasher>() && IsNoThrowSwappable<key_equal>() &&
  1221. IsNoThrowSwappable<allocator_type>(
  1222. typename AllocTraits::propagate_on_container_swap{})) {
  1223. using std::swap;
  1224. swap(ctrl_, that.ctrl_);
  1225. swap(slots_, that.slots_);
  1226. swap(size_, that.size_);
  1227. swap(capacity_, that.capacity_);
  1228. swap(growth_left(), that.growth_left());
  1229. swap(hash_ref(), that.hash_ref());
  1230. swap(eq_ref(), that.eq_ref());
  1231. swap(infoz(), that.infoz());
  1232. SwapAlloc(alloc_ref(), that.alloc_ref(),
  1233. typename AllocTraits::propagate_on_container_swap{});
  1234. }
  1235. void rehash(size_t n) {
  1236. if (n == 0 && capacity_ == 0) return;
  1237. if (n == 0 && size_ == 0) {
  1238. destroy_slots();
  1239. infoz().RecordStorageChanged(0, 0);
  1240. infoz().RecordClearedReservation();
  1241. return;
  1242. }
  1243. // bitor is a faster way of doing `max` here. We will round up to the next
  1244. // power-of-2-minus-1, so bitor is good enough.
  1245. auto m = NormalizeCapacity(n | GrowthToLowerboundCapacity(size()));
  1246. // n == 0 unconditionally rehashes as per the standard.
  1247. if (n == 0 || m > capacity_) {
  1248. resize(m);
  1249. // This is after resize, to ensure that we have completed the allocation
  1250. // and have potentially sampled the hashtable.
  1251. infoz().RecordReservation(n);
  1252. }
  1253. }
  1254. void reserve(size_t n) {
  1255. if (n > size() + growth_left()) {
  1256. size_t m = GrowthToLowerboundCapacity(n);
  1257. resize(NormalizeCapacity(m));
  1258. // This is after resize, to ensure that we have completed the allocation
  1259. // and have potentially sampled the hashtable.
  1260. infoz().RecordReservation(n);
  1261. }
  1262. }
  1263. // Extension API: support for heterogeneous keys.
  1264. //
  1265. // std::unordered_set<std::string> s;
  1266. // // Turns "abc" into std::string.
  1267. // s.count("abc");
  1268. //
  1269. // ch_set<std::string> s;
  1270. // // Uses "abc" directly without copying it into std::string.
  1271. // s.count("abc");
  1272. template <class K = key_type>
  1273. size_t count(const key_arg<K>& key) const {
  1274. return find(key) == end() ? 0 : 1;
  1275. }
  1276. // Issues CPU prefetch instructions for the memory needed to find or insert
  1277. // a key. Like all lookup functions, this support heterogeneous keys.
  1278. //
  1279. // NOTE: This is a very low level operation and should not be used without
  1280. // specific benchmarks indicating its importance.
  1281. template <class K = key_type>
  1282. void prefetch(const key_arg<K>& key) const {
  1283. (void)key;
  1284. #if defined(__GNUC__)
  1285. prefetch_heap_block();
  1286. auto seq = probe(ctrl_, hash_ref()(key), capacity_);
  1287. __builtin_prefetch(static_cast<const void*>(ctrl_ + seq.offset()));
  1288. __builtin_prefetch(static_cast<const void*>(slots_ + seq.offset()));
  1289. #endif // __GNUC__
  1290. }
  1291. // The API of find() has two extensions.
  1292. //
  1293. // 1. The hash can be passed by the user. It must be equal to the hash of the
  1294. // key.
  1295. //
  1296. // 2. The type of the key argument doesn't have to be key_type. This is so
  1297. // called heterogeneous key support.
  1298. template <class K = key_type>
  1299. iterator find(const key_arg<K>& key, size_t hash) {
  1300. auto seq = probe(ctrl_, hash, capacity_);
  1301. while (true) {
  1302. Group g{ctrl_ + seq.offset()};
  1303. for (int i : g.Match(H2(hash))) {
  1304. if (ABSL_PREDICT_TRUE(PolicyTraits::apply(
  1305. EqualElement<K>{key, eq_ref()},
  1306. PolicyTraits::element(slots_ + seq.offset(i)))))
  1307. return iterator_at(seq.offset(i));
  1308. }
  1309. if (ABSL_PREDICT_TRUE(g.MatchEmpty())) return end();
  1310. seq.next();
  1311. assert(seq.index() <= capacity_ && "full table!");
  1312. }
  1313. }
  1314. template <class K = key_type>
  1315. iterator find(const key_arg<K>& key) {
  1316. prefetch_heap_block();
  1317. return find(key, hash_ref()(key));
  1318. }
  1319. template <class K = key_type>
  1320. const_iterator find(const key_arg<K>& key, size_t hash) const {
  1321. return const_cast<raw_hash_set*>(this)->find(key, hash);
  1322. }
  1323. template <class K = key_type>
  1324. const_iterator find(const key_arg<K>& key) const {
  1325. prefetch_heap_block();
  1326. return find(key, hash_ref()(key));
  1327. }
  1328. template <class K = key_type>
  1329. bool contains(const key_arg<K>& key) const {
  1330. return find(key) != end();
  1331. }
  1332. template <class K = key_type>
  1333. std::pair<iterator, iterator> equal_range(const key_arg<K>& key) {
  1334. auto it = find(key);
  1335. if (it != end()) return {it, std::next(it)};
  1336. return {it, it};
  1337. }
  1338. template <class K = key_type>
  1339. std::pair<const_iterator, const_iterator> equal_range(
  1340. const key_arg<K>& key) const {
  1341. auto it = find(key);
  1342. if (it != end()) return {it, std::next(it)};
  1343. return {it, it};
  1344. }
  1345. size_t bucket_count() const { return capacity_; }
  1346. float load_factor() const {
  1347. return capacity_ ? static_cast<double>(size()) / capacity_ : 0.0;
  1348. }
  1349. float max_load_factor() const { return 1.0f; }
  1350. void max_load_factor(float) {
  1351. // Does nothing.
  1352. }
  1353. hasher hash_function() const { return hash_ref(); }
  1354. key_equal key_eq() const { return eq_ref(); }
  1355. allocator_type get_allocator() const { return alloc_ref(); }
  1356. friend bool operator==(const raw_hash_set& a, const raw_hash_set& b) {
  1357. if (a.size() != b.size()) return false;
  1358. const raw_hash_set* outer = &a;
  1359. const raw_hash_set* inner = &b;
  1360. if (outer->capacity() > inner->capacity()) std::swap(outer, inner);
  1361. for (const value_type& elem : *outer)
  1362. if (!inner->has_element(elem)) return false;
  1363. return true;
  1364. }
  1365. friend bool operator!=(const raw_hash_set& a, const raw_hash_set& b) {
  1366. return !(a == b);
  1367. }
  1368. friend void swap(raw_hash_set& a,
  1369. raw_hash_set& b) noexcept(noexcept(a.swap(b))) {
  1370. a.swap(b);
  1371. }
  1372. private:
  1373. template <class Container, typename Enabler>
  1374. friend struct absl::container_internal::hashtable_debug_internal::
  1375. HashtableDebugAccess;
  1376. struct FindElement {
  1377. template <class K, class... Args>
  1378. const_iterator operator()(const K& key, Args&&...) const {
  1379. return s.find(key);
  1380. }
  1381. const raw_hash_set& s;
  1382. };
  1383. struct HashElement {
  1384. template <class K, class... Args>
  1385. size_t operator()(const K& key, Args&&...) const {
  1386. return h(key);
  1387. }
  1388. const hasher& h;
  1389. };
  1390. template <class K1>
  1391. struct EqualElement {
  1392. template <class K2, class... Args>
  1393. bool operator()(const K2& lhs, Args&&...) const {
  1394. return eq(lhs, rhs);
  1395. }
  1396. const K1& rhs;
  1397. const key_equal& eq;
  1398. };
  1399. struct EmplaceDecomposable {
  1400. template <class K, class... Args>
  1401. std::pair<iterator, bool> operator()(const K& key, Args&&... args) const {
  1402. auto res = s.find_or_prepare_insert(key);
  1403. if (res.second) {
  1404. s.emplace_at(res.first, std::forward<Args>(args)...);
  1405. }
  1406. return {s.iterator_at(res.first), res.second};
  1407. }
  1408. raw_hash_set& s;
  1409. };
  1410. template <bool do_destroy>
  1411. struct InsertSlot {
  1412. template <class K, class... Args>
  1413. std::pair<iterator, bool> operator()(const K& key, Args&&...) && {
  1414. auto res = s.find_or_prepare_insert(key);
  1415. if (res.second) {
  1416. PolicyTraits::transfer(&s.alloc_ref(), s.slots_ + res.first, &slot);
  1417. } else if (do_destroy) {
  1418. PolicyTraits::destroy(&s.alloc_ref(), &slot);
  1419. }
  1420. return {s.iterator_at(res.first), res.second};
  1421. }
  1422. raw_hash_set& s;
  1423. // Constructed slot. Either moved into place or destroyed.
  1424. slot_type&& slot;
  1425. };
  1426. // "erases" the object from the container, except that it doesn't actually
  1427. // destroy the object. It only updates all the metadata of the class.
  1428. // This can be used in conjunction with Policy::transfer to move the object to
  1429. // another place.
  1430. void erase_meta_only(const_iterator it) {
  1431. assert(IsFull(*it.inner_.ctrl_) && "erasing a dangling iterator");
  1432. --size_;
  1433. const size_t index = it.inner_.ctrl_ - ctrl_;
  1434. const size_t index_before = (index - Group::kWidth) & capacity_;
  1435. const auto empty_after = Group(it.inner_.ctrl_).MatchEmpty();
  1436. const auto empty_before = Group(ctrl_ + index_before).MatchEmpty();
  1437. // We count how many consecutive non empties we have to the right and to the
  1438. // left of `it`. If the sum is >= kWidth then there is at least one probe
  1439. // window that might have seen a full group.
  1440. bool was_never_full =
  1441. empty_before && empty_after &&
  1442. static_cast<size_t>(empty_after.TrailingZeros() +
  1443. empty_before.LeadingZeros()) < Group::kWidth;
  1444. SetCtrl(index, was_never_full ? ctrl_t::kEmpty : ctrl_t::kDeleted,
  1445. capacity_, ctrl_, slots_, sizeof(slot_type));
  1446. growth_left() += was_never_full;
  1447. infoz().RecordErase();
  1448. }
  1449. void initialize_slots() {
  1450. assert(capacity_);
  1451. // Folks with custom allocators often make unwarranted assumptions about the
  1452. // behavior of their classes vis-a-vis trivial destructability and what
  1453. // calls they will or wont make. Avoid sampling for people with custom
  1454. // allocators to get us out of this mess. This is not a hard guarantee but
  1455. // a workaround while we plan the exact guarantee we want to provide.
  1456. //
  1457. // People are often sloppy with the exact type of their allocator (sometimes
  1458. // it has an extra const or is missing the pair, but rebinds made it work
  1459. // anyway). To avoid the ambiguity, we work off SlotAlloc which we have
  1460. // bound more carefully.
  1461. if (std::is_same<SlotAlloc, std::allocator<slot_type>>::value &&
  1462. slots_ == nullptr) {
  1463. infoz() = Sample(sizeof(slot_type));
  1464. }
  1465. char* mem = static_cast<char*>(Allocate<alignof(slot_type)>(
  1466. &alloc_ref(),
  1467. AllocSize(capacity_, sizeof(slot_type), alignof(slot_type))));
  1468. ctrl_ = reinterpret_cast<ctrl_t*>(mem);
  1469. slots_ = reinterpret_cast<slot_type*>(
  1470. mem + SlotOffset(capacity_, alignof(slot_type)));
  1471. ResetCtrl(capacity_, ctrl_, slots_, sizeof(slot_type));
  1472. reset_growth_left();
  1473. infoz().RecordStorageChanged(size_, capacity_);
  1474. }
  1475. void destroy_slots() {
  1476. if (!capacity_) return;
  1477. for (size_t i = 0; i != capacity_; ++i) {
  1478. if (IsFull(ctrl_[i])) {
  1479. PolicyTraits::destroy(&alloc_ref(), slots_ + i);
  1480. }
  1481. }
  1482. // Unpoison before returning the memory to the allocator.
  1483. SanitizerUnpoisonMemoryRegion(slots_, sizeof(slot_type) * capacity_);
  1484. Deallocate<alignof(slot_type)>(
  1485. &alloc_ref(), ctrl_,
  1486. AllocSize(capacity_, sizeof(slot_type), alignof(slot_type)));
  1487. ctrl_ = EmptyGroup();
  1488. slots_ = nullptr;
  1489. size_ = 0;
  1490. capacity_ = 0;
  1491. growth_left() = 0;
  1492. }
  1493. void resize(size_t new_capacity) {
  1494. assert(IsValidCapacity(new_capacity));
  1495. auto* old_ctrl = ctrl_;
  1496. auto* old_slots = slots_;
  1497. const size_t old_capacity = capacity_;
  1498. capacity_ = new_capacity;
  1499. initialize_slots();
  1500. size_t total_probe_length = 0;
  1501. for (size_t i = 0; i != old_capacity; ++i) {
  1502. if (IsFull(old_ctrl[i])) {
  1503. size_t hash = PolicyTraits::apply(HashElement{hash_ref()},
  1504. PolicyTraits::element(old_slots + i));
  1505. auto target = find_first_non_full(ctrl_, hash, capacity_);
  1506. size_t new_i = target.offset;
  1507. total_probe_length += target.probe_length;
  1508. SetCtrl(new_i, H2(hash), capacity_, ctrl_, slots_, sizeof(slot_type));
  1509. PolicyTraits::transfer(&alloc_ref(), slots_ + new_i, old_slots + i);
  1510. }
  1511. }
  1512. if (old_capacity) {
  1513. SanitizerUnpoisonMemoryRegion(old_slots,
  1514. sizeof(slot_type) * old_capacity);
  1515. Deallocate<alignof(slot_type)>(
  1516. &alloc_ref(), old_ctrl,
  1517. AllocSize(old_capacity, sizeof(slot_type), alignof(slot_type)));
  1518. }
  1519. infoz().RecordRehash(total_probe_length);
  1520. }
  1521. void drop_deletes_without_resize() ABSL_ATTRIBUTE_NOINLINE {
  1522. assert(IsValidCapacity(capacity_));
  1523. assert(!is_small(capacity_));
  1524. // Algorithm:
  1525. // - mark all DELETED slots as EMPTY
  1526. // - mark all FULL slots as DELETED
  1527. // - for each slot marked as DELETED
  1528. // hash = Hash(element)
  1529. // target = find_first_non_full(hash)
  1530. // if target is in the same group
  1531. // mark slot as FULL
  1532. // else if target is EMPTY
  1533. // transfer element to target
  1534. // mark slot as EMPTY
  1535. // mark target as FULL
  1536. // else if target is DELETED
  1537. // swap current element with target element
  1538. // mark target as FULL
  1539. // repeat procedure for current slot with moved from element (target)
  1540. ConvertDeletedToEmptyAndFullToDeleted(ctrl_, capacity_);
  1541. alignas(slot_type) unsigned char raw[sizeof(slot_type)];
  1542. size_t total_probe_length = 0;
  1543. slot_type* slot = reinterpret_cast<slot_type*>(&raw);
  1544. for (size_t i = 0; i != capacity_; ++i) {
  1545. if (!IsDeleted(ctrl_[i])) continue;
  1546. const size_t hash = PolicyTraits::apply(
  1547. HashElement{hash_ref()}, PolicyTraits::element(slots_ + i));
  1548. const FindInfo target = find_first_non_full(ctrl_, hash, capacity_);
  1549. const size_t new_i = target.offset;
  1550. total_probe_length += target.probe_length;
  1551. // Verify if the old and new i fall within the same group wrt the hash.
  1552. // If they do, we don't need to move the object as it falls already in the
  1553. // best probe we can.
  1554. const size_t probe_offset = probe(ctrl_, hash, capacity_).offset();
  1555. const auto probe_index = [probe_offset, this](size_t pos) {
  1556. return ((pos - probe_offset) & capacity_) / Group::kWidth;
  1557. };
  1558. // Element doesn't move.
  1559. if (ABSL_PREDICT_TRUE(probe_index(new_i) == probe_index(i))) {
  1560. SetCtrl(i, H2(hash), capacity_, ctrl_, slots_, sizeof(slot_type));
  1561. continue;
  1562. }
  1563. if (IsEmpty(ctrl_[new_i])) {
  1564. // Transfer element to the empty spot.
  1565. // SetCtrl poisons/unpoisons the slots so we have to call it at the
  1566. // right time.
  1567. SetCtrl(new_i, H2(hash), capacity_, ctrl_, slots_, sizeof(slot_type));
  1568. PolicyTraits::transfer(&alloc_ref(), slots_ + new_i, slots_ + i);
  1569. SetCtrl(i, ctrl_t::kEmpty, capacity_, ctrl_, slots_, sizeof(slot_type));
  1570. } else {
  1571. assert(IsDeleted(ctrl_[new_i]));
  1572. SetCtrl(new_i, H2(hash), capacity_, ctrl_, slots_, sizeof(slot_type));
  1573. // Until we are done rehashing, DELETED marks previously FULL slots.
  1574. // Swap i and new_i elements.
  1575. PolicyTraits::transfer(&alloc_ref(), slot, slots_ + i);
  1576. PolicyTraits::transfer(&alloc_ref(), slots_ + i, slots_ + new_i);
  1577. PolicyTraits::transfer(&alloc_ref(), slots_ + new_i, slot);
  1578. --i; // repeat
  1579. }
  1580. }
  1581. reset_growth_left();
  1582. infoz().RecordRehash(total_probe_length);
  1583. }
  1584. void rehash_and_grow_if_necessary() {
  1585. if (capacity_ == 0) {
  1586. resize(1);
  1587. } else if (capacity_ > Group::kWidth &&
  1588. // Do these calcuations in 64-bit to avoid overflow.
  1589. size() * uint64_t{32} <= capacity_ * uint64_t{25}) {
  1590. // Squash DELETED without growing if there is enough capacity.
  1591. //
  1592. // Rehash in place if the current size is <= 25/32 of capacity_.
  1593. // Rationale for such a high factor: 1) drop_deletes_without_resize() is
  1594. // faster than resize, and 2) it takes quite a bit of work to add
  1595. // tombstones. In the worst case, seems to take approximately 4
  1596. // insert/erase pairs to create a single tombstone and so if we are
  1597. // rehashing because of tombstones, we can afford to rehash-in-place as
  1598. // long as we are reclaiming at least 1/8 the capacity without doing more
  1599. // than 2X the work. (Where "work" is defined to be size() for rehashing
  1600. // or rehashing in place, and 1 for an insert or erase.) But rehashing in
  1601. // place is faster per operation than inserting or even doubling the size
  1602. // of the table, so we actually afford to reclaim even less space from a
  1603. // resize-in-place. The decision is to rehash in place if we can reclaim
  1604. // at about 1/8th of the usable capacity (specifically 3/28 of the
  1605. // capacity) which means that the total cost of rehashing will be a small
  1606. // fraction of the total work.
  1607. //
  1608. // Here is output of an experiment using the BM_CacheInSteadyState
  1609. // benchmark running the old case (where we rehash-in-place only if we can
  1610. // reclaim at least 7/16*capacity_) vs. this code (which rehashes in place
  1611. // if we can recover 3/32*capacity_).
  1612. //
  1613. // Note that although in the worst-case number of rehashes jumped up from
  1614. // 15 to 190, but the number of operations per second is almost the same.
  1615. //
  1616. // Abridged output of running BM_CacheInSteadyState benchmark from
  1617. // raw_hash_set_benchmark. N is the number of insert/erase operations.
  1618. //
  1619. // | OLD (recover >= 7/16 | NEW (recover >= 3/32)
  1620. // size | N/s LoadFactor NRehashes | N/s LoadFactor NRehashes
  1621. // 448 | 145284 0.44 18 | 140118 0.44 19
  1622. // 493 | 152546 0.24 11 | 151417 0.48 28
  1623. // 538 | 151439 0.26 11 | 151152 0.53 38
  1624. // 583 | 151765 0.28 11 | 150572 0.57 50
  1625. // 628 | 150241 0.31 11 | 150853 0.61 66
  1626. // 672 | 149602 0.33 12 | 150110 0.66 90
  1627. // 717 | 149998 0.35 12 | 149531 0.70 129
  1628. // 762 | 149836 0.37 13 | 148559 0.74 190
  1629. // 807 | 149736 0.39 14 | 151107 0.39 14
  1630. // 852 | 150204 0.42 15 | 151019 0.42 15
  1631. drop_deletes_without_resize();
  1632. } else {
  1633. // Otherwise grow the container.
  1634. resize(capacity_ * 2 + 1);
  1635. }
  1636. }
  1637. bool has_element(const value_type& elem) const {
  1638. size_t hash = PolicyTraits::apply(HashElement{hash_ref()}, elem);
  1639. auto seq = probe(ctrl_, hash, capacity_);
  1640. while (true) {
  1641. Group g{ctrl_ + seq.offset()};
  1642. for (int i : g.Match(H2(hash))) {
  1643. if (ABSL_PREDICT_TRUE(PolicyTraits::element(slots_ + seq.offset(i)) ==
  1644. elem))
  1645. return true;
  1646. }
  1647. if (ABSL_PREDICT_TRUE(g.MatchEmpty())) return false;
  1648. seq.next();
  1649. assert(seq.index() <= capacity_ && "full table!");
  1650. }
  1651. return false;
  1652. }
  1653. // TODO(alkis): Optimize this assuming *this and that don't overlap.
  1654. raw_hash_set& move_assign(raw_hash_set&& that, std::true_type) {
  1655. raw_hash_set tmp(std::move(that));
  1656. swap(tmp);
  1657. return *this;
  1658. }
  1659. raw_hash_set& move_assign(raw_hash_set&& that, std::false_type) {
  1660. raw_hash_set tmp(std::move(that), alloc_ref());
  1661. swap(tmp);
  1662. return *this;
  1663. }
  1664. protected:
  1665. template <class K>
  1666. std::pair<size_t, bool> find_or_prepare_insert(const K& key) {
  1667. prefetch_heap_block();
  1668. auto hash = hash_ref()(key);
  1669. auto seq = probe(ctrl_, hash, capacity_);
  1670. while (true) {
  1671. Group g{ctrl_ + seq.offset()};
  1672. for (int i : g.Match(H2(hash))) {
  1673. if (ABSL_PREDICT_TRUE(PolicyTraits::apply(
  1674. EqualElement<K>{key, eq_ref()},
  1675. PolicyTraits::element(slots_ + seq.offset(i)))))
  1676. return {seq.offset(i), false};
  1677. }
  1678. if (ABSL_PREDICT_TRUE(g.MatchEmpty())) break;
  1679. seq.next();
  1680. assert(seq.index() <= capacity_ && "full table!");
  1681. }
  1682. return {prepare_insert(hash), true};
  1683. }
  1684. size_t prepare_insert(size_t hash) ABSL_ATTRIBUTE_NOINLINE {
  1685. auto target = find_first_non_full(ctrl_, hash, capacity_);
  1686. if (ABSL_PREDICT_FALSE(growth_left() == 0 &&
  1687. !IsDeleted(ctrl_[target.offset]))) {
  1688. rehash_and_grow_if_necessary();
  1689. target = find_first_non_full(ctrl_, hash, capacity_);
  1690. }
  1691. ++size_;
  1692. growth_left() -= IsEmpty(ctrl_[target.offset]);
  1693. SetCtrl(target.offset, H2(hash), capacity_, ctrl_, slots_,
  1694. sizeof(slot_type));
  1695. infoz().RecordInsert(hash, target.probe_length);
  1696. return target.offset;
  1697. }
  1698. // Constructs the value in the space pointed by the iterator. This only works
  1699. // after an unsuccessful find_or_prepare_insert() and before any other
  1700. // modifications happen in the raw_hash_set.
  1701. //
  1702. // PRECONDITION: i is an index returned from find_or_prepare_insert(k), where
  1703. // k is the key decomposed from `forward<Args>(args)...`, and the bool
  1704. // returned by find_or_prepare_insert(k) was true.
  1705. // POSTCONDITION: *m.iterator_at(i) == value_type(forward<Args>(args)...).
  1706. template <class... Args>
  1707. void emplace_at(size_t i, Args&&... args) {
  1708. PolicyTraits::construct(&alloc_ref(), slots_ + i,
  1709. std::forward<Args>(args)...);
  1710. assert(PolicyTraits::apply(FindElement{*this}, *iterator_at(i)) ==
  1711. iterator_at(i) &&
  1712. "constructed value does not match the lookup key");
  1713. }
  1714. iterator iterator_at(size_t i) { return {ctrl_ + i, slots_ + i}; }
  1715. const_iterator iterator_at(size_t i) const { return {ctrl_ + i, slots_ + i}; }
  1716. private:
  1717. friend struct RawHashSetTestOnlyAccess;
  1718. void reset_growth_left() {
  1719. growth_left() = CapacityToGrowth(capacity()) - size_;
  1720. }
  1721. size_t& growth_left() { return settings_.template get<0>(); }
  1722. void prefetch_heap_block() const {
  1723. // Prefetch the heap-allocated memory region to resolve potential TLB
  1724. // misses. This is intended to overlap with execution of calculating the
  1725. // hash for a key.
  1726. #if defined(__GNUC__)
  1727. __builtin_prefetch(static_cast<const void*>(ctrl_), 0, 1);
  1728. #endif // __GNUC__
  1729. }
  1730. HashtablezInfoHandle& infoz() { return settings_.template get<1>(); }
  1731. hasher& hash_ref() { return settings_.template get<2>(); }
  1732. const hasher& hash_ref() const { return settings_.template get<2>(); }
  1733. key_equal& eq_ref() { return settings_.template get<3>(); }
  1734. const key_equal& eq_ref() const { return settings_.template get<3>(); }
  1735. allocator_type& alloc_ref() { return settings_.template get<4>(); }
  1736. const allocator_type& alloc_ref() const {
  1737. return settings_.template get<4>();
  1738. }
  1739. // TODO(alkis): Investigate removing some of these fields:
  1740. // - ctrl/slots can be derived from each other
  1741. // - size can be moved into the slot array
  1742. ctrl_t* ctrl_ = EmptyGroup(); // [(capacity + 1 + NumClonedBytes()) * ctrl_t]
  1743. slot_type* slots_ = nullptr; // [capacity * slot_type]
  1744. size_t size_ = 0; // number of full slots
  1745. size_t capacity_ = 0; // total number of slots
  1746. absl::container_internal::CompressedTuple<size_t /* growth_left */,
  1747. HashtablezInfoHandle, hasher,
  1748. key_equal, allocator_type>
  1749. settings_{0, HashtablezInfoHandle{}, hasher{}, key_equal{},
  1750. allocator_type{}};
  1751. };
  1752. // Erases all elements that satisfy the predicate `pred` from the container `c`.
  1753. template <typename P, typename H, typename E, typename A, typename Predicate>
  1754. void EraseIf(Predicate& pred, raw_hash_set<P, H, E, A>* c) {
  1755. for (auto it = c->begin(), last = c->end(); it != last;) {
  1756. if (pred(*it)) {
  1757. c->erase(it++);
  1758. } else {
  1759. ++it;
  1760. }
  1761. }
  1762. }
  1763. namespace hashtable_debug_internal {
  1764. template <typename Set>
  1765. struct HashtableDebugAccess<Set, absl::void_t<typename Set::raw_hash_set>> {
  1766. using Traits = typename Set::PolicyTraits;
  1767. using Slot = typename Traits::slot_type;
  1768. static size_t GetNumProbes(const Set& set,
  1769. const typename Set::key_type& key) {
  1770. size_t num_probes = 0;
  1771. size_t hash = set.hash_ref()(key);
  1772. auto seq = probe(set.ctrl_, hash, set.capacity_);
  1773. while (true) {
  1774. container_internal::Group g{set.ctrl_ + seq.offset()};
  1775. for (int i : g.Match(container_internal::H2(hash))) {
  1776. if (Traits::apply(
  1777. typename Set::template EqualElement<typename Set::key_type>{
  1778. key, set.eq_ref()},
  1779. Traits::element(set.slots_ + seq.offset(i))))
  1780. return num_probes;
  1781. ++num_probes;
  1782. }
  1783. if (g.MatchEmpty()) return num_probes;
  1784. seq.next();
  1785. ++num_probes;
  1786. }
  1787. }
  1788. static size_t AllocatedByteSize(const Set& c) {
  1789. size_t capacity = c.capacity_;
  1790. if (capacity == 0) return 0;
  1791. size_t m = AllocSize(capacity, sizeof(Slot), alignof(Slot));
  1792. size_t per_slot = Traits::space_used(static_cast<const Slot*>(nullptr));
  1793. if (per_slot != ~size_t{}) {
  1794. m += per_slot * c.size();
  1795. } else {
  1796. for (size_t i = 0; i != capacity; ++i) {
  1797. if (container_internal::IsFull(c.ctrl_[i])) {
  1798. m += Traits::space_used(c.slots_ + i);
  1799. }
  1800. }
  1801. }
  1802. return m;
  1803. }
  1804. static size_t LowerBoundAllocatedByteSize(size_t size) {
  1805. size_t capacity = GrowthToLowerboundCapacity(size);
  1806. if (capacity == 0) return 0;
  1807. size_t m =
  1808. AllocSize(NormalizeCapacity(capacity), sizeof(Slot), alignof(Slot));
  1809. size_t per_slot = Traits::space_used(static_cast<const Slot*>(nullptr));
  1810. if (per_slot != ~size_t{}) {
  1811. m += per_slot * size;
  1812. }
  1813. return m;
  1814. }
  1815. };
  1816. } // namespace hashtable_debug_internal
  1817. } // namespace container_internal
  1818. ABSL_NAMESPACE_END
  1819. } // namespace absl
  1820. #endif // ABSL_CONTAINER_INTERNAL_RAW_HASH_SET_H_