re2 1.22.2 → 1.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (495) hide show
  1. package/README.md +60 -4
  2. package/binding.gyp +5 -1
  3. package/lib/addon.cc +4 -0
  4. package/lib/new.cc +1 -246
  5. package/lib/pattern.cc +252 -0
  6. package/lib/pattern.h +10 -0
  7. package/lib/set.cc +777 -0
  8. package/lib/wrapped_re2_set.h +42 -0
  9. package/package.json +21 -9
  10. package/re2.d.ts +46 -9
  11. package/vendor/abseil-cpp/CMake/AbseilDll.cmake +14 -24
  12. package/vendor/abseil-cpp/CMake/AbseilHelpers.cmake +3 -3
  13. package/vendor/abseil-cpp/CMake/README.md +2 -2
  14. package/vendor/abseil-cpp/CMakeLists.txt +3 -3
  15. package/vendor/abseil-cpp/MODULE.bazel +6 -9
  16. package/vendor/abseil-cpp/README.md +6 -8
  17. package/vendor/abseil-cpp/absl/abseil.podspec.gen.py +6 -4
  18. package/vendor/abseil-cpp/absl/algorithm/BUILD.bazel +3 -0
  19. package/vendor/abseil-cpp/absl/algorithm/CMakeLists.txt +1 -0
  20. package/vendor/abseil-cpp/absl/algorithm/container.h +2 -19
  21. package/vendor/abseil-cpp/absl/algorithm/container_test.cc +4 -11
  22. package/vendor/abseil-cpp/absl/base/BUILD.bazel +60 -45
  23. package/vendor/abseil-cpp/absl/base/CMakeLists.txt +57 -38
  24. package/vendor/abseil-cpp/absl/base/attributes.h +76 -7
  25. package/vendor/abseil-cpp/absl/base/attributes_test.cc +43 -0
  26. package/vendor/abseil-cpp/absl/base/call_once.h +11 -12
  27. package/vendor/abseil-cpp/absl/base/config.h +22 -129
  28. package/vendor/abseil-cpp/absl/base/exception_safety_testing_test.cc +0 -4
  29. package/vendor/abseil-cpp/absl/base/{internal/fast_type_id.h → fast_type_id.h} +11 -16
  30. package/vendor/abseil-cpp/absl/base/{internal/fast_type_id_test.cc → fast_type_id_test.cc} +34 -30
  31. package/vendor/abseil-cpp/absl/base/internal/cycleclock.cc +0 -5
  32. package/vendor/abseil-cpp/absl/base/internal/cycleclock_config.h +7 -7
  33. package/vendor/abseil-cpp/absl/base/internal/endian.h +34 -38
  34. package/vendor/abseil-cpp/absl/base/internal/iterator_traits.h +71 -0
  35. package/vendor/abseil-cpp/absl/base/internal/iterator_traits_test.cc +85 -0
  36. package/vendor/abseil-cpp/absl/base/internal/iterator_traits_test_helper.h +97 -0
  37. package/vendor/abseil-cpp/absl/base/internal/low_level_alloc.cc +39 -9
  38. package/vendor/abseil-cpp/absl/base/internal/low_level_alloc.h +6 -0
  39. package/vendor/abseil-cpp/absl/base/internal/poison.cc +7 -6
  40. package/vendor/abseil-cpp/absl/base/internal/spinlock.cc +15 -28
  41. package/vendor/abseil-cpp/absl/base/internal/spinlock.h +65 -35
  42. package/vendor/abseil-cpp/absl/base/internal/spinlock_benchmark.cc +2 -2
  43. package/vendor/abseil-cpp/absl/base/internal/sysinfo_test.cc +2 -2
  44. package/vendor/abseil-cpp/absl/base/internal/thread_identity_benchmark.cc +1 -1
  45. package/vendor/abseil-cpp/absl/base/internal/thread_identity_test.cc +4 -4
  46. package/vendor/abseil-cpp/absl/base/internal/unaligned_access.h +6 -6
  47. package/vendor/abseil-cpp/absl/base/internal/unscaledcycleclock.cc +4 -0
  48. package/vendor/abseil-cpp/absl/base/internal/unscaledcycleclock.h +8 -3
  49. package/vendor/abseil-cpp/absl/base/no_destructor.h +11 -32
  50. package/vendor/abseil-cpp/absl/base/no_destructor_test.cc +0 -4
  51. package/vendor/abseil-cpp/absl/base/nullability.h +83 -72
  52. package/vendor/abseil-cpp/absl/base/nullability_test.cc +25 -64
  53. package/vendor/abseil-cpp/absl/base/options.h +3 -80
  54. package/vendor/abseil-cpp/absl/base/policy_checks.h +7 -7
  55. package/vendor/abseil-cpp/absl/base/raw_logging_test.cc +15 -0
  56. package/vendor/abseil-cpp/absl/base/spinlock_test_common.cc +50 -30
  57. package/vendor/abseil-cpp/absl/cleanup/BUILD.bazel +2 -1
  58. package/vendor/abseil-cpp/absl/cleanup/CMakeLists.txt +0 -1
  59. package/vendor/abseil-cpp/absl/cleanup/cleanup.h +1 -3
  60. package/vendor/abseil-cpp/absl/cleanup/cleanup_test.cc +0 -2
  61. package/vendor/abseil-cpp/absl/cleanup/internal/cleanup.h +3 -4
  62. package/vendor/abseil-cpp/absl/container/BUILD.bazel +74 -1
  63. package/vendor/abseil-cpp/absl/container/CMakeLists.txt +73 -0
  64. package/vendor/abseil-cpp/absl/container/btree_benchmark.cc +51 -9
  65. package/vendor/abseil-cpp/absl/container/btree_map.h +8 -6
  66. package/vendor/abseil-cpp/absl/container/btree_set.h +8 -6
  67. package/vendor/abseil-cpp/absl/container/btree_test.cc +89 -4
  68. package/vendor/abseil-cpp/absl/container/fixed_array.h +7 -15
  69. package/vendor/abseil-cpp/absl/container/fixed_array_test.cc +17 -0
  70. package/vendor/abseil-cpp/absl/container/flat_hash_map.h +20 -15
  71. package/vendor/abseil-cpp/absl/container/flat_hash_map_test.cc +8 -14
  72. package/vendor/abseil-cpp/absl/container/flat_hash_set.h +19 -14
  73. package/vendor/abseil-cpp/absl/container/flat_hash_set_test.cc +46 -0
  74. package/vendor/abseil-cpp/absl/container/inlined_vector.h +7 -6
  75. package/vendor/abseil-cpp/absl/container/inlined_vector_test.cc +28 -0
  76. package/vendor/abseil-cpp/absl/container/internal/btree.h +132 -29
  77. package/vendor/abseil-cpp/absl/container/internal/btree_container.h +175 -71
  78. package/vendor/abseil-cpp/absl/container/internal/common.h +43 -0
  79. package/vendor/abseil-cpp/absl/container/internal/common_policy_traits.h +1 -2
  80. package/vendor/abseil-cpp/absl/container/internal/compressed_tuple.h +28 -24
  81. package/vendor/abseil-cpp/absl/container/internal/compressed_tuple_test.cc +4 -17
  82. package/vendor/abseil-cpp/absl/container/internal/container_memory.h +80 -17
  83. package/vendor/abseil-cpp/absl/container/internal/container_memory_test.cc +32 -2
  84. package/vendor/abseil-cpp/absl/container/internal/hash_function_defaults.h +13 -8
  85. package/vendor/abseil-cpp/absl/container/internal/hash_function_defaults_test.cc +1 -52
  86. package/vendor/abseil-cpp/absl/container/internal/hash_generator_testing.cc +9 -31
  87. package/vendor/abseil-cpp/absl/container/internal/hash_generator_testing.h +23 -32
  88. package/vendor/abseil-cpp/absl/container/internal/hash_policy_testing.h +5 -1
  89. package/vendor/abseil-cpp/absl/container/internal/hash_policy_traits.h +11 -23
  90. package/vendor/abseil-cpp/absl/container/internal/hash_policy_traits_test.cc +14 -9
  91. package/vendor/abseil-cpp/absl/container/internal/hashtable_control_bytes.h +516 -0
  92. package/vendor/abseil-cpp/absl/container/internal/hashtable_control_bytes_test.cc +259 -0
  93. package/vendor/abseil-cpp/absl/container/internal/hashtablez_sampler.cc +23 -6
  94. package/vendor/abseil-cpp/absl/container/internal/hashtablez_sampler.h +32 -13
  95. package/vendor/abseil-cpp/absl/container/internal/hashtablez_sampler_test.cc +8 -8
  96. package/vendor/abseil-cpp/absl/container/internal/inlined_vector.h +2 -7
  97. package/vendor/abseil-cpp/absl/container/internal/layout.h +26 -42
  98. package/vendor/abseil-cpp/absl/container/internal/raw_hash_map.h +199 -68
  99. package/vendor/abseil-cpp/absl/container/internal/raw_hash_set.cc +1506 -213
  100. package/vendor/abseil-cpp/absl/container/internal/raw_hash_set.h +1095 -1658
  101. package/vendor/abseil-cpp/absl/container/internal/raw_hash_set_allocator_test.cc +3 -2
  102. package/vendor/abseil-cpp/absl/container/internal/raw_hash_set_benchmark.cc +31 -29
  103. package/vendor/abseil-cpp/absl/container/internal/raw_hash_set_probe_benchmark.cc +51 -20
  104. package/vendor/abseil-cpp/absl/container/internal/raw_hash_set_resize_impl.h +79 -0
  105. package/vendor/abseil-cpp/absl/container/internal/raw_hash_set_resize_impl_test.cc +66 -0
  106. package/vendor/abseil-cpp/absl/container/internal/raw_hash_set_test.cc +707 -363
  107. package/vendor/abseil-cpp/absl/container/node_hash_map.h +20 -15
  108. package/vendor/abseil-cpp/absl/container/node_hash_map_test.cc +0 -3
  109. package/vendor/abseil-cpp/absl/container/node_hash_set.h +18 -13
  110. package/vendor/abseil-cpp/absl/container/sample_element_size_test.cc +3 -8
  111. package/vendor/abseil-cpp/absl/copts/AbseilConfigureCopts.cmake +1 -1
  112. package/vendor/abseil-cpp/absl/copts/GENERATED_AbseilCopts.cmake +9 -20
  113. package/vendor/abseil-cpp/absl/copts/GENERATED_copts.bzl +9 -20
  114. package/vendor/abseil-cpp/absl/copts/copts.py +24 -15
  115. package/vendor/abseil-cpp/absl/crc/BUILD.bazel +3 -0
  116. package/vendor/abseil-cpp/absl/crc/crc32c.cc +0 -4
  117. package/vendor/abseil-cpp/absl/crc/crc32c.h +7 -5
  118. package/vendor/abseil-cpp/absl/crc/crc32c_benchmark.cc +17 -4
  119. package/vendor/abseil-cpp/absl/crc/crc32c_test.cc +30 -0
  120. package/vendor/abseil-cpp/absl/crc/internal/cpu_detect.cc +17 -0
  121. package/vendor/abseil-cpp/absl/crc/internal/cpu_detect.h +7 -1
  122. package/vendor/abseil-cpp/absl/crc/internal/crc32_x86_arm_combined_simd.h +0 -22
  123. package/vendor/abseil-cpp/absl/crc/internal/crc_memcpy_x86_arm_combined.cc +5 -0
  124. package/vendor/abseil-cpp/absl/crc/internal/crc_x86_arm_combined.cc +136 -165
  125. package/vendor/abseil-cpp/absl/crc/internal/gen_crc32c_consts.py +90 -0
  126. package/vendor/abseil-cpp/absl/debugging/BUILD.bazel +7 -0
  127. package/vendor/abseil-cpp/absl/debugging/CMakeLists.txt +4 -0
  128. package/vendor/abseil-cpp/absl/debugging/internal/addresses.h +57 -0
  129. package/vendor/abseil-cpp/absl/debugging/internal/decode_rust_punycode.cc +1 -1
  130. package/vendor/abseil-cpp/absl/debugging/internal/decode_rust_punycode.h +5 -5
  131. package/vendor/abseil-cpp/absl/debugging/internal/demangle.cc +8 -35
  132. package/vendor/abseil-cpp/absl/debugging/internal/demangle_rust.cc +16 -16
  133. package/vendor/abseil-cpp/absl/debugging/internal/demangle_test.cc +11 -10
  134. package/vendor/abseil-cpp/absl/debugging/internal/stacktrace_aarch64-inl.inc +40 -37
  135. package/vendor/abseil-cpp/absl/debugging/internal/stacktrace_arm-inl.inc +16 -7
  136. package/vendor/abseil-cpp/absl/debugging/internal/stacktrace_config.h +6 -5
  137. package/vendor/abseil-cpp/absl/debugging/internal/stacktrace_emscripten-inl.inc +14 -5
  138. package/vendor/abseil-cpp/absl/debugging/internal/stacktrace_generic-inl.inc +10 -4
  139. package/vendor/abseil-cpp/absl/debugging/internal/stacktrace_powerpc-inl.inc +27 -16
  140. package/vendor/abseil-cpp/absl/debugging/internal/stacktrace_riscv-inl.inc +13 -4
  141. package/vendor/abseil-cpp/absl/debugging/internal/stacktrace_unimplemented-inl.inc +4 -3
  142. package/vendor/abseil-cpp/absl/debugging/internal/stacktrace_win32-inl.inc +15 -28
  143. package/vendor/abseil-cpp/absl/debugging/internal/stacktrace_x86-inl.inc +25 -14
  144. package/vendor/abseil-cpp/absl/debugging/internal/vdso_support.cc +4 -0
  145. package/vendor/abseil-cpp/absl/debugging/stacktrace.cc +161 -27
  146. package/vendor/abseil-cpp/absl/debugging/stacktrace.h +73 -5
  147. package/vendor/abseil-cpp/absl/debugging/stacktrace_test.cc +435 -1
  148. package/vendor/abseil-cpp/absl/debugging/symbolize_elf.inc +55 -63
  149. package/vendor/abseil-cpp/absl/debugging/symbolize_emscripten.inc +3 -2
  150. package/vendor/abseil-cpp/absl/debugging/symbolize_win32.inc +25 -6
  151. package/vendor/abseil-cpp/absl/flags/BUILD.bazel +6 -0
  152. package/vendor/abseil-cpp/absl/flags/CMakeLists.txt +3 -0
  153. package/vendor/abseil-cpp/absl/flags/commandlineflag.h +2 -2
  154. package/vendor/abseil-cpp/absl/flags/flag.h +4 -3
  155. package/vendor/abseil-cpp/absl/flags/internal/commandlineflag.h +2 -2
  156. package/vendor/abseil-cpp/absl/flags/internal/flag.cc +14 -13
  157. package/vendor/abseil-cpp/absl/flags/internal/flag.h +34 -34
  158. package/vendor/abseil-cpp/absl/flags/internal/program_name.cc +2 -2
  159. package/vendor/abseil-cpp/absl/flags/internal/registry.h +4 -3
  160. package/vendor/abseil-cpp/absl/flags/internal/usage.cc +2 -2
  161. package/vendor/abseil-cpp/absl/flags/parse.cc +10 -6
  162. package/vendor/abseil-cpp/absl/flags/reflection.cc +9 -7
  163. package/vendor/abseil-cpp/absl/flags/usage.cc +2 -2
  164. package/vendor/abseil-cpp/absl/flags/usage_config.cc +2 -2
  165. package/vendor/abseil-cpp/absl/functional/BUILD.bazel +7 -6
  166. package/vendor/abseil-cpp/absl/functional/CMakeLists.txt +2 -4
  167. package/vendor/abseil-cpp/absl/functional/any_invocable.h +15 -15
  168. package/vendor/abseil-cpp/absl/functional/any_invocable_test.cc +10 -42
  169. package/vendor/abseil-cpp/absl/functional/function_ref.h +2 -9
  170. package/vendor/abseil-cpp/absl/functional/function_ref_test.cc +10 -0
  171. package/vendor/abseil-cpp/absl/functional/function_type_benchmark.cc +1 -1
  172. package/vendor/abseil-cpp/absl/functional/internal/any_invocable.h +112 -227
  173. package/vendor/abseil-cpp/absl/functional/internal/front_binder.h +10 -12
  174. package/vendor/abseil-cpp/absl/functional/internal/function_ref.h +2 -5
  175. package/vendor/abseil-cpp/absl/functional/overload.h +0 -20
  176. package/vendor/abseil-cpp/absl/functional/overload_test.cc +1 -7
  177. package/vendor/abseil-cpp/absl/hash/BUILD.bazel +16 -9
  178. package/vendor/abseil-cpp/absl/hash/CMakeLists.txt +6 -9
  179. package/vendor/abseil-cpp/absl/hash/hash.h +18 -0
  180. package/vendor/abseil-cpp/absl/hash/hash_benchmark.cc +3 -0
  181. package/vendor/abseil-cpp/absl/hash/hash_instantiated_test.cc +1 -1
  182. package/vendor/abseil-cpp/absl/hash/hash_test.cc +131 -30
  183. package/vendor/abseil-cpp/absl/hash/hash_testing.h +20 -20
  184. package/vendor/abseil-cpp/absl/hash/internal/hash.cc +129 -17
  185. package/vendor/abseil-cpp/absl/hash/internal/hash.h +326 -362
  186. package/vendor/abseil-cpp/absl/hash/internal/low_level_hash_test.cc +54 -151
  187. package/vendor/abseil-cpp/absl/hash/internal/spy_hash_state.h +14 -2
  188. package/vendor/abseil-cpp/absl/{strings/cord_buffer.cc → hash/internal/weakly_mixed_integer.h} +14 -6
  189. package/vendor/abseil-cpp/absl/log/BUILD.bazel +4 -0
  190. package/vendor/abseil-cpp/absl/log/CMakeLists.txt +7 -0
  191. package/vendor/abseil-cpp/absl/log/check.h +2 -1
  192. package/vendor/abseil-cpp/absl/log/check_test_impl.inc +308 -14
  193. package/vendor/abseil-cpp/absl/log/die_if_null.h +2 -2
  194. package/vendor/abseil-cpp/absl/log/flags_test.cc +7 -0
  195. package/vendor/abseil-cpp/absl/log/globals.h +4 -5
  196. package/vendor/abseil-cpp/absl/log/internal/BUILD.bazel +13 -9
  197. package/vendor/abseil-cpp/absl/log/internal/append_truncated.h +28 -0
  198. package/vendor/abseil-cpp/absl/log/internal/check_op.cc +24 -22
  199. package/vendor/abseil-cpp/absl/log/internal/check_op.h +149 -94
  200. package/vendor/abseil-cpp/absl/log/internal/conditions.cc +5 -3
  201. package/vendor/abseil-cpp/absl/log/internal/conditions.h +7 -2
  202. package/vendor/abseil-cpp/absl/log/internal/fnmatch_test.cc +1 -0
  203. package/vendor/abseil-cpp/absl/log/internal/log_message.cc +85 -43
  204. package/vendor/abseil-cpp/absl/log/internal/log_message.h +84 -59
  205. package/vendor/abseil-cpp/absl/log/internal/log_sink_set.cc +4 -4
  206. package/vendor/abseil-cpp/absl/log/internal/nullstream.h +1 -0
  207. package/vendor/abseil-cpp/absl/log/internal/proto.cc +3 -2
  208. package/vendor/abseil-cpp/absl/log/internal/proto.h +3 -3
  209. package/vendor/abseil-cpp/absl/log/internal/strip.h +4 -12
  210. package/vendor/abseil-cpp/absl/log/internal/structured.h +3 -7
  211. package/vendor/abseil-cpp/absl/log/internal/vlog_config.cc +9 -9
  212. package/vendor/abseil-cpp/absl/log/internal/vlog_config.h +8 -6
  213. package/vendor/abseil-cpp/absl/log/internal/voidify.h +10 -4
  214. package/vendor/abseil-cpp/absl/log/log.h +48 -35
  215. package/vendor/abseil-cpp/absl/log/log_basic_test_impl.inc +45 -0
  216. package/vendor/abseil-cpp/absl/log/log_entry.cc +241 -19
  217. package/vendor/abseil-cpp/absl/log/log_entry.h +2 -0
  218. package/vendor/abseil-cpp/absl/log/log_format_test.cc +412 -6
  219. package/vendor/abseil-cpp/absl/log/log_modifier_methods_test.cc +20 -0
  220. package/vendor/abseil-cpp/absl/log/log_sink_registry.h +2 -2
  221. package/vendor/abseil-cpp/absl/log/log_streamer_test.cc +15 -2
  222. package/vendor/abseil-cpp/absl/log/scoped_mock_log.h +7 -1
  223. package/vendor/abseil-cpp/absl/log/structured_test.cc +1 -0
  224. package/vendor/abseil-cpp/absl/memory/BUILD.bazel +2 -0
  225. package/vendor/abseil-cpp/absl/meta/BUILD.bazel +2 -0
  226. package/vendor/abseil-cpp/absl/meta/type_traits.h +46 -175
  227. package/vendor/abseil-cpp/absl/meta/type_traits_test.cc +1 -478
  228. package/vendor/abseil-cpp/absl/numeric/BUILD.bazel +7 -3
  229. package/vendor/abseil-cpp/absl/numeric/CMakeLists.txt +2 -0
  230. package/vendor/abseil-cpp/absl/numeric/bits.h +68 -2
  231. package/vendor/abseil-cpp/absl/numeric/bits_benchmark.cc +1 -1
  232. package/vendor/abseil-cpp/absl/numeric/bits_test.cc +83 -0
  233. package/vendor/abseil-cpp/absl/numeric/int128.cc +0 -52
  234. package/vendor/abseil-cpp/absl/numeric/int128_benchmark.cc +14 -15
  235. package/vendor/abseil-cpp/absl/numeric/int128_test.cc +13 -8
  236. package/vendor/abseil-cpp/absl/numeric/internal/bits.h +39 -7
  237. package/vendor/abseil-cpp/absl/profiling/BUILD.bazel +47 -0
  238. package/vendor/abseil-cpp/absl/profiling/CMakeLists.txt +38 -0
  239. package/vendor/abseil-cpp/absl/profiling/hashtable.cc +124 -0
  240. package/vendor/abseil-cpp/absl/profiling/hashtable.h +40 -0
  241. package/vendor/abseil-cpp/absl/profiling/internal/exponential_biased.cc +1 -1
  242. package/vendor/abseil-cpp/absl/profiling/internal/profile_builder.cc +462 -0
  243. package/vendor/abseil-cpp/absl/profiling/internal/profile_builder.h +138 -0
  244. package/vendor/abseil-cpp/absl/profiling/internal/sample_recorder.h +9 -9
  245. package/vendor/abseil-cpp/absl/profiling/internal/sample_recorder_test.cc +7 -3
  246. package/vendor/abseil-cpp/absl/random/BUILD.bazel +6 -4
  247. package/vendor/abseil-cpp/absl/random/CMakeLists.txt +20 -19
  248. package/vendor/abseil-cpp/absl/random/benchmarks.cc +16 -23
  249. package/vendor/abseil-cpp/absl/random/bit_gen_ref.h +10 -11
  250. package/vendor/abseil-cpp/absl/random/bit_gen_ref_test.cc +7 -2
  251. package/vendor/abseil-cpp/absl/random/distributions.h +6 -8
  252. package/vendor/abseil-cpp/absl/random/gaussian_distribution.h +1 -1
  253. package/vendor/abseil-cpp/absl/random/internal/BUILD.bazel +19 -20
  254. package/vendor/abseil-cpp/absl/random/internal/distribution_caller.h +5 -6
  255. package/vendor/abseil-cpp/absl/random/internal/{pool_urbg.cc → entropy_pool.cc} +24 -92
  256. package/vendor/abseil-cpp/absl/{base/inline_variable_test_b.cc → random/internal/entropy_pool.h} +14 -6
  257. package/vendor/abseil-cpp/absl/random/internal/entropy_pool_test.cc +119 -0
  258. package/vendor/abseil-cpp/absl/random/internal/mock_helpers.h +6 -7
  259. package/vendor/abseil-cpp/absl/random/internal/nonsecure_base.h +5 -6
  260. package/vendor/abseil-cpp/absl/random/internal/nonsecure_base_test.cc +39 -0
  261. package/vendor/abseil-cpp/absl/random/internal/randen_benchmarks.cc +8 -6
  262. package/vendor/abseil-cpp/absl/random/internal/randen_detect.cc +1 -1
  263. package/vendor/abseil-cpp/absl/random/internal/seed_material.cc +20 -12
  264. package/vendor/abseil-cpp/absl/random/internal/seed_material.h +5 -5
  265. package/vendor/abseil-cpp/absl/random/internal/seed_material_test.cc +3 -0
  266. package/vendor/abseil-cpp/absl/random/mock_distributions_test.cc +5 -4
  267. package/vendor/abseil-cpp/absl/random/mocking_bit_gen.h +8 -10
  268. package/vendor/abseil-cpp/absl/random/random.h +88 -53
  269. package/vendor/abseil-cpp/absl/random/seed_sequences.cc +6 -2
  270. package/vendor/abseil-cpp/absl/status/BUILD.bazel +26 -0
  271. package/vendor/abseil-cpp/absl/status/internal/status_internal.cc +3 -4
  272. package/vendor/abseil-cpp/absl/status/internal/status_internal.h +3 -4
  273. package/vendor/abseil-cpp/absl/status/internal/status_matchers.cc +4 -3
  274. package/vendor/abseil-cpp/absl/status/internal/statusor_internal.h +194 -32
  275. package/vendor/abseil-cpp/absl/status/status.cc +4 -8
  276. package/vendor/abseil-cpp/absl/status/status.h +8 -8
  277. package/vendor/abseil-cpp/absl/{base/inline_variable_test_a.cc → status/status_benchmark.cc} +20 -10
  278. package/vendor/abseil-cpp/absl/status/status_matchers_test.cc +65 -0
  279. package/vendor/abseil-cpp/absl/status/status_payload_printer.h +2 -2
  280. package/vendor/abseil-cpp/absl/status/statusor.cc +2 -2
  281. package/vendor/abseil-cpp/absl/status/statusor.h +49 -102
  282. package/vendor/abseil-cpp/absl/status/statusor_benchmark.cc +480 -0
  283. package/vendor/abseil-cpp/absl/status/statusor_test.cc +323 -1
  284. package/vendor/abseil-cpp/absl/strings/BUILD.bazel +70 -34
  285. package/vendor/abseil-cpp/absl/strings/CMakeLists.txt +6 -3
  286. package/vendor/abseil-cpp/absl/strings/ascii.cc +9 -9
  287. package/vendor/abseil-cpp/absl/strings/ascii.h +18 -18
  288. package/vendor/abseil-cpp/absl/strings/ascii_benchmark.cc +5 -8
  289. package/vendor/abseil-cpp/absl/strings/charconv.cc +21 -22
  290. package/vendor/abseil-cpp/absl/strings/charconv.h +5 -5
  291. package/vendor/abseil-cpp/absl/strings/charconv_benchmark.cc +1 -2
  292. package/vendor/abseil-cpp/absl/strings/charset_benchmark.cc +1 -1
  293. package/vendor/abseil-cpp/absl/strings/cord.cc +54 -58
  294. package/vendor/abseil-cpp/absl/strings/cord.h +94 -84
  295. package/vendor/abseil-cpp/absl/strings/cord_analysis.cc +11 -11
  296. package/vendor/abseil-cpp/absl/strings/cord_analysis.h +3 -3
  297. package/vendor/abseil-cpp/absl/strings/cord_test.cc +23 -0
  298. package/vendor/abseil-cpp/absl/strings/cordz_test_helpers.h +4 -5
  299. package/vendor/abseil-cpp/absl/strings/escaping.cc +130 -149
  300. package/vendor/abseil-cpp/absl/strings/escaping.h +9 -10
  301. package/vendor/abseil-cpp/absl/strings/escaping_benchmark.cc +2 -3
  302. package/vendor/abseil-cpp/absl/strings/escaping_test.cc +19 -9
  303. package/vendor/abseil-cpp/absl/strings/internal/charconv_bigint.cc +1 -1
  304. package/vendor/abseil-cpp/absl/strings/internal/charconv_bigint_test.cc +1 -1
  305. package/vendor/abseil-cpp/absl/strings/internal/cord_internal.h +6 -10
  306. package/vendor/abseil-cpp/absl/strings/internal/cord_rep_btree.cc +0 -4
  307. package/vendor/abseil-cpp/absl/strings/internal/cordz_handle.cc +6 -6
  308. package/vendor/abseil-cpp/absl/strings/internal/cordz_info.cc +5 -9
  309. package/vendor/abseil-cpp/absl/strings/internal/cordz_info.h +2 -4
  310. package/vendor/abseil-cpp/absl/strings/internal/damerau_levenshtein_distance_benchmark.cc +56 -0
  311. package/vendor/abseil-cpp/absl/strings/internal/memutil_benchmark.cc +2 -3
  312. package/vendor/abseil-cpp/absl/strings/internal/ostringstream_benchmark.cc +1 -2
  313. package/vendor/abseil-cpp/absl/strings/internal/str_format/arg.cc +7 -63
  314. package/vendor/abseil-cpp/absl/strings/internal/str_format/arg.h +1 -11
  315. package/vendor/abseil-cpp/absl/strings/internal/str_format/convert_test.cc +1 -6
  316. package/vendor/abseil-cpp/absl/strings/internal/str_format/extension.cc +0 -22
  317. package/vendor/abseil-cpp/absl/strings/internal/str_format/extension_test.cc +3 -2
  318. package/vendor/abseil-cpp/absl/strings/internal/str_format/output.cc +5 -3
  319. package/vendor/abseil-cpp/absl/strings/internal/str_format/parser.h +4 -2
  320. package/vendor/abseil-cpp/absl/strings/internal/str_join_internal.h +3 -3
  321. package/vendor/abseil-cpp/absl/strings/internal/str_split_internal.h +7 -2
  322. package/vendor/abseil-cpp/absl/strings/internal/string_constant.h +0 -5
  323. package/vendor/abseil-cpp/absl/strings/internal/utf8.cc +96 -1
  324. package/vendor/abseil-cpp/absl/strings/internal/utf8.h +15 -1
  325. package/vendor/abseil-cpp/absl/strings/internal/utf8_test.cc +196 -3
  326. package/vendor/abseil-cpp/absl/strings/numbers.cc +53 -32
  327. package/vendor/abseil-cpp/absl/strings/numbers.h +87 -58
  328. package/vendor/abseil-cpp/absl/strings/numbers_benchmark.cc +1 -1
  329. package/vendor/abseil-cpp/absl/strings/numbers_test.cc +634 -120
  330. package/vendor/abseil-cpp/absl/strings/str_cat.cc +6 -7
  331. package/vendor/abseil-cpp/absl/strings/str_cat.h +32 -32
  332. package/vendor/abseil-cpp/absl/strings/str_cat_benchmark.cc +25 -1
  333. package/vendor/abseil-cpp/absl/strings/str_cat_test.cc +2 -7
  334. package/vendor/abseil-cpp/absl/strings/str_format.h +18 -18
  335. package/vendor/abseil-cpp/absl/strings/str_format_test.cc +8 -14
  336. package/vendor/abseil-cpp/absl/strings/str_join_benchmark.cc +2 -3
  337. package/vendor/abseil-cpp/absl/strings/str_replace.cc +3 -3
  338. package/vendor/abseil-cpp/absl/strings/str_replace.h +6 -6
  339. package/vendor/abseil-cpp/absl/strings/str_replace_benchmark.cc +2 -3
  340. package/vendor/abseil-cpp/absl/strings/str_split.h +2 -2
  341. package/vendor/abseil-cpp/absl/strings/str_split_benchmark.cc +2 -3
  342. package/vendor/abseil-cpp/absl/strings/string_view.cc +4 -9
  343. package/vendor/abseil-cpp/absl/strings/string_view.h +38 -39
  344. package/vendor/abseil-cpp/absl/strings/string_view_benchmark.cc +4 -6
  345. package/vendor/abseil-cpp/absl/strings/string_view_test.cc +2 -50
  346. package/vendor/abseil-cpp/absl/strings/strip.h +4 -4
  347. package/vendor/abseil-cpp/absl/strings/substitute.cc +5 -4
  348. package/vendor/abseil-cpp/absl/strings/substitute.h +66 -64
  349. package/vendor/abseil-cpp/absl/strings/substitute_benchmark.cc +158 -0
  350. package/vendor/abseil-cpp/absl/synchronization/BUILD.bazel +6 -1
  351. package/vendor/abseil-cpp/absl/synchronization/CMakeLists.txt +2 -1
  352. package/vendor/abseil-cpp/absl/synchronization/barrier.cc +1 -1
  353. package/vendor/abseil-cpp/absl/synchronization/barrier_test.cc +3 -3
  354. package/vendor/abseil-cpp/absl/synchronization/blocking_counter.cc +2 -2
  355. package/vendor/abseil-cpp/absl/synchronization/internal/create_thread_identity.cc +3 -3
  356. package/vendor/abseil-cpp/absl/synchronization/internal/futex_waiter.cc +0 -4
  357. package/vendor/abseil-cpp/absl/synchronization/internal/graphcycles.cc +30 -33
  358. package/vendor/abseil-cpp/absl/synchronization/internal/graphcycles_benchmark.cc +2 -3
  359. package/vendor/abseil-cpp/absl/synchronization/internal/graphcycles_test.cc +6 -5
  360. package/vendor/abseil-cpp/absl/synchronization/internal/kernel_timeout.cc +0 -5
  361. package/vendor/abseil-cpp/absl/synchronization/internal/pthread_waiter.cc +0 -4
  362. package/vendor/abseil-cpp/absl/synchronization/internal/sem_waiter.cc +0 -4
  363. package/vendor/abseil-cpp/absl/synchronization/internal/stdcpp_waiter.cc +0 -4
  364. package/vendor/abseil-cpp/absl/synchronization/internal/thread_pool.h +3 -3
  365. package/vendor/abseil-cpp/absl/synchronization/internal/waiter_base.cc +0 -4
  366. package/vendor/abseil-cpp/absl/synchronization/internal/waiter_test.cc +12 -3
  367. package/vendor/abseil-cpp/absl/synchronization/internal/win32_waiter.cc +0 -4
  368. package/vendor/abseil-cpp/absl/synchronization/lifetime_test.cc +4 -4
  369. package/vendor/abseil-cpp/absl/synchronization/mutex.cc +27 -29
  370. package/vendor/abseil-cpp/absl/synchronization/mutex.h +205 -126
  371. package/vendor/abseil-cpp/absl/synchronization/mutex_benchmark.cc +13 -31
  372. package/vendor/abseil-cpp/absl/synchronization/mutex_test.cc +183 -169
  373. package/vendor/abseil-cpp/absl/synchronization/notification.cc +5 -5
  374. package/vendor/abseil-cpp/absl/synchronization/notification.h +1 -1
  375. package/vendor/abseil-cpp/absl/synchronization/notification_test.cc +3 -3
  376. package/vendor/abseil-cpp/absl/time/BUILD.bazel +9 -1
  377. package/vendor/abseil-cpp/absl/time/CMakeLists.txt +3 -1
  378. package/vendor/abseil-cpp/absl/time/civil_time.cc +1 -0
  379. package/vendor/abseil-cpp/absl/time/civil_time_test.cc +134 -0
  380. package/vendor/abseil-cpp/absl/time/clock.cc +11 -14
  381. package/vendor/abseil-cpp/absl/time/duration.cc +14 -9
  382. package/vendor/abseil-cpp/absl/time/duration_test.cc +6 -7
  383. package/vendor/abseil-cpp/absl/time/internal/cctz/BUILD.bazel +14 -3
  384. package/vendor/abseil-cpp/absl/time/internal/cctz/include/cctz/civil_time_detail.h +12 -0
  385. package/vendor/abseil-cpp/absl/time/internal/cctz/include/cctz/time_zone.h +1 -1
  386. package/vendor/abseil-cpp/absl/time/internal/cctz/src/cctz_benchmark.cc +4 -490
  387. package/vendor/abseil-cpp/absl/time/internal/cctz/src/test_time_zone_names.cc +515 -0
  388. package/vendor/abseil-cpp/absl/time/internal/cctz/src/test_time_zone_names.h +33 -0
  389. package/vendor/abseil-cpp/absl/time/internal/cctz/src/time_zone_format.cc +41 -4
  390. package/vendor/abseil-cpp/absl/time/internal/cctz/src/time_zone_format_test.cc +22 -23
  391. package/vendor/abseil-cpp/absl/time/internal/cctz/src/time_zone_lookup.cc +90 -111
  392. package/vendor/abseil-cpp/absl/time/internal/cctz/src/time_zone_lookup_test.cc +1 -488
  393. package/vendor/abseil-cpp/absl/time/internal/cctz/testdata/version +1 -1
  394. package/vendor/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Coyhaique +0 -0
  395. package/vendor/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tehran +0 -0
  396. package/vendor/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Iran +0 -0
  397. package/vendor/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/zone1970.tab +2 -1
  398. package/vendor/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/zonenow.tab +1 -1
  399. package/vendor/abseil-cpp/absl/time/time.h +24 -18
  400. package/vendor/abseil-cpp/absl/time/time_test.cc +26 -0
  401. package/vendor/abseil-cpp/absl/types/BUILD.bazel +11 -164
  402. package/vendor/abseil-cpp/absl/types/CMakeLists.txt +23 -167
  403. package/vendor/abseil-cpp/absl/types/any.h +9 -484
  404. package/vendor/abseil-cpp/absl/types/optional.h +7 -747
  405. package/vendor/abseil-cpp/absl/types/span.h +46 -19
  406. package/vendor/abseil-cpp/absl/types/span_test.cc +27 -0
  407. package/vendor/abseil-cpp/absl/types/variant.h +5 -784
  408. package/vendor/abseil-cpp/absl/types/variant_test.cc +43 -2597
  409. package/vendor/abseil-cpp/absl/utility/BUILD.bazel +1 -41
  410. package/vendor/abseil-cpp/absl/utility/CMakeLists.txt +0 -40
  411. package/vendor/abseil-cpp/absl/utility/utility.h +10 -185
  412. package/vendor/abseil-cpp/ci/absl_alternate_options.h +2 -3
  413. package/vendor/abseil-cpp/ci/cmake_common.sh +2 -2
  414. package/vendor/abseil-cpp/ci/linux_arm_clang-latest_libcxx_bazel.sh +12 -13
  415. package/vendor/abseil-cpp/ci/linux_clang-latest_libcxx_asan_bazel.sh +24 -21
  416. package/vendor/abseil-cpp/ci/linux_clang-latest_libcxx_bazel.sh +12 -12
  417. package/vendor/abseil-cpp/ci/linux_clang-latest_libcxx_tsan_bazel.sh +23 -22
  418. package/vendor/abseil-cpp/ci/linux_clang-latest_libstdcxx_bazel.sh +20 -19
  419. package/vendor/abseil-cpp/ci/linux_docker_containers.sh +4 -4
  420. package/vendor/abseil-cpp/ci/linux_gcc-floor_libstdcxx_bazel.sh +17 -17
  421. package/vendor/abseil-cpp/ci/linux_gcc-latest_libstdcxx_bazel.sh +10 -10
  422. package/vendor/abseil-cpp/ci/linux_gcc-latest_libstdcxx_cmake.sh +1 -1
  423. package/vendor/abseil-cpp/ci/linux_gcc_alpine_cmake.sh +1 -1
  424. package/vendor/abseil-cpp/ci/macos_xcode_bazel.sh +9 -10
  425. package/vendor/abseil-cpp/ci/macos_xcode_cmake.sh +9 -1
  426. package/vendor/abseil-cpp/ci/windows_clangcl_bazel.bat +14 -6
  427. package/vendor/abseil-cpp/ci/windows_msvc_bazel.bat +14 -6
  428. package/vendor/abseil-cpp/ci/windows_msvc_cmake.bat +1 -1
  429. package/vendor/re2/.bazelrc +4 -4
  430. package/vendor/re2/.bcr/metadata.template.json +16 -0
  431. package/vendor/re2/.bcr/presubmit.yml +57 -0
  432. package/vendor/re2/.bcr/source.template.json +5 -0
  433. package/vendor/re2/.github/bazel.sh +1 -7
  434. package/vendor/re2/.github/workflows/ci-bazel.yml +5 -5
  435. package/vendor/re2/.github/workflows/ci-cmake.yml +4 -4
  436. package/vendor/re2/.github/workflows/ci.yml +5 -6
  437. package/vendor/re2/.github/workflows/pages.yml +3 -3
  438. package/vendor/re2/.github/workflows/python.yml +29 -24
  439. package/vendor/re2/.github/workflows/release-bazel.yml +42 -0
  440. package/vendor/re2/.github/workflows/release.yml +15 -4
  441. package/vendor/re2/BUILD.bazel +25 -0
  442. package/vendor/re2/CMakeLists.txt +100 -85
  443. package/vendor/re2/CONTRIBUTING.md +0 -1
  444. package/vendor/re2/MODULE.bazel +10 -10
  445. package/vendor/re2/Makefile +1 -1
  446. package/vendor/re2/README.md +259 -0
  447. package/vendor/re2/python/BUILD.bazel +8 -0
  448. package/vendor/re2/python/re2.py +1 -1
  449. package/vendor/re2/python/re2_test.py +6 -0
  450. package/vendor/re2/python/setup.py +3 -3
  451. package/vendor/re2/re2/bitmap256.cc +3 -4
  452. package/vendor/re2/re2/bitstate.cc +15 -10
  453. package/vendor/re2/re2/dfa.cc +1 -2
  454. package/vendor/re2/re2/parse.cc +3 -4
  455. package/vendor/re2/re2/prog.cc +1 -2
  456. package/vendor/re2/re2/prog.h +1 -0
  457. package/vendor/re2/re2/re2.cc +5 -0
  458. package/vendor/re2/re2/re2.h +9 -9
  459. package/vendor/re2/re2/set.cc +6 -0
  460. package/vendor/re2/re2/set.h +5 -0
  461. package/vendor/re2/re2/testing/re2_arg_test.cc +3 -3
  462. package/vendor/re2/re2/testing/re2_test.cc +8 -0
  463. package/vendor/re2/re2/testing/set_test.cc +5 -0
  464. package/vendor/re2/re2/walker-inl.h +1 -1
  465. package/vendor/abseil-cpp/WORKSPACE +0 -76
  466. package/vendor/abseil-cpp/WORKSPACE.bzlmod +0 -19
  467. package/vendor/abseil-cpp/absl/base/inline_variable_test.cc +0 -64
  468. package/vendor/abseil-cpp/absl/base/internal/inline_variable.h +0 -108
  469. package/vendor/abseil-cpp/absl/base/internal/inline_variable_testing.h +0 -46
  470. package/vendor/abseil-cpp/absl/base/internal/invoke.h +0 -241
  471. package/vendor/abseil-cpp/absl/base/internal/nullability_impl.h +0 -69
  472. package/vendor/abseil-cpp/absl/base/invoke_test.cc +0 -331
  473. package/vendor/abseil-cpp/absl/hash/internal/low_level_hash.cc +0 -148
  474. package/vendor/abseil-cpp/absl/hash/internal/low_level_hash.h +0 -54
  475. package/vendor/abseil-cpp/absl/random/internal/pool_urbg.h +0 -131
  476. package/vendor/abseil-cpp/absl/random/internal/pool_urbg_test.cc +0 -182
  477. package/vendor/abseil-cpp/absl/types/any_exception_safety_test.cc +0 -173
  478. package/vendor/abseil-cpp/absl/types/any_test.cc +0 -778
  479. package/vendor/abseil-cpp/absl/types/bad_any_cast.cc +0 -64
  480. package/vendor/abseil-cpp/absl/types/bad_any_cast.h +0 -75
  481. package/vendor/abseil-cpp/absl/types/bad_optional_access.cc +0 -66
  482. package/vendor/abseil-cpp/absl/types/bad_optional_access.h +0 -78
  483. package/vendor/abseil-cpp/absl/types/bad_variant_access.cc +0 -82
  484. package/vendor/abseil-cpp/absl/types/bad_variant_access.h +0 -82
  485. package/vendor/abseil-cpp/absl/types/internal/optional.h +0 -352
  486. package/vendor/abseil-cpp/absl/types/internal/variant.h +0 -1622
  487. package/vendor/abseil-cpp/absl/types/optional_exception_safety_test.cc +0 -292
  488. package/vendor/abseil-cpp/absl/types/optional_test.cc +0 -1615
  489. package/vendor/abseil-cpp/absl/types/variant_benchmark.cc +0 -222
  490. package/vendor/abseil-cpp/absl/types/variant_exception_safety_test.cc +0 -532
  491. package/vendor/abseil-cpp/absl/utility/internal/if_constexpr.h +0 -70
  492. package/vendor/abseil-cpp/absl/utility/internal/if_constexpr_test.cc +0 -79
  493. package/vendor/abseil-cpp/absl/utility/utility_test.cc +0 -239
  494. package/vendor/re2/.github/workflows/pr.yml +0 -34
  495. package/vendor/re2/README +0 -47
