re2 1.24.0 → 1.25.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 (370) hide show
  1. package/LICENSE +15 -20
  2. package/README.md +63 -4
  3. package/binding.gyp +1 -2
  4. package/lib/addon.cc +9 -5
  5. package/lib/exec.cc +4 -4
  6. package/lib/match.cc +4 -4
  7. package/lib/new.cc +6 -6
  8. package/lib/pattern.cc +148 -1
  9. package/lib/replace.cc +5 -4
  10. package/lib/search.cc +1 -1
  11. package/lib/set.cc +85 -10
  12. package/lib/test.cc +1 -1
  13. package/lib/unicode_properties.h +15840 -0
  14. package/lib/wrapped_re2.h +40 -4
  15. package/lib/wrapped_re2_set.h +3 -1
  16. package/llms-full.txt +497 -0
  17. package/llms.txt +135 -0
  18. package/package.json +19 -11
  19. package/re2.d.ts +2 -0
  20. package/re2.js +1 -0
  21. package/vendor/abseil-cpp/CMake/AbseilDll.cmake +87 -74
  22. package/vendor/abseil-cpp/CMakeLists.txt +3 -3
  23. package/vendor/abseil-cpp/FAQ.md +130 -79
  24. package/vendor/abseil-cpp/MODULE.bazel +6 -7
  25. package/vendor/abseil-cpp/absl/BUILD.bazel +6 -0
  26. package/vendor/abseil-cpp/absl/algorithm/BUILD.bazel +4 -0
  27. package/vendor/abseil-cpp/absl/algorithm/CMakeLists.txt +4 -0
  28. package/vendor/abseil-cpp/absl/algorithm/algorithm.h +34 -2
  29. package/vendor/abseil-cpp/absl/algorithm/container.h +164 -17
  30. package/vendor/abseil-cpp/absl/algorithm/container_test.cc +390 -13
  31. package/vendor/abseil-cpp/absl/base/BUILD.bazel +53 -6
  32. package/vendor/abseil-cpp/absl/base/CMakeLists.txt +28 -4
  33. package/vendor/abseil-cpp/absl/base/attributes.h +61 -42
  34. package/vendor/abseil-cpp/absl/base/call_once.h +1 -0
  35. package/vendor/abseil-cpp/absl/base/casts.h +8 -1
  36. package/vendor/abseil-cpp/absl/base/casts_test.cc +3 -6
  37. package/vendor/abseil-cpp/absl/base/config.h +53 -9
  38. package/vendor/abseil-cpp/absl/base/exception_safety_testing_test.cc +9 -9
  39. package/vendor/abseil-cpp/absl/base/fast_type_id.h +30 -2
  40. package/vendor/abseil-cpp/absl/base/fast_type_id_test.cc +3 -0
  41. package/vendor/abseil-cpp/absl/base/internal/exception_safety_testing.h +15 -12
  42. package/vendor/abseil-cpp/absl/base/internal/hardening.h +136 -0
  43. package/vendor/abseil-cpp/absl/base/internal/hardening_test.cc +168 -0
  44. package/vendor/abseil-cpp/absl/base/internal/iterator_traits.h +2 -2
  45. package/vendor/abseil-cpp/absl/base/internal/low_level_alloc.cc +6 -0
  46. package/vendor/abseil-cpp/absl/base/internal/low_level_scheduling.h +77 -15
  47. package/vendor/abseil-cpp/absl/base/internal/sysinfo.cc +1 -2
  48. package/vendor/abseil-cpp/absl/base/internal/thread_identity.h +52 -0
  49. package/vendor/abseil-cpp/absl/base/internal/unscaledcycleclock.h +5 -0
  50. package/vendor/abseil-cpp/absl/base/macros.h +36 -20
  51. package/vendor/abseil-cpp/absl/base/nullability.h +4 -3
  52. package/vendor/abseil-cpp/absl/base/optimization.h +3 -2
  53. package/vendor/abseil-cpp/absl/base/optimization_test.cc +4 -3
  54. package/vendor/abseil-cpp/absl/base/options.h +55 -1
  55. package/vendor/abseil-cpp/absl/base/policy_checks.h +5 -5
  56. package/vendor/abseil-cpp/absl/base/{internal/throw_delegate.cc → throw_delegate.cc} +9 -7
  57. package/vendor/abseil-cpp/absl/base/{internal/throw_delegate.h → throw_delegate.h} +4 -14
  58. package/vendor/abseil-cpp/absl/base/throw_delegate_test.cc +19 -28
  59. package/vendor/abseil-cpp/absl/cleanup/BUILD.bazel +2 -0
  60. package/vendor/abseil-cpp/absl/cleanup/CMakeLists.txt +2 -0
  61. package/vendor/abseil-cpp/absl/cleanup/cleanup.h +3 -2
  62. package/vendor/abseil-cpp/absl/cleanup/internal/cleanup.h +3 -2
  63. package/vendor/abseil-cpp/absl/container/BUILD.bazel +19 -7
  64. package/vendor/abseil-cpp/absl/container/CMakeLists.txt +6 -5
  65. package/vendor/abseil-cpp/absl/container/btree_benchmark.cc +3 -5
  66. package/vendor/abseil-cpp/absl/container/btree_set.h +5 -5
  67. package/vendor/abseil-cpp/absl/container/btree_test.cc +11 -14
  68. package/vendor/abseil-cpp/absl/container/chunked_queue.h +8 -6
  69. package/vendor/abseil-cpp/absl/container/chunked_queue_test.cc +5 -5
  70. package/vendor/abseil-cpp/absl/container/fixed_array.h +14 -13
  71. package/vendor/abseil-cpp/absl/container/fixed_array_test.cc +3 -3
  72. package/vendor/abseil-cpp/absl/container/flat_hash_map.h +18 -6
  73. package/vendor/abseil-cpp/absl/container/flat_hash_map_test.cc +34 -1
  74. package/vendor/abseil-cpp/absl/container/flat_hash_set.h +21 -7
  75. package/vendor/abseil-cpp/absl/container/flat_hash_set_test.cc +39 -7
  76. package/vendor/abseil-cpp/absl/container/inlined_vector.h +29 -29
  77. package/vendor/abseil-cpp/absl/container/inlined_vector_test.cc +2 -2
  78. package/vendor/abseil-cpp/absl/container/internal/btree.h +32 -24
  79. package/vendor/abseil-cpp/absl/container/internal/btree_container.h +16 -17
  80. package/vendor/abseil-cpp/absl/container/internal/common.h +6 -5
  81. package/vendor/abseil-cpp/absl/container/internal/common_policy_traits.h +1 -1
  82. package/vendor/abseil-cpp/absl/container/internal/compressed_tuple.h +16 -16
  83. package/vendor/abseil-cpp/absl/container/internal/compressed_tuple_test.cc +13 -13
  84. package/vendor/abseil-cpp/absl/container/internal/container_memory.h +41 -31
  85. package/vendor/abseil-cpp/absl/container/internal/hash_function_defaults.h +2 -2
  86. package/vendor/abseil-cpp/absl/container/internal/hash_generator_testing.h +4 -4
  87. package/vendor/abseil-cpp/absl/container/internal/hash_policy_traits.h +3 -3
  88. package/vendor/abseil-cpp/absl/container/internal/hashtable_control_bytes.h +27 -19
  89. package/vendor/abseil-cpp/absl/container/internal/hashtablez_sampler.cc +2 -2
  90. package/vendor/abseil-cpp/absl/container/internal/hashtablez_sampler.h +0 -17
  91. package/vendor/abseil-cpp/absl/container/internal/hashtablez_sampler_test.cc +12 -30
  92. package/vendor/abseil-cpp/absl/container/internal/inlined_vector.h +28 -28
  93. package/vendor/abseil-cpp/absl/container/internal/layout.h +13 -13
  94. package/vendor/abseil-cpp/absl/container/internal/layout_test.cc +3 -2
  95. package/vendor/abseil-cpp/absl/container/internal/raw_hash_map.h +60 -62
  96. package/vendor/abseil-cpp/absl/container/internal/raw_hash_set.cc +59 -39
  97. package/vendor/abseil-cpp/absl/container/internal/raw_hash_set.h +619 -326
  98. package/vendor/abseil-cpp/absl/container/internal/raw_hash_set_benchmark.cc +25 -2
  99. package/vendor/abseil-cpp/absl/container/internal/raw_hash_set_probe_benchmark.cc +4 -4
  100. package/vendor/abseil-cpp/absl/container/internal/raw_hash_set_test.cc +575 -159
  101. package/vendor/abseil-cpp/absl/container/linked_hash_map.h +2 -2
  102. package/vendor/abseil-cpp/absl/container/node_hash_map.h +27 -15
  103. package/vendor/abseil-cpp/absl/container/node_hash_map_test.cc +34 -0
  104. package/vendor/abseil-cpp/absl/container/node_hash_set.h +25 -11
  105. package/vendor/abseil-cpp/absl/container/node_hash_set_test.cc +39 -7
  106. package/vendor/abseil-cpp/absl/container/sample_element_size_test.cc +7 -4
  107. package/vendor/abseil-cpp/absl/crc/BUILD.bazel +0 -1
  108. package/vendor/abseil-cpp/absl/crc/CMakeLists.txt +2 -3
  109. package/vendor/abseil-cpp/absl/crc/crc32c_benchmark.cc +2 -1
  110. package/vendor/abseil-cpp/absl/crc/internal/cpu_detect.cc +6 -6
  111. package/vendor/abseil-cpp/absl/crc/internal/crc.cc +4 -6
  112. package/vendor/abseil-cpp/absl/crc/internal/crc32_x86_arm_combined_simd.h +41 -0
  113. package/vendor/abseil-cpp/absl/crc/internal/crc_internal.h +0 -16
  114. package/vendor/abseil-cpp/absl/crc/internal/crc_x86_arm_combined.cc +143 -81
  115. package/vendor/abseil-cpp/absl/debugging/BUILD.bazel +9 -31
  116. package/vendor/abseil-cpp/absl/debugging/CMakeLists.txt +3 -33
  117. package/vendor/abseil-cpp/absl/debugging/internal/demangle_rust.h +8 -0
  118. package/vendor/abseil-cpp/absl/debugging/internal/demangle_test.cc +2 -1
  119. package/vendor/abseil-cpp/absl/debugging/internal/examine_stack.cc +12 -2
  120. package/vendor/abseil-cpp/absl/debugging/internal/examine_stack.h +2 -3
  121. package/vendor/abseil-cpp/absl/debugging/internal/stacktrace_aarch64-inl.inc +11 -0
  122. package/vendor/abseil-cpp/absl/debugging/internal/stacktrace_emscripten-inl.inc +13 -4
  123. package/vendor/abseil-cpp/absl/debugging/internal/stacktrace_generic-inl.inc +14 -7
  124. package/vendor/abseil-cpp/absl/debugging/internal/stacktrace_riscv-inl.inc +4 -0
  125. package/vendor/abseil-cpp/absl/debugging/internal/symbolize.h +46 -36
  126. package/vendor/abseil-cpp/absl/debugging/stacktrace.cc +18 -58
  127. package/vendor/abseil-cpp/absl/debugging/stacktrace.h +5 -48
  128. package/vendor/abseil-cpp/absl/debugging/stacktrace_test.cc +10 -124
  129. package/vendor/abseil-cpp/absl/debugging/symbolize.cc +20 -2
  130. package/vendor/abseil-cpp/absl/debugging/symbolize_elf.inc +58 -106
  131. package/vendor/abseil-cpp/absl/debugging/symbolize_test.cc +37 -36
  132. package/vendor/abseil-cpp/absl/debugging/symbolize_unimplemented.inc +4 -4
  133. package/vendor/abseil-cpp/absl/flags/BUILD.bazel +6 -3
  134. package/vendor/abseil-cpp/absl/flags/CMakeLists.txt +1 -1
  135. package/vendor/abseil-cpp/absl/flags/commandlineflag.h +8 -6
  136. package/vendor/abseil-cpp/absl/flags/commandlineflag_test.cc +1 -1
  137. package/vendor/abseil-cpp/absl/flags/flag_benchmark.cc +5 -5
  138. package/vendor/abseil-cpp/absl/flags/flag_test.cc +30 -30
  139. package/vendor/abseil-cpp/absl/flags/internal/flag.cc +4 -4
  140. package/vendor/abseil-cpp/absl/flags/internal/flag.h +6 -6
  141. package/vendor/abseil-cpp/absl/flags/marshalling.h +2 -28
  142. package/vendor/abseil-cpp/absl/flags/marshalling_test.cc +12 -11
  143. package/vendor/abseil-cpp/absl/flags/reflection_test.cc +1 -1
  144. package/vendor/abseil-cpp/absl/functional/BUILD.bazel +26 -1
  145. package/vendor/abseil-cpp/absl/functional/CMakeLists.txt +29 -1
  146. package/vendor/abseil-cpp/absl/functional/any_invocable.h +13 -14
  147. package/vendor/abseil-cpp/absl/functional/any_invocable_test.cc +46 -47
  148. package/vendor/abseil-cpp/absl/functional/bind_back.h +79 -0
  149. package/vendor/abseil-cpp/absl/functional/bind_back_test.cc +237 -0
  150. package/vendor/abseil-cpp/absl/functional/bind_front.h +7 -1
  151. package/vendor/abseil-cpp/absl/functional/bind_front_test.cc +4 -4
  152. package/vendor/abseil-cpp/absl/functional/function_ref_test.cc +2 -2
  153. package/vendor/abseil-cpp/absl/functional/internal/any_invocable.h +28 -28
  154. package/vendor/abseil-cpp/absl/functional/internal/back_binder.h +95 -0
  155. package/vendor/abseil-cpp/absl/functional/internal/front_binder.h +4 -4
  156. package/vendor/abseil-cpp/absl/functional/internal/function_ref.h +2 -2
  157. package/vendor/abseil-cpp/absl/functional/overload_test.cc +13 -13
  158. package/vendor/abseil-cpp/absl/hash/BUILD.bazel +1 -2
  159. package/vendor/abseil-cpp/absl/hash/CMakeLists.txt +1 -2
  160. package/vendor/abseil-cpp/absl/hash/hash.h +1 -1
  161. package/vendor/abseil-cpp/absl/hash/hash_test.cc +14 -20
  162. package/vendor/abseil-cpp/absl/hash/hash_testing.h +11 -9
  163. package/vendor/abseil-cpp/absl/hash/internal/city.cc +39 -51
  164. package/vendor/abseil-cpp/absl/hash/internal/hash.cc +165 -47
  165. package/vendor/abseil-cpp/absl/hash/internal/hash.h +86 -27
  166. package/vendor/abseil-cpp/absl/hash/internal/low_level_hash_test.cc +36 -1
  167. package/vendor/abseil-cpp/absl/hash/internal/spy_hash_state.h +8 -5
  168. package/vendor/abseil-cpp/absl/log/BUILD.bazel +5 -2
  169. package/vendor/abseil-cpp/absl/log/CMakeLists.txt +5 -3
  170. package/vendor/abseil-cpp/absl/log/absl_vlog_is_on.h +0 -2
  171. package/vendor/abseil-cpp/absl/log/internal/BUILD.bazel +15 -1
  172. package/vendor/abseil-cpp/absl/log/internal/log_message.cc +5 -4
  173. package/vendor/abseil-cpp/absl/log/internal/log_message.h +14 -0
  174. package/vendor/abseil-cpp/absl/log/internal/nullstream.h +1 -1
  175. package/vendor/abseil-cpp/absl/log/internal/proto.cc +13 -0
  176. package/vendor/abseil-cpp/absl/log/internal/structured_proto.cc +5 -5
  177. package/vendor/abseil-cpp/absl/log/internal/structured_proto.h +6 -5
  178. package/vendor/abseil-cpp/absl/log/internal/structured_proto_test.cc +3 -3
  179. package/vendor/abseil-cpp/absl/log/internal/vlog_config.cc +2 -2
  180. package/vendor/abseil-cpp/absl/log/internal/vlog_config_benchmark.cc +3 -3
  181. package/vendor/abseil-cpp/absl/log/log_format_test.cc +19 -2
  182. package/vendor/abseil-cpp/absl/log/log_modifier_methods_test.cc +18 -0
  183. package/vendor/abseil-cpp/absl/log/log_streamer.h +29 -2
  184. package/vendor/abseil-cpp/absl/log/log_streamer_test.cc +18 -0
  185. package/vendor/abseil-cpp/absl/log/scoped_mock_log_test.cc +1 -1
  186. package/vendor/abseil-cpp/absl/log/vlog_is_on.h +0 -2
  187. package/vendor/abseil-cpp/absl/log/vlog_is_on_test.cc +6 -5
  188. package/vendor/abseil-cpp/absl/memory/memory.h +55 -5
  189. package/vendor/abseil-cpp/absl/memory/memory_test.cc +55 -1
  190. package/vendor/abseil-cpp/absl/meta/BUILD.bazel +2 -0
  191. package/vendor/abseil-cpp/absl/meta/internal/requires.h +1 -1
  192. package/vendor/abseil-cpp/absl/meta/type_traits.h +119 -55
  193. package/vendor/abseil-cpp/absl/meta/type_traits_test.cc +7 -7
  194. package/vendor/abseil-cpp/absl/numeric/int128_test.cc +6 -6
  195. package/vendor/abseil-cpp/absl/profiling/BUILD.bazel +3 -1
  196. package/vendor/abseil-cpp/absl/profiling/hashtable.cc +0 -4
  197. package/vendor/abseil-cpp/absl/profiling/internal/profile_builder.cc +32 -33
  198. package/vendor/abseil-cpp/absl/profiling/internal/profile_builder.h +25 -2
  199. package/vendor/abseil-cpp/absl/profiling/internal/sample_recorder_test.cc +8 -5
  200. package/vendor/abseil-cpp/absl/random/BUILD.bazel +13 -1
  201. package/vendor/abseil-cpp/absl/random/CMakeLists.txt +23 -2
  202. package/vendor/abseil-cpp/absl/random/benchmarks.cc +1 -1
  203. package/vendor/abseil-cpp/absl/random/beta_distribution.h +2 -2
  204. package/vendor/abseil-cpp/absl/random/bit_gen_ref.h +26 -53
  205. package/vendor/abseil-cpp/absl/random/bit_gen_ref_test.cc +43 -0
  206. package/vendor/abseil-cpp/absl/random/discrete_distribution.h +1 -1
  207. package/vendor/abseil-cpp/absl/random/distributions.h +17 -17
  208. package/vendor/abseil-cpp/absl/random/distributions_test.cc +4 -4
  209. package/vendor/abseil-cpp/absl/random/exponential_distribution.h +1 -1
  210. package/vendor/abseil-cpp/absl/random/internal/BUILD.bazel +4 -2
  211. package/vendor/abseil-cpp/absl/random/internal/distribution_caller.h +8 -21
  212. package/vendor/abseil-cpp/absl/random/internal/fast_uniform_bits.h +1 -1
  213. package/vendor/abseil-cpp/absl/random/internal/generate_real.h +1 -1
  214. package/vendor/abseil-cpp/absl/random/internal/iostream_state_saver.h +2 -2
  215. package/vendor/abseil-cpp/absl/random/internal/iostream_state_saver_test.cc +3 -2
  216. package/vendor/abseil-cpp/absl/random/internal/mock_helpers.h +14 -40
  217. package/vendor/abseil-cpp/absl/random/internal/nonsecure_base.h +2 -2
  218. package/vendor/abseil-cpp/absl/random/internal/nonsecure_base_test.cc +2 -2
  219. package/vendor/abseil-cpp/absl/random/internal/pcg_engine.h +6 -6
  220. package/vendor/abseil-cpp/absl/random/internal/pcg_engine_test.cc +3 -2
  221. package/vendor/abseil-cpp/absl/random/internal/randen_detect.cc +6 -6
  222. package/vendor/abseil-cpp/absl/random/internal/randen_engine.h +2 -2
  223. package/vendor/abseil-cpp/absl/random/internal/randen_engine_test.cc +3 -2
  224. package/vendor/abseil-cpp/absl/random/internal/randen_test.cc +3 -2
  225. package/vendor/abseil-cpp/absl/random/internal/salted_seed_seq.h +6 -5
  226. package/vendor/abseil-cpp/absl/random/internal/seed_material.cc +4 -4
  227. package/vendor/abseil-cpp/absl/random/internal/seed_material.h +2 -1
  228. package/vendor/abseil-cpp/absl/random/internal/traits.h +21 -0
  229. package/vendor/abseil-cpp/absl/random/internal/traits_test.cc +5 -0
  230. package/vendor/abseil-cpp/absl/random/internal/uniform_helper.h +23 -23
  231. package/vendor/abseil-cpp/absl/random/internal/uniform_helper_test.cc +2 -1
  232. package/vendor/abseil-cpp/absl/random/mocking_access.h +74 -0
  233. package/vendor/abseil-cpp/absl/random/mocking_bit_gen.h +9 -19
  234. package/vendor/abseil-cpp/absl/random/uniform_real_distribution.h +1 -1
  235. package/vendor/abseil-cpp/absl/status/BUILD.bazel +81 -0
  236. package/vendor/abseil-cpp/absl/status/CMakeLists.txt +91 -0
  237. package/vendor/abseil-cpp/absl/status/internal/status_internal.cc +63 -18
  238. package/vendor/abseil-cpp/absl/status/internal/status_internal.h +26 -2
  239. package/vendor/abseil-cpp/absl/status/internal/status_matchers.h +22 -8
  240. package/vendor/abseil-cpp/absl/status/internal/statusor_internal.h +43 -43
  241. package/vendor/abseil-cpp/absl/status/status.cc +62 -70
  242. package/vendor/abseil-cpp/absl/status/status.h +249 -23
  243. package/vendor/abseil-cpp/absl/status/status_benchmark.cc +12 -0
  244. package/vendor/abseil-cpp/absl/status/status_builder.cc +196 -0
  245. package/vendor/abseil-cpp/absl/status/status_builder.h +978 -0
  246. package/vendor/abseil-cpp/absl/status/status_builder_test.cc +380 -0
  247. package/vendor/abseil-cpp/absl/status/status_macros.h +484 -0
  248. package/vendor/abseil-cpp/absl/status/status_macros_test.cc +634 -0
  249. package/vendor/abseil-cpp/absl/status/status_matchers.h +2 -1
  250. package/vendor/abseil-cpp/absl/status/status_matchers_test.cc +3 -4
  251. package/vendor/abseil-cpp/absl/status/status_payload_printer.h +3 -2
  252. package/vendor/abseil-cpp/absl/status/status_test.cc +443 -13
  253. package/vendor/abseil-cpp/absl/status/statusor.h +69 -36
  254. package/vendor/abseil-cpp/absl/status/statusor_test.cc +132 -35
  255. package/vendor/abseil-cpp/absl/strings/BUILD.bazel +42 -7
  256. package/vendor/abseil-cpp/absl/strings/CMakeLists.txt +33 -4
  257. package/vendor/abseil-cpp/absl/strings/ascii.h +1 -2
  258. package/vendor/abseil-cpp/absl/strings/atod_manual_test.cc +5 -5
  259. package/vendor/abseil-cpp/absl/strings/cord.cc +26 -7
  260. package/vendor/abseil-cpp/absl/strings/cord.h +23 -13
  261. package/vendor/abseil-cpp/absl/strings/cord_buffer.h +4 -2
  262. package/vendor/abseil-cpp/absl/strings/cord_test.cc +85 -9
  263. package/vendor/abseil-cpp/absl/strings/escaping.cc +183 -35
  264. package/vendor/abseil-cpp/absl/strings/escaping.h +12 -2
  265. package/vendor/abseil-cpp/absl/strings/escaping_benchmark.cc +1 -3
  266. package/vendor/abseil-cpp/absl/strings/escaping_test.cc +22 -18
  267. package/vendor/abseil-cpp/absl/strings/has_absl_stringify_test.cc +2 -2
  268. package/vendor/abseil-cpp/absl/strings/has_ostream_operator_test.cc +2 -2
  269. package/vendor/abseil-cpp/absl/strings/internal/append_and_overwrite.h +10 -10
  270. package/vendor/abseil-cpp/absl/strings/internal/cordz_sample_token_test.cc +1 -1
  271. package/vendor/abseil-cpp/absl/strings/internal/damerau_levenshtein_distance.cc +6 -0
  272. package/vendor/abseil-cpp/absl/strings/internal/damerau_levenshtein_distance.h +1 -0
  273. package/vendor/abseil-cpp/absl/strings/internal/escaping.cc +0 -141
  274. package/vendor/abseil-cpp/absl/strings/internal/escaping.h +2 -26
  275. package/vendor/abseil-cpp/absl/strings/internal/generic_printer_internal.h +23 -2
  276. package/vendor/abseil-cpp/absl/strings/internal/generic_printer_test.cc +6 -2
  277. package/vendor/abseil-cpp/absl/strings/internal/resize_uninitialized.h +31 -24
  278. package/vendor/abseil-cpp/absl/strings/internal/resize_uninitialized_test.cc +16 -41
  279. package/vendor/abseil-cpp/absl/strings/internal/stl_type_traits.h +39 -39
  280. package/vendor/abseil-cpp/absl/strings/internal/str_format/arg.h +14 -22
  281. package/vendor/abseil-cpp/absl/strings/internal/str_format/bind.h +2 -2
  282. package/vendor/abseil-cpp/absl/strings/internal/str_format/convert_test.cc +12 -20
  283. package/vendor/abseil-cpp/absl/strings/internal/str_format/float_conversion.cc +510 -307
  284. package/vendor/abseil-cpp/absl/strings/internal/str_join_internal.h +0 -1
  285. package/vendor/abseil-cpp/absl/strings/internal/str_split_internal.h +9 -10
  286. package/vendor/abseil-cpp/absl/strings/internal/string_constant_test.cc +6 -5
  287. package/vendor/abseil-cpp/absl/strings/internal/stringify_sink.h +12 -0
  288. package/vendor/abseil-cpp/absl/strings/internal/stringify_stream.h +119 -0
  289. package/vendor/abseil-cpp/absl/strings/internal/stringify_stream_test.cc +111 -0
  290. package/vendor/abseil-cpp/absl/strings/numbers.cc +406 -0
  291. package/vendor/abseil-cpp/absl/strings/numbers.h +4 -0
  292. package/vendor/abseil-cpp/absl/strings/numbers_test.cc +33 -0
  293. package/vendor/abseil-cpp/absl/strings/resize_and_overwrite.h +10 -6
  294. package/vendor/abseil-cpp/absl/strings/str_cat.h +36 -1
  295. package/vendor/abseil-cpp/absl/strings/str_cat_benchmark.cc +1 -2
  296. package/vendor/abseil-cpp/absl/strings/str_cat_test.cc +28 -0
  297. package/vendor/abseil-cpp/absl/strings/str_join_test.cc +4 -4
  298. package/vendor/abseil-cpp/absl/strings/str_split.h +11 -6
  299. package/vendor/abseil-cpp/absl/strings/str_split_test.cc +13 -0
  300. package/vendor/abseil-cpp/absl/strings/substitute.h +2 -2
  301. package/vendor/abseil-cpp/absl/synchronization/BUILD.bazel +3 -0
  302. package/vendor/abseil-cpp/absl/synchronization/internal/create_thread_identity.cc +21 -0
  303. package/vendor/abseil-cpp/absl/synchronization/internal/per_thread_sem.h +5 -0
  304. package/vendor/abseil-cpp/absl/synchronization/mutex.cc +13 -0
  305. package/vendor/abseil-cpp/absl/synchronization/mutex.h +32 -2
  306. package/vendor/abseil-cpp/absl/synchronization/mutex_test.cc +17 -3
  307. package/vendor/abseil-cpp/absl/time/BUILD.bazel +80 -0
  308. package/vendor/abseil-cpp/absl/time/CMakeLists.txt +73 -0
  309. package/vendor/abseil-cpp/absl/time/clock.h +3 -0
  310. package/vendor/abseil-cpp/absl/time/clock_interface.cc +71 -0
  311. package/vendor/abseil-cpp/absl/time/clock_interface.h +93 -0
  312. package/vendor/abseil-cpp/absl/time/clock_interface_test.cc +128 -0
  313. package/vendor/abseil-cpp/absl/time/format.cc +3 -10
  314. package/vendor/abseil-cpp/absl/time/format_test.cc +12 -0
  315. package/vendor/abseil-cpp/absl/time/internal/cctz/src/time_zone_format.cc +90 -89
  316. package/vendor/abseil-cpp/absl/time/internal/cctz/src/time_zone_format_test.cc +80 -5
  317. package/vendor/abseil-cpp/absl/time/internal/cctz/src/time_zone_name_win.cc +1 -2
  318. package/vendor/abseil-cpp/absl/time/internal/cctz/src/tzfile.h +10 -15
  319. package/vendor/abseil-cpp/absl/time/internal/cctz/testdata/version +1 -1
  320. package/vendor/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Vancouver +0 -0
  321. package/vendor/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ho_Chi_Minh +0 -0
  322. package/vendor/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Phnom_Penh +0 -0
  323. package/vendor/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Saigon +0 -0
  324. package/vendor/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tbilisi +0 -0
  325. package/vendor/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Vientiane +0 -0
  326. package/vendor/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Canada/Pacific +0 -0
  327. package/vendor/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Chisinau +0 -0
  328. package/vendor/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Tiraspol +0 -0
  329. package/vendor/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/zone1970.tab +1 -1
  330. package/vendor/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/zonenow.tab +3 -3
  331. package/vendor/abseil-cpp/absl/time/simulated_clock.cc +225 -0
  332. package/vendor/abseil-cpp/absl/time/simulated_clock.h +109 -0
  333. package/vendor/abseil-cpp/absl/time/simulated_clock_test.cc +614 -0
  334. package/vendor/abseil-cpp/absl/types/BUILD.bazel +116 -0
  335. package/vendor/abseil-cpp/absl/types/CMakeLists.txt +100 -0
  336. package/vendor/abseil-cpp/absl/types/any.h +26 -4
  337. package/vendor/abseil-cpp/absl/types/any_span.h +1067 -0
  338. package/vendor/abseil-cpp/absl/types/any_span_benchmark.cc +258 -0
  339. package/vendor/abseil-cpp/absl/types/any_span_test.cc +1210 -0
  340. package/vendor/abseil-cpp/absl/types/compare.h +4 -4
  341. package/vendor/abseil-cpp/absl/types/internal/any_span.h +477 -0
  342. package/vendor/abseil-cpp/absl/types/internal/span.h +5 -6
  343. package/vendor/abseil-cpp/absl/types/optional.h +30 -3
  344. package/vendor/abseil-cpp/absl/types/optional_ref.h +295 -0
  345. package/vendor/abseil-cpp/absl/types/optional_ref_test.cc +370 -0
  346. package/vendor/abseil-cpp/absl/types/source_location.cc +18 -0
  347. package/vendor/abseil-cpp/absl/types/source_location.h +172 -0
  348. package/vendor/abseil-cpp/absl/types/source_location_test.cc +139 -0
  349. package/vendor/abseil-cpp/absl/types/span.h +19 -23
  350. package/vendor/abseil-cpp/absl/types/variant.h +75 -18
  351. package/vendor/abseil-cpp/absl/types/variant_test.cc +23 -23
  352. package/vendor/abseil-cpp/absl/utility/BUILD.bazel +1 -0
  353. package/vendor/abseil-cpp/absl/utility/CMakeLists.txt +1 -0
  354. package/vendor/abseil-cpp/absl/utility/utility.h +99 -16
  355. package/vendor/abseil-cpp/ci/absl_alternate_options.h +2 -0
  356. package/vendor/abseil-cpp/ci/linux_arm_clang-latest_libcxx_bazel.sh +10 -4
  357. package/vendor/abseil-cpp/ci/linux_clang-latest_libcxx_asan_bazel.sh +13 -6
  358. package/vendor/abseil-cpp/ci/linux_clang-latest_libcxx_bazel.sh +10 -4
  359. package/vendor/abseil-cpp/ci/linux_clang-latest_libcxx_tsan_bazel.sh +12 -5
  360. package/vendor/abseil-cpp/ci/linux_clang-latest_libstdcxx_bazel.sh +9 -2
  361. package/vendor/abseil-cpp/ci/linux_docker_containers.sh +4 -4
  362. package/vendor/abseil-cpp/ci/linux_gcc-floor_libstdcxx_bazel.sh +10 -3
  363. package/vendor/abseil-cpp/ci/linux_gcc-latest_libstdcxx_bazel.sh +8 -2
  364. package/vendor/abseil-cpp/ci/macos_xcode_bazel.sh +4 -3
  365. package/vendor/abseil-cpp/ci/macos_xcode_cmake.sh +2 -2
  366. package/vendor/abseil-cpp/ci/windows_clangcl_bazel.bat +1 -1
  367. package/vendor/abseil-cpp/ci/windows_msvc_bazel.bat +1 -1
  368. package/vendor/abseil-cpp/absl/debugging/internal/borrowed_fixup_buffer.cc +0 -118
  369. package/vendor/abseil-cpp/absl/debugging/internal/borrowed_fixup_buffer.h +0 -71
  370. package/vendor/abseil-cpp/absl/debugging/internal/borrowed_fixup_buffer_test.cc +0 -97
@@ -31,6 +31,7 @@
31
31
  #include <map>
32
32
  #include <memory>
33
33
  #include <numeric>
34
+ #include <optional>
34
35
  #include <ostream>
35
36
  #include <random>
36
37
  #include <set>
@@ -53,7 +54,6 @@
53
54
  #include "absl/container/internal/container_memory.h"
54
55
  #include "absl/container/internal/hash_function_defaults.h"
55
56
  #include "absl/container/internal/hash_policy_testing.h"
56
- #include "absl/random/random.h"
57
57
  #include "absl/container/internal/hashtable_control_bytes.h"
58
58
  #include "absl/container/internal/hashtable_debug.h"
59
59
  #include "absl/container/internal/hashtablez_sampler.h"
@@ -68,9 +68,9 @@
68
68
  #include "absl/memory/memory.h"
69
69
  #include "absl/meta/type_traits.h"
70
70
  #include "absl/numeric/int128.h"
71
+ #include "absl/random/random.h"
71
72
  #include "absl/strings/str_cat.h"
72
73
  #include "absl/strings/string_view.h"
73
- #include "absl/types/optional.h"
74
74
 
75
75
  namespace absl {
76
76
  ABSL_NAMESPACE_BEGIN
@@ -96,6 +96,7 @@ namespace {
96
96
  using ::testing::ElementsAre;
97
97
  using ::testing::Eq;
98
98
  using ::testing::Ge;
99
+ using ::testing::HasSubstr;
99
100
  using ::testing::Lt;
100
101
  using ::testing::Pair;
101
102
  using ::testing::UnorderedElementsAre;
@@ -337,7 +338,8 @@ TEST(Util, GrowthAndCapacity) {
337
338
  }
338
339
 
339
340
  TEST(Util, probe_seq) {
340
- probe_seq<16> seq(0, 127);
341
+ HashtableCapacity capacity(127);
342
+ probe_seq<16> seq(capacity, /*hash=*/0);
341
343
  auto gen = [&]() {
342
344
  size_t res = seq.offset();
343
345
  seq.next();
@@ -346,11 +348,191 @@ TEST(Util, probe_seq) {
346
348
  std::vector<size_t> offsets(8);
347
349
  std::generate_n(offsets.begin(), 8, gen);
348
350
  EXPECT_THAT(offsets, ElementsAre(0, 16, 48, 96, 32, 112, 80, 64));
349
- seq = probe_seq<16>(128, 127);
351
+ seq = probe_seq<16>(capacity, /*hash=*/128);
350
352
  std::generate_n(offsets.begin(), 8, gen);
351
353
  EXPECT_THAT(offsets, ElementsAre(0, 16, 48, 96, 32, 112, 80, 64));
352
354
  }
353
355
 
356
+ template <typename T>
357
+ class HashtableDataTest : public ::testing::Test {};
358
+
359
+ using StorageModes = ::testing::Types<
360
+ std::integral_constant<HashtableCapacityStorageMode,
361
+ HashtableCapacityStorageMode::kCapacityByValue>,
362
+ std::integral_constant<HashtableCapacityStorageMode,
363
+ HashtableCapacityStorageMode::kCapacityByLog>>;
364
+
365
+ TYPED_TEST_SUITE(HashtableDataTest, StorageModes);
366
+
367
+ TYPED_TEST(HashtableDataTest, HashtableCapacity) {
368
+ constexpr HashtableCapacityStorageMode kMode = TypeParam::value;
369
+ using Capacity = HashtableCapacityImpl<kMode>;
370
+
371
+ Capacity cap0(0);
372
+ EXPECT_TRUE(cap0.IsValid());
373
+ EXPECT_EQ(cap0.capacity(), 0);
374
+ EXPECT_FALSE(cap0.IsDestroyed());
375
+ EXPECT_FALSE(cap0.IsReentrance());
376
+ EXPECT_FALSE(cap0.IsMovedFrom());
377
+ EXPECT_FALSE(cap0.IsSelfMovedFrom());
378
+
379
+ for (size_t i = 0, cap = 0; i < 20; ++i, cap = NextCapacity(cap)) {
380
+ Capacity capacity(cap);
381
+ ASSERT_TRUE(capacity.IsValid());
382
+ ASSERT_EQ(capacity.capacity(), cap);
383
+ }
384
+
385
+ auto destroyed = Capacity::CreateDestroyed();
386
+ EXPECT_FALSE(destroyed.IsValid());
387
+ EXPECT_TRUE(destroyed.IsDestroyed());
388
+
389
+ auto reentrance = Capacity::CreateReentrance();
390
+ EXPECT_FALSE(reentrance.IsValid());
391
+ EXPECT_TRUE(reentrance.IsReentrance());
392
+
393
+ auto moved_from = Capacity::CreateMovedFrom();
394
+ EXPECT_FALSE(moved_from.IsValid());
395
+ EXPECT_TRUE(moved_from.IsMovedFrom());
396
+ EXPECT_FALSE(moved_from.IsSelfMovedFrom());
397
+
398
+ auto self_moved_from = Capacity::CreateSelfMovedFrom();
399
+ EXPECT_FALSE(self_moved_from.IsValid());
400
+ EXPECT_TRUE(self_moved_from.IsSelfMovedFrom());
401
+ EXPECT_TRUE(self_moved_from.IsMovedFrom());
402
+ }
403
+
404
+ TYPED_TEST(HashtableDataTest, RawData) {
405
+ constexpr HashtableCapacityStorageMode kMode = TypeParam::value;
406
+ using Capacity = HashtableCapacityImpl<kMode>;
407
+
408
+ for (size_t i = 0, cap = 0; i < 20; ++i, cap = NextCapacity(cap)) {
409
+ Capacity orig_capacity(cap);
410
+ Capacity capacity = Capacity::FromRawData(orig_capacity.ToRawData());
411
+ ASSERT_TRUE(capacity.IsValid());
412
+ ASSERT_EQ(capacity.capacity(), cap);
413
+ }
414
+ auto orig_reentrance = Capacity::CreateReentrance();
415
+ Capacity reentrance = Capacity::FromRawData(orig_reentrance.ToRawData());
416
+ EXPECT_TRUE(reentrance.IsReentrance());
417
+ }
418
+
419
+ TYPED_TEST(HashtableDataTest, HashtableInlineDataCapacity) {
420
+ constexpr HashtableCapacityStorageMode kMode = TypeParam::value;
421
+ using InlineData = HashtableInlineDataImpl<kMode>;
422
+ using Capacity = HashtableCapacityImpl<kMode>;
423
+
424
+ InlineData data(Capacity(0), no_seed_empty_tag_t{});
425
+ EXPECT_EQ(data.capacity().capacity(), 0);
426
+ EXPECT_EQ(data.size(), 0);
427
+ EXPECT_TRUE(data.empty());
428
+
429
+ for (size_t i = 0, cap = 0; i < 20; ++i, cap = NextCapacity(cap)) {
430
+ data.set_capacity(cap);
431
+ ASSERT_EQ(data.capacity().capacity(), cap);
432
+ }
433
+
434
+ // Test overload from `Capacity` object.
435
+ for (size_t i = 0, cap = 0; i < 20; ++i, cap = NextCapacity(cap)) {
436
+ data.set_capacity(Capacity(cap));
437
+ ASSERT_EQ(data.capacity().capacity(), cap);
438
+ }
439
+
440
+ auto reentrance = Capacity::CreateReentrance();
441
+ data.set_capacity(reentrance);
442
+ EXPECT_TRUE(data.capacity().IsReentrance());
443
+ }
444
+
445
+ TYPED_TEST(HashtableDataTest, HashtableInlineDataSize) {
446
+ constexpr HashtableCapacityStorageMode kMode = TypeParam::value;
447
+ using InlineData = HashtableInlineDataImpl<kMode>;
448
+ using Capacity = HashtableCapacityImpl<kMode>;
449
+
450
+ InlineData data(Capacity(0), no_seed_empty_tag_t{});
451
+ EXPECT_EQ(data.size(), 0);
452
+ data.increment_size();
453
+ EXPECT_EQ(data.size(), 1);
454
+ EXPECT_FALSE(data.empty());
455
+
456
+ data.increment_size(5);
457
+ EXPECT_EQ(data.size(), 6);
458
+
459
+ data.decrement_size();
460
+ EXPECT_EQ(data.size(), 5);
461
+
462
+ constexpr size_t kHugeIncrement =
463
+ (size_t(1) << (sizeof(size_t) == 4 ? 31 : 42));
464
+ data.increment_size(kHugeIncrement);
465
+ EXPECT_EQ(data.size(), kHugeIncrement + 5);
466
+
467
+ EXPECT_FALSE(data.has_infoz());
468
+ data.set_has_infoz();
469
+ data.set_size(10);
470
+ EXPECT_EQ(data.size(), 10);
471
+ EXPECT_TRUE(data.has_infoz());
472
+ }
473
+
474
+ TYPED_TEST(HashtableDataTest, HashtableInlineDataMetadata) {
475
+ constexpr HashtableCapacityStorageMode kMode = TypeParam::value;
476
+ using InlineData = HashtableInlineDataImpl<kMode>;
477
+ using Capacity = HashtableCapacityImpl<kMode>;
478
+
479
+ InlineData data(Capacity(0), no_seed_empty_tag_t{});
480
+
481
+ // SOO sampling (test this first before seed messes with bit 0)
482
+ EXPECT_FALSE(data.soo_has_tried_sampling());
483
+ data.set_soo_has_tried_sampling();
484
+ EXPECT_TRUE(data.soo_has_tried_sampling());
485
+
486
+ data.set_no_seed_for_testing();
487
+ EXPECT_EQ(data.seed().seed(), 0);
488
+
489
+ data.set_sampled_seed();
490
+ EXPECT_TRUE(data.is_sampled_seed());
491
+
492
+ // Infoz
493
+ EXPECT_FALSE(data.has_infoz());
494
+ data.set_has_infoz();
495
+ EXPECT_TRUE(data.has_infoz());
496
+ }
497
+
498
+ TYPED_TEST(HashtableDataTest, HashtableInlineDataFullSooConstructor) {
499
+ constexpr HashtableCapacityStorageMode kMode = TypeParam::value;
500
+ using InlineData = HashtableInlineDataImpl<kMode>;
501
+ using Capacity = HashtableCapacityImpl<kMode>;
502
+
503
+ {
504
+ InlineData data_soo(Capacity(1), full_soo_tag_t{},
505
+ /*has_tried_sampling=*/true);
506
+ EXPECT_EQ(data_soo.capacity().capacity(), 1);
507
+ EXPECT_EQ(data_soo.size(), 1);
508
+ EXPECT_TRUE(data_soo.soo_has_tried_sampling());
509
+ }
510
+
511
+ {
512
+ InlineData data_soo(Capacity(1), full_soo_tag_t{},
513
+ /*has_tried_sampling=*/false);
514
+ EXPECT_EQ(data_soo.capacity().capacity(), 1);
515
+ EXPECT_EQ(data_soo.size(), 1);
516
+ EXPECT_FALSE(data_soo.soo_has_tried_sampling());
517
+ }
518
+ }
519
+
520
+ TYPED_TEST(HashtableDataTest, GenerateNewSeedDoesntChangeSize) {
521
+ constexpr HashtableCapacityStorageMode kMode = TypeParam::value;
522
+ using InlineData = HashtableInlineDataImpl<kMode>;
523
+ using Capacity = HashtableCapacityImpl<kMode>;
524
+ size_t size = 1;
525
+ do {
526
+ InlineData inline_data(Capacity(15), no_seed_empty_tag_t{});
527
+ inline_data.increment_size(size);
528
+ EXPECT_EQ(inline_data.size(), size);
529
+ inline_data.generate_new_seed();
530
+ EXPECT_EQ(inline_data.size(), size);
531
+ size = size * 2 + 1;
532
+ } while (size < std::min(MaxStorableSize(),
533
+ MaxSizeAtMaxValidCapacity(/*slot_size=*/1)));
534
+ }
535
+
354
536
  TEST(Batch, DropDeletes) {
355
537
  constexpr size_t kCapacity = 63;
356
538
  constexpr size_t kGroupWidth = container_internal::Group::kWidth;
@@ -388,13 +570,13 @@ struct ValuePolicy {
388
570
 
389
571
  template <class Allocator, class... Args>
390
572
  static void construct(Allocator* alloc, slot_type* slot, Args&&... args) {
391
- absl::allocator_traits<Allocator>::construct(*alloc, slot,
392
- std::forward<Args>(args)...);
573
+ std::allocator_traits<Allocator>::construct(*alloc, slot,
574
+ std::forward<Args>(args)...);
393
575
  }
394
576
 
395
577
  template <class Allocator>
396
578
  static void destroy(Allocator* alloc, slot_type* slot) {
397
- absl::allocator_traits<Allocator>::destroy(*alloc, slot);
579
+ std::allocator_traits<Allocator>::destroy(*alloc, slot);
398
580
  }
399
581
 
400
582
  template <class Allocator>
@@ -745,12 +927,20 @@ TEST(Table, EmptyFunctorOptimization) {
745
927
  static_assert(std::is_empty<std::equal_to<absl::string_view>>::value, "");
746
928
  static_assert(std::is_empty<std::allocator<int>>::value, "");
747
929
 
748
- struct MockTable {
930
+ struct MockTableByValue {
749
931
  size_t capacity;
750
932
  uint64_t size;
751
933
  void* ctrl;
752
934
  void* slots;
753
935
  };
936
+ struct MockTableByLog {
937
+ uint64_t size;
938
+ void* ctrl;
939
+ void* slots;
940
+ };
941
+ using MockTable =
942
+ std::conditional_t<HashtableInlineData::kStorageMode == kCapacityByValue,
943
+ MockTableByValue, MockTableByLog>;
754
944
  struct StatelessHash {
755
945
  size_t operator()(absl::string_view) const { return 0; }
756
946
  };
@@ -975,6 +1165,101 @@ TYPED_TEST(SooTest, InsertWithinCapacity) {
975
1165
  EXPECT_THAT(addr(0), original_addr_0);
976
1166
  }
977
1167
 
1168
+ TYPED_TEST(SooTest, ClearDifferentSizes) {
1169
+ for (size_t size = 0; size < 32; ++size) {
1170
+ for (bool reserve : {false, true}) {
1171
+ for (bool clear_via_erase : {false, true}) {
1172
+ SCOPED_TRACE(absl::StrCat("size: ", size, ", reserve: ", reserve,
1173
+ ", clear_via_erase: ", clear_via_erase));
1174
+ TypeParam t;
1175
+ if (reserve) {
1176
+ t.reserve(size);
1177
+ }
1178
+ for (size_t i = 0; i < size; ++i) {
1179
+ ASSERT_TRUE(t.insert(static_cast<int>(i)).second) << i;
1180
+ }
1181
+ if (clear_via_erase) {
1182
+ t.erase(t.begin(), t.end());
1183
+ } else {
1184
+ t.clear();
1185
+ }
1186
+ ASSERT_EQ(t.size(), 0);
1187
+ for (size_t i = 0; i < size; ++i) {
1188
+ ASSERT_TRUE(t.insert(static_cast<int>(i)).second) << i;
1189
+ }
1190
+ }
1191
+ }
1192
+ }
1193
+ }
1194
+
1195
+ TYPED_TEST(SooTest, ReserveTwice) {
1196
+ for (size_t reserve_size = 0; reserve_size < 32; ++reserve_size) {
1197
+ for (size_t reserve_size2 = reserve_size; reserve_size2 < 32;
1198
+ ++reserve_size2) {
1199
+ SCOPED_TRACE(absl::StrCat("reserve_size: ", reserve_size,
1200
+ ", reserve_size2: ", reserve_size2));
1201
+ TypeParam t;
1202
+ t.reserve(reserve_size);
1203
+ { // Insert first batch of elements.
1204
+ size_t cap = t.capacity();
1205
+ for (size_t i = 0; i < reserve_size; ++i) {
1206
+ ASSERT_TRUE(t.insert(static_cast<int>(i)).second) << i;
1207
+ }
1208
+ ASSERT_EQ(t.capacity(), cap);
1209
+ }
1210
+ t.reserve(reserve_size2);
1211
+ { // Insert second batch of elements.
1212
+ size_t cap = t.capacity();
1213
+ for (size_t i = reserve_size; i < reserve_size2; ++i) {
1214
+ ASSERT_TRUE(t.insert(static_cast<int>(i)).second) << i;
1215
+ }
1216
+ ASSERT_EQ(t.capacity(), cap);
1217
+ }
1218
+ for (size_t i = 0; i < reserve_size2; ++i) {
1219
+ ASSERT_TRUE(t.contains(static_cast<int>(i))) << i;
1220
+ }
1221
+ }
1222
+ }
1223
+ }
1224
+
1225
+ TYPED_TEST(SooTest, GrowAfterReserve) {
1226
+ for (size_t reserve_size = 1; reserve_size <= 150; ++reserve_size) {
1227
+ size_t size = reserve_size + 1;
1228
+ TypeParam s;
1229
+ s.reserve(reserve_size);
1230
+ for (size_t i = 0; i < size; ++i) {
1231
+ ASSERT_TRUE(s.insert(static_cast<int>(i)).second) << i;
1232
+ }
1233
+ EXPECT_EQ(s.size(), size);
1234
+ for (size_t i = 0; i < size; ++i) {
1235
+ ASSERT_TRUE(s.contains(static_cast<int>(i))) << i;
1236
+ }
1237
+ }
1238
+ }
1239
+
1240
+ TYPED_TEST(SooTest, ClearAfterReserve) {
1241
+ for (size_t reserve_size :
1242
+ std::vector<size_t>{1, 3, 4, 6, 7, 8, 13, 14, 15, 128, 150}) {
1243
+ TypeParam s;
1244
+ s.reserve(reserve_size);
1245
+ for (size_t i = 0; i < reserve_size; ++i) {
1246
+ ASSERT_TRUE(s.insert(static_cast<int>(i)).second);
1247
+ }
1248
+ EXPECT_EQ(s.size(), reserve_size);
1249
+ s.clear();
1250
+ EXPECT_EQ(s.size(), 0);
1251
+ for (size_t i = 0; i < reserve_size; ++i) {
1252
+ ASSERT_FALSE(s.contains(static_cast<int>(i))) << i;
1253
+ }
1254
+ for (size_t i = 0; i < reserve_size; ++i) {
1255
+ ASSERT_TRUE(s.insert(static_cast<int>(i)).second) << i;
1256
+ }
1257
+ for (size_t i = 0; i < reserve_size; ++i) {
1258
+ ASSERT_TRUE(s.contains(static_cast<int>(i))) << i;
1259
+ }
1260
+ }
1261
+ }
1262
+
978
1263
  template <class TableType>
979
1264
  class SmallTableResizeTest : public testing::Test {};
980
1265
 
@@ -2307,7 +2592,7 @@ TEST(Table, NoThrowMoveAssign) {
2307
2592
  std::is_nothrow_move_assignable<std::equal_to<absl::string_view>>::value);
2308
2593
  ASSERT_TRUE(std::is_nothrow_move_assignable<std::allocator<int>>::value);
2309
2594
  ASSERT_TRUE(
2310
- absl::allocator_traits<std::allocator<int>>::is_always_equal::value);
2595
+ std::allocator_traits<std::allocator<int>>::is_always_equal::value);
2311
2596
  EXPECT_TRUE(std::is_nothrow_move_assignable<StringTable>::value);
2312
2597
  }
2313
2598
 
@@ -2383,7 +2668,7 @@ template <template <typename> class C, class Table, class = void>
2383
2668
  struct VerifyResultOf : std::false_type {};
2384
2669
 
2385
2670
  template <template <typename> class C, class Table>
2386
- struct VerifyResultOf<C, Table, absl::void_t<C<Table>>> : std::true_type {};
2671
+ struct VerifyResultOf<C, Table, std::void_t<C<Table>>> : std::true_type {};
2387
2672
 
2388
2673
  TEST(Table, HeterogeneousLookupOverloads) {
2389
2674
  using NonTransparentTable =
@@ -2582,6 +2867,18 @@ TYPED_TEST(SooTest, HintInsert) {
2582
2867
  EXPECT_TRUE(node); // NOLINT(bugprone-use-after-move)
2583
2868
  }
2584
2869
 
2870
+ TYPED_TEST(SooTest, RehashZeroForSmallTable) {
2871
+ TypeParam t{0};
2872
+ EXPECT_EQ(t.capacity(), 1);
2873
+ t.rehash(0);
2874
+ EXPECT_EQ(t.capacity(), 1);
2875
+ EXPECT_TRUE(t.contains(0));
2876
+ t.insert(1);
2877
+ EXPECT_EQ(t.capacity(), NextCapacity(1));
2878
+ EXPECT_TRUE(t.contains(0));
2879
+ EXPECT_TRUE(t.contains(1));
2880
+ }
2881
+
2585
2882
  template <typename T>
2586
2883
  T MakeSimpleTable(size_t size, bool do_reserve) {
2587
2884
  T t;
@@ -2601,7 +2898,7 @@ std::vector<int> OrderOfIteration(const T& t) {
2601
2898
  // in seed.
2602
2899
  void GenerateIrrelevantSeeds(int cnt) {
2603
2900
  for (int i = cnt % 17; i > 0; --i) {
2604
- HashtableSize::NextSeed();
2901
+ NextHashTableSeed();
2605
2902
  }
2606
2903
  }
2607
2904
 
@@ -2639,8 +2936,8 @@ TYPED_TEST(SooTest, IterationOrderChangesOnRehash) {
2639
2936
  for (bool do_reserve : {false, true}) {
2640
2937
  for (size_t size : {2u, 3u, 6u, 7u, 12u, 15u, 20u, 50u}) {
2641
2938
  for (size_t rehash_size : {
2642
- size_t{0}, // Force rehash is guaranteed.
2643
- size * 10 // Rehash to the larger capacity is guaranteed.
2939
+ size_t{0}, // Force rehash is guaranteed.
2940
+ size * 10 // Rehash to the larger capacity is guaranteed.
2644
2941
  }) {
2645
2942
  SCOPED_TRACE(absl::StrCat("size: ", size, " rehash_size: ", rehash_size,
2646
2943
  " do_reserve: ", do_reserve));
@@ -2732,18 +3029,12 @@ TEST(TableDeathTest, InvalidIteratorAssertsSoo) {
2732
3029
  // the control is static constant.
2733
3030
  }
2734
3031
 
2735
- // Invalid iterator use can trigger use-after-free in asan/hwasan,
2736
- // use-of-uninitialized-value in msan, or invalidated iterator assertions.
2737
- constexpr const char* kInvalidIteratorDeathMessage =
2738
- "use-after-free|use-of-uninitialized-value|invalidated "
2739
- "iterator|Invalid iterator|invalid iterator";
2740
-
2741
- // MSVC doesn't support | in regex.
2742
- #if defined(_MSC_VER)
2743
- constexpr bool kMsvc = true;
2744
- #else
2745
- constexpr bool kMsvc = false;
2746
- #endif
3032
+ // Invalid iterator use can trigger crashes or invalidated iterator assertions.
3033
+ testing::Matcher<const std::string&> InvalidIteratorMatcher() {
3034
+ return AnyOf(HasSubstr("invalidated iterator"), HasSubstr("Invalid iterator"),
3035
+ HasSubstr("invalid iterator"),
3036
+ HasSubstr("CrashIfIteratorIsInvalid"));
3037
+ }
2747
3038
 
2748
3039
  TYPED_TEST(SooTest, IteratorInvalidAssertsEqualityOperator) {
2749
3040
  if (!IsAssertEnabled() && !SwisstableGenerationsEnabled())
@@ -2785,7 +3076,6 @@ TYPED_TEST(SooTest, IteratorInvalidAssertsEqualityOperator) {
2785
3076
  TYPED_TEST(SooTest, IteratorInvalidAssertsEqualityOperatorRehash) {
2786
3077
  if (!IsAssertEnabled() && !SwisstableGenerationsEnabled())
2787
3078
  GTEST_SKIP() << "Assertions not enabled.";
2788
- if (kMsvc) GTEST_SKIP() << "MSVC doesn't support | in regex.";
2789
3079
  #ifdef ABSL_HAVE_THREAD_SANITIZER
2790
3080
  GTEST_SKIP() << "ThreadSanitizer test runs fail on use-after-free even in "
2791
3081
  "EXPECT_DEATH.";
@@ -2798,11 +3088,20 @@ TYPED_TEST(SooTest, IteratorInvalidAssertsEqualityOperatorRehash) {
2798
3088
  // Trigger a rehash in t.
2799
3089
  for (int i = 0; i < 10; ++i) t.insert(i);
2800
3090
 
2801
- const char* const kRehashedDeathMessage =
2802
- SwisstableGenerationsEnabled()
2803
- ? kInvalidIteratorDeathMessage
2804
- : "Invalid iterator comparison.*might have rehashed.*config=asan";
2805
- EXPECT_DEATH_IF_SUPPORTED(void(iter == t.begin()), kRehashedDeathMessage);
3091
+ EXPECT_DEATH_IF_SUPPORTED(void(iter == t.begin()), InvalidIteratorMatcher());
3092
+ }
3093
+
3094
+ TYPED_TEST(SooTest, IteratorInvalidAssertsEqualityOperatorMovedFrom) {
3095
+ if (!SwisstableGenerationsEnabled())
3096
+ GTEST_SKIP() << "Generations not enabled.";
3097
+
3098
+ TypeParam t;
3099
+ for (int i = 0; i < 10; ++i) t.insert(i);
3100
+ auto iter = t.begin();
3101
+
3102
+ TypeParam t2 = std::move(t);
3103
+
3104
+ EXPECT_DEATH_IF_SUPPORTED(void(iter == t2.begin()), InvalidIteratorMatcher());
2806
3105
  }
2807
3106
 
2808
3107
  #if defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE)
@@ -2812,8 +3111,7 @@ class RawHashSamplerTest : public testing::Test {};
2812
3111
  using RawHashSamplerTestTypes = ::testing::Types<
2813
3112
  // 32 bits to make sure that table is Soo for 32 bits platform as well.
2814
3113
  // 64 bits table is not SOO due to alignment.
2815
- SooInt32Table,
2816
- NonSooIntTable>;
3114
+ SooInt32Table, NonSooIntTable>;
2817
3115
  TYPED_TEST_SUITE(RawHashSamplerTest, RawHashSamplerTestTypes);
2818
3116
 
2819
3117
  TYPED_TEST(RawHashSamplerTest, Sample) {
@@ -2831,7 +3129,6 @@ TYPED_TEST(RawHashSamplerTest, Sample) {
2831
3129
  absl::flat_hash_set<const HashtablezInfo*> preexisting_info(10);
2832
3130
  absl::flat_hash_map<size_t, int> observed_checksums(10);
2833
3131
  absl::flat_hash_map<ssize_t, int> reservations(10);
2834
- absl::flat_hash_map<std::pair<size_t, size_t>, int> hit_misses(10);
2835
3132
 
2836
3133
  start_size += sampler.Iterate([&](const HashtablezInfo& info) {
2837
3134
  preexisting_info.insert(&info);
@@ -2844,8 +3141,6 @@ TYPED_TEST(RawHashSamplerTest, Sample) {
2844
3141
 
2845
3142
  const bool do_reserve = (i % 10 > 5);
2846
3143
  const bool do_rehash = !do_reserve && (i % 10 > 0);
2847
- const bool do_first_insert_hit = i % 2 == 0;
2848
- const bool do_second_insert_hit = i % 4 == 0;
2849
3144
 
2850
3145
  if (do_reserve) {
2851
3146
  // Don't reserve on all tables.
@@ -2853,14 +3148,7 @@ TYPED_TEST(RawHashSamplerTest, Sample) {
2853
3148
  }
2854
3149
 
2855
3150
  tables.back().insert(1);
2856
- if (do_first_insert_hit) {
2857
- tables.back().insert(1);
2858
- tables.back().insert(1);
2859
- }
2860
3151
  tables.back().insert(i % 5);
2861
- if (do_second_insert_hit) {
2862
- tables.back().insert(i % 5);
2863
- }
2864
3152
 
2865
3153
  if (do_rehash) {
2866
3154
  // Rehash some other tables.
@@ -2872,10 +3160,6 @@ TYPED_TEST(RawHashSamplerTest, Sample) {
2872
3160
  ++end_size;
2873
3161
  if (preexisting_info.contains(&info)) return;
2874
3162
  reservations[info.max_reserve.load(std::memory_order_relaxed)]++;
2875
- hit_misses[std::make_pair(
2876
- info.num_insert_hits.load(std::memory_order_relaxed),
2877
- info.size.load(std::memory_order_relaxed))]++;
2878
-
2879
3163
  EXPECT_EQ(info.inline_element_size, sizeof(typename TypeParam::value_type));
2880
3164
  EXPECT_EQ(info.key_size, sizeof(typename TypeParam::key_type));
2881
3165
  EXPECT_EQ(info.value_size, sizeof(typename TypeParam::value_type));
@@ -2899,25 +3183,11 @@ TYPED_TEST(RawHashSamplerTest, Sample) {
2899
3183
  EXPECT_NEAR((100 * count) / static_cast<double>(tables.size()), 0.1, 0.05)
2900
3184
  << reservation;
2901
3185
  }
2902
-
2903
- EXPECT_THAT(hit_misses, testing::SizeIs(6));
2904
- const double sampled_tables = end_size - start_size;
2905
- // i % 20: { 1, 11 }
2906
- EXPECT_NEAR((hit_misses[{1, 1}] / sampled_tables), 0.10, 0.02);
2907
- // i % 20: { 6 }
2908
- EXPECT_NEAR((hit_misses[{3, 1}] / sampled_tables), 0.05, 0.02);
2909
- // i % 20: { 0, 4, 8, 12 }
2910
- EXPECT_NEAR((hit_misses[{3, 2}] / sampled_tables), 0.20, 0.02);
2911
- // i % 20: { 2, 10, 14, 18 }
2912
- EXPECT_NEAR((hit_misses[{2, 2}] / sampled_tables), 0.20, 0.02);
2913
- // i % 20: { 16 }
2914
- EXPECT_NEAR((hit_misses[{4, 1}] / sampled_tables), 0.05, 0.02);
2915
- // i % 20: { 3, 5, 7, 9, 13, 15, 17, 19 }
2916
- EXPECT_NEAR((hit_misses[{0, 2}] / sampled_tables), 0.40, 0.02);
2917
3186
  }
2918
3187
 
2919
- std::vector<const HashtablezInfo*> SampleSooMutation(
2920
- absl::FunctionRef<void(SooInt32Table&)> mutate_table) {
3188
+ template <typename IntTableType>
3189
+ std::vector<const HashtablezInfo*> SampleTableMutation(
3190
+ absl::FunctionRef<void(IntTableType&)> mutate_table) {
2921
3191
  // Enable the feature even if the prod default is off.
2922
3192
  SetSamplingRateTo1Percent();
2923
3193
 
@@ -2930,7 +3200,7 @@ std::vector<const HashtablezInfo*> SampleSooMutation(
2930
3200
  ++start_size;
2931
3201
  });
2932
3202
 
2933
- std::vector<SooInt32Table> tables;
3203
+ std::vector<IntTableType> tables;
2934
3204
  for (int i = 0; i < 1000000; ++i) {
2935
3205
  tables.emplace_back();
2936
3206
  mutate_table(tables.back());
@@ -2949,6 +3219,16 @@ std::vector<const HashtablezInfo*> SampleSooMutation(
2949
3219
  return infos;
2950
3220
  }
2951
3221
 
3222
+ std::vector<const HashtablezInfo*> SampleSooMutation(
3223
+ absl::FunctionRef<void(SooInt32Table&)> mutate_table) {
3224
+ return SampleTableMutation<SooInt32Table>(mutate_table);
3225
+ }
3226
+
3227
+ std::vector<const HashtablezInfo*> SampleNonSooMutation(
3228
+ absl::FunctionRef<void(NonSooIntTable&)> mutate_table) {
3229
+ return SampleTableMutation<NonSooIntTable>(mutate_table);
3230
+ }
3231
+
2952
3232
  TEST(RawHashSamplerTest, SooTableInsertToEmpty) {
2953
3233
  if (SooInt32Table().capacity() != SooCapacity()) {
2954
3234
  CHECK_LT(sizeof(void*), 8) << "missing SOO coverage";
@@ -2970,6 +3250,86 @@ TEST(RawHashSamplerTest, SooTableInsertToEmpty) {
2970
3250
  }
2971
3251
  }
2972
3252
 
3253
+ // Verifies that repeated insertions and erasures on an SOO table do not cause
3254
+ // the sampling decision to be evaluated multiple times, preventing
3255
+ // oversampling.
3256
+ TEST(RawHashSamplerTest, SooTableRepeatedInsertEraseDoesNotOversample) {
3257
+ if (SooInt32Table().capacity() != SooCapacity()) {
3258
+ CHECK_LT(sizeof(void*), 8) << "missing SOO coverage";
3259
+ GTEST_SKIP() << "not SOO on this platform";
3260
+ }
3261
+ std::vector<const HashtablezInfo*> infos =
3262
+ SampleSooMutation([](SooInt32Table& t) {
3263
+ for (int i = 0; i < 10; ++i) {
3264
+ t.insert(1);
3265
+ t.erase(1);
3266
+ }
3267
+ });
3268
+
3269
+ // SampleSooMutation checks EXPECT_NEAR(sampled/total, 1%, 0.5%).
3270
+ // If the sampling logic is incorrectly evaluated on every 0->1 element
3271
+ // transition, the chance of being sampled per table approaches 10% (1 -
3272
+ // 0.99^10), which is enough to cause this test to fail. By passing, this test
3273
+ // verifies that the sampling decision is evaluated exactly once per SOO table
3274
+ // instance.
3275
+ }
3276
+
3277
+ TEST(RawHashSamplerTest, NonSooTableRepeatedInsertEraseCountSizeRight) {
3278
+ ASSERT_EQ(NonSooIntTable().capacity(), 0);
3279
+ std::vector<const HashtablezInfo*> infos =
3280
+ SampleNonSooMutation([](NonSooIntTable& t) {
3281
+ for (int i = 0; i < 10; ++i) {
3282
+ t.insert(1);
3283
+ t.erase(1);
3284
+ }
3285
+ });
3286
+ for (const HashtablezInfo* info : infos) {
3287
+ EXPECT_EQ(info->soo_capacity, 0);
3288
+ ASSERT_EQ(info->capacity, 1);
3289
+ ASSERT_EQ(info->size, 0);
3290
+ }
3291
+ }
3292
+
3293
+ // Verifies that copy-constructing or copy-assigning an SOO table does not
3294
+ // incorrectly trigger new sampling evaluations.
3295
+ TEST(RawHashSamplerTest, SooTableCopyDoesNotOversample) {
3296
+ if (SooInt32Table().capacity() != SooCapacity()) {
3297
+ CHECK_LT(sizeof(void*), 8) << "missing SOO coverage";
3298
+ GTEST_SKIP() << "not SOO on this platform";
3299
+ }
3300
+ std::vector<const HashtablezInfo*> infos =
3301
+ SampleSooMutation([](SooInt32Table& t) {
3302
+ t.insert(1);
3303
+ t.erase(1);
3304
+ SooInt32Table t_copy(t);
3305
+ for (int i = 0; i < 10; ++i) {
3306
+ t_copy.insert(1);
3307
+ t_copy.erase(1);
3308
+ }
3309
+ t = std::move(t_copy);
3310
+ });
3311
+ }
3312
+
3313
+ // Verifies that move-constructing or move-assigning an SOO table correctly
3314
+ // transfers the sampling state and does not trigger oversampling.
3315
+ TEST(RawHashSamplerTest, SooTableMoveDoesNotOversample) {
3316
+ if (SooInt32Table().capacity() != SooCapacity()) {
3317
+ CHECK_LT(sizeof(void*), 8) << "missing SOO coverage";
3318
+ GTEST_SKIP() << "not SOO on this platform";
3319
+ }
3320
+ std::vector<const HashtablezInfo*> infos =
3321
+ SampleSooMutation([](SooInt32Table& t) {
3322
+ t.insert(1);
3323
+ t.erase(1);
3324
+ SooInt32Table t_moved(std::move(t));
3325
+ for (int i = 0; i < 10; ++i) {
3326
+ t_moved.insert(1);
3327
+ t_moved.erase(1);
3328
+ }
3329
+ t = std::move(t_moved);
3330
+ });
3331
+ }
3332
+
2973
3333
  TEST(RawHashSamplerTest, SooTableReserveToEmpty) {
2974
3334
  if (SooInt32Table().capacity() != SooCapacity()) {
2975
3335
  CHECK_LT(sizeof(void*), 8) << "missing SOO coverage";
@@ -3027,9 +3387,7 @@ TEST(RawHashSamplerTest, SooTableSampleOnCopy) {
3027
3387
  t_orig.insert(1);
3028
3388
 
3029
3389
  std::vector<const HashtablezInfo*> infos =
3030
- SampleSooMutation([&t_orig](SooInt32Table& t) {
3031
- t = t_orig;
3032
- });
3390
+ SampleSooMutation([&t_orig](SooInt32Table& t) { t = t_orig; });
3033
3391
 
3034
3392
  for (const HashtablezInfo* info : infos) {
3035
3393
  ASSERT_EQ(info->inline_element_size,
@@ -3067,6 +3425,63 @@ TEST(RawHashSamplerTest, SooTableRehashShrinkWhenSizeFitsInSoo) {
3067
3425
  ASSERT_EQ(info->total_probe_length, 0);
3068
3426
  }
3069
3427
  }
3428
+
3429
+ // Verifies that a moved-from table does not retain the sampled state of the
3430
+ // original table, allowing it to be used without incorrectly updating global
3431
+ // sampling stats.
3432
+ TEST(RawHashSamplerTest, MovedFromTableIsNotSampled) {
3433
+ if (SooInt32Table().capacity() != SooCapacity()) {
3434
+ CHECK_LT(sizeof(void*), 8) << "missing SOO coverage";
3435
+ GTEST_SKIP() << "not SOO on this platform";
3436
+ }
3437
+
3438
+ SetSamplingRateTo1Percent();
3439
+ auto& sampler = GlobalHashtablezSampler();
3440
+ size_t start_size = 0;
3441
+ absl::flat_hash_set<const HashtablezInfo*> preexisting_info;
3442
+ sampler.Iterate([&](const HashtablezInfo& info) {
3443
+ preexisting_info.insert(&info);
3444
+ ++start_size;
3445
+ });
3446
+
3447
+ SooInt32Table t1;
3448
+ // Loop until t1 is sampled
3449
+ while (true) {
3450
+ t1 = SooInt32Table();
3451
+ t1.insert(1);
3452
+ size_t new_size = 0;
3453
+ sampler.Iterate([&](const HashtablezInfo&) { ++new_size; });
3454
+ if (new_size > start_size) break;
3455
+ }
3456
+
3457
+ // Move the table
3458
+ SooInt32Table t2 = std::move(t1);
3459
+
3460
+ // Disable sampling to ensure any new sampling is a bug.
3461
+ SetHashtablezEnabled(false);
3462
+
3463
+ // t2 is now the sampled table. t1 is moved-from.
3464
+ // We want to verify that t2 is still sampled, and that t1 isn't sampled
3465
+ // anymore, even if we insert a new entry into it.
3466
+ t1.clear(); // Must clear before using a moved-from table.
3467
+ t1.insert(2);
3468
+ t2.insert(2);
3469
+
3470
+ // Verify no new sample was generated, and t2's sample size is now 2.
3471
+ size_t final_size = 0;
3472
+ const HashtablezInfo* latest_info = nullptr;
3473
+ size_t dropped = sampler.Iterate([&](const HashtablezInfo& info) {
3474
+ ++final_size;
3475
+ if (!preexisting_info.contains(&info)) {
3476
+ latest_info = &info;
3477
+ }
3478
+ });
3479
+ EXPECT_EQ(0, dropped);
3480
+ EXPECT_EQ(final_size, start_size + 1);
3481
+ ASSERT_NE(latest_info, nullptr);
3482
+ EXPECT_EQ(latest_info->size.load(std::memory_order_relaxed), 2);
3483
+ }
3484
+
3070
3485
  #endif // ABSL_INTERNAL_HASHTABLEZ_SAMPLE
3071
3486
 
3072
3487
  TEST(RawHashSamplerTest, DoNotSampleCustomAllocators) {
@@ -3177,7 +3592,6 @@ TYPED_TEST(AlignOneTest, AlignOne) {
3177
3592
 
3178
3593
  TEST(Iterator, InvalidUseCrashesWithSanitizers) {
3179
3594
  if (!SwisstableGenerationsEnabled()) GTEST_SKIP() << "Generations disabled.";
3180
- if (kMsvc) GTEST_SKIP() << "MSVC doesn't support | in regexp.";
3181
3595
 
3182
3596
  NonSooIntTable t;
3183
3597
  // Start with 1 element so that `it` is never an end iterator.
@@ -3185,15 +3599,13 @@ TEST(Iterator, InvalidUseCrashesWithSanitizers) {
3185
3599
  for (int i = 0; i < 10; ++i) {
3186
3600
  auto it = t.begin();
3187
3601
  t.insert(i);
3188
- EXPECT_DEATH_IF_SUPPORTED(*it, kInvalidIteratorDeathMessage);
3189
- EXPECT_DEATH_IF_SUPPORTED(void(it == t.begin()),
3190
- kInvalidIteratorDeathMessage);
3602
+ EXPECT_DEATH_IF_SUPPORTED(*it, InvalidIteratorMatcher());
3603
+ EXPECT_DEATH_IF_SUPPORTED(void(it == t.begin()), InvalidIteratorMatcher());
3191
3604
  }
3192
3605
  }
3193
3606
 
3194
3607
  TEST(Iterator, InvalidUseWithReserveCrashesWithSanitizers) {
3195
3608
  if (!SwisstableGenerationsEnabled()) GTEST_SKIP() << "Generations disabled.";
3196
- if (kMsvc) GTEST_SKIP() << "MSVC doesn't support | in regexp.";
3197
3609
 
3198
3610
  IntTable t;
3199
3611
  t.reserve(10);
@@ -3214,9 +3626,8 @@ TEST(Iterator, InvalidUseWithReserveCrashesWithSanitizers) {
3214
3626
  // The first insert after reserved growth is 0 is guaranteed to rehash when
3215
3627
  // generations are enabled.
3216
3628
  t.insert(10);
3217
- EXPECT_DEATH_IF_SUPPORTED(*it, kInvalidIteratorDeathMessage);
3218
- EXPECT_DEATH_IF_SUPPORTED(void(it == t.begin()),
3219
- kInvalidIteratorDeathMessage);
3629
+ EXPECT_DEATH_IF_SUPPORTED(*it, InvalidIteratorMatcher());
3630
+ EXPECT_DEATH_IF_SUPPORTED(void(it == t.begin()), InvalidIteratorMatcher());
3220
3631
  #ifdef ABSL_HAVE_ADDRESS_SANITIZER
3221
3632
  EXPECT_DEATH_IF_SUPPORTED(std::cout << *ptr, "heap-use-after-free");
3222
3633
  #endif
@@ -3224,7 +3635,6 @@ TEST(Iterator, InvalidUseWithReserveCrashesWithSanitizers) {
3224
3635
 
3225
3636
  TEST(Iterator, InvalidUseWithMoveCrashesWithSanitizers) {
3226
3637
  if (!SwisstableGenerationsEnabled()) GTEST_SKIP() << "Generations disabled.";
3227
- if (kMsvc) GTEST_SKIP() << "MSVC doesn't support | in regexp.";
3228
3638
 
3229
3639
  NonSooIntTable t1, t2;
3230
3640
  t1.insert(1);
@@ -3234,9 +3644,8 @@ TEST(Iterator, InvalidUseWithMoveCrashesWithSanitizers) {
3234
3644
  (void)ptr;
3235
3645
 
3236
3646
  t2 = std::move(t1);
3237
- EXPECT_DEATH_IF_SUPPORTED(*it, kInvalidIteratorDeathMessage);
3238
- EXPECT_DEATH_IF_SUPPORTED(void(it == t2.begin()),
3239
- kInvalidIteratorDeathMessage);
3647
+ EXPECT_DEATH_IF_SUPPORTED(*it, InvalidIteratorMatcher());
3648
+ EXPECT_DEATH_IF_SUPPORTED(void(it == t2.begin()), InvalidIteratorMatcher());
3240
3649
  #ifdef ABSL_HAVE_ADDRESS_SANITIZER
3241
3650
  EXPECT_DEATH_IF_SUPPORTED(std::cout << **ptr, "heap-use-after-free");
3242
3651
  #endif
@@ -3491,7 +3900,6 @@ TEST(Table, EraseBeginEndResetsReservedGrowth) {
3491
3900
 
3492
3901
  TEST(Table, GenerationInfoResetsOnClear) {
3493
3902
  if (!SwisstableGenerationsEnabled()) GTEST_SKIP() << "Generations disabled.";
3494
- if (kMsvc) GTEST_SKIP() << "MSVC doesn't support | in regexp.";
3495
3903
 
3496
3904
  NonSooIntTable t;
3497
3905
  for (int i = 0; i < 1000; ++i) t.insert(i);
@@ -3502,7 +3910,7 @@ TEST(Table, GenerationInfoResetsOnClear) {
3502
3910
  t.insert(0);
3503
3911
  auto it = t.begin();
3504
3912
  t.insert(1);
3505
- EXPECT_DEATH_IF_SUPPORTED(*it, kInvalidIteratorDeathMessage);
3913
+ EXPECT_DEATH_IF_SUPPORTED(*it, InvalidIteratorMatcher());
3506
3914
  }
3507
3915
 
3508
3916
  TEST(Table, InvalidReferenceUseCrashesWithSanitizers) {
@@ -3869,7 +4277,7 @@ struct DestroyCaller {
3869
4277
  ~DestroyCaller() {
3870
4278
  if (destroy_func) (*destroy_func)();
3871
4279
  }
3872
- void Deactivate() { destroy_func = absl::nullopt; }
4280
+ void Deactivate() { destroy_func = std::nullopt; }
3873
4281
 
3874
4282
  template <typename H>
3875
4283
  friend H AbslHashValue(H h, const DestroyCaller& d) {
@@ -3878,7 +4286,7 @@ struct DestroyCaller {
3878
4286
  bool operator==(const DestroyCaller& d) const { return val == d.val; }
3879
4287
 
3880
4288
  int val;
3881
- absl::optional<absl::FunctionRef<void()>> destroy_func;
4289
+ std::optional<absl::FunctionRef<void()>> destroy_func;
3882
4290
  };
3883
4291
 
3884
4292
  TEST(Table, ReentrantCallsFail) {
@@ -3912,7 +4320,6 @@ TEST(Table, ReentrantCallsFail) {
3912
4320
  #endif
3913
4321
  }
3914
4322
 
3915
- // TODO(b/328794765): this check is very useful to run with ASAN in opt mode.
3916
4323
  TEST(Table, DestroyedCallsFail) {
3917
4324
  #ifdef NDEBUG
3918
4325
  ASSERT_EQ(SwisstableAssertAccessToDestroyedTable(),
@@ -3925,19 +4332,21 @@ TEST(Table, DestroyedCallsFail) {
3925
4332
  }
3926
4333
  #if !defined(__clang__) && defined(__GNUC__)
3927
4334
  GTEST_SKIP() << "Flaky on GCC.";
3928
- #endif
3929
- absl::optional<IntTable> t;
4335
+ #elif defined(ABSL_HAVE_THREAD_SANITIZER)
4336
+ GTEST_SKIP() << "Fails on TSan.";
4337
+ // Note: we use else rather than endif here to avoid unreachable code errors.
4338
+ #else
4339
+ std::optional<IntTable> t;
3930
4340
  t.emplace({1});
3931
4341
  IntTable* t_ptr = &*t;
3932
4342
  EXPECT_TRUE(t_ptr->contains(1));
3933
4343
  t.reset();
3934
- std::string expected_death_message =
3935
- #if defined(ABSL_HAVE_MEMORY_SANITIZER)
3936
- "use-of-uninitialized-value";
3937
- #else
3938
- "destroyed hash table";
3939
- #endif
3940
- EXPECT_DEATH_IF_SUPPORTED(t_ptr->contains(1), expected_death_message);
4344
+ EXPECT_DEATH_IF_SUPPORTED(
4345
+ t_ptr->contains(1),
4346
+ AnyOf(HasSubstr("destroyed hash table"), HasSubstr("use-after-free"),
4347
+ HasSubstr("use-of-uninitialized-value")));
4348
+
4349
+ #endif // ABSL_HAVE_THREAD_SANITIZER
3941
4350
  }
3942
4351
 
3943
4352
  TEST(Table, DestroyedCallsFailDuringDestruction) {
@@ -3946,6 +4355,10 @@ TEST(Table, DestroyedCallsFailDuringDestruction) {
3946
4355
  }
3947
4356
  #if !defined(__clang__) && defined(__GNUC__)
3948
4357
  GTEST_SKIP() << "Flaky on GCC.";
4358
+ #endif
4359
+ #if defined(ABSL_HAVE_ADDRESS_SANITIZER) && defined(NDEBUG)
4360
+ // TODO(b/487002780): see if we can re-enable this test in opt-ASan mode.
4361
+ GTEST_SKIP() << "Fails to die in opt ASAN.";
3949
4362
  #endif
3950
4363
  // When EXPECT_DEATH_IF_SUPPORTED is not executed, the code after it is not
3951
4364
  // executed as well.
@@ -3954,7 +4367,7 @@ TEST(Table, DestroyedCallsFailDuringDestruction) {
3954
4367
  bool do_lookup = false;
3955
4368
 
3956
4369
  using Table = absl::flat_hash_map<int, std::shared_ptr<int>>;
3957
- absl::optional<Table> t = Table();
4370
+ std::optional<Table> t = Table();
3958
4371
  Table* t_ptr = &*t;
3959
4372
  auto destroy = [&](int* ptr) {
3960
4373
  if (do_lookup) {
@@ -3967,13 +4380,9 @@ TEST(Table, DestroyedCallsFailDuringDestruction) {
3967
4380
  do_lookup = true;
3968
4381
  t.reset();
3969
4382
  };
3970
- std::string expected_death_message =
3971
- #ifdef NDEBUG
3972
- "destroyed hash table";
3973
- #else
3974
- "Reentrant container access";
3975
- #endif
3976
- EXPECT_DEATH_IF_SUPPORTED(destroy_with_lookup(), expected_death_message);
4383
+ EXPECT_DEATH_IF_SUPPORTED(destroy_with_lookup(),
4384
+ AnyOf(HasSubstr("destroyed hash table"),
4385
+ HasSubstr("Reentrant container access")));
3977
4386
  }
3978
4387
 
3979
4388
  TEST(Table, MovedFromCallsFail) {
@@ -4021,73 +4430,87 @@ TEST(Table, MovedFromCallsFail) {
4021
4430
  }
4022
4431
  }
4023
4432
 
4024
- TEST(HashtableSize, GenerateNewSeedDoesntChangeSize) {
4025
- size_t size = 1;
4026
- do {
4027
- HashtableSize hs(no_seed_empty_tag_t{});
4028
- hs.increment_size(size);
4029
- EXPECT_EQ(hs.size(), size);
4030
- hs.generate_new_seed();
4031
- EXPECT_EQ(hs.size(), size);
4032
- size = size * 2 + 1;
4033
- } while (size < MaxValidSizeFor1ByteSlot());
4034
- }
4035
-
4036
4433
  TEST(Table, MaxValidSize) {
4037
4434
  IntTable t;
4038
- EXPECT_EQ(MaxValidSize(sizeof(IntTable::value_type)), t.max_size());
4435
+ EXPECT_EQ(
4436
+ MaxValidSize(sizeof(IntTable::key_type), sizeof(IntTable::value_type)),
4437
+ t.max_size());
4039
4438
  if constexpr (sizeof(size_t) == 8) {
4040
4439
  for (size_t i = 0; i < 35; ++i) {
4041
4440
  SCOPED_TRACE(i);
4042
4441
  size_t slot_size = size_t{1} << i;
4043
- size_t max_size = MaxValidSize(slot_size);
4044
- ASSERT_FALSE(IsAboveValidSize(max_size, slot_size));
4045
- ASSERT_TRUE(IsAboveValidSize(max_size + 1, slot_size));
4442
+ size_t key_size = slot_size;
4443
+ size_t max_size = MaxValidSize(key_size, slot_size);
4046
4444
  ASSERT_LT(max_size, uint64_t{1} << 60);
4047
- // For non gigantic slot sizes we expect max size to be at least 2^40.
4048
- if (i <= 22) {
4049
- ASSERT_FALSE(IsAboveValidSize(size_t{1} << 40, slot_size));
4445
+ if (key_size <= 4) {
4446
+ ASSERT_EQ(max_size, uint64_t{1} << 8 * key_size);
4447
+ } else if (i <= 21) {
4050
4448
  ASSERT_GE(max_size, uint64_t{1} << 40);
4051
4449
  }
4052
- ASSERT_LT(SizeToCapacity(max_size),
4053
- uint64_t{1} << HashtableSize::kSizeBitCount);
4450
+ ASSERT_LE(max_size, uint64_t{1} << HashtableInlineData::kSizeBitCount);
4054
4451
  ASSERT_LT(absl::uint128(max_size) * slot_size, uint64_t{1} << 63);
4055
4452
  }
4056
4453
  }
4057
- EXPECT_LT(MaxValidSize</*kSizeOfSizeT=*/4>(1), 1 << 30);
4058
- EXPECT_LT(MaxValidSize</*kSizeOfSizeT=*/4>(2), 1 << 29);
4454
+ EXPECT_LT(MaxValidSize</*kSizeOfSizeT=*/4>(1, 1), 1 << 30);
4455
+ EXPECT_LT(MaxValidSize</*kSizeOfSizeT=*/4>(2, 2), 1 << 29);
4059
4456
  for (size_t i = 0; i < 29; ++i) {
4457
+ SCOPED_TRACE(i);
4060
4458
  size_t slot_size = size_t{1} << i;
4061
- size_t max_size = MaxValidSize</*kSizeOfSizeT=*/4>(slot_size);
4062
- ASSERT_FALSE(IsAboveValidSize</*kSizeOfSizeT=*/4>(max_size, slot_size));
4063
- ASSERT_TRUE(IsAboveValidSize</*kSizeOfSizeT=*/4>(max_size + 1, slot_size));
4459
+ size_t key_size = slot_size;
4460
+ size_t max_size = MaxValidSize</*kSizeOfSizeT=*/4>(key_size, slot_size);
4064
4461
  ASSERT_LT(max_size, 1 << 30);
4065
4462
  size_t max_capacity = SizeToCapacity(max_size);
4066
- ASSERT_LT(max_capacity, (size_t{1} << 31) / slot_size);
4067
- ASSERT_GT(max_capacity, (1 << 29) / slot_size);
4463
+ ASSERT_LT(uint64_t{max_capacity} * slot_size, size_t{1} << 31);
4464
+ if (key_size < 4) {
4465
+ ASSERT_EQ(max_size, uint64_t{1} << 8 * key_size);
4466
+ } else {
4467
+ ASSERT_GT(max_capacity, (1 << 29) / slot_size);
4468
+ }
4068
4469
  ASSERT_LT(max_capacity * slot_size, size_t{1} << 31);
4069
4470
  }
4070
4471
  }
4071
4472
 
4072
4473
  TEST(Table, MaxSizeOverflow) {
4474
+ #ifdef ABSL_HAVE_EXCEPTIONS
4475
+ GTEST_SKIP() << "Skipping test because exceptions are enabled. EXPECT_DEATH "
4476
+ "doesn't work with exceptions.";
4477
+ #elif defined(ABSL_HAVE_THREAD_SANITIZER)
4478
+ GTEST_SKIP() << "ThreadSanitizer test runs fail on OOM even in EXPECT_DEATH.";
4479
+ #else
4480
+ const std::string expected_death_message =
4481
+ "new failed|failed to allocate|bad_alloc|exceeds maximum supported size";
4073
4482
  size_t overflow = (std::numeric_limits<size_t>::max)();
4074
- EXPECT_DEATH_IF_SUPPORTED(IntTable t(overflow), "Hash table size overflow");
4483
+ EXPECT_DEATH_IF_SUPPORTED(IntTable t(overflow), expected_death_message);
4075
4484
  IntTable t;
4076
- EXPECT_DEATH_IF_SUPPORTED(t.reserve(overflow), "Hash table size overflow");
4077
- EXPECT_DEATH_IF_SUPPORTED(t.rehash(overflow), "Hash table size overflow");
4078
- size_t slightly_overflow = MaxValidSize(sizeof(IntTable::value_type)) + 1;
4485
+ EXPECT_DEATH_IF_SUPPORTED(t.reserve(overflow), expected_death_message);
4486
+ EXPECT_DEATH_IF_SUPPORTED(t.rehash(overflow), expected_death_message);
4487
+ size_t slightly_overflow =
4488
+ MaxValidSize(sizeof(IntTable::key_type), sizeof(IntTable::value_type)) +
4489
+ 1;
4079
4490
  size_t slightly_overflow_capacity =
4080
4491
  NextCapacity(NormalizeCapacity(slightly_overflow));
4081
4492
  EXPECT_DEATH_IF_SUPPORTED(IntTable t2(slightly_overflow_capacity - 10),
4082
- "Hash table size overflow");
4493
+ expected_death_message);
4083
4494
  EXPECT_DEATH_IF_SUPPORTED(t.reserve(slightly_overflow),
4084
- "Hash table size overflow");
4495
+ expected_death_message);
4085
4496
  EXPECT_DEATH_IF_SUPPORTED(t.rehash(slightly_overflow),
4086
- "Hash table size overflow");
4497
+ expected_death_message);
4087
4498
  IntTable non_empty_table;
4088
4499
  non_empty_table.insert(0);
4089
4500
  EXPECT_DEATH_IF_SUPPORTED(non_empty_table.reserve(slightly_overflow),
4090
- "Hash table size overflow");
4501
+ expected_death_message);
4502
+ #endif // defined(ABSL_HAVE_THREAD_SANITIZER)
4503
+ }
4504
+
4505
+ // Tests that reserving enough space for more than the max number of unique keys
4506
+ // doesn't crash and we end up with kMaxValidCapacity.
4507
+ TEST(Table, MaxSizeOverflowUniqueKeys) {
4508
+ absl::flat_hash_set<uint8_t> t8;
4509
+ t8.reserve(1 << 9);
4510
+ EXPECT_EQ(t8.capacity(), SizeToCapacity(t8.max_size()));
4511
+ absl::flat_hash_set<uint16_t> t16;
4512
+ t16.reserve(1 << 17);
4513
+ EXPECT_EQ(t16.capacity(), SizeToCapacity(t16.max_size()));
4091
4514
  }
4092
4515
 
4093
4516
  // TODO(b/397453582): Remove support for const hasher and remove this test.
@@ -4111,9 +4534,11 @@ TEST(Table, ConstLambdaHash) {
4111
4534
  EXPECT_EQ(t.find(3), t.end());
4112
4535
  }
4113
4536
 
4114
- struct ConstUint8Hash {
4115
- size_t operator()(uint8_t) const { return *value; }
4116
- size_t* value;
4537
+ struct ZeroHash {
4538
+ template <typename T>
4539
+ size_t operator()(T) const {
4540
+ return 0;
4541
+ }
4117
4542
  };
4118
4543
 
4119
4544
  // This test is imitating growth of a very big table and triggers all buffer
@@ -4129,18 +4554,18 @@ struct ConstUint8Hash {
4129
4554
  // 4. Then a few times we will extend control buffer end.
4130
4555
  // 5. Finally we will catch up and go to overflow codepath.
4131
4556
  TEST(Table, GrowExtremelyLargeTable) {
4557
+ // ProbedItem8Bytes causes OOMs on some platforms so we use ProbedItem4Bytes.
4132
4558
  constexpr size_t kTargetCapacity =
4133
- #if defined(__wasm__) || defined(__asmjs__) || defined(__i386__)
4134
- NextCapacity(ProbedItem4Bytes::kMaxNewCapacity); // OOMs on WASM, 32-bit.
4559
+ #if defined(__wasm__) || defined(__asmjs__) || defined(__i386__) || \
4560
+ defined(_MSC_VER) || defined(ABSL_HAVE_THREAD_SANITIZER) || \
4561
+ defined(ABSL_HAVE_MEMORY_SANITIZER) || \
4562
+ (!defined(__clang__) && defined(__GNUC__))
4563
+ NextCapacity(ProbedItem4Bytes::kMaxNewCapacity);
4135
4564
  #else
4136
4565
  NextCapacity(ProbedItem8Bytes::kMaxNewCapacity);
4137
4566
  #endif
4138
4567
 
4139
- size_t hash = 0;
4140
- // In order to save memory we use 1 byte slot.
4141
- // There are not enough different values to achieve big capacity, so we
4142
- // artificially update growth info to force resize.
4143
- absl::flat_hash_set<uint8_t, ConstUint8Hash> t(63, ConstUint8Hash{&hash});
4568
+ absl::flat_hash_set<uint32_t, ZeroHash> t(63);
4144
4569
  CommonFields& common = RawHashSetTestOnlyAccess::GetCommon(t);
4145
4570
  // Set 0 seed so that H1 is always 0.
4146
4571
  common.set_no_seed_for_testing();
@@ -4156,7 +4581,8 @@ TEST(Table, GrowExtremelyLargeTable) {
4156
4581
  for (size_t cap = t.capacity(); cap < kTargetCapacity;
4157
4582
  cap = NextCapacity(cap)) {
4158
4583
  ASSERT_EQ(t.capacity(), cap);
4159
- // Update growth info to force resize on the next insert.
4584
+ // Update growth info to force resize on the next insert. This way we avoid
4585
+ // having to insert many elements.
4160
4586
  common.growth_info().OverwriteManyEmptyAsFull(CapacityToGrowth(cap) -
4161
4587
  t.size());
4162
4588
  t.insert(inserted_till++);
@@ -4168,16 +4594,6 @@ TEST(Table, GrowExtremelyLargeTable) {
4168
4594
  EXPECT_EQ(t.capacity(), kTargetCapacity);
4169
4595
  }
4170
4596
 
4171
- // Test that after calling generate_new_seed(), the high bits of the returned
4172
- // seed are non-zero.
4173
- TEST(PerTableSeed, HighBitsAreNonZero) {
4174
- HashtableSize hs(no_seed_empty_tag_t{});
4175
- for (int i = 0; i < 100; ++i) {
4176
- hs.generate_new_seed();
4177
- ASSERT_GT(hs.seed().seed() >> 16, 0);
4178
- }
4179
- }
4180
-
4181
4597
  } // namespace
4182
4598
  } // namespace container_internal
4183
4599
  ABSL_NAMESPACE_END