grpc 1.84.0 → 1.85.0.pre1

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 (1004) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +40 -27
  3. data/include/grpc/event_engine/memory_allocator.h +1 -0
  4. data/include/grpc/grpc.h +3 -0
  5. data/include/grpc/grpc_security_constants.h +2 -0
  6. data/include/grpc/impl/channel_arg_names.h +4 -0
  7. data/src/core/call/call_filters.h +10 -10
  8. data/src/core/{lib/security/authorization → call}/evaluate_args.cc +22 -1
  9. data/src/core/{lib/security/authorization → call}/evaluate_args.h +19 -5
  10. data/src/core/call/filter_fusion.h +15 -15
  11. data/src/core/call/interception_chain.h +3 -3
  12. data/src/core/call/metadata_batch.cc +1 -0
  13. data/src/core/call/metadata_batch.h +45 -33
  14. data/src/core/call/parsed_metadata.h +3 -3
  15. data/src/core/call/request_buffer.cc +6 -6
  16. data/src/core/call/request_buffer.h +1 -1
  17. data/src/core/channelz/channel_trace.cc +5 -5
  18. data/src/core/channelz/channel_trace.h +1 -1
  19. data/src/core/channelz/channelz.cc +9 -9
  20. data/src/core/channelz/channelz.h +12 -12
  21. data/src/core/channelz/channelz_registry.cc +10 -10
  22. data/src/core/channelz/ztrace_collector.h +5 -5
  23. data/src/core/client_channel/client_channel.cc +4 -4
  24. data/src/core/client_channel/client_channel_filter.cc +14 -14
  25. data/src/core/client_channel/global_subchannel_pool.cc +4 -4
  26. data/src/core/client_channel/subchannel.cc +24 -23
  27. data/src/core/client_channel/subchannel_stream_client.cc +5 -5
  28. data/src/core/credentials/call/external/aws_external_account_credentials.cc +7 -7
  29. data/src/core/credentials/call/external/aws_request_signer.cc +16 -0
  30. data/src/core/credentials/call/external/external_account_credentials.cc +4 -4
  31. data/src/core/credentials/call/regional_access_boundary_fetcher.cc +9 -9
  32. data/src/core/credentials/call/token_fetcher/token_fetcher_credentials.cc +4 -4
  33. data/src/core/credentials/transport/google_default/google_default_credentials.cc +3 -3
  34. data/src/core/credentials/transport/ssl/ssl_security_connector.cc +1 -1
  35. data/src/core/credentials/transport/tls/grpc_tls_certificate_distributor.cc +9 -9
  36. data/src/core/credentials/transport/tls/grpc_tls_certificate_distributor.h +1 -1
  37. data/src/core/credentials/transport/tls/grpc_tls_certificate_provider.cc +6 -6
  38. data/src/core/credentials/transport/tls/grpc_tls_certificate_verifier.cc +3 -3
  39. data/src/core/credentials/transport/tls/grpc_tls_crl_provider.cc +4 -4
  40. data/src/core/credentials/transport/tls/ssl_utils.cc +10 -0
  41. data/src/core/credentials/transport/tls/tls_security_connector.cc +10 -10
  42. data/src/core/credentials/transport/tls/tls_security_connector.h +6 -6
  43. data/src/core/credentials/transport/tls/tls_utils.h +9 -0
  44. data/src/core/ext/filters/channel_idle/legacy_channel_idle_filter.cc +1 -1
  45. data/src/core/ext/filters/fault_injection/fault_injection_filter.cc +1 -1
  46. data/src/core/ext/filters/gcp_authentication/gcp_authentication_filter.cc +2 -2
  47. data/src/core/ext/filters/gcp_authentication/gcp_authentication_filter.h +1 -1
  48. data/src/core/ext/filters/http/message_compress/compression_filter.cc +15 -0
  49. data/src/core/ext/filters/rbac/rbac_filter.h +1 -1
  50. data/src/core/ext/transport/chttp2/client/chttp2_connector.cc +5 -5
  51. data/src/core/ext/transport/chttp2/server/chttp2_server.cc +30 -21
  52. data/src/core/ext/transport/chttp2/server/chttp2_server.h +5 -11
  53. data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +14 -11
  54. data/src/core/ext/transport/chttp2/transport/flow_control.cc +1 -0
  55. data/src/core/ext/transport/chttp2/transport/flow_control.h +0 -4
  56. data/src/core/ext/transport/chttp2/transport/frame.h +9 -0
  57. data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +12 -9
  58. data/src/core/ext/transport/chttp2/transport/hpack_parser.h +4 -2
  59. data/src/core/ext/transport/chttp2/transport/http2_client_transport.cc +16 -18
  60. data/src/core/ext/transport/chttp2/transport/http2_client_transport.h +2 -1
  61. data/src/core/ext/transport/chttp2/transport/http2_server_transport.cc +277 -189
  62. data/src/core/ext/transport/chttp2/transport/http2_server_transport.h +40 -17
  63. data/src/core/ext/transport/chttp2/transport/http2_transport.cc +12 -24
  64. data/src/core/ext/transport/chttp2/transport/http2_transport.h +3 -29
  65. data/src/core/ext/transport/chttp2/transport/internal.h +2 -2
  66. data/src/core/ext/transport/chttp2/transport/parsing.cc +3 -2
  67. data/src/core/ext/transport/chttp2/transport/read_context.h +96 -3
  68. data/src/core/ext/transport/chttp2/transport/reclaimer.cc +32 -0
  69. data/src/core/ext/transport/chttp2/transport/reclaimer.h +64 -0
  70. data/src/core/ext/transport/chttp2/transport/security_frame.h +8 -8
  71. data/src/core/ext/transport/chttp2/transport/stream_data_queue.h +17 -9
  72. data/src/core/ext/transport/chttp2/transport/write_cycle.h +23 -3
  73. data/src/core/ext/transport/inproc/inproc_transport.cc +5 -5
  74. data/src/core/ext/upb-gen/grpc/channelz/v1/channelz.upb.h +137 -73
  75. data/src/core/ext/upb-gen/grpc/channelz/v1/channelz.upb_minitable.c +45 -25
  76. data/src/core/ext/upb-gen/{src/proto/grpc → grpc}/gcp/altscontext.upb.h +6 -6
  77. data/src/core/ext/upb-gen/{src/proto/grpc → grpc}/gcp/altscontext.upb_minitable.c +4 -4
  78. data/src/core/ext/upb-gen/{src/proto/grpc → grpc}/gcp/altscontext.upb_minitable.h +5 -5
  79. data/src/core/ext/upb-gen/{src/proto/grpc → grpc}/gcp/handshaker.upb.h +46 -26
  80. data/src/core/ext/upb-gen/{src/proto/grpc → grpc}/gcp/handshaker.upb_minitable.c +17 -14
  81. data/src/core/ext/upb-gen/{src/proto/grpc → grpc}/gcp/handshaker.upb_minitable.h +5 -5
  82. data/src/core/ext/upb-gen/{src/proto/grpc → grpc}/gcp/transport_security_common.upb.h +5 -5
  83. data/src/core/ext/upb-gen/{src/proto/grpc → grpc}/gcp/transport_security_common.upb_minitable.c +3 -3
  84. data/src/core/ext/upb-gen/{src/proto/grpc → grpc}/gcp/transport_security_common.upb_minitable.h +5 -5
  85. data/src/core/ext/upb-gen/grpc/health/v1/health.upb.h +329 -0
  86. data/src/core/ext/upb-gen/grpc/health/v1/health.upb_minitable.c +128 -0
  87. data/src/core/ext/upb-gen/{src/proto/grpc → grpc}/health/v1/health.upb_minitable.h +8 -5
  88. data/src/core/ext/upb-gen/{src/proto/grpc → grpc}/lb/v1/load_balancer.upb.h +5 -5
  89. data/src/core/ext/upb-gen/{src/proto/grpc → grpc}/lb/v1/load_balancer.upb_minitable.c +3 -3
  90. data/src/core/ext/upb-gen/{src/proto/grpc → grpc}/lb/v1/load_balancer.upb_minitable.h +5 -5
  91. data/src/core/ext/upb-gen/{src/proto/grpc → grpc}/lookup/v1/rls.upb.h +185 -23
  92. data/src/core/ext/upb-gen/{src/proto/grpc → grpc}/lookup/v1/rls.upb_minitable.c +20 -12
  93. data/src/core/ext/upb-gen/{src/proto/grpc → grpc}/lookup/v1/rls.upb_minitable.h +5 -5
  94. data/src/core/ext/upb-gen/{src/proto/grpc → grpc}/lookup/v1/rls_config.upb.h +58 -42
  95. data/src/core/ext/upb-gen/{src/proto/grpc → grpc}/lookup/v1/rls_config.upb_minitable.c +17 -12
  96. data/src/core/ext/upb-gen/{src/proto/grpc → grpc}/lookup/v1/rls_config.upb_minitable.h +5 -5
  97. data/src/core/ext/upbdefs-gen/grpc/channelz/v1/channelz.upbdefs.c +567 -549
  98. data/src/core/ext/upbdefs-gen/grpc/lookup/v1/rls_config.upbdefs.c +182 -0
  99. data/src/core/ext/upbdefs-gen/{src/proto/grpc → grpc}/lookup/v1/rls_config.upbdefs.h +14 -14
  100. data/src/core/filter/ext_proc/ext_proc_filter.cc +1603 -46
  101. data/src/core/filter/ext_proc/ext_proc_filter.h +55 -22
  102. data/src/core/filter/ext_proc/ext_proc_messages.cc +106 -51
  103. data/src/core/filter/ext_proc/ext_proc_messages.h +36 -9
  104. data/src/core/handshaker/handshaker.cc +4 -4
  105. data/src/core/handshaker/http_connect/http_connect_client_handshaker.cc +3 -3
  106. data/src/core/handshaker/security/pipelined_secure_endpoint.cc +10 -10
  107. data/src/core/handshaker/security/secure_endpoint.cc +13 -13
  108. data/src/core/handshaker/security/security_handshaker.cc +6 -6
  109. data/src/core/handshaker/tcp_connect/tcp_connect_handshaker.cc +4 -4
  110. data/src/core/lib/channel/channel_args.cc +20 -0
  111. data/src/core/lib/channel/channel_args.h +17 -17
  112. data/src/core/lib/channel/promise_based_filter.cc +2 -2
  113. data/src/core/lib/channel/promise_based_filter.h +66 -27
  114. data/src/core/lib/debug/trace_flags.cc +2 -0
  115. data/src/core/lib/debug/trace_flags.h +1 -0
  116. data/src/core/lib/event_engine/ares_resolver.cc +14 -14
  117. data/src/core/lib/event_engine/cf_engine/cf_engine.cc +7 -7
  118. data/src/core/lib/event_engine/cf_engine/cfsocket_listener.cc +4 -4
  119. data/src/core/lib/event_engine/default_event_engine.cc +5 -5
  120. data/src/core/lib/event_engine/posix_engine/ev_epoll1_linux.cc +9 -9
  121. data/src/core/lib/event_engine/posix_engine/ev_poll_posix.cc +16 -14
  122. data/src/core/lib/event_engine/posix_engine/file_descriptor_collection.cc +6 -6
  123. data/src/core/lib/event_engine/posix_engine/grpc_polled_fd_posix.h +3 -3
  124. data/src/core/lib/event_engine/posix_engine/posix_endpoint.cc +1 -1
  125. data/src/core/lib/event_engine/posix_engine/posix_endpoint.h +7 -7
  126. data/src/core/lib/event_engine/posix_engine/posix_engine.cc +17 -17
  127. data/src/core/lib/event_engine/posix_engine/posix_engine_listener.cc +3 -3
  128. data/src/core/lib/event_engine/posix_engine/timer.cc +5 -5
  129. data/src/core/lib/event_engine/posix_engine/timer_manager.cc +5 -5
  130. data/src/core/lib/event_engine/posix_engine/traced_buffer_list.cc +3 -3
  131. data/src/core/lib/event_engine/posix_engine/traced_buffer_list.h +1 -1
  132. data/src/core/lib/event_engine/thread_pool/thread_count.cc +1 -1
  133. data/src/core/lib/event_engine/thread_pool/thread_count.h +3 -3
  134. data/src/core/lib/event_engine/thread_pool/work_stealing_thread_pool.cc +50 -21
  135. data/src/core/lib/event_engine/thready_event_engine/thready_event_engine.cc +3 -3
  136. data/src/core/lib/event_engine/windows/grpc_polled_fd_windows.cc +3 -3
  137. data/src/core/lib/event_engine/windows/windows_engine.cc +15 -15
  138. data/src/core/lib/event_engine/windows/windows_listener.cc +6 -6
  139. data/src/core/lib/event_engine/work_queue/basic_work_queue.cc +6 -6
  140. data/src/core/lib/experiments/experiments.cc +48 -0
  141. data/src/core/lib/experiments/experiments.h +24 -0
  142. data/src/core/lib/iomgr/buffer_list.cc +3 -3
  143. data/src/core/lib/iomgr/buffer_list.h +1 -1
  144. data/src/core/lib/iomgr/combiner.cc +0 -1
  145. data/src/core/lib/iomgr/ev_apple.cc +4 -4
  146. data/src/core/lib/iomgr/event_engine_shims/endpoint.cc +2 -2
  147. data/src/core/lib/iomgr/tcp_client_posix.cc +3 -3
  148. data/src/core/lib/iomgr/tcp_posix.cc +7 -7
  149. data/src/core/lib/promise/activity.cc +1 -1
  150. data/src/core/lib/promise/activity.h +1 -1
  151. data/src/core/lib/promise/arena_promise.h +7 -7
  152. data/src/core/lib/promise/detail/promise_factory.h +8 -8
  153. data/src/core/lib/promise/detail/promise_like.h +4 -4
  154. data/src/core/lib/promise/inter_activity_latch.h +6 -6
  155. data/src/core/lib/promise/inter_activity_pipe.h +1 -1
  156. data/src/core/lib/promise/observable.h +3 -3
  157. data/src/core/lib/promise/party.cc +1 -1
  158. data/src/core/lib/promise/try_seq.h +2 -2
  159. data/src/core/lib/resource_quota/arena.h +3 -3
  160. data/src/core/lib/resource_quota/memory_quota.cc +16 -16
  161. data/src/core/lib/resource_quota/memory_quota.h +1 -1
  162. data/src/core/lib/resource_quota/thread_quota.cc +3 -3
  163. data/src/core/lib/security/authorization/audit_logging.cc +5 -5
  164. data/src/core/lib/security/authorization/authorization_engine.h +1 -1
  165. data/src/core/lib/security/authorization/grpc_authorization_engine.h +1 -1
  166. data/src/core/lib/security/authorization/grpc_server_authz_filter.cc +1 -1
  167. data/src/core/lib/security/authorization/grpc_server_authz_filter.h +1 -1
  168. data/src/core/lib/security/authorization/matchers.h +1 -1
  169. data/src/core/lib/surface/call.cc +8 -7
  170. data/src/core/lib/surface/call.h +3 -3
  171. data/src/core/lib/surface/call_utils.h +4 -0
  172. data/src/core/lib/surface/channel.cc +1 -1
  173. data/src/core/lib/surface/channel.h +1 -1
  174. data/src/core/lib/surface/channel_init.cc +1 -1
  175. data/src/core/lib/surface/init.cc +7 -7
  176. data/src/core/lib/surface/lame_client.cc +1 -1
  177. data/src/core/lib/surface/legacy_channel.cc +2 -2
  178. data/src/core/lib/surface/version.cc +1 -1
  179. data/src/core/lib/transport/transport_framing_endpoint_extension.h +3 -3
  180. data/src/core/load_balancing/autosharding/autosharding.cc +931 -0
  181. data/src/core/load_balancing/autosharding/autosharding.h +78 -0
  182. data/src/core/load_balancing/grpclb/grpclb_client_stats.cc +2 -2
  183. data/src/core/load_balancing/grpclb/load_balancer_api.cc +1 -1
  184. data/src/core/load_balancing/grpclb/load_balancer_api.h +3 -1
  185. data/src/core/load_balancing/health_check_client.cc +7 -7
  186. data/src/core/load_balancing/lb_policy.cc +1 -1
  187. data/src/core/load_balancing/oob_backend_metric.cc +5 -5
  188. data/src/core/load_balancing/outlier_detection/outlier_detection.cc +2 -2
  189. data/src/core/load_balancing/ring_hash/ring_hash.cc +109 -37
  190. data/src/core/load_balancing/rls/rls.cc +23 -17
  191. data/src/core/load_balancing/weighted_round_robin/weighted_round_robin.cc +10 -10
  192. data/src/core/load_balancing/xds/cds.cc +6 -5
  193. data/src/core/load_balancing/xds/xds_cluster_impl.cc +2 -2
  194. data/src/core/load_balancing/xds/xds_override_host.cc +10 -10
  195. data/src/core/mitigation_engine/mitigation_engine.h +28 -4
  196. data/src/core/plugin_registry/grpc_plugin_registry.cc +2 -0
  197. data/src/core/resolver/dns/dns_resolver.cc +7 -7
  198. data/src/core/resolver/fake/fake_resolver.cc +5 -5
  199. data/src/core/resolver/google_c2p/google_c2p_resolver.cc +38 -30
  200. data/src/core/server/server.cc +30 -30
  201. data/src/core/server/server.h +4 -3
  202. data/src/core/server/server_config_selector_filter.cc +3 -3
  203. data/src/core/server/xds_server_config_fetcher_legacy.cc +15 -15
  204. data/src/core/telemetry/default_tcp_tracer.cc +1 -1
  205. data/src/core/telemetry/instrument.cc +30 -16
  206. data/src/core/telemetry/instrument.h +3 -3
  207. data/src/core/tsi/alts/handshaker/alts_handshaker_client.cc +3 -3
  208. data/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc +4 -4
  209. data/src/core/tsi/alts/handshaker/alts_tsi_handshaker.h +2 -2
  210. data/src/core/tsi/alts/handshaker/alts_tsi_utils.h +1 -1
  211. data/src/core/tsi/alts/handshaker/transport_security_common_api.h +1 -1
  212. data/src/core/tsi/ssl/key_logging/ssl_key_logging.cc +5 -5
  213. data/src/core/tsi/ssl/session_cache/ssl_session_cache.cc +3 -3
  214. data/src/core/tsi/ssl_transport_security.cc +46 -13
  215. data/src/core/tsi/ssl_transport_security.h +7 -0
  216. data/src/core/tsi/ssl_transport_security_utils.cc +16 -6
  217. data/src/core/util/event_log.cc +3 -3
  218. data/src/core/util/http_client/httpcli.cc +5 -5
  219. data/src/core/util/http_client/httpcli.h +1 -1
  220. data/src/core/util/json/json_object_loader.cc +7 -0
  221. data/src/core/util/json/json_object_loader.h +17 -2
  222. data/src/core/util/latent_see.cc +123 -36
  223. data/src/core/util/latent_see.h +14 -1
  224. data/src/core/util/mpscq.cc +1 -1
  225. data/src/core/util/notification.h +4 -4
  226. data/src/core/util/sync.h +20 -6
  227. data/src/core/util/table.h +20 -22
  228. data/src/core/util/work_serializer.cc +2 -2
  229. data/src/core/xds/grpc/blackboard.cc +4 -3
  230. data/src/core/xds/grpc/certificate_provider_store.cc +2 -2
  231. data/src/core/xds/grpc/streaming_call_promise_wrapper.cc +181 -0
  232. data/src/core/xds/grpc/streaming_call_promise_wrapper.h +213 -0
  233. data/src/core/xds/grpc/xds_bootstrap_grpc_builder.cc +2 -2
  234. data/src/core/xds/grpc/xds_client_grpc.cc +8 -8
  235. data/src/core/xds/grpc/xds_cluster_specifier_plugin.cc +2 -2
  236. data/src/core/xds/grpc/xds_endpoint.cc +1 -1
  237. data/src/core/xds/grpc/xds_endpoint_parser.cc +11 -0
  238. data/src/core/xds/grpc/xds_grpc_service_parser.cc +12 -10
  239. data/src/core/xds/grpc/xds_http_ext_proc_filter.cc +17 -14
  240. data/src/core/xds/grpc/xds_matcher.h +2 -2
  241. data/src/core/xds/grpc/xds_transport_grpc.cc +125 -85
  242. data/src/core/xds/grpc/xds_transport_grpc.h +19 -4
  243. data/src/core/xds/xds_client/lrs_client.cc +22 -19
  244. data/src/core/xds/xds_client/xds_client.cc +19 -16
  245. data/src/core/xds/xds_client/xds_transport.h +49 -3
  246. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +2 -0
  247. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +3 -0
  248. data/src/ruby/lib/grpc/version.rb +1 -1
  249. data/src/ruby/pb/README.md +1 -1
  250. data/src/ruby/pb/generate_proto_ruby.sh +1 -1
  251. data/third_party/abseil-cpp/absl/algorithm/algorithm.h +34 -2
  252. data/third_party/abseil-cpp/absl/algorithm/container.h +345 -147
  253. data/third_party/abseil-cpp/absl/base/attributes.h +67 -44
  254. data/third_party/abseil-cpp/absl/base/call_once.h +1 -0
  255. data/third_party/abseil-cpp/absl/base/casts.cc +61 -0
  256. data/third_party/abseil-cpp/absl/base/casts.h +135 -2
  257. data/third_party/abseil-cpp/absl/base/config.h +63 -41
  258. data/third_party/abseil-cpp/absl/base/fast_type_id.h +30 -2
  259. data/third_party/abseil-cpp/absl/base/internal/dynamic_annotations.h +1 -1
  260. data/third_party/abseil-cpp/absl/base/internal/hardening.h +136 -0
  261. data/third_party/abseil-cpp/absl/base/internal/iterator_traits.h +6 -2
  262. data/third_party/abseil-cpp/absl/base/internal/low_level_alloc.cc +39 -4
  263. data/third_party/abseil-cpp/absl/base/internal/low_level_alloc.h +6 -0
  264. data/third_party/abseil-cpp/absl/base/internal/low_level_scheduling.h +77 -15
  265. data/third_party/abseil-cpp/absl/base/internal/raw_logging.cc +3 -4
  266. data/third_party/abseil-cpp/absl/base/internal/spinlock.cc +26 -24
  267. data/third_party/abseil-cpp/absl/base/internal/spinlock.h +74 -29
  268. data/third_party/abseil-cpp/absl/base/internal/sysinfo.cc +1 -11
  269. data/third_party/abseil-cpp/absl/base/internal/thread_identity.h +52 -0
  270. data/third_party/abseil-cpp/absl/base/internal/unscaledcycleclock.cc +5 -1
  271. data/third_party/abseil-cpp/absl/base/internal/unscaledcycleclock.h +5 -0
  272. data/third_party/abseil-cpp/absl/base/internal/unscaledcycleclock_config.h +1 -1
  273. data/third_party/abseil-cpp/absl/base/macros.h +76 -37
  274. data/third_party/abseil-cpp/absl/base/nullability.h +5 -5
  275. data/third_party/abseil-cpp/absl/base/optimization.h +4 -5
  276. data/third_party/abseil-cpp/absl/base/options.h +46 -18
  277. data/third_party/abseil-cpp/absl/base/policy_checks.h +5 -5
  278. data/third_party/abseil-cpp/absl/base/{internal/throw_delegate.cc → throw_delegate.cc} +9 -7
  279. data/third_party/abseil-cpp/absl/base/{internal/throw_delegate.h → throw_delegate.h} +4 -14
  280. data/third_party/abseil-cpp/absl/cleanup/cleanup.h +7 -2
  281. data/third_party/abseil-cpp/absl/cleanup/internal/cleanup.h +3 -2
  282. data/third_party/abseil-cpp/absl/container/btree_map.h +60 -10
  283. data/third_party/abseil-cpp/absl/container/btree_set.h +61 -15
  284. data/third_party/abseil-cpp/absl/container/fixed_array.h +19 -21
  285. data/third_party/abseil-cpp/absl/container/flat_hash_map.h +49 -27
  286. data/third_party/abseil-cpp/absl/container/flat_hash_set.h +50 -26
  287. data/third_party/abseil-cpp/absl/container/inlined_vector.h +42 -36
  288. data/third_party/abseil-cpp/absl/container/internal/btree.h +32 -24
  289. data/third_party/abseil-cpp/absl/container/internal/btree_container.h +30 -22
  290. data/third_party/abseil-cpp/absl/container/internal/common.h +57 -5
  291. data/third_party/abseil-cpp/absl/container/internal/common_policy_traits.h +1 -1
  292. data/third_party/abseil-cpp/absl/container/internal/compressed_tuple.h +40 -36
  293. data/third_party/abseil-cpp/absl/container/internal/container_memory.h +119 -39
  294. data/third_party/abseil-cpp/absl/container/internal/hash_function_defaults.h +14 -2
  295. data/third_party/abseil-cpp/absl/container/internal/hash_policy_traits.h +14 -22
  296. data/third_party/abseil-cpp/absl/container/internal/hashtable_control_bytes.h +52 -52
  297. data/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler.cc +7 -7
  298. data/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler.h +7 -7
  299. data/third_party/abseil-cpp/absl/container/internal/inlined_vector.h +32 -40
  300. data/third_party/abseil-cpp/absl/container/internal/layout.h +13 -13
  301. data/third_party/abseil-cpp/absl/container/internal/raw_hash_map.h +95 -72
  302. data/third_party/abseil-cpp/absl/container/internal/raw_hash_set.cc +633 -365
  303. data/third_party/abseil-cpp/absl/container/internal/raw_hash_set.h +1016 -749
  304. data/third_party/abseil-cpp/absl/container/internal/raw_hash_set_resize_impl.h +0 -1
  305. data/third_party/abseil-cpp/absl/container/node_hash_map.h +58 -35
  306. data/third_party/abseil-cpp/absl/crc/internal/cpu_detect.cc +23 -6
  307. data/third_party/abseil-cpp/absl/crc/internal/cpu_detect.h +7 -1
  308. data/third_party/abseil-cpp/absl/crc/internal/crc.cc +4 -6
  309. data/third_party/abseil-cpp/absl/crc/internal/crc32_x86_arm_combined_simd.h +41 -0
  310. data/third_party/abseil-cpp/absl/crc/internal/crc_internal.h +0 -16
  311. data/third_party/abseil-cpp/absl/crc/internal/crc_memcpy_x86_arm_combined.cc +5 -0
  312. data/third_party/abseil-cpp/absl/crc/internal/crc_x86_arm_combined.cc +304 -188
  313. data/third_party/abseil-cpp/absl/crc/internal/non_temporal_arm_intrinsics.h +4 -2
  314. data/third_party/abseil-cpp/absl/debugging/internal/demangle.cc +2 -2
  315. data/third_party/abseil-cpp/absl/debugging/internal/demangle_rust.h +8 -0
  316. data/third_party/abseil-cpp/absl/debugging/internal/elf_mem_image.h +4 -4
  317. data/third_party/abseil-cpp/absl/debugging/internal/examine_stack.cc +15 -1
  318. data/third_party/abseil-cpp/absl/debugging/internal/examine_stack.h +7 -1
  319. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_aarch64-inl.inc +12 -1
  320. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_config.h +6 -5
  321. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_emscripten-inl.inc +13 -11
  322. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_generic-inl.inc +14 -7
  323. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_powerpc-inl.inc +3 -2
  324. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_riscv-inl.inc +6 -1
  325. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_x86-inl.inc +14 -8
  326. data/third_party/abseil-cpp/absl/debugging/internal/symbolize.h +48 -38
  327. data/third_party/abseil-cpp/absl/debugging/internal/vdso_support.cc +4 -0
  328. data/third_party/abseil-cpp/absl/debugging/stacktrace.cc +63 -118
  329. data/third_party/abseil-cpp/absl/debugging/stacktrace.h +7 -47
  330. data/third_party/abseil-cpp/absl/debugging/symbolize.cc +20 -2
  331. data/third_party/abseil-cpp/absl/debugging/symbolize_elf.inc +83 -149
  332. data/third_party/abseil-cpp/absl/debugging/symbolize_emscripten.inc +4 -17
  333. data/third_party/abseil-cpp/absl/debugging/symbolize_unimplemented.inc +4 -4
  334. data/third_party/abseil-cpp/absl/debugging/symbolize_win32.inc +2 -4
  335. data/third_party/abseil-cpp/absl/flags/commandlineflag.h +8 -6
  336. data/third_party/abseil-cpp/absl/flags/declare.h +9 -0
  337. data/third_party/abseil-cpp/absl/flags/flag.h +2 -1
  338. data/third_party/abseil-cpp/absl/flags/internal/commandlineflag.h +1 -1
  339. data/third_party/abseil-cpp/absl/flags/internal/flag.cc +19 -18
  340. data/third_party/abseil-cpp/absl/flags/internal/flag.h +33 -34
  341. data/third_party/abseil-cpp/absl/flags/internal/program_name.cc +2 -2
  342. data/third_party/abseil-cpp/absl/flags/marshalling.cc +1 -16
  343. data/third_party/abseil-cpp/absl/flags/marshalling.h +2 -28
  344. data/third_party/abseil-cpp/absl/flags/reflection.cc +11 -7
  345. data/third_party/abseil-cpp/absl/flags/usage_config.cc +2 -2
  346. data/third_party/abseil-cpp/absl/functional/any_invocable.h +22 -19
  347. data/third_party/abseil-cpp/absl/functional/bind_front.h +7 -1
  348. data/third_party/abseil-cpp/absl/functional/function_ref.h +125 -20
  349. data/third_party/abseil-cpp/absl/functional/internal/any_invocable.h +43 -31
  350. data/third_party/abseil-cpp/absl/functional/internal/front_binder.h +4 -4
  351. data/third_party/abseil-cpp/absl/functional/internal/function_ref.h +44 -6
  352. data/third_party/abseil-cpp/absl/hash/hash.h +1 -1
  353. data/third_party/abseil-cpp/absl/hash/internal/city.cc +39 -51
  354. data/third_party/abseil-cpp/absl/hash/internal/hash.cc +379 -14
  355. data/third_party/abseil-cpp/absl/hash/internal/hash.h +457 -353
  356. data/third_party/abseil-cpp/absl/log/absl_vlog_is_on.h +0 -2
  357. data/third_party/abseil-cpp/absl/log/internal/check_impl.h +2 -1
  358. data/third_party/abseil-cpp/absl/log/internal/check_op.cc +4 -0
  359. data/third_party/abseil-cpp/absl/log/internal/check_op.h +128 -50
  360. data/third_party/abseil-cpp/absl/log/internal/conditions.h +38 -35
  361. data/third_party/abseil-cpp/absl/log/internal/log_impl.h +108 -110
  362. data/third_party/abseil-cpp/absl/log/internal/log_message.cc +10 -6
  363. data/third_party/abseil-cpp/absl/log/internal/log_message.h +19 -1
  364. data/third_party/abseil-cpp/absl/log/internal/log_sink_set.cc +4 -4
  365. data/third_party/abseil-cpp/absl/log/internal/nullstream.h +1 -1
  366. data/third_party/abseil-cpp/absl/log/internal/proto.cc +13 -0
  367. data/third_party/abseil-cpp/absl/log/internal/strip.h +30 -31
  368. data/third_party/abseil-cpp/absl/log/internal/structured_proto.cc +5 -5
  369. data/third_party/abseil-cpp/absl/log/internal/structured_proto.h +6 -5
  370. data/third_party/abseil-cpp/absl/log/internal/vlog_config.cc +30 -30
  371. data/third_party/abseil-cpp/absl/log/internal/vlog_config.h +0 -1
  372. data/third_party/abseil-cpp/absl/log/log.h +2 -2
  373. data/third_party/abseil-cpp/absl/log/log_entry.cc +263 -0
  374. data/third_party/abseil-cpp/absl/log/log_entry.h +2 -0
  375. data/third_party/abseil-cpp/absl/log/vlog_is_on.h +0 -2
  376. data/third_party/abseil-cpp/absl/memory/memory.h +55 -5
  377. data/third_party/abseil-cpp/absl/meta/type_traits.h +161 -56
  378. data/third_party/abseil-cpp/absl/numeric/int128.h +41 -21
  379. data/third_party/abseil-cpp/absl/numeric/int128_have_intrinsic.inc +16 -22
  380. data/third_party/abseil-cpp/absl/numeric/int128_no_intrinsic.inc +5 -7
  381. data/third_party/abseil-cpp/absl/numeric/internal/bits.h +32 -4
  382. data/third_party/abseil-cpp/absl/profiling/internal/sample_recorder.h +9 -9
  383. data/third_party/abseil-cpp/absl/random/beta_distribution.h +2 -2
  384. data/third_party/abseil-cpp/absl/random/bit_gen_ref.h +26 -53
  385. data/third_party/abseil-cpp/absl/random/discrete_distribution.h +1 -1
  386. data/third_party/abseil-cpp/absl/random/distributions.h +17 -17
  387. data/third_party/abseil-cpp/absl/random/exponential_distribution.h +1 -1
  388. data/third_party/abseil-cpp/absl/random/internal/distribution_caller.h +8 -21
  389. data/third_party/abseil-cpp/absl/random/internal/entropy_pool.cc +2 -2
  390. data/third_party/abseil-cpp/absl/random/internal/fast_uniform_bits.h +1 -1
  391. data/third_party/abseil-cpp/absl/random/internal/generate_real.h +1 -1
  392. data/third_party/abseil-cpp/absl/random/internal/iostream_state_saver.h +2 -2
  393. data/third_party/abseil-cpp/absl/random/internal/nonsecure_base.h +2 -2
  394. data/third_party/abseil-cpp/absl/random/internal/pcg_engine.h +6 -6
  395. data/third_party/abseil-cpp/absl/random/internal/platform.h +0 -13
  396. data/third_party/abseil-cpp/absl/random/internal/randen_detect.cc +6 -6
  397. data/third_party/abseil-cpp/absl/random/internal/randen_engine.h +2 -2
  398. data/third_party/abseil-cpp/absl/random/internal/salted_seed_seq.h +6 -5
  399. data/third_party/abseil-cpp/absl/random/internal/seed_material.cc +5 -31
  400. data/third_party/abseil-cpp/absl/random/internal/seed_material.h +2 -1
  401. data/third_party/abseil-cpp/absl/random/internal/traits.h +21 -0
  402. data/third_party/abseil-cpp/absl/random/internal/uniform_helper.h +23 -23
  403. data/third_party/abseil-cpp/absl/random/mocking_access.h +74 -0
  404. data/third_party/abseil-cpp/absl/random/uniform_real_distribution.h +1 -1
  405. data/third_party/abseil-cpp/absl/status/internal/status_internal.cc +63 -18
  406. data/third_party/abseil-cpp/absl/status/internal/status_internal.h +30 -4
  407. data/third_party/abseil-cpp/absl/status/internal/statusor_internal.h +225 -63
  408. data/third_party/abseil-cpp/absl/status/status.cc +66 -70
  409. data/third_party/abseil-cpp/absl/status/status.h +254 -23
  410. data/third_party/abseil-cpp/absl/status/status_payload_printer.h +3 -2
  411. data/third_party/abseil-cpp/absl/status/statusor.h +117 -137
  412. data/third_party/abseil-cpp/absl/strings/ascii.h +10 -6
  413. data/third_party/abseil-cpp/absl/strings/cord.cc +41 -17
  414. data/third_party/abseil-cpp/absl/strings/cord.h +26 -17
  415. data/third_party/abseil-cpp/absl/strings/cord_buffer.h +4 -2
  416. data/third_party/abseil-cpp/absl/strings/escaping.cc +305 -125
  417. data/third_party/abseil-cpp/absl/strings/escaping.h +12 -2
  418. data/third_party/abseil-cpp/absl/strings/internal/append_and_overwrite.h +93 -0
  419. data/third_party/abseil-cpp/absl/strings/internal/cord_internal.h +2 -2
  420. data/third_party/abseil-cpp/absl/strings/internal/cordz_handle.cc +6 -6
  421. data/third_party/abseil-cpp/absl/strings/internal/cordz_info.cc +27 -21
  422. data/third_party/abseil-cpp/absl/strings/internal/cordz_info.h +11 -19
  423. data/third_party/abseil-cpp/absl/strings/internal/damerau_levenshtein_distance.cc +6 -0
  424. data/third_party/abseil-cpp/absl/strings/internal/damerau_levenshtein_distance.h +1 -0
  425. data/third_party/abseil-cpp/absl/strings/internal/escaping.cc +0 -141
  426. data/third_party/abseil-cpp/absl/strings/internal/escaping.h +2 -24
  427. data/third_party/abseil-cpp/absl/strings/internal/resize_uninitialized.h +31 -36
  428. data/third_party/abseil-cpp/absl/strings/internal/stl_type_traits.h +39 -39
  429. data/third_party/abseil-cpp/absl/strings/internal/str_format/arg.h +14 -22
  430. data/third_party/abseil-cpp/absl/strings/internal/str_format/bind.h +2 -2
  431. data/third_party/abseil-cpp/absl/strings/internal/str_format/checker.h +2 -4
  432. data/third_party/abseil-cpp/absl/strings/internal/str_format/float_conversion.cc +921 -231
  433. data/third_party/abseil-cpp/absl/strings/internal/str_join_internal.h +18 -16
  434. data/third_party/abseil-cpp/absl/strings/internal/str_split_internal.h +16 -12
  435. data/third_party/abseil-cpp/absl/strings/internal/stringify_sink.h +12 -0
  436. data/third_party/abseil-cpp/absl/strings/numbers.cc +477 -8
  437. data/third_party/abseil-cpp/absl/strings/numbers.h +29 -12
  438. data/third_party/abseil-cpp/absl/strings/resize_and_overwrite.h +198 -0
  439. data/third_party/abseil-cpp/absl/strings/str_cat.cc +96 -91
  440. data/third_party/abseil-cpp/absl/strings/str_cat.h +53 -13
  441. data/third_party/abseil-cpp/absl/strings/str_split.h +14 -9
  442. data/third_party/abseil-cpp/absl/strings/string_view.h +10 -716
  443. data/third_party/abseil-cpp/absl/strings/substitute.cc +24 -24
  444. data/third_party/abseil-cpp/absl/strings/substitute.h +2 -2
  445. data/third_party/abseil-cpp/absl/synchronization/barrier.cc +1 -1
  446. data/third_party/abseil-cpp/absl/synchronization/blocking_counter.cc +2 -2
  447. data/third_party/abseil-cpp/absl/synchronization/internal/create_thread_identity.cc +24 -3
  448. data/third_party/abseil-cpp/absl/synchronization/internal/graphcycles.cc +30 -33
  449. data/third_party/abseil-cpp/absl/synchronization/internal/kernel_timeout.h +2 -2
  450. data/third_party/abseil-cpp/absl/synchronization/internal/per_thread_sem.h +5 -0
  451. data/third_party/abseil-cpp/absl/synchronization/mutex.cc +41 -29
  452. data/third_party/abseil-cpp/absl/synchronization/mutex.h +199 -94
  453. data/third_party/abseil-cpp/absl/synchronization/notification.cc +5 -5
  454. data/third_party/abseil-cpp/absl/synchronization/notification.h +1 -1
  455. data/third_party/abseil-cpp/absl/time/clock.cc +29 -30
  456. data/third_party/abseil-cpp/absl/time/clock.h +3 -0
  457. data/third_party/abseil-cpp/absl/time/duration.cc +2 -2
  458. data/third_party/abseil-cpp/absl/time/format.cc +3 -10
  459. data/third_party/abseil-cpp/absl/time/internal/cctz/include/cctz/civil_time_detail.h +12 -0
  460. data/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_format.cc +131 -91
  461. data/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_lookup.cc +6 -103
  462. data/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_name_win.cc +185 -0
  463. data/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_name_win.h +37 -0
  464. data/third_party/abseil-cpp/absl/time/internal/cctz/src/tzfile.h +10 -15
  465. data/third_party/abseil-cpp/absl/time/time.cc +4 -4
  466. data/third_party/abseil-cpp/absl/time/time.h +14 -13
  467. data/third_party/abseil-cpp/absl/types/compare.h +64 -63
  468. data/third_party/abseil-cpp/absl/types/internal/span.h +6 -6
  469. data/third_party/abseil-cpp/absl/types/optional.h +31 -4
  470. data/third_party/abseil-cpp/absl/types/optional_ref.h +295 -0
  471. data/third_party/{boringssl-with-bazel/crypto/x509/x_val.cc → abseil-cpp/absl/types/source_location.cc} +4 -14
  472. data/third_party/abseil-cpp/absl/types/source_location.h +172 -0
  473. data/third_party/abseil-cpp/absl/types/span.h +67 -38
  474. data/third_party/abseil-cpp/absl/types/variant.h +75 -18
  475. data/third_party/abseil-cpp/absl/utility/utility.h +112 -16
  476. data/third_party/boringssl-with-bazel/crypto/aes/aes.cc +3 -0
  477. data/third_party/boringssl-with-bazel/crypto/armv8_feature_parsing.h +67 -0
  478. data/third_party/boringssl-with-bazel/crypto/asn1/a_bitstr.cc +143 -105
  479. data/third_party/boringssl-with-bazel/crypto/asn1/a_bool.cc +5 -8
  480. data/third_party/boringssl-with-bazel/crypto/asn1/a_d2i_fp.cc +3 -3
  481. data/third_party/boringssl-with-bazel/crypto/asn1/a_dup.cc +6 -6
  482. data/third_party/boringssl-with-bazel/crypto/asn1/a_gentm.cc +33 -12
  483. data/third_party/boringssl-with-bazel/crypto/asn1/a_i2d_fp.cc +7 -6
  484. data/third_party/boringssl-with-bazel/crypto/asn1/a_int.cc +80 -52
  485. data/third_party/boringssl-with-bazel/crypto/asn1/a_mbstr.cc +7 -4
  486. data/third_party/boringssl-with-bazel/crypto/asn1/a_object.cc +70 -72
  487. data/third_party/boringssl-with-bazel/crypto/asn1/a_strex.cc +38 -42
  488. data/third_party/boringssl-with-bazel/crypto/asn1/a_strnid.cc +41 -39
  489. data/third_party/boringssl-with-bazel/crypto/asn1/a_time.cc +59 -35
  490. data/third_party/boringssl-with-bazel/crypto/asn1/a_type.cc +275 -15
  491. data/third_party/boringssl-with-bazel/crypto/asn1/a_utctm.cc +32 -13
  492. data/third_party/boringssl-with-bazel/crypto/asn1/asn1_lib.cc +128 -30
  493. data/third_party/boringssl-with-bazel/crypto/asn1/asn_pack.cc +10 -10
  494. data/third_party/boringssl-with-bazel/crypto/asn1/f_int.cc +1 -1
  495. data/third_party/boringssl-with-bazel/crypto/asn1/f_string.cc +1 -1
  496. data/third_party/boringssl-with-bazel/crypto/asn1/internal.h +261 -115
  497. data/third_party/boringssl-with-bazel/crypto/asn1/posix_time.cc +8 -5
  498. data/third_party/boringssl-with-bazel/crypto/asn1/tasn_dec.cc +373 -725
  499. data/third_party/boringssl-with-bazel/crypto/asn1/tasn_enc.cc +211 -526
  500. data/third_party/boringssl-with-bazel/crypto/asn1/tasn_fre.cc +22 -19
  501. data/third_party/boringssl-with-bazel/crypto/asn1/tasn_new.cc +26 -24
  502. data/third_party/boringssl-with-bazel/crypto/asn1/tasn_typ.cc +19 -5
  503. data/third_party/boringssl-with-bazel/crypto/asn1/tasn_utl.cc +47 -51
  504. data/third_party/boringssl-with-bazel/crypto/base64/base64.cc +14 -15
  505. data/third_party/boringssl-with-bazel/crypto/bcm_support.h +7 -29
  506. data/third_party/boringssl-with-bazel/crypto/bio/bio.cc +234 -176
  507. data/third_party/boringssl-with-bazel/crypto/bio/bio_mem.cc +72 -86
  508. data/third_party/boringssl-with-bazel/crypto/bio/connect.cc +153 -199
  509. data/third_party/boringssl-with-bazel/crypto/bio/errno.cc +3 -1
  510. data/third_party/boringssl-with-bazel/crypto/bio/fd.cc +56 -55
  511. data/third_party/boringssl-with-bazel/crypto/bio/file.cc +70 -78
  512. data/third_party/boringssl-with-bazel/crypto/bio/hexdump.cc +6 -4
  513. data/third_party/boringssl-with-bazel/crypto/bio/internal.h +69 -17
  514. data/third_party/boringssl-with-bazel/crypto/bio/pair.cc +117 -136
  515. data/third_party/boringssl-with-bazel/crypto/bio/printf.cc +1 -1
  516. data/third_party/boringssl-with-bazel/crypto/bio/socket.cc +116 -50
  517. data/third_party/boringssl-with-bazel/crypto/bio/socket_helper.cc +53 -5
  518. data/third_party/boringssl-with-bazel/crypto/blake2/blake2.cc +9 -5
  519. data/third_party/boringssl-with-bazel/crypto/bn/bn_asn1.cc +2 -2
  520. data/third_party/boringssl-with-bazel/crypto/bn/convert.cc +56 -70
  521. data/third_party/boringssl-with-bazel/crypto/bn/div.cc +102 -0
  522. data/third_party/boringssl-with-bazel/crypto/bn/exponentiation.cc +26 -42
  523. data/third_party/boringssl-with-bazel/crypto/bn/sqrt.cc +93 -0
  524. data/third_party/boringssl-with-bazel/crypto/buf/buf.cc +6 -5
  525. data/third_party/boringssl-with-bazel/crypto/bytestring/asn1_compat.cc +6 -5
  526. data/third_party/boringssl-with-bazel/crypto/bytestring/ber.cc +22 -20
  527. data/third_party/boringssl-with-bazel/crypto/bytestring/cbb.cc +119 -59
  528. data/third_party/boringssl-with-bazel/crypto/bytestring/cbs.cc +115 -31
  529. data/third_party/boringssl-with-bazel/crypto/bytestring/internal.h +79 -24
  530. data/third_party/boringssl-with-bazel/crypto/bytestring/unicode.cc +2 -2
  531. data/third_party/boringssl-with-bazel/crypto/chacha/chacha.cc +5 -3
  532. data/third_party/boringssl-with-bazel/crypto/chacha/internal.h +23 -22
  533. data/third_party/boringssl-with-bazel/crypto/cipher/derive_key.cc +14 -18
  534. data/third_party/boringssl-with-bazel/crypto/cipher/e_aesctrhmac.cc +73 -58
  535. data/third_party/boringssl-with-bazel/crypto/cipher/e_aeseax.cc +132 -70
  536. data/third_party/boringssl-with-bazel/crypto/cipher/e_aesgcmsiv.cc +390 -249
  537. data/third_party/boringssl-with-bazel/crypto/cipher/e_chacha20poly1305.cc +200 -137
  538. data/third_party/boringssl-with-bazel/crypto/cipher/e_des.cc +45 -29
  539. data/third_party/boringssl-with-bazel/crypto/cipher/e_null.cc +9 -5
  540. data/third_party/boringssl-with-bazel/crypto/cipher/e_rc2.cc +43 -28
  541. data/third_party/boringssl-with-bazel/crypto/cipher/e_rc4.cc +7 -5
  542. data/third_party/boringssl-with-bazel/crypto/cipher/e_tls.cc +250 -237
  543. data/third_party/boringssl-with-bazel/crypto/cipher/get_cipher.cc +12 -12
  544. data/third_party/boringssl-with-bazel/crypto/cipher/internal.h +59 -59
  545. data/third_party/boringssl-with-bazel/crypto/cipher/tls_cbc.cc +111 -111
  546. data/third_party/boringssl-with-bazel/crypto/cms/cms.cc +48 -42
  547. data/third_party/boringssl-with-bazel/crypto/conf/conf.cc +69 -63
  548. data/third_party/boringssl-with-bazel/crypto/conf/internal.h +11 -12
  549. data/third_party/boringssl-with-bazel/crypto/cpu_aarch64_apple.cc +8 -5
  550. data/third_party/boringssl-with-bazel/crypto/cpu_aarch64_fuchsia.cc +6 -1
  551. data/third_party/boringssl-with-bazel/crypto/cpu_aarch64_linux.cc +7 -1
  552. data/third_party/boringssl-with-bazel/crypto/cpu_aarch64_openbsd.cc +7 -21
  553. data/third_party/boringssl-with-bazel/crypto/cpu_aarch64_sysreg.cc +15 -41
  554. data/third_party/boringssl-with-bazel/crypto/cpu_aarch64_win.cc +16 -3
  555. data/third_party/boringssl-with-bazel/crypto/cpu_arm_freebsd.cc +4 -2
  556. data/third_party/boringssl-with-bazel/crypto/cpu_arm_linux.cc +54 -31
  557. data/third_party/boringssl-with-bazel/crypto/cpu_arm_linux.h +79 -101
  558. data/third_party/boringssl-with-bazel/crypto/cpu_intel.cc +51 -45
  559. data/third_party/boringssl-with-bazel/crypto/crypto.cc +26 -55
  560. data/third_party/boringssl-with-bazel/crypto/curve25519/curve25519.cc +28 -25
  561. data/third_party/boringssl-with-bazel/crypto/curve25519/curve25519_tables.h +6 -6
  562. data/third_party/boringssl-with-bazel/crypto/curve25519/internal.h +14 -15
  563. data/third_party/boringssl-with-bazel/crypto/curve25519/spake25519.cc +23 -20
  564. data/third_party/boringssl-with-bazel/crypto/des/des.cc +27 -19
  565. data/third_party/boringssl-with-bazel/crypto/des/internal.h +4 -9
  566. data/third_party/boringssl-with-bazel/crypto/dh/dh_asn1.cc +34 -49
  567. data/third_party/boringssl-with-bazel/crypto/dh/params.cc +44 -41
  568. data/third_party/boringssl-with-bazel/crypto/digest/digest_extra.cc +87 -40
  569. data/third_party/boringssl-with-bazel/crypto/dsa/dsa.cc +237 -260
  570. data/third_party/boringssl-with-bazel/crypto/dsa/dsa_asn1.cc +100 -173
  571. data/third_party/boringssl-with-bazel/crypto/dsa/internal.h +23 -21
  572. data/third_party/boringssl-with-bazel/crypto/ec/ec_asn1.cc +181 -209
  573. data/third_party/boringssl-with-bazel/crypto/ec/ec_derive.cc +26 -28
  574. data/third_party/boringssl-with-bazel/crypto/ec/hash_to_curve.cc +265 -174
  575. data/third_party/boringssl-with-bazel/crypto/ec/internal.h +54 -18
  576. data/third_party/boringssl-with-bazel/crypto/ecdh/ecdh.cc +7 -5
  577. data/third_party/boringssl-with-bazel/crypto/ecdsa/ecdsa_asn1.cc +50 -70
  578. data/third_party/boringssl-with-bazel/crypto/ecdsa/ecdsa_p1363.cc +54 -0
  579. data/third_party/boringssl-with-bazel/crypto/engine/engine.cc +7 -7
  580. data/third_party/boringssl-with-bazel/crypto/err/err.cc +116 -105
  581. data/third_party/boringssl-with-bazel/crypto/err/internal.h +8 -21
  582. data/third_party/boringssl-with-bazel/crypto/evp/evp.cc +238 -166
  583. data/third_party/boringssl-with-bazel/crypto/evp/evp_asn1.cc +202 -234
  584. data/third_party/boringssl-with-bazel/crypto/evp/evp_ctx.cc +260 -159
  585. data/third_party/boringssl-with-bazel/crypto/evp/evp_kem.cc +82 -0
  586. data/third_party/boringssl-with-bazel/crypto/evp/internal.h +292 -137
  587. data/third_party/boringssl-with-bazel/crypto/evp/p_dh.cc +198 -25
  588. data/third_party/boringssl-with-bazel/crypto/evp/p_dsa.cc +333 -0
  589. data/third_party/boringssl-with-bazel/crypto/evp/p_ec.cc +427 -42
  590. data/third_party/boringssl-with-bazel/crypto/evp/p_ed25519.cc +270 -14
  591. data/third_party/boringssl-with-bazel/crypto/evp/p_hkdf.cc +70 -102
  592. data/third_party/boringssl-with-bazel/crypto/evp/p_mldsa.cc +549 -0
  593. data/third_party/boringssl-with-bazel/crypto/evp/p_mlkem.cc +485 -0
  594. data/third_party/boringssl-with-bazel/crypto/evp/p_rsa.cc +666 -158
  595. data/third_party/boringssl-with-bazel/crypto/evp/p_x25519.cc +290 -28
  596. data/third_party/boringssl-with-bazel/crypto/evp/p_xwing.cc +273 -0
  597. data/third_party/boringssl-with-bazel/crypto/evp/pbkdf.cc +14 -7
  598. data/third_party/boringssl-with-bazel/crypto/evp/print.cc +34 -89
  599. data/third_party/boringssl-with-bazel/crypto/evp/scrypt.cc +23 -21
  600. data/third_party/boringssl-with-bazel/crypto/evp/sign.cc +23 -42
  601. data/third_party/boringssl-with-bazel/crypto/ex_data.cc +40 -41
  602. data/third_party/boringssl-with-bazel/crypto/fipsmodule/aes/aes.cc.inc +34 -28
  603. data/third_party/boringssl-with-bazel/crypto/fipsmodule/aes/aes_nohw.cc.inc +119 -121
  604. data/third_party/boringssl-with-bazel/crypto/fipsmodule/aes/cbc.cc.inc +16 -14
  605. data/third_party/boringssl-with-bazel/crypto/fipsmodule/aes/cfb.cc.inc +12 -10
  606. data/third_party/boringssl-with-bazel/crypto/fipsmodule/aes/ctr.cc.inc +7 -5
  607. data/third_party/boringssl-with-bazel/crypto/fipsmodule/aes/gcm.cc.inc +39 -29
  608. data/third_party/boringssl-with-bazel/crypto/fipsmodule/aes/gcm_nohw.cc.inc +15 -13
  609. data/third_party/boringssl-with-bazel/crypto/fipsmodule/aes/internal.h +193 -177
  610. data/third_party/boringssl-with-bazel/crypto/fipsmodule/aes/key_wrap.cc.inc +5 -3
  611. data/third_party/boringssl-with-bazel/crypto/fipsmodule/aes/mode_wrappers.cc.inc +7 -3
  612. data/third_party/boringssl-with-bazel/crypto/fipsmodule/aes/ofb.cc.inc +7 -5
  613. data/third_party/boringssl-with-bazel/crypto/fipsmodule/bcm.cc +24 -19
  614. data/third_party/boringssl-with-bazel/crypto/fipsmodule/bcm_interface.h +512 -384
  615. data/third_party/boringssl-with-bazel/crypto/fipsmodule/bn/add.cc.inc +7 -5
  616. data/third_party/boringssl-with-bazel/crypto/fipsmodule/bn/asm/x86_64-gcc.cc.inc +63 -44
  617. data/third_party/boringssl-with-bazel/crypto/fipsmodule/bn/bn.cc.inc +40 -37
  618. data/third_party/boringssl-with-bazel/crypto/fipsmodule/bn/bytes.cc.inc +27 -22
  619. data/third_party/boringssl-with-bazel/crypto/fipsmodule/bn/cmp.cc.inc +9 -7
  620. data/third_party/boringssl-with-bazel/crypto/fipsmodule/bn/ctx.cc.inc +62 -126
  621. data/third_party/boringssl-with-bazel/crypto/fipsmodule/bn/div.cc.inc +92 -167
  622. data/third_party/boringssl-with-bazel/crypto/fipsmodule/bn/div_extra.cc.inc +15 -12
  623. data/third_party/boringssl-with-bazel/crypto/fipsmodule/bn/exponentiation.cc.inc +96 -93
  624. data/third_party/boringssl-with-bazel/crypto/fipsmodule/bn/gcd.cc.inc +73 -92
  625. data/third_party/boringssl-with-bazel/crypto/fipsmodule/bn/gcd_extra.cc.inc +59 -71
  626. data/third_party/boringssl-with-bazel/crypto/fipsmodule/bn/generic.cc.inc +54 -57
  627. data/third_party/boringssl-with-bazel/crypto/fipsmodule/bn/internal.h +333 -255
  628. data/third_party/boringssl-with-bazel/crypto/fipsmodule/bn/jacobi.cc.inc +12 -19
  629. data/third_party/boringssl-with-bazel/crypto/fipsmodule/bn/montgomery.cc.inc +80 -95
  630. data/third_party/boringssl-with-bazel/crypto/fipsmodule/bn/montgomery_inv.cc.inc +53 -96
  631. data/third_party/boringssl-with-bazel/crypto/fipsmodule/bn/mul.cc.inc +58 -419
  632. data/third_party/boringssl-with-bazel/crypto/fipsmodule/bn/prime.cc.inc +164 -213
  633. data/third_party/boringssl-with-bazel/crypto/fipsmodule/bn/random.cc.inc +27 -26
  634. data/third_party/boringssl-with-bazel/crypto/fipsmodule/bn/rsaz_exp.cc.inc +12 -10
  635. data/third_party/boringssl-with-bazel/crypto/fipsmodule/bn/rsaz_exp.h +47 -49
  636. data/third_party/boringssl-with-bazel/crypto/fipsmodule/bn/shift.cc.inc +14 -17
  637. data/third_party/boringssl-with-bazel/crypto/fipsmodule/bn/sqrt.cc.inc +19 -108
  638. data/third_party/boringssl-with-bazel/crypto/fipsmodule/cipher/aead.cc.inc +427 -105
  639. data/third_party/boringssl-with-bazel/crypto/fipsmodule/cipher/cipher.cc.inc +412 -212
  640. data/third_party/boringssl-with-bazel/crypto/fipsmodule/cipher/e_aes.cc.inc +230 -225
  641. data/third_party/boringssl-with-bazel/crypto/fipsmodule/cipher/e_aesccm.cc.inc +115 -84
  642. data/third_party/boringssl-with-bazel/crypto/fipsmodule/cipher/internal.h +374 -27
  643. data/third_party/boringssl-with-bazel/crypto/fipsmodule/cmac/cmac.cc.inc +28 -23
  644. data/third_party/boringssl-with-bazel/crypto/fipsmodule/delocate.h +36 -40
  645. data/third_party/boringssl-with-bazel/crypto/fipsmodule/dh/check.cc.inc +68 -78
  646. data/third_party/boringssl-with-bazel/crypto/fipsmodule/dh/dh.cc.inc +154 -196
  647. data/third_party/boringssl-with-bazel/crypto/fipsmodule/dh/internal.h +24 -24
  648. data/third_party/boringssl-with-bazel/crypto/fipsmodule/digest/digest.cc.inc +40 -69
  649. data/third_party/boringssl-with-bazel/crypto/fipsmodule/digest/digests.cc.inc +13 -7
  650. data/third_party/boringssl-with-bazel/crypto/fipsmodule/digest/internal.h +13 -11
  651. data/third_party/boringssl-with-bazel/crypto/fipsmodule/digest/md32_common.h +86 -81
  652. data/third_party/boringssl-with-bazel/crypto/fipsmodule/digestsign/digestsign.cc.inc +38 -34
  653. data/third_party/boringssl-with-bazel/crypto/fipsmodule/ec/ec.cc.inc +187 -196
  654. data/third_party/boringssl-with-bazel/crypto/fipsmodule/ec/ec_key.cc.inc +196 -154
  655. data/third_party/boringssl-with-bazel/crypto/fipsmodule/ec/ec_montgomery.cc.inc +65 -125
  656. data/third_party/boringssl-with-bazel/crypto/fipsmodule/ec/felem.cc.inc +85 -22
  657. data/third_party/boringssl-with-bazel/crypto/fipsmodule/ec/internal.h +281 -287
  658. data/third_party/boringssl-with-bazel/crypto/fipsmodule/ec/oct.cc.inc +23 -22
  659. data/third_party/boringssl-with-bazel/crypto/fipsmodule/ec/p256.cc.inc +514 -573
  660. data/third_party/boringssl-with-bazel/crypto/fipsmodule/ec/p256_internal.h +193 -0
  661. data/third_party/boringssl-with-bazel/crypto/fipsmodule/ec/scalar.cc.inc +44 -39
  662. data/third_party/boringssl-with-bazel/crypto/fipsmodule/ec/simple.cc.inc +58 -90
  663. data/third_party/boringssl-with-bazel/crypto/fipsmodule/ec/simple_mul.cc.inc +39 -34
  664. data/third_party/boringssl-with-bazel/crypto/fipsmodule/ec/util.cc.inc +6 -3
  665. data/third_party/boringssl-with-bazel/crypto/fipsmodule/ec/wnaf.cc.inc +23 -20
  666. data/third_party/boringssl-with-bazel/crypto/fipsmodule/ecdh/ecdh.cc.inc +6 -3
  667. data/third_party/boringssl-with-bazel/crypto/fipsmodule/ecdsa/ecdsa.cc.inc +47 -37
  668. data/third_party/boringssl-with-bazel/crypto/fipsmodule/ecdsa/internal.h +5 -10
  669. data/third_party/boringssl-with-bazel/crypto/fipsmodule/entropy/internal.h +38 -0
  670. data/third_party/boringssl-with-bazel/crypto/fipsmodule/entropy/jitter.cc.inc +463 -0
  671. data/third_party/boringssl-with-bazel/crypto/fipsmodule/entropy/sha512.cc.inc +329 -0
  672. data/third_party/boringssl-with-bazel/crypto/fipsmodule/hkdf/hkdf.cc.inc +8 -6
  673. data/third_party/boringssl-with-bazel/crypto/fipsmodule/hmac/hmac.cc.inc +19 -16
  674. data/third_party/boringssl-with-bazel/crypto/fipsmodule/keccak/internal.h +41 -15
  675. data/third_party/boringssl-with-bazel/crypto/fipsmodule/keccak/keccak.cc.inc +172 -44
  676. data/third_party/boringssl-with-bazel/crypto/fipsmodule/mldsa/fips_known_values.inc +5 -5
  677. data/third_party/boringssl-with-bazel/crypto/fipsmodule/mldsa/mldsa.cc.inc +1632 -766
  678. data/third_party/boringssl-with-bazel/crypto/fipsmodule/mlkem/fips_known_values.inc +5 -5
  679. data/third_party/boringssl-with-bazel/crypto/fipsmodule/mlkem/mlkem.cc.inc +740 -436
  680. data/third_party/boringssl-with-bazel/crypto/fipsmodule/rand/android_entropy_client.cc.inc +82 -0
  681. data/third_party/boringssl-with-bazel/crypto/fipsmodule/rand/ctrdrbg.cc.inc +240 -53
  682. data/third_party/boringssl-with-bazel/crypto/fipsmodule/rand/internal.h +41 -26
  683. data/third_party/boringssl-with-bazel/crypto/fipsmodule/rand/rand.cc.inc +221 -218
  684. data/third_party/boringssl-with-bazel/crypto/fipsmodule/rsa/internal.h +64 -67
  685. data/third_party/boringssl-with-bazel/crypto/fipsmodule/rsa/padding.cc.inc +49 -57
  686. data/third_party/boringssl-with-bazel/crypto/fipsmodule/rsa/rsa.cc.inc +247 -234
  687. data/third_party/boringssl-with-bazel/crypto/fipsmodule/rsa/rsa_impl.cc.inc +392 -692
  688. data/third_party/boringssl-with-bazel/crypto/fipsmodule/self_check/fips.cc.inc +10 -10
  689. data/third_party/boringssl-with-bazel/crypto/fipsmodule/self_check/self_check.cc.inc +479 -449
  690. data/third_party/boringssl-with-bazel/crypto/fipsmodule/service_indicator/internal.h +34 -11
  691. data/third_party/boringssl-with-bazel/crypto/fipsmodule/service_indicator/service_indicator.cc.inc +46 -43
  692. data/third_party/boringssl-with-bazel/crypto/fipsmodule/sha/internal.h +61 -70
  693. data/third_party/boringssl-with-bazel/crypto/fipsmodule/sha/sha1.cc.inc +27 -13
  694. data/third_party/boringssl-with-bazel/crypto/fipsmodule/sha/sha256.cc.inc +46 -30
  695. data/third_party/boringssl-with-bazel/crypto/fipsmodule/sha/sha512.cc.inc +47 -47
  696. data/third_party/boringssl-with-bazel/crypto/fipsmodule/slhdsa/address.h +98 -73
  697. data/third_party/boringssl-with-bazel/crypto/fipsmodule/slhdsa/fors.cc.inc +108 -98
  698. data/third_party/boringssl-with-bazel/crypto/fipsmodule/slhdsa/fors.h +14 -24
  699. data/third_party/boringssl-with-bazel/crypto/fipsmodule/slhdsa/merkle.cc.inc +94 -91
  700. data/third_party/boringssl-with-bazel/crypto/fipsmodule/slhdsa/merkle.h +19 -31
  701. data/third_party/boringssl-with-bazel/crypto/fipsmodule/slhdsa/params.h +156 -56
  702. data/third_party/boringssl-with-bazel/crypto/fipsmodule/slhdsa/slhdsa.cc.inc +318 -132
  703. data/third_party/boringssl-with-bazel/crypto/fipsmodule/slhdsa/thash.cc.inc +234 -81
  704. data/third_party/boringssl-with-bazel/crypto/fipsmodule/slhdsa/thash.h +20 -34
  705. data/third_party/boringssl-with-bazel/crypto/fipsmodule/slhdsa/wots.cc.inc +97 -96
  706. data/third_party/boringssl-with-bazel/crypto/fipsmodule/slhdsa/wots.h +10 -20
  707. data/third_party/boringssl-with-bazel/crypto/fipsmodule/tls/internal.h +2 -16
  708. data/third_party/boringssl-with-bazel/crypto/fipsmodule/tls/kdf.cc.inc +26 -26
  709. data/third_party/boringssl-with-bazel/crypto/fuzzer_mode.cc +5 -5
  710. data/third_party/boringssl-with-bazel/crypto/hpke/hpke.cc +461 -97
  711. data/third_party/boringssl-with-bazel/crypto/hrss/hrss.cc +153 -149
  712. data/third_party/boringssl-with-bazel/crypto/hrss/internal.h +9 -13
  713. data/third_party/boringssl-with-bazel/crypto/internal.h +531 -394
  714. data/third_party/boringssl-with-bazel/crypto/kyber/internal.h +117 -12
  715. data/third_party/boringssl-with-bazel/crypto/kyber/kyber.cc +59 -58
  716. data/third_party/boringssl-with-bazel/crypto/lhash/internal.h +38 -37
  717. data/third_party/boringssl-with-bazel/crypto/lhash/lhash.cc +68 -65
  718. data/third_party/boringssl-with-bazel/crypto/md4/md4.cc +19 -6
  719. data/third_party/boringssl-with-bazel/crypto/md5/internal.h +6 -9
  720. data/third_party/boringssl-with-bazel/crypto/md5/md5.cc +18 -6
  721. data/third_party/boringssl-with-bazel/crypto/mem.cc +61 -65
  722. data/third_party/boringssl-with-bazel/crypto/mem_internal.h +671 -0
  723. data/third_party/boringssl-with-bazel/crypto/mldsa/mldsa.cc +238 -32
  724. data/third_party/boringssl-with-bazel/crypto/mlkem/mlkem.cc +21 -65
  725. data/third_party/boringssl-with-bazel/crypto/obj/obj.cc +132 -157
  726. data/third_party/boringssl-with-bazel/crypto/obj/obj_dat.h +79 -1
  727. data/third_party/boringssl-with-bazel/crypto/obj/obj_xref.cc +14 -11
  728. data/third_party/boringssl-with-bazel/crypto/params_internal.h +30 -0
  729. data/third_party/boringssl-with-bazel/crypto/pem/internal.h +20 -15
  730. data/third_party/boringssl-with-bazel/crypto/pem/pem_all.cc +20 -19
  731. data/third_party/boringssl-with-bazel/crypto/pem/pem_info.cc +72 -76
  732. data/third_party/boringssl-with-bazel/crypto/pem/pem_lib.cc +215 -217
  733. data/third_party/boringssl-with-bazel/crypto/pem/pem_oth.cc +6 -6
  734. data/third_party/boringssl-with-bazel/crypto/pem/pem_pk8.cc +13 -13
  735. data/third_party/boringssl-with-bazel/crypto/pem/pem_pkey.cc +11 -11
  736. data/third_party/boringssl-with-bazel/crypto/pkcs7/internal.h +12 -17
  737. data/third_party/boringssl-with-bazel/crypto/pkcs7/pkcs7.cc +29 -27
  738. data/third_party/boringssl-with-bazel/crypto/pkcs7/pkcs7_x509.cc +55 -49
  739. data/third_party/boringssl-with-bazel/crypto/pkcs8/internal.h +21 -26
  740. data/third_party/boringssl-with-bazel/crypto/pkcs8/p5_pbev2.cc +33 -31
  741. data/third_party/boringssl-with-bazel/crypto/pkcs8/pkcs8.cc +73 -81
  742. data/third_party/boringssl-with-bazel/crypto/pkcs8/pkcs8_x509.cc +139 -138
  743. data/third_party/boringssl-with-bazel/crypto/poly1305/internal.h +3 -7
  744. data/third_party/boringssl-with-bazel/crypto/poly1305/poly1305.cc +5 -4
  745. data/third_party/boringssl-with-bazel/crypto/poly1305/poly1305_arm.cc +43 -47
  746. data/third_party/boringssl-with-bazel/crypto/poly1305/poly1305_vec.cc +29 -26
  747. data/third_party/boringssl-with-bazel/crypto/pool/internal.h +64 -20
  748. data/third_party/boringssl-with-bazel/crypto/pool/pool.cc +177 -157
  749. data/third_party/boringssl-with-bazel/crypto/rand/deterministic.cc +9 -16
  750. data/third_party/boringssl-with-bazel/crypto/rand/fork_detect.cc +70 -42
  751. data/third_party/boringssl-with-bazel/crypto/rand/forkunsafe.cc +7 -7
  752. data/third_party/boringssl-with-bazel/crypto/rand/getentropy.cc +6 -13
  753. data/third_party/boringssl-with-bazel/crypto/rand/internal.h +16 -4
  754. data/third_party/boringssl-with-bazel/crypto/rand/ios.cc +4 -11
  755. data/third_party/boringssl-with-bazel/crypto/rand/rand.cc +11 -9
  756. data/third_party/boringssl-with-bazel/crypto/rand/trusty.cc +4 -11
  757. data/third_party/boringssl-with-bazel/crypto/rand/urandom.cc +16 -195
  758. data/third_party/boringssl-with-bazel/crypto/rand/windows.cc +12 -19
  759. data/third_party/boringssl-with-bazel/crypto/refcount.cc +7 -17
  760. data/third_party/boringssl-with-bazel/crypto/rsa/internal.h +22 -7
  761. data/third_party/boringssl-with-bazel/crypto/rsa/rsa_asn1.cc +199 -78
  762. data/third_party/boringssl-with-bazel/crypto/rsa/rsa_crypt.cc +49 -50
  763. data/third_party/boringssl-with-bazel/crypto/rsa/rsa_extra.cc +11 -0
  764. data/third_party/boringssl-with-bazel/crypto/rsa/rsa_print.cc +4 -6
  765. data/third_party/boringssl-with-bazel/crypto/sha/sha1.cc +3 -0
  766. data/third_party/boringssl-with-bazel/crypto/sha/sha256.cc +3 -1
  767. data/third_party/boringssl-with-bazel/crypto/sha/sha512.cc +6 -4
  768. data/third_party/boringssl-with-bazel/crypto/siphash/siphash.cc +2 -0
  769. data/third_party/boringssl-with-bazel/crypto/slhdsa/slhdsa.cc +43 -6
  770. data/third_party/boringssl-with-bazel/crypto/spake2plus/internal.h +31 -31
  771. data/third_party/boringssl-with-bazel/crypto/spake2plus/spake2plus.cc +1 -1
  772. data/third_party/boringssl-with-bazel/crypto/stack/stack.cc +89 -130
  773. data/third_party/boringssl-with-bazel/crypto/thread.cc +14 -14
  774. data/third_party/boringssl-with-bazel/crypto/thread_none.cc +10 -13
  775. data/third_party/boringssl-with-bazel/crypto/thread_pthread.cc +22 -35
  776. data/third_party/boringssl-with-bazel/crypto/thread_win.cc +29 -40
  777. data/third_party/boringssl-with-bazel/crypto/trust_token/internal.h +81 -88
  778. data/third_party/boringssl-with-bazel/crypto/trust_token/pmbtoken.cc +160 -144
  779. data/third_party/boringssl-with-bazel/crypto/trust_token/trust_token.cc +96 -80
  780. data/third_party/boringssl-with-bazel/crypto/trust_token/voprf.cc +90 -87
  781. data/third_party/boringssl-with-bazel/crypto/x509/a_digest.cc +5 -5
  782. data/third_party/boringssl-with-bazel/crypto/x509/a_sign.cc +51 -48
  783. data/third_party/boringssl-with-bazel/crypto/x509/a_verify.cc +30 -34
  784. data/third_party/boringssl-with-bazel/crypto/x509/algorithm.cc +47 -16
  785. data/third_party/boringssl-with-bazel/crypto/x509/asn1_gen.cc +41 -43
  786. data/third_party/boringssl-with-bazel/crypto/x509/by_dir.cc +183 -237
  787. data/third_party/boringssl-with-bazel/crypto/x509/by_file.cc +29 -30
  788. data/third_party/boringssl-with-bazel/crypto/x509/internal.h +276 -180
  789. data/third_party/boringssl-with-bazel/crypto/x509/name_print.cc +15 -13
  790. data/third_party/boringssl-with-bazel/crypto/x509/policy.cc +415 -525
  791. data/third_party/boringssl-with-bazel/crypto/x509/rsa_pss.cc +94 -271
  792. data/third_party/boringssl-with-bazel/crypto/x509/t_crl.cc +11 -8
  793. data/third_party/boringssl-with-bazel/crypto/x509/t_req.cc +26 -23
  794. data/third_party/boringssl-with-bazel/crypto/x509/t_x509.cc +26 -22
  795. data/third_party/boringssl-with-bazel/crypto/x509/t_x509a.cc +3 -1
  796. data/third_party/boringssl-with-bazel/crypto/x509/v3_akey.cc +69 -76
  797. data/third_party/boringssl-with-bazel/crypto/x509/v3_akeya.cc +2 -2
  798. data/third_party/boringssl-with-bazel/crypto/x509/v3_alt.cc +112 -69
  799. data/third_party/boringssl-with-bazel/crypto/x509/v3_bcons.cc +15 -14
  800. data/third_party/boringssl-with-bazel/crypto/x509/v3_bitst.cc +16 -18
  801. data/third_party/boringssl-with-bazel/crypto/x509/v3_conf.cc +62 -67
  802. data/third_party/boringssl-with-bazel/crypto/x509/v3_cpols.cc +143 -170
  803. data/third_party/boringssl-with-bazel/crypto/x509/v3_crld.cc +121 -165
  804. data/third_party/boringssl-with-bazel/crypto/x509/v3_enum.cc +13 -12
  805. data/third_party/boringssl-with-bazel/crypto/x509/v3_extku.cc +17 -34
  806. data/third_party/boringssl-with-bazel/crypto/x509/v3_genn.cc +20 -10
  807. data/third_party/boringssl-with-bazel/crypto/x509/v3_ia5.cc +22 -18
  808. data/third_party/boringssl-with-bazel/crypto/x509/v3_info.cc +45 -47
  809. data/third_party/boringssl-with-bazel/crypto/x509/v3_int.cc +35 -33
  810. data/third_party/boringssl-with-bazel/crypto/x509/v3_lib.cc +106 -61
  811. data/third_party/boringssl-with-bazel/crypto/x509/v3_ncons.cc +642 -358
  812. data/third_party/boringssl-with-bazel/crypto/x509/v3_ocsp.cc +25 -22
  813. data/third_party/boringssl-with-bazel/crypto/x509/v3_pcons.cc +15 -14
  814. data/third_party/boringssl-with-bazel/crypto/x509/v3_pmaps.cc +16 -15
  815. data/third_party/boringssl-with-bazel/crypto/x509/v3_prn.cc +6 -6
  816. data/third_party/boringssl-with-bazel/crypto/x509/v3_purp.cc +150 -137
  817. data/third_party/boringssl-with-bazel/crypto/x509/v3_skey.cc +23 -26
  818. data/third_party/boringssl-with-bazel/crypto/x509/v3_utl.cc +151 -178
  819. data/third_party/boringssl-with-bazel/crypto/x509/x509.cc +1 -1
  820. data/third_party/boringssl-with-bazel/crypto/x509/x509_att.cc +32 -30
  821. data/third_party/boringssl-with-bazel/crypto/x509/x509_cmp.cc +95 -88
  822. data/third_party/boringssl-with-bazel/crypto/x509/x509_d2.cc +9 -9
  823. data/third_party/boringssl-with-bazel/crypto/x509/x509_def.cc +6 -8
  824. data/third_party/boringssl-with-bazel/crypto/x509/x509_ext.cc +46 -24
  825. data/third_party/boringssl-with-bazel/crypto/x509/x509_lu.cc +211 -195
  826. data/third_party/boringssl-with-bazel/crypto/x509/x509_obj.cc +20 -16
  827. data/third_party/boringssl-with-bazel/crypto/x509/x509_req.cc +37 -46
  828. data/third_party/boringssl-with-bazel/crypto/x509/x509_set.cc +62 -90
  829. data/third_party/boringssl-with-bazel/crypto/x509/x509_trs.cc +18 -13
  830. data/third_party/boringssl-with-bazel/crypto/x509/x509_v3.cc +33 -33
  831. data/third_party/boringssl-with-bazel/crypto/x509/x509_vfy.cc +109 -110
  832. data/third_party/boringssl-with-bazel/crypto/x509/x509_vpm.cc +56 -47
  833. data/third_party/boringssl-with-bazel/crypto/x509/x509cset.cc +27 -40
  834. data/third_party/boringssl-with-bazel/crypto/x509/x509name.cc +77 -67
  835. data/third_party/boringssl-with-bazel/crypto/x509/x509rset.cc +5 -17
  836. data/third_party/boringssl-with-bazel/crypto/x509/x509spki.cc +13 -13
  837. data/third_party/boringssl-with-bazel/crypto/x509/x_algor.cc +131 -24
  838. data/third_party/boringssl-with-bazel/crypto/x509/x_all.cc +72 -39
  839. data/third_party/boringssl-with-bazel/crypto/x509/x_attrib.cc +10 -4
  840. data/third_party/boringssl-with-bazel/crypto/x509/x_crl.cc +77 -44
  841. data/third_party/boringssl-with-bazel/crypto/x509/x_exten.cc +6 -0
  842. data/third_party/boringssl-with-bazel/crypto/x509/x_name.cc +311 -383
  843. data/third_party/boringssl-with-bazel/crypto/x509/x_pubkey.cc +129 -82
  844. data/third_party/boringssl-with-bazel/crypto/x509/x_req.cc +11 -6
  845. data/third_party/boringssl-with-bazel/crypto/x509/x_sig.cc +4 -4
  846. data/third_party/boringssl-with-bazel/crypto/x509/x_spki.cc +11 -1
  847. data/third_party/boringssl-with-bazel/crypto/x509/x_x509.cc +285 -280
  848. data/third_party/boringssl-with-bazel/crypto/x509/x_x509a.cc +60 -60
  849. data/third_party/boringssl-with-bazel/crypto/xwing/xwing.cc +257 -0
  850. data/third_party/boringssl-with-bazel/gen/boringssl_prefix_symbols_internal_x86_64_win_asm.inc +301 -0
  851. data/third_party/boringssl-with-bazel/gen/boringssl_prefix_symbols_internal_x86_win_asm.inc +301 -0
  852. data/third_party/boringssl-with-bazel/gen/crypto/err_data.cc +526 -500
  853. data/third_party/boringssl-with-bazel/include/openssl/aead.h +286 -114
  854. data/third_party/boringssl-with-bazel/include/openssl/aes.h +43 -43
  855. data/third_party/boringssl-with-bazel/include/openssl/asm_base.h +29 -16
  856. data/third_party/boringssl-with-bazel/include/openssl/asn1.h +641 -631
  857. data/third_party/boringssl-with-bazel/include/openssl/asn1t.h +7 -9
  858. data/third_party/boringssl-with-bazel/include/openssl/base.h +34 -54
  859. data/third_party/boringssl-with-bazel/include/openssl/base64.h +30 -30
  860. data/third_party/boringssl-with-bazel/include/openssl/bio.h +373 -316
  861. data/third_party/boringssl-with-bazel/include/openssl/blake2.h +15 -11
  862. data/third_party/boringssl-with-bazel/include/openssl/blowfish.h +10 -3
  863. data/third_party/boringssl-with-bazel/include/openssl/bn.h +298 -306
  864. data/third_party/boringssl-with-bazel/include/openssl/buf.h +14 -14
  865. data/third_party/boringssl-with-bazel/include/openssl/bytestring.h +272 -207
  866. data/third_party/boringssl-with-bazel/include/openssl/cast.h +45 -8
  867. data/third_party/boringssl-with-bazel/include/openssl/chacha.h +3 -3
  868. data/third_party/boringssl-with-bazel/include/openssl/cipher.h +334 -152
  869. data/third_party/boringssl-with-bazel/include/openssl/cmac.h +13 -13
  870. data/third_party/boringssl-with-bazel/include/openssl/cms.h +35 -34
  871. data/third_party/boringssl-with-bazel/include/openssl/conf.h +15 -14
  872. data/third_party/boringssl-with-bazel/include/openssl/crypto.h +15 -13
  873. data/third_party/boringssl-with-bazel/include/openssl/ctrdrbg.h +49 -15
  874. data/third_party/boringssl-with-bazel/include/openssl/curve25519.h +24 -24
  875. data/third_party/boringssl-with-bazel/include/openssl/des.h +22 -16
  876. data/third_party/boringssl-with-bazel/include/openssl/dh.h +95 -95
  877. data/third_party/boringssl-with-bazel/include/openssl/digest.h +140 -71
  878. data/third_party/boringssl-with-bazel/include/openssl/dsa.h +101 -101
  879. data/third_party/boringssl-with-bazel/include/openssl/ec.h +143 -119
  880. data/third_party/boringssl-with-bazel/include/openssl/ec_key.h +97 -97
  881. data/third_party/boringssl-with-bazel/include/openssl/ecdh.h +9 -9
  882. data/third_party/boringssl-with-bazel/include/openssl/ecdsa.h +89 -46
  883. data/third_party/boringssl-with-bazel/include/openssl/engine.h +5 -5
  884. data/third_party/boringssl-with-bazel/include/openssl/err.h +73 -71
  885. data/third_party/boringssl-with-bazel/include/openssl/evp.h +824 -344
  886. data/third_party/boringssl-with-bazel/include/openssl/evp_errors.h +9 -2
  887. data/third_party/boringssl-with-bazel/include/openssl/ex_data.h +27 -32
  888. data/third_party/boringssl-with-bazel/include/openssl/hkdf.h +6 -6
  889. data/third_party/boringssl-with-bazel/include/openssl/hmac.h +31 -31
  890. data/third_party/boringssl-with-bazel/include/openssl/hpke.h +133 -117
  891. data/third_party/boringssl-with-bazel/include/openssl/hrss.h +14 -8
  892. data/third_party/boringssl-with-bazel/include/openssl/kdf.h +20 -19
  893. data/third_party/boringssl-with-bazel/include/openssl/lhash.h +4 -25
  894. data/third_party/boringssl-with-bazel/include/openssl/md4.h +14 -7
  895. data/third_party/boringssl-with-bazel/include/openssl/md5.h +7 -7
  896. data/third_party/boringssl-with-bazel/include/openssl/mem.h +38 -38
  897. data/third_party/boringssl-with-bazel/include/openssl/mldsa.h +380 -24
  898. data/third_party/boringssl-with-bazel/include/openssl/mlkem.h +43 -43
  899. data/third_party/boringssl-with-bazel/include/openssl/nid.h +1297 -2
  900. data/third_party/boringssl-with-bazel/include/openssl/obj.h +49 -49
  901. data/third_party/boringssl-with-bazel/include/openssl/opensslconf.h +30 -0
  902. data/third_party/boringssl-with-bazel/include/openssl/params.h +42 -0
  903. data/third_party/boringssl-with-bazel/include/openssl/pem.h +39 -30
  904. data/third_party/boringssl-with-bazel/include/openssl/pkcs7.h +40 -40
  905. data/third_party/boringssl-with-bazel/include/openssl/pkcs8.h +69 -63
  906. data/third_party/boringssl-with-bazel/include/openssl/poly1305.h +8 -5
  907. data/third_party/boringssl-with-bazel/include/openssl/pool.h +54 -25
  908. data/third_party/boringssl-with-bazel/include/openssl/posix_time.h +6 -6
  909. data/third_party/boringssl-with-bazel/include/openssl/prefix_symbols.h +7866 -0
  910. data/third_party/boringssl-with-bazel/include/openssl/prefix_symbols_internal_S.h +585 -0
  911. data/third_party/boringssl-with-bazel/include/openssl/prefix_symbols_internal_c.h +305 -0
  912. data/third_party/boringssl-with-bazel/include/openssl/rand.h +18 -18
  913. data/third_party/boringssl-with-bazel/include/openssl/rc4.h +4 -4
  914. data/third_party/boringssl-with-bazel/include/openssl/ripemd.h +15 -10
  915. data/third_party/boringssl-with-bazel/include/openssl/rsa.h +272 -235
  916. data/third_party/boringssl-with-bazel/include/openssl/service_indicator.h +4 -81
  917. data/third_party/boringssl-with-bazel/include/openssl/sha.h +43 -166
  918. data/third_party/boringssl-with-bazel/include/openssl/sha2.h +201 -0
  919. data/third_party/boringssl-with-bazel/include/openssl/slhdsa.h +100 -48
  920. data/third_party/boringssl-with-bazel/include/openssl/span.h +190 -75
  921. data/third_party/boringssl-with-bazel/include/openssl/ssl.h +2168 -1567
  922. data/third_party/boringssl-with-bazel/include/openssl/ssl3.h +11 -69
  923. data/third_party/boringssl-with-bazel/include/openssl/stack.h +135 -80
  924. data/third_party/boringssl-with-bazel/include/openssl/target.h +13 -1
  925. data/third_party/boringssl-with-bazel/include/openssl/thread.h +0 -10
  926. data/third_party/boringssl-with-bazel/include/openssl/tls1.h +31 -310
  927. data/third_party/boringssl-with-bazel/include/openssl/tls_prf.h +47 -0
  928. data/third_party/boringssl-with-bazel/include/openssl/trust_token.h +97 -92
  929. data/third_party/boringssl-with-bazel/include/openssl/type_check.h +1 -1
  930. data/third_party/boringssl-with-bazel/include/openssl/x509.h +1805 -1857
  931. data/third_party/boringssl-with-bazel/include/openssl/x509v3.h +1 -1
  932. data/third_party/boringssl-with-bazel/include/openssl/xwing.h +115 -0
  933. data/third_party/boringssl-with-bazel/ssl/bio_ssl.cc +24 -19
  934. data/third_party/boringssl-with-bazel/ssl/d1_both.cc +59 -57
  935. data/third_party/boringssl-with-bazel/ssl/d1_lib.cc +53 -42
  936. data/third_party/boringssl-with-bazel/ssl/d1_pkt.cc +4 -4
  937. data/third_party/boringssl-with-bazel/ssl/d1_srtp.cc +2 -2
  938. data/third_party/boringssl-with-bazel/ssl/dtls_method.cc +10 -10
  939. data/third_party/boringssl-with-bazel/ssl/dtls_record.cc +6 -6
  940. data/third_party/boringssl-with-bazel/ssl/encrypted_client_hello.cc +61 -71
  941. data/third_party/boringssl-with-bazel/ssl/extensions.cc +967 -366
  942. data/third_party/boringssl-with-bazel/ssl/handoff.cc +77 -38
  943. data/third_party/boringssl-with-bazel/ssl/handshake.cc +63 -30
  944. data/third_party/boringssl-with-bazel/ssl/handshake_client.cc +129 -85
  945. data/third_party/boringssl-with-bazel/ssl/handshake_server.cc +116 -68
  946. data/third_party/boringssl-with-bazel/ssl/internal.h +983 -1207
  947. data/third_party/boringssl-with-bazel/ssl/s3_both.cc +34 -29
  948. data/third_party/boringssl-with-bazel/ssl/s3_lib.cc +4 -3
  949. data/third_party/boringssl-with-bazel/ssl/s3_pkt.cc +12 -12
  950. data/third_party/boringssl-with-bazel/ssl/ssl_aead_ctx.cc +5 -5
  951. data/third_party/boringssl-with-bazel/ssl/ssl_asn1.cc +114 -59
  952. data/third_party/boringssl-with-bazel/ssl/ssl_buffer.cc +17 -18
  953. data/third_party/boringssl-with-bazel/ssl/ssl_cert.cc +99 -61
  954. data/third_party/boringssl-with-bazel/ssl/ssl_cipher.cc +143 -134
  955. data/third_party/boringssl-with-bazel/ssl/ssl_credential.cc +188 -90
  956. data/third_party/boringssl-with-bazel/ssl/ssl_file.cc +132 -225
  957. data/third_party/boringssl-with-bazel/ssl/ssl_key_share.cc +79 -7
  958. data/third_party/boringssl-with-bazel/ssl/ssl_lib.cc +698 -302
  959. data/third_party/boringssl-with-bazel/ssl/ssl_privkey.cc +102 -45
  960. data/third_party/boringssl-with-bazel/ssl/ssl_session.cc +117 -102
  961. data/third_party/boringssl-with-bazel/ssl/ssl_transcript.cc +3 -3
  962. data/third_party/boringssl-with-bazel/ssl/ssl_versions.cc +24 -24
  963. data/third_party/boringssl-with-bazel/ssl/ssl_x509.cc +184 -170
  964. data/third_party/boringssl-with-bazel/ssl/t1_enc.cc +12 -10
  965. data/third_party/boringssl-with-bazel/ssl/tls13_both.cc +86 -54
  966. data/third_party/boringssl-with-bazel/ssl/tls13_client.cc +176 -90
  967. data/third_party/boringssl-with-bazel/ssl/tls13_enc.cc +166 -112
  968. data/third_party/boringssl-with-bazel/ssl/tls13_server.cc +188 -97
  969. data/third_party/boringssl-with-bazel/ssl/tls_method.cc +23 -23
  970. data/third_party/boringssl-with-bazel/ssl/tls_record.cc +17 -14
  971. data/third_party/boringssl-with-bazel/third_party/fiat/bedrock_unverified_bareminimum.c.inc +47 -0
  972. data/third_party/boringssl-with-bazel/third_party/fiat/bedrock_unverified_platform.c.inc +137 -0
  973. data/third_party/boringssl-with-bazel/third_party/fiat/curve25519_64_adx.h +37 -33
  974. data/third_party/boringssl-with-bazel/third_party/fiat/p256_64.h +4 -93
  975. data/third_party/boringssl-with-bazel/third_party/fiat/p256_64_msvc.h +4 -69
  976. data/third_party/boringssl-with-bazel/third_party/fiat/p256_field_32.br.c.inc +71 -0
  977. data/third_party/boringssl-with-bazel/third_party/fiat/p256_field_64.br.c.inc +84 -0
  978. data/third_party/boringssl-with-bazel/third_party/fiat/p256_point.br.c.inc +166 -0
  979. metadata +77 -52
  980. data/src/core/ext/transport/chttp2/transport/bin_decoder.cc +0 -240
  981. data/src/core/ext/transport/chttp2/transport/bin_decoder.h +0 -56
  982. data/src/core/ext/upb-gen/src/proto/grpc/health/v1/health.upb.h +0 -157
  983. data/src/core/ext/upb-gen/src/proto/grpc/health/v1/health.upb_minitable.c +0 -72
  984. data/src/core/ext/upbdefs-gen/src/proto/grpc/lookup/v1/rls_config.upbdefs.c +0 -181
  985. data/third_party/abseil-cpp/absl/base/internal/identity.h +0 -39
  986. data/third_party/abseil-cpp/absl/base/internal/nullability_deprecated.h +0 -106
  987. data/third_party/abseil-cpp/absl/hash/internal/low_level_hash.cc +0 -105
  988. data/third_party/abseil-cpp/absl/hash/internal/low_level_hash.h +0 -50
  989. data/third_party/abseil-cpp/absl/strings/string_view.cc +0 -257
  990. data/third_party/boringssl-with-bazel/crypto/evp/p_dh_asn1.cc +0 -142
  991. data/third_party/boringssl-with-bazel/crypto/evp/p_dsa_asn1.cc +0 -279
  992. data/third_party/boringssl-with-bazel/crypto/evp/p_ec_asn1.cc +0 -286
  993. data/third_party/boringssl-with-bazel/crypto/evp/p_ed25519_asn1.cc +0 -225
  994. data/third_party/boringssl-with-bazel/crypto/evp/p_rsa_asn1.cc +0 -198
  995. data/third_party/boringssl-with-bazel/crypto/evp/p_x25519_asn1.cc +0 -237
  996. data/third_party/boringssl-with-bazel/crypto/fipsmodule/ec/p224-64.cc.inc +0 -1163
  997. data/third_party/boringssl-with-bazel/crypto/fipsmodule/ec/p256-nistz.cc.inc +0 -741
  998. data/third_party/boringssl-with-bazel/crypto/fipsmodule/ec/p256-nistz.h +0 -207
  999. data/third_party/boringssl-with-bazel/crypto/fipsmodule/rsa/blinding.cc.inc +0 -147
  1000. data/third_party/boringssl-with-bazel/crypto/rand/getrandom_fillin.h +0 -64
  1001. data/third_party/boringssl-with-bazel/crypto/rand/passive.cc +0 -178
  1002. data/third_party/boringssl-with-bazel/crypto/x509/ext_dat.h +0 -92
  1003. data/third_party/boringssl-with-bazel/include/openssl/bcm_public.h +0 -82
  1004. data/third_party/boringssl-with-bazel/include/openssl/experimental/kyber.h +0 -146
@@ -150,11 +150,11 @@
150
150
  // To `insert`, we compose `unchecked_insert` with `find`. We compute `h(x)` and
151
151
  // perform a `find` to see if it's already present; if it is, we're done. If
152
152
  // it's not, we may decide the table is getting overcrowded (i.e. the load
153
- // factor is greater than 7/8 for big tables; `is_small()` tables use a max load
154
- // factor of 1); in this case, we allocate a bigger array, `unchecked_insert`
155
- // each element of the table into the new array (we know that no insertion here
156
- // will insert an already-present value), and discard the old backing array. At
157
- // this point, we may `unchecked_insert` the value `x`.
153
+ // factor is greater than 7/8 for big tables; tables smaller than one probing
154
+ // group use a max load factor of 1); in this case, we allocate a bigger array,
155
+ // `unchecked_insert` each element of the table into the new array (we know that
156
+ // no insertion here will insert an already-present value), and discard the old
157
+ // backing array. At this point, we may `unchecked_insert` the value `x`.
158
158
  //
159
159
  // Below, `unchecked_insert` is partly implemented by `prepare_insert`, which
160
160
  // presents a viable, initialized slot pointee to the caller.
@@ -194,6 +194,7 @@
194
194
  #include <utility>
195
195
 
196
196
  #include "absl/base/attributes.h"
197
+ #include "absl/base/casts.h"
197
198
  #include "absl/base/config.h"
198
199
  #include "absl/base/internal/endian.h"
199
200
  #include "absl/base/internal/iterator_traits.h"
@@ -220,6 +221,14 @@
220
221
  #include "absl/numeric/bits.h"
221
222
  #include "absl/utility/utility.h"
222
223
 
224
+ #if ABSL_INTERNAL_CPLUSPLUS_LANG >= 202002L
225
+ #include <ranges> // NOLINT(build/c++20)
226
+ #endif
227
+
228
+ #ifdef __BMI2__
229
+ #include <bmi2intrin.h>
230
+ #endif // __BMI2__
231
+
223
232
  namespace absl {
224
233
  ABSL_NAMESPACE_BEGIN
225
234
  namespace container_internal {
@@ -282,10 +291,8 @@ void SwapAlloc(AllocType& lhs, AllocType& rhs,
282
291
  swap(lhs, rhs);
283
292
  }
284
293
  template <typename AllocType>
285
- void SwapAlloc(AllocType& lhs, AllocType& rhs,
294
+ void SwapAlloc([[maybe_unused]] AllocType& lhs, [[maybe_unused]] AllocType& rhs,
286
295
  std::false_type /* propagate_on_container_swap */) {
287
- (void)lhs;
288
- (void)rhs;
289
296
  assert(lhs == rhs &&
290
297
  "It's UB to call swap with unequal non-propagating allocators.");
291
298
  }
@@ -298,57 +305,6 @@ void CopyAlloc(AllocType& lhs, AllocType& rhs,
298
305
  template <typename AllocType>
299
306
  void CopyAlloc(AllocType&, AllocType&, std::false_type /* propagate_alloc */) {}
300
307
 
301
- // The state for a probe sequence.
302
- //
303
- // Currently, the sequence is a triangular progression of the form
304
- //
305
- // p(i) := Width * (i^2 + i)/2 + hash (mod mask + 1)
306
- //
307
- // The use of `Width` ensures that each probe step does not overlap groups;
308
- // the sequence effectively outputs the addresses of *groups* (although not
309
- // necessarily aligned to any boundary). The `Group` machinery allows us
310
- // to check an entire group with minimal branching.
311
- //
312
- // Wrapping around at `mask + 1` is important, but not for the obvious reason.
313
- // As described above, the first few entries of the control byte array
314
- // are mirrored at the end of the array, which `Group` will find and use
315
- // for selecting candidates. However, when those candidates' slots are
316
- // actually inspected, there are no corresponding slots for the cloned bytes,
317
- // so we need to make sure we've treated those offsets as "wrapping around".
318
- //
319
- // It turns out that this probe sequence visits every group exactly once if the
320
- // number of groups is a power of two, since (i^2+i)/2 is a bijection in
321
- // Z/(2^m). See https://en.wikipedia.org/wiki/Quadratic_probing
322
- template <size_t Width>
323
- class probe_seq {
324
- public:
325
- // Creates a new probe sequence using `hash` as the initial value of the
326
- // sequence and `mask` (usually the capacity of the table) as the mask to
327
- // apply to each value in the progression.
328
- probe_seq(size_t hash, size_t mask) {
329
- ABSL_SWISSTABLE_ASSERT(((mask + 1) & mask) == 0 && "not a mask");
330
- mask_ = mask;
331
- offset_ = hash & mask_;
332
- }
333
-
334
- // The offset within the table, i.e., the value `p(i)` above.
335
- size_t offset() const { return offset_; }
336
- size_t offset(size_t i) const { return (offset_ + i) & mask_; }
337
-
338
- void next() {
339
- index_ += Width;
340
- offset_ += index_;
341
- offset_ &= mask_;
342
- }
343
- // 0-based probe index, a multiple of `Width`.
344
- size_t index() const { return index_; }
345
-
346
- private:
347
- size_t mask_;
348
- size_t offset_;
349
- size_t index_ = 0;
350
- };
351
-
352
308
  template <class ContainerKey, class Hash, class Eq>
353
309
  struct RequireUsableKey {
354
310
  template <class PassedKey, class... Args>
@@ -364,48 +320,21 @@ struct IsDecomposable : std::false_type {};
364
320
 
365
321
  template <class Policy, class Hash, class Eq, class... Ts>
366
322
  struct IsDecomposable<
367
- absl::void_t<decltype(Policy::apply(
323
+ std::void_t<decltype(Policy::apply(
368
324
  RequireUsableKey<typename Policy::key_type, Hash, Eq>(),
369
325
  std::declval<Ts>()...))>,
370
326
  Policy, Hash, Eq, Ts...> : std::true_type {};
371
327
 
372
- // TODO(alkis): Switch to std::is_nothrow_swappable when gcc/clang supports it.
373
- template <class T>
374
- constexpr bool IsNoThrowSwappable(std::true_type = {} /* is_swappable */) {
375
- using std::swap;
376
- return noexcept(swap(std::declval<T&>(), std::declval<T&>()));
377
- }
378
- template <class T>
379
- constexpr bool IsNoThrowSwappable(std::false_type /* is_swappable */) {
380
- return false;
381
- }
328
+ ABSL_DLL extern ctrl_t kDefaultIterControl;
382
329
 
383
- // See definition comment for why this is size 32.
384
- ABSL_DLL extern const ctrl_t kEmptyGroup[32];
385
-
386
- // We use these sentinel capacity values in debug mode to indicate different
387
- // classes of bugs.
388
- enum InvalidCapacity : size_t {
389
- kAboveMaxValidCapacity = ~size_t{} - 100,
390
- kReentrance,
391
- kDestroyed,
392
-
393
- // These two must be last because we use `>= kMovedFrom` to mean moved-from.
394
- kMovedFrom,
395
- kSelfMovedFrom,
396
- };
397
-
398
- // Returns a pointer to a control byte group that can be used by empty tables.
399
- inline ctrl_t* EmptyGroup() {
400
- // Const must be cast away here; no uses of this function will actually write
401
- // to it because it is only used for empty tables.
402
- return const_cast<ctrl_t*>(kEmptyGroup + 16);
403
- }
330
+ // Returns a pointer to a control byte that can be used by default-constructed
331
+ // iterators. We don't expect this pointer to be dereferenced.
332
+ inline ctrl_t* DefaultIterControl() { return &kDefaultIterControl; }
404
333
 
405
334
  // For use in SOO iterators.
406
335
  // TODO(b/289225379): we could potentially get rid of this by adding an is_soo
407
336
  // bit in iterators. This would add branches but reduce cache misses.
408
- ABSL_DLL extern const ctrl_t kSooControl[17];
337
+ ABSL_DLL extern const ctrl_t kSooControl[2];
409
338
 
410
339
  // Returns a pointer to a full byte followed by a sentinel byte.
411
340
  inline ctrl_t* SooControl() {
@@ -433,6 +362,8 @@ inline bool IsEmptyGeneration(const GenerationType* generation) {
433
362
  // - In order to prevent user code from depending on iteration order for small
434
363
  // tables, we would need to randomize the iteration order somehow.
435
364
  constexpr size_t SooCapacity() { return 1; }
365
+ // Maximum capacity of a table where we don't need to hash any keys.
366
+ constexpr size_t MaxSmallCapacity() { return 1; }
436
367
  // Sentinel type to indicate SOO CommonFields construction.
437
368
  struct soo_tag_t {};
438
369
  // Sentinel type to indicate SOO CommonFields construction with full size.
@@ -444,66 +375,308 @@ struct uninitialized_tag_t {};
444
375
  // Sentinel value to indicate creation of an empty table without a seed.
445
376
  struct no_seed_empty_tag_t {};
446
377
 
378
+ // Returns whether `n` is a valid capacity (i.e., number of slots).
379
+ //
380
+ // A valid capacity is a non-zero integer `2^m - 1`.
381
+ constexpr bool IsValidCapacity(size_t n) { return ((n + 1) & n) == 0 && n > 0; }
382
+
383
+ // Whether a table is small enough that we don't need to hash any keys.
384
+ constexpr bool IsSmallCapacity(size_t capacity) {
385
+ return capacity <= MaxSmallCapacity();
386
+ }
387
+
388
+ // Converts `n` into the next valid capacity, per `IsValidCapacity`.
389
+ constexpr size_t NormalizeCapacity(size_t n) {
390
+ return n ? ~size_t{} >> countl_zero(n) : 1;
391
+ }
392
+
393
+ // Returns the next valid capacity after `n`.
394
+ constexpr size_t NextCapacity(size_t n) {
395
+ ABSL_SWISSTABLE_ASSERT(IsValidCapacity(n) || n == 0);
396
+ return n * 2 + 1;
397
+ }
398
+
399
+ // Returns the previous valid capacity before `n`.
400
+ constexpr size_t PreviousCapacity(size_t n) {
401
+ ABSL_SWISSTABLE_ASSERT(IsValidCapacity(n));
402
+ return n / 2;
403
+ }
404
+
405
+ // General notes on capacity/growth methods below:
406
+ // - We use 7/8th as maximum load factor. For 16-wide groups, that gives an
407
+ // average of two empty slots per group.
408
+ // - For (capacity+1) >= Group::kWidth, growth is 7/8*capacity.
409
+ // - For (capacity+1) < Group::kWidth, growth == capacity. In this case, we
410
+ // never need to probe (the whole table fits in one group) so we don't need a
411
+ // load factor less than 1.
412
+
413
+ // Given `capacity`, applies the load factor; i.e., it returns the maximum
414
+ // number of values we should put into the table before a resizing rehash.
415
+ constexpr size_t CapacityToGrowth(size_t capacity) {
416
+ ABSL_SWISSTABLE_ASSERT(IsValidCapacity(capacity));
417
+ // `capacity*7/8`
418
+ if (Group::kWidth == 8 && capacity == 7) {
419
+ // x-x/8 does not work when x==7.
420
+ return 6;
421
+ }
422
+ return capacity - capacity / 8;
423
+ }
424
+
425
+ // Given `size`, "unapplies" the load factor to find how large the capacity
426
+ // should be to stay within the load factor.
427
+ //
428
+ // For size == 0, returns 0.
429
+ // For other values, returns the same as `NormalizeCapacity(size*8/7)`.
430
+ constexpr size_t SizeToCapacity(size_t size) {
431
+ if (size == 0) {
432
+ return 0;
433
+ }
434
+ // The minimum possible capacity is NormalizeCapacity(size).
435
+ // Shifting right `~size_t{}` by `leading_zeros` yields
436
+ // NormalizeCapacity(size).
437
+ int leading_zeros = absl::countl_zero(size);
438
+ constexpr size_t kLast3Bits = size_t{7} << (sizeof(size_t) * 8 - 3);
439
+ // max_size_for_next_capacity = max_load_factor * next_capacity
440
+ // = (7/8) * (~size_t{} >> leading_zeros)
441
+ // = (7/8*~size_t{}) >> leading_zeros
442
+ // = kLast3Bits >> leading_zeros
443
+ size_t max_size_for_next_capacity = kLast3Bits >> leading_zeros;
444
+ // Decrease shift if size is too big for the minimum capacity.
445
+ leading_zeros -= static_cast<int>(size > max_size_for_next_capacity);
446
+ if constexpr (Group::kWidth == 8) {
447
+ // Formula doesn't work when size==7 for 8-wide groups.
448
+ leading_zeros -= (size == 7);
449
+ }
450
+ return (~size_t{}) >> leading_zeros;
451
+ }
452
+
453
+ // The mode we store capacity in the table.
454
+ enum HashtableCapacityStorageMode {
455
+ // Capacity stored as size_t as a full number.
456
+ kCapacityByValue,
457
+ // Capacity stored as uint8_t as log2, i.e. capacity = 2^capacity_ - 1.
458
+ kCapacityByLog,
459
+ };
460
+
461
+ // The number of slots in the backing array. This is always 2^N-1 for an
462
+ // integer N.
463
+ // NOTE: this class exists to simplify experiments with different ways to store
464
+ // capacity within size.
465
+ // NOTE: we tried experimenting with compressing the capacity and storing it
466
+ // together with size_: (a) using 6 bits to store the corresponding power (N in
467
+ // 2^N-1), and (b) storing 2^N as the most significant bit of size_ and storing
468
+ // size in the low bits. Both of these experiments were regressions, presumably
469
+ // because we need capacity to do find operations.
470
+ template <HashtableCapacityStorageMode StorageMode>
471
+ class HashtableCapacityImpl {
472
+ using IntType =
473
+ std::conditional_t<StorageMode == kCapacityByValue, size_t, uint8_t>;
474
+
475
+ public:
476
+ static constexpr HashtableCapacityImpl CreateDestroyed() {
477
+ return HashtableCapacityImpl(kDestroyed);
478
+ }
479
+ static constexpr HashtableCapacityImpl CreateReentrance() {
480
+ return HashtableCapacityImpl(kReentrance);
481
+ }
482
+ static constexpr HashtableCapacityImpl CreateMovedFrom() {
483
+ return HashtableCapacityImpl(kMovedFrom);
484
+ }
485
+ static constexpr HashtableCapacityImpl CreateSelfMovedFrom() {
486
+ return HashtableCapacityImpl(kSelfMovedFrom);
487
+ }
488
+
489
+ explicit HashtableCapacityImpl(uninitialized_tag_t) {}
490
+ explicit constexpr HashtableCapacityImpl(size_t capacity)
491
+ : capacity_data_(static_cast<IntType>(
492
+ StorageMode == kCapacityByValue ? capacity
493
+ : TrailingZeros(capacity + 1))) {
494
+ ABSL_SWISSTABLE_ASSERT(capacity == 0 || IsValidCapacity(capacity));
495
+ }
496
+
497
+ // Creates capacity from the value that was returned by `ToRawData()`.
498
+ // This is needed to use bitfield for capacity.
499
+ // At least on Windows combination uint8_t and uint64_t bitfield in one struct
500
+ // is not optimized by compiler.
501
+ static HashtableCapacityImpl FromRawData(uint64_t capacity) {
502
+ auto cap = HashtableCapacityImpl(uninitialized_tag_t{});
503
+ cap.capacity_data_ = static_cast<IntType>(capacity);
504
+ return cap;
505
+ }
506
+ IntType ToRawData() const { return capacity_data_; }
507
+
508
+ constexpr bool IsValid() const {
509
+ return capacity_data_ <= kAboveMaxValidCapacity;
510
+ }
511
+
512
+ constexpr bool IsDestroyed() const { return capacity_data_ == kDestroyed; }
513
+ constexpr bool IsReentrance() const { return capacity_data_ == kReentrance; }
514
+ // Returns true if the table is moved-from including self moved-from.
515
+ constexpr bool IsMovedFrom() const { return capacity_data_ >= kMovedFrom; }
516
+ constexpr bool IsSelfMovedFrom() const {
517
+ return capacity_data_ == kSelfMovedFrom;
518
+ }
519
+
520
+ constexpr size_t capacity() const {
521
+ ABSL_SWISSTABLE_ASSERT(IsValid());
522
+ return StorageMode == kCapacityByValue ? capacity_data_
523
+ : (size_t{1} << capacity_data_) - 1;
524
+ }
525
+
526
+ constexpr bool is_small() const {
527
+ // Small tables have capacity 0 or 1. This expression is valid for both
528
+ // capacity storage modes.
529
+ // Comparing capacity_data_ directly leads to a better generated code.
530
+ // One byte comparison is used before computing the capacity in order to
531
+ // detect small tables faster for critical path.
532
+ static_assert(MaxSmallCapacity() == 1);
533
+ return capacity_data_ <= 1;
534
+ }
535
+
536
+ constexpr size_t mask(size_t value) const {
537
+ #ifdef __BMI2__
538
+ if constexpr (StorageMode == kCapacityByLog) {
539
+ if constexpr (sizeof(size_t) == 8) {
540
+ return _bzhi_u64(value, capacity_data_);
541
+ } else {
542
+ return _bzhi_u32(value, capacity_data_);
543
+ }
544
+ }
545
+ #endif // __BMI2__
546
+ return value & capacity();
547
+ }
548
+
549
+ private:
550
+ // We use these sentinel capacity values in debug mode to indicate different
551
+ // classes of bugs.
552
+ enum InvalidCapacity : IntType {
553
+ kAboveMaxValidCapacity = (std::numeric_limits<IntType>::max)() - 100,
554
+ kReentrance,
555
+ kDestroyed,
556
+
557
+ // These two must be last because we use `>= kMovedFrom` to mean moved-from.
558
+ kMovedFrom,
559
+ kSelfMovedFrom,
560
+ };
561
+
562
+ explicit constexpr HashtableCapacityImpl(InvalidCapacity capacity)
563
+ : capacity_data_(capacity) {
564
+ ABSL_SWISSTABLE_ASSERT(capacity_data_ > kAboveMaxValidCapacity);
565
+ }
566
+
567
+ // Capacity is stored as a value or as a log2 depending on `StorageMode`.
568
+ IntType capacity_data_;
569
+ };
570
+
571
+ template <HashtableCapacityStorageMode StorageMode>
572
+ class HashtableInlineDataImpl;
573
+
574
+ // Returns next per-table seed.
575
+ uint16_t NextHashTableSeed();
576
+
447
577
  // Per table hash salt. This gets mixed into H1 to randomize iteration order
448
578
  // per-table.
449
579
  // The seed is needed to ensure non-determinism of iteration order.
450
- class PerTableSeed {
580
+ template <typename StorageType>
581
+ class PerTableSeedImpl {
451
582
  public:
583
+ using IntType = StorageType;
584
+
452
585
  // The number of bits in the seed.
453
586
  // It is big enough to ensure non-determinism of iteration order.
454
587
  // We store the seed inside a uint64_t together with size and other metadata.
455
- // Using 16 bits allows us to save one `and` instruction in H1 (we use movzwl
456
- // instead of movq+and).
457
- static constexpr size_t kBitCount = 16;
588
+ // Using 8 or 16 bits allows us to save one `and` instruction in H1 (we use
589
+ // zero-extended move instead of mov+and). When absl::Hash is inlined, it can
590
+ // also have lower latency knowing that the high bits of the seed are zero.
591
+ static constexpr size_t kBitCount = sizeof(IntType) * 8;
458
592
 
459
- // Returns the seed for the table. Only the lowest kBitCount are non zero.
593
+ // We need to use a constant seed when the table is sampled so that sampled
594
+ // hashes use the same seed and can e.g. identify stuck bits accurately.
595
+ static constexpr IntType kSampledSeed = static_cast<IntType>(~IntType{0});
596
+
597
+ // Returns the seed for the table.
460
598
  size_t seed() const { return seed_; }
461
599
 
462
600
  private:
463
- friend class HashtableSize;
464
- explicit PerTableSeed(size_t seed) : seed_(seed) {}
601
+ template <HashtableCapacityStorageMode StorageMode>
602
+ friend class HashtableInlineDataImpl;
465
603
 
466
- const size_t seed_;
467
- };
604
+ explicit PerTableSeedImpl(uint64_t seed)
605
+ : seed_(static_cast<IntType>(seed)) {}
468
606
 
469
- // Returns next per-table seed.
470
- inline uint16_t NextSeed() {
471
- static_assert(PerTableSeed::kBitCount == 16);
472
- thread_local uint16_t seed =
473
- static_cast<uint16_t>(reinterpret_cast<uintptr_t>(&seed));
474
- seed += uint16_t{0xad53};
475
- return seed;
476
- }
607
+ const IntType seed_;
608
+ };
477
609
 
478
- // The size and also has additionally
610
+ // Capacity, size and also has additionally
479
611
  // 1) one bit that stores whether we have infoz.
480
- // 2) PerTableSeed::kBitCount bits for the seed.
481
- class HashtableSize {
612
+ // 2) PerTableSeed::kBitCount bits for the seed. (For SOO tables, the lowest
613
+ // bit of the seed is repurposed to track if sampling has been tried).
614
+ template <HashtableCapacityStorageMode StorageMode>
615
+ class HashtableInlineDataImpl {
482
616
  public:
483
- static constexpr size_t kSizeBitCount = 64 - PerTableSeed::kBitCount - 1;
484
-
485
- explicit HashtableSize(uninitialized_tag_t) {}
486
- explicit HashtableSize(no_seed_empty_tag_t) : data_(0) {}
487
- explicit HashtableSize(full_soo_tag_t) : data_(kSizeOneNoMetadata) {}
617
+ static constexpr HashtableCapacityStorageMode kStorageMode = StorageMode;
618
+ using PerTableSeed = PerTableSeedImpl<
619
+ std::conditional_t<StorageMode == kCapacityByValue, uint16_t, uint8_t>>;
620
+ using HashtableCapacity = HashtableCapacityImpl<StorageMode>;
621
+ static constexpr size_t kSizeBitCount =
622
+ StorageMode == kCapacityByValue
623
+ ? 64 - PerTableSeed::kBitCount - 1
624
+ : 64 - PerTableSeed::kBitCount - sizeof(HashtableCapacity) * 8 - 1;
625
+
626
+ explicit HashtableInlineDataImpl(uninitialized_tag_t) {}
627
+ explicit HashtableInlineDataImpl(HashtableCapacity capacity,
628
+ no_seed_empty_tag_t)
629
+ : capacity_internal_(capacity.ToRawData()), data_(0) {}
630
+ HashtableInlineDataImpl(HashtableCapacity capacity, full_soo_tag_t,
631
+ bool has_tried_sampling)
632
+ : capacity_internal_(capacity.ToRawData()),
633
+ data_(kSizeOneNoMetadata |
634
+ (has_tried_sampling ? kSooHasTriedSamplingMask : 0)) {}
635
+
636
+ HashtableCapacity capacity() const {
637
+ return HashtableCapacity::FromRawData(capacity_internal_);
638
+ }
639
+ bool is_small() const { return capacity().is_small(); }
640
+
641
+ void set_capacity(HashtableCapacity c) { capacity_internal_ = c.ToRawData(); }
642
+ void set_capacity(size_t c) { set_capacity(HashtableCapacity(c)); }
488
643
 
489
644
  // Returns actual size of the table.
490
645
  size_t size() const { return static_cast<size_t>(data_ >> kSizeShift); }
491
646
  void increment_size() { data_ += kSizeOneNoMetadata; }
492
647
  void increment_size(size_t size) {
493
- data_ += static_cast<uint64_t>(size) * kSizeOneNoMetadata;
648
+ data_ += static_cast<uint64_t>(size) << kSizeShift;
494
649
  }
495
650
  void decrement_size() { data_ -= kSizeOneNoMetadata; }
496
651
  // Returns true if the table is empty.
497
652
  bool empty() const { return data_ < kSizeOneNoMetadata; }
498
- // Sets the size to zero, but keeps all the metadata bits.
499
- void set_size_to_zero_keep_metadata() { data_ = data_ & kMetadataMask; }
500
653
 
501
- PerTableSeed seed() const {
502
- return PerTableSeed(static_cast<size_t>(data_) & kSeedMask);
654
+ // Returns true if an empty SOO table has already queried should_sample_soo().
655
+ bool soo_has_tried_sampling() const {
656
+ return (data_ & kSooHasTriedSamplingMask) != 0;
657
+ }
658
+
659
+ // Records that an empty SOO table has tried sampling.
660
+ void set_soo_has_tried_sampling() { data_ |= kSooHasTriedSamplingMask; }
661
+
662
+ // Sets the size, but keeps all the metadata bits.
663
+ void set_size(size_t size) {
664
+ data_ =
665
+ (data_ & kMetadataMask) | (static_cast<uint64_t>(size) << kSizeShift);
503
666
  }
504
667
 
668
+ PerTableSeed seed() const { return PerTableSeed(data_ & kSeedMask); }
669
+
505
670
  void generate_new_seed() {
506
- data_ = (data_ & ~kSeedMask) ^ uint64_t{NextSeed()};
671
+ set_seed(static_cast<typename PerTableSeed::IntType>(NextHashTableSeed()));
672
+ }
673
+
674
+ // We need to use a constant seed when the table is sampled so that sampled
675
+ // hashes use the same seed and can e.g. identify stuck bits accurately.
676
+ void set_sampled_seed() { set_seed(PerTableSeed::kSampledSeed); }
677
+
678
+ bool is_sampled_seed() const {
679
+ return seed().seed() == PerTableSeed::kSampledSeed;
507
680
  }
508
681
 
509
682
  // Returns true if the table has infoz.
@@ -517,25 +690,59 @@ class HashtableSize {
517
690
  void set_no_seed_for_testing() { data_ &= ~kSeedMask; }
518
691
 
519
692
  private:
520
- static constexpr size_t kSizeShift = 64 - kSizeBitCount;
693
+ // Bit layout of `data_` from MSB to LSB:
694
+ // (47 bits) : size
695
+ // (1 bit) : has_infoz
696
+ // (16 or 8 bits) : seed
697
+ // We don't split these components of `data_` into separate bit field elements
698
+ // because we get worse generated code that way.
699
+ static constexpr size_t kDataBitCount =
700
+ PerTableSeed::kBitCount + 1 + kSizeBitCount;
701
+ static constexpr size_t kSizeShift = kDataBitCount - kSizeBitCount;
521
702
  static constexpr uint64_t kSizeOneNoMetadata = uint64_t{1} << kSizeShift;
522
703
  static constexpr uint64_t kMetadataMask = kSizeOneNoMetadata - 1;
523
704
  static constexpr uint64_t kSeedMask =
524
705
  (uint64_t{1} << PerTableSeed::kBitCount) - 1;
525
706
  // The next bit after the seed.
526
707
  static constexpr uint64_t kHasInfozMask = kSeedMask + 1;
527
- uint64_t data_;
708
+ // For SOO tables, the seed is unused, and bit 0 is repurposed to track
709
+ // whether the table has already queried should_sample_soo().
710
+ static constexpr uint64_t kSooHasTriedSamplingMask = 1;
711
+
712
+ void set_seed(typename PerTableSeed::IntType seed) {
713
+ data_ = (data_ & ~kSeedMask) | seed;
714
+ }
715
+
716
+ uint64_t capacity_internal_ : sizeof(HashtableCapacity) * 8;
717
+ uint64_t data_ : kDataBitCount;
528
718
  };
529
719
 
530
- // Extracts the H1 portion of a hash: 57 bits mixed with a per-table seed.
531
- inline size_t H1(size_t hash, PerTableSeed seed) {
532
- return (hash >> 7) ^ seed.seed();
533
- }
720
+ static_assert(
721
+ sizeof(HashtableInlineDataImpl<kCapacityByValue>::HashtableCapacity) ==
722
+ sizeof(size_t));
723
+ // NOTE: some platforms have this size to be equal to 12 for two reasons:
724
+ // 1) alignof(uint64_t) == 4.
725
+ // 2) sizeof(size_t) == sizeof(HashtableCapacityImpl<kCapacityByValue>) == 4.
726
+ static_assert(sizeof(HashtableInlineDataImpl<kCapacityByValue>) <= 16);
727
+ static_assert(
728
+ sizeof(HashtableInlineDataImpl<kCapacityByLog>::HashtableCapacity) == 1);
729
+ static_assert(sizeof(HashtableInlineDataImpl<kCapacityByLog>) == 8);
730
+
731
+ #ifndef ABSL_SWISSTABLE_INTERNAL_ENABLE_CAPACITY_BY_VALUE
732
+ using HashtableInlineData = HashtableInlineDataImpl<kCapacityByLog>;
733
+ #else
734
+ using HashtableInlineData = HashtableInlineDataImpl<kCapacityByValue>;
735
+ #endif // ABSL_SWISSTABLE_INTERNAL_ENABLE_CAPACITY_BY_VALUE
736
+ using PerTableSeed = HashtableInlineData::PerTableSeed;
737
+ using HashtableCapacity = HashtableInlineData::HashtableCapacity;
738
+
739
+ // H1 is just the low bits of the hash.
740
+ inline size_t H1(size_t hash) { return hash; }
534
741
 
535
- // Extracts the H2 portion of a hash: the 7 bits not used for H1.
742
+ // Extracts the H2 portion of a hash: the 7 most significant bits.
536
743
  //
537
744
  // These are used as an occupied control byte.
538
- inline h2_t H2(size_t hash) { return hash & 0x7F; }
745
+ inline h2_t H2(size_t hash) { return hash >> (sizeof(size_t) * 8 - 7); }
539
746
 
540
747
  // When there is an insertion with no reserved growth, we rehash with
541
748
  // probability `min(1, RehashProbabilityConstant() / capacity())`. Using a
@@ -571,11 +778,9 @@ class CommonFieldsGenerationInfoEnabled {
571
778
  // references. We rehash on the first insertion after reserved_growth_ reaches
572
779
  // 0 after a call to reserve. We also do a rehash with low probability
573
780
  // whenever reserved_growth_ is zero.
574
- bool should_rehash_for_bug_detection_on_insert(PerTableSeed seed,
575
- size_t capacity) const;
781
+ bool should_rehash_for_bug_detection_on_insert(size_t capacity) const;
576
782
  // Similar to above, except that we don't depend on reserved_growth_.
577
- bool should_rehash_for_bug_detection_on_move(PerTableSeed seed,
578
- size_t capacity) const;
783
+ bool should_rehash_for_bug_detection_on_move(size_t capacity) const;
579
784
  void maybe_increment_generation_on_insert() {
580
785
  if (reserved_growth_ == kReservedGrowthJustRanOut) reserved_growth_ = 0;
581
786
 
@@ -628,12 +833,8 @@ class CommonFieldsGenerationInfoDisabled {
628
833
  CommonFieldsGenerationInfoDisabled& operator=(
629
834
  CommonFieldsGenerationInfoDisabled&&) = default;
630
835
 
631
- bool should_rehash_for_bug_detection_on_insert(PerTableSeed, size_t) const {
632
- return false;
633
- }
634
- bool should_rehash_for_bug_detection_on_move(PerTableSeed, size_t) const {
635
- return false;
636
- }
836
+ bool should_rehash_for_bug_detection_on_insert(size_t) const { return false; }
837
+ bool should_rehash_for_bug_detection_on_move(size_t) const { return false; }
637
838
  void maybe_increment_generation_on_insert() {}
638
839
  void increment_generation() {}
639
840
  void reset_reserved_growth(size_t, size_t) {}
@@ -776,11 +977,6 @@ class GrowthInfo {
776
977
  static_assert(sizeof(GrowthInfo) == sizeof(size_t), "");
777
978
  static_assert(alignof(GrowthInfo) == alignof(size_t), "");
778
979
 
779
- // Returns whether `n` is a valid capacity (i.e., number of slots).
780
- //
781
- // A valid capacity is a non-zero integer `2^m - 1`.
782
- constexpr bool IsValidCapacity(size_t n) { return ((n + 1) & n) == 0 && n > 0; }
783
-
784
980
  // Returns the number of "cloned control bytes".
785
981
  //
786
982
  // This is the number of control bytes that are present both at the beginning
@@ -790,13 +986,23 @@ constexpr size_t NumClonedBytes() { return Group::kWidth - 1; }
790
986
 
791
987
  // Returns the number of control bytes including cloned.
792
988
  constexpr size_t NumControlBytes(size_t capacity) {
793
- return capacity + 1 + NumClonedBytes();
989
+ return IsSmallCapacity(capacity) ? 0 : capacity + 1 + NumClonedBytes();
990
+ }
991
+
992
+ // Returns whether table with the given capacity has a GrowthInfo.
993
+ constexpr bool HasGrowthInfoForCapacity(size_t capacity) {
994
+ return !IsSmallCapacity(capacity);
794
995
  }
795
996
 
796
997
  // Computes the offset from the start of the backing allocation of control.
797
998
  // infoz and growth_info are stored at the beginning of the backing array.
798
- constexpr size_t ControlOffset(bool has_infoz) {
799
- return (has_infoz ? sizeof(HashtablezInfoHandle) : 0) + sizeof(GrowthInfo);
999
+ constexpr size_t ControlOffset(bool has_infoz, bool has_growth_info) {
1000
+ if (ABSL_PREDICT_FALSE(has_infoz)) {
1001
+ // We always allocate GrowthInfo for sampled tables to allow branchless
1002
+ // access to infoz pointer.
1003
+ return sizeof(HashtablezInfoHandle) + sizeof(GrowthInfo);
1004
+ }
1005
+ return has_growth_info ? sizeof(GrowthInfo) : 0;
800
1006
  }
801
1007
 
802
1008
  // Returns the offset of the next item after `offset` that is aligned to `align`
@@ -810,7 +1016,8 @@ class RawHashSetLayout {
810
1016
  public:
811
1017
  explicit RawHashSetLayout(size_t capacity, size_t slot_size,
812
1018
  size_t slot_align, bool has_infoz)
813
- : control_offset_(ControlOffset(has_infoz)),
1019
+ : control_offset_(
1020
+ ControlOffset(has_infoz, HasGrowthInfoForCapacity(capacity))),
814
1021
  generation_offset_(control_offset_ + NumControlBytes(capacity)),
815
1022
  slot_offset_(
816
1023
  AlignUpTo(generation_offset_ + NumGenerationBytes(), slot_align)),
@@ -846,50 +1053,30 @@ class RawHashSetLayout {
846
1053
 
847
1054
  struct HashtableFreeFunctionsAccess;
848
1055
 
849
- // Suppress erroneous uninitialized memory errors on GCC. For example, GCC
850
- // thinks that the call to slot_array() in find_or_prepare_insert() is reading
851
- // uninitialized memory, but slot_array is only called there when the table is
852
- // non-empty and this memory is initialized when the table is non-empty.
853
- #if !defined(__clang__) && defined(__GNUC__)
854
- #define ABSL_SWISSTABLE_IGNORE_UNINITIALIZED(x) \
855
- _Pragma("GCC diagnostic push") \
856
- _Pragma("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") \
857
- _Pragma("GCC diagnostic ignored \"-Wuninitialized\"") x; \
858
- _Pragma("GCC diagnostic pop")
859
- #define ABSL_SWISSTABLE_IGNORE_UNINITIALIZED_RETURN(x) \
860
- ABSL_SWISSTABLE_IGNORE_UNINITIALIZED(return x)
861
- #else
862
- #define ABSL_SWISSTABLE_IGNORE_UNINITIALIZED(x) x
863
- #define ABSL_SWISSTABLE_IGNORE_UNINITIALIZED_RETURN(x) return x
864
- #endif
865
-
866
1056
  // This allows us to work around an uninitialized memory warning when
867
1057
  // constructing begin() iterators in empty hashtables.
1058
+ template <typename T>
868
1059
  union MaybeInitializedPtr {
869
- void* get() const { ABSL_SWISSTABLE_IGNORE_UNINITIALIZED_RETURN(p); }
870
- void set(void* ptr) { p = ptr; }
1060
+ T* get() const { ABSL_SWISSTABLE_IGNORE_UNINITIALIZED_RETURN(p); }
1061
+ void set(T* ptr) { p = ptr; }
871
1062
 
872
- void* p;
1063
+ T* p;
873
1064
  };
874
1065
 
875
1066
  struct HeapPtrs {
876
- explicit HeapPtrs(uninitialized_tag_t) {}
877
- explicit HeapPtrs(ctrl_t* c) : control(c) {}
878
-
879
1067
  // The control bytes (and, also, a pointer near to the base of the backing
880
1068
  // array).
881
1069
  //
882
- // This contains `capacity + 1 + NumClonedBytes()` entries, even
883
- // when the table is empty (hence EmptyGroup).
1070
+ // This contains `capacity + 1 + NumClonedBytes()` entries.
884
1071
  //
885
1072
  // Note that growth_info is stored immediately before this pointer.
886
- // May be uninitialized for SOO tables.
887
- ctrl_t* control;
1073
+ // May be uninitialized for small tables.
1074
+ MaybeInitializedPtr<ctrl_t> control;
888
1075
 
889
1076
  // The beginning of the slots, located at `SlotOffset()` bytes after
890
1077
  // `control`. May be uninitialized for empty tables.
891
1078
  // Note: we can't use `slots` because Qt defines "slots" as a macro.
892
- MaybeInitializedPtr slot_array;
1079
+ MaybeInitializedPtr<void> slot_array;
893
1080
  };
894
1081
 
895
1082
  // Returns the maximum size of the SOO slot.
@@ -898,19 +1085,16 @@ constexpr size_t MaxSooSlotSize() { return sizeof(HeapPtrs); }
898
1085
  // Manages the backing array pointers or the SOO slot. When raw_hash_set::is_soo
899
1086
  // is true, the SOO slot is stored in `soo_data`. Otherwise, we use `heap`.
900
1087
  union HeapOrSoo {
901
- explicit HeapOrSoo(uninitialized_tag_t) : heap(uninitialized_tag_t{}) {}
902
- explicit HeapOrSoo(ctrl_t* c) : heap(c) {}
903
-
904
- ctrl_t*& control() {
1088
+ MaybeInitializedPtr<ctrl_t>& control() {
905
1089
  ABSL_SWISSTABLE_IGNORE_UNINITIALIZED_RETURN(heap.control);
906
1090
  }
907
- ctrl_t* control() const {
1091
+ MaybeInitializedPtr<ctrl_t> control() const {
908
1092
  ABSL_SWISSTABLE_IGNORE_UNINITIALIZED_RETURN(heap.control);
909
1093
  }
910
- MaybeInitializedPtr& slot_array() {
1094
+ MaybeInitializedPtr<void>& slot_array() {
911
1095
  ABSL_SWISSTABLE_IGNORE_UNINITIALIZED_RETURN(heap.slot_array);
912
1096
  }
913
- MaybeInitializedPtr slot_array() const {
1097
+ MaybeInitializedPtr<void> slot_array() const {
914
1098
  ABSL_SWISSTABLE_IGNORE_UNINITIALIZED_RETURN(heap.slot_array);
915
1099
  }
916
1100
  void* get_soo_data() {
@@ -939,20 +1123,15 @@ inline GrowthInfo& GetGrowthInfoFromControl(ctrl_t* control) {
939
1123
  class CommonFields : public CommonFieldsGenerationInfo {
940
1124
  public:
941
1125
  explicit CommonFields(soo_tag_t)
942
- : capacity_(SooCapacity()),
943
- size_(no_seed_empty_tag_t{}),
944
- heap_or_soo_(uninitialized_tag_t{}) {}
945
- explicit CommonFields(full_soo_tag_t)
946
- : capacity_(SooCapacity()),
947
- size_(full_soo_tag_t{}),
948
- heap_or_soo_(uninitialized_tag_t{}) {}
1126
+ : inline_data_(HashtableCapacity(SooCapacity()), no_seed_empty_tag_t{}) {}
1127
+ explicit CommonFields(full_soo_tag_t, bool has_tried_sampling)
1128
+ : inline_data_(HashtableCapacity(SooCapacity()), full_soo_tag_t{},
1129
+ has_tried_sampling) {}
949
1130
  explicit CommonFields(non_soo_tag_t)
950
- : capacity_(0),
951
- size_(no_seed_empty_tag_t{}),
952
- heap_or_soo_(EmptyGroup()) {}
1131
+ : inline_data_(HashtableCapacity(0), no_seed_empty_tag_t{}) {}
953
1132
  // For use in swapping.
954
1133
  explicit CommonFields(uninitialized_tag_t)
955
- : size_(uninitialized_tag_t{}), heap_or_soo_(uninitialized_tag_t{}) {}
1134
+ : inline_data_(uninitialized_tag_t{}) {}
956
1135
 
957
1136
  // Not copyable
958
1137
  CommonFields(const CommonFields&) = delete;
@@ -960,10 +1139,7 @@ class CommonFields : public CommonFieldsGenerationInfo {
960
1139
 
961
1140
  // Copy with guarantee that it is not SOO.
962
1141
  CommonFields(non_soo_tag_t, const CommonFields& that)
963
- : capacity_(that.capacity_),
964
- size_(that.size_),
965
- heap_or_soo_(that.heap_or_soo_) {
966
- }
1142
+ : inline_data_(that.inline_data_), heap_or_soo_(that.heap_or_soo_) {}
967
1143
 
968
1144
  // Movable
969
1145
  CommonFields(CommonFields&& that) = default;
@@ -979,76 +1155,91 @@ class CommonFields : public CommonFieldsGenerationInfo {
979
1155
  const void* soo_data() const { return heap_or_soo_.get_soo_data(); }
980
1156
  void* soo_data() { return heap_or_soo_.get_soo_data(); }
981
1157
 
982
- ctrl_t* control() const { return heap_or_soo_.control(); }
983
-
984
- // When we set the control bytes, we also often want to generate a new seed.
985
- // So we bundle these two operations together to make sure we don't forget to
986
- // generate a new seed.
987
- // The table will be invalidated if
988
- // `kGenerateSeed && !empty() && !is_single_group(capacity())` because H1 is
989
- // being changed. In such cases, we will need to rehash the table.
990
- template <bool kGenerateSeed>
991
- void set_control(ctrl_t* c) {
992
- heap_or_soo_.control() = c;
993
- if constexpr (kGenerateSeed) {
994
- generate_new_seed();
995
- }
996
- }
997
- void* backing_array_start() const {
998
- // growth_info (and maybe infoz) is stored before control bytes.
999
- ABSL_SWISSTABLE_ASSERT(
1000
- reinterpret_cast<uintptr_t>(control()) % alignof(size_t) == 0);
1001
- return control() - ControlOffset(has_infoz());
1158
+ ctrl_t* control() const {
1159
+ ABSL_SWISSTABLE_ASSERT(capacity() > 0);
1160
+ // Assume that the control bytes don't alias `this`.
1161
+ ctrl_t* ctrl = heap_or_soo_.control().get();
1162
+ [[maybe_unused]] size_t num_control_bytes = NumControlBytes(capacity());
1163
+ ABSL_ASSUME(reinterpret_cast<uintptr_t>(ctrl + num_control_bytes) <=
1164
+ reinterpret_cast<uintptr_t>(this) ||
1165
+ reinterpret_cast<uintptr_t>(this + 1) <=
1166
+ reinterpret_cast<uintptr_t>(ctrl));
1167
+ ABSL_SWISSTABLE_IGNORE_UNINITIALIZED_RETURN(ctrl);
1002
1168
  }
1003
1169
 
1170
+ void set_control(ctrl_t* c) { heap_or_soo_.control().set(c); }
1171
+
1004
1172
  // Note: we can't use slots() because Qt defines "slots" as a macro.
1005
1173
  void* slot_array() const { return heap_or_soo_.slot_array().get(); }
1006
- MaybeInitializedPtr slots_union() const { return heap_or_soo_.slot_array(); }
1174
+ MaybeInitializedPtr<void> slots_union() const {
1175
+ return heap_or_soo_.slot_array();
1176
+ }
1007
1177
  void set_slots(void* s) { heap_or_soo_.slot_array().set(s); }
1008
1178
 
1009
1179
  // The number of filled slots.
1010
- size_t size() const { return size_.size(); }
1180
+ size_t size() const { return inline_data_.size(); }
1011
1181
  // Sets the size to zero, but keeps hashinfoz bit and seed.
1012
- void set_size_to_zero() { size_.set_size_to_zero_keep_metadata(); }
1182
+ void set_size_to_zero() { inline_data_.set_size(0); }
1013
1183
  void set_empty_soo() {
1014
1184
  AssertInSooMode();
1015
- size_ = HashtableSize(no_seed_empty_tag_t{});
1185
+ inline_data_.set_size(0);
1016
1186
  }
1017
1187
  void set_full_soo() {
1018
1188
  AssertInSooMode();
1019
- size_ = HashtableSize(full_soo_tag_t{});
1189
+ inline_data_.set_size(1);
1020
1190
  }
1021
1191
  void increment_size() {
1022
1192
  ABSL_SWISSTABLE_ASSERT(size() < capacity());
1023
- size_.increment_size();
1193
+ inline_data_.increment_size();
1024
1194
  }
1025
1195
  void increment_size(size_t n) {
1026
1196
  ABSL_SWISSTABLE_ASSERT(size() + n <= capacity());
1027
- size_.increment_size(n);
1197
+ inline_data_.increment_size(n);
1028
1198
  }
1029
1199
  void decrement_size() {
1030
1200
  ABSL_SWISSTABLE_ASSERT(!empty());
1031
- size_.decrement_size();
1201
+ inline_data_.decrement_size();
1202
+ }
1203
+ bool empty() const { return inline_data_.empty(); }
1204
+ void set_soo_has_tried_sampling() {
1205
+ inline_data_.set_soo_has_tried_sampling();
1206
+ }
1207
+ bool soo_has_tried_sampling() const {
1208
+ return inline_data_.soo_has_tried_sampling();
1209
+ }
1210
+
1211
+ // The seed used for the hash function.
1212
+ PerTableSeed seed() const { return inline_data_.seed(); }
1213
+ // Generates a new seed the hash function.
1214
+ // The table will be invalidated if `!empty()` because hash is being changed.
1215
+ // In such cases, we will need to rehash the table.
1216
+ void generate_new_seed(bool has_infoz) {
1217
+ // Note: we can't use has_infoz() here because we set has_infoz later than
1218
+ // we generate the seed.
1219
+ if (ABSL_PREDICT_FALSE(has_infoz)) {
1220
+ inline_data_.set_sampled_seed();
1221
+ return;
1222
+ }
1223
+ inline_data_.generate_new_seed();
1032
1224
  }
1033
- bool empty() const { return size_.empty(); }
1034
-
1035
- // The seed used for the H1 part of the hash function.
1036
- PerTableSeed seed() const { return size_.seed(); }
1037
- // Generates a new seed for the H1 part of the hash function.
1038
- // The table will be invalidated if
1039
- // `kGenerateSeed && !empty() && !is_single_group(capacity())` because H1 is
1040
- // being changed. In such cases, we will need to rehash the table.
1041
- void generate_new_seed() { size_.generate_new_seed(); }
1042
- void set_no_seed_for_testing() { size_.set_no_seed_for_testing(); }
1225
+ void set_no_seed_for_testing() { inline_data_.set_no_seed_for_testing(); }
1043
1226
 
1044
- // The total number of available slots.
1045
- size_t capacity() const { return capacity_; }
1227
+ HashtableCapacity capacity_impl() const {
1228
+ HashtableCapacity cap = inline_data_.capacity();
1229
+ ABSL_SWISSTABLE_ASSERT(cap.IsValid());
1230
+ return cap;
1231
+ }
1232
+ size_t capacity() const { return capacity_impl().capacity(); }
1233
+ // We have a separate alias for callsites in which the capacity may be
1234
+ // invalid.
1235
+ HashtableCapacity maybe_invalid_capacity() const {
1236
+ return inline_data_.capacity();
1237
+ }
1238
+ void set_capacity(HashtableCapacity c) { inline_data_.set_capacity(c); }
1046
1239
  void set_capacity(size_t c) {
1047
- // We allow setting above the max valid capacity for debugging purposes.
1048
- ABSL_SWISSTABLE_ASSERT(c == 0 || IsValidCapacity(c) ||
1049
- c > kAboveMaxValidCapacity);
1050
- capacity_ = c;
1240
+ set_capacity(HashtableCapacity(c));
1051
1241
  }
1242
+ bool is_small() const { return inline_data_.is_small(); }
1052
1243
 
1053
1244
  // The number of slots we can still fill without needing to rehash.
1054
1245
  // This is stored in the heap allocation before the control bytes.
@@ -1057,23 +1248,35 @@ class CommonFields : public CommonFieldsGenerationInfo {
1057
1248
  size_t growth_left() const { return growth_info().GetGrowthLeft(); }
1058
1249
 
1059
1250
  GrowthInfo& growth_info() {
1251
+ ABSL_SWISSTABLE_ASSERT(HasGrowthInfoForCapacity(capacity()));
1060
1252
  return GetGrowthInfoFromControl(control());
1061
1253
  }
1062
1254
  GrowthInfo growth_info() const {
1063
1255
  return const_cast<CommonFields*>(this)->growth_info();
1064
1256
  }
1065
1257
 
1066
- bool has_infoz() const { return size_.has_infoz(); }
1067
- void set_has_infoz() { size_.set_has_infoz(); }
1258
+ bool has_infoz() const { return inline_data_.has_infoz(); }
1259
+ void set_has_infoz() {
1260
+ ABSL_SWISSTABLE_ASSERT(inline_data_.is_sampled_seed());
1261
+ inline_data_.set_has_infoz();
1262
+ }
1263
+
1264
+ HashtablezInfoHandle* infoz_ptr() const {
1265
+ // growth_info is stored before control bytes.
1266
+ ABSL_SWISSTABLE_ASSERT(
1267
+ reinterpret_cast<uintptr_t>(control()) % alignof(size_t) == 0);
1268
+ ABSL_SWISSTABLE_ASSERT(has_infoz());
1269
+ return reinterpret_cast<HashtablezInfoHandle*>(
1270
+ control() - ControlOffset(/*has_infoz=*/true,
1271
+ HasGrowthInfoForCapacity(capacity())));
1272
+ }
1068
1273
 
1069
1274
  HashtablezInfoHandle infoz() {
1070
- return has_infoz()
1071
- ? *reinterpret_cast<HashtablezInfoHandle*>(backing_array_start())
1072
- : HashtablezInfoHandle();
1275
+ return has_infoz() ? *infoz_ptr() : HashtablezInfoHandle();
1073
1276
  }
1074
1277
  void set_infoz(HashtablezInfoHandle infoz) {
1075
1278
  ABSL_SWISSTABLE_ASSERT(has_infoz());
1076
- *reinterpret_cast<HashtablezInfoHandle*>(backing_array_start()) = infoz;
1279
+ *infoz_ptr() = infoz;
1077
1280
  }
1078
1281
 
1079
1282
  bool should_rehash_for_bug_detection_on_insert() const {
@@ -1084,11 +1287,11 @@ class CommonFields : public CommonFieldsGenerationInfo {
1084
1287
  // will end up rehashing anyways.
1085
1288
  if (growth_left() == 0) return false;
1086
1289
  return CommonFieldsGenerationInfo::
1087
- should_rehash_for_bug_detection_on_insert(seed(), capacity());
1290
+ should_rehash_for_bug_detection_on_insert(capacity());
1088
1291
  }
1089
1292
  bool should_rehash_for_bug_detection_on_move() const {
1090
1293
  return CommonFieldsGenerationInfo::should_rehash_for_bug_detection_on_move(
1091
- seed(), capacity());
1294
+ capacity());
1092
1295
  }
1093
1296
  void reset_reserved_growth(size_t reservation) {
1094
1297
  CommonFieldsGenerationInfo::reset_reserved_growth(reservation, size());
@@ -1104,8 +1307,7 @@ class CommonFields : public CommonFieldsGenerationInfo {
1104
1307
  void move_non_heap_or_soo_fields(CommonFields& that) {
1105
1308
  static_cast<CommonFieldsGenerationInfo&>(*this) =
1106
1309
  std::move(static_cast<CommonFieldsGenerationInfo&>(that));
1107
- capacity_ = that.capacity_;
1108
- size_ = that.size_;
1310
+ inline_data_ = that.inline_data_;
1109
1311
  }
1110
1312
 
1111
1313
  // Returns the number of control bytes set to kDeleted. For testing only.
@@ -1122,8 +1324,8 @@ class CommonFields : public CommonFieldsGenerationInfo {
1122
1324
  f();
1123
1325
  return;
1124
1326
  #endif
1125
- const size_t cap = capacity();
1126
- set_capacity(InvalidCapacity::kReentrance);
1327
+ const HashtableCapacity cap = maybe_invalid_capacity();
1328
+ set_capacity(HashtableCapacity::CreateReentrance());
1127
1329
  f();
1128
1330
  set_capacity(cap);
1129
1331
  }
@@ -1142,38 +1344,18 @@ class CommonFields : public CommonFieldsGenerationInfo {
1142
1344
  ABSL_SWISSTABLE_ASSERT(!has_infoz());
1143
1345
  }
1144
1346
 
1145
- // The number of slots in the backing array. This is always 2^N-1 for an
1146
- // integer N. NOTE: we tried experimenting with compressing the capacity and
1147
- // storing it together with size_: (a) using 6 bits to store the corresponding
1148
- // power (N in 2^N-1), and (b) storing 2^N as the most significant bit of
1149
- // size_ and storing size in the low bits. Both of these experiments were
1150
- // regressions, presumably because we need capacity to do find operations.
1151
- size_t capacity_;
1152
-
1153
1347
  // TODO(b/289225379): we could put size_ into HeapOrSoo and make capacity_
1154
1348
  // encode the size in SOO case. We would be making size()/capacity() more
1155
1349
  // expensive in order to have more SOO space.
1156
- HashtableSize size_;
1350
+ HashtableInlineData inline_data_;
1157
1351
 
1158
1352
  // Either the control/slots pointers or the SOO slot.
1159
1353
  HeapOrSoo heap_or_soo_;
1160
1354
  };
1161
1355
 
1162
- template <class Policy, class Hash, class Eq, class Alloc>
1356
+ template <class Policy, class... Params>
1163
1357
  class raw_hash_set;
1164
1358
 
1165
- // Returns the next valid capacity after `n`.
1166
- constexpr size_t NextCapacity(size_t n) {
1167
- ABSL_SWISSTABLE_ASSERT(IsValidCapacity(n) || n == 0);
1168
- return n * 2 + 1;
1169
- }
1170
-
1171
- // Returns the previous valid capacity before `n`.
1172
- constexpr size_t PreviousCapacity(size_t n) {
1173
- ABSL_SWISSTABLE_ASSERT(IsValidCapacity(n));
1174
- return n / 2;
1175
- }
1176
-
1177
1359
  // Applies the following mapping to every byte in the control array:
1178
1360
  // * kDeleted -> kEmpty
1179
1361
  // * kEmpty -> kEmpty
@@ -1184,55 +1366,6 @@ constexpr size_t PreviousCapacity(size_t n) {
1184
1366
  // ctrl[i] != ctrl_t::kSentinel for all i < capacity
1185
1367
  void ConvertDeletedToEmptyAndFullToDeleted(ctrl_t* ctrl, size_t capacity);
1186
1368
 
1187
- // Converts `n` into the next valid capacity, per `IsValidCapacity`.
1188
- constexpr size_t NormalizeCapacity(size_t n) {
1189
- return n ? ~size_t{} >> countl_zero(n) : 1;
1190
- }
1191
-
1192
- // General notes on capacity/growth methods below:
1193
- // - We use 7/8th as maximum load factor. For 16-wide groups, that gives an
1194
- // average of two empty slots per group.
1195
- // - For (capacity+1) >= Group::kWidth, growth is 7/8*capacity.
1196
- // - For (capacity+1) < Group::kWidth, growth == capacity. In this case, we
1197
- // never need to probe (the whole table fits in one group) so we don't need a
1198
- // load factor less than 1.
1199
-
1200
- // Given `capacity`, applies the load factor; i.e., it returns the maximum
1201
- // number of values we should put into the table before a resizing rehash.
1202
- constexpr size_t CapacityToGrowth(size_t capacity) {
1203
- ABSL_SWISSTABLE_ASSERT(IsValidCapacity(capacity));
1204
- // `capacity*7/8`
1205
- if (Group::kWidth == 8 && capacity == 7) {
1206
- // x-x/8 does not work when x==7.
1207
- return 6;
1208
- }
1209
- return capacity - capacity / 8;
1210
- }
1211
-
1212
- // Given `size`, "unapplies" the load factor to find how large the capacity
1213
- // should be to stay within the load factor.
1214
- //
1215
- // For size == 0, returns 0.
1216
- // For other values, returns the same as `NormalizeCapacity(size*8/7)`.
1217
- constexpr size_t SizeToCapacity(size_t size) {
1218
- if (size == 0) {
1219
- return 0;
1220
- }
1221
- // The minimum possible capacity is NormalizeCapacity(size).
1222
- // Shifting right `~size_t{}` by `leading_zeros` yields
1223
- // NormalizeCapacity(size).
1224
- int leading_zeros = absl::countl_zero(size);
1225
- constexpr size_t kLast3Bits = size_t{7} << (sizeof(size_t) * 8 - 3);
1226
- size_t max_size_for_next_capacity = kLast3Bits >> leading_zeros;
1227
- // Decrease shift if size is too big for the minimum capacity.
1228
- leading_zeros -= static_cast<int>(size > max_size_for_next_capacity);
1229
- if constexpr (Group::kWidth == 8) {
1230
- // Formula doesn't work when size==7 for 8-wide groups.
1231
- leading_zeros -= (size == 7);
1232
- }
1233
- return (~size_t{}) >> leading_zeros;
1234
- }
1235
-
1236
1369
  template <class InputIter>
1237
1370
  size_t SelectBucketCountForIterRange(InputIter first, InputIter last,
1238
1371
  size_t bucket_count) {
@@ -1255,6 +1388,26 @@ constexpr bool SwisstableDebugEnabled() {
1255
1388
  #endif
1256
1389
  }
1257
1390
 
1391
+ // Dereferences `ptr`. The function is named in order to provide a helpful error
1392
+ // message when users see crashing stack traces. Note that this function is not
1393
+ // guaranteed to crash when `ptr` is invalid if sanitizer mode is not enabled.
1394
+ template <typename T>
1395
+ T CrashIfIteratorIsInvalid(const T* ptr) {
1396
+ // If the following line(s) crash, then it's likely that `ptr` is from a
1397
+ // backing array that has been deallocated. If you see a crash here, it likely
1398
+ // means that you are comparing an invalid iterator from a table that has
1399
+ // rehashed, moved, or been destroyed. In such cases, it is often helpful to
1400
+ // reproduce the issue with --config=asan and (assuming there's a crash here)
1401
+ // examine the corresponding deallocation stack trace.
1402
+ T ret = *ptr;
1403
+ // Force a read with inline asm to make sure that a crash happens here, rather
1404
+ // than later when the value is used.
1405
+ #ifdef __clang__
1406
+ asm("" : "+r"(ret));
1407
+ #endif
1408
+ return ret;
1409
+ }
1410
+
1258
1411
  inline void AssertIsFull(const ctrl_t* ctrl, GenerationType generation,
1259
1412
  const GenerationType* generation_ptr,
1260
1413
  const char* operation) {
@@ -1267,25 +1420,26 @@ inline void AssertIsFull(const ctrl_t* ctrl, GenerationType generation,
1267
1420
  if (ABSL_PREDICT_FALSE(ctrl == nullptr)) {
1268
1421
  ABSL_RAW_LOG(FATAL, "%s called on end() iterator.", operation);
1269
1422
  }
1270
- if (ABSL_PREDICT_FALSE(ctrl == EmptyGroup())) {
1423
+ if (ABSL_PREDICT_FALSE(ctrl == DefaultIterControl())) {
1271
1424
  ABSL_RAW_LOG(FATAL, "%s called on default-constructed iterator.",
1272
1425
  operation);
1273
1426
  }
1274
1427
  if (SwisstableGenerationsEnabled()) {
1275
- if (ABSL_PREDICT_FALSE(generation != *generation_ptr)) {
1428
+ if (ABSL_PREDICT_FALSE(generation !=
1429
+ CrashIfIteratorIsInvalid(generation_ptr))) {
1276
1430
  ABSL_RAW_LOG(FATAL,
1277
1431
  "%s called on invalid iterator. The table could have "
1278
1432
  "rehashed or moved since this iterator was initialized.",
1279
1433
  operation);
1280
1434
  }
1281
- if (ABSL_PREDICT_FALSE(!IsFull(*ctrl))) {
1435
+ if (ABSL_PREDICT_FALSE(!IsFull(CrashIfIteratorIsInvalid(ctrl)))) {
1282
1436
  ABSL_RAW_LOG(
1283
1437
  FATAL,
1284
1438
  "%s called on invalid iterator. The element was likely erased.",
1285
1439
  operation);
1286
1440
  }
1287
1441
  } else {
1288
- if (ABSL_PREDICT_FALSE(!IsFull(*ctrl))) {
1442
+ if (ABSL_PREDICT_FALSE(!IsFull(CrashIfIteratorIsInvalid(ctrl)))) {
1289
1443
  ABSL_RAW_LOG(
1290
1444
  FATAL,
1291
1445
  "%s called on invalid iterator. The element might have been erased "
@@ -1302,12 +1456,19 @@ inline void AssertIsValidForComparison(const ctrl_t* ctrl,
1302
1456
  const GenerationType* generation_ptr) {
1303
1457
  if (!SwisstableDebugEnabled()) return;
1304
1458
  const bool ctrl_is_valid_for_comparison =
1305
- ctrl == nullptr || ctrl == EmptyGroup() || IsFull(*ctrl);
1459
+ ctrl == nullptr || ctrl == DefaultIterControl() ||
1460
+ IsFull(CrashIfIteratorIsInvalid(ctrl));
1306
1461
  if (SwisstableGenerationsEnabled()) {
1307
- if (ABSL_PREDICT_FALSE(generation != *generation_ptr)) {
1308
- ABSL_RAW_LOG(FATAL,
1309
- "Invalid iterator comparison. The table could have rehashed "
1310
- "or moved since this iterator was initialized.");
1462
+ if (ABSL_PREDICT_FALSE(generation !=
1463
+ CrashIfIteratorIsInvalid(generation_ptr))) {
1464
+ // Note: in the case of a rehash, we would expect to see a sanitizer crash
1465
+ // in CrashIfIteratorIsInvalid so this assertion will only catch moved
1466
+ // table cases, unless we're using a custom allocator that does not
1467
+ // deallocate the old backing array (e.g. an arena allocator).
1468
+ ABSL_RAW_LOG(
1469
+ FATAL,
1470
+ "Invalid iterator comparison. The table was likely moved (or "
1471
+ "possibly rehashed) since this iterator was initialized.");
1311
1472
  }
1312
1473
  if (ABSL_PREDICT_FALSE(!ctrl_is_valid_for_comparison)) {
1313
1474
  ABSL_RAW_LOG(
@@ -1368,8 +1529,8 @@ inline void AssertSameContainer(const ctrl_t* ctrl_a, const ctrl_t* ctrl_b,
1368
1529
  }
1369
1530
  };
1370
1531
 
1371
- const bool a_is_default = ctrl_a == EmptyGroup();
1372
- const bool b_is_default = ctrl_b == EmptyGroup();
1532
+ const bool a_is_default = ctrl_a == DefaultIterControl();
1533
+ const bool b_is_default = ctrl_b == DefaultIterControl();
1373
1534
  if (a_is_default && b_is_default) return;
1374
1535
  fail_if(a_is_default != b_is_default,
1375
1536
  "Comparing default-constructed hashtable iterator with a "
@@ -1377,13 +1538,6 @@ inline void AssertSameContainer(const ctrl_t* ctrl_a, const ctrl_t* ctrl_b,
1377
1538
 
1378
1539
  if (SwisstableGenerationsEnabled()) {
1379
1540
  if (ABSL_PREDICT_TRUE(generation_ptr_a == generation_ptr_b)) return;
1380
- // Users don't need to know whether the tables are SOO so don't mention SOO
1381
- // in the debug message.
1382
- const bool a_is_soo = IsSooControl(ctrl_a);
1383
- const bool b_is_soo = IsSooControl(ctrl_b);
1384
- fail_if(a_is_soo != b_is_soo || (a_is_soo && b_is_soo),
1385
- "Comparing iterators from different hashtables.");
1386
-
1387
1541
  const bool a_is_empty = IsEmptyGeneration(generation_ptr_a);
1388
1542
  const bool b_is_empty = IsEmptyGeneration(generation_ptr_b);
1389
1543
  fail_if(a_is_empty != b_is_empty,
@@ -1418,27 +1572,66 @@ constexpr bool is_single_group(size_t capacity) {
1418
1572
  return capacity <= Group::kWidth;
1419
1573
  }
1420
1574
 
1575
+ // The state for a probe sequence.
1576
+ //
1577
+ // Currently, the sequence is a triangular progression of the form
1578
+ //
1579
+ // p(i) := Width * (i^2 + i)/2 + hash (mod mask + 1)
1580
+ //
1581
+ // The use of `Width` ensures that each probe step does not overlap groups;
1582
+ // the sequence effectively outputs the addresses of *groups* (although not
1583
+ // necessarily aligned to any boundary). The `Group` machinery allows us
1584
+ // to check an entire group with minimal branching.
1585
+ //
1586
+ // Wrapping around at `mask + 1` is important, but not for the obvious reason.
1587
+ // As described above, the first few entries of the control byte array
1588
+ // are mirrored at the end of the array, which `Group` will find and use
1589
+ // for selecting candidates. However, when those candidates' slots are
1590
+ // actually inspected, there are no corresponding slots for the cloned bytes,
1591
+ // so we need to make sure we've treated those offsets as "wrapping around".
1592
+ //
1593
+ // It turns out that this probe sequence visits every group exactly once if the
1594
+ // number of groups is a power of two, since (i^2+i)/2 is a bijection in
1595
+ // Z/(2^m). See https://en.wikipedia.org/wiki/Quadratic_probing
1596
+ template <size_t Width>
1597
+ class probe_seq {
1598
+ public:
1599
+ // Creates a new probe sequence using `hash` as the initial value of the
1600
+ // sequence and `capacity` as the mask to apply to each value in the
1601
+ // progression.
1602
+ probe_seq(HashtableCapacity capacity, size_t hash)
1603
+ : capacity_(capacity), offset_(capacity.mask(hash)) {}
1604
+
1605
+ // The offset within the table, i.e., the value `p(i)` above.
1606
+ size_t offset() const { return offset_; }
1607
+ size_t offset(size_t i) const { return capacity_.mask(offset_ + i); }
1608
+
1609
+ void next() {
1610
+ index_ += Width;
1611
+ offset_ += index_;
1612
+ offset_ = capacity_.mask(offset_);
1613
+ }
1614
+ // 0-based probe index, a multiple of `Width`.
1615
+ size_t index() const { return index_; }
1616
+
1617
+ private:
1618
+ HashtableCapacity capacity_;
1619
+ size_t offset_;
1620
+ size_t index_ = 0;
1621
+ };
1622
+
1421
1623
  // Begins a probing operation on `common.control`, using `hash`.
1422
- inline probe_seq<Group::kWidth> probe(size_t h1, size_t capacity) {
1423
- return probe_seq<Group::kWidth>(h1, capacity);
1624
+ inline probe_seq<Group::kWidth> probe_h1(HashtableCapacity capacity,
1625
+ size_t h1) {
1626
+ return probe_seq<Group::kWidth>(capacity, h1);
1424
1627
  }
1425
- inline probe_seq<Group::kWidth> probe(PerTableSeed seed, size_t capacity,
1426
- size_t hash) {
1427
- return probe(H1(hash, seed), capacity);
1628
+ inline probe_seq<Group::kWidth> probe(HashtableCapacity capacity, size_t hash) {
1629
+ return probe_h1(capacity, H1(hash));
1428
1630
  }
1429
1631
  inline probe_seq<Group::kWidth> probe(const CommonFields& common, size_t hash) {
1430
- return probe(common.seed(), common.capacity(), hash);
1632
+ return probe(common.capacity_impl(), hash);
1431
1633
  }
1432
1634
 
1433
- // Probes an array of control bits using a probe sequence derived from `hash`,
1434
- // and returns the offset corresponding to the first deleted or empty slot.
1435
- //
1436
- // Behavior when the entire table is full is undefined.
1437
- //
1438
- // NOTE: this function must work with tables having both empty and deleted
1439
- // slots in the same group. Such tables appear during `erase()`.
1440
- FindInfo find_first_non_full(const CommonFields& common, size_t hash);
1441
-
1442
1635
  constexpr size_t kProbedElementIndexSentinel = ~size_t{};
1443
1636
 
1444
1637
  // Implementation detail of transfer_unprobed_elements_to_next_capacity_fn.
@@ -1502,79 +1695,11 @@ extern template size_t TryFindNewIndexWithoutProbing(size_t h1,
1502
1695
  ctrl_t* new_ctrl,
1503
1696
  size_t new_capacity);
1504
1697
 
1505
- // Sets sanitizer poisoning for slot corresponding to control byte being set.
1506
- inline void DoSanitizeOnSetCtrl(const CommonFields& c, size_t i, ctrl_t h,
1507
- size_t slot_size) {
1508
- ABSL_SWISSTABLE_ASSERT(i < c.capacity());
1509
- auto* slot_i = static_cast<const char*>(c.slot_array()) + i * slot_size;
1510
- if (IsFull(h)) {
1511
- SanitizerUnpoisonMemoryRegion(slot_i, slot_size);
1512
- } else {
1513
- SanitizerPoisonMemoryRegion(slot_i, slot_size);
1514
- }
1515
- }
1516
-
1517
- // Sets `ctrl[i]` to `h`.
1518
- //
1519
- // Unlike setting it directly, this function will perform bounds checks and
1520
- // mirror the value to the cloned tail if necessary.
1521
- inline void SetCtrl(const CommonFields& c, size_t i, ctrl_t h,
1522
- size_t slot_size) {
1523
- DoSanitizeOnSetCtrl(c, i, h, slot_size);
1524
- ctrl_t* ctrl = c.control();
1525
- ctrl[i] = h;
1526
- ctrl[((i - NumClonedBytes()) & c.capacity()) +
1527
- (NumClonedBytes() & c.capacity())] = h;
1528
- }
1529
- // Overload for setting to an occupied `h2_t` rather than a special `ctrl_t`.
1530
- inline void SetCtrl(const CommonFields& c, size_t i, h2_t h, size_t slot_size) {
1531
- SetCtrl(c, i, static_cast<ctrl_t>(h), slot_size);
1532
- }
1533
-
1534
- // Like SetCtrl, but in a single group table, we can save some operations when
1535
- // setting the cloned control byte.
1536
- inline void SetCtrlInSingleGroupTable(const CommonFields& c, size_t i, ctrl_t h,
1537
- size_t slot_size) {
1538
- ABSL_SWISSTABLE_ASSERT(is_single_group(c.capacity()));
1539
- DoSanitizeOnSetCtrl(c, i, h, slot_size);
1540
- ctrl_t* ctrl = c.control();
1541
- ctrl[i] = h;
1542
- ctrl[i + c.capacity() + 1] = h;
1543
- }
1544
- // Overload for setting to an occupied `h2_t` rather than a special `ctrl_t`.
1545
- inline void SetCtrlInSingleGroupTable(const CommonFields& c, size_t i, h2_t h,
1546
- size_t slot_size) {
1547
- SetCtrlInSingleGroupTable(c, i, static_cast<ctrl_t>(h), slot_size);
1548
- }
1549
-
1550
- // Like SetCtrl, but in a table with capacity >= Group::kWidth - 1,
1551
- // we can save some operations when setting the cloned control byte.
1552
- inline void SetCtrlInLargeTable(const CommonFields& c, size_t i, ctrl_t h,
1553
- size_t slot_size) {
1554
- ABSL_SWISSTABLE_ASSERT(c.capacity() >= Group::kWidth - 1);
1555
- DoSanitizeOnSetCtrl(c, i, h, slot_size);
1556
- ctrl_t* ctrl = c.control();
1557
- ctrl[i] = h;
1558
- ctrl[((i - NumClonedBytes()) & c.capacity()) + NumClonedBytes()] = h;
1559
- }
1560
- // Overload for setting to an occupied `h2_t` rather than a special `ctrl_t`.
1561
- inline void SetCtrlInLargeTable(const CommonFields& c, size_t i, h2_t h,
1562
- size_t slot_size) {
1563
- SetCtrlInLargeTable(c, i, static_cast<ctrl_t>(h), slot_size);
1564
- }
1565
-
1566
1698
  // growth_info (which is a size_t) is stored with the backing array.
1567
1699
  constexpr size_t BackingArrayAlignment(size_t align_of_slot) {
1568
1700
  return (std::max)(align_of_slot, alignof(GrowthInfo));
1569
1701
  }
1570
1702
 
1571
- // Returns the address of the ith slot in slots where each slot occupies
1572
- // slot_size.
1573
- inline void* SlotAddress(void* slot_array, size_t slot, size_t slot_size) {
1574
- return static_cast<void*>(static_cast<char*>(slot_array) +
1575
- (slot * slot_size));
1576
- }
1577
-
1578
1703
  // Iterates over all full slots and calls `cb(const ctrl_t*, void*)`.
1579
1704
  // No insertion to the table is allowed during `cb` call.
1580
1705
  // Erasure is allowed only for the element passed to the callback.
@@ -1592,33 +1717,14 @@ constexpr bool ShouldSampleHashtablezInfoForAlloc() {
1592
1717
  return std::is_same_v<CharAlloc, std::allocator<char>>;
1593
1718
  }
1594
1719
 
1595
- template <bool kSooEnabled>
1596
- bool ShouldSampleHashtablezInfoOnResize(bool force_sampling,
1597
- bool is_hashtablez_eligible,
1598
- size_t old_capacity, CommonFields& c) {
1599
- if (!is_hashtablez_eligible) return false;
1600
- // Force sampling is only allowed for SOO tables.
1601
- ABSL_SWISSTABLE_ASSERT(kSooEnabled || !force_sampling);
1602
- if (kSooEnabled && force_sampling) {
1603
- return true;
1604
- }
1605
- // In SOO, we sample on the first insertion so if this is an empty SOO case
1606
- // (e.g. when reserve is called), then we still need to sample.
1607
- if (kSooEnabled && old_capacity == SooCapacity() && c.empty()) {
1608
- return ShouldSampleNextTable();
1609
- }
1610
- if (!kSooEnabled && old_capacity == 0) {
1611
- return ShouldSampleNextTable();
1612
- }
1613
- return false;
1614
- }
1615
-
1616
1720
  // Allocates `n` bytes for a backing array.
1617
1721
  template <size_t AlignOfBackingArray, typename Alloc>
1618
- ABSL_ATTRIBUTE_NOINLINE void* AllocateBackingArray(void* alloc, size_t n) {
1722
+ void* AllocateBackingArray(void* alloc, size_t n) {
1619
1723
  return Allocate<AlignOfBackingArray>(static_cast<Alloc*>(alloc), n);
1620
1724
  }
1621
1725
 
1726
+ // Note: we mark this function as ABSL_ATTRIBUTE_NOINLINE because we don't want
1727
+ // it to be inlined into e.g. the destructor to save code size.
1622
1728
  template <size_t AlignOfBackingArray, typename Alloc>
1623
1729
  ABSL_ATTRIBUTE_NOINLINE void DeallocateBackingArray(
1624
1730
  void* alloc, size_t capacity, ctrl_t* ctrl, size_t slot_size,
@@ -1647,7 +1753,7 @@ struct PolicyFunctions {
1647
1753
  void* (*hash_fn)(CommonFields& common);
1648
1754
 
1649
1755
  // Returns the hash of the pointed-to slot.
1650
- size_t (*hash_slot)(const void* hash_fn, void* slot);
1756
+ HashSlotFn hash_slot;
1651
1757
 
1652
1758
  // Transfers the contents of `count` slots from src_slot to dst_slot.
1653
1759
  // We use ability to transfer several slots in single group table growth.
@@ -1684,51 +1790,54 @@ struct PolicyFunctions {
1684
1790
  }
1685
1791
  };
1686
1792
 
1687
- // Returns the maximum valid size for a table with 1-byte slots.
1688
- // This function is an utility shared by MaxValidSize and IsAboveValidSize.
1689
- // Template parameter is only used to enable testing.
1793
+ // The following functions are used for calculating the max valid size of the
1794
+ // table. This is important for security to avoid overflowing size_t when
1795
+ // calculating the allocation size of the backing array
1796
+ // (https://nvd.nist.gov/vuln/detail/CVE-2025-0838). We also limit the max valid
1797
+ // size based on the size of the key_type, and this is an optimization because
1798
+ // we ABSL_ASSUME that the size is less than MaxValidSize, which can enable
1799
+ // other optimizations for tables with small keys.
1800
+
1690
1801
  template <size_t kSizeOfSizeT = sizeof(size_t)>
1691
- constexpr size_t MaxValidSizeFor1ByteSlot() {
1692
- if constexpr (kSizeOfSizeT == 8) {
1693
- return CapacityToGrowth(
1694
- static_cast<size_t>(uint64_t{1} << HashtableSize::kSizeBitCount) - 1);
1695
- } else {
1696
- static_assert(kSizeOfSizeT == 4);
1697
- return CapacityToGrowth((size_t{1} << (kSizeOfSizeT * 8 - 2)) - 1);
1698
- }
1802
+ constexpr size_t MaxSizeAtMaxValidCapacity(size_t slot_size) {
1803
+ using SizeT = std::conditional_t<kSizeOfSizeT == 4, uint32_t, uint64_t>;
1804
+ // We shift right by 2 for a safe margin against overflow.
1805
+ constexpr SizeT kMaxValidCapacity = ~SizeT{} >> 2;
1806
+ return CapacityToGrowth(kMaxValidCapacity) / slot_size;
1807
+ }
1808
+
1809
+ constexpr size_t MaxStorableSize() {
1810
+ return static_cast<size_t>(uint64_t{1}
1811
+ << HashtableInlineData::kSizeBitCount) -
1812
+ 1;
1813
+ }
1814
+
1815
+ // There are no more than 2^sizeof(key_type) unique key_types (and hashtable
1816
+ // keys must be unique) so we can't have a hashtable with more than
1817
+ // 2^sizeof(key_type) elements.
1818
+ template <size_t kSizeOfSizeT = sizeof(size_t)>
1819
+ constexpr size_t MaxValidSizeForKeySize(size_t key_size) {
1820
+ if (key_size < kSizeOfSizeT) return size_t{1} << 8 * key_size;
1821
+ return (std::numeric_limits<size_t>::max)();
1699
1822
  }
1700
1823
 
1701
- // Returns the maximum valid size for a table with provided slot size.
1702
- // Template parameter is only used to enable testing.
1703
1824
  template <size_t kSizeOfSizeT = sizeof(size_t)>
1704
- constexpr size_t MaxValidSize(size_t slot_size) {
1825
+ constexpr size_t MaxValidSizeForSlotSize(size_t slot_size) {
1705
1826
  if constexpr (kSizeOfSizeT == 8) {
1706
- // For small slot sizes we are limited by HashtableSize::kSizeBitCount.
1707
- if (slot_size < size_t{1} << (64 - HashtableSize::kSizeBitCount)) {
1708
- return MaxValidSizeFor1ByteSlot<kSizeOfSizeT>();
1827
+ // For small slot sizes we are limited by HashtableStackData::kSizeBitCount.
1828
+ if (slot_size < size_t{1} << (64 - HashtableInlineData::kSizeBitCount)) {
1829
+ return MaxStorableSize();
1709
1830
  }
1710
- return (size_t{1} << (kSizeOfSizeT * 8 - 2)) / slot_size;
1711
- } else {
1712
- return MaxValidSizeFor1ByteSlot<kSizeOfSizeT>() / slot_size;
1713
1831
  }
1832
+ return MaxSizeAtMaxValidCapacity<kSizeOfSizeT>(slot_size);
1714
1833
  }
1715
1834
 
1716
- // Returns true if size is larger than the maximum valid size.
1717
- // It is an optimization to avoid the division operation in the common case.
1835
+ // Returns the maximum valid size for a table, given the key size and slot size.
1718
1836
  // Template parameter is only used to enable testing.
1719
1837
  template <size_t kSizeOfSizeT = sizeof(size_t)>
1720
- constexpr bool IsAboveValidSize(size_t size, size_t slot_size) {
1721
- if constexpr (kSizeOfSizeT == 8) {
1722
- // For small slot sizes we are limited by HashtableSize::kSizeBitCount.
1723
- if (ABSL_PREDICT_TRUE(slot_size <
1724
- (size_t{1} << (64 - HashtableSize::kSizeBitCount)))) {
1725
- return size > MaxValidSizeFor1ByteSlot<kSizeOfSizeT>();
1726
- }
1727
- return size > MaxValidSize<kSizeOfSizeT>(slot_size);
1728
- } else {
1729
- return uint64_t{size} * slot_size >
1730
- MaxValidSizeFor1ByteSlot<kSizeOfSizeT>();
1731
- }
1838
+ constexpr size_t MaxValidSize(size_t key_size, size_t slot_size) {
1839
+ return (std::min)(MaxValidSizeForKeySize<kSizeOfSizeT>(key_size),
1840
+ MaxValidSizeForSlotSize<kSizeOfSizeT>(slot_size));
1732
1841
  }
1733
1842
 
1734
1843
  // Returns the index of the SOO slot when growing from SOO to non-SOO in a
@@ -1743,8 +1852,9 @@ constexpr size_t SooSlotIndex() { return 1; }
1743
1852
  // Allowing till 16 would require additional store that can be avoided.
1744
1853
  constexpr size_t MaxSmallAfterSooCapacity() { return 7; }
1745
1854
 
1746
- // Type erased version of raw_hash_set::reserve.
1747
- // Requires: `new_size > policy.soo_capacity`.
1855
+ // Type erased version of raw_hash_set::reserve. Requires:
1856
+ // 1. `new_size > policy.soo_capacity`.
1857
+ // 2. `new_size <= kMaxValidSize`.
1748
1858
  void ReserveTableToFitNewSize(CommonFields& common,
1749
1859
  const PolicyFunctions& policy, size_t new_size);
1750
1860
 
@@ -1753,11 +1863,13 @@ void ReserveTableToFitNewSize(CommonFields& common,
1753
1863
  // 1. `c.capacity() == policy.soo_capacity`.
1754
1864
  // 2. `c.empty()`.
1755
1865
  // 3. `new_size > policy.soo_capacity`.
1866
+ // 4. `bucket_count <= MaxValidCapacity()`.
1756
1867
  // The table will be attempted to be sampled.
1757
1868
  void ReserveEmptyNonAllocatedTableToFitBucketCount(
1758
1869
  CommonFields& common, const PolicyFunctions& policy, size_t bucket_count);
1759
1870
 
1760
1871
  // Type erased version of raw_hash_set::rehash.
1872
+ // Requires: `n <= MaxValidCapacity()`.
1761
1873
  void Rehash(CommonFields& common, const PolicyFunctions& policy, size_t n);
1762
1874
 
1763
1875
  // Type erased version of copy constructor.
@@ -1802,23 +1914,20 @@ constexpr size_t OptimalMemcpySizeForSooSlotTransfer(
1802
1914
 
1803
1915
  // Resizes SOO table to the NextCapacity(SooCapacity()) and prepares insert for
1804
1916
  // the given new_hash. Returns the offset of the new element.
1805
- // `soo_slot_ctrl` is the control byte of the SOO slot.
1806
- // If soo_slot_ctrl is kEmpty
1807
- // 1. The table must be empty.
1808
- // 2. Table will be forced to be sampled.
1809
1917
  // All possible template combinations are defined in cc file to improve
1810
1918
  // compilation time.
1811
1919
  template <size_t SooSlotMemcpySize, bool TransferUsesMemcpy>
1812
- size_t GrowSooTableToNextCapacityAndPrepareInsert(CommonFields& common,
1813
- const PolicyFunctions& policy,
1814
- size_t new_hash,
1815
- ctrl_t soo_slot_ctrl);
1816
-
1817
- // As `ResizeFullSooTableToNextCapacity`, except that we also force the SOO
1818
- // table to be sampled. SOO tables need to switch from SOO to heap in order to
1819
- // store the infoz. No-op if sampling is disabled or not possible.
1820
- void GrowFullSooTableToNextCapacityForceSampling(CommonFields& common,
1821
- const PolicyFunctions& policy);
1920
+ size_t GrowSooTableToNextCapacityAndPrepareInsert(
1921
+ CommonFields& common, const PolicyFunctions& policy,
1922
+ absl::FunctionRef<size_t(size_t)> get_hash, bool force_sampling);
1923
+
1924
+ // PrepareInsert for small tables (is_small()==true).
1925
+ // Returns the new control and the new slot.
1926
+ // Hash is only computed if the table is sampled or grew to large size
1927
+ // (is_small()==false).
1928
+ std::pair<ctrl_t*, void*> PrepareInsertSmallNonSoo(
1929
+ CommonFields& common, const PolicyFunctions& policy,
1930
+ absl::FunctionRef<size_t(size_t)> get_hash);
1822
1931
 
1823
1932
  // Resizes table with allocated slots and change the table seed.
1824
1933
  // Tables with SOO enabled must have capacity > policy.soo_capacity.
@@ -1829,12 +1938,13 @@ void ResizeAllocatedTableWithSeedChange(CommonFields& common,
1829
1938
 
1830
1939
  // ClearBackingArray clears the backing array, either modifying it in place,
1831
1940
  // or creating a new one based on the value of "reuse".
1832
- // REQUIRES: c.capacity > 0
1941
+ // REQUIRES: c.capacity > MaxSmallCapacity().
1833
1942
  void ClearBackingArray(CommonFields& c, const PolicyFunctions& policy,
1834
- void* alloc, bool reuse, bool soo_enabled);
1943
+ void* alloc, bool reuse);
1835
1944
 
1836
- // Type-erased version of raw_hash_set::erase_meta_only.
1837
- void EraseMetaOnly(CommonFields& c, size_t index, size_t slot_size);
1945
+ // Type-erased versions of raw_hash_set::erase_meta_only_{small,large}.
1946
+ void EraseMetaOnlySmall(CommonFields& c, bool soo_enabled, size_t slot_size);
1947
+ void EraseMetaOnlyLarge(CommonFields& c, const ctrl_t* ctrl, size_t slot_size);
1838
1948
 
1839
1949
  // For trivially relocatable types we use memcpy directly. This allows us to
1840
1950
  // share the same function body for raw_hash_set instantiations that have the
@@ -1853,23 +1963,44 @@ ABSL_ATTRIBUTE_NOINLINE void TransferNRelocatable(void*, void* dst, void* src,
1853
1963
  // empty class cases.
1854
1964
  void* GetRefForEmptyClass(CommonFields& common);
1855
1965
 
1856
- // Given the hash of a value not currently in the table and the first empty
1857
- // slot in the probe sequence, finds a viable slot index to insert it at.
1966
+ // Given the hash of a value not currently in the table and the first group with
1967
+ // an empty slot in the probe sequence, finds a viable slot index to insert it
1968
+ // at.
1858
1969
  //
1859
1970
  // In case there's no space left, the table can be resized or rehashed
1860
1971
  // (for tables with deleted slots, see FindInsertPositionWithGrowthOrRehash).
1861
1972
  //
1862
1973
  // In the case of absence of deleted slots and positive growth_left, the element
1863
- // can be inserted in the provided `target` position.
1974
+ // can be inserted in one of the empty slots in the provided `target_group`.
1864
1975
  //
1865
1976
  // When the table has deleted slots (according to GrowthInfo), the target
1866
1977
  // position will be searched one more time using `find_first_non_full`.
1867
1978
  //
1868
- // REQUIRES: Table is not SOO.
1979
+ // REQUIRES: `!common.is_small()`.
1869
1980
  // REQUIRES: At least one non-full slot available.
1870
- // REQUIRES: `target` is a valid empty position to insert.
1871
- size_t PrepareInsertNonSoo(CommonFields& common, const PolicyFunctions& policy,
1872
- size_t hash, FindInfo target);
1981
+ // REQUIRES: `mask_empty` is a mask containing empty slots for the
1982
+ // `target_group`.
1983
+ // REQUIRES: `target_group` is a starting position for the group that has
1984
+ // at least one empty slot.
1985
+ size_t PrepareInsertLarge(CommonFields& common, const PolicyFunctions& policy,
1986
+ size_t hash, Group::NonIterableBitMaskType mask_empty,
1987
+ FindInfo target_group);
1988
+
1989
+ // Same as above, but with generations enabled, we may end up changing the seed,
1990
+ // which means we need to be able to recompute the hash.
1991
+ size_t PrepareInsertLargeGenerationsEnabled(
1992
+ CommonFields& common, const PolicyFunctions& policy, size_t hash,
1993
+ Group::NonIterableBitMaskType mask_empty, FindInfo target_group,
1994
+ absl::FunctionRef<size_t(size_t)> recompute_hash);
1995
+
1996
+ template <typename Policy, typename Hash, typename Eq, typename Alloc>
1997
+ struct InstantiateRawHashSet {
1998
+ using type = typename ApplyWithoutDefaultSuffix<
1999
+ raw_hash_set,
2000
+ TypeList<void, typename Policy::DefaultHash, typename Policy::DefaultEq,
2001
+ typename Policy::DefaultAlloc>,
2002
+ TypeList<Policy, Hash, Eq, Alloc>>::type;
2003
+ };
1873
2004
 
1874
2005
  // A SwissTable.
1875
2006
  //
@@ -1877,26 +2008,47 @@ size_t PrepareInsertNonSoo(CommonFields& common, const PolicyFunctions& policy,
1877
2008
  // the slots of the hashtable (see hash_policy_traits.h for the full interface
1878
2009
  // of policy).
1879
2010
  //
2011
+ // Params...: a variadic list of parameters that allows us to omit default
2012
+ // types. This reduces the mangled name of the class and the size of
2013
+ // debug strings like __PRETTY_FUNCTION__. Default types do not give
2014
+ // any new information.
2015
+ //
1880
2016
  // Hash: a (possibly polymorphic) functor that hashes keys of the hashtable. The
1881
2017
  // functor should accept a key and return size_t as hash. For best performance
1882
2018
  // it is important that the hash function provides high entropy across all bits
1883
2019
  // of the hash.
2020
+ // This is the first element in `Params...` if it exists, or Policy::DefaultHash
2021
+ // otherwise.
1884
2022
  //
1885
2023
  // Eq: a (possibly polymorphic) functor that compares two keys for equality. It
1886
2024
  // should accept two (of possibly different type) keys and return a bool: true
1887
2025
  // if they are equal, false if they are not. If two keys compare equal, then
1888
2026
  // their hash values as defined by Hash MUST be equal.
2027
+ // This is the second element in `Params...` if it exists, or Policy::DefaultEq
2028
+ // otherwise.
1889
2029
  //
1890
2030
  // Allocator: an Allocator
1891
2031
  // [https://en.cppreference.com/w/cpp/named_req/Allocator] with which
1892
2032
  // the storage of the hashtable will be allocated and the elements will be
1893
2033
  // constructed and destroyed.
1894
- template <class Policy, class Hash, class Eq, class Alloc>
2034
+ // This is the third element in `Params...` if it exists, or
2035
+ // Policy::DefaultAlloc otherwise.
2036
+ template <class Policy, class... Params>
1895
2037
  class raw_hash_set {
1896
2038
  using PolicyTraits = hash_policy_traits<Policy>;
2039
+ using Hash = GetFromListOr<typename Policy::DefaultHash, 0, Params...>;
2040
+ using Eq = GetFromListOr<typename Policy::DefaultEq, 1, Params...>;
2041
+ using Alloc = GetFromListOr<typename Policy::DefaultAlloc, 2, Params...>;
1897
2042
  using KeyArgImpl =
1898
2043
  KeyArg<IsTransparent<Eq>::value && IsTransparent<Hash>::value>;
1899
2044
 
2045
+ static_assert(
2046
+ std::is_same_v<
2047
+ typename InstantiateRawHashSet<Policy, Hash, Eq, Alloc>::type,
2048
+ raw_hash_set>,
2049
+ "Redundant template parameters were passed. Use InstantiateRawHashSet<> "
2050
+ "instead");
2051
+
1900
2052
  public:
1901
2053
  using init_type = typename PolicyTraits::init_type;
1902
2054
  using key_type = typename PolicyTraits::key_type;
@@ -1909,9 +2061,9 @@ class raw_hash_set {
1909
2061
  using value_type = typename PolicyTraits::value_type;
1910
2062
  using reference = value_type&;
1911
2063
  using const_reference = const value_type&;
1912
- using pointer = typename absl::allocator_traits<
2064
+ using pointer = typename std::allocator_traits<
1913
2065
  allocator_type>::template rebind_traits<value_type>::pointer;
1914
- using const_pointer = typename absl::allocator_traits<
2066
+ using const_pointer = typename std::allocator_traits<
1915
2067
  allocator_type>::template rebind_traits<value_type>::const_pointer;
1916
2068
 
1917
2069
  private:
@@ -1924,6 +2076,10 @@ class raw_hash_set {
1924
2076
 
1925
2077
  using slot_type = typename PolicyTraits::slot_type;
1926
2078
 
2079
+ constexpr static bool kIsDefaultHash =
2080
+ std::is_same_v<hasher, absl::Hash<key_type>> ||
2081
+ std::is_same_v<hasher, absl::container_internal::StringHash>;
2082
+
1927
2083
  // TODO(b/289225379): we could add extra SOO space inside raw_hash_set
1928
2084
  // after CommonFields to allow inlining larger slot_types (e.g. std::string),
1929
2085
  // but it's a bit complicated if we want to support incomplete mapped_type in
@@ -1939,28 +2095,47 @@ class raw_hash_set {
1939
2095
  constexpr static size_t DefaultCapacity() {
1940
2096
  return SooEnabled() ? SooCapacity() : 0;
1941
2097
  }
2098
+ constexpr static size_t MaxValidSize() {
2099
+ return container_internal::MaxValidSize(sizeof(key_type),
2100
+ sizeof(slot_type));
2101
+ }
2102
+ constexpr static size_t MaxValidCapacity() {
2103
+ return SizeToCapacity(MaxValidSize());
2104
+ }
1942
2105
 
1943
2106
  // Whether `size` fits in the SOO capacity of this table.
1944
2107
  bool fits_in_soo(size_t size) const {
1945
2108
  return SooEnabled() && size <= SooCapacity();
1946
2109
  }
1947
2110
  // Whether this table is in SOO mode or non-SOO mode.
1948
- bool is_soo() const { return fits_in_soo(capacity()); }
2111
+ bool is_soo() const {
2112
+ HashtableCapacity cap = maybe_invalid_capacity();
2113
+ return cap.IsValid() && fits_in_soo(cap.capacity());
2114
+ }
1949
2115
  bool is_full_soo() const { return is_soo() && !empty(); }
1950
2116
 
2117
+ bool is_small() const { return common().is_small(); }
2118
+
1951
2119
  // Give an early error when key_type is not hashable/eq.
1952
2120
  auto KeyTypeCanBeHashed(const Hash& h, const key_type& k) -> decltype(h(k));
1953
2121
  auto KeyTypeCanBeEq(const Eq& eq, const key_type& k) -> decltype(eq(k, k));
1954
2122
 
1955
- using AllocTraits = absl::allocator_traits<allocator_type>;
1956
- using SlotAlloc = typename absl::allocator_traits<
2123
+ // Try to be helpful when the hasher returns an unreasonable type.
2124
+ using key_hash_result =
2125
+ absl::remove_cvref_t<decltype(std::declval<const Hash&>()(
2126
+ std::declval<const key_type&>()))>;
2127
+ static_assert(sizeof(key_hash_result) >= sizeof(size_t),
2128
+ "`Hash::operator()` should return a `size_t`");
2129
+
2130
+ using AllocTraits = std::allocator_traits<allocator_type>;
2131
+ using SlotAlloc = typename std::allocator_traits<
1957
2132
  allocator_type>::template rebind_alloc<slot_type>;
1958
2133
  // People are often sloppy with the exact type of their allocator (sometimes
1959
2134
  // it has an extra const or is missing the pair, but rebinds made it work
1960
2135
  // anyway).
1961
2136
  using CharAlloc =
1962
- typename absl::allocator_traits<Alloc>::template rebind_alloc<char>;
1963
- using SlotAllocTraits = typename absl::allocator_traits<
2137
+ typename std::allocator_traits<Alloc>::template rebind_alloc<char>;
2138
+ using SlotAllocTraits = typename std::allocator_traits<
1964
2139
  allocator_type>::template rebind_traits<slot_type>;
1965
2140
 
1966
2141
  static_assert(std::is_lvalue_reference<reference>::value,
@@ -1969,7 +2144,7 @@ class raw_hash_set {
1969
2144
  // An enabler for insert(T&&): T must be convertible to init_type or be the
1970
2145
  // same as [cv] value_type [ref].
1971
2146
  template <class T>
1972
- using Insertable = absl::disjunction<
2147
+ using Insertable = std::disjunction<
1973
2148
  std::is_same<absl::remove_cvref_t<reference>, absl::remove_cvref_t<T>>,
1974
2149
  std::is_convertible<T, init_type>>;
1975
2150
  template <class T>
@@ -2009,28 +2184,28 @@ class raw_hash_set {
2009
2184
  using iterator_category = std::forward_iterator_tag;
2010
2185
  using value_type = typename raw_hash_set::value_type;
2011
2186
  using reference =
2012
- absl::conditional_t<PolicyTraits::constant_iterators::value,
2187
+ std::conditional_t<PolicyTraits::constant_iterators::value,
2013
2188
  const value_type&, value_type&>;
2014
- using pointer = absl::remove_reference_t<reference>*;
2189
+ using pointer = std::remove_reference_t<reference>*;
2015
2190
  using difference_type = typename raw_hash_set::difference_type;
2016
2191
 
2017
2192
  iterator() {}
2018
2193
 
2019
2194
  // PRECONDITION: not an end() iterator.
2020
2195
  reference operator*() const {
2021
- AssertIsFull(ctrl_, generation(), generation_ptr(), "operator*()");
2196
+ assert_is_full("operator*()");
2022
2197
  return unchecked_deref();
2023
2198
  }
2024
2199
 
2025
2200
  // PRECONDITION: not an end() iterator.
2026
2201
  pointer operator->() const {
2027
- AssertIsFull(ctrl_, generation(), generation_ptr(), "operator->");
2202
+ assert_is_full("operator->");
2028
2203
  return &operator*();
2029
2204
  }
2030
2205
 
2031
2206
  // PRECONDITION: not an end() iterator.
2032
2207
  iterator& operator++() {
2033
- AssertIsFull(ctrl_, generation(), generation_ptr(), "operator++");
2208
+ assert_is_full("operator++");
2034
2209
  ++ctrl_;
2035
2210
  ++slot_;
2036
2211
  skip_empty_or_deleted();
@@ -2068,7 +2243,7 @@ class raw_hash_set {
2068
2243
  // This constructor is used in begin() to avoid an MSan
2069
2244
  // use-of-uninitialized-value error. Delegating from this constructor to
2070
2245
  // the previous one doesn't avoid the error.
2071
- iterator(ctrl_t* ctrl, MaybeInitializedPtr slot,
2246
+ iterator(ctrl_t* ctrl, MaybeInitializedPtr<void> slot,
2072
2247
  const GenerationType* generation_ptr)
2073
2248
  : HashSetIteratorGenerationInfo(generation_ptr),
2074
2249
  ctrl_(ctrl),
@@ -2081,38 +2256,42 @@ class raw_hash_set {
2081
2256
  explicit iterator(const GenerationType* generation_ptr)
2082
2257
  : HashSetIteratorGenerationInfo(generation_ptr), ctrl_(nullptr) {}
2083
2258
 
2259
+ void assert_is_full(const char* operation) const {
2260
+ AssertIsFull(ctrl_, generation(), generation_ptr(), operation);
2261
+ }
2262
+
2084
2263
  // Fixes up `ctrl_` to point to a full or sentinel by advancing `ctrl_` and
2085
2264
  // `slot_` until they reach one.
2086
2265
  void skip_empty_or_deleted() {
2087
2266
  while (IsEmptyOrDeleted(*ctrl_)) {
2088
- uint32_t shift =
2089
- GroupFullEmptyOrDeleted{ctrl_}.CountLeadingEmptyOrDeleted();
2090
- ctrl_ += shift;
2091
- slot_ += shift;
2267
+ ++ctrl_;
2268
+ ++slot_;
2092
2269
  }
2093
2270
  }
2094
2271
 
2095
- ctrl_t* control() const { return ctrl_; }
2096
- slot_type* slot() const { return slot_; }
2097
-
2098
- // We use EmptyGroup() for default-constructed iterators so that they can
2099
- // be distinguished from end iterators, which have nullptr ctrl_.
2100
- ctrl_t* ctrl_ = EmptyGroup();
2101
- // To avoid uninitialized member warnings, put slot_ in an anonymous union.
2102
- // The member is not initialized on singleton and end iterators.
2103
- union {
2104
- slot_type* slot_;
2105
- };
2106
-
2107
2272
  // An equality check which skips ABSL Hardening iterator invalidation
2108
2273
  // checks.
2109
2274
  // Should be used when the lifetimes of the iterators are well-enough
2110
2275
  // understood to prove that they cannot be invalid.
2111
- bool unchecked_equals(const iterator& b) { return ctrl_ == b.control(); }
2276
+ bool unchecked_equals(const iterator& b) const {
2277
+ return ctrl_ == b.control();
2278
+ }
2112
2279
 
2113
2280
  // Dereferences the iterator without ABSL Hardening iterator invalidation
2114
2281
  // checks.
2115
2282
  reference unchecked_deref() const { return PolicyTraits::element(slot_); }
2283
+
2284
+ ctrl_t* control() const { return ctrl_; }
2285
+ slot_type* slot() const { return slot_; }
2286
+
2287
+ // We use DefaultIterControl() for default-constructed iterators so that
2288
+ // they can be distinguished from end iterators, which have nullptr ctrl_.
2289
+ ctrl_t* ctrl_ = DefaultIterControl();
2290
+ // To avoid uninitialized member warnings, put slot_ in an anonymous union.
2291
+ // The member is not initialized on singleton and end iterators.
2292
+ union {
2293
+ slot_type* slot_;
2294
+ };
2116
2295
  };
2117
2296
 
2118
2297
  class const_iterator {
@@ -2153,14 +2332,13 @@ class raw_hash_set {
2153
2332
  const GenerationType* gen)
2154
2333
  : inner_(const_cast<ctrl_t*>(ctrl), const_cast<slot_type*>(slot), gen) {
2155
2334
  }
2335
+ bool unchecked_equals(const const_iterator& b) const {
2336
+ return inner_.unchecked_equals(b.inner_);
2337
+ }
2156
2338
  ctrl_t* control() const { return inner_.control(); }
2157
2339
  slot_type* slot() const { return inner_.slot(); }
2158
2340
 
2159
2341
  iterator inner_;
2160
-
2161
- bool unchecked_equals(const const_iterator& b) {
2162
- return inner_.unchecked_equals(b.inner_);
2163
- }
2164
2342
  };
2165
2343
 
2166
2344
  using node_type = node_handle<Policy, hash_policy_traits<Policy>, Alloc>;
@@ -2181,7 +2359,8 @@ class raw_hash_set {
2181
2359
  alloc) {
2182
2360
  if (bucket_count > DefaultCapacity()) {
2183
2361
  ReserveEmptyNonAllocatedTableToFitBucketCount(
2184
- common(), GetPolicyFunctions(), bucket_count);
2362
+ common(), GetPolicyFunctions(),
2363
+ (std::min)(bucket_count, MaxValidCapacity()));
2185
2364
  }
2186
2365
  }
2187
2366
 
@@ -2214,6 +2393,28 @@ class raw_hash_set {
2214
2393
  const allocator_type& alloc)
2215
2394
  : raw_hash_set(first, last, bucket_count, hasher(), key_equal(), alloc) {}
2216
2395
 
2396
+ #if defined(__cpp_lib_containers_ranges) && \
2397
+ __cpp_lib_containers_ranges >= 202202L
2398
+ template <typename R>
2399
+ raw_hash_set(std::from_range_t, R&& rg, size_type bucket_count = 0,
2400
+ const hasher& hash = hasher(), const key_equal& eq = key_equal(),
2401
+ const allocator_type& alloc = allocator_type())
2402
+ : raw_hash_set(std::begin(rg), std::end(rg), bucket_count, hash, eq,
2403
+ alloc) {}
2404
+
2405
+ template <typename R>
2406
+ raw_hash_set(std::from_range_t, R&& rg, size_type bucket_count,
2407
+ const allocator_type& alloc)
2408
+ : raw_hash_set(std::from_range, std::forward<R>(rg), bucket_count,
2409
+ hasher(), key_equal(), alloc) {}
2410
+
2411
+ template <typename R>
2412
+ raw_hash_set(std::from_range_t, R&& rg, size_type bucket_count,
2413
+ const hasher& hash, const allocator_type& alloc)
2414
+ : raw_hash_set(std::from_range, std::forward<R>(rg), bucket_count, hash,
2415
+ key_equal(), alloc) {}
2416
+ #endif
2417
+
2217
2418
  template <class InputIter>
2218
2419
  raw_hash_set(InputIter first, InputIter last, const allocator_type& alloc)
2219
2420
  : raw_hash_set(first, last, 0, hasher(), key_equal(), alloc) {}
@@ -2308,7 +2509,8 @@ class raw_hash_set {
2308
2509
  // Note: we avoid using exchange for better generated code.
2309
2510
  settings_(PolicyTraits::transfer_uses_memcpy() || !that.is_full_soo()
2310
2511
  ? std::move(that.common())
2311
- : CommonFields{full_soo_tag_t{}},
2512
+ : CommonFields{full_soo_tag_t{},
2513
+ that.common().soo_has_tried_sampling()},
2312
2514
  that.hash_ref(), that.eq_ref(), that.char_alloc_ref()) {
2313
2515
  if (!PolicyTraits::transfer_uses_memcpy() && that.is_full_soo()) {
2314
2516
  transfer(soo_slot(), that.soo_slot());
@@ -2345,7 +2547,7 @@ class raw_hash_set {
2345
2547
  }
2346
2548
 
2347
2549
  raw_hash_set& operator=(raw_hash_set&& that) noexcept(
2348
- absl::allocator_traits<allocator_type>::is_always_equal::value &&
2550
+ AllocTraits::is_always_equal::value &&
2349
2551
  std::is_nothrow_move_assignable<hasher>::value &&
2350
2552
  std::is_nothrow_move_assignable<key_equal>::value) {
2351
2553
  // TODO(sbenza): We should only use the operations from the noexcept clause
@@ -2359,13 +2561,13 @@ class raw_hash_set {
2359
2561
  ~raw_hash_set() {
2360
2562
  destructor_impl();
2361
2563
  if constexpr (SwisstableAssertAccessToDestroyedTable()) {
2362
- common().set_capacity(InvalidCapacity::kDestroyed);
2564
+ common().set_capacity(HashtableCapacity::CreateDestroyed());
2363
2565
  }
2364
2566
  }
2365
2567
 
2366
2568
  iterator begin() ABSL_ATTRIBUTE_LIFETIME_BOUND {
2367
2569
  if (ABSL_PREDICT_FALSE(empty())) return end();
2368
- if (capacity() == 1) return single_iterator();
2570
+ if (is_small()) return single_iterator();
2369
2571
  iterator it = {control(), common().slots_union(),
2370
2572
  common().generation_ptr()};
2371
2573
  it.skip_empty_or_deleted();
@@ -2391,21 +2593,27 @@ class raw_hash_set {
2391
2593
  bool empty() const { return !size(); }
2392
2594
  size_t size() const {
2393
2595
  AssertNotDebugCapacity();
2394
- return common().size();
2596
+ const size_t size = common().size();
2597
+ [[maybe_unused]] const size_t kMaxValidSize = MaxValidSize();
2598
+ ABSL_ASSUME(size <= kMaxValidSize);
2599
+ return size;
2395
2600
  }
2396
2601
  size_t capacity() const {
2397
2602
  const size_t cap = common().capacity();
2398
- // Compiler complains when using functions in ASSUME so use local variable.
2399
- ABSL_ATTRIBUTE_UNUSED static constexpr size_t kDefaultCapacity =
2400
- DefaultCapacity();
2603
+ // Compiler complains when using functions in ASSUME so use local variables.
2604
+ [[maybe_unused]] const bool kIsValid = IsValidCapacity(cap);
2605
+ [[maybe_unused]] const size_t kDefaultCapacity = DefaultCapacity();
2606
+ [[maybe_unused]] const size_t kMaxValidCapacity = MaxValidCapacity();
2607
+ ABSL_ASSUME(kIsValid || cap == 0);
2401
2608
  ABSL_ASSUME(cap >= kDefaultCapacity);
2609
+ ABSL_ASSUME(cap <= kMaxValidCapacity);
2402
2610
  return cap;
2403
2611
  }
2404
- size_t max_size() const { return MaxValidSize(sizeof(slot_type)); }
2612
+ size_t max_size() const { return MaxValidSize(); }
2405
2613
 
2406
2614
  ABSL_ATTRIBUTE_REINITIALIZES void clear() {
2407
2615
  if (SwisstableGenerationsEnabled() &&
2408
- capacity() >= InvalidCapacity::kMovedFrom) {
2616
+ maybe_invalid_capacity().IsMovedFrom()) {
2409
2617
  common().set_capacity(DefaultCapacity());
2410
2618
  }
2411
2619
  AssertNotDebugCapacity();
@@ -2419,9 +2627,11 @@ class raw_hash_set {
2419
2627
  const size_t cap = capacity();
2420
2628
  if (cap == 0) {
2421
2629
  // Already guaranteed to be empty; so nothing to do.
2422
- } else if (is_soo()) {
2423
- if (!empty()) destroy(soo_slot());
2424
- common().set_empty_soo();
2630
+ } else if (is_small()) {
2631
+ if (!empty()) {
2632
+ destroy(single_slot());
2633
+ decrement_small_size();
2634
+ }
2425
2635
  } else {
2426
2636
  destroy_slots();
2427
2637
  clear_backing_array(/*reuse=*/cap < 128);
@@ -2491,13 +2701,13 @@ class raw_hash_set {
2491
2701
  // s.insert({"abc", 42});
2492
2702
  std::pair<iterator, bool> insert(init_type&& value)
2493
2703
  ABSL_ATTRIBUTE_LIFETIME_BOUND
2494
- #if __cplusplus >= 202002L
2704
+ #if ABSL_INTERNAL_CPLUSPLUS_LANG >= 202002L
2495
2705
  requires(!IsLifetimeBoundAssignmentFrom<init_type>::value)
2496
2706
  #endif
2497
2707
  {
2498
2708
  return emplace(std::move(value));
2499
2709
  }
2500
- #if __cplusplus >= 202002L
2710
+ #if ABSL_INTERNAL_CPLUSPLUS_LANG >= 202002L
2501
2711
  std::pair<iterator, bool> insert(
2502
2712
  init_type&& value ABSL_INTERNAL_ATTRIBUTE_CAPTURED_BY(this))
2503
2713
  ABSL_ATTRIBUTE_LIFETIME_BOUND
@@ -2540,17 +2750,17 @@ class raw_hash_set {
2540
2750
 
2541
2751
  template <class InputIt>
2542
2752
  void insert(InputIt first, InputIt last) {
2543
- for (; first != last; ++first) emplace(*first);
2753
+ insert_range(first, last);
2544
2754
  }
2545
2755
 
2546
2756
  template <class T, RequiresNotInit<T> = 0,
2547
2757
  std::enable_if_t<Insertable<const T&>::value, int> = 0>
2548
2758
  void insert(std::initializer_list<T> ilist) {
2549
- insert(ilist.begin(), ilist.end());
2759
+ insert_range(ilist.begin(), ilist.end());
2550
2760
  }
2551
2761
 
2552
2762
  void insert(std::initializer_list<init_type> ilist) {
2553
- insert(ilist.begin(), ilist.end());
2763
+ insert_range(ilist.begin(), ilist.end());
2554
2764
  }
2555
2765
 
2556
2766
  insert_return_type insert(node_type&& node) ABSL_ATTRIBUTE_LIFETIME_BOUND {
@@ -2697,26 +2907,23 @@ class raw_hash_set {
2697
2907
  // This overload is necessary because otherwise erase<K>(const K&) would be
2698
2908
  // a better match if non-const iterator is passed as an argument.
2699
2909
  void erase(iterator it) {
2910
+ ABSL_SWISSTABLE_ASSERT(capacity() > 0);
2700
2911
  AssertNotDebugCapacity();
2701
- AssertIsFull(it.control(), it.generation(), it.generation_ptr(), "erase()");
2912
+ it.assert_is_full("erase()");
2702
2913
  destroy(it.slot());
2703
- if (is_soo()) {
2704
- common().set_empty_soo();
2705
- } else {
2706
- erase_meta_only(it);
2707
- }
2914
+ erase_meta_only(it);
2708
2915
  }
2709
2916
 
2710
2917
  iterator erase(const_iterator first,
2711
2918
  const_iterator last) ABSL_ATTRIBUTE_LIFETIME_BOUND {
2712
2919
  AssertNotDebugCapacity();
2713
- // We check for empty first because clear_backing_array requires that
2714
- // capacity() > 0 as a precondition.
2920
+ // We check for empty and for is_small because clear_backing_array requires
2921
+ // that capacity() > MaxSmallCapacity() as a precondition.
2715
2922
  if (empty()) return end();
2716
2923
  if (first == last) return last.inner_;
2717
- if (is_soo()) {
2718
- destroy(soo_slot());
2719
- common().set_empty_soo();
2924
+ if (is_small()) {
2925
+ destroy(single_slot());
2926
+ erase_meta_only_small();
2720
2927
  return end();
2721
2928
  }
2722
2929
  if (first == begin() && last == end()) {
@@ -2736,8 +2943,11 @@ class raw_hash_set {
2736
2943
 
2737
2944
  // Moves elements from `src` into `this`.
2738
2945
  // If the element already exists in `this`, it is left unmodified in `src`.
2739
- template <typename H, typename E>
2740
- void merge(raw_hash_set<Policy, H, E, Alloc>& src) { // NOLINT
2946
+ template <
2947
+ typename... Params2,
2948
+ typename = std::enable_if_t<std::is_same_v<
2949
+ Alloc, typename raw_hash_set<Policy, Params2...>::allocator_type>>>
2950
+ void merge(raw_hash_set<Policy, Params2...>& src) { // NOLINT
2741
2951
  AssertNotDebugCapacity();
2742
2952
  src.AssertNotDebugCapacity();
2743
2953
  assert(this != &src);
@@ -2748,34 +2958,33 @@ class raw_hash_set {
2748
2958
  .second;
2749
2959
  };
2750
2960
 
2751
- if (src.is_soo()) {
2961
+ if (src.is_small()) {
2752
2962
  if (src.empty()) return;
2753
- if (insert_slot(src.soo_slot())) src.common().set_empty_soo();
2963
+ if (insert_slot(src.single_slot()))
2964
+ src.erase_meta_only_small();
2754
2965
  return;
2755
2966
  }
2756
2967
  for (auto it = src.begin(), e = src.end(); it != e;) {
2757
2968
  auto next = std::next(it);
2758
- if (insert_slot(it.slot())) src.erase_meta_only(it);
2969
+ if (insert_slot(it.slot())) src.erase_meta_only_large(it);
2759
2970
  it = next;
2760
2971
  }
2761
2972
  }
2762
2973
 
2763
- template <typename H, typename E>
2764
- void merge(raw_hash_set<Policy, H, E, Alloc>&& src) {
2974
+ template <
2975
+ typename... Params2,
2976
+ typename = std::enable_if_t<std::is_same_v<
2977
+ Alloc, typename raw_hash_set<Policy, Params2...>::allocator_type>>>
2978
+ void merge(raw_hash_set<Policy, Params2...>&& src) { // NOLINT
2765
2979
  merge(src);
2766
2980
  }
2767
2981
 
2768
2982
  node_type extract(const_iterator position) {
2769
2983
  AssertNotDebugCapacity();
2770
- AssertIsFull(position.control(), position.inner_.generation(),
2771
- position.inner_.generation_ptr(), "extract()");
2984
+ position.inner_.assert_is_full("extract()");
2772
2985
  allocator_type alloc(char_alloc_ref());
2773
2986
  auto node = CommonAccess::Transfer<node_type>(alloc, position.slot());
2774
- if (is_soo()) {
2775
- common().set_empty_soo();
2776
- } else {
2777
- erase_meta_only(position);
2778
- }
2987
+ erase_meta_only(position);
2779
2988
  return node;
2780
2989
  }
2781
2990
 
@@ -2787,9 +2996,9 @@ class raw_hash_set {
2787
2996
  }
2788
2997
 
2789
2998
  void swap(raw_hash_set& that) noexcept(
2790
- IsNoThrowSwappable<hasher>() && IsNoThrowSwappable<key_equal>() &&
2791
- IsNoThrowSwappable<allocator_type>(
2792
- typename AllocTraits::propagate_on_container_swap{})) {
2999
+ AllocTraits::is_always_equal::value &&
3000
+ std::is_nothrow_swappable<hasher>::value &&
3001
+ std::is_nothrow_swappable<key_equal>::value) {
2793
3002
  AssertNotDebugCapacity();
2794
3003
  that.AssertNotDebugCapacity();
2795
3004
  using std::swap;
@@ -2800,11 +3009,14 @@ class raw_hash_set {
2800
3009
  typename AllocTraits::propagate_on_container_swap{});
2801
3010
  }
2802
3011
 
2803
- void rehash(size_t n) { Rehash(common(), GetPolicyFunctions(), n); }
3012
+ void rehash(size_t n) {
3013
+ Rehash(common(), GetPolicyFunctions(), (std::min)(n, MaxValidCapacity()));
3014
+ }
2804
3015
 
2805
3016
  void reserve(size_t n) {
2806
3017
  if (ABSL_PREDICT_TRUE(n > DefaultCapacity())) {
2807
- ReserveTableToFitNewSize(common(), GetPolicyFunctions(), n);
3018
+ ReserveTableToFitNewSize(common(), GetPolicyFunctions(),
3019
+ (std::min)(n, MaxValidSize()));
2808
3020
  }
2809
3021
  }
2810
3022
 
@@ -2828,12 +3040,12 @@ class raw_hash_set {
2828
3040
  // NOTE: This is a very low level operation and should not be used without
2829
3041
  // specific benchmarks indicating its importance.
2830
3042
  template <class K = key_type>
2831
- void prefetch(const key_arg<K>& key) const {
3043
+ void prefetch([[maybe_unused]] const key_arg<K>& key) const {
2832
3044
  if (capacity() == DefaultCapacity()) return;
2833
- (void)key;
2834
3045
  // Avoid probing if we won't be able to prefetch the addresses received.
2835
3046
  #ifdef ABSL_HAVE_PREFETCH
2836
3047
  prefetch_heap_block();
3048
+ if (is_small()) return;
2837
3049
  auto seq = probe(common(), hash_of(key));
2838
3050
  PrefetchToLocalCache(control() + seq.offset());
2839
3051
  PrefetchToLocalCache(slot_array() + seq.offset());
@@ -2851,7 +3063,7 @@ class raw_hash_set {
2851
3063
  template <class K = key_type>
2852
3064
  iterator find(const key_arg<K>& key) ABSL_ATTRIBUTE_LIFETIME_BOUND {
2853
3065
  AssertOnFind(key);
2854
- if (capacity() <= 1) return find_small(key);
3066
+ if (is_small()) return find_small(key);
2855
3067
  prefetch_heap_block();
2856
3068
  return find_large(key, hash_of(key));
2857
3069
  }
@@ -2960,24 +3172,6 @@ class raw_hash_set {
2960
3172
  const raw_hash_set& s;
2961
3173
  };
2962
3174
 
2963
- struct HashElement {
2964
- template <class K, class... Args>
2965
- size_t operator()(const K& key, Args&&...) const {
2966
- return h(key);
2967
- }
2968
- const hasher& h;
2969
- };
2970
-
2971
- template <class K1>
2972
- struct EqualElement {
2973
- template <class K2, class... Args>
2974
- bool operator()(const K2& lhs, Args&&...) const {
2975
- ABSL_SWISSTABLE_IGNORE_UNINITIALIZED_RETURN(eq(lhs, rhs));
2976
- }
2977
- const K1& rhs;
2978
- const key_equal& eq;
2979
- };
2980
-
2981
3175
  struct EmplaceDecomposable {
2982
3176
  template <class K, class... Args>
2983
3177
  std::pair<iterator, bool> operator()(const K& key, Args&&... args) const {
@@ -3031,18 +3225,13 @@ class raw_hash_set {
3031
3225
  // SOO functionality.
3032
3226
  template <class K = key_type>
3033
3227
  iterator find_small(const key_arg<K>& key) {
3034
- ABSL_SWISSTABLE_ASSERT(capacity() <= 1);
3035
- return empty() || !PolicyTraits::apply(
3036
- EqualElement<K>{key, eq_ref()},
3037
- PolicyTraits::element(single_slot()))
3038
- ? end()
3039
- : single_iterator();
3228
+ ABSL_SWISSTABLE_ASSERT(is_small());
3229
+ return empty() || !equal_to(key, single_slot()) ? end() : single_iterator();
3040
3230
  }
3041
3231
 
3042
3232
  template <class K = key_type>
3043
3233
  iterator find_large(const key_arg<K>& key, size_t hash) {
3044
- ABSL_SWISSTABLE_ASSERT(capacity() > 1);
3045
- ABSL_SWISSTABLE_ASSERT(!is_soo());
3234
+ ABSL_SWISSTABLE_ASSERT(!is_small());
3046
3235
  auto seq = probe(common(), hash);
3047
3236
  const h2_t h2 = H2(hash);
3048
3237
  const ctrl_t* ctrl = control();
@@ -3052,9 +3241,7 @@ class raw_hash_set {
3052
3241
  #endif
3053
3242
  Group g{ctrl + seq.offset()};
3054
3243
  for (uint32_t i : g.Match(h2)) {
3055
- if (ABSL_PREDICT_TRUE(PolicyTraits::apply(
3056
- EqualElement<K>{key, eq_ref()},
3057
- PolicyTraits::element(slot_array() + seq.offset(i)))))
3244
+ if (ABSL_PREDICT_TRUE(equal_to(key, slot_array() + seq.offset(i))))
3058
3245
  return iterator_at(seq.offset(i));
3059
3246
  }
3060
3247
  if (ABSL_PREDICT_TRUE(g.MaskEmpty())) return end();
@@ -3063,30 +3250,42 @@ class raw_hash_set {
3063
3250
  }
3064
3251
  }
3065
3252
 
3066
- // Returns true if the table needs to be sampled.
3253
+ // Returns true if the table needs to be sampled. This keeps track of whether
3254
+ // sampling has already been evaluated and ensures that it can only return
3255
+ // true on its first evaluation. All subsequent calls will return false.
3256
+ //
3067
3257
  // This should be called on insertion into an empty SOO table and in copy
3068
3258
  // construction when the size can fit in SOO capacity.
3069
- bool should_sample_soo() const {
3259
+ bool should_sample_soo() {
3070
3260
  ABSL_SWISSTABLE_ASSERT(is_soo());
3071
- if (!ShouldSampleHashtablezInfoForAlloc<CharAlloc>()) return false;
3261
+ if constexpr (!ShouldSampleHashtablezInfoForAlloc<CharAlloc>()) {
3262
+ return false;
3263
+ }
3264
+ if (common().soo_has_tried_sampling()) {
3265
+ // Already evaluated sampling on this SOO table; do not re-evaluate
3266
+ // sampling each time it transitions from empty to full SOO state.
3267
+ return false;
3268
+ }
3269
+ // TODO: b/396049910 -- consider managing this flag on the 1->0 size
3270
+ // transition of SOO tables rather than the 0->1 transition.
3271
+ common().set_soo_has_tried_sampling();
3072
3272
  return ABSL_PREDICT_FALSE(ShouldSampleNextTable());
3073
3273
  }
3074
3274
 
3075
3275
  void clear_backing_array(bool reuse) {
3076
- ABSL_SWISSTABLE_ASSERT(capacity() > DefaultCapacity());
3077
- ClearBackingArray(common(), GetPolicyFunctions(), &char_alloc_ref(), reuse,
3078
- SooEnabled());
3276
+ ABSL_SWISSTABLE_ASSERT(capacity() > MaxSmallCapacity());
3277
+ ClearBackingArray(common(), GetPolicyFunctions(), &char_alloc_ref(), reuse);
3079
3278
  }
3080
3279
 
3081
3280
  void destroy_slots() {
3082
- ABSL_SWISSTABLE_ASSERT(!is_soo());
3281
+ ABSL_SWISSTABLE_ASSERT(!is_small());
3083
3282
  if (PolicyTraits::template destroy_is_trivial<Alloc>()) return;
3084
3283
  auto destroy_slot = [&](const ctrl_t*, void* slot) {
3085
3284
  this->destroy(static_cast<slot_type*>(slot));
3086
3285
  };
3087
3286
  if constexpr (SwisstableAssertAccessToDestroyedTable()) {
3088
3287
  CommonFields common_copy(non_soo_tag_t{}, this->common());
3089
- common().set_capacity(InvalidCapacity::kDestroyed);
3288
+ common().set_capacity(HashtableCapacity::CreateDestroyed());
3090
3289
  IterateOverFullSlots(common_copy, sizeof(slot_type), destroy_slot);
3091
3290
  common().set_capacity(common_copy.capacity());
3092
3291
  } else {
@@ -3107,17 +3306,18 @@ class raw_hash_set {
3107
3306
 
3108
3307
  void destructor_impl() {
3109
3308
  if (SwisstableGenerationsEnabled() &&
3110
- capacity() >= InvalidCapacity::kMovedFrom) {
3309
+ maybe_invalid_capacity().IsMovedFrom()) {
3111
3310
  return;
3112
3311
  }
3113
3312
  if (capacity() == 0) return;
3114
- if (is_soo()) {
3313
+ if (is_small()) {
3115
3314
  if (!empty()) {
3116
- ABSL_SWISSTABLE_IGNORE_UNINITIALIZED(destroy(soo_slot()));
3315
+ ABSL_SWISSTABLE_IGNORE_UNINITIALIZED(destroy(single_slot()));
3117
3316
  }
3118
- return;
3317
+ if constexpr (SooEnabled()) return;
3318
+ } else {
3319
+ destroy_slots();
3119
3320
  }
3120
- destroy_slots();
3121
3321
  dealloc();
3122
3322
  }
3123
3323
 
@@ -3126,23 +3326,41 @@ class raw_hash_set {
3126
3326
  // This merely updates the pertinent control byte. This can be used in
3127
3327
  // conjunction with Policy::transfer to move the object to another place.
3128
3328
  void erase_meta_only(const_iterator it) {
3129
- ABSL_SWISSTABLE_ASSERT(!is_soo());
3130
- EraseMetaOnly(common(), static_cast<size_t>(it.control() - control()),
3131
- sizeof(slot_type));
3329
+ if (is_small()) {
3330
+ erase_meta_only_small();
3331
+ return;
3332
+ }
3333
+ erase_meta_only_large(it);
3334
+ }
3335
+ void erase_meta_only_small() {
3336
+ EraseMetaOnlySmall(common(), SooEnabled(), sizeof(slot_type));
3337
+ }
3338
+ void erase_meta_only_large(const_iterator it) {
3339
+ EraseMetaOnlyLarge(common(), it.control(), sizeof(slot_type));
3132
3340
  }
3133
3341
 
3134
3342
  template <class K>
3135
- size_t hash_of(const K& key) const {
3136
- return hash_ref()(key);
3137
- }
3138
- size_t hash_of(slot_type* slot) const {
3139
- return PolicyTraits::apply(HashElement{hash_ref()},
3343
+ ABSL_ATTRIBUTE_ALWAYS_INLINE bool equal_to(const K& key,
3344
+ slot_type* slot) const {
3345
+ return PolicyTraits::apply(EqualElement<K, key_equal>{key, eq_ref()},
3140
3346
  PolicyTraits::element(slot));
3141
3347
  }
3348
+ template <class K>
3349
+ ABSL_ATTRIBUTE_ALWAYS_INLINE size_t hash_of(const K& key) const {
3350
+ return HashElement<hasher, kIsDefaultHash>{hash_ref(),
3351
+ common().seed().seed()}(key);
3352
+ }
3353
+ ABSL_ATTRIBUTE_ALWAYS_INLINE size_t hash_of(slot_type* slot) const {
3354
+ return PolicyTraits::apply(
3355
+ HashElement<hasher, kIsDefaultHash>{hash_ref(), common().seed().seed()},
3356
+ PolicyTraits::element(slot));
3357
+ }
3142
3358
 
3143
3359
  // Casting directly from e.g. char* to slot_type* can cause compilation errors
3144
3360
  // on objective-C. This function converts to void* first, avoiding the issue.
3145
- static slot_type* to_slot(void* buf) { return static_cast<slot_type*>(buf); }
3361
+ static ABSL_ATTRIBUTE_ALWAYS_INLINE slot_type* to_slot(void* buf) {
3362
+ return static_cast<slot_type*>(buf);
3363
+ }
3146
3364
 
3147
3365
  // Requires that lhs does not have a full SOO slot.
3148
3366
  static void move_common(bool rhs_is_full_soo, CharAlloc& rhs_alloc,
@@ -3178,17 +3396,18 @@ class raw_hash_set {
3178
3396
  std::move(tmp));
3179
3397
  }
3180
3398
 
3181
- void annotate_for_bug_detection_on_move(
3182
- ABSL_ATTRIBUTE_UNUSED raw_hash_set& that) {
3399
+ void annotate_for_bug_detection_on_move([[maybe_unused]] raw_hash_set& that) {
3183
3400
  // We only enable moved-from validation when generations are enabled (rather
3184
3401
  // than using NDEBUG) to avoid issues in which NDEBUG is enabled in some
3185
3402
  // translation units but not in others.
3186
3403
  if (SwisstableGenerationsEnabled()) {
3187
- that.common().set_capacity(this == &that ? InvalidCapacity::kSelfMovedFrom
3188
- : InvalidCapacity::kMovedFrom);
3404
+ that.common().set_capacity(this == &that
3405
+ ? HashtableCapacity::CreateSelfMovedFrom()
3406
+ : HashtableCapacity::CreateMovedFrom());
3189
3407
  }
3190
- if (!SwisstableGenerationsEnabled() || capacity() == DefaultCapacity() ||
3191
- capacity() > kAboveMaxValidCapacity) {
3408
+ if (!SwisstableGenerationsEnabled() ||
3409
+ !maybe_invalid_capacity().IsValid() ||
3410
+ capacity() == DefaultCapacity()) {
3192
3411
  return;
3193
3412
  }
3194
3413
  common().increment_generation();
@@ -3250,64 +3469,102 @@ class raw_hash_set {
3250
3469
 
3251
3470
  template <class K>
3252
3471
  std::pair<iterator, bool> find_or_prepare_insert_soo(const K& key) {
3253
- ctrl_t soo_slot_ctrl;
3472
+ ABSL_SWISSTABLE_ASSERT(is_soo());
3473
+ bool force_sampling;
3254
3474
  if (empty()) {
3255
3475
  if (!should_sample_soo()) {
3256
3476
  common().set_full_soo();
3257
- return {soo_iterator(), true};
3477
+ return {single_iterator(), true};
3258
3478
  }
3259
- soo_slot_ctrl = ctrl_t::kEmpty;
3260
- } else if (PolicyTraits::apply(EqualElement<K>{key, eq_ref()},
3261
- PolicyTraits::element(soo_slot()))) {
3262
- return {soo_iterator(), false};
3479
+ force_sampling = true;
3480
+ } else if (equal_to(key, single_slot())) {
3481
+ return {single_iterator(), false};
3263
3482
  } else {
3264
- soo_slot_ctrl = static_cast<ctrl_t>(H2(hash_of(soo_slot())));
3483
+ force_sampling = false;
3265
3484
  }
3485
+ ABSL_SWISSTABLE_ASSERT(capacity() == 1);
3266
3486
  constexpr bool kUseMemcpy =
3267
3487
  PolicyTraits::transfer_uses_memcpy() && SooEnabled();
3268
3488
  size_t index = GrowSooTableToNextCapacityAndPrepareInsert<
3269
3489
  kUseMemcpy ? OptimalMemcpySizeForSooSlotTransfer(sizeof(slot_type)) : 0,
3270
- kUseMemcpy>(common(), GetPolicyFunctions(), hash_of(key),
3271
- soo_slot_ctrl);
3490
+ kUseMemcpy>(common(), GetPolicyFunctions(),
3491
+ HashKey<hasher, K, kIsDefaultHash>{hash_ref(), key},
3492
+ force_sampling);
3272
3493
  return {iterator_at(index), true};
3273
3494
  }
3274
3495
 
3275
3496
  template <class K>
3276
- std::pair<iterator, bool> find_or_prepare_insert_non_soo(const K& key) {
3497
+ std::pair<iterator, bool> find_or_prepare_insert_small(const K& key) {
3498
+ ABSL_SWISSTABLE_ASSERT(is_small());
3499
+ if constexpr (SooEnabled()) {
3500
+ return find_or_prepare_insert_soo(key);
3501
+ }
3502
+ if (!empty()) {
3503
+ if (equal_to(key, single_slot())) {
3504
+ return {single_iterator(), false};
3505
+ }
3506
+ }
3507
+ return {iterator_at_ptr(PrepareInsertSmallNonSoo(
3508
+ common(), GetPolicyFunctions(),
3509
+ HashKey<hasher, K, kIsDefaultHash>{hash_ref(), key})),
3510
+ true};
3511
+ }
3512
+
3513
+ template <class K>
3514
+ std::pair<iterator, bool> find_or_prepare_insert_large(const K& key) {
3277
3515
  ABSL_SWISSTABLE_ASSERT(!is_soo());
3278
3516
  prefetch_heap_block();
3279
3517
  const size_t hash = hash_of(key);
3280
3518
  auto seq = probe(common(), hash);
3281
3519
  const h2_t h2 = H2(hash);
3282
3520
  const ctrl_t* ctrl = control();
3283
- while (true) {
3521
+ size_t index;
3522
+ bool inserted;
3523
+ // We use a lambda function to be able to exit from the nested loop without
3524
+ // duplicating generated code for the return statement (e.g. iterator_at).
3525
+ [&]() ABSL_ATTRIBUTE_ALWAYS_INLINE {
3526
+ while (true) {
3284
3527
  #ifndef ABSL_HAVE_MEMORY_SANITIZER
3285
- absl::PrefetchToLocalCache(slot_array() + seq.offset());
3528
+ absl::PrefetchToLocalCache(slot_array() + seq.offset());
3286
3529
  #endif
3287
- Group g{ctrl + seq.offset()};
3288
- for (uint32_t i : g.Match(h2)) {
3289
- if (ABSL_PREDICT_TRUE(PolicyTraits::apply(
3290
- EqualElement<K>{key, eq_ref()},
3291
- PolicyTraits::element(slot_array() + seq.offset(i)))))
3292
- return {iterator_at(seq.offset(i)), false};
3293
- }
3294
- auto mask_empty = g.MaskEmpty();
3295
- if (ABSL_PREDICT_TRUE(mask_empty)) {
3296
- size_t target = seq.offset(mask_empty.LowestBitSet());
3297
- return {iterator_at(PrepareInsertNonSoo(common(), GetPolicyFunctions(),
3298
- hash,
3299
- FindInfo{target, seq.index()})),
3300
- true};
3530
+ Group g{ctrl + seq.offset()};
3531
+ for (uint32_t i : g.Match(h2)) {
3532
+ if (ABSL_PREDICT_TRUE(equal_to(key, slot_array() + seq.offset(i)))) {
3533
+ index = seq.offset(i);
3534
+ inserted = false;
3535
+ return;
3536
+ }
3537
+ }
3538
+ auto mask_empty = g.MaskEmpty();
3539
+ if (ABSL_PREDICT_TRUE(mask_empty)) {
3540
+ size_t target_group_offset = seq.offset();
3541
+ index = SwisstableGenerationsEnabled()
3542
+ ? PrepareInsertLargeGenerationsEnabled(
3543
+ common(), GetPolicyFunctions(), hash, mask_empty,
3544
+ FindInfo{target_group_offset, seq.index()},
3545
+ HashKey<hasher, K, kIsDefaultHash>{hash_ref(), key})
3546
+ : PrepareInsertLarge(
3547
+ common(), GetPolicyFunctions(), hash, mask_empty,
3548
+ FindInfo{target_group_offset, seq.index()});
3549
+ inserted = true;
3550
+ return;
3551
+ }
3552
+ seq.next();
3553
+ ABSL_SWISSTABLE_ASSERT(seq.index() <= capacity() && "full table!");
3301
3554
  }
3302
- seq.next();
3303
- ABSL_SWISSTABLE_ASSERT(seq.index() <= capacity() && "full table!");
3304
- }
3555
+ }();
3556
+ return {iterator_at(index), inserted};
3557
+ }
3558
+
3559
+ template <class InputIt>
3560
+ void insert_range(InputIt first, InputIt last) {
3561
+ for (; first != last; ++first) emplace(*first);
3305
3562
  }
3306
3563
 
3307
3564
  protected:
3308
3565
  // Asserts for correctness that we run on find/find_or_prepare_insert.
3309
3566
  template <class K>
3310
- void AssertOnFind(ABSL_ATTRIBUTE_UNUSED const K& key) {
3567
+ void AssertOnFind([[maybe_unused]] const K& key) {
3311
3568
  AssertHashEqConsistent(key);
3312
3569
  AssertNotDebugCapacity();
3313
3570
  }
@@ -3319,21 +3576,21 @@ class raw_hash_set {
3319
3576
  return;
3320
3577
  }
3321
3578
  #endif
3322
- if (ABSL_PREDICT_TRUE(capacity() <
3323
- InvalidCapacity::kAboveMaxValidCapacity)) {
3579
+ const HashtableCapacity cap = maybe_invalid_capacity();
3580
+ if (ABSL_PREDICT_TRUE(cap.IsValid())) {
3324
3581
  return;
3325
3582
  }
3326
- assert(capacity() != InvalidCapacity::kReentrance &&
3583
+ assert(!cap.IsReentrance() &&
3327
3584
  "Reentrant container access during element construction/destruction "
3328
3585
  "is not allowed.");
3329
3586
  if constexpr (SwisstableAssertAccessToDestroyedTable()) {
3330
- if (capacity() == InvalidCapacity::kDestroyed) {
3587
+ if (cap.IsDestroyed()) {
3331
3588
  ABSL_RAW_LOG(FATAL, "Use of destroyed hash table.");
3332
3589
  }
3333
3590
  }
3334
3591
  if (SwisstableGenerationsEnabled() &&
3335
- ABSL_PREDICT_FALSE(capacity() >= InvalidCapacity::kMovedFrom)) {
3336
- if (capacity() == InvalidCapacity::kSelfMovedFrom) {
3592
+ ABSL_PREDICT_FALSE(cap.IsMovedFrom())) {
3593
+ if (cap.IsSelfMovedFrom()) {
3337
3594
  // If this log triggers, then a hash table was move-assigned to itself
3338
3595
  // and then used again later without being reinitialized.
3339
3596
  ABSL_RAW_LOG(FATAL, "Use of self-move-assigned hash table.");
@@ -3363,23 +3620,18 @@ class raw_hash_set {
3363
3620
 
3364
3621
  const size_t hash_of_arg = hash_of(key);
3365
3622
  const auto assert_consistent = [&](const ctrl_t*, void* slot) {
3366
- const value_type& element =
3367
- PolicyTraits::element(static_cast<slot_type*>(slot));
3368
- const bool is_key_equal =
3369
- PolicyTraits::apply(EqualElement<K>{key, eq_ref()}, element);
3623
+ const bool is_key_equal = equal_to(key, to_slot(slot));
3370
3624
  if (!is_key_equal) return;
3371
3625
 
3372
- const size_t hash_of_slot =
3373
- PolicyTraits::apply(HashElement{hash_ref()}, element);
3374
- ABSL_ATTRIBUTE_UNUSED const bool is_hash_equal =
3375
- hash_of_arg == hash_of_slot;
3626
+ [[maybe_unused]] const bool is_hash_equal =
3627
+ hash_of_arg == hash_of(to_slot(slot));
3376
3628
  assert((!is_key_equal || is_hash_equal) &&
3377
3629
  "eq(k1, k2) must imply that hash(k1) == hash(k2). "
3378
3630
  "hash/eq functors are inconsistent.");
3379
3631
  };
3380
3632
 
3381
- if (is_soo()) {
3382
- assert_consistent(/*unused*/ nullptr, soo_slot());
3633
+ if (is_small()) {
3634
+ assert_consistent(/*unused*/ nullptr, single_slot());
3383
3635
  return;
3384
3636
  }
3385
3637
  // We only do validation for small tables so that it's constant time.
@@ -3393,8 +3645,8 @@ class raw_hash_set {
3393
3645
  template <class K>
3394
3646
  std::pair<iterator, bool> find_or_prepare_insert(const K& key) {
3395
3647
  AssertOnFind(key);
3396
- if (is_soo()) return find_or_prepare_insert_soo(key);
3397
- return find_or_prepare_insert_non_soo(key);
3648
+ if (is_small()) return find_or_prepare_insert_small(key);
3649
+ return find_or_prepare_insert_large(key);
3398
3650
  }
3399
3651
 
3400
3652
  // Constructs the value in the space pointed by the iterator. This only works
@@ -3409,9 +3661,9 @@ class raw_hash_set {
3409
3661
  void emplace_at(iterator iter, Args&&... args) {
3410
3662
  construct(iter.slot(), std::forward<Args>(args)...);
3411
3663
 
3412
- // When capacity is 1, find calls find_small and if size is 0, then it will
3664
+ // When is_small, find calls find_small and if size is 0, then it will
3413
3665
  // return an end iterator. This can happen in the raw_hash_set copy ctor.
3414
- assert((capacity() == 1 ||
3666
+ assert((is_small() ||
3415
3667
  PolicyTraits::apply(FindElement{*this}, *iter) == iter) &&
3416
3668
  "constructed value does not match the lookup key");
3417
3669
  }
@@ -3422,6 +3674,10 @@ class raw_hash_set {
3422
3674
  const_iterator iterator_at(size_t i) const ABSL_ATTRIBUTE_LIFETIME_BOUND {
3423
3675
  return const_cast<raw_hash_set*>(this)->iterator_at(i);
3424
3676
  }
3677
+ iterator iterator_at_ptr(std::pair<ctrl_t*, void*> ptrs)
3678
+ ABSL_ATTRIBUTE_LIFETIME_BOUND {
3679
+ return {ptrs.first, to_slot(ptrs.second), common().generation_ptr()};
3680
+ }
3425
3681
 
3426
3682
  reference unchecked_deref(iterator it) { return it.unchecked_deref(); }
3427
3683
 
@@ -3439,16 +3695,13 @@ class raw_hash_set {
3439
3695
  //
3440
3696
  // See `CapacityToGrowth()`.
3441
3697
  size_t growth_left() const {
3442
- ABSL_SWISSTABLE_ASSERT(!is_soo());
3443
3698
  return common().growth_left();
3444
3699
  }
3445
3700
 
3446
3701
  GrowthInfo& growth_info() {
3447
- ABSL_SWISSTABLE_ASSERT(!is_soo());
3448
3702
  return common().growth_info();
3449
3703
  }
3450
3704
  GrowthInfo growth_info() const {
3451
- ABSL_SWISSTABLE_ASSERT(!is_soo());
3452
3705
  return common().growth_info();
3453
3706
  }
3454
3707
 
@@ -3465,6 +3718,11 @@ class raw_hash_set {
3465
3718
  CommonFields& common() { return settings_.template get<0>(); }
3466
3719
  const CommonFields& common() const { return settings_.template get<0>(); }
3467
3720
 
3721
+ // For use when the capacity is potentially invalid we return
3722
+ // HashtableCapacity directly.
3723
+ HashtableCapacity maybe_invalid_capacity() const {
3724
+ return common().maybe_invalid_capacity();
3725
+ }
3468
3726
  ctrl_t* control() const {
3469
3727
  ABSL_SWISSTABLE_ASSERT(!is_soo());
3470
3728
  return common().control();
@@ -3482,22 +3740,22 @@ class raw_hash_set {
3482
3740
  ABSL_SWISSTABLE_IGNORE_UNINITIALIZED_RETURN(
3483
3741
  const_cast<raw_hash_set*>(this)->soo_slot());
3484
3742
  }
3485
- iterator soo_iterator() {
3486
- return {SooControl(), soo_slot(), common().generation_ptr()};
3487
- }
3488
- const_iterator soo_iterator() const {
3489
- return const_cast<raw_hash_set*>(this)->soo_iterator();
3490
- }
3491
3743
  slot_type* single_slot() {
3492
- ABSL_SWISSTABLE_ASSERT(capacity() <= 1);
3744
+ ABSL_SWISSTABLE_ASSERT(is_small());
3493
3745
  return SooEnabled() ? soo_slot() : slot_array();
3494
3746
  }
3495
3747
  const slot_type* single_slot() const {
3496
3748
  return const_cast<raw_hash_set*>(this)->single_slot();
3497
3749
  }
3750
+ void decrement_small_size() {
3751
+ ABSL_SWISSTABLE_ASSERT(is_small());
3752
+ SooEnabled() ? common().set_empty_soo() : common().decrement_size();
3753
+ if (!SooEnabled()) {
3754
+ SanitizerPoisonObject(single_slot());
3755
+ }
3756
+ }
3498
3757
  iterator single_iterator() {
3499
- return {SooEnabled() ? SooControl() : control(), single_slot(),
3500
- common().generation_ptr()};
3758
+ return {SooControl(), single_slot(), common().generation_ptr()};
3501
3759
  }
3502
3760
  const_iterator single_iterator() const {
3503
3761
  return const_cast<raw_hash_set*>(this)->single_iterator();
@@ -3554,8 +3812,6 @@ class raw_hash_set {
3554
3812
  ctrl_t* new_ctrl = common.control();
3555
3813
  slot_type* new_slots = set->slot_array();
3556
3814
 
3557
- const PerTableSeed seed = common.seed();
3558
-
3559
3815
  for (size_t group_index = 0; group_index < old_capacity;
3560
3816
  group_index += Group::kWidth) {
3561
3817
  GroupFullEmptyOrDeleted old_g(old_ctrl + group_index);
@@ -3571,7 +3827,7 @@ class raw_hash_set {
3571
3827
  // TODO(b/382423690): try to avoid entire hash calculation since we need
3572
3828
  // only one new bit of h1.
3573
3829
  size_t hash = set->hash_of(old_slot);
3574
- size_t h1 = H1(hash, seed);
3830
+ size_t h1 = H1(hash);
3575
3831
  h2_t h2 = H2(hash);
3576
3832
  size_t new_index = TryFindNewIndexWithoutProbing(
3577
3833
  h1, old_index, old_capacity, new_ctrl, new_capacity);
@@ -3614,7 +3870,7 @@ class raw_hash_set {
3614
3870
  // for standard layout and alignof(Hash) <= alignof(CommonFields).
3615
3871
  std::is_empty_v<hasher> ? &GetRefForEmptyClass
3616
3872
  : &raw_hash_set::get_hash_ref_fn,
3617
- PolicyTraits::template get_hash_slot_fn<hasher>(),
3873
+ PolicyTraits::template get_hash_slot_fn<hasher, kIsDefaultHash>(),
3618
3874
  PolicyTraits::transfer_uses_memcpy()
3619
3875
  ? TransferNRelocatable<sizeof(slot_type)>
3620
3876
  : &raw_hash_set::transfer_n_slots_fn,
@@ -3642,18 +3898,18 @@ struct HashtableFreeFunctionsAccess {
3642
3898
  if (c->empty()) {
3643
3899
  return 0;
3644
3900
  }
3645
- if (c->is_soo()) {
3646
- auto it = c->soo_iterator();
3901
+ if (c->is_small()) {
3902
+ auto it = c->single_iterator();
3647
3903
  if (!pred(*it)) {
3648
3904
  ABSL_SWISSTABLE_ASSERT(c->size() == 1 &&
3649
3905
  "hash table was modified unexpectedly");
3650
3906
  return 0;
3651
3907
  }
3652
3908
  c->destroy(it.slot());
3653
- c->common().set_empty_soo();
3909
+ c->erase_meta_only_small();
3654
3910
  return 1;
3655
3911
  }
3656
- ABSL_ATTRIBUTE_UNUSED const size_t original_size_for_assert = c->size();
3912
+ [[maybe_unused]] const size_t original_size_for_assert = c->size();
3657
3913
  size_t num_deleted = 0;
3658
3914
  using SlotType = typename Set::slot_type;
3659
3915
  IterateOverFullSlots(
@@ -3662,8 +3918,7 @@ struct HashtableFreeFunctionsAccess {
3662
3918
  auto* slot = static_cast<SlotType*>(slot_void);
3663
3919
  if (pred(Set::PolicyTraits::element(slot))) {
3664
3920
  c->destroy(slot);
3665
- EraseMetaOnly(c->common(), static_cast<size_t>(ctrl - c->control()),
3666
- sizeof(*slot));
3921
+ EraseMetaOnlyLarge(c->common(), ctrl, sizeof(*slot));
3667
3922
  ++num_deleted;
3668
3923
  }
3669
3924
  });
@@ -3680,8 +3935,8 @@ struct HashtableFreeFunctionsAccess {
3680
3935
  if (c->empty()) {
3681
3936
  return;
3682
3937
  }
3683
- if (c->is_soo()) {
3684
- cb(*c->soo_iterator());
3938
+ if (c->is_small()) {
3939
+ cb(*c->single_iterator());
3685
3940
  return;
3686
3941
  }
3687
3942
  using SlotType = typename Set::slot_type;
@@ -3696,31 +3951,33 @@ struct HashtableFreeFunctionsAccess {
3696
3951
  };
3697
3952
 
3698
3953
  // Erases all elements that satisfy the predicate `pred` from the container `c`.
3699
- template <typename P, typename H, typename E, typename A, typename Predicate>
3700
- typename raw_hash_set<P, H, E, A>::size_type EraseIf(
3701
- Predicate& pred, raw_hash_set<P, H, E, A>* c) {
3954
+ template <typename P, typename... Params, typename Predicate>
3955
+ typename raw_hash_set<P, Params...>::size_type EraseIf(
3956
+ Predicate& pred, raw_hash_set<P, Params...>* c) {
3702
3957
  return HashtableFreeFunctionsAccess::EraseIf(pred, c);
3703
3958
  }
3704
3959
 
3705
3960
  // Calls `cb` for all elements in the container `c`.
3706
- template <typename P, typename H, typename E, typename A, typename Callback>
3707
- void ForEach(Callback& cb, raw_hash_set<P, H, E, A>* c) {
3961
+ template <typename P, typename... Params, typename Callback>
3962
+ void ForEach(Callback& cb, raw_hash_set<P, Params...>* c) {
3708
3963
  return HashtableFreeFunctionsAccess::ForEach(cb, c);
3709
3964
  }
3710
- template <typename P, typename H, typename E, typename A, typename Callback>
3711
- void ForEach(Callback& cb, const raw_hash_set<P, H, E, A>* c) {
3965
+ template <typename P, typename... Params, typename Callback>
3966
+ void ForEach(Callback& cb, const raw_hash_set<P, Params...>* c) {
3712
3967
  return HashtableFreeFunctionsAccess::ForEach(cb, c);
3713
3968
  }
3714
3969
 
3715
3970
  namespace hashtable_debug_internal {
3716
3971
  template <typename Set>
3717
- struct HashtableDebugAccess<Set, absl::void_t<typename Set::raw_hash_set>> {
3972
+ struct HashtableDebugAccess<Set, std::void_t<typename Set::raw_hash_set>> {
3718
3973
  using Traits = typename Set::PolicyTraits;
3719
3974
  using Slot = typename Traits::slot_type;
3720
3975
 
3976
+ constexpr static bool kIsDefaultHash = Set::kIsDefaultHash;
3977
+
3721
3978
  static size_t GetNumProbes(const Set& set,
3722
3979
  const typename Set::key_type& key) {
3723
- if (set.is_soo()) return 0;
3980
+ if (set.is_small()) return 0;
3724
3981
  size_t num_probes = 0;
3725
3982
  const size_t hash = set.hash_of(key);
3726
3983
  auto seq = probe(set.common(), hash);
@@ -3729,10 +3986,7 @@ struct HashtableDebugAccess<Set, absl::void_t<typename Set::raw_hash_set>> {
3729
3986
  while (true) {
3730
3987
  container_internal::Group g{ctrl + seq.offset()};
3731
3988
  for (uint32_t i : g.Match(h2)) {
3732
- if (Traits::apply(
3733
- typename Set::template EqualElement<typename Set::key_type>{
3734
- key, set.eq_ref()},
3735
- Traits::element(set.slot_array() + seq.offset(i))))
3989
+ if (set.equal_to(key, set.slot_array() + seq.offset(i)))
3736
3990
  return num_probes;
3737
3991
  ++num_probes;
3738
3992
  }
@@ -3765,18 +4019,31 @@ struct HashtableDebugAccess<Set, absl::void_t<typename Set::raw_hash_set>> {
3765
4019
  // Extern template instantiations reduce binary size and linker input size.
3766
4020
  // Function definition is in raw_hash_set.cc.
3767
4021
  extern template size_t GrowSooTableToNextCapacityAndPrepareInsert<0, false>(
3768
- CommonFields&, const PolicyFunctions&, size_t, ctrl_t);
4022
+ CommonFields&, const PolicyFunctions&, absl::FunctionRef<size_t(size_t)>,
4023
+ bool);
3769
4024
  extern template size_t GrowSooTableToNextCapacityAndPrepareInsert<1, true>(
3770
- CommonFields&, const PolicyFunctions&, size_t, ctrl_t);
4025
+ CommonFields&, const PolicyFunctions&, absl::FunctionRef<size_t(size_t)>,
4026
+ bool);
3771
4027
  extern template size_t GrowSooTableToNextCapacityAndPrepareInsert<4, true>(
3772
- CommonFields&, const PolicyFunctions&, size_t, ctrl_t);
4028
+ CommonFields&, const PolicyFunctions&, absl::FunctionRef<size_t(size_t)>,
4029
+ bool);
3773
4030
  extern template size_t GrowSooTableToNextCapacityAndPrepareInsert<8, true>(
3774
- CommonFields&, const PolicyFunctions&, size_t, ctrl_t);
4031
+ CommonFields&, const PolicyFunctions&, absl::FunctionRef<size_t(size_t)>,
4032
+ bool);
3775
4033
  #if UINTPTR_MAX == UINT64_MAX
3776
4034
  extern template size_t GrowSooTableToNextCapacityAndPrepareInsert<16, true>(
3777
- CommonFields&, const PolicyFunctions&, size_t, ctrl_t);
4035
+ CommonFields&, const PolicyFunctions&, absl::FunctionRef<size_t(size_t)>,
4036
+ bool);
3778
4037
  #endif
3779
4038
 
4039
+ extern template void* AllocateBackingArray<
4040
+ BackingArrayAlignment(alignof(size_t)), std::allocator<char>>(void* alloc,
4041
+ size_t n);
4042
+ extern template void DeallocateBackingArray<
4043
+ BackingArrayAlignment(alignof(size_t)), std::allocator<char>>(
4044
+ void* alloc, size_t capacity, ctrl_t* ctrl, size_t slot_size,
4045
+ size_t slot_align, bool had_infoz);
4046
+
3780
4047
  } // namespace container_internal
3781
4048
  ABSL_NAMESPACE_END
3782
4049
  } // namespace absl