@@ -17,9 +17,11 @@
17
17
  #include <algorithm>
18
18
  #include <array>
19
19
  #include <atomic>
20
+ #include <bitset>
20
21
  #include <cmath>
21
22
  #include <cstddef>
22
23
  #include <cstdint>
24
+ #include <cstring>
23
25
  #include <deque>
24
26
  #include <functional>
25
27
  #include <iostream>
@@ -51,8 +53,11 @@
51
53
  #include "absl/container/internal/container_memory.h"
52
54
  #include "absl/container/internal/hash_function_defaults.h"
53
55
  #include "absl/container/internal/hash_policy_testing.h"
56
+ #include "absl/random/random.h"
57
+ #include "absl/container/internal/hashtable_control_bytes.h"
54
58
  #include "absl/container/internal/hashtable_debug.h"
55
59
  #include "absl/container/internal/hashtablez_sampler.h"
60
+ #include "absl/container/internal/raw_hash_set_resize_impl.h"
56
61
  #include "absl/container/internal/test_allocator.h"
57
62
  #include "absl/container/internal/test_instance_tracker.h"
58
63
  #include "absl/container/node_hash_set.h"
@@ -62,6 +67,7 @@
62
67
  #include "absl/log/log.h"
63
68
  #include "absl/memory/memory.h"
64
69
  #include "absl/meta/type_traits.h"
70
+ #include "absl/numeric/int128.h"
65
71
  #include "absl/strings/str_cat.h"
66
72
  #include "absl/strings/string_view.h"
67
73
  #include "absl/types/optional.h"
@@ -72,8 +78,8 @@ namespace container_internal {
72
78
 
73
79
  struct RawHashSetTestOnlyAccess {
74
80
  template <typename C>
75
- static auto GetCommon(const C& c) -> decltype(c.common()) {
76
- return c.common();
81
+ static auto GetCommon(C&& c) -> decltype(std::forward<C>(c).common()) {
82
+ return std::forward<C>(c).common();
77
83
  }
78
84
  template <typename C>
79
85
  static auto GetSlots(const C& c) -> decltype(c.slot_array()) {
@@ -88,16 +94,33 @@ struct RawHashSetTestOnlyAccess {
88
94
  namespace {
89
95
 
90
96
  using ::testing::ElementsAre;
91
- using ::testing::ElementsAreArray;
92
97
  using ::testing::Eq;
93
98
  using ::testing::Ge;
94
99
  using ::testing::Lt;
95
100
  using ::testing::Pair;
96
101
  using ::testing::UnorderedElementsAre;
102
+ using ::testing::UnorderedElementsAreArray;
97
103
 
98
104
  // Convenience function to static cast to ctrl_t.
99
105
  ctrl_t CtrlT(int i) { return static_cast<ctrl_t>(i); }
100
106
 
107
+ // Enables sampling with 1 percent sampling rate and
108
+ // resets the rate counter for the current thread.
109
+ void SetSamplingRateTo1Percent() {
110
+ SetHashtablezEnabled(true);
111
+ SetHashtablezSampleParameter(100); // Sample ~1% of tables.
112
+ // Reset rate counter for the current thread.
113
+ TestOnlyRefreshSamplingStateForCurrentThread();
114
+ }
115
+
116
+ // Disables sampling and resets the rate counter for the current thread.
117
+ void DisableSampling() {
118
+ SetHashtablezEnabled(false);
119
+ SetHashtablezSampleParameter(1 << 16);
120
+ // Reset rate counter for the current thread.
121
+ TestOnlyRefreshSamplingStateForCurrentThread();
122
+ }
123
+
101
124
  TEST(GrowthInfoTest, GetGrowthLeft) {
102
125
  GrowthInfo gi;
103
126
  gi.InitGrowthLeftNoDeleted(5);
@@ -186,6 +209,60 @@ TEST(GrowthInfoTest, OverwriteControlAsFull) {
186
209
  EXPECT_FALSE(gi.HasNoDeleted());
187
210
  }
188
211
 
212
+ TEST(GrowthInfoTest, HasNoGrowthLeftAssumingMayHaveDeleted) {
213
+ GrowthInfo gi;
214
+ gi.InitGrowthLeftNoDeleted(1);
215
+ gi.OverwriteFullAsDeleted();
216
+ EXPECT_EQ(gi.GetGrowthLeft(), 1);
217
+ EXPECT_FALSE(gi.HasNoGrowthLeftAssumingMayHaveDeleted());
218
+ gi.OverwriteControlAsFull(ctrl_t::kDeleted);
219
+ EXPECT_EQ(gi.GetGrowthLeft(), 1);
220
+ EXPECT_FALSE(gi.HasNoGrowthLeftAssumingMayHaveDeleted());
221
+ gi.OverwriteFullAsEmpty();
222
+ EXPECT_EQ(gi.GetGrowthLeft(), 2);
223
+ EXPECT_FALSE(gi.HasNoGrowthLeftAssumingMayHaveDeleted());
224
+ gi.OverwriteEmptyAsFull();
225
+ EXPECT_EQ(gi.GetGrowthLeft(), 1);
226
+ EXPECT_FALSE(gi.HasNoGrowthLeftAssumingMayHaveDeleted());
227
+ gi.OverwriteEmptyAsFull();
228
+ EXPECT_EQ(gi.GetGrowthLeft(), 0);
229
+ EXPECT_TRUE(gi.HasNoGrowthLeftAssumingMayHaveDeleted());
230
+ }
231
+
232
+ TEST(Util, OptimalMemcpySizeForSooSlotTransfer) {
233
+ EXPECT_EQ(1, OptimalMemcpySizeForSooSlotTransfer(1));
234
+ ASSERT_EQ(4, OptimalMemcpySizeForSooSlotTransfer(2));
235
+ ASSERT_EQ(4, OptimalMemcpySizeForSooSlotTransfer(3));
236
+ for (size_t slot_size = 4; slot_size <= 8; ++slot_size) {
237
+ ASSERT_EQ(8, OptimalMemcpySizeForSooSlotTransfer(slot_size));
238
+ }
239
+ // If maximum amount of memory is 16, then we can copy up to 16 bytes.
240
+ for (size_t slot_size = 9; slot_size <= 16; ++slot_size) {
241
+ ASSERT_EQ(16,
242
+ OptimalMemcpySizeForSooSlotTransfer(slot_size,
243
+ /*max_soo_slot_size=*/16));
244
+ ASSERT_EQ(16,
245
+ OptimalMemcpySizeForSooSlotTransfer(slot_size,
246
+ /*max_soo_slot_size=*/24));
247
+ }
248
+ // But we shouldn't try to copy more than maximum amount of memory.
249
+ for (size_t slot_size = 9; slot_size <= 12; ++slot_size) {
250
+ ASSERT_EQ(12, OptimalMemcpySizeForSooSlotTransfer(
251
+ slot_size, /*max_soo_slot_size=*/12));
252
+ }
253
+ for (size_t slot_size = 17; slot_size <= 24; ++slot_size) {
254
+ ASSERT_EQ(24,
255
+ OptimalMemcpySizeForSooSlotTransfer(slot_size,
256
+ /*max_soo_slot_size=*/24));
257
+ }
258
+ // We shouldn't copy more than maximum.
259
+ for (size_t slot_size = 17; slot_size <= 20; ++slot_size) {
260
+ ASSERT_EQ(20,
261
+ OptimalMemcpySizeForSooSlotTransfer(slot_size,
262
+ /*max_soo_slot_size=*/20));
263
+ }
264
+ }
265
+
189
266
  TEST(Util, NormalizeCapacity) {
190
267
  EXPECT_EQ(1, NormalizeCapacity(0));
191
268
  EXPECT_EQ(1, NormalizeCapacity(1));
@@ -202,9 +279,14 @@ TEST(Util, NormalizeCapacity) {
202
279
  TEST(Util, GrowthAndCapacity) {
203
280
  // Verify that GrowthToCapacity gives the minimum capacity that has enough
204
281
  // growth.
205
- for (size_t growth = 0; growth < 10000; ++growth) {
282
+ EXPECT_EQ(SizeToCapacity(0), 0);
283
+ EXPECT_EQ(SizeToCapacity(1), 1);
284
+ EXPECT_EQ(SizeToCapacity(2), 3);
285
+ EXPECT_EQ(SizeToCapacity(3), 3);
286
+ for (size_t growth = 1; growth < 10000; ++growth) {
206
287
  SCOPED_TRACE(growth);
207
- size_t capacity = NormalizeCapacity(GrowthToLowerboundCapacity(growth));
288
+ size_t capacity = SizeToCapacity(growth);
289
+ ASSERT_TRUE(IsValidCapacity(capacity));
208
290
  // The capacity is large enough for `growth`.
209
291
  EXPECT_THAT(CapacityToGrowth(capacity), Ge(growth));
210
292
  // For (capacity+1) < kWidth, growth should equal capacity.
@@ -224,8 +306,8 @@ TEST(Util, GrowthAndCapacity) {
224
306
  SCOPED_TRACE(capacity);
225
307
  size_t growth = CapacityToGrowth(capacity);
226
308
  EXPECT_THAT(growth, Lt(capacity));
227
- EXPECT_LE(GrowthToLowerboundCapacity(growth), capacity);
228
- EXPECT_EQ(NormalizeCapacity(GrowthToLowerboundCapacity(growth)), capacity);
309
+ EXPECT_EQ(SizeToCapacity(growth), capacity);
310
+ EXPECT_EQ(NormalizeCapacity(SizeToCapacity(growth)), capacity);
229
311
  }
230
312
  }
231
313
 
@@ -244,203 +326,6 @@ TEST(Util, probe_seq) {
244
326
  EXPECT_THAT(offsets, ElementsAre(0, 16, 48, 96, 32, 112, 80, 64));
245
327
  }
246
328
 
247
- TEST(BitMask, Smoke) {
248
- EXPECT_FALSE((BitMask<uint8_t, 8>(0)));
249
- EXPECT_TRUE((BitMask<uint8_t, 8>(5)));
250
-
251
- EXPECT_THAT((BitMask<uint8_t, 8>(0)), ElementsAre());
252
- EXPECT_THAT((BitMask<uint8_t, 8>(0x1)), ElementsAre(0));
253
- EXPECT_THAT((BitMask<uint8_t, 8>(0x2)), ElementsAre(1));
254
- EXPECT_THAT((BitMask<uint8_t, 8>(0x3)), ElementsAre(0, 1));
255
- EXPECT_THAT((BitMask<uint8_t, 8>(0x4)), ElementsAre(2));
256
- EXPECT_THAT((BitMask<uint8_t, 8>(0x5)), ElementsAre(0, 2));
257
- EXPECT_THAT((BitMask<uint8_t, 8>(0x55)), ElementsAre(0, 2, 4, 6));
258
- EXPECT_THAT((BitMask<uint8_t, 8>(0xAA)), ElementsAre(1, 3, 5, 7));
259
- }
260
-
261
- TEST(BitMask, WithShift_MatchPortable) {
262
- // See the non-SSE version of Group for details on what this math is for.
263
- uint64_t ctrl = 0x1716151413121110;
264
- uint64_t hash = 0x12;
265
- constexpr uint64_t lsbs = 0x0101010101010101ULL;
266
- auto x = ctrl ^ (lsbs * hash);
267
- uint64_t mask = (x - lsbs) & ~x & kMsbs8Bytes;
268
- EXPECT_EQ(0x0000000080800000, mask);
269
-
270
- BitMask<uint64_t, 8, 3> b(mask);
271
- EXPECT_EQ(*b, 2);
272
- }
273
-
274
- constexpr uint64_t kSome8BytesMask = /* */ 0x8000808080008000ULL;
275
- constexpr uint64_t kSome8BytesMaskAllOnes = 0xff00ffffff00ff00ULL;
276
- constexpr auto kSome8BytesMaskBits = std::array<int, 5>{1, 3, 4, 5, 7};
277
-
278
-
279
- TEST(BitMask, WithShift_FullMask) {
280
- EXPECT_THAT((BitMask<uint64_t, 8, 3>(kMsbs8Bytes)),
281
- ElementsAre(0, 1, 2, 3, 4, 5, 6, 7));
282
- EXPECT_THAT(
283
- (BitMask<uint64_t, 8, 3, /*NullifyBitsOnIteration=*/true>(kMsbs8Bytes)),
284
- ElementsAre(0, 1, 2, 3, 4, 5, 6, 7));
285
- EXPECT_THAT(
286
- (BitMask<uint64_t, 8, 3, /*NullifyBitsOnIteration=*/true>(~uint64_t{0})),
287
- ElementsAre(0, 1, 2, 3, 4, 5, 6, 7));
288
- }
289
-
290
- TEST(BitMask, WithShift_EmptyMask) {
291
- EXPECT_THAT((BitMask<uint64_t, 8, 3>(0)), ElementsAre());
292
- EXPECT_THAT((BitMask<uint64_t, 8, 3, /*NullifyBitsOnIteration=*/true>(0)),
293
- ElementsAre());
294
- }
295
-
296
- TEST(BitMask, WithShift_SomeMask) {
297
- EXPECT_THAT((BitMask<uint64_t, 8, 3>(kSome8BytesMask)),
298
- ElementsAreArray(kSome8BytesMaskBits));
299
- EXPECT_THAT((BitMask<uint64_t, 8, 3, /*NullifyBitsOnIteration=*/true>(
300
- kSome8BytesMask)),
301
- ElementsAreArray(kSome8BytesMaskBits));
302
- EXPECT_THAT((BitMask<uint64_t, 8, 3, /*NullifyBitsOnIteration=*/true>(
303
- kSome8BytesMaskAllOnes)),
304
- ElementsAreArray(kSome8BytesMaskBits));
305
- }
306
-
307
- TEST(BitMask, WithShift_SomeMaskExtraBitsForNullify) {
308
- // Verify that adding extra bits into non zero bytes is fine.
309
- uint64_t extra_bits = 77;
310
- for (int i = 0; i < 100; ++i) {
311
- // Add extra bits, but keep zero bytes untouched.
312
- uint64_t extra_mask = extra_bits & kSome8BytesMaskAllOnes;
313
- EXPECT_THAT((BitMask<uint64_t, 8, 3, /*NullifyBitsOnIteration=*/true>(
314
- kSome8BytesMask | extra_mask)),
315
- ElementsAreArray(kSome8BytesMaskBits))
316
- << i << " " << extra_mask;
317
- extra_bits = (extra_bits + 1) * 3;
318
- }
319
- }
320
-
321
- TEST(BitMask, LeadingTrailing) {
322
- EXPECT_EQ((BitMask<uint32_t, 16>(0x00001a40).LeadingZeros()), 3);
323
- EXPECT_EQ((BitMask<uint32_t, 16>(0x00001a40).TrailingZeros()), 6);
324
-
325
- EXPECT_EQ((BitMask<uint32_t, 16>(0x00000001).LeadingZeros()), 15);
326
- EXPECT_EQ((BitMask<uint32_t, 16>(0x00000001).TrailingZeros()), 0);
327
-
328
- EXPECT_EQ((BitMask<uint32_t, 16>(0x00008000).LeadingZeros()), 0);
329
- EXPECT_EQ((BitMask<uint32_t, 16>(0x00008000).TrailingZeros()), 15);
330
-
331
- EXPECT_EQ((BitMask<uint64_t, 8, 3>(0x0000008080808000).LeadingZeros()), 3);
332
- EXPECT_EQ((BitMask<uint64_t, 8, 3>(0x0000008080808000).TrailingZeros()), 1);
333
-
334
- EXPECT_EQ((BitMask<uint64_t, 8, 3>(0x0000000000000080).LeadingZeros()), 7);
335
- EXPECT_EQ((BitMask<uint64_t, 8, 3>(0x0000000000000080).TrailingZeros()), 0);
336
-
337
- EXPECT_EQ((BitMask<uint64_t, 8, 3>(0x8000000000000000).LeadingZeros()), 0);
338
- EXPECT_EQ((BitMask<uint64_t, 8, 3>(0x8000000000000000).TrailingZeros()), 7);
339
- }
340
-
341
- TEST(Group, EmptyGroup) {
342
- for (h2_t h = 0; h != 128; ++h) EXPECT_FALSE(Group{EmptyGroup()}.Match(h));
343
- }
344
-
345
- TEST(Group, Match) {
346
- if (Group::kWidth == 16) {
347
- ctrl_t group[] = {ctrl_t::kEmpty, CtrlT(1), ctrl_t::kDeleted, CtrlT(3),
348
- ctrl_t::kEmpty, CtrlT(5), ctrl_t::kSentinel, CtrlT(7),
349
- CtrlT(7), CtrlT(5), CtrlT(3), CtrlT(1),
350
- CtrlT(1), CtrlT(1), CtrlT(1), CtrlT(1)};
351
- EXPECT_THAT(Group{group}.Match(0), ElementsAre());
352
- EXPECT_THAT(Group{group}.Match(1), ElementsAre(1, 11, 12, 13, 14, 15));
353
- EXPECT_THAT(Group{group}.Match(3), ElementsAre(3, 10));
354
- EXPECT_THAT(Group{group}.Match(5), ElementsAre(5, 9));
355
- EXPECT_THAT(Group{group}.Match(7), ElementsAre(7, 8));
356
- } else if (Group::kWidth == 8) {
357
- ctrl_t group[] = {ctrl_t::kEmpty, CtrlT(1), CtrlT(2),
358
- ctrl_t::kDeleted, CtrlT(2), CtrlT(1),
359
- ctrl_t::kSentinel, CtrlT(1)};
360
- EXPECT_THAT(Group{group}.Match(0), ElementsAre());
361
- EXPECT_THAT(Group{group}.Match(1), ElementsAre(1, 5, 7));
362
- EXPECT_THAT(Group{group}.Match(2), ElementsAre(2, 4));
363
- } else {
364
- FAIL() << "No test coverage for Group::kWidth==" << Group::kWidth;
365
- }
366
- }
367
-
368
- TEST(Group, MaskEmpty) {
369
- if (Group::kWidth == 16) {
370
- ctrl_t group[] = {ctrl_t::kEmpty, CtrlT(1), ctrl_t::kDeleted, CtrlT(3),
371
- ctrl_t::kEmpty, CtrlT(5), ctrl_t::kSentinel, CtrlT(7),
372
- CtrlT(7), CtrlT(5), CtrlT(3), CtrlT(1),
373
- CtrlT(1), CtrlT(1), CtrlT(1), CtrlT(1)};
374
- EXPECT_THAT(Group{group}.MaskEmpty().LowestBitSet(), 0);
375
- EXPECT_THAT(Group{group}.MaskEmpty().HighestBitSet(), 4);
376
- } else if (Group::kWidth == 8) {
377
- ctrl_t group[] = {ctrl_t::kEmpty, CtrlT(1), CtrlT(2),
378
- ctrl_t::kDeleted, CtrlT(2), CtrlT(1),
379
- ctrl_t::kSentinel, CtrlT(1)};
380
- EXPECT_THAT(Group{group}.MaskEmpty().LowestBitSet(), 0);
381
- EXPECT_THAT(Group{group}.MaskEmpty().HighestBitSet(), 0);
382
- } else {
383
- FAIL() << "No test coverage for Group::kWidth==" << Group::kWidth;
384
- }
385
- }
386
-
387
- TEST(Group, MaskFull) {
388
- if (Group::kWidth == 16) {
389
- ctrl_t group[] = {
390
- ctrl_t::kEmpty, CtrlT(1), ctrl_t::kDeleted, CtrlT(3),
391
- ctrl_t::kEmpty, CtrlT(5), ctrl_t::kSentinel, CtrlT(7),
392
- CtrlT(7), CtrlT(5), ctrl_t::kDeleted, CtrlT(1),
393
- CtrlT(1), ctrl_t::kSentinel, ctrl_t::kEmpty, CtrlT(1)};
394
- EXPECT_THAT(Group{group}.MaskFull(),
395
- ElementsAre(1, 3, 5, 7, 8, 9, 11, 12, 15));
396
- } else if (Group::kWidth == 8) {
397
- ctrl_t group[] = {ctrl_t::kEmpty, CtrlT(1), ctrl_t::kEmpty,
398
- ctrl_t::kDeleted, CtrlT(2), ctrl_t::kSentinel,
399
- ctrl_t::kSentinel, CtrlT(1)};
400
- EXPECT_THAT(Group{group}.MaskFull(), ElementsAre(1, 4, 7));
401
- } else {
402
- FAIL() << "No test coverage for Group::kWidth==" << Group::kWidth;
403
- }
404
- }
405
-
406
- TEST(Group, MaskNonFull) {
407
- if (Group::kWidth == 16) {
408
- ctrl_t group[] = {
409
- ctrl_t::kEmpty, CtrlT(1), ctrl_t::kDeleted, CtrlT(3),
410
- ctrl_t::kEmpty, CtrlT(5), ctrl_t::kSentinel, CtrlT(7),
411
- CtrlT(7), CtrlT(5), ctrl_t::kDeleted, CtrlT(1),
412
- CtrlT(1), ctrl_t::kSentinel, ctrl_t::kEmpty, CtrlT(1)};
413
- EXPECT_THAT(Group{group}.MaskNonFull(),
414
- ElementsAre(0, 2, 4, 6, 10, 13, 14));
415
- } else if (Group::kWidth == 8) {
416
- ctrl_t group[] = {ctrl_t::kEmpty, CtrlT(1), ctrl_t::kEmpty,
417
- ctrl_t::kDeleted, CtrlT(2), ctrl_t::kSentinel,
418
- ctrl_t::kSentinel, CtrlT(1)};
419
- EXPECT_THAT(Group{group}.MaskNonFull(), ElementsAre(0, 2, 3, 5, 6));
420
- } else {
421
- FAIL() << "No test coverage for Group::kWidth==" << Group::kWidth;
422
- }
423
- }
424
-
425
- TEST(Group, MaskEmptyOrDeleted) {
426
- if (Group::kWidth == 16) {
427
- ctrl_t group[] = {ctrl_t::kEmpty, CtrlT(1), ctrl_t::kEmpty, CtrlT(3),
428
- ctrl_t::kDeleted, CtrlT(5), ctrl_t::kSentinel, CtrlT(7),
429
- CtrlT(7), CtrlT(5), CtrlT(3), CtrlT(1),
430
- CtrlT(1), CtrlT(1), CtrlT(1), CtrlT(1)};
431
- EXPECT_THAT(Group{group}.MaskEmptyOrDeleted().LowestBitSet(), 0);
432
- EXPECT_THAT(Group{group}.MaskEmptyOrDeleted().HighestBitSet(), 4);
433
- } else if (Group::kWidth == 8) {
434
- ctrl_t group[] = {ctrl_t::kEmpty, CtrlT(1), CtrlT(2),
435
- ctrl_t::kDeleted, CtrlT(2), CtrlT(1),
436
- ctrl_t::kSentinel, CtrlT(1)};
437
- EXPECT_THAT(Group{group}.MaskEmptyOrDeleted().LowestBitSet(), 0);
438
- EXPECT_THAT(Group{group}.MaskEmptyOrDeleted().HighestBitSet(), 3);
439
- } else {
440
- FAIL() << "No test coverage for Group::kWidth==" << Group::kWidth;
441
- }
442
- }
443
-
444
329
  TEST(Batch, DropDeletes) {
445
330
  constexpr size_t kCapacity = 63;
446
331
  constexpr size_t kGroupWidth = container_internal::Group::kWidth;
@@ -466,30 +351,6 @@ TEST(Batch, DropDeletes) {
466
351
  }
467
352
  }
468
353
 
469
- TEST(Group, CountLeadingEmptyOrDeleted) {
470
- const std::vector<ctrl_t> empty_examples = {ctrl_t::kEmpty, ctrl_t::kDeleted};
471
- const std::vector<ctrl_t> full_examples = {
472
- CtrlT(0), CtrlT(1), CtrlT(2), CtrlT(3),
473
- CtrlT(5), CtrlT(9), CtrlT(127), ctrl_t::kSentinel};
474
-
475
- for (ctrl_t empty : empty_examples) {
476
- std::vector<ctrl_t> e(Group::kWidth, empty);
477
- EXPECT_EQ(Group::kWidth, Group{e.data()}.CountLeadingEmptyOrDeleted());
478
- for (ctrl_t full : full_examples) {
479
- for (size_t i = 0; i != Group::kWidth; ++i) {
480
- std::vector<ctrl_t> f(Group::kWidth, empty);
481
- f[i] = full;
482
- EXPECT_EQ(i, Group{f.data()}.CountLeadingEmptyOrDeleted());
483
- }
484
- std::vector<ctrl_t> f(Group::kWidth, empty);
485
- f[Group::kWidth * 2 / 3] = full;
486
- f[Group::kWidth / 2] = full;
487
- EXPECT_EQ(Group::kWidth / 2,
488
- Group{f.data()}.CountLeadingEmptyOrDeleted());
489
- }
490
- }
491
- }
492
-
493
354
  template <class T, bool kTransferable = false, bool kSoo = false>
494
355
  struct ValuePolicy {
495
356
  using slot_type = T;
@@ -525,7 +386,7 @@ struct ValuePolicy {
525
386
  std::forward<F>(f), std::forward<Args>(args)...);
526
387
  }
527
388
 
528
- template <class Hash>
389
+ template <class Hash, bool kIsDefault>
529
390
  static constexpr HashSlotFn get_hash_slot_fn() {
530
391
  return nullptr;
531
392
  }
@@ -536,8 +397,6 @@ struct ValuePolicy {
536
397
  using IntPolicy = ValuePolicy<int64_t>;
537
398
  using Uint8Policy = ValuePolicy<uint8_t>;
538
399
 
539
- using TranferableIntPolicy = ValuePolicy<int64_t, /*kTransferable=*/true>;
540
-
541
400
  // For testing SOO.
542
401
  template <int N>
543
402
  class SizedValue {
@@ -576,6 +435,48 @@ template <int N, bool kSoo>
576
435
  using SizedValuePolicy =
577
436
  ValuePolicy<SizedValue<N>, /*kTransferable=*/true, kSoo>;
578
437
 
438
+ // Value is aligned as type T and contains N copies of it.
439
+ template <typename T, int N>
440
+ class AlignedValue {
441
+ public:
442
+ AlignedValue(int64_t v) { // NOLINT
443
+ for (int i = 0; i < N; ++i) {
444
+ vals_[i] = v;
445
+ if (sizeof(T) < sizeof(int64_t)) {
446
+ v >>= (8 * sizeof(T));
447
+ } else {
448
+ v = 0;
449
+ }
450
+ }
451
+ }
452
+ AlignedValue() : AlignedValue(0) {}
453
+ AlignedValue(const AlignedValue&) = default;
454
+ AlignedValue& operator=(const AlignedValue&) = default;
455
+
456
+ int64_t operator*() const {
457
+ if (sizeof(T) == sizeof(int64_t)) {
458
+ return vals_[0];
459
+ }
460
+ int64_t result = 0;
461
+ for (int i = N - 1; i >= 0; --i) {
462
+ result <<= (8 * sizeof(T));
463
+ result += vals_[i];
464
+ }
465
+ return result;
466
+ }
467
+ explicit operator int() const { return **this; }
468
+ explicit operator int64_t() const { return **this; }
469
+
470
+ template <typename H>
471
+ friend H AbslHashValue(H h, AlignedValue sv) {
472
+ return H::combine(std::move(h), *sv);
473
+ }
474
+ bool operator==(const AlignedValue& rhs) const { return **this == *rhs; }
475
+
476
+ private:
477
+ T vals_[N];
478
+ };
479
+
579
480
  class StringPolicy {
580
481
  template <class F, class K, class V,
581
482
  class = typename std::enable_if<
@@ -633,7 +534,7 @@ class StringPolicy {
633
534
  PairArgs(std::forward<Args>(args)...));
634
535
  }
635
536
 
636
- template <class Hash>
537
+ template <class Hash, bool kIsDefault>
637
538
  static constexpr HashSlotFn get_hash_slot_fn() {
638
539
  return nullptr;
639
540
  }
@@ -653,10 +554,11 @@ struct StringTable
653
554
  using Base::Base;
654
555
  };
655
556
 
656
- template <typename T, bool kTransferable = false, bool kSoo = false>
557
+ template <typename T, bool kTransferable = false, bool kSoo = false,
558
+ class Alloc = std::allocator<T>>
657
559
  struct ValueTable
658
560
  : raw_hash_set<ValuePolicy<T, kTransferable, kSoo>, hash_default_hash<T>,
659
- std::equal_to<T>, std::allocator<T>> {
561
+ std::equal_to<T>, Alloc> {
660
562
  using Base = typename ValueTable::raw_hash_set;
661
563
  using Base::Base;
662
564
  };
@@ -666,11 +568,6 @@ using Uint8Table = ValueTable<uint8_t>;
666
568
 
667
569
  using TransferableIntTable = ValueTable<int64_t, /*kTransferable=*/true>;
668
570
 
669
- constexpr size_t kNonSooSize = sizeof(HeapOrSoo) + 8;
670
- static_assert(sizeof(SizedValue<kNonSooSize>) >= kNonSooSize, "too small");
671
- using NonSooIntTable = ValueTable<SizedValue<kNonSooSize>>;
672
- using SooIntTable = ValueTable<int64_t, /*kTransferable=*/true, /*kSoo=*/true>;
673
-
674
571
  template <typename T>
675
572
  struct CustomAlloc : std::allocator<T> {
676
573
  CustomAlloc() = default;
@@ -691,6 +588,50 @@ struct CustomAllocIntTable
691
588
  using Base::Base;
692
589
  };
693
590
 
591
+ template <typename T>
592
+ struct ChangingSizeAndTrackingTypeAlloc : std::allocator<T> {
593
+ ChangingSizeAndTrackingTypeAlloc() = default;
594
+
595
+ template <typename U>
596
+ explicit ChangingSizeAndTrackingTypeAlloc(
597
+ const ChangingSizeAndTrackingTypeAlloc<U>& other) {
598
+ EXPECT_EQ(other.type_id,
599
+ ChangingSizeAndTrackingTypeAlloc<U>::ComputeTypeId());
600
+ }
601
+
602
+ template <class U>
603
+ struct rebind {
604
+ using other = ChangingSizeAndTrackingTypeAlloc<U>;
605
+ };
606
+
607
+ T* allocate(size_t n) {
608
+ EXPECT_EQ(type_id, ComputeTypeId());
609
+ return std::allocator<T>::allocate(n);
610
+ }
611
+
612
+ void deallocate(T* p, std::size_t n) {
613
+ EXPECT_EQ(type_id, ComputeTypeId());
614
+ return std::allocator<T>::deallocate(p, n);
615
+ }
616
+
617
+ static size_t ComputeTypeId() { return absl::HashOf(typeid(T).name()); }
618
+
619
+ // We add extra data to make the allocator size being changed.
620
+ // This also make type_id positioned differently, so that assertions in the
621
+ // allocator can catch bugs more likely.
622
+ char data_before[sizeof(T) * 3] = {0};
623
+ size_t type_id = ComputeTypeId();
624
+ char data_after[sizeof(T) * 5] = {0};
625
+ };
626
+
627
+ struct ChangingSizeAllocIntTable
628
+ : raw_hash_set<IntPolicy, hash_default_hash<int64_t>,
629
+ std::equal_to<int64_t>,
630
+ ChangingSizeAndTrackingTypeAlloc<int64_t>> {
631
+ using Base = typename ChangingSizeAllocIntTable::raw_hash_set;
632
+ using Base::Base;
633
+ };
634
+
694
635
  struct MinimumAlignmentUint8Table
695
636
  : raw_hash_set<Uint8Policy, hash_default_hash<uint8_t>,
696
637
  std::equal_to<uint8_t>, MinimumAlignmentAlloc<uint8_t>> {
@@ -744,28 +685,44 @@ struct BadHashFreezableIntTable
744
685
  using Base::Base;
745
686
  };
746
687
 
747
- struct BadTable : raw_hash_set<IntPolicy, BadFastHash, std::equal_to<int>,
688
+ struct BadTable : raw_hash_set<IntPolicy, BadFastHash, std::equal_to<int64_t>,
748
689
  std::allocator<int>> {
749
690
  using Base = typename BadTable::raw_hash_set;
750
691
  BadTable() = default;
751
692
  using Base::Base;
752
693
  };
753
694
 
695
+ constexpr size_t kNonSooSize = sizeof(HeapOrSoo) + 8;
696
+ using NonSooIntTableSlotType = SizedValue<kNonSooSize>;
697
+ static_assert(sizeof(NonSooIntTableSlotType) >= kNonSooSize, "too small");
698
+ using NonSooIntTable = ValueTable<NonSooIntTableSlotType>;
699
+ using SooInt32Table =
700
+ ValueTable<int32_t, /*kTransferable=*/true, /*kSoo=*/true>;
701
+ using SooIntTable = ValueTable<int64_t, /*kTransferable=*/true, /*kSoo=*/true>;
702
+ using NonMemcpyableSooIntTable =
703
+ ValueTable<int64_t, /*kTransferable=*/false, /*kSoo=*/true>;
704
+ using MemcpyableSooIntCustomAllocTable =
705
+ ValueTable<int64_t, /*kTransferable=*/true, /*kSoo=*/true,
706
+ ChangingSizeAndTrackingTypeAlloc<int64_t>>;
707
+ using NonMemcpyableSooIntCustomAllocTable =
708
+ ValueTable<int64_t, /*kTransferable=*/false, /*kSoo=*/true,
709
+ ChangingSizeAndTrackingTypeAlloc<int64_t>>;
710
+
754
711
  TEST(Table, EmptyFunctorOptimization) {
755
712
  static_assert(std::is_empty<std::equal_to<absl::string_view>>::value, "");
756
713
  static_assert(std::is_empty<std::allocator<int>>::value, "");
757
714
 
758
715
  struct MockTable {
716
+ size_t capacity;
717
+ uint64_t size;
759
718
  void* ctrl;
760
719
  void* slots;
761
- size_t size;
762
- size_t capacity;
763
720
  };
764
721
  struct StatelessHash {
765
722
  size_t operator()(absl::string_view) const { return 0; }
766
723
  };
767
724
  struct StatefulHash : StatelessHash {
768
- size_t dummy;
725
+ uint64_t dummy;
769
726
  };
770
727
 
771
728
  struct GenerationData {
@@ -803,7 +760,10 @@ TEST(Table, EmptyFunctorOptimization) {
803
760
  template <class TableType>
804
761
  class SooTest : public testing::Test {};
805
762
 
806
- using SooTableTypes = ::testing::Types<SooIntTable, NonSooIntTable>;
763
+ using SooTableTypes =
764
+ ::testing::Types<SooIntTable, NonSooIntTable, NonMemcpyableSooIntTable,
765
+ MemcpyableSooIntCustomAllocTable,
766
+ NonMemcpyableSooIntCustomAllocTable>;
807
767
  TYPED_TEST_SUITE(SooTest, SooTableTypes);
808
768
 
809
769
  TYPED_TEST(SooTest, Empty) {
@@ -812,6 +772,21 @@ TYPED_TEST(SooTest, Empty) {
812
772
  EXPECT_TRUE(t.empty());
813
773
  }
814
774
 
775
+ TEST(Table, Prefetch) {
776
+ IntTable t;
777
+ t.emplace(1);
778
+ // Works for both present and absent keys.
779
+ t.prefetch(1);
780
+ t.prefetch(2);
781
+
782
+ static constexpr int size = 10;
783
+ for (int i = 0; i < size; ++i) t.insert(i);
784
+ for (int i = 0; i < size; ++i) {
785
+ t.prefetch(i);
786
+ ASSERT_TRUE(t.find(i) != t.end()) << i;
787
+ }
788
+ }
789
+
815
790
  TYPED_TEST(SooTest, LookupEmpty) {
816
791
  TypeParam t;
817
792
  auto it = t.find(0);
@@ -942,8 +917,41 @@ TYPED_TEST(SooTest, InsertWithinCapacity) {
942
917
  template <class TableType>
943
918
  class SmallTableResizeTest : public testing::Test {};
944
919
 
945
- using SmallTableTypes =
946
- ::testing::Types<IntTable, TransferableIntTable, SooIntTable>;
920
+ using SmallTableTypes = ::testing::Types<
921
+ IntTable, TransferableIntTable, SooIntTable,
922
+ // int8
923
+ ValueTable<int8_t, /*kTransferable=*/true, /*kSoo=*/true>,
924
+ ValueTable<int8_t, /*kTransferable=*/false, /*kSoo=*/true>,
925
+ // int16
926
+ ValueTable<int16_t, /*kTransferable=*/true, /*kSoo=*/true>,
927
+ ValueTable<int16_t, /*kTransferable=*/false, /*kSoo=*/true>,
928
+ // int128
929
+ ValueTable<SizedValue<16>, /*kTransferable=*/true, /*kSoo=*/true>,
930
+ ValueTable<SizedValue<16>, /*kTransferable=*/false, /*kSoo=*/true>,
931
+ // int192
932
+ ValueTable<SizedValue<24>, /*kTransferable=*/true, /*kSoo=*/true>,
933
+ ValueTable<SizedValue<24>, /*kTransferable=*/false, /*kSoo=*/true>,
934
+ // Special tables.
935
+ MinimumAlignmentUint8Table, CustomAllocIntTable, ChangingSizeAllocIntTable,
936
+ BadTable,
937
+ // alignment 1, size 2.
938
+ ValueTable<AlignedValue<uint8_t, 2>, /*kTransferable=*/true, /*kSoo=*/true>,
939
+ ValueTable<AlignedValue<uint8_t, 2>, /*kTransferable=*/false,
940
+ /*kSoo=*/true>,
941
+ // alignment 1, size 7.
942
+ ValueTable<AlignedValue<uint8_t, 7>, /*kTransferable=*/true, /*kSoo=*/true>,
943
+ ValueTable<AlignedValue<uint8_t, 7>, /*kTransferable=*/false,
944
+ /*kSoo=*/true>,
945
+ // alignment 2, size 6.
946
+ ValueTable<AlignedValue<uint16_t, 3>, /*kTransferable=*/true,
947
+ /*kSoo=*/true>,
948
+ ValueTable<AlignedValue<uint16_t, 3>, /*kTransferable=*/false,
949
+ /*kSoo=*/true>,
950
+ // alignment 2, size 10.
951
+ ValueTable<AlignedValue<uint16_t, 5>, /*kTransferable=*/true,
952
+ /*kSoo=*/true>,
953
+ ValueTable<AlignedValue<uint16_t, 5>, /*kTransferable=*/false,
954
+ /*kSoo=*/true>>;
947
955
  TYPED_TEST_SUITE(SmallTableResizeTest, SmallTableTypes);
948
956
 
949
957
  TYPED_TEST(SmallTableResizeTest, InsertIntoSmallTable) {
@@ -952,7 +960,7 @@ TYPED_TEST(SmallTableResizeTest, InsertIntoSmallTable) {
952
960
  t.insert(i);
953
961
  ASSERT_EQ(t.size(), i + 1);
954
962
  for (int j = 0; j < i + 1; ++j) {
955
- EXPECT_TRUE(t.find(j) != t.end());
963
+ ASSERT_TRUE(t.find(j) != t.end());
956
964
  EXPECT_EQ(*t.find(j), j);
957
965
  }
958
966
  }
@@ -962,6 +970,9 @@ TYPED_TEST(SmallTableResizeTest, ResizeGrowSmallTables) {
962
970
  for (size_t source_size = 0; source_size < 32; ++source_size) {
963
971
  for (size_t target_size = source_size; target_size < 32; ++target_size) {
964
972
  for (bool rehash : {false, true}) {
973
+ SCOPED_TRACE(absl::StrCat("source_size: ", source_size,
974
+ ", target_size: ", target_size,
975
+ ", rehash: ", rehash));
965
976
  TypeParam t;
966
977
  for (size_t i = 0; i < source_size; ++i) {
967
978
  t.insert(static_cast<int>(i));
@@ -972,7 +983,7 @@ TYPED_TEST(SmallTableResizeTest, ResizeGrowSmallTables) {
972
983
  t.reserve(target_size);
973
984
  }
974
985
  for (size_t i = 0; i < source_size; ++i) {
975
- EXPECT_TRUE(t.find(static_cast<int>(i)) != t.end());
986
+ ASSERT_TRUE(t.find(static_cast<int>(i)) != t.end());
976
987
  EXPECT_EQ(*t.find(static_cast<int>(i)), static_cast<int>(i));
977
988
  }
978
989
  }
@@ -981,6 +992,7 @@ TYPED_TEST(SmallTableResizeTest, ResizeGrowSmallTables) {
981
992
  }
982
993
 
983
994
  TYPED_TEST(SmallTableResizeTest, ResizeReduceSmallTables) {
995
+ DisableSampling();
984
996
  for (size_t source_size = 0; source_size < 32; ++source_size) {
985
997
  for (size_t target_size = 0; target_size <= source_size; ++target_size) {
986
998
  TypeParam t;
@@ -996,7 +1008,7 @@ TYPED_TEST(SmallTableResizeTest, ResizeReduceSmallTables) {
996
1008
  << "rehash(0) must resize to the minimum capacity";
997
1009
  }
998
1010
  for (size_t i = 0; i < inserted_count; ++i) {
999
- EXPECT_TRUE(t.find(static_cast<int>(i)) != t.end());
1011
+ ASSERT_TRUE(t.find(static_cast<int>(i)) != t.end());
1000
1012
  EXPECT_EQ(*t.find(static_cast<int>(i)), static_cast<int>(i));
1001
1013
  }
1002
1014
  }
@@ -1047,6 +1059,9 @@ TYPED_TEST(SooTest, Contains2) {
1047
1059
 
1048
1060
  t.clear();
1049
1061
  EXPECT_FALSE(t.contains(0));
1062
+
1063
+ EXPECT_TRUE(t.insert(0).second);
1064
+ EXPECT_TRUE(t.contains(0));
1050
1065
  }
1051
1066
 
1052
1067
  int decompose_constructed;
@@ -1116,7 +1131,7 @@ struct DecomposePolicy {
1116
1131
  return std::forward<F>(f)(x, x);
1117
1132
  }
1118
1133
 
1119
- template <class Hash>
1134
+ template <class Hash, bool kIsDefault>
1120
1135
  static constexpr HashSlotFn get_hash_slot_fn() {
1121
1136
  return nullptr;
1122
1137
  }
@@ -1284,7 +1299,7 @@ struct Modulo1000Hash {
1284
1299
  };
1285
1300
 
1286
1301
  struct Modulo1000HashTable
1287
- : public raw_hash_set<IntPolicy, Modulo1000Hash, std::equal_to<int>,
1302
+ : public raw_hash_set<IntPolicy, Modulo1000Hash, std::equal_to<int64_t>,
1288
1303
  std::allocator<int>> {};
1289
1304
 
1290
1305
  // Test that rehash with no resize happen in case of many deleted slots.
@@ -1338,18 +1353,18 @@ TEST(Table, RehashWithNoResize) {
1338
1353
 
1339
1354
  TYPED_TEST(SooTest, InsertEraseStressTest) {
1340
1355
  TypeParam t;
1341
- const size_t kMinElementCount = 250;
1356
+ const size_t kMinElementCount = 50;
1342
1357
  std::deque<int> keys;
1343
1358
  size_t i = 0;
1344
1359
  for (; i < MaxDensitySize(kMinElementCount); ++i) {
1345
- t.emplace(i);
1360
+ t.emplace(static_cast<int64_t>(i));
1346
1361
  keys.push_back(i);
1347
1362
  }
1348
- const size_t kNumIterations = 1000000;
1363
+ const size_t kNumIterations = 20000;
1349
1364
  for (; i < kNumIterations; ++i) {
1350
1365
  ASSERT_EQ(1, t.erase(keys.front()));
1351
1366
  keys.pop_front();
1352
- t.emplace(i);
1367
+ t.emplace(static_cast<int64_t>(i));
1353
1368
  keys.push_back(i);
1354
1369
  }
1355
1370
  }
@@ -1367,8 +1382,11 @@ TEST(Table, InsertOverloads) {
1367
1382
 
1368
1383
  TYPED_TEST(SooTest, LargeTable) {
1369
1384
  TypeParam t;
1370
- for (int64_t i = 0; i != 100000; ++i) t.emplace(i << 40);
1371
- for (int64_t i = 0; i != 100000; ++i)
1385
+ for (int64_t i = 0; i != 10000; ++i) {
1386
+ t.emplace(i << 40);
1387
+ ASSERT_EQ(t.size(), i + 1);
1388
+ }
1389
+ for (int64_t i = 0; i != 10000; ++i)
1372
1390
  ASSERT_EQ(i << 40, static_cast<int64_t>(*t.find(i << 40)));
1373
1391
  }
1374
1392
 
@@ -1699,8 +1717,7 @@ ProbeStats CollectProbeStatsOnLinearlyTransformedKeys(
1699
1717
  const std::vector<int64_t>& keys, size_t num_iters) {
1700
1718
  ProbeStats stats;
1701
1719
 
1702
- std::random_device rd;
1703
- std::mt19937 rng(rd());
1720
+ absl::InsecureBitGen rng;
1704
1721
  auto linear_transform = [](size_t x, size_t y) { return x * 17 + y * 13; };
1705
1722
  std::uniform_int_distribution<size_t> dist(0, keys.size() - 1);
1706
1723
  while (num_iters--) {
@@ -1845,8 +1862,6 @@ TEST(Table, EraseInsertProbing) {
1845
1862
 
1846
1863
  TEST(Table, GrowthInfoDeletedBit) {
1847
1864
  BadTable t;
1848
- EXPECT_TRUE(
1849
- RawHashSetTestOnlyAccess::GetCommon(t).growth_info().HasNoDeleted());
1850
1865
  int64_t init_count = static_cast<int64_t>(
1851
1866
  CapacityToGrowth(NormalizeCapacity(Group::kWidth + 1)));
1852
1867
  for (int64_t i = 0; i < init_count; ++i) {
@@ -1966,6 +1981,43 @@ TYPED_TEST(SooTest, CopyConstruct) {
1966
1981
  }
1967
1982
  }
1968
1983
 
1984
+ TYPED_TEST(SooTest, CopyAssignment) {
1985
+ std::vector<size_t> sizes = {0, 1, 7, 25};
1986
+ for (size_t source_size : sizes) {
1987
+ for (size_t target_size : sizes) {
1988
+ SCOPED_TRACE(absl::StrCat("source_size: ", source_size,
1989
+ " target_size: ", target_size));
1990
+ TypeParam source;
1991
+ std::vector<int> source_elements;
1992
+ for (size_t i = 0; i < source_size; ++i) {
1993
+ source.emplace(static_cast<int>(i) * 2);
1994
+ source_elements.push_back(static_cast<int>(i) * 2);
1995
+ }
1996
+ TypeParam target;
1997
+ for (size_t i = 0; i < target_size; ++i) {
1998
+ target.emplace(static_cast<int>(i) * 3);
1999
+ }
2000
+ target = source;
2001
+ ASSERT_EQ(target.size(), source_size);
2002
+ ASSERT_THAT(target, UnorderedElementsAreArray(source_elements));
2003
+ }
2004
+ }
2005
+ }
2006
+
2007
+ TYPED_TEST(SooTest, CopyConstructWithSampling) {
2008
+ SetSamplingRateTo1Percent();
2009
+ for (int i = 0; i < 10000; ++i) {
2010
+ TypeParam t;
2011
+ t.emplace(0);
2012
+ EXPECT_EQ(1, t.size());
2013
+ {
2014
+ TypeParam u(t);
2015
+ EXPECT_EQ(1, u.size());
2016
+ EXPECT_THAT(*u.find(0), 0);
2017
+ }
2018
+ }
2019
+ }
2020
+
1969
2021
  TYPED_TEST(SooTest, CopyDifferentSizes) {
1970
2022
  TypeParam t;
1971
2023
 
@@ -2153,7 +2205,7 @@ TYPED_TEST(SooTest, FindFullDeletedRegression) {
2153
2205
 
2154
2206
  TYPED_TEST(SooTest, ReplacingDeletedSlotDoesNotRehash) {
2155
2207
  // We need to disable hashtablez to avoid issues related to SOO and sampling.
2156
- SetHashtablezEnabled(false);
2208
+ DisableSampling();
2157
2209
 
2158
2210
  size_t n;
2159
2211
  {
@@ -2195,12 +2247,10 @@ TEST(Table, NoThrowMoveAssign) {
2195
2247
  }
2196
2248
 
2197
2249
  TEST(Table, NoThrowSwappable) {
2198
- ASSERT_TRUE(
2199
- container_internal::IsNoThrowSwappable<absl::Hash<absl::string_view>>());
2200
- ASSERT_TRUE(container_internal::IsNoThrowSwappable<
2201
- std::equal_to<absl::string_view>>());
2202
- ASSERT_TRUE(container_internal::IsNoThrowSwappable<std::allocator<int>>());
2203
- EXPECT_TRUE(container_internal::IsNoThrowSwappable<StringTable>());
2250
+ ASSERT_TRUE(std::is_nothrow_swappable<absl::Hash<absl::string_view>>());
2251
+ ASSERT_TRUE(std::is_nothrow_swappable<std::equal_to<absl::string_view>>());
2252
+ ASSERT_TRUE(std::is_nothrow_swappable<std::allocator<int>>());
2253
+ EXPECT_TRUE(std::is_nothrow_swappable<StringTable>());
2204
2254
  }
2205
2255
 
2206
2256
  TEST(Table, HeterogeneousLookup) {
@@ -2329,6 +2379,19 @@ TEST(Table, Merge) {
2329
2379
  EXPECT_THAT(t2, UnorderedElementsAre(Pair("0", "~0")));
2330
2380
  }
2331
2381
 
2382
+ TEST(Table, MergeSmall) {
2383
+ StringTable t1, t2;
2384
+ t1.emplace("1", "1");
2385
+ t2.emplace("2", "2");
2386
+
2387
+ EXPECT_THAT(t1, UnorderedElementsAre(Pair("1", "1")));
2388
+ EXPECT_THAT(t2, UnorderedElementsAre(Pair("2", "2")));
2389
+
2390
+ t2.merge(t1);
2391
+ EXPECT_EQ(t1.size(), 0);
2392
+ EXPECT_THAT(t2, UnorderedElementsAre(Pair("1", "1"), Pair("2", "2")));
2393
+ }
2394
+
2332
2395
  TEST(Table, IteratorEmplaceConstructibleRequirement) {
2333
2396
  struct Value {
2334
2397
  explicit Value(absl::string_view view) : value(view) {}
@@ -2415,6 +2478,24 @@ TEST(Nodes, ExtractInsert) {
2415
2478
  EXPECT_FALSE(node); // NOLINT(bugprone-use-after-move)
2416
2479
  }
2417
2480
 
2481
+ TEST(Nodes, ExtractInsertSmall) {
2482
+ constexpr char k0[] = "Very long string zero.";
2483
+ StringTable t = {{k0, ""}};
2484
+ EXPECT_THAT(t, UnorderedElementsAre(Pair(k0, "")));
2485
+
2486
+ auto node = t.extract(k0);
2487
+ EXPECT_EQ(t.size(), 0);
2488
+ EXPECT_TRUE(node);
2489
+ EXPECT_FALSE(node.empty());
2490
+
2491
+ StringTable t2;
2492
+ StringTable::insert_return_type res = t2.insert(std::move(node));
2493
+ EXPECT_TRUE(res.inserted);
2494
+ EXPECT_THAT(*res.position, Pair(k0, ""));
2495
+ EXPECT_FALSE(res.node);
2496
+ EXPECT_THAT(t2, UnorderedElementsAre(Pair(k0, "")));
2497
+ }
2498
+
2418
2499
  TYPED_TEST(SooTest, HintInsert) {
2419
2500
  TypeParam t = {1, 2, 3};
2420
2501
  auto node = t.extract(1);
@@ -2450,38 +2531,41 @@ std::vector<int> OrderOfIteration(const T& t) {
2450
2531
  return res;
2451
2532
  }
2452
2533
 
2534
+ // Generate irrelevant seeds to avoid being stuck in the same last bit
2535
+ // in seed.
2536
+ void GenerateIrrelevantSeeds(int cnt) {
2537
+ for (int i = cnt % 17; i > 0; --i) {
2538
+ NextSeed();
2539
+ }
2540
+ }
2541
+
2453
2542
  // These IterationOrderChanges tests depend on non-deterministic behavior.
2454
- // We are injecting non-determinism from the pointer of the table, but do so in
2455
- // a way that only the page matters. We have to retry enough times to make sure
2456
- // we are touching different memory pages to cause the ordering to change.
2457
- // We also need to keep the old tables around to avoid getting the same memory
2458
- // blocks over and over.
2543
+ // We are injecting non-determinism to the table.
2544
+ // We have to retry enough times to make sure that the seed changes in bits that
2545
+ // matter for the iteration order.
2459
2546
  TYPED_TEST(SooTest, IterationOrderChangesByInstance) {
2547
+ DisableSampling(); // We do not want test to pass only because of sampling.
2460
2548
  for (bool do_reserve : {false, true}) {
2461
2549
  for (size_t size : {2u, 6u, 12u, 20u}) {
2462
2550
  SCOPED_TRACE(absl::StrCat("size: ", size, " do_reserve: ", do_reserve));
2463
2551
  const auto reference_table = MakeSimpleTable<TypeParam>(size, do_reserve);
2464
2552
  const auto reference = OrderOfIteration(reference_table);
2465
2553
 
2466
- std::vector<TypeParam> tables;
2467
2554
  bool found_difference = false;
2468
- for (int i = 0; !found_difference && i < 5000; ++i) {
2469
- tables.push_back(MakeSimpleTable<TypeParam>(size, do_reserve));
2470
- found_difference = OrderOfIteration(tables.back()) != reference;
2555
+ for (int i = 0; !found_difference && i < 500; ++i) {
2556
+ auto new_table = MakeSimpleTable<TypeParam>(size, do_reserve);
2557
+ found_difference = OrderOfIteration(new_table) != reference;
2558
+ GenerateIrrelevantSeeds(i);
2471
2559
  }
2472
2560
  if (!found_difference) {
2473
- FAIL() << "Iteration order remained the same across many attempts with "
2474
- "size "
2475
- << size;
2561
+ FAIL() << "Iteration order remained the same across many attempts.";
2476
2562
  }
2477
2563
  }
2478
2564
  }
2479
2565
  }
2480
2566
 
2481
2567
  TYPED_TEST(SooTest, IterationOrderChangesOnRehash) {
2482
- #ifdef ABSL_HAVE_ADDRESS_SANITIZER
2483
- GTEST_SKIP() << "Hash quality is lower in asan mode, causing flakiness.";
2484
- #endif
2568
+ DisableSampling(); // We do not want test to pass only because of sampling.
2485
2569
 
2486
2570
  // We test different sizes with many small numbers, because small table
2487
2571
  // resize has a different codepath.
@@ -2494,11 +2578,17 @@ TYPED_TEST(SooTest, IterationOrderChangesOnRehash) {
2494
2578
  }) {
2495
2579
  SCOPED_TRACE(absl::StrCat("size: ", size, " rehash_size: ", rehash_size,
2496
2580
  " do_reserve: ", do_reserve));
2497
- std::vector<TypeParam> garbage;
2498
2581
  bool ok = false;
2499
- for (int i = 0; i < 5000; ++i) {
2500
- auto t = MakeSimpleTable<TypeParam>(size, do_reserve);
2501
- const auto reference = OrderOfIteration(t);
2582
+ auto t = MakeSimpleTable<TypeParam>(size, do_reserve);
2583
+ const size_t original_capacity = t.capacity();
2584
+ auto reference = OrderOfIteration(t);
2585
+ for (int i = 0; i < 500; ++i) {
2586
+ if (i > 0 && rehash_size != 0) {
2587
+ // Rehash back to original size.
2588
+ t.rehash(0);
2589
+ ASSERT_EQ(t.capacity(), original_capacity);
2590
+ reference = OrderOfIteration(t);
2591
+ }
2502
2592
  // Force rehash.
2503
2593
  t.rehash(rehash_size);
2504
2594
  auto trial = OrderOfIteration(t);
@@ -2507,7 +2597,7 @@ TYPED_TEST(SooTest, IterationOrderChangesOnRehash) {
2507
2597
  ok = true;
2508
2598
  break;
2509
2599
  }
2510
- garbage.push_back(std::move(t));
2600
+ GenerateIrrelevantSeeds(i);
2511
2601
  }
2512
2602
  EXPECT_TRUE(ok)
2513
2603
  << "Iteration order remained the same across many attempts " << size
@@ -2521,7 +2611,7 @@ TYPED_TEST(SooTest, IterationOrderChangesOnRehash) {
2521
2611
  // This prevents dependency on pointer stability on small tables.
2522
2612
  TYPED_TEST(SooTest, UnstablePointers) {
2523
2613
  // We need to disable hashtablez to avoid issues related to SOO and sampling.
2524
- SetHashtablezEnabled(false);
2614
+ DisableSampling();
2525
2615
 
2526
2616
  TypeParam table;
2527
2617
 
@@ -2544,12 +2634,12 @@ TEST(TableDeathTest, InvalidIteratorAsserts) {
2544
2634
 
2545
2635
  NonSooIntTable t;
2546
2636
  // Extra simple "regexp" as regexp support is highly varied across platforms.
2547
- EXPECT_DEATH_IF_SUPPORTED(t.erase(t.end()),
2548
- "erase.* called on end.. iterator.");
2637
+ EXPECT_DEATH_IF_SUPPORTED(++t.end(), "operator.* called on end.. iterator.");
2549
2638
  typename NonSooIntTable::iterator iter;
2550
2639
  EXPECT_DEATH_IF_SUPPORTED(
2551
2640
  ++iter, "operator.* called on default-constructed iterator.");
2552
2641
  t.insert(0);
2642
+ t.insert(1);
2553
2643
  iter = t.begin();
2554
2644
  t.erase(iter);
2555
2645
  const char* const kErasedDeathMessage =
@@ -2653,18 +2743,29 @@ TYPED_TEST(SooTest, IteratorInvalidAssertsEqualityOperatorRehash) {
2653
2743
  template <typename T>
2654
2744
  class RawHashSamplerTest : public testing::Test {};
2655
2745
 
2656
- using RawHashSamplerTestTypes = ::testing::Types<SooIntTable, NonSooIntTable>;
2746
+ using RawHashSamplerTestTypes = ::testing::Types<
2747
+ // 32 bits to make sure that table is Soo for 32 bits platform as well.
2748
+ // 64 bits table is not SOO due to alignment.
2749
+ SooInt32Table,
2750
+ NonSooIntTable>;
2657
2751
  TYPED_TEST_SUITE(RawHashSamplerTest, RawHashSamplerTestTypes);
2658
2752
 
2659
2753
  TYPED_TEST(RawHashSamplerTest, Sample) {
2660
- constexpr bool soo_enabled = std::is_same<SooIntTable, TypeParam>::value;
2754
+ constexpr bool soo_enabled = std::is_same<SooInt32Table, TypeParam>::value;
2661
2755
  // Enable the feature even if the prod default is off.
2662
- SetHashtablezEnabled(true);
2663
- SetHashtablezSampleParameter(100); // Sample ~1% of tables.
2756
+ SetSamplingRateTo1Percent();
2757
+
2758
+ ASSERT_EQ(TypeParam().capacity(), soo_enabled ? SooCapacity() : 0);
2664
2759
 
2665
2760
  auto& sampler = GlobalHashtablezSampler();
2666
2761
  size_t start_size = 0;
2667
- absl::flat_hash_set<const HashtablezInfo*> preexisting_info;
2762
+
2763
+ // Reserve these utility tables, so that if they sampled, they'll be
2764
+ // preexisting.
2765
+ absl::flat_hash_set<const HashtablezInfo*> preexisting_info(10);
2766
+ absl::flat_hash_map<size_t, int> observed_checksums(10);
2767
+ absl::flat_hash_map<ssize_t, int> reservations(10);
2768
+
2668
2769
  start_size += sampler.Iterate([&](const HashtablezInfo& info) {
2669
2770
  preexisting_info.insert(&info);
2670
2771
  ++start_size;
@@ -2691,8 +2792,6 @@ TYPED_TEST(RawHashSamplerTest, Sample) {
2691
2792
  }
2692
2793
  }
2693
2794
  size_t end_size = 0;
2694
- absl::flat_hash_map<size_t, int> observed_checksums;
2695
- absl::flat_hash_map<ssize_t, int> reservations;
2696
2795
  end_size += sampler.Iterate([&](const HashtablezInfo& info) {
2697
2796
  ++end_size;
2698
2797
  if (preexisting_info.contains(&info)) return;
@@ -2713,12 +2812,12 @@ TYPED_TEST(RawHashSamplerTest, Sample) {
2713
2812
  // Expect that we sampled at the requested sampling rate of ~1%.
2714
2813
  EXPECT_NEAR((end_size - start_size) / static_cast<double>(tables.size()),
2715
2814
  0.01, 0.005);
2716
- EXPECT_EQ(observed_checksums.size(), 5);
2815
+ ASSERT_EQ(observed_checksums.size(), 5);
2717
2816
  for (const auto& [_, count] : observed_checksums) {
2718
2817
  EXPECT_NEAR((100 * count) / static_cast<double>(tables.size()), 0.2, 0.05);
2719
2818
  }
2720
2819
 
2721
- EXPECT_EQ(reservations.size(), 10);
2820
+ ASSERT_EQ(reservations.size(), 10);
2722
2821
  for (const auto& [reservation, count] : reservations) {
2723
2822
  EXPECT_GE(reservation, 0);
2724
2823
  EXPECT_LT(reservation, 100);
@@ -2729,25 +2828,25 @@ TYPED_TEST(RawHashSamplerTest, Sample) {
2729
2828
  }
2730
2829
 
2731
2830
  std::vector<const HashtablezInfo*> SampleSooMutation(
2732
- absl::FunctionRef<void(SooIntTable&)> mutate_table) {
2831
+ absl::FunctionRef<void(SooInt32Table&)> mutate_table) {
2733
2832
  // Enable the feature even if the prod default is off.
2734
- SetHashtablezEnabled(true);
2735
- SetHashtablezSampleParameter(100); // Sample ~1% of tables.
2833
+ SetSamplingRateTo1Percent();
2736
2834
 
2737
2835
  auto& sampler = GlobalHashtablezSampler();
2738
- size_t start_size = 0;
2739
- absl::flat_hash_set<const HashtablezInfo*> preexisting_info;
2836
+ int64_t start_size = 0;
2837
+ // Reserve the table, so that if it sampled, it'll be preexisting.
2838
+ absl::flat_hash_set<const HashtablezInfo*> preexisting_info(10);
2740
2839
  start_size += sampler.Iterate([&](const HashtablezInfo& info) {
2741
2840
  preexisting_info.insert(&info);
2742
2841
  ++start_size;
2743
2842
  });
2744
2843
 
2745
- std::vector<SooIntTable> tables;
2844
+ std::vector<SooInt32Table> tables;
2746
2845
  for (int i = 0; i < 1000000; ++i) {
2747
2846
  tables.emplace_back();
2748
2847
  mutate_table(tables.back());
2749
2848
  }
2750
- size_t end_size = 0;
2849
+ int64_t end_size = 0;
2751
2850
  std::vector<const HashtablezInfo*> infos;
2752
2851
  end_size += sampler.Iterate([&](const HashtablezInfo& info) {
2753
2852
  ++end_size;
@@ -2762,16 +2861,16 @@ std::vector<const HashtablezInfo*> SampleSooMutation(
2762
2861
  }
2763
2862
 
2764
2863
  TEST(RawHashSamplerTest, SooTableInsertToEmpty) {
2765
- if (SooIntTable().capacity() != SooCapacity()) {
2864
+ if (SooInt32Table().capacity() != SooCapacity()) {
2766
2865
  CHECK_LT(sizeof(void*), 8) << "missing SOO coverage";
2767
2866
  GTEST_SKIP() << "not SOO on this platform";
2768
2867
  }
2769
2868
  std::vector<const HashtablezInfo*> infos =
2770
- SampleSooMutation([](SooIntTable& t) { t.insert(1); });
2869
+ SampleSooMutation([](SooInt32Table& t) { t.insert(1); });
2771
2870
 
2772
2871
  for (const HashtablezInfo* info : infos) {
2773
2872
  ASSERT_EQ(info->inline_element_size,
2774
- sizeof(typename SooIntTable::value_type));
2873
+ sizeof(typename SooInt32Table::value_type));
2775
2874
  ASSERT_EQ(info->soo_capacity, SooCapacity());
2776
2875
  ASSERT_EQ(info->capacity, NextCapacity(SooCapacity()));
2777
2876
  ASSERT_EQ(info->size, 1);
@@ -2783,16 +2882,16 @@ TEST(RawHashSamplerTest, SooTableInsertToEmpty) {
2783
2882
  }
2784
2883
 
2785
2884
  TEST(RawHashSamplerTest, SooTableReserveToEmpty) {
2786
- if (SooIntTable().capacity() != SooCapacity()) {
2885
+ if (SooInt32Table().capacity() != SooCapacity()) {
2787
2886
  CHECK_LT(sizeof(void*), 8) << "missing SOO coverage";
2788
2887
  GTEST_SKIP() << "not SOO on this platform";
2789
2888
  }
2790
2889
  std::vector<const HashtablezInfo*> infos =
2791
- SampleSooMutation([](SooIntTable& t) { t.reserve(100); });
2890
+ SampleSooMutation([](SooInt32Table& t) { t.reserve(100); });
2792
2891
 
2793
2892
  for (const HashtablezInfo* info : infos) {
2794
2893
  ASSERT_EQ(info->inline_element_size,
2795
- sizeof(typename SooIntTable::value_type));
2894
+ sizeof(typename SooInt32Table::value_type));
2796
2895
  ASSERT_EQ(info->soo_capacity, SooCapacity());
2797
2896
  ASSERT_GE(info->capacity, 100);
2798
2897
  ASSERT_EQ(info->size, 0);
@@ -2806,19 +2905,19 @@ TEST(RawHashSamplerTest, SooTableReserveToEmpty) {
2806
2905
  // This tests that reserve on a full SOO table doesn't incorrectly result in new
2807
2906
  // (over-)sampling.
2808
2907
  TEST(RawHashSamplerTest, SooTableReserveToFullSoo) {
2809
- if (SooIntTable().capacity() != SooCapacity()) {
2908
+ if (SooInt32Table().capacity() != SooCapacity()) {
2810
2909
  CHECK_LT(sizeof(void*), 8) << "missing SOO coverage";
2811
2910
  GTEST_SKIP() << "not SOO on this platform";
2812
2911
  }
2813
2912
  std::vector<const HashtablezInfo*> infos =
2814
- SampleSooMutation([](SooIntTable& t) {
2913
+ SampleSooMutation([](SooInt32Table& t) {
2815
2914
  t.insert(1);
2816
2915
  t.reserve(100);
2817
2916
  });
2818
2917
 
2819
2918
  for (const HashtablezInfo* info : infos) {
2820
2919
  ASSERT_EQ(info->inline_element_size,
2821
- sizeof(typename SooIntTable::value_type));
2920
+ sizeof(typename SooInt32Table::value_type));
2822
2921
  ASSERT_EQ(info->soo_capacity, SooCapacity());
2823
2922
  ASSERT_GE(info->capacity, 100);
2824
2923
  ASSERT_EQ(info->size, 1);
@@ -2829,15 +2928,38 @@ TEST(RawHashSamplerTest, SooTableReserveToFullSoo) {
2829
2928
  }
2830
2929
  }
2831
2930
 
2931
+ TEST(RawHashSamplerTest, SooTableSampleOnCopy) {
2932
+ if (SooInt32Table().capacity() != SooCapacity()) {
2933
+ CHECK_LT(sizeof(void*), 8) << "missing SOO coverage";
2934
+ GTEST_SKIP() << "not SOO on this platform";
2935
+ }
2936
+
2937
+ SooInt32Table t_orig;
2938
+ t_orig.insert(1);
2939
+
2940
+ std::vector<const HashtablezInfo*> infos =
2941
+ SampleSooMutation([&t_orig](SooInt32Table& t) {
2942
+ t = t_orig;
2943
+ });
2944
+
2945
+ for (const HashtablezInfo* info : infos) {
2946
+ ASSERT_EQ(info->inline_element_size,
2947
+ sizeof(typename SooInt32Table::value_type));
2948
+ ASSERT_EQ(info->soo_capacity, SooCapacity());
2949
+ ASSERT_EQ(info->capacity, NextCapacity(SooCapacity()));
2950
+ ASSERT_EQ(info->size, 1);
2951
+ }
2952
+ }
2953
+
2832
2954
  // This tests that rehash(0) on a sampled table with size that fits in SOO
2833
2955
  // doesn't incorrectly result in losing sampling.
2834
2956
  TEST(RawHashSamplerTest, SooTableRehashShrinkWhenSizeFitsInSoo) {
2835
- if (SooIntTable().capacity() != SooCapacity()) {
2957
+ if (SooInt32Table().capacity() != SooCapacity()) {
2836
2958
  CHECK_LT(sizeof(void*), 8) << "missing SOO coverage";
2837
2959
  GTEST_SKIP() << "not SOO on this platform";
2838
2960
  }
2839
2961
  std::vector<const HashtablezInfo*> infos =
2840
- SampleSooMutation([](SooIntTable& t) {
2962
+ SampleSooMutation([](SooInt32Table& t) {
2841
2963
  t.reserve(100);
2842
2964
  t.insert(1);
2843
2965
  EXPECT_GE(t.capacity(), 100);
@@ -2846,7 +2968,7 @@ TEST(RawHashSamplerTest, SooTableRehashShrinkWhenSizeFitsInSoo) {
2846
2968
 
2847
2969
  for (const HashtablezInfo* info : infos) {
2848
2970
  ASSERT_EQ(info->inline_element_size,
2849
- sizeof(typename SooIntTable::value_type));
2971
+ sizeof(typename SooInt32Table::value_type));
2850
2972
  ASSERT_EQ(info->soo_capacity, SooCapacity());
2851
2973
  ASSERT_EQ(info->capacity, NextCapacity(SooCapacity()));
2852
2974
  ASSERT_EQ(info->size, 1);
@@ -2860,19 +2982,19 @@ TEST(RawHashSamplerTest, SooTableRehashShrinkWhenSizeFitsInSoo) {
2860
2982
 
2861
2983
  TEST(RawHashSamplerTest, DoNotSampleCustomAllocators) {
2862
2984
  // Enable the feature even if the prod default is off.
2863
- SetHashtablezEnabled(true);
2864
- SetHashtablezSampleParameter(100); // Sample ~1% of tables.
2985
+ SetSamplingRateTo1Percent();
2865
2986
 
2866
2987
  auto& sampler = GlobalHashtablezSampler();
2867
- size_t start_size = 0;
2988
+ int64_t start_size = 0;
2868
2989
  start_size += sampler.Iterate([&](const HashtablezInfo&) { ++start_size; });
2869
2990
 
2870
2991
  std::vector<CustomAllocIntTable> tables;
2871
- for (int i = 0; i < 1000000; ++i) {
2992
+ for (int i = 0; i < 100000; ++i) {
2872
2993
  tables.emplace_back();
2873
2994
  tables.back().insert(1);
2995
+ tables.push_back(tables.back()); // Copies the table.
2874
2996
  }
2875
- size_t end_size = 0;
2997
+ int64_t end_size = 0;
2876
2998
  end_size += sampler.Iterate([&](const HashtablezInfo&) { ++end_size; });
2877
2999
 
2878
3000
  EXPECT_NEAR((end_size - start_size) / static_cast<double>(tables.size()),
@@ -2904,6 +3026,20 @@ TYPED_TEST(SanitizerTest, PoisoningUnused) {
2904
3026
  }
2905
3027
  }
2906
3028
 
3029
+ TYPED_TEST(SanitizerTest, PoisoningUnusedOnGrowth) {
3030
+ TypeParam t;
3031
+ for (int64_t i = 0; i < 100; ++i) {
3032
+ t.insert(i);
3033
+
3034
+ int64_t* slots = RawHashSetTestOnlyAccess::GetSlots(t);
3035
+ int poisoned = 0;
3036
+ for (size_t i = 0; i < t.capacity(); ++i) {
3037
+ poisoned += static_cast<int>(__asan_address_is_poisoned(slots + i));
3038
+ }
3039
+ ASSERT_EQ(poisoned, t.capacity() - t.size());
3040
+ }
3041
+ }
3042
+
2907
3043
  // TODO(b/289225379): poison inline space when empty SOO.
2908
3044
  TEST(Sanitizer, PoisoningOnErase) {
2909
3045
  NonSooIntTable t;
@@ -2926,28 +3062,27 @@ TYPED_TEST(AlignOneTest, AlignOne) {
2926
3062
  // first slot when alignof(value_type) is 1. We test repeated
2927
3063
  // insertions/erases and verify that the behavior is correct.
2928
3064
  TypeParam t;
2929
- std::unordered_set<uint8_t> verifier; // NOLINT
3065
+ std::bitset<256> verifier;
2930
3066
 
2931
3067
  // Do repeated insertions/erases from the table.
2932
- for (int64_t i = 0; i < 100000; ++i) {
3068
+ for (int64_t i = 0; i < 10000; ++i) {
2933
3069
  SCOPED_TRACE(i);
2934
3070
  const uint8_t u = (i * -i) & 0xFF;
2935
3071
  auto it = t.find(u);
2936
- auto verifier_it = verifier.find(u);
2937
3072
  if (it == t.end()) {
2938
- ASSERT_EQ(verifier_it, verifier.end());
3073
+ ASSERT_FALSE(verifier.test(u));
2939
3074
  t.insert(u);
2940
- verifier.insert(u);
3075
+ verifier.set(u);
2941
3076
  } else {
2942
- ASSERT_NE(verifier_it, verifier.end());
3077
+ ASSERT_TRUE(verifier.test(u));
2943
3078
  t.erase(it);
2944
- verifier.erase(verifier_it);
3079
+ verifier.reset(u);
2945
3080
  }
2946
3081
  }
2947
3082
 
2948
- EXPECT_EQ(t.size(), verifier.size());
3083
+ EXPECT_EQ(t.size(), verifier.count());
2949
3084
  for (uint8_t u : t) {
2950
- EXPECT_EQ(verifier.count(u), 1);
3085
+ ASSERT_TRUE(verifier.test(u));
2951
3086
  }
2952
3087
  }
2953
3088
 
@@ -3315,11 +3450,13 @@ TEST(Iterator, InvalidComparisonDifferentTables) {
3315
3450
  EXPECT_DEATH_IF_SUPPORTED(void(t1.end() == default_constructed_iter),
3316
3451
  "Invalid iterator comparison.*default-constructed");
3317
3452
  t1.insert(0);
3453
+ t1.insert(1);
3318
3454
  EXPECT_DEATH_IF_SUPPORTED(void(t1.begin() == t2.end()),
3319
3455
  "Invalid iterator comparison.*empty hashtable");
3320
3456
  EXPECT_DEATH_IF_SUPPORTED(void(t1.begin() == default_constructed_iter),
3321
3457
  "Invalid iterator comparison.*default-constructed");
3322
3458
  t2.insert(0);
3459
+ t2.insert(1);
3323
3460
  EXPECT_DEATH_IF_SUPPORTED(void(t1.begin() == t2.end()),
3324
3461
  "Invalid iterator comparison.*end.. iterator");
3325
3462
  EXPECT_DEATH_IF_SUPPORTED(void(t1.begin() == t2.begin()),
@@ -3358,73 +3495,80 @@ TEST(Table, CountedHash) {
3358
3495
  GTEST_SKIP() << "Only run under NDEBUG: `assert` statements may cause "
3359
3496
  "redundant hashing.";
3360
3497
  }
3498
+ // When the table is sampled, we need to hash on the first insertion.
3499
+ DisableSampling();
3361
3500
 
3362
3501
  using Table = CountedHashIntTable;
3363
3502
  auto HashCount = [](const Table& t) { return t.hash_function().count; };
3364
3503
  {
3365
3504
  Table t;
3505
+ t.find(0);
3366
3506
  EXPECT_EQ(HashCount(t), 0);
3367
3507
  }
3368
3508
  {
3369
3509
  Table t;
3370
3510
  t.insert(1);
3371
- EXPECT_EQ(HashCount(t), 1);
3511
+ t.find(1);
3512
+ EXPECT_EQ(HashCount(t), 0);
3372
3513
  t.erase(1);
3514
+ EXPECT_EQ(HashCount(t), 0);
3515
+ t.insert(1);
3516
+ t.insert(2);
3373
3517
  EXPECT_EQ(HashCount(t), 2);
3374
3518
  }
3375
3519
  {
3376
3520
  Table t;
3377
3521
  t.insert(3);
3378
- EXPECT_EQ(HashCount(t), 1);
3522
+ EXPECT_EQ(HashCount(t), 0);
3379
3523
  auto node = t.extract(3);
3380
- EXPECT_EQ(HashCount(t), 2);
3524
+ EXPECT_EQ(HashCount(t), 0);
3381
3525
  t.insert(std::move(node));
3382
- EXPECT_EQ(HashCount(t), 3);
3526
+ EXPECT_EQ(HashCount(t), 0);
3383
3527
  }
3384
3528
  {
3385
3529
  Table t;
3386
3530
  t.emplace(5);
3387
- EXPECT_EQ(HashCount(t), 1);
3531
+ EXPECT_EQ(HashCount(t), 0);
3388
3532
  }
3389
3533
  {
3390
3534
  Table src;
3391
3535
  src.insert(7);
3392
3536
  Table dst;
3393
3537
  dst.merge(src);
3394
- EXPECT_EQ(HashCount(dst), 1);
3538
+ EXPECT_EQ(HashCount(dst), 0);
3395
3539
  }
3396
3540
  }
3397
3541
 
3398
3542
  // IterateOverFullSlots doesn't support SOO.
3399
3543
  TEST(Table, IterateOverFullSlotsEmpty) {
3400
3544
  NonSooIntTable t;
3401
- auto fail_if_any = [](const ctrl_t*, auto* i) {
3402
- FAIL() << "expected no slots " << **i;
3545
+ using SlotType = NonSooIntTableSlotType;
3546
+ auto fail_if_any = [](const ctrl_t*, void* i) {
3547
+ FAIL() << "expected no slots " << **static_cast<SlotType*>(i);
3403
3548
  };
3404
- container_internal::IterateOverFullSlots(
3405
- RawHashSetTestOnlyAccess::GetCommon(t),
3406
- RawHashSetTestOnlyAccess::GetSlots(t), fail_if_any);
3407
- for (size_t i = 0; i < 256; ++i) {
3549
+ for (size_t i = 2; i < 256; ++i) {
3408
3550
  t.reserve(i);
3409
3551
  container_internal::IterateOverFullSlots(
3410
- RawHashSetTestOnlyAccess::GetCommon(t),
3411
- RawHashSetTestOnlyAccess::GetSlots(t), fail_if_any);
3552
+ RawHashSetTestOnlyAccess::GetCommon(t), sizeof(SlotType), fail_if_any);
3412
3553
  }
3413
3554
  }
3414
3555
 
3415
3556
  TEST(Table, IterateOverFullSlotsFull) {
3416
3557
  NonSooIntTable t;
3558
+ using SlotType = NonSooIntTableSlotType;
3417
3559
 
3418
3560
  std::vector<int64_t> expected_slots;
3419
- for (int64_t idx = 0; idx < 128; ++idx) {
3561
+ t.insert(0);
3562
+ expected_slots.push_back(0);
3563
+ for (int64_t idx = 1; idx < 128; ++idx) {
3420
3564
  t.insert(idx);
3421
3565
  expected_slots.push_back(idx);
3422
3566
 
3423
3567
  std::vector<int64_t> slots;
3424
3568
  container_internal::IterateOverFullSlots(
3425
- RawHashSetTestOnlyAccess::GetCommon(t),
3426
- RawHashSetTestOnlyAccess::GetSlots(t),
3427
- [&t, &slots](const ctrl_t* ctrl, auto* i) {
3569
+ RawHashSetTestOnlyAccess::GetCommon(t), sizeof(SlotType),
3570
+ [&t, &slots](const ctrl_t* ctrl, void* slot) {
3571
+ SlotType* i = static_cast<SlotType*>(slot);
3428
3572
  ptrdiff_t ctrl_offset =
3429
3573
  ctrl - RawHashSetTestOnlyAccess::GetCommon(t).control();
3430
3574
  ptrdiff_t slot_offset = i - RawHashSetTestOnlyAccess::GetSlots(t);
@@ -3443,16 +3587,16 @@ TEST(Table, IterateOverFullSlotsDeathOnRemoval) {
3443
3587
  if (reserve_size == -1) reserve_size = size;
3444
3588
  for (int64_t idx = 0; idx < size; ++idx) {
3445
3589
  NonSooIntTable t;
3590
+ using SlotType = NonSooIntTableSlotType;
3446
3591
  t.reserve(static_cast<size_t>(reserve_size));
3447
3592
  for (int val = 0; val <= idx; ++val) {
3448
3593
  t.insert(val);
3449
3594
  }
3450
3595
 
3451
3596
  container_internal::IterateOverFullSlots(
3452
- RawHashSetTestOnlyAccess::GetCommon(t),
3453
- RawHashSetTestOnlyAccess::GetSlots(t),
3454
- [&t](const ctrl_t*, auto* i) {
3455
- int64_t value = **i;
3597
+ RawHashSetTestOnlyAccess::GetCommon(t), sizeof(SlotType),
3598
+ [&t](const ctrl_t*, void* slot) {
3599
+ int64_t value = **static_cast<SlotType*>(slot);
3456
3600
  // Erase the other element from 2*k and 2*k+1 pair.
3457
3601
  t.erase(value ^ 1);
3458
3602
  });
@@ -3478,16 +3622,16 @@ TEST(Table, IterateOverFullSlotsDeathOnInsert) {
3478
3622
  int64_t size = reserve_size / size_divisor;
3479
3623
  for (int64_t idx = 1; idx <= size; ++idx) {
3480
3624
  NonSooIntTable t;
3625
+ using SlotType = NonSooIntTableSlotType;
3481
3626
  t.reserve(static_cast<size_t>(reserve_size));
3482
3627
  for (int val = 1; val <= idx; ++val) {
3483
3628
  t.insert(val);
3484
3629
  }
3485
3630
 
3486
3631
  container_internal::IterateOverFullSlots(
3487
- RawHashSetTestOnlyAccess::GetCommon(t),
3488
- RawHashSetTestOnlyAccess::GetSlots(t),
3489
- [&t](const ctrl_t*, auto* i) {
3490
- int64_t value = **i;
3632
+ RawHashSetTestOnlyAccess::GetCommon(t), sizeof(SlotType),
3633
+ [&t](const ctrl_t*, void* slot) {
3634
+ int64_t value = **static_cast<SlotType*>(slot);
3491
3635
  t.insert(-value);
3492
3636
  });
3493
3637
  }
@@ -3550,7 +3694,7 @@ TEST(Table, RehashToSooUnsampled) {
3550
3694
 
3551
3695
  // We disable hashtablez sampling for this test to ensure that the table isn't
3552
3696
  // sampled. When the table is sampled, it won't rehash down to SOO.
3553
- SetHashtablezEnabled(false);
3697
+ DisableSampling();
3554
3698
 
3555
3699
  t.reserve(100);
3556
3700
  t.insert(0);
@@ -3566,7 +3710,7 @@ TEST(Table, RehashToSooUnsampled) {
3566
3710
  }
3567
3711
 
3568
3712
  TEST(Table, ReserveToNonSoo) {
3569
- for (int reserve_capacity : {8, 100000}) {
3713
+ for (size_t reserve_capacity : {2u, 8u, 100000u}) {
3570
3714
  SooIntTable t;
3571
3715
  t.insert(0);
3572
3716
 
@@ -3679,17 +3823,68 @@ TEST(Table, ReentrantCallsFail) {
3679
3823
  #endif
3680
3824
  }
3681
3825
 
3826
+ // TODO(b/328794765): this check is very useful to run with ASAN in opt mode.
3682
3827
  TEST(Table, DestroyedCallsFail) {
3683
3828
  #ifdef NDEBUG
3684
- GTEST_SKIP() << "Destroyed checks only enabled in debug mode.";
3829
+ ASSERT_EQ(SwisstableAssertAccessToDestroyedTable(),
3830
+ SwisstableGenerationsEnabled());
3685
3831
  #else
3832
+ ASSERT_TRUE(SwisstableAssertAccessToDestroyedTable());
3833
+ #endif
3834
+ if (!SwisstableAssertAccessToDestroyedTable()) {
3835
+ GTEST_SKIP() << "Validation not enabled.";
3836
+ }
3837
+ #if !defined(__clang__) && defined(__GNUC__)
3838
+ GTEST_SKIP() << "Flaky on GCC.";
3839
+ #endif
3686
3840
  absl::optional<IntTable> t;
3687
3841
  t.emplace({1});
3688
3842
  IntTable* t_ptr = &*t;
3689
3843
  EXPECT_TRUE(t_ptr->contains(1));
3690
3844
  t.reset();
3691
- EXPECT_DEATH_IF_SUPPORTED(t_ptr->contains(1), "");
3845
+ std::string expected_death_message =
3846
+ #if defined(ABSL_HAVE_MEMORY_SANITIZER)
3847
+ "use-of-uninitialized-value";
3848
+ #else
3849
+ "destroyed hash table";
3692
3850
  #endif
3851
+ EXPECT_DEATH_IF_SUPPORTED(t_ptr->contains(1), expected_death_message);
3852
+ }
3853
+
3854
+ TEST(Table, DestroyedCallsFailDuringDestruction) {
3855
+ if (!SwisstableAssertAccessToDestroyedTable()) {
3856
+ GTEST_SKIP() << "Validation not enabled.";
3857
+ }
3858
+ #if !defined(__clang__) && defined(__GNUC__)
3859
+ GTEST_SKIP() << "Flaky on GCC.";
3860
+ #endif
3861
+ // When EXPECT_DEATH_IF_SUPPORTED is not executed, the code after it is not
3862
+ // executed as well.
3863
+ // We need to destruct the table correctly in such a case.
3864
+ // Must be defined before the table for correct destruction order.
3865
+ bool do_lookup = false;
3866
+
3867
+ using Table = absl::flat_hash_map<int, std::shared_ptr<int>>;
3868
+ absl::optional<Table> t = Table();
3869
+ Table* t_ptr = &*t;
3870
+ auto destroy = [&](int* ptr) {
3871
+ if (do_lookup) {
3872
+ ASSERT_TRUE(t_ptr->contains(*ptr));
3873
+ }
3874
+ delete ptr;
3875
+ };
3876
+ t->insert({0, std::shared_ptr<int>(new int(0), destroy)});
3877
+ auto destroy_with_lookup = [&] {
3878
+ do_lookup = true;
3879
+ t.reset();
3880
+ };
3881
+ std::string expected_death_message =
3882
+ #ifdef NDEBUG
3883
+ "destroyed hash table";
3884
+ #else
3885
+ "Reentrant container access";
3886
+ #endif
3887
+ EXPECT_DEATH_IF_SUPPORTED(destroy_with_lookup(), expected_death_message);
3693
3888
  }
3694
3889
 
3695
3890
  TEST(Table, MovedFromCallsFail) {
@@ -3737,12 +3932,161 @@ TEST(Table, MovedFromCallsFail) {
3737
3932
  }
3738
3933
  }
3739
3934
 
3935
+ TEST(HashtableSize, GenerateNewSeedDoesntChangeSize) {
3936
+ size_t size = 1;
3937
+ do {
3938
+ HashtableSize hs(no_seed_empty_tag_t{});
3939
+ hs.increment_size(size);
3940
+ EXPECT_EQ(hs.size(), size);
3941
+ hs.generate_new_seed();
3942
+ EXPECT_EQ(hs.size(), size);
3943
+ size = size * 2 + 1;
3944
+ } while (size < MaxValidSizeFor1ByteSlot());
3945
+ }
3946
+
3947
+ TEST(Table, MaxValidSize) {
3948
+ IntTable t;
3949
+ EXPECT_EQ(MaxValidSize(sizeof(IntTable::value_type)), t.max_size());
3950
+ if constexpr (sizeof(size_t) == 8) {
3951
+ for (size_t i = 0; i < 35; ++i) {
3952
+ SCOPED_TRACE(i);
3953
+ size_t slot_size = size_t{1} << i;
3954
+ size_t max_size = MaxValidSize(slot_size);
3955
+ ASSERT_FALSE(IsAboveValidSize(max_size, slot_size));
3956
+ ASSERT_TRUE(IsAboveValidSize(max_size + 1, slot_size));
3957
+ ASSERT_LT(max_size, uint64_t{1} << 60);
3958
+ // For non gigantic slot sizes we expect max size to be at least 2^40.
3959
+ if (i <= 22) {
3960
+ ASSERT_FALSE(IsAboveValidSize(size_t{1} << 40, slot_size));
3961
+ ASSERT_GE(max_size, uint64_t{1} << 40);
3962
+ }
3963
+ ASSERT_LT(SizeToCapacity(max_size),
3964
+ uint64_t{1} << HashtableSize::kSizeBitCount);
3965
+ ASSERT_LT(absl::uint128(max_size) * slot_size, uint64_t{1} << 63);
3966
+ }
3967
+ }
3968
+ EXPECT_LT(MaxValidSize</*kSizeOfSizeT=*/4>(1), 1 << 30);
3969
+ EXPECT_LT(MaxValidSize</*kSizeOfSizeT=*/4>(2), 1 << 29);
3970
+ for (size_t i = 0; i < 29; ++i) {
3971
+ size_t slot_size = size_t{1} << i;
3972
+ size_t max_size = MaxValidSize</*kSizeOfSizeT=*/4>(slot_size);
3973
+ ASSERT_FALSE(IsAboveValidSize</*kSizeOfSizeT=*/4>(max_size, slot_size));
3974
+ ASSERT_TRUE(IsAboveValidSize</*kSizeOfSizeT=*/4>(max_size + 1, slot_size));
3975
+ ASSERT_LT(max_size, 1 << 30);
3976
+ size_t max_capacity = SizeToCapacity(max_size);
3977
+ ASSERT_LT(max_capacity, (size_t{1} << 31) / slot_size);
3978
+ ASSERT_GT(max_capacity, (1 << 29) / slot_size);
3979
+ ASSERT_LT(max_capacity * slot_size, size_t{1} << 31);
3980
+ }
3981
+ }
3982
+
3740
3983
  TEST(Table, MaxSizeOverflow) {
3741
3984
  size_t overflow = (std::numeric_limits<size_t>::max)();
3742
3985
  EXPECT_DEATH_IF_SUPPORTED(IntTable t(overflow), "Hash table size overflow");
3743
3986
  IntTable t;
3744
3987
  EXPECT_DEATH_IF_SUPPORTED(t.reserve(overflow), "Hash table size overflow");
3745
3988
  EXPECT_DEATH_IF_SUPPORTED(t.rehash(overflow), "Hash table size overflow");
3989
+ size_t slightly_overflow = MaxValidSize(sizeof(IntTable::value_type)) + 1;
3990
+ size_t slightly_overflow_capacity =
3991
+ NextCapacity(NormalizeCapacity(slightly_overflow));
3992
+ EXPECT_DEATH_IF_SUPPORTED(IntTable t2(slightly_overflow_capacity - 10),
3993
+ "Hash table size overflow");
3994
+ EXPECT_DEATH_IF_SUPPORTED(t.reserve(slightly_overflow),
3995
+ "Hash table size overflow");
3996
+ EXPECT_DEATH_IF_SUPPORTED(t.rehash(slightly_overflow),
3997
+ "Hash table size overflow");
3998
+ IntTable non_empty_table;
3999
+ non_empty_table.insert(0);
4000
+ EXPECT_DEATH_IF_SUPPORTED(non_empty_table.reserve(slightly_overflow),
4001
+ "Hash table size overflow");
4002
+ }
4003
+
4004
+ // TODO(b/397453582): Remove support for const hasher and remove this test.
4005
+ TEST(Table, ConstLambdaHash) {
4006
+ int64_t multiplier = 17;
4007
+ // Make sure that code compiles and work OK with non-empty hasher with const
4008
+ // qualifier.
4009
+ const auto hash = [multiplier](SizedValue<64> value) -> size_t {
4010
+ return static_cast<size_t>(static_cast<int64_t>(value) * multiplier);
4011
+ };
4012
+ static_assert(!std::is_empty_v<decltype(hash)>);
4013
+ absl::flat_hash_set<SizedValue<64>, decltype(hash)> t(0, hash);
4014
+ t.insert(1);
4015
+ EXPECT_EQ(t.size(), 1);
4016
+ EXPECT_EQ(t.find(1), t.begin());
4017
+ EXPECT_EQ(t.find(2), t.end());
4018
+ t.insert(2);
4019
+ EXPECT_EQ(t.size(), 2);
4020
+ EXPECT_NE(t.find(1), t.end());
4021
+ EXPECT_NE(t.find(2), t.end());
4022
+ EXPECT_EQ(t.find(3), t.end());
4023
+ }
4024
+
4025
+ struct ConstUint8Hash {
4026
+ size_t operator()(uint8_t) const { return *value; }
4027
+ size_t* value;
4028
+ };
4029
+
4030
+ // This test is imitating growth of a very big table and triggers all buffer
4031
+ // overflows.
4032
+ // We try to insert all elements into the first probe group.
4033
+ // So the resize codepath in test does the following:
4034
+ // 1. Insert 16 elements into the first probe group. No other elements will be
4035
+ // inserted into the first probe group.
4036
+ // 2. There will be enough elements to fill up the local buffer even for
4037
+ // encoding with 4 bytes.
4038
+ // 3. After local buffer is full, we will fill up the control buffer till
4039
+ // some point.
4040
+ // 4. Then a few times we will extend control buffer end.
4041
+ // 5. Finally we will catch up and go to overflow codepath.
4042
+ TEST(Table, GrowExtremelyLargeTable) {
4043
+ constexpr size_t kTargetCapacity =
4044
+ #if defined(__wasm__) || defined(__asmjs__) || defined(__i386__)
4045
+ NextCapacity(ProbedItem4Bytes::kMaxNewCapacity); // OOMs on WASM, 32-bit.
4046
+ #else
4047
+ NextCapacity(ProbedItem8Bytes::kMaxNewCapacity);
4048
+ #endif
4049
+
4050
+ size_t hash = 0;
4051
+ // In order to save memory we use 1 byte slot.
4052
+ // There are not enough different values to achieve big capacity, so we
4053
+ // artificially update growth info to force resize.
4054
+ absl::flat_hash_set<uint8_t, ConstUint8Hash> t(63, ConstUint8Hash{&hash});
4055
+ CommonFields& common = RawHashSetTestOnlyAccess::GetCommon(t);
4056
+ // Set 0 seed so that H1 is always 0.
4057
+ common.set_no_seed_for_testing();
4058
+ ASSERT_EQ(H1(t.hash_function()(75)), 0);
4059
+ uint8_t inserted_till = 210;
4060
+ for (uint8_t i = 0; i < inserted_till; ++i) {
4061
+ t.insert(i);
4062
+ }
4063
+ for (uint8_t i = 0; i < inserted_till; ++i) {
4064
+ ASSERT_TRUE(t.contains(i));
4065
+ }
4066
+
4067
+ for (size_t cap = t.capacity(); cap < kTargetCapacity;
4068
+ cap = NextCapacity(cap)) {
4069
+ ASSERT_EQ(t.capacity(), cap);
4070
+ // Update growth info to force resize on the next insert.
4071
+ common.growth_info().OverwriteManyEmptyAsFull(CapacityToGrowth(cap) -
4072
+ t.size());
4073
+ t.insert(inserted_till++);
4074
+ ASSERT_EQ(t.capacity(), NextCapacity(cap));
4075
+ for (uint8_t i = 0; i < inserted_till; ++i) {
4076
+ ASSERT_TRUE(t.contains(i));
4077
+ }
4078
+ }
4079
+ EXPECT_EQ(t.capacity(), kTargetCapacity);
4080
+ }
4081
+
4082
+ // Test that after calling generate_new_seed(), the high bits of the returned
4083
+ // seed are non-zero.
4084
+ TEST(PerTableSeed, HighBitsAreNonZero) {
4085
+ HashtableSize hs(no_seed_empty_tag_t{});
4086
+ for (int i = 0; i < 100; ++i) {
4087
+ hs.generate_new_seed();
4088
+ ASSERT_GT(hs.seed().seed() >> 16, 0);
4089
+ }
3746
4090
  }
3747
4091
 
3748
4092
  } // namespace