grpc 1.71.0 → 1.74.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1726) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +129 -88
  3. data/include/grpc/create_channel_from_endpoint.h +54 -0
  4. data/include/grpc/credentials.h +11 -5
  5. data/include/grpc/event_engine/event_engine.h +182 -8
  6. data/include/grpc/event_engine/internal/write_event.h +34 -0
  7. data/include/grpc/event_engine/memory_request.h +3 -3
  8. data/include/grpc/grpc_posix.h +20 -1
  9. data/include/grpc/impl/channel_arg_names.h +81 -55
  10. data/include/grpc/impl/compression_types.h +3 -2
  11. data/include/grpc/impl/slice_type.h +1 -1
  12. data/include/grpc/module.modulemap +1 -0
  13. data/include/grpc/support/json.h +27 -21
  14. data/include/grpc/support/port_platform.h +8 -5
  15. data/include/grpc/support/workaround_list.h +1 -4
  16. data/src/core/{lib/transport → call}/call_arena_allocator.cc +1 -1
  17. data/src/core/{lib/transport → call}/call_arena_allocator.h +3 -3
  18. data/src/core/{lib/transport → call}/call_destination.h +4 -4
  19. data/src/core/{lib/transport → call}/call_filters.cc +2 -2
  20. data/src/core/{lib/transport → call}/call_filters.h +53 -25
  21. data/src/core/{lib/channel → call}/call_finalization.h +3 -3
  22. data/src/core/{lib/transport → call}/call_spine.cc +1 -1
  23. data/src/core/{lib/transport → call}/call_spine.h +70 -26
  24. data/src/core/{lib/transport → call}/call_state.cc +1 -1
  25. data/src/core/{lib/transport → call}/call_state.h +3 -3
  26. data/src/core/{lib/surface → call}/client_call.cc +9 -7
  27. data/src/core/{lib/surface → call}/client_call.h +4 -4
  28. data/src/core/{lib/transport → call}/custom_metadata.h +3 -3
  29. data/src/core/{lib/transport → call}/interception_chain.cc +5 -5
  30. data/src/core/{lib/transport → call}/interception_chain.h +14 -18
  31. data/src/core/{lib/transport → call}/message.cc +1 -1
  32. data/src/core/{lib/transport → call}/message.h +7 -3
  33. data/src/core/{lib/transport → call}/metadata.cc +2 -2
  34. data/src/core/{lib/transport → call}/metadata.h +21 -4
  35. data/src/core/{lib/transport → call}/metadata_batch.cc +1 -1
  36. data/src/core/{lib/transport → call}/metadata_batch.h +7 -7
  37. data/src/core/{lib/transport → call}/metadata_compression_traits.h +3 -3
  38. data/src/core/{lib/transport → call}/metadata_info.cc +27 -9
  39. data/src/core/{lib/transport → call}/metadata_info.h +4 -4
  40. data/src/core/{lib/transport → call}/parsed_metadata.cc +1 -1
  41. data/src/core/{lib/transport → call}/parsed_metadata.h +3 -3
  42. data/src/core/call/request_buffer.h +3 -3
  43. data/src/core/call/security_context.cc +125 -0
  44. data/src/core/call/security_context.h +114 -0
  45. data/src/core/{lib/surface → call}/server_call.cc +3 -3
  46. data/src/core/{lib/surface → call}/server_call.h +5 -5
  47. data/src/core/{lib/transport → call}/simple_slice_based_metadata.h +4 -4
  48. data/src/core/{lib/channel → call}/status_util.cc +1 -1
  49. data/src/core/{lib/channel → call}/status_util.h +3 -3
  50. data/src/core/channelz/channel_trace.cc +217 -111
  51. data/src/core/channelz/channel_trace.h +389 -64
  52. data/src/core/channelz/channelz.cc +480 -178
  53. data/src/core/channelz/channelz.h +426 -71
  54. data/src/core/channelz/channelz_registry.cc +323 -117
  55. data/src/core/channelz/channelz_registry.h +203 -21
  56. data/src/core/channelz/property_list.cc +357 -0
  57. data/src/core/channelz/property_list.h +202 -0
  58. data/src/core/channelz/ztrace_collector.h +316 -0
  59. data/src/core/client_channel/backup_poller.cc +17 -2
  60. data/src/core/client_channel/client_channel.cc +66 -68
  61. data/src/core/client_channel/client_channel.h +4 -3
  62. data/src/core/client_channel/client_channel_filter.cc +45 -64
  63. data/src/core/client_channel/client_channel_filter.h +1 -3
  64. data/src/core/client_channel/client_channel_internal.h +1 -1
  65. data/src/core/client_channel/config_selector.h +10 -4
  66. data/src/core/client_channel/connector.h +0 -3
  67. data/src/core/client_channel/direct_channel.cc +2 -2
  68. data/src/core/client_channel/dynamic_filters.cc +5 -7
  69. data/src/core/client_channel/dynamic_filters.h +1 -2
  70. data/src/core/client_channel/global_subchannel_pool.cc +71 -7
  71. data/src/core/client_channel/global_subchannel_pool.h +37 -4
  72. data/src/core/client_channel/lb_metadata.h +1 -1
  73. data/src/core/client_channel/load_balanced_call_destination.cc +1 -1
  74. data/src/core/client_channel/load_balanced_call_destination.h +1 -1
  75. data/src/core/client_channel/retry_filter.cc +21 -27
  76. data/src/core/client_channel/retry_filter.h +10 -7
  77. data/src/core/client_channel/retry_filter_legacy_call_data.cc +48 -46
  78. data/src/core/client_channel/retry_filter_legacy_call_data.h +7 -7
  79. data/src/core/client_channel/retry_interceptor.cc +30 -44
  80. data/src/core/client_channel/retry_interceptor.h +19 -18
  81. data/src/core/client_channel/retry_service_config.cc +1 -1
  82. data/src/core/client_channel/retry_service_config.h +1 -1
  83. data/src/core/client_channel/retry_throttle.cc +42 -61
  84. data/src/core/client_channel/retry_throttle.h +21 -35
  85. data/src/core/client_channel/subchannel.cc +57 -36
  86. data/src/core/client_channel/subchannel.h +11 -10
  87. data/src/core/client_channel/subchannel_pool_interface.cc +5 -6
  88. data/src/core/client_channel/subchannel_pool_interface.h +11 -1
  89. data/src/core/client_channel/subchannel_stream_client.cc +14 -11
  90. data/src/core/client_channel/subchannel_stream_client.h +2 -2
  91. data/src/core/config/config_vars.cc +13 -1
  92. data/src/core/config/config_vars.h +8 -0
  93. data/src/core/config/core_configuration.cc +51 -11
  94. data/src/core/config/core_configuration.h +102 -9
  95. data/src/core/credentials/call/call_credentials.h +157 -0
  96. data/src/core/credentials/call/call_creds_registry.h +125 -0
  97. data/src/core/credentials/call/call_creds_registry_init.cc +91 -0
  98. data/src/core/{lib/security/credentials → credentials/call}/call_creds_util.cc +4 -4
  99. data/src/core/{lib/security/credentials → credentials/call}/call_creds_util.h +4 -4
  100. data/src/core/{lib/security/credentials/composite/composite_credentials.cc → credentials/call/composite/composite_call_credentials.cc} +4 -57
  101. data/src/core/credentials/call/composite/composite_call_credentials.h +82 -0
  102. data/src/core/{lib/security/credentials → credentials/call}/external/aws_external_account_credentials.cc +2 -2
  103. data/src/core/{lib/security/credentials → credentials/call}/external/aws_external_account_credentials.h +5 -5
  104. data/src/core/{lib/security/credentials → credentials/call}/external/aws_request_signer.cc +4 -3
  105. data/src/core/{lib/security/credentials → credentials/call}/external/aws_request_signer.h +3 -3
  106. data/src/core/{lib/security/credentials → credentials/call}/external/external_account_credentials.cc +6 -6
  107. data/src/core/{lib/security/credentials → credentials/call}/external/external_account_credentials.h +5 -5
  108. data/src/core/{lib/security/credentials → credentials/call}/external/file_external_account_credentials.cc +1 -1
  109. data/src/core/{lib/security/credentials → credentials/call}/external/file_external_account_credentials.h +4 -4
  110. data/src/core/{lib/security/credentials → credentials/call}/external/url_external_account_credentials.cc +5 -4
  111. data/src/core/{lib/security/credentials → credentials/call}/external/url_external_account_credentials.h +4 -4
  112. data/src/core/{lib/security/credentials → credentials/call}/gcp_service_account_identity/gcp_service_account_identity_credentials.cc +10 -51
  113. data/src/core/{lib/security/credentials → credentials/call}/gcp_service_account_identity/gcp_service_account_identity_credentials.h +6 -6
  114. data/src/core/{lib/security/credentials → credentials/call}/iam/iam_credentials.cc +2 -2
  115. data/src/core/{lib/security/credentials → credentials/call}/iam/iam_credentials.h +4 -4
  116. data/src/core/{lib/security/util → credentials/call}/json_util.cc +1 -1
  117. data/src/core/{lib/security/util → credentials/call}/json_util.h +3 -3
  118. data/src/core/{lib/security/credentials → credentials/call}/jwt/json_token.cc +2 -2
  119. data/src/core/{lib/security/credentials → credentials/call}/jwt/json_token.h +3 -3
  120. data/src/core/{lib/security/credentials → credentials/call}/jwt/jwt_credentials.cc +3 -3
  121. data/src/core/{lib/security/credentials → credentials/call}/jwt/jwt_credentials.h +5 -5
  122. data/src/core/{lib/security/credentials → credentials/call}/jwt/jwt_verifier.cc +7 -6
  123. data/src/core/{lib/security/credentials → credentials/call}/jwt/jwt_verifier.h +3 -3
  124. data/src/core/credentials/call/jwt_token_file/jwt_token_file_call_credentials.cc +86 -0
  125. data/src/core/credentials/call/jwt_token_file/jwt_token_file_call_credentials.h +74 -0
  126. data/src/core/credentials/call/jwt_util.cc +70 -0
  127. data/src/core/credentials/call/jwt_util.h +32 -0
  128. data/src/core/{lib/security/credentials → credentials/call}/oauth2/oauth2_credentials.cc +8 -5
  129. data/src/core/{lib/security/credentials → credentials/call}/oauth2/oauth2_credentials.h +5 -5
  130. data/src/core/{lib/security/credentials → credentials/call}/plugin/plugin_credentials.cc +2 -2
  131. data/src/core/{lib/security/credentials → credentials/call}/plugin/plugin_credentials.h +5 -5
  132. data/src/core/{lib/security/credentials → credentials/call}/token_fetcher/token_fetcher_credentials.cc +1 -1
  133. data/src/core/{lib/security/credentials → credentials/call}/token_fetcher/token_fetcher_credentials.h +5 -5
  134. data/src/core/{lib/security/credentials → credentials/transport}/alts/alts_credentials.cc +4 -4
  135. data/src/core/{lib/security/credentials → credentials/transport}/alts/alts_credentials.h +5 -5
  136. data/src/core/{lib/security/security_connector → credentials/transport}/alts/alts_security_connector.cc +13 -12
  137. data/src/core/{lib/security/security_connector → credentials/transport}/alts/alts_security_connector.h +4 -4
  138. data/src/core/{lib/security/credentials → credentials/transport}/alts/check_gcp_environment.cc +1 -1
  139. data/src/core/{lib/security/credentials → credentials/transport}/alts/check_gcp_environment.h +3 -3
  140. data/src/core/{lib/security/credentials → credentials/transport}/alts/check_gcp_environment_linux.cc +1 -1
  141. data/src/core/{lib/security/credentials → credentials/transport}/alts/check_gcp_environment_no_op.cc +1 -1
  142. data/src/core/{lib/security/credentials → credentials/transport}/alts/check_gcp_environment_windows.cc +1 -1
  143. data/src/core/{lib/security/credentials → credentials/transport}/alts/grpc_alts_credentials_client_options.cc +1 -1
  144. data/src/core/{lib/security/credentials → credentials/transport}/alts/grpc_alts_credentials_options.cc +1 -1
  145. data/src/core/{lib/security/credentials → credentials/transport}/alts/grpc_alts_credentials_options.h +3 -3
  146. data/src/core/{lib/security/credentials → credentials/transport}/alts/grpc_alts_credentials_server_options.cc +1 -1
  147. data/src/core/{lib/security/credentials → credentials/transport}/channel_creds_registry.h +4 -4
  148. data/src/core/{lib/security/credentials → credentials/transport}/channel_creds_registry_init.cc +22 -18
  149. data/src/core/credentials/transport/composite/composite_channel_credentials.cc +68 -0
  150. data/src/core/{lib/security/credentials/composite/composite_credentials.h → credentials/transport/composite/composite_channel_credentials.h} +6 -51
  151. data/src/core/{lib/security/credentials → credentials/transport}/fake/fake_credentials.cc +4 -26
  152. data/src/core/{lib/security/credentials → credentials/transport}/fake/fake_credentials.h +5 -37
  153. data/src/core/{lib/security/security_connector → credentials/transport}/fake/fake_security_connector.cc +4 -4
  154. data/src/core/{lib/security/security_connector → credentials/transport}/fake/fake_security_connector.h +4 -4
  155. data/src/core/{lib/security/credentials → credentials/transport}/google_default/credentials_generic.cc +2 -2
  156. data/src/core/{lib/security/credentials → credentials/transport}/google_default/google_default_credentials.cc +106 -26
  157. data/src/core/{lib/security/credentials → credentials/transport}/google_default/google_default_credentials.h +5 -5
  158. data/src/core/{lib/security/credentials → credentials/transport}/insecure/insecure_credentials.cc +2 -2
  159. data/src/core/{lib/security/credentials → credentials/transport}/insecure/insecure_credentials.h +5 -5
  160. data/src/core/{lib/security/security_connector → credentials/transport}/insecure/insecure_security_connector.cc +2 -2
  161. data/src/core/{lib/security/security_connector → credentials/transport}/insecure/insecure_security_connector.h +5 -5
  162. data/src/core/{lib/security/credentials → credentials/transport}/local/local_credentials.cc +2 -2
  163. data/src/core/{lib/security/credentials → credentials/transport}/local/local_credentials.h +5 -5
  164. data/src/core/{lib/security/security_connector → credentials/transport}/local/local_security_connector.cc +4 -4
  165. data/src/core/{lib/security/security_connector → credentials/transport}/local/local_security_connector.h +4 -4
  166. data/src/core/{lib/security/security_connector → credentials/transport}/security_connector.cc +2 -2
  167. data/src/core/{lib/security/security_connector → credentials/transport}/security_connector.h +3 -3
  168. data/src/core/{lib/security/credentials → credentials/transport}/ssl/ssl_credentials.cc +4 -5
  169. data/src/core/{lib/security/credentials → credentials/transport}/ssl/ssl_credentials.h +6 -6
  170. data/src/core/{lib/security/security_connector → credentials/transport}/ssl/ssl_security_connector.cc +46 -16
  171. data/src/core/{lib/security/security_connector → credentials/transport}/ssl/ssl_security_connector.h +6 -5
  172. data/src/core/{lib/security/certificate_provider → credentials/transport/tls}/certificate_provider_factory.h +3 -3
  173. data/src/core/{lib/security/certificate_provider → credentials/transport/tls}/certificate_provider_registry.cc +1 -1
  174. data/src/core/{lib/security/certificate_provider → credentials/transport/tls}/certificate_provider_registry.h +4 -4
  175. data/src/core/{lib/security/credentials → credentials/transport}/tls/grpc_tls_certificate_distributor.cc +1 -1
  176. data/src/core/{lib/security/credentials → credentials/transport}/tls/grpc_tls_certificate_distributor.h +4 -4
  177. data/src/core/{lib/security/credentials → credentials/transport}/tls/grpc_tls_certificate_match.cc +1 -1
  178. data/src/core/{lib/security/credentials → credentials/transport}/tls/grpc_tls_certificate_provider.cc +2 -2
  179. data/src/core/{lib/security/credentials → credentials/transport}/tls/grpc_tls_certificate_provider.h +5 -5
  180. data/src/core/{lib/security/credentials → credentials/transport}/tls/grpc_tls_certificate_verifier.cc +2 -2
  181. data/src/core/{lib/security/credentials → credentials/transport}/tls/grpc_tls_certificate_verifier.h +3 -3
  182. data/src/core/{lib/security/credentials → credentials/transport}/tls/grpc_tls_credentials_options.cc +1 -1
  183. data/src/core/{lib/security/credentials → credentials/transport}/tls/grpc_tls_credentials_options.h +7 -7
  184. data/src/core/{lib/security/credentials → credentials/transport}/tls/grpc_tls_crl_provider.cc +1 -1
  185. data/src/core/{lib/security/credentials → credentials/transport}/tls/grpc_tls_crl_provider.h +3 -3
  186. data/src/core/{lib/security/security_connector → credentials/transport/tls}/load_system_roots.h +3 -3
  187. data/src/core/{lib/security/security_connector → credentials/transport/tls}/load_system_roots_fallback.cc +1 -1
  188. data/src/core/{lib/security/security_connector → credentials/transport/tls}/load_system_roots_supported.cc +3 -2
  189. data/src/core/{lib/security/security_connector → credentials/transport/tls}/load_system_roots_supported.h +3 -3
  190. data/src/core/{lib/security/security_connector → credentials/transport/tls}/load_system_roots_windows.cc +1 -1
  191. data/src/core/{lib/security/security_connector → credentials/transport/tls}/ssl_utils.cc +21 -3
  192. data/src/core/{lib/security/security_connector → credentials/transport/tls}/ssl_utils.h +9 -4
  193. data/src/core/{lib/security/credentials → credentials/transport}/tls/tls_credentials.cc +4 -4
  194. data/src/core/{lib/security/credentials → credentials/transport}/tls/tls_credentials.h +5 -5
  195. data/src/core/{lib/security/security_connector → credentials/transport}/tls/tls_security_connector.cc +8 -7
  196. data/src/core/{lib/security/security_connector → credentials/transport}/tls/tls_security_connector.h +6 -6
  197. data/src/core/{lib/security/credentials → credentials/transport}/tls/tls_utils.cc +1 -1
  198. data/src/core/{lib/security/credentials → credentials/transport}/tls/tls_utils.h +3 -3
  199. data/src/core/{lib/security/credentials/credentials.cc → credentials/transport/transport_credentials.cc} +1 -3
  200. data/src/core/{lib/security/credentials/credentials.h → credentials/transport/transport_credentials.h} +5 -121
  201. data/src/core/{lib/security/credentials → credentials/transport}/xds/xds_credentials.cc +5 -8
  202. data/src/core/{lib/security/credentials → credentials/transport}/xds/xds_credentials.h +6 -6
  203. data/src/core/ext/filters/backend_metrics/backend_metric_filter.cc +1 -1
  204. data/src/core/ext/filters/channel_idle/legacy_channel_idle_filter.cc +14 -8
  205. data/src/core/ext/filters/fault_injection/fault_injection_filter.cc +2 -2
  206. data/src/core/ext/filters/fault_injection/fault_injection_service_config_parser.cc +1 -1
  207. data/src/core/ext/filters/gcp_authentication/gcp_authentication_filter.cc +10 -10
  208. data/src/core/ext/filters/gcp_authentication/gcp_authentication_filter.h +17 -17
  209. data/src/core/ext/filters/http/client/http_client_filter.h +1 -1
  210. data/src/core/ext/filters/http/client_authority_filter.cc +4 -6
  211. data/src/core/ext/filters/http/message_compress/compression_filter.cc +1 -1
  212. data/src/core/ext/filters/http/message_compress/compression_filter.h +38 -5
  213. data/src/core/ext/filters/http/server/http_server_filter.cc +2 -2
  214. data/src/core/ext/filters/http/server/http_server_filter.h +18 -6
  215. data/src/core/ext/filters/message_size/message_size_filter.cc +1 -1
  216. data/src/core/ext/filters/rbac/rbac_filter.cc +2 -2
  217. data/src/core/ext/filters/stateful_session/stateful_session_filter.cc +1 -1
  218. data/src/core/ext/transport/chttp2/chttp2_plugin.cc +40 -0
  219. data/src/core/ext/transport/chttp2/client/chttp2_connector.cc +133 -149
  220. data/src/core/ext/transport/chttp2/client/chttp2_connector.h +3 -0
  221. data/src/core/ext/transport/chttp2/server/chttp2_server.cc +45 -970
  222. data/src/core/ext/transport/chttp2/server/chttp2_server.h +10 -2
  223. data/src/core/ext/transport/chttp2/transport/call_tracer_wrapper.cc +2 -2
  224. data/src/core/ext/transport/chttp2/transport/call_tracer_wrapper.h +1 -3
  225. data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +263 -133
  226. data/src/core/ext/transport/chttp2/transport/chttp2_transport.h +0 -6
  227. data/src/core/ext/transport/chttp2/transport/decode_huff.cc +1239 -3514
  228. data/src/core/ext/transport/chttp2/transport/decode_huff.h +1008 -1486
  229. data/src/core/ext/transport/chttp2/transport/flow_control.h +23 -0
  230. data/src/core/ext/transport/chttp2/transport/frame.cc +310 -171
  231. data/src/core/ext/transport/chttp2/transport/frame.h +113 -5
  232. data/src/core/ext/transport/chttp2/transport/frame_data.cc +12 -0
  233. data/src/core/ext/transport/chttp2/transport/frame_data.h +2 -0
  234. data/src/core/ext/transport/chttp2/transport/frame_goaway.cc +15 -3
  235. data/src/core/ext/transport/chttp2/transport/frame_goaway.h +5 -3
  236. data/src/core/ext/transport/chttp2/transport/frame_ping.cc +2 -0
  237. data/src/core/ext/transport/chttp2/transport/frame_rst_stream.cc +17 -7
  238. data/src/core/ext/transport/chttp2/transport/frame_rst_stream.h +3 -1
  239. data/src/core/ext/transport/chttp2/transport/frame_settings.cc +30 -11
  240. data/src/core/ext/transport/chttp2/transport/frame_window_update.cc +8 -5
  241. data/src/core/ext/transport/chttp2/transport/header_assembler.h +299 -0
  242. data/src/core/ext/transport/chttp2/transport/hpack_encoder.cc +7 -0
  243. data/src/core/ext/transport/chttp2/transport/hpack_encoder.h +4 -2
  244. data/src/core/ext/transport/chttp2/transport/hpack_parse_result.h +1 -1
  245. data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +3 -3
  246. data/src/core/ext/transport/chttp2/transport/hpack_parser.h +1 -1
  247. data/src/core/ext/transport/chttp2/transport/hpack_parser_table.cc +11 -5
  248. data/src/core/ext/transport/chttp2/transport/hpack_parser_table.h +14 -3
  249. data/src/core/ext/transport/chttp2/transport/http2_client_transport.cc +1017 -0
  250. data/src/core/ext/transport/chttp2/transport/http2_client_transport.h +593 -0
  251. data/src/core/ext/transport/chttp2/transport/http2_settings.cc +10 -8
  252. data/src/core/ext/transport/chttp2/transport/http2_settings.h +25 -2
  253. data/{third_party/abseil-cpp/absl/strings/cord_buffer.cc → src/core/ext/transport/chttp2/transport/http2_stats_collector.cc} +14 -14
  254. data/src/core/ext/transport/chttp2/transport/http2_stats_collector.h +33 -0
  255. data/src/core/ext/transport/chttp2/transport/http2_status.h +414 -0
  256. data/src/core/ext/transport/chttp2/transport/http2_transport.cc +43 -0
  257. data/src/core/ext/transport/chttp2/transport/http2_transport.h +65 -0
  258. data/src/core/ext/transport/chttp2/transport/http2_ztrace_collector.h +223 -0
  259. data/src/core/ext/transport/chttp2/transport/internal.h +54 -23
  260. data/src/core/ext/transport/chttp2/transport/internal_channel_arg_names.h +24 -0
  261. data/src/core/ext/transport/chttp2/transport/keepalive.cc +105 -0
  262. data/src/core/ext/transport/chttp2/transport/keepalive.h +138 -0
  263. data/src/core/ext/transport/chttp2/transport/message_assembler.h +185 -0
  264. data/src/core/ext/transport/chttp2/transport/parsing.cc +57 -31
  265. data/src/core/ext/transport/chttp2/transport/ping_callbacks.h +19 -0
  266. data/src/core/ext/transport/chttp2/transport/ping_promise.cc +151 -0
  267. data/src/core/ext/transport/chttp2/transport/ping_promise.h +180 -0
  268. data/src/core/ext/transport/chttp2/transport/ping_rate_policy.cc +15 -18
  269. data/src/core/ext/transport/chttp2/transport/ping_rate_policy.h +17 -0
  270. data/src/core/ext/transport/chttp2/transport/stream_lists.cc +39 -1
  271. data/src/core/ext/transport/chttp2/transport/transport_common.cc +19 -0
  272. data/src/core/ext/transport/chttp2/transport/transport_common.h +27 -0
  273. data/src/core/ext/transport/chttp2/transport/writing.cc +103 -65
  274. data/src/core/ext/transport/inproc/inproc_transport.cc +8 -3
  275. data/src/core/ext/transport/inproc/legacy_inproc_transport.cc +7 -3
  276. data/src/core/ext/upb-gen/envoy/admin/v3/certs.upb.h +4 -0
  277. data/src/core/ext/upb-gen/envoy/admin/v3/clusters.upb.h +65 -65
  278. data/src/core/ext/upb-gen/envoy/admin/v3/clusters.upb_minitable.c +28 -28
  279. data/src/core/ext/upb-gen/envoy/admin/v3/config_dump_shared.upb.h +14 -14
  280. data/src/core/ext/upb-gen/envoy/admin/v3/config_dump_shared.upb_minitable.c +6 -6
  281. data/src/core/ext/upb-gen/envoy/admin/v3/metrics.upb.h +6 -6
  282. data/src/core/ext/upb-gen/envoy/admin/v3/metrics.upb_minitable.c +4 -4
  283. data/src/core/ext/upb-gen/envoy/admin/v3/server_info.upb.h +133 -133
  284. data/src/core/ext/upb-gen/envoy/admin/v3/server_info.upb_minitable.c +71 -71
  285. data/src/core/ext/upb-gen/envoy/config/accesslog/v3/accesslog.upb.h +38 -26
  286. data/src/core/ext/upb-gen/envoy/config/accesslog/v3/accesslog.upb_minitable.c +7 -7
  287. data/src/core/ext/upb-gen/envoy/config/bootstrap/v3/bootstrap.upb.h +228 -240
  288. data/src/core/ext/upb-gen/envoy/config/bootstrap/v3/bootstrap.upb_minitable.c +66 -66
  289. data/src/core/ext/upb-gen/envoy/config/cluster/v3/circuit_breaker.upb.h +27 -27
  290. data/src/core/ext/upb-gen/envoy/config/cluster/v3/circuit_breaker.upb_minitable.c +9 -9
  291. data/src/core/ext/upb-gen/envoy/config/cluster/v3/cluster.upb.h +338 -350
  292. data/src/core/ext/upb-gen/envoy/config/cluster/v3/cluster.upb_minitable.c +103 -103
  293. data/src/core/ext/upb-gen/envoy/config/cluster/v3/outlier_detection.upb.h +58 -58
  294. data/src/core/ext/upb-gen/envoy/config/cluster/v3/outlier_detection.upb_minitable.c +14 -14
  295. data/src/core/ext/upb-gen/envoy/config/common/matcher/v3/matcher.upb.h +50 -46
  296. data/src/core/ext/upb-gen/envoy/config/common/matcher/v3/matcher.upb_minitable.c +3 -3
  297. data/src/core/ext/upb-gen/envoy/config/core/v3/address.upb.h +41 -29
  298. data/src/core/ext/upb-gen/envoy/config/core/v3/address.upb_minitable.c +16 -16
  299. data/src/core/ext/upb-gen/envoy/config/core/v3/base.upb.h +210 -259
  300. data/src/core/ext/upb-gen/envoy/config/core/v3/base.upb_minitable.c +54 -54
  301. data/src/core/ext/upb-gen/envoy/config/core/v3/config_source.upb.h +58 -54
  302. data/src/core/ext/upb-gen/envoy/config/core/v3/config_source.upb_minitable.c +21 -21
  303. data/src/core/ext/upb-gen/envoy/config/core/v3/event_service_config.upb.h +4 -0
  304. data/src/core/ext/upb-gen/envoy/config/core/v3/grpc_service.upb.h +88 -92
  305. data/src/core/ext/upb-gen/envoy/config/core/v3/grpc_service.upb_minitable.c +17 -17
  306. data/src/core/ext/upb-gen/envoy/config/core/v3/health_check.upb.h +112 -100
  307. data/src/core/ext/upb-gen/envoy/config/core/v3/health_check.upb_minitable.c +34 -34
  308. data/src/core/ext/upb-gen/envoy/config/core/v3/http_uri.upb.h +16 -12
  309. data/src/core/ext/upb-gen/envoy/config/core/v3/http_uri.upb_minitable.c +5 -5
  310. data/src/core/ext/upb-gen/envoy/config/core/v3/protocol.upb.h +126 -118
  311. data/src/core/ext/upb-gen/envoy/config/core/v3/protocol.upb_minitable.c +39 -39
  312. data/src/core/ext/upb-gen/envoy/config/core/v3/socket_option.upb.h +23 -19
  313. data/src/core/ext/upb-gen/envoy/config/core/v3/socket_option.upb_minitable.c +9 -9
  314. data/src/core/ext/upb-gen/envoy/config/core/v3/substitution_format_string.upb.h +31 -27
  315. data/src/core/ext/upb-gen/envoy/config/core/v3/substitution_format_string.upb_minitable.c +10 -10
  316. data/src/core/ext/upb-gen/envoy/config/endpoint/v3/endpoint.upb.h +12 -37
  317. data/src/core/ext/upb-gen/envoy/config/endpoint/v3/endpoint.upb_minitable.c +2 -2
  318. data/src/core/ext/upb-gen/envoy/config/endpoint/v3/endpoint_components.upb.h +49 -41
  319. data/src/core/ext/upb-gen/envoy/config/endpoint/v3/endpoint_components.upb_minitable.c +16 -16
  320. data/src/core/ext/upb-gen/envoy/config/endpoint/v3/load_report.upb.h +24 -24
  321. data/src/core/ext/upb-gen/envoy/config/endpoint/v3/load_report.upb_minitable.c +9 -9
  322. data/src/core/ext/upb-gen/envoy/config/listener/v3/listener.upb.h +147 -139
  323. data/src/core/ext/upb-gen/envoy/config/listener/v3/listener.upb_minitable.c +46 -46
  324. data/src/core/ext/upb-gen/envoy/config/listener/v3/listener_components.upb.h +73 -61
  325. data/src/core/ext/upb-gen/envoy/config/listener/v3/listener_components.upb_minitable.c +20 -20
  326. data/src/core/ext/upb-gen/envoy/config/listener/v3/quic_config.upb.h +3 -3
  327. data/src/core/ext/upb-gen/envoy/config/listener/v3/quic_config.upb_minitable.c +1 -1
  328. data/src/core/ext/upb-gen/envoy/config/metrics/v3/metrics_service.upb.h +6 -6
  329. data/src/core/ext/upb-gen/envoy/config/metrics/v3/metrics_service.upb_minitable.c +4 -4
  330. data/src/core/ext/upb-gen/envoy/config/metrics/v3/stats.upb.h +53 -33
  331. data/src/core/ext/upb-gen/envoy/config/metrics/v3/stats.upb_minitable.c +14 -14
  332. data/src/core/ext/upb-gen/envoy/config/overload/v3/overload.upb.h +12 -0
  333. data/src/core/ext/upb-gen/envoy/config/rbac/v3/rbac.upb.h +20 -36
  334. data/src/core/ext/upb-gen/envoy/config/rbac/v3/rbac.upb_minitable.c +2 -2
  335. data/src/core/ext/upb-gen/envoy/config/route/v3/route.upb.h +52 -77
  336. data/src/core/ext/upb-gen/envoy/config/route/v3/route.upb_minitable.c +10 -10
  337. data/src/core/ext/upb-gen/envoy/config/route/v3/route_components.upb.h +684 -692
  338. data/src/core/ext/upb-gen/envoy/config/route/v3/route_components.upb_minitable.c +215 -215
  339. data/src/core/ext/upb-gen/envoy/config/route/v3/scoped_route.upb.h +17 -13
  340. data/src/core/ext/upb-gen/envoy/config/route/v3/scoped_route.upb_minitable.c +4 -4
  341. data/src/core/ext/upb-gen/envoy/config/tap/v3/common.upb.h +15 -3
  342. data/src/core/ext/upb-gen/envoy/config/tap/v3/common.upb_minitable.c +2 -2
  343. data/src/core/ext/upb-gen/envoy/config/trace/v3/http_tracer.upb.h +4 -0
  344. data/src/core/ext/upb-gen/envoy/config/trace/v3/opentelemetry.upb.h +7 -7
  345. data/src/core/ext/upb-gen/envoy/config/trace/v3/opentelemetry.upb_minitable.c +3 -3
  346. data/src/core/ext/upb-gen/envoy/config/trace/v3/skywalking.upb.h +19 -15
  347. data/src/core/ext/upb-gen/envoy/config/trace/v3/skywalking.upb_minitable.c +7 -7
  348. data/src/core/ext/upb-gen/envoy/config/trace/v3/xray.upb.h +7 -7
  349. data/src/core/ext/upb-gen/envoy/config/trace/v3/xray.upb_minitable.c +3 -3
  350. data/src/core/ext/upb-gen/envoy/config/trace/v3/zipkin.upb.h +16 -16
  351. data/src/core/ext/upb-gen/envoy/config/trace/v3/zipkin.upb_minitable.c +10 -10
  352. data/src/core/ext/upb-gen/envoy/data/accesslog/v3/accesslog.upb.h +310 -407
  353. data/src/core/ext/upb-gen/envoy/data/accesslog/v3/accesslog.upb_minitable.c +96 -96
  354. data/src/core/ext/upb-gen/envoy/extensions/filters/common/fault/v3/fault.upb.h +8 -0
  355. data/src/core/ext/upb-gen/envoy/extensions/filters/http/fault/v3/fault.upb.h +65 -61
  356. data/src/core/ext/upb-gen/envoy/extensions/filters/http/fault/v3/fault.upb_minitable.c +27 -27
  357. data/src/core/ext/upb-gen/envoy/extensions/filters/http/gcp_authn/v3/gcp_authn.upb.h +19 -19
  358. data/src/core/ext/upb-gen/envoy/extensions/filters/http/gcp_authn/v3/gcp_authn.upb_minitable.c +6 -6
  359. data/src/core/ext/upb-gen/envoy/extensions/filters/http/rbac/v3/rbac.upb.h +25 -25
  360. data/src/core/ext/upb-gen/envoy/extensions/filters/http/rbac/v3/rbac.upb_minitable.c +9 -9
  361. data/src/core/ext/upb-gen/envoy/extensions/filters/http/router/v3/router.upb.h +34 -34
  362. data/src/core/ext/upb-gen/envoy/extensions/filters/http/router/v3/router.upb_minitable.c +9 -9
  363. data/src/core/ext/upb-gen/envoy/extensions/filters/http/stateful_session/v3/stateful_session.upb.h +7 -3
  364. data/src/core/ext/upb-gen/envoy/extensions/filters/http/stateful_session/v3/stateful_session.upb_minitable.c +2 -2
  365. data/src/core/ext/upb-gen/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.h +322 -294
  366. data/src/core/ext/upb-gen/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb_minitable.c +105 -105
  367. data/src/core/ext/upb-gen/envoy/extensions/load_balancing_policies/common/v3/common.upb.h +7 -3
  368. data/src/core/ext/upb-gen/envoy/extensions/load_balancing_policies/common/v3/common.upb_minitable.c +1 -1
  369. data/src/core/ext/upb-gen/envoy/extensions/load_balancing_policies/ring_hash/v3/ring_hash.upb.h +23 -23
  370. data/src/core/ext/upb-gen/envoy/extensions/load_balancing_policies/ring_hash/v3/ring_hash.upb_minitable.c +8 -8
  371. data/src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/common.upb.h +88 -84
  372. data/src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/common.upb_minitable.c +28 -28
  373. data/src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/secret.upb.h +4 -0
  374. data/src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/tls.upb.h +99 -87
  375. data/src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/tls.upb_minitable.c +31 -31
  376. data/src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb.h +32 -24
  377. data/src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb_minitable.c +5 -5
  378. data/src/core/ext/upb-gen/envoy/service/discovery/v3/discovery.upb.h +138 -168
  379. data/src/core/ext/upb-gen/envoy/service/discovery/v3/discovery.upb_minitable.c +43 -43
  380. data/src/core/ext/upb-gen/envoy/service/load_stats/v3/lrs.upb.h +6 -6
  381. data/src/core/ext/upb-gen/envoy/service/load_stats/v3/lrs.upb_minitable.c +2 -2
  382. data/src/core/ext/upb-gen/envoy/service/status/v3/csds.upb.h +64 -60
  383. data/src/core/ext/upb-gen/envoy/service/status/v3/csds.upb_minitable.c +26 -26
  384. data/src/core/ext/upb-gen/envoy/type/http/v3/cookie.upb.h +7 -7
  385. data/src/core/ext/upb-gen/envoy/type/http/v3/cookie.upb_minitable.c +3 -3
  386. data/src/core/ext/upb-gen/envoy/type/http/v3/path_transformation.upb.h +4 -0
  387. data/src/core/ext/upb-gen/envoy/type/matcher/v3/filter_state.upb.h +4 -0
  388. data/src/core/ext/upb-gen/envoy/type/matcher/v3/metadata.upb.h +10 -6
  389. data/src/core/ext/upb-gen/envoy/type/matcher/v3/metadata.upb_minitable.c +2 -2
  390. data/src/core/ext/upb-gen/envoy/type/matcher/v3/number.upb.h +4 -0
  391. data/src/core/ext/upb-gen/envoy/type/matcher/v3/path.upb.h +4 -0
  392. data/src/core/ext/upb-gen/envoy/type/matcher/v3/regex.upb.h +11 -7
  393. data/src/core/ext/upb-gen/envoy/type/matcher/v3/regex.upb_minitable.c +3 -3
  394. data/src/core/ext/upb-gen/envoy/type/matcher/v3/string.upb.h +4 -0
  395. data/src/core/ext/upb-gen/envoy/type/matcher/v3/struct.upb.h +4 -0
  396. data/src/core/ext/upb-gen/envoy/type/matcher/v3/value.upb.h +8 -0
  397. data/src/core/ext/upb-gen/envoy/type/metadata/v3/metadata.upb.h +8 -0
  398. data/src/core/ext/upb-gen/envoy/type/tracing/v3/custom_tag.upb.h +15 -11
  399. data/src/core/ext/upb-gen/envoy/type/tracing/v3/custom_tag.upb_minitable.c +4 -4
  400. data/src/core/ext/upb-gen/envoy/type/v3/hash_policy.upb.h +4 -0
  401. data/src/core/ext/upb-gen/envoy/type/v3/ratelimit_strategy.upb.h +4 -0
  402. data/src/core/ext/upb-gen/google/api/expr/v1alpha1/checked.upb.h +93 -133
  403. data/src/core/ext/upb-gen/google/api/expr/v1alpha1/checked.upb_minitable.c +20 -20
  404. data/src/core/ext/upb-gen/google/api/expr/v1alpha1/syntax.upb.h +92 -123
  405. data/src/core/ext/upb-gen/google/api/expr/v1alpha1/syntax.upb_minitable.c +27 -27
  406. data/src/core/ext/upb-gen/google/api/http.upb.h +55 -51
  407. data/src/core/ext/upb-gen/google/api/http.upb_minitable.c +22 -22
  408. data/src/core/ext/upb-gen/google/protobuf/descriptor.upb.h +516 -317
  409. data/src/core/ext/upb-gen/google/protobuf/descriptor.upb_minitable.c +150 -100
  410. data/src/core/ext/upb-gen/google/protobuf/descriptor.upb_minitable.h +5 -0
  411. data/src/core/ext/upb-gen/google/protobuf/struct.upb.h +13 -33
  412. data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/channelz.upb.h +571 -0
  413. data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/channelz.upb_minitable.c +120 -0
  414. data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/channelz.upb_minitable.h +36 -0
  415. data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/promise.upb.h +1272 -0
  416. data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/promise.upb_minitable.c +312 -0
  417. data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/promise.upb_minitable.h +50 -0
  418. data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/property_list.upb.h +984 -0
  419. data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/property_list.upb_minitable.c +226 -0
  420. data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/property_list.upb_minitable.h +44 -0
  421. data/src/core/ext/upb-gen/src/proto/grpc/gcp/altscontext.upb.h +9 -28
  422. data/src/core/ext/upb-gen/src/proto/grpc/gcp/handshaker.upb.h +199 -142
  423. data/src/core/ext/upb-gen/src/proto/grpc/gcp/handshaker.upb_minitable.c +37 -31
  424. data/src/core/ext/upb-gen/src/proto/grpc/gcp/transport_security_common.upb.h +154 -0
  425. data/src/core/ext/upb-gen/src/proto/grpc/gcp/transport_security_common.upb_minitable.c +40 -2
  426. data/src/core/ext/upb-gen/src/proto/grpc/gcp/transport_security_common.upb_minitable.h +4 -0
  427. data/src/core/ext/upb-gen/src/proto/grpc/lb/v1/load_balancer.upb.h +14 -6
  428. data/src/core/ext/upb-gen/src/proto/grpc/lb/v1/load_balancer.upb_minitable.c +4 -4
  429. data/src/core/ext/upb-gen/src/proto/grpc/lookup/v1/rls.upb.h +21 -40
  430. data/src/core/ext/upb-gen/src/proto/grpc/lookup/v1/rls.upb_minitable.c +3 -3
  431. data/src/core/ext/upb-gen/src/proto/grpc/lookup/v1/rls_config.upb.h +70 -108
  432. data/src/core/ext/upb-gen/src/proto/grpc/lookup/v1/rls_config.upb_minitable.c +17 -17
  433. data/src/core/ext/upb-gen/validate/validate.upb.h +380 -368
  434. data/src/core/ext/upb-gen/validate/validate.upb_minitable.c +117 -117
  435. data/src/core/ext/upb-gen/xds/core/v3/collection_entry.upb.h +4 -0
  436. data/src/core/ext/upb-gen/xds/core/v3/context_params.upb.h +9 -28
  437. data/src/core/ext/upb-gen/xds/core/v3/resource.upb.h +7 -7
  438. data/src/core/ext/upb-gen/xds/core/v3/resource.upb_minitable.c +3 -3
  439. data/src/core/ext/upb-gen/xds/core/v3/resource_locator.upb.h +20 -12
  440. data/src/core/ext/upb-gen/xds/core/v3/resource_locator.upb_minitable.c +2 -2
  441. data/src/core/ext/upb-gen/xds/data/orca/v3/orca_load_report.upb.h +27 -84
  442. data/src/core/ext/upb-gen/xds/type/matcher/v3/cel.upb.h +7 -7
  443. data/src/core/ext/upb-gen/xds/type/matcher/v3/cel.upb_minitable.c +3 -3
  444. data/src/core/ext/upb-gen/xds/type/matcher/v3/ip.upb.h +3 -3
  445. data/src/core/ext/upb-gen/xds/type/matcher/v3/ip.upb_minitable.c +1 -1
  446. data/src/core/ext/upb-gen/xds/type/matcher/v3/matcher.upb.h +42 -46
  447. data/src/core/ext/upb-gen/xds/type/matcher/v3/matcher.upb_minitable.c +3 -3
  448. data/src/core/ext/upb-gen/xds/type/matcher/v3/regex.upb.h +4 -0
  449. data/src/core/ext/upb-gen/xds/type/matcher/v3/string.upb.h +4 -0
  450. data/src/core/ext/upb-gen/xds/type/v3/cel.upb.h +4 -0
  451. data/src/core/ext/upbdefs-gen/envoy/admin/v3/certs.upbdefs.c +123 -62
  452. data/src/core/ext/upbdefs-gen/envoy/admin/v3/certs.upbdefs.h +5 -1
  453. data/src/core/ext/upbdefs-gen/envoy/admin/v3/clusters.upbdefs.c +200 -101
  454. data/src/core/ext/upbdefs-gen/envoy/admin/v3/clusters.upbdefs.h +5 -1
  455. data/src/core/ext/upbdefs-gen/envoy/admin/v3/config_dump.upbdefs.c +152 -77
  456. data/src/core/ext/upbdefs-gen/envoy/admin/v3/config_dump.upbdefs.h +5 -1
  457. data/src/core/ext/upbdefs-gen/envoy/admin/v3/config_dump_shared.upbdefs.c +524 -255
  458. data/src/core/ext/upbdefs-gen/envoy/admin/v3/config_dump_shared.upbdefs.h +5 -1
  459. data/src/core/ext/upbdefs-gen/envoy/admin/v3/init_dump.upbdefs.c +44 -23
  460. data/src/core/ext/upbdefs-gen/envoy/admin/v3/init_dump.upbdefs.h +5 -1
  461. data/src/core/ext/upbdefs-gen/envoy/admin/v3/listeners.upbdefs.c +66 -34
  462. data/src/core/ext/upbdefs-gen/envoy/admin/v3/listeners.upbdefs.h +5 -1
  463. data/src/core/ext/upbdefs-gen/envoy/admin/v3/memory.upbdefs.c +54 -28
  464. data/src/core/ext/upbdefs-gen/envoy/admin/v3/memory.upbdefs.h +5 -1
  465. data/src/core/ext/upbdefs-gen/envoy/admin/v3/metrics.upbdefs.c +46 -25
  466. data/src/core/ext/upbdefs-gen/envoy/admin/v3/metrics.upbdefs.h +5 -1
  467. data/src/core/ext/upbdefs-gen/envoy/admin/v3/mutex_stats.upbdefs.c +47 -25
  468. data/src/core/ext/upbdefs-gen/envoy/admin/v3/mutex_stats.upbdefs.h +5 -1
  469. data/src/core/ext/upbdefs-gen/envoy/admin/v3/server_info.upbdefs.c +256 -126
  470. data/src/core/ext/upbdefs-gen/envoy/admin/v3/server_info.upbdefs.h +5 -1
  471. data/src/core/ext/upbdefs-gen/envoy/admin/v3/tap.upbdefs.c +50 -28
  472. data/src/core/ext/upbdefs-gen/envoy/admin/v3/tap.upbdefs.h +5 -1
  473. data/src/core/ext/upbdefs-gen/envoy/annotations/deprecation.upbdefs.c +55 -28
  474. data/src/core/ext/upbdefs-gen/envoy/annotations/deprecation.upbdefs.h +5 -1
  475. data/src/core/ext/upbdefs-gen/envoy/annotations/resource.upbdefs.c +34 -18
  476. data/src/core/ext/upbdefs-gen/envoy/annotations/resource.upbdefs.h +5 -1
  477. data/src/core/ext/upbdefs-gen/envoy/config/accesslog/v3/accesslog.upbdefs.c +414 -206
  478. data/src/core/ext/upbdefs-gen/envoy/config/accesslog/v3/accesslog.upbdefs.h +5 -1
  479. data/src/core/ext/upbdefs-gen/envoy/config/bootstrap/v3/bootstrap.upbdefs.c +831 -413
  480. data/src/core/ext/upbdefs-gen/envoy/config/bootstrap/v3/bootstrap.upbdefs.h +5 -1
  481. data/src/core/ext/upbdefs-gen/envoy/config/cluster/v3/circuit_breaker.upbdefs.c +143 -73
  482. data/src/core/ext/upbdefs-gen/envoy/config/cluster/v3/circuit_breaker.upbdefs.h +5 -1
  483. data/src/core/ext/upbdefs-gen/envoy/config/cluster/v3/cluster.upbdefs.c +1132 -557
  484. data/src/core/ext/upbdefs-gen/envoy/config/cluster/v3/cluster.upbdefs.h +5 -1
  485. data/src/core/ext/upbdefs-gen/envoy/config/cluster/v3/filter.upbdefs.c +63 -34
  486. data/src/core/ext/upbdefs-gen/envoy/config/cluster/v3/filter.upbdefs.h +5 -1
  487. data/src/core/ext/upbdefs-gen/envoy/config/cluster/v3/outlier_detection.upbdefs.c +255 -127
  488. data/src/core/ext/upbdefs-gen/envoy/config/cluster/v3/outlier_detection.upbdefs.h +5 -1
  489. data/src/core/ext/upbdefs-gen/envoy/config/common/matcher/v3/matcher.upbdefs.c +363 -178
  490. data/src/core/ext/upbdefs-gen/envoy/config/common/matcher/v3/matcher.upbdefs.h +5 -1
  491. data/src/core/ext/upbdefs-gen/envoy/config/core/v3/address.upbdefs.c +227 -114
  492. data/src/core/ext/upbdefs-gen/envoy/config/core/v3/address.upbdefs.h +5 -1
  493. data/src/core/ext/upbdefs-gen/envoy/config/core/v3/backoff.upbdefs.c +57 -31
  494. data/src/core/ext/upbdefs-gen/envoy/config/core/v3/backoff.upbdefs.h +5 -1
  495. data/src/core/ext/upbdefs-gen/envoy/config/core/v3/base.upbdefs.c +596 -295
  496. data/src/core/ext/upbdefs-gen/envoy/config/core/v3/base.upbdefs.h +5 -1
  497. data/src/core/ext/upbdefs-gen/envoy/config/core/v3/config_source.upbdefs.c +271 -137
  498. data/src/core/ext/upbdefs-gen/envoy/config/core/v3/config_source.upbdefs.h +5 -1
  499. data/src/core/ext/upbdefs-gen/envoy/config/core/v3/event_service_config.upbdefs.c +56 -30
  500. data/src/core/ext/upbdefs-gen/envoy/config/core/v3/event_service_config.upbdefs.h +5 -1
  501. data/src/core/ext/upbdefs-gen/envoy/config/core/v3/extension.upbdefs.c +45 -25
  502. data/src/core/ext/upbdefs-gen/envoy/config/core/v3/extension.upbdefs.h +5 -1
  503. data/src/core/ext/upbdefs-gen/envoy/config/core/v3/grpc_method_list.upbdefs.c +59 -31
  504. data/src/core/ext/upbdefs-gen/envoy/config/core/v3/grpc_method_list.upbdefs.h +5 -1
  505. data/src/core/ext/upbdefs-gen/envoy/config/core/v3/grpc_service.upbdefs.c +438 -217
  506. data/src/core/ext/upbdefs-gen/envoy/config/core/v3/grpc_service.upbdefs.h +5 -1
  507. data/src/core/ext/upbdefs-gen/envoy/config/core/v3/health_check.upbdefs.c +441 -221
  508. data/src/core/ext/upbdefs-gen/envoy/config/core/v3/health_check.upbdefs.h +5 -1
  509. data/src/core/ext/upbdefs-gen/envoy/config/core/v3/http_service.upbdefs.c +55 -30
  510. data/src/core/ext/upbdefs-gen/envoy/config/core/v3/http_service.upbdefs.h +5 -1
  511. data/src/core/ext/upbdefs-gen/envoy/config/core/v3/http_uri.upbdefs.c +57 -31
  512. data/src/core/ext/upbdefs-gen/envoy/config/core/v3/http_uri.upbdefs.h +5 -1
  513. data/src/core/ext/upbdefs-gen/envoy/config/core/v3/protocol.upbdefs.c +619 -303
  514. data/src/core/ext/upbdefs-gen/envoy/config/core/v3/protocol.upbdefs.h +5 -1
  515. data/src/core/ext/upbdefs-gen/envoy/config/core/v3/proxy_protocol.upbdefs.c +70 -36
  516. data/src/core/ext/upbdefs-gen/envoy/config/core/v3/proxy_protocol.upbdefs.h +5 -1
  517. data/src/core/ext/upbdefs-gen/envoy/config/core/v3/resolver.upbdefs.c +62 -33
  518. data/src/core/ext/upbdefs-gen/envoy/config/core/v3/resolver.upbdefs.h +5 -1
  519. data/src/core/ext/upbdefs-gen/envoy/config/core/v3/socket_cmsg_headers.upbdefs.c +47 -25
  520. data/src/core/ext/upbdefs-gen/envoy/config/core/v3/socket_cmsg_headers.upbdefs.h +5 -1
  521. data/src/core/ext/upbdefs-gen/envoy/config/core/v3/socket_option.upbdefs.c +97 -49
  522. data/src/core/ext/upbdefs-gen/envoy/config/core/v3/socket_option.upbdefs.h +5 -1
  523. data/src/core/ext/upbdefs-gen/envoy/config/core/v3/substitution_format_string.upbdefs.c +97 -51
  524. data/src/core/ext/upbdefs-gen/envoy/config/core/v3/substitution_format_string.upbdefs.h +5 -1
  525. data/src/core/ext/upbdefs-gen/envoy/config/core/v3/udp_socket_config.upbdefs.c +51 -27
  526. data/src/core/ext/upbdefs-gen/envoy/config/core/v3/udp_socket_config.upbdefs.h +5 -1
  527. data/src/core/ext/upbdefs-gen/envoy/config/endpoint/v3/endpoint.upbdefs.c +147 -76
  528. data/src/core/ext/upbdefs-gen/envoy/config/endpoint/v3/endpoint.upbdefs.h +5 -1
  529. data/src/core/ext/upbdefs-gen/envoy/config/endpoint/v3/endpoint_components.upbdefs.c +230 -116
  530. data/src/core/ext/upbdefs-gen/envoy/config/endpoint/v3/endpoint_components.upbdefs.h +5 -1
  531. data/src/core/ext/upbdefs-gen/envoy/config/endpoint/v3/load_report.upbdefs.c +277 -138
  532. data/src/core/ext/upbdefs-gen/envoy/config/endpoint/v3/load_report.upbdefs.h +5 -1
  533. data/src/core/ext/upbdefs-gen/envoy/config/listener/v3/api_listener.upbdefs.c +48 -26
  534. data/src/core/ext/upbdefs-gen/envoy/config/listener/v3/api_listener.upbdefs.h +5 -1
  535. data/src/core/ext/upbdefs-gen/envoy/config/listener/v3/listener.upbdefs.c +388 -197
  536. data/src/core/ext/upbdefs-gen/envoy/config/listener/v3/listener.upbdefs.h +5 -1
  537. data/src/core/ext/upbdefs-gen/envoy/config/listener/v3/listener_components.upbdefs.c +304 -153
  538. data/src/core/ext/upbdefs-gen/envoy/config/listener/v3/listener_components.upbdefs.h +5 -1
  539. data/src/core/ext/upbdefs-gen/envoy/config/listener/v3/quic_config.upbdefs.c +173 -90
  540. data/src/core/ext/upbdefs-gen/envoy/config/listener/v3/quic_config.upbdefs.h +5 -1
  541. data/src/core/ext/upbdefs-gen/envoy/config/listener/v3/udp_listener_config.upbdefs.c +90 -47
  542. data/src/core/ext/upbdefs-gen/envoy/config/listener/v3/udp_listener_config.upbdefs.h +5 -1
  543. data/src/core/ext/upbdefs-gen/envoy/config/metrics/v3/metrics_service.upbdefs.c +98 -51
  544. data/src/core/ext/upbdefs-gen/envoy/config/metrics/v3/metrics_service.upbdefs.h +5 -1
  545. data/src/core/ext/upbdefs-gen/envoy/config/metrics/v3/stats.upbdefs.c +196 -99
  546. data/src/core/ext/upbdefs-gen/envoy/config/metrics/v3/stats.upbdefs.h +5 -1
  547. data/src/core/ext/upbdefs-gen/envoy/config/overload/v3/overload.upbdefs.c +237 -118
  548. data/src/core/ext/upbdefs-gen/envoy/config/overload/v3/overload.upbdefs.h +5 -1
  549. data/src/core/ext/upbdefs-gen/envoy/config/rbac/v3/rbac.upbdefs.c +418 -210
  550. data/src/core/ext/upbdefs-gen/envoy/config/rbac/v3/rbac.upbdefs.h +5 -1
  551. data/src/core/ext/upbdefs-gen/envoy/config/route/v3/route.upbdefs.c +194 -99
  552. data/src/core/ext/upbdefs-gen/envoy/config/route/v3/route.upbdefs.h +5 -1
  553. data/src/core/ext/upbdefs-gen/envoy/config/route/v3/route_components.upbdefs.c +2003 -973
  554. data/src/core/ext/upbdefs-gen/envoy/config/route/v3/route_components.upbdefs.h +5 -1
  555. data/src/core/ext/upbdefs-gen/envoy/config/route/v3/scoped_route.upbdefs.c +101 -53
  556. data/src/core/ext/upbdefs-gen/envoy/config/route/v3/scoped_route.upbdefs.h +5 -1
  557. data/src/core/ext/upbdefs-gen/envoy/config/tap/v3/common.upbdefs.c +352 -176
  558. data/src/core/ext/upbdefs-gen/envoy/config/tap/v3/common.upbdefs.h +5 -1
  559. data/src/core/ext/upbdefs-gen/envoy/config/trace/v3/datadog.upbdefs.c +79 -42
  560. data/src/core/ext/upbdefs-gen/envoy/config/trace/v3/datadog.upbdefs.h +5 -1
  561. data/src/core/ext/upbdefs-gen/envoy/config/trace/v3/dynamic_ot.upbdefs.c +67 -37
  562. data/src/core/ext/upbdefs-gen/envoy/config/trace/v3/dynamic_ot.upbdefs.h +5 -1
  563. data/src/core/ext/upbdefs-gen/envoy/config/trace/v3/http_tracer.upbdefs.c +63 -34
  564. data/src/core/ext/upbdefs-gen/envoy/config/trace/v3/http_tracer.upbdefs.h +5 -1
  565. data/src/core/ext/upbdefs-gen/envoy/config/trace/v3/lightstep.upbdefs.c +88 -47
  566. data/src/core/ext/upbdefs-gen/envoy/config/trace/v3/lightstep.upbdefs.h +5 -1
  567. data/src/core/ext/upbdefs-gen/envoy/config/trace/v3/opentelemetry.upbdefs.c +80 -43
  568. data/src/core/ext/upbdefs-gen/envoy/config/trace/v3/opentelemetry.upbdefs.h +5 -1
  569. data/src/core/ext/upbdefs-gen/envoy/config/trace/v3/service.upbdefs.c +53 -29
  570. data/src/core/ext/upbdefs-gen/envoy/config/trace/v3/service.upbdefs.h +5 -1
  571. data/src/core/ext/upbdefs-gen/envoy/config/trace/v3/skywalking.upbdefs.c +86 -46
  572. data/src/core/ext/upbdefs-gen/envoy/config/trace/v3/skywalking.upbdefs.h +5 -1
  573. data/src/core/ext/upbdefs-gen/envoy/config/trace/v3/trace.upbdefs.c +55 -32
  574. data/src/core/ext/upbdefs-gen/envoy/config/trace/v3/trace.upbdefs.h +5 -1
  575. data/src/core/ext/upbdefs-gen/envoy/config/trace/v3/xray.upbdefs.c +91 -49
  576. data/src/core/ext/upbdefs-gen/envoy/config/trace/v3/xray.upbdefs.h +5 -1
  577. data/src/core/ext/upbdefs-gen/envoy/config/trace/v3/zipkin.upbdefs.c +105 -55
  578. data/src/core/ext/upbdefs-gen/envoy/config/trace/v3/zipkin.upbdefs.h +5 -1
  579. data/src/core/ext/upbdefs-gen/envoy/data/accesslog/v3/accesslog.upbdefs.c +775 -379
  580. data/src/core/ext/upbdefs-gen/envoy/data/accesslog/v3/accesslog.upbdefs.h +5 -1
  581. data/src/core/ext/upbdefs-gen/envoy/extensions/clusters/aggregate/v3/cluster.upbdefs.c +52 -28
  582. data/src/core/ext/upbdefs-gen/envoy/extensions/clusters/aggregate/v3/cluster.upbdefs.h +5 -1
  583. data/src/core/ext/upbdefs-gen/envoy/extensions/filters/common/fault/v3/fault.upbdefs.c +134 -68
  584. data/src/core/ext/upbdefs-gen/envoy/extensions/filters/common/fault/v3/fault.upbdefs.h +5 -1
  585. data/src/core/ext/upbdefs-gen/envoy/extensions/filters/http/fault/v3/fault.upbdefs.c +189 -96
  586. data/src/core/ext/upbdefs-gen/envoy/extensions/filters/http/fault/v3/fault.upbdefs.h +5 -1
  587. data/src/core/ext/upbdefs-gen/envoy/extensions/filters/http/gcp_authn/v3/gcp_authn.upbdefs.c +116 -61
  588. data/src/core/ext/upbdefs-gen/envoy/extensions/filters/http/gcp_authn/v3/gcp_authn.upbdefs.h +5 -1
  589. data/src/core/ext/upbdefs-gen/envoy/extensions/filters/http/rbac/v3/rbac.upbdefs.c +112 -58
  590. data/src/core/ext/upbdefs-gen/envoy/extensions/filters/http/rbac/v3/rbac.upbdefs.h +5 -1
  591. data/src/core/ext/upbdefs-gen/envoy/extensions/filters/http/router/v3/router.upbdefs.c +160 -82
  592. data/src/core/ext/upbdefs-gen/envoy/extensions/filters/http/router/v3/router.upbdefs.h +5 -1
  593. data/src/core/ext/upbdefs-gen/envoy/extensions/filters/http/stateful_session/v3/stateful_session.upbdefs.c +75 -39
  594. data/src/core/ext/upbdefs-gen/envoy/extensions/filters/http/stateful_session/v3/stateful_session.upbdefs.h +5 -1
  595. data/src/core/ext/upbdefs-gen/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upbdefs.c +1161 -570
  596. data/src/core/ext/upbdefs-gen/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upbdefs.h +5 -1
  597. data/src/core/ext/upbdefs-gen/envoy/extensions/http/stateful_session/cookie/v3/cookie.upbdefs.c +52 -28
  598. data/src/core/ext/upbdefs-gen/envoy/extensions/http/stateful_session/cookie/v3/cookie.upbdefs.h +5 -1
  599. data/src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/http_11_proxy/v3/upstream_http_11_connect.upbdefs.c +55 -29
  600. data/src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/http_11_proxy/v3/upstream_http_11_connect.upbdefs.h +5 -1
  601. data/src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/cert.upbdefs.c +48 -26
  602. data/src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/cert.upbdefs.h +5 -1
  603. data/src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/common.upbdefs.c +390 -194
  604. data/src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/common.upbdefs.h +5 -1
  605. data/src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/secret.upbdefs.c +126 -65
  606. data/src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/secret.upbdefs.h +5 -1
  607. data/src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/tls.upbdefs.c +498 -246
  608. data/src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/tls.upbdefs.h +5 -1
  609. data/src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/tls_spiffe_validator_config.upbdefs.c +74 -38
  610. data/src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/tls_spiffe_validator_config.upbdefs.h +5 -1
  611. data/src/core/ext/upbdefs-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upbdefs.c +221 -110
  612. data/src/core/ext/upbdefs-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upbdefs.h +5 -1
  613. data/src/core/ext/upbdefs-gen/envoy/service/discovery/v3/ads.upbdefs.c +68 -36
  614. data/src/core/ext/upbdefs-gen/envoy/service/discovery/v3/ads.upbdefs.h +5 -1
  615. data/src/core/ext/upbdefs-gen/envoy/service/discovery/v3/discovery.upbdefs.c +378 -187
  616. data/src/core/ext/upbdefs-gen/envoy/service/discovery/v3/discovery.upbdefs.h +5 -1
  617. data/src/core/ext/upbdefs-gen/envoy/service/load_stats/v3/lrs.upbdefs.c +100 -52
  618. data/src/core/ext/upbdefs-gen/envoy/service/load_stats/v3/lrs.upbdefs.h +5 -1
  619. data/src/core/ext/upbdefs-gen/envoy/service/status/v3/csds.upbdefs.c +257 -129
  620. data/src/core/ext/upbdefs-gen/envoy/service/status/v3/csds.upbdefs.h +5 -1
  621. data/src/core/ext/upbdefs-gen/envoy/type/http/v3/cookie.upbdefs.c +44 -24
  622. data/src/core/ext/upbdefs-gen/envoy/type/http/v3/cookie.upbdefs.h +5 -1
  623. data/src/core/ext/upbdefs-gen/envoy/type/http/v3/path_transformation.upbdefs.c +68 -35
  624. data/src/core/ext/upbdefs-gen/envoy/type/http/v3/path_transformation.upbdefs.h +5 -1
  625. data/src/core/ext/upbdefs-gen/envoy/type/matcher/v3/address.upbdefs.c +38 -20
  626. data/src/core/ext/upbdefs-gen/envoy/type/matcher/v3/address.upbdefs.h +5 -1
  627. data/src/core/ext/upbdefs-gen/envoy/type/matcher/v3/filter_state.upbdefs.c +59 -32
  628. data/src/core/ext/upbdefs-gen/envoy/type/matcher/v3/filter_state.upbdefs.h +5 -1
  629. data/src/core/ext/upbdefs-gen/envoy/type/matcher/v3/http_inputs.upbdefs.c +65 -34
  630. data/src/core/ext/upbdefs-gen/envoy/type/matcher/v3/http_inputs.upbdefs.h +5 -1
  631. data/src/core/ext/upbdefs-gen/envoy/type/matcher/v3/metadata.upbdefs.c +72 -38
  632. data/src/core/ext/upbdefs-gen/envoy/type/matcher/v3/metadata.upbdefs.h +5 -1
  633. data/src/core/ext/upbdefs-gen/envoy/type/matcher/v3/node.upbdefs.c +57 -31
  634. data/src/core/ext/upbdefs-gen/envoy/type/matcher/v3/node.upbdefs.h +5 -1
  635. data/src/core/ext/upbdefs-gen/envoy/type/matcher/v3/number.upbdefs.c +52 -29
  636. data/src/core/ext/upbdefs-gen/envoy/type/matcher/v3/number.upbdefs.h +5 -1
  637. data/src/core/ext/upbdefs-gen/envoy/type/matcher/v3/path.upbdefs.c +51 -28
  638. data/src/core/ext/upbdefs-gen/envoy/type/matcher/v3/path.upbdefs.h +5 -1
  639. data/src/core/ext/upbdefs-gen/envoy/type/matcher/v3/regex.upbdefs.c +89 -47
  640. data/src/core/ext/upbdefs-gen/envoy/type/matcher/v3/regex.upbdefs.h +5 -1
  641. data/src/core/ext/upbdefs-gen/envoy/type/matcher/v3/status_code_input.upbdefs.c +37 -20
  642. data/src/core/ext/upbdefs-gen/envoy/type/matcher/v3/status_code_input.upbdefs.h +5 -1
  643. data/src/core/ext/upbdefs-gen/envoy/type/matcher/v3/string.upbdefs.c +89 -47
  644. data/src/core/ext/upbdefs-gen/envoy/type/matcher/v3/string.upbdefs.h +5 -1
  645. data/src/core/ext/upbdefs-gen/envoy/type/matcher/v3/struct.upbdefs.c +67 -35
  646. data/src/core/ext/upbdefs-gen/envoy/type/matcher/v3/struct.upbdefs.h +5 -1
  647. data/src/core/ext/upbdefs-gen/envoy/type/matcher/v3/value.upbdefs.c +112 -58
  648. data/src/core/ext/upbdefs-gen/envoy/type/matcher/v3/value.upbdefs.h +5 -1
  649. data/src/core/ext/upbdefs-gen/envoy/type/metadata/v3/metadata.upbdefs.c +110 -56
  650. data/src/core/ext/upbdefs-gen/envoy/type/metadata/v3/metadata.upbdefs.h +5 -1
  651. data/src/core/ext/upbdefs-gen/envoy/type/tracing/v3/custom_tag.upbdefs.c +123 -62
  652. data/src/core/ext/upbdefs-gen/envoy/type/tracing/v3/custom_tag.upbdefs.h +5 -1
  653. data/src/core/ext/upbdefs-gen/envoy/type/v3/hash_policy.upbdefs.c +59 -31
  654. data/src/core/ext/upbdefs-gen/envoy/type/v3/hash_policy.upbdefs.h +5 -1
  655. data/src/core/ext/upbdefs-gen/envoy/type/v3/http.upbdefs.c +30 -16
  656. data/src/core/ext/upbdefs-gen/envoy/type/v3/http.upbdefs.h +5 -1
  657. data/src/core/ext/upbdefs-gen/envoy/type/v3/http_status.upbdefs.c +143 -72
  658. data/src/core/ext/upbdefs-gen/envoy/type/v3/http_status.upbdefs.h +5 -1
  659. data/src/core/ext/upbdefs-gen/envoy/type/v3/percent.upbdefs.c +61 -32
  660. data/src/core/ext/upbdefs-gen/envoy/type/v3/percent.upbdefs.h +5 -1
  661. data/src/core/ext/upbdefs-gen/envoy/type/v3/range.upbdefs.c +51 -27
  662. data/src/core/ext/upbdefs-gen/envoy/type/v3/range.upbdefs.h +5 -1
  663. data/src/core/ext/upbdefs-gen/envoy/type/v3/ratelimit_strategy.upbdefs.c +85 -45
  664. data/src/core/ext/upbdefs-gen/envoy/type/v3/ratelimit_strategy.upbdefs.h +5 -1
  665. data/src/core/ext/upbdefs-gen/envoy/type/v3/ratelimit_unit.upbdefs.c +35 -19
  666. data/src/core/ext/upbdefs-gen/envoy/type/v3/ratelimit_unit.upbdefs.h +5 -1
  667. data/src/core/ext/upbdefs-gen/envoy/type/v3/semantic_version.upbdefs.c +44 -23
  668. data/src/core/ext/upbdefs-gen/envoy/type/v3/semantic_version.upbdefs.h +5 -1
  669. data/src/core/ext/upbdefs-gen/envoy/type/v3/token_bucket.upbdefs.c +61 -33
  670. data/src/core/ext/upbdefs-gen/envoy/type/v3/token_bucket.upbdefs.h +5 -1
  671. data/src/core/ext/upbdefs-gen/google/api/annotations.upbdefs.c +35 -19
  672. data/src/core/ext/upbdefs-gen/google/api/annotations.upbdefs.h +5 -1
  673. data/src/core/ext/upbdefs-gen/google/api/expr/v1alpha1/checked.upbdefs.c +272 -133
  674. data/src/core/ext/upbdefs-gen/google/api/expr/v1alpha1/checked.upbdefs.h +5 -1
  675. data/src/core/ext/upbdefs-gen/google/api/expr/v1alpha1/syntax.upbdefs.c +315 -154
  676. data/src/core/ext/upbdefs-gen/google/api/expr/v1alpha1/syntax.upbdefs.h +5 -1
  677. data/src/core/ext/upbdefs-gen/google/api/http.upbdefs.c +64 -33
  678. data/src/core/ext/upbdefs-gen/google/api/http.upbdefs.h +5 -1
  679. data/src/core/ext/upbdefs-gen/google/api/httpbody.upbdefs.c +35 -19
  680. data/src/core/ext/upbdefs-gen/google/api/httpbody.upbdefs.h +5 -1
  681. data/src/core/ext/upbdefs-gen/google/protobuf/any.upbdefs.c +26 -15
  682. data/src/core/ext/upbdefs-gen/google/protobuf/any.upbdefs.h +5 -1
  683. data/src/core/ext/upbdefs-gen/google/protobuf/descriptor.upbdefs.c +1106 -497
  684. data/src/core/ext/upbdefs-gen/google/protobuf/descriptor.upbdefs.h +10 -1
  685. data/src/core/ext/upbdefs-gen/google/protobuf/duration.upbdefs.c +28 -16
  686. data/src/core/ext/upbdefs-gen/google/protobuf/duration.upbdefs.h +5 -1
  687. data/src/core/ext/upbdefs-gen/google/protobuf/empty.upbdefs.c +23 -13
  688. data/src/core/ext/upbdefs-gen/google/protobuf/empty.upbdefs.h +5 -1
  689. data/src/core/ext/upbdefs-gen/google/protobuf/struct.upbdefs.c +69 -35
  690. data/src/core/ext/upbdefs-gen/google/protobuf/struct.upbdefs.h +5 -1
  691. data/src/core/ext/upbdefs-gen/google/protobuf/timestamp.upbdefs.c +29 -16
  692. data/src/core/ext/upbdefs-gen/google/protobuf/timestamp.upbdefs.h +5 -1
  693. data/src/core/ext/upbdefs-gen/google/protobuf/wrappers.upbdefs.c +51 -26
  694. data/src/core/ext/upbdefs-gen/google/protobuf/wrappers.upbdefs.h +5 -1
  695. data/src/core/ext/upbdefs-gen/google/rpc/status.upbdefs.c +32 -17
  696. data/src/core/ext/upbdefs-gen/google/rpc/status.upbdefs.h +5 -1
  697. data/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/promise.upbdefs.c +175 -0
  698. data/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/promise.upbdefs.h +82 -0
  699. data/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/property_list.upbdefs.c +135 -0
  700. data/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/property_list.upbdefs.h +67 -0
  701. data/src/core/ext/upbdefs-gen/src/proto/grpc/lookup/v1/rls_config.upbdefs.c +161 -79
  702. data/src/core/ext/upbdefs-gen/src/proto/grpc/lookup/v1/rls_config.upbdefs.h +5 -1
  703. data/src/core/ext/upbdefs-gen/udpa/annotations/migrate.upbdefs.c +84 -42
  704. data/src/core/ext/upbdefs-gen/udpa/annotations/migrate.upbdefs.h +5 -1
  705. data/src/core/ext/upbdefs-gen/udpa/annotations/security.upbdefs.c +48 -26
  706. data/src/core/ext/upbdefs-gen/udpa/annotations/security.upbdefs.h +5 -1
  707. data/src/core/ext/upbdefs-gen/udpa/annotations/sensitive.upbdefs.c +26 -14
  708. data/src/core/ext/upbdefs-gen/udpa/annotations/sensitive.upbdefs.h +5 -1
  709. data/src/core/ext/upbdefs-gen/udpa/annotations/status.upbdefs.c +50 -26
  710. data/src/core/ext/upbdefs-gen/udpa/annotations/status.upbdefs.h +5 -1
  711. data/src/core/ext/upbdefs-gen/udpa/annotations/versioning.upbdefs.c +36 -19
  712. data/src/core/ext/upbdefs-gen/udpa/annotations/versioning.upbdefs.h +5 -1
  713. data/src/core/ext/upbdefs-gen/validate/validate.upbdefs.c +538 -261
  714. data/src/core/ext/upbdefs-gen/validate/validate.upbdefs.h +5 -1
  715. data/src/core/ext/upbdefs-gen/xds/annotations/v3/migrate.upbdefs.c +86 -43
  716. data/src/core/ext/upbdefs-gen/xds/annotations/v3/migrate.upbdefs.h +5 -1
  717. data/src/core/ext/upbdefs-gen/xds/annotations/v3/security.upbdefs.c +49 -26
  718. data/src/core/ext/upbdefs-gen/xds/annotations/v3/security.upbdefs.h +5 -1
  719. data/src/core/ext/upbdefs-gen/xds/annotations/v3/sensitive.upbdefs.c +27 -15
  720. data/src/core/ext/upbdefs-gen/xds/annotations/v3/sensitive.upbdefs.h +5 -1
  721. data/src/core/ext/upbdefs-gen/xds/annotations/v3/status.upbdefs.c +87 -44
  722. data/src/core/ext/upbdefs-gen/xds/annotations/v3/status.upbdefs.h +5 -1
  723. data/src/core/ext/upbdefs-gen/xds/annotations/v3/versioning.upbdefs.c +37 -20
  724. data/src/core/ext/upbdefs-gen/xds/annotations/v3/versioning.upbdefs.h +5 -1
  725. data/src/core/ext/upbdefs-gen/xds/core/v3/authority.upbdefs.c +30 -17
  726. data/src/core/ext/upbdefs-gen/xds/core/v3/authority.upbdefs.h +5 -1
  727. data/src/core/ext/upbdefs-gen/xds/core/v3/cidr.upbdefs.c +41 -23
  728. data/src/core/ext/upbdefs-gen/xds/core/v3/cidr.upbdefs.h +5 -1
  729. data/src/core/ext/upbdefs-gen/xds/core/v3/collection_entry.upbdefs.c +62 -33
  730. data/src/core/ext/upbdefs-gen/xds/core/v3/collection_entry.upbdefs.h +5 -1
  731. data/src/core/ext/upbdefs-gen/xds/core/v3/context_params.upbdefs.c +36 -19
  732. data/src/core/ext/upbdefs-gen/xds/core/v3/context_params.upbdefs.h +5 -1
  733. data/src/core/ext/upbdefs-gen/xds/core/v3/extension.upbdefs.c +36 -20
  734. data/src/core/ext/upbdefs-gen/xds/core/v3/extension.upbdefs.h +5 -1
  735. data/src/core/ext/upbdefs-gen/xds/core/v3/resource.upbdefs.c +42 -23
  736. data/src/core/ext/upbdefs-gen/xds/core/v3/resource.upbdefs.h +5 -1
  737. data/src/core/ext/upbdefs-gen/xds/core/v3/resource_locator.upbdefs.c +76 -39
  738. data/src/core/ext/upbdefs-gen/xds/core/v3/resource_locator.upbdefs.h +5 -1
  739. data/src/core/ext/upbdefs-gen/xds/core/v3/resource_name.upbdefs.c +45 -24
  740. data/src/core/ext/upbdefs-gen/xds/core/v3/resource_name.upbdefs.h +5 -1
  741. data/src/core/ext/upbdefs-gen/xds/type/matcher/v3/cel.upbdefs.c +41 -23
  742. data/src/core/ext/upbdefs-gen/xds/type/matcher/v3/cel.upbdefs.h +5 -1
  743. data/src/core/ext/upbdefs-gen/xds/type/matcher/v3/domain.upbdefs.c +53 -29
  744. data/src/core/ext/upbdefs-gen/xds/type/matcher/v3/domain.upbdefs.h +5 -1
  745. data/src/core/ext/upbdefs-gen/xds/type/matcher/v3/http_inputs.upbdefs.c +29 -16
  746. data/src/core/ext/upbdefs-gen/xds/type/matcher/v3/http_inputs.upbdefs.h +5 -1
  747. data/src/core/ext/upbdefs-gen/xds/type/matcher/v3/ip.upbdefs.c +58 -32
  748. data/src/core/ext/upbdefs-gen/xds/type/matcher/v3/ip.upbdefs.h +5 -1
  749. data/src/core/ext/upbdefs-gen/xds/type/matcher/v3/matcher.upbdefs.c +207 -103
  750. data/src/core/ext/upbdefs-gen/xds/type/matcher/v3/matcher.upbdefs.h +5 -1
  751. data/src/core/ext/upbdefs-gen/xds/type/matcher/v3/range.upbdefs.c +95 -49
  752. data/src/core/ext/upbdefs-gen/xds/type/matcher/v3/range.upbdefs.h +5 -1
  753. data/src/core/ext/upbdefs-gen/xds/type/matcher/v3/regex.upbdefs.c +38 -20
  754. data/src/core/ext/upbdefs-gen/xds/type/matcher/v3/regex.upbdefs.h +5 -1
  755. data/src/core/ext/upbdefs-gen/xds/type/matcher/v3/string.upbdefs.c +60 -31
  756. data/src/core/ext/upbdefs-gen/xds/type/matcher/v3/string.upbdefs.h +5 -1
  757. data/src/core/ext/upbdefs-gen/xds/type/v3/cel.upbdefs.c +67 -36
  758. data/src/core/ext/upbdefs-gen/xds/type/v3/cel.upbdefs.h +5 -1
  759. data/src/core/ext/upbdefs-gen/xds/type/v3/range.upbdefs.c +31 -17
  760. data/src/core/ext/upbdefs-gen/xds/type/v3/range.upbdefs.h +5 -1
  761. data/src/core/ext/upbdefs-gen/xds/type/v3/typed_struct.upbdefs.c +31 -17
  762. data/src/core/ext/upbdefs-gen/xds/type/v3/typed_struct.upbdefs.h +5 -1
  763. data/src/core/{lib/security/transport → filter/auth}/auth_filters.h +8 -32
  764. data/src/core/{lib/security/transport → filter/auth}/client_auth_filter.cc +7 -124
  765. data/src/core/{lib/security/transport → filter/auth}/server_auth_filter.cc +5 -4
  766. data/src/core/filter/filter_args.h +9 -23
  767. data/src/core/handshaker/handshaker.cc +23 -22
  768. data/src/core/handshaker/handshaker.h +3 -0
  769. data/src/core/handshaker/http_connect/http_connect_handshaker.cc +3 -1
  770. data/src/core/handshaker/http_connect/http_proxy_mapper.cc +7 -22
  771. data/src/core/handshaker/security/legacy_secure_endpoint.cc +597 -0
  772. data/src/core/handshaker/security/secure_endpoint.cc +812 -310
  773. data/src/core/handshaker/security/secure_endpoint.h +17 -0
  774. data/src/core/handshaker/security/security_handshaker.cc +8 -5
  775. data/src/core/handshaker/security/security_handshaker.h +1 -1
  776. data/src/core/handshaker/tcp_connect/tcp_connect_handshaker.cc +7 -1
  777. data/src/core/lib/address_utils/sockaddr_utils.cc +5 -5
  778. data/src/core/lib/channel/channel_args.cc +15 -0
  779. data/src/core/lib/channel/channel_args.h +56 -30
  780. data/src/core/lib/channel/channel_stack.cc +32 -4
  781. data/src/core/lib/channel/channel_stack.h +16 -6
  782. data/src/core/lib/channel/channel_stack_builder_impl.cc +2 -2
  783. data/src/core/lib/channel/channel_stack_builder_impl.h +2 -7
  784. data/src/core/lib/channel/connected_channel.cc +2 -2
  785. data/src/core/lib/channel/promise_based_filter.h +715 -307
  786. data/src/core/lib/debug/trace_flags.cc +4 -6
  787. data/src/core/lib/debug/trace_flags.h +2 -3
  788. data/src/core/lib/debug/trace_impl.h +0 -1
  789. data/src/core/lib/event_engine/ares_resolver.cc +165 -46
  790. data/src/core/lib/event_engine/ares_resolver.h +48 -2
  791. data/src/core/lib/event_engine/cf_engine/cf_engine.cc +8 -2
  792. data/src/core/lib/event_engine/cf_engine/cf_engine.h +1 -4
  793. data/src/core/lib/event_engine/cf_engine/cfstream_endpoint.cc +4 -4
  794. data/src/core/lib/event_engine/cf_engine/cfstream_endpoint.h +10 -6
  795. data/src/core/lib/event_engine/default_event_engine_factory.cc +6 -6
  796. data/src/core/lib/event_engine/default_event_engine_factory.h +1 -1
  797. data/src/core/lib/event_engine/endpoint_channel_arg_wrapper.cc +40 -0
  798. data/src/core/lib/event_engine/endpoint_channel_arg_wrapper.h +60 -0
  799. data/src/core/lib/event_engine/event_engine.cc +7 -0
  800. data/src/core/lib/event_engine/extensions/blocking_dns.h +46 -0
  801. data/src/core/lib/event_engine/extensions/channelz.h +66 -0
  802. data/src/core/lib/event_engine/extensions/iomgr_compatible.h +39 -0
  803. data/src/core/lib/event_engine/extensions/supports_win_sockets.h +48 -0
  804. data/src/core/lib/event_engine/extensions/tcp_trace.h +2 -2
  805. data/src/core/lib/event_engine/grpc_polled_fd.h +5 -0
  806. data/src/core/lib/event_engine/posix_engine/ev_epoll1_linux.cc +130 -162
  807. data/src/core/lib/event_engine/posix_engine/ev_epoll1_linux.h +11 -15
  808. data/src/core/lib/event_engine/posix_engine/ev_poll_posix.cc +75 -117
  809. data/src/core/lib/event_engine/posix_engine/ev_poll_posix.h +7 -9
  810. data/src/core/lib/event_engine/posix_engine/event_poller.h +18 -15
  811. data/src/core/lib/event_engine/posix_engine/event_poller_posix_default.cc +0 -18
  812. data/src/core/lib/event_engine/posix_engine/file_descriptor_collection.cc +124 -0
  813. data/src/core/lib/event_engine/posix_engine/file_descriptor_collection.h +243 -0
  814. data/src/core/lib/event_engine/posix_engine/grpc_polled_fd_posix.h +29 -19
  815. data/src/core/lib/event_engine/posix_engine/internal_errqueue.cc +6 -2
  816. data/src/core/lib/event_engine/posix_engine/internal_errqueue.h +6 -1
  817. data/src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.cc +4 -7
  818. data/src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.h +3 -0
  819. data/src/core/lib/event_engine/posix_engine/posix_endpoint.cc +149 -99
  820. data/src/core/lib/event_engine/posix_engine/posix_endpoint.h +29 -33
  821. data/src/core/lib/event_engine/posix_engine/posix_engine.cc +342 -105
  822. data/src/core/lib/event_engine/posix_engine/posix_engine.h +72 -29
  823. data/src/core/lib/event_engine/posix_engine/posix_engine_listener.cc +45 -37
  824. data/src/core/lib/event_engine/posix_engine/posix_engine_listener.h +6 -4
  825. data/src/core/lib/event_engine/posix_engine/posix_engine_listener_utils.cc +58 -142
  826. data/src/core/lib/event_engine/posix_engine/posix_engine_listener_utils.h +10 -5
  827. data/src/core/lib/event_engine/posix_engine/posix_interface.h +211 -0
  828. data/src/core/lib/event_engine/posix_engine/posix_interface_posix.cc +1083 -0
  829. data/src/core/lib/event_engine/posix_engine/posix_interface_windows.cc +281 -0
  830. data/src/core/lib/event_engine/posix_engine/posix_write_event_sink.cc +154 -0
  831. data/src/core/lib/event_engine/posix_engine/posix_write_event_sink.h +174 -0
  832. data/src/core/lib/event_engine/posix_engine/set_socket_dualstack.cc +64 -0
  833. data/src/core/lib/event_engine/posix_engine/tcp_socket_utils.cc +3 -730
  834. data/src/core/lib/event_engine/posix_engine/tcp_socket_utils.h +10 -170
  835. data/src/core/lib/event_engine/posix_engine/timer_manager.cc +33 -22
  836. data/src/core/lib/event_engine/posix_engine/timer_manager.h +13 -11
  837. data/src/core/lib/event_engine/posix_engine/traced_buffer_list.cc +117 -151
  838. data/src/core/lib/event_engine/posix_engine/traced_buffer_list.h +26 -94
  839. data/src/core/lib/event_engine/posix_engine/wakeup_fd_eventfd.cc +26 -25
  840. data/src/core/lib/event_engine/posix_engine/wakeup_fd_eventfd.h +6 -2
  841. data/src/core/lib/event_engine/posix_engine/wakeup_fd_pipe.cc +36 -54
  842. data/src/core/lib/event_engine/posix_engine/wakeup_fd_pipe.h +6 -2
  843. data/src/core/lib/event_engine/posix_engine/wakeup_fd_posix.h +7 -6
  844. data/src/core/lib/event_engine/posix_engine/wakeup_fd_posix_default.cc +12 -6
  845. data/src/core/lib/event_engine/posix_engine/wakeup_fd_posix_default.h +3 -1
  846. data/src/core/lib/event_engine/query_extensions.h +10 -21
  847. data/src/core/lib/event_engine/shim.cc +16 -14
  848. data/src/core/lib/event_engine/shim.h +14 -0
  849. data/src/core/lib/event_engine/tcp_socket_utils.cc +10 -9
  850. data/src/core/lib/event_engine/thread_pool/thread_pool.h +7 -3
  851. data/src/core/lib/event_engine/thread_pool/thread_pool_factory.cc +0 -17
  852. data/src/core/lib/event_engine/thread_pool/work_stealing_thread_pool.cc +19 -9
  853. data/src/core/lib/event_engine/thread_pool/work_stealing_thread_pool.h +5 -3
  854. data/src/core/lib/event_engine/utils.cc +34 -0
  855. data/src/core/lib/event_engine/utils.h +3 -0
  856. data/src/core/lib/event_engine/windows/grpc_polled_fd_windows.cc +4 -0
  857. data/src/core/lib/event_engine/windows/grpc_polled_fd_windows.h +4 -0
  858. data/src/core/lib/event_engine/windows/win_socket.cc +11 -0
  859. data/src/core/lib/event_engine/windows/win_socket.h +3 -0
  860. data/src/core/lib/event_engine/windows/windows_endpoint.cc +7 -12
  861. data/src/core/lib/event_engine/windows/windows_endpoint.h +5 -2
  862. data/src/core/lib/event_engine/windows/windows_engine.cc +42 -1
  863. data/src/core/lib/event_engine/windows/windows_engine.h +7 -3
  864. data/src/core/lib/event_engine/windows/windows_listener.cc +19 -8
  865. data/src/core/lib/event_engine/windows/windows_listener.h +9 -4
  866. data/src/core/lib/experiments/experiments.cc +393 -141
  867. data/src/core/lib/experiments/experiments.h +149 -79
  868. data/src/core/lib/iomgr/combiner.cc +3 -2
  869. data/src/core/lib/iomgr/endpoint.cc +4 -3
  870. data/src/core/lib/iomgr/endpoint.h +7 -4
  871. data/src/core/lib/iomgr/endpoint_cfstream.cc +3 -2
  872. data/src/core/lib/iomgr/endpoint_pair_posix.cc +43 -16
  873. data/src/core/lib/iomgr/endpoint_pair_windows.cc +43 -8
  874. data/src/core/lib/iomgr/error.cc +27 -43
  875. data/src/core/lib/iomgr/ev_epoll1_linux.cc +18 -1
  876. data/src/core/lib/iomgr/ev_poll_posix.cc +22 -0
  877. data/src/core/lib/iomgr/event_engine_shims/endpoint.cc +11 -10
  878. data/src/core/lib/iomgr/fork_posix.cc +0 -7
  879. data/src/core/lib/iomgr/iomgr.cc +0 -3
  880. data/src/core/lib/iomgr/iomgr_posix_cfstream.cc +3 -0
  881. data/src/core/lib/iomgr/polling_entity.cc +2 -7
  882. data/src/core/lib/iomgr/resolve_address_posix.cc +37 -47
  883. data/src/core/lib/iomgr/resolve_address_posix.h +15 -0
  884. data/src/core/lib/iomgr/resolve_address_windows.cc +22 -45
  885. data/src/core/lib/iomgr/resolve_address_windows.h +15 -2
  886. data/src/core/lib/iomgr/socket_utils_common_posix.cc +1 -0
  887. data/src/core/lib/iomgr/socket_utils_posix.cc +22 -11
  888. data/src/core/lib/iomgr/socket_utils_posix.h +12 -2
  889. data/src/core/lib/iomgr/tcp_client_cfstream.cc +8 -9
  890. data/src/core/lib/iomgr/tcp_client_posix.cc +25 -21
  891. data/src/core/lib/iomgr/tcp_client_posix.h +1 -1
  892. data/src/core/lib/iomgr/tcp_posix.cc +82 -47
  893. data/src/core/lib/iomgr/tcp_posix.h +10 -2
  894. data/src/core/lib/iomgr/tcp_server_posix.cc +9 -1
  895. data/src/core/lib/iomgr/tcp_server_utils_posix_common.cc +1 -4
  896. data/src/core/lib/iomgr/tcp_server_windows.cc +41 -18
  897. data/src/core/lib/iomgr/tcp_windows.cc +3 -2
  898. data/src/core/lib/iomgr/wakeup_fd_pipe.cc +10 -2
  899. data/src/core/lib/promise/activity.h +1 -0
  900. data/src/core/lib/promise/all_ok.h +31 -0
  901. data/src/core/lib/promise/arena_promise.h +23 -7
  902. data/src/core/lib/promise/detail/promise_factory.h +10 -0
  903. data/src/core/lib/promise/detail/promise_like.h +132 -1
  904. data/src/core/lib/promise/detail/promise_variant.h +50 -0
  905. data/src/core/lib/promise/detail/seq_state.h +880 -0
  906. data/src/core/lib/promise/if.h +20 -0
  907. data/src/core/lib/promise/inter_activity_latch.h +147 -0
  908. data/src/core/lib/promise/inter_activity_mutex.h +547 -0
  909. data/src/core/lib/promise/loop.h +73 -8
  910. data/src/core/lib/promise/map.h +106 -2
  911. data/src/core/lib/promise/match_promise.h +103 -0
  912. data/src/core/lib/promise/mpsc.cc +425 -0
  913. data/src/core/lib/promise/mpsc.h +490 -0
  914. data/src/core/lib/promise/party.cc +50 -1
  915. data/src/core/lib/promise/party.h +71 -2
  916. data/src/core/lib/promise/poll.h +22 -20
  917. data/src/core/lib/promise/promise.h +4 -2
  918. data/src/core/lib/promise/race.h +31 -0
  919. data/src/core/lib/promise/seq.h +5 -0
  920. data/src/core/lib/promise/sleep.cc +6 -3
  921. data/src/core/lib/promise/status_flag.h +28 -9
  922. data/src/core/lib/promise/try_seq.h +5 -0
  923. data/src/core/lib/promise/wait_set.cc +28 -0
  924. data/src/core/lib/promise/wait_set.h +86 -0
  925. data/src/core/lib/resource_quota/arena.h +19 -0
  926. data/src/core/lib/resource_quota/memory_quota.cc +9 -0
  927. data/src/core/lib/resource_quota/memory_quota.h +1 -3
  928. data/src/core/lib/security/authorization/evaluate_args.cc +1 -1
  929. data/src/core/lib/security/authorization/evaluate_args.h +1 -1
  930. data/src/core/lib/security/authorization/grpc_server_authz_filter.cc +1 -1
  931. data/src/core/lib/security/authorization/grpc_server_authz_filter.h +1 -1
  932. data/src/core/lib/slice/slice.h +11 -0
  933. data/src/core/lib/slice/slice_buffer.h +6 -0
  934. data/src/core/lib/surface/call.cc +24 -18
  935. data/src/core/lib/surface/call_utils.cc +3 -3
  936. data/src/core/lib/surface/call_utils.h +3 -3
  937. data/src/core/lib/surface/channel.h +2 -2
  938. data/src/core/lib/surface/channel_create.cc +139 -4
  939. data/src/core/lib/surface/channel_create.h +4 -0
  940. data/src/core/lib/surface/channel_init.cc +164 -47
  941. data/src/core/lib/surface/channel_init.h +66 -3
  942. data/src/core/lib/surface/completion_queue.cc +77 -17
  943. data/src/core/lib/surface/filter_stack_call.cc +58 -36
  944. data/src/core/lib/surface/filter_stack_call.h +1 -1
  945. data/src/core/lib/surface/init.cc +10 -20
  946. data/src/core/lib/surface/lame_client.cc +1 -1
  947. data/src/core/lib/surface/legacy_channel.cc +30 -28
  948. data/src/core/lib/surface/legacy_channel.h +4 -2
  949. data/src/core/lib/surface/version.cc +2 -2
  950. data/src/core/lib/transport/error_utils.cc +65 -11
  951. data/src/core/lib/transport/error_utils.h +2 -2
  952. data/src/core/lib/transport/promise_endpoint.cc +110 -0
  953. data/src/core/lib/transport/promise_endpoint.h +307 -0
  954. data/src/core/lib/transport/status_conversion.cc +11 -36
  955. data/src/core/lib/transport/status_conversion.h +5 -4
  956. data/src/core/lib/transport/transport.cc +2 -2
  957. data/src/core/lib/transport/transport.h +8 -5
  958. data/src/core/lib/transport/transport_op_string.cc +1 -1
  959. data/src/core/load_balancing/backend_metric_parser.cc +12 -18
  960. data/src/core/load_balancing/child_policy_handler.cc +2 -4
  961. data/src/core/load_balancing/delegating_helper.h +3 -4
  962. data/src/core/load_balancing/grpclb/client_load_reporting_filter.cc +1 -1
  963. data/src/core/load_balancing/grpclb/grpclb.cc +3 -4
  964. data/src/core/load_balancing/health_check_client.cc +3 -9
  965. data/src/core/load_balancing/lb_policy.h +1 -3
  966. data/src/core/load_balancing/oob_backend_metric.cc +3 -9
  967. data/src/core/load_balancing/outlier_detection/outlier_detection.cc +4 -3
  968. data/src/core/load_balancing/pick_first/pick_first.cc +6 -958
  969. data/src/core/load_balancing/rls/rls.cc +37 -42
  970. data/src/core/load_balancing/round_robin/round_robin.cc +2 -3
  971. data/src/core/load_balancing/weighted_round_robin/weighted_round_robin.cc +4 -4
  972. data/src/core/load_balancing/weighted_target/weighted_target.cc +4 -10
  973. data/src/core/load_balancing/xds/cds.cc +13 -11
  974. data/src/core/load_balancing/xds/xds_cluster_impl.cc +1 -1
  975. data/src/core/load_balancing/xds/xds_override_host.cc +55 -34
  976. data/src/core/plugin_registry/grpc_plugin_registry.cc +4 -0
  977. data/src/core/plugin_registry/grpc_plugin_registry_extra.cc +2 -2
  978. data/src/core/resolver/dns/c_ares/dns_resolver_ares.cc +1 -3
  979. data/src/core/resolver/dns/c_ares/grpc_ares_wrapper.h +4 -0
  980. data/src/core/resolver/google_c2p/google_c2p_resolver.cc +1 -1
  981. data/src/core/resolver/sockaddr/sockaddr_resolver.cc +2 -1
  982. data/src/core/resolver/xds/xds_config.cc +6 -3
  983. data/src/core/resolver/xds/xds_config.h +9 -4
  984. data/src/core/resolver/xds/xds_dependency_manager.cc +29 -9
  985. data/src/core/resolver/xds/xds_dependency_manager.h +2 -1
  986. data/src/core/resolver/xds/xds_resolver.cc +35 -14
  987. data/src/core/server/add_port.cc +87 -0
  988. data/src/core/server/server.cc +135 -66
  989. data/src/core/server/server.h +24 -7
  990. data/src/core/server/server_call_tracer_filter.cc +1 -1
  991. data/src/core/server/server_config_selector.h +1 -1
  992. data/src/core/server/server_config_selector_filter.cc +1 -1
  993. data/src/core/server/xds_server_config_fetcher.cc +68 -30
  994. data/src/core/service_config/service_config.h +1 -1
  995. data/src/core/service_config/service_config_channel_arg_filter.cc +1 -1
  996. data/src/core/service_config/service_config_impl.h +1 -1
  997. data/src/core/telemetry/call_tracer.cc +4 -6
  998. data/src/core/telemetry/call_tracer.h +4 -4
  999. data/src/core/telemetry/context_list_entry.cc +38 -0
  1000. data/src/core/{ext/transport/chttp2/transport → telemetry}/context_list_entry.h +45 -15
  1001. data/src/core/telemetry/default_tcp_tracer.cc +26 -0
  1002. data/src/core/telemetry/default_tcp_tracer.h +44 -0
  1003. data/src/core/telemetry/metrics.cc +30 -12
  1004. data/src/core/telemetry/metrics.h +15 -3
  1005. data/src/core/telemetry/stats.h +0 -5
  1006. data/src/core/telemetry/stats_data.cc +564 -423
  1007. data/src/core/telemetry/stats_data.h +474 -241
  1008. data/src/core/telemetry/tcp_tracer.cc +38 -0
  1009. data/src/core/telemetry/tcp_tracer.h +103 -99
  1010. data/src/core/{lib/security/context/security_context.cc → transport/auth_context.cc} +1 -97
  1011. data/src/core/{lib/security/context/security_context.h → transport/auth_context.h} +5 -76
  1012. data/src/core/transport/endpoint_transport.h +90 -0
  1013. data/src/core/transport/endpoint_transport_client_channel_factory.cc +61 -0
  1014. data/src/core/transport/endpoint_transport_client_channel_factory.h +57 -0
  1015. data/src/core/tsi/alts/handshaker/alts_handshaker_client.cc +33 -1
  1016. data/src/core/tsi/alts/handshaker/alts_handshaker_client.h +3 -1
  1017. data/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc +76 -22
  1018. data/src/core/tsi/alts/handshaker/alts_tsi_handshaker.h +9 -3
  1019. data/src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc +11 -3
  1020. data/src/core/tsi/fake_transport_security.cc +17 -0
  1021. data/src/core/tsi/ssl_transport_security.cc +192 -72
  1022. data/src/core/tsi/ssl_transport_security.h +6 -1
  1023. data/src/core/tsi/transport_security.h +3 -0
  1024. data/src/core/tsi/transport_security_grpc.cc +8 -0
  1025. data/src/core/tsi/transport_security_grpc.h +22 -3
  1026. data/src/core/tsi/transport_security_interface.h +30 -25
  1027. data/src/core/util/backoff.cc +5 -16
  1028. data/src/core/util/backoff.h +1 -1
  1029. data/src/core/util/check_class_size.h +48 -0
  1030. data/src/core/util/down_cast.h +1 -1
  1031. data/src/core/util/dual_ref_counted.h +48 -0
  1032. data/src/core/util/function_signature.h +80 -0
  1033. data/src/core/util/gcp_metadata_query.cc +4 -3
  1034. data/src/core/util/http_client/httpcli.cc +15 -8
  1035. data/src/core/util/http_client/httpcli.h +4 -1
  1036. data/src/core/util/http_client/httpcli_security_connector.cc +5 -4
  1037. data/src/core/util/json/json_object_loader.h +3 -3
  1038. data/src/core/util/latent_see.cc +28 -2
  1039. data/src/core/util/latent_see.h +19 -28
  1040. data/src/core/util/linux/env.cc +3 -1
  1041. data/src/core/util/load_file.cc +26 -14
  1042. data/src/core/util/log.cc +4 -0
  1043. data/src/core/util/memory_usage.h +268 -0
  1044. data/src/core/util/per_cpu.cc +2 -0
  1045. data/src/core/util/per_cpu.h +7 -0
  1046. data/src/core/util/ref_counted_ptr.h +26 -0
  1047. data/src/core/util/shared_bit_gen.cc +21 -0
  1048. data/src/core/util/shared_bit_gen.h +64 -0
  1049. data/src/core/util/single_set_ptr.h +35 -4
  1050. data/src/core/util/status_helper.cc +86 -63
  1051. data/src/core/util/status_helper.h +9 -26
  1052. data/src/core/util/upb_utils.h +42 -0
  1053. data/src/core/util/uri.cc +76 -17
  1054. data/src/core/util/uri.h +13 -8
  1055. data/src/core/util/useful.h +53 -2
  1056. data/src/core/util/wait_for_single_owner.cc +31 -0
  1057. data/src/core/util/wait_for_single_owner.h +24 -0
  1058. data/src/core/xds/grpc/certificate_provider_store.cc +1 -1
  1059. data/src/core/xds/grpc/certificate_provider_store.h +3 -3
  1060. data/src/core/xds/grpc/file_watcher_certificate_provider_factory.cc +3 -3
  1061. data/src/core/xds/grpc/file_watcher_certificate_provider_factory.h +1 -1
  1062. data/src/core/xds/grpc/xds_bootstrap_grpc.cc +12 -7
  1063. data/src/core/xds/grpc/xds_bootstrap_grpc.h +5 -0
  1064. data/src/core/xds/grpc/xds_certificate_provider.cc +1 -1
  1065. data/src/core/xds/grpc/xds_certificate_provider.h +2 -2
  1066. data/src/core/xds/grpc/xds_client_grpc.cc +13 -8
  1067. data/src/core/xds/grpc/xds_client_grpc.h +4 -2
  1068. data/src/core/xds/grpc/xds_cluster.h +3 -3
  1069. data/src/core/xds/grpc/xds_cluster_parser.cc +3 -2
  1070. data/src/core/xds/grpc/xds_common_types_parser.cc +138 -58
  1071. data/src/core/xds/grpc/xds_common_types_parser.h +12 -0
  1072. data/src/core/xds/grpc/xds_http_fault_filter.cc +1 -1
  1073. data/src/core/xds/grpc/xds_http_filter.h +8 -1
  1074. data/src/core/xds/grpc/xds_http_filter_registry.cc +1 -3
  1075. data/src/core/xds/grpc/xds_http_filter_registry.h +1 -1
  1076. data/src/core/xds/grpc/xds_http_gcp_authn_filter.cc +22 -0
  1077. data/src/core/xds/grpc/xds_http_gcp_authn_filter.h +3 -0
  1078. data/src/core/xds/grpc/xds_http_rbac_filter.cc +10 -17
  1079. data/src/core/xds/grpc/xds_metadata_parser.cc +40 -64
  1080. data/src/core/xds/grpc/xds_metadata_parser.h +0 -2
  1081. data/src/core/xds/grpc/xds_route_config.h +1 -1
  1082. data/src/core/xds/grpc/xds_route_config_parser.cc +71 -116
  1083. data/src/core/xds/grpc/xds_route_config_parser.h +1 -1
  1084. data/src/core/xds/grpc/xds_routing.h +1 -1
  1085. data/src/core/xds/grpc/xds_server_grpc.cc +110 -48
  1086. data/src/core/xds/grpc/xds_server_grpc.h +31 -13
  1087. data/src/core/xds/grpc/xds_server_grpc_interface.h +6 -2
  1088. data/src/core/xds/grpc/xds_transport_grpc.cc +23 -5
  1089. data/src/core/xds/grpc/xds_transport_grpc.h +5 -3
  1090. data/src/core/xds/xds_client/lrs_client.cc +6 -5
  1091. data/src/core/xds/xds_client/lrs_client.h +7 -7
  1092. data/src/core/xds/xds_client/xds_bootstrap.h +18 -1
  1093. data/src/core/xds/xds_client/xds_client.cc +52 -29
  1094. data/src/core/xds/xds_client/xds_client.h +3 -1
  1095. data/src/core/xds/xds_client/xds_resource_type.h +1 -2
  1096. data/src/core/xds/xds_client/xds_transport.h +1 -1
  1097. data/src/ruby/ext/grpc/extconf.rb +4 -2
  1098. data/src/ruby/ext/grpc/rb_call.c +1 -8
  1099. data/src/ruby/ext/grpc/rb_channel.c +72 -568
  1100. data/src/ruby/ext/grpc/rb_channel.h +0 -3
  1101. data/src/ruby/ext/grpc/rb_completion_queue.c +26 -14
  1102. data/src/ruby/ext/grpc/rb_completion_queue.h +1 -7
  1103. data/src/ruby/ext/grpc/rb_grpc.c +9 -5
  1104. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +1 -1
  1105. data/src/ruby/ext/grpc/rb_loader.c +0 -4
  1106. data/src/ruby/ext/grpc/rb_server.c +31 -50
  1107. data/src/ruby/lib/grpc/generic/client_stub.rb +4 -4
  1108. data/src/ruby/lib/grpc/version.rb +1 -1
  1109. data/src/ruby/spec/core_spec.rb +22 -0
  1110. data/src/ruby/spec/generic/active_call_spec.rb +1 -1
  1111. data/src/ruby/spec/generic/client_stub_spec.rb +2 -6
  1112. data/src/ruby/spec/generic/rpc_server_spec.rb +1 -1
  1113. data/third_party/abseil-cpp/absl/algorithm/algorithm.h +2 -2
  1114. data/third_party/abseil-cpp/absl/algorithm/container.h +81 -67
  1115. data/third_party/abseil-cpp/absl/base/attributes.h +142 -23
  1116. data/third_party/abseil-cpp/absl/base/call_once.h +18 -16
  1117. data/third_party/abseil-cpp/absl/base/config.h +23 -132
  1118. data/third_party/abseil-cpp/absl/base/{internal/fast_type_id.h → fast_type_id.h} +11 -16
  1119. data/third_party/abseil-cpp/absl/base/internal/cycleclock.cc +0 -5
  1120. data/third_party/abseil-cpp/absl/base/internal/cycleclock_config.h +7 -7
  1121. data/third_party/abseil-cpp/absl/base/internal/endian.h +34 -38
  1122. data/third_party/abseil-cpp/absl/base/internal/iterator_traits.h +71 -0
  1123. data/third_party/abseil-cpp/absl/base/internal/low_level_alloc.cc +6 -5
  1124. data/third_party/abseil-cpp/absl/base/internal/nullability_deprecated.h +106 -0
  1125. data/third_party/abseil-cpp/absl/base/internal/raw_logging.cc +1 -1
  1126. data/third_party/abseil-cpp/absl/base/internal/spinlock.cc +0 -9
  1127. data/third_party/abseil-cpp/absl/base/internal/spinlock.h +3 -13
  1128. data/third_party/abseil-cpp/absl/base/internal/sysinfo.cc +14 -0
  1129. data/third_party/abseil-cpp/absl/base/internal/thread_identity.h +5 -1
  1130. data/third_party/abseil-cpp/absl/base/internal/tracing.cc +39 -0
  1131. data/third_party/abseil-cpp/absl/base/internal/tracing.h +81 -0
  1132. data/third_party/abseil-cpp/absl/base/internal/unaligned_access.h +6 -6
  1133. data/third_party/abseil-cpp/absl/base/internal/unscaledcycleclock.cc +0 -10
  1134. data/third_party/abseil-cpp/absl/base/internal/unscaledcycleclock.h +17 -0
  1135. data/third_party/abseil-cpp/absl/base/macros.h +35 -4
  1136. data/third_party/abseil-cpp/absl/base/no_destructor.h +11 -32
  1137. data/third_party/abseil-cpp/absl/base/nullability.h +124 -56
  1138. data/third_party/abseil-cpp/absl/base/optimization.h +8 -12
  1139. data/third_party/abseil-cpp/absl/base/options.h +7 -81
  1140. data/third_party/abseil-cpp/absl/base/policy_checks.h +9 -7
  1141. data/third_party/abseil-cpp/absl/cleanup/cleanup.h +1 -3
  1142. data/third_party/abseil-cpp/absl/cleanup/internal/cleanup.h +3 -4
  1143. data/third_party/abseil-cpp/absl/container/btree_map.h +891 -0
  1144. data/third_party/abseil-cpp/absl/container/btree_set.h +826 -0
  1145. data/third_party/abseil-cpp/absl/container/fixed_array.h +9 -15
  1146. data/third_party/abseil-cpp/absl/container/flat_hash_map.h +22 -3
  1147. data/third_party/abseil-cpp/absl/container/flat_hash_set.h +23 -4
  1148. data/third_party/abseil-cpp/absl/container/inlined_vector.h +10 -6
  1149. data/third_party/abseil-cpp/absl/container/internal/btree.h +3149 -0
  1150. data/third_party/abseil-cpp/absl/container/internal/btree_container.h +867 -0
  1151. data/third_party/abseil-cpp/absl/container/internal/common.h +43 -0
  1152. data/third_party/abseil-cpp/absl/container/internal/common_policy_traits.h +10 -2
  1153. data/third_party/abseil-cpp/absl/container/internal/container_memory.h +10 -10
  1154. data/third_party/abseil-cpp/absl/container/internal/hash_function_defaults.h +1 -8
  1155. data/third_party/abseil-cpp/absl/container/internal/hash_policy_traits.h +0 -4
  1156. data/third_party/abseil-cpp/absl/container/internal/hashtable_control_bytes.h +527 -0
  1157. data/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler.cc +20 -4
  1158. data/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler.h +31 -12
  1159. data/third_party/abseil-cpp/absl/container/internal/inlined_vector.h +6 -9
  1160. data/third_party/abseil-cpp/absl/container/internal/layout.h +27 -43
  1161. data/third_party/abseil-cpp/absl/container/internal/raw_hash_map.h +199 -68
  1162. data/third_party/abseil-cpp/absl/container/internal/raw_hash_set.cc +1462 -263
  1163. data/third_party/abseil-cpp/absl/container/internal/raw_hash_set.h +1170 -1547
  1164. data/third_party/abseil-cpp/absl/container/internal/raw_hash_set_resize_impl.h +80 -0
  1165. data/third_party/abseil-cpp/absl/crc/crc32c.cc +0 -4
  1166. data/third_party/abseil-cpp/absl/crc/crc32c.h +7 -5
  1167. data/third_party/abseil-cpp/absl/crc/internal/cpu_detect.cc +56 -0
  1168. data/third_party/abseil-cpp/absl/crc/internal/crc32_x86_arm_combined_simd.h +0 -22
  1169. data/third_party/abseil-cpp/absl/crc/internal/crc_x86_arm_combined.cc +45 -74
  1170. data/third_party/abseil-cpp/absl/crc/internal/non_temporal_memcpy.h +21 -7
  1171. data/third_party/abseil-cpp/absl/debugging/internal/addresses.h +57 -0
  1172. data/third_party/abseil-cpp/absl/debugging/internal/decode_rust_punycode.cc +1 -1
  1173. data/third_party/abseil-cpp/absl/debugging/internal/decode_rust_punycode.h +5 -5
  1174. data/third_party/abseil-cpp/absl/debugging/internal/demangle.cc +12 -37
  1175. data/third_party/abseil-cpp/absl/debugging/internal/demangle_rust.cc +16 -16
  1176. data/third_party/abseil-cpp/absl/debugging/internal/elf_mem_image.h +1 -1
  1177. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_aarch64-inl.inc +40 -21
  1178. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_arm-inl.inc +16 -7
  1179. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_config.h +7 -0
  1180. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_emscripten-inl.inc +14 -5
  1181. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_generic-inl.inc +10 -4
  1182. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_powerpc-inl.inc +27 -16
  1183. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_riscv-inl.inc +20 -8
  1184. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_unimplemented-inl.inc +4 -3
  1185. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_win32-inl.inc +15 -28
  1186. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_x86-inl.inc +19 -9
  1187. data/third_party/abseil-cpp/absl/debugging/leak_check.cc +73 -0
  1188. data/third_party/abseil-cpp/absl/debugging/leak_check.h +150 -0
  1189. data/third_party/abseil-cpp/absl/debugging/stacktrace.cc +144 -27
  1190. data/third_party/abseil-cpp/absl/debugging/stacktrace.h +73 -5
  1191. data/third_party/abseil-cpp/absl/debugging/symbolize.cc +3 -2
  1192. data/third_party/abseil-cpp/absl/debugging/symbolize_elf.inc +67 -18
  1193. data/third_party/abseil-cpp/absl/debugging/symbolize_emscripten.inc +3 -2
  1194. data/third_party/abseil-cpp/absl/debugging/symbolize_win32.inc +25 -6
  1195. data/third_party/abseil-cpp/absl/flags/commandlineflag.cc +1 -0
  1196. data/third_party/abseil-cpp/absl/flags/commandlineflag.h +9 -2
  1197. data/third_party/abseil-cpp/absl/flags/flag.h +18 -15
  1198. data/third_party/abseil-cpp/absl/flags/internal/commandlineflag.h +2 -2
  1199. data/third_party/abseil-cpp/absl/flags/internal/flag.cc +14 -5
  1200. data/third_party/abseil-cpp/absl/flags/internal/flag.h +23 -11
  1201. data/third_party/abseil-cpp/absl/flags/internal/private_handle_accessor.cc +4 -0
  1202. data/third_party/abseil-cpp/absl/flags/internal/private_handle_accessor.h +3 -0
  1203. data/third_party/abseil-cpp/absl/flags/internal/program_name.cc +13 -12
  1204. data/third_party/abseil-cpp/absl/flags/internal/registry.h +4 -3
  1205. data/third_party/abseil-cpp/absl/flags/reflection.cc +2 -3
  1206. data/third_party/abseil-cpp/absl/flags/usage_config.cc +9 -4
  1207. data/third_party/abseil-cpp/absl/functional/any_invocable.h +8 -10
  1208. data/third_party/abseil-cpp/absl/functional/function_ref.h +2 -9
  1209. data/third_party/abseil-cpp/absl/functional/internal/any_invocable.h +110 -226
  1210. data/third_party/abseil-cpp/absl/functional/internal/front_binder.h +10 -12
  1211. data/third_party/abseil-cpp/absl/functional/internal/function_ref.h +2 -5
  1212. data/third_party/abseil-cpp/absl/hash/hash.h +44 -2
  1213. data/third_party/abseil-cpp/absl/hash/internal/hash.cc +14 -18
  1214. data/third_party/abseil-cpp/absl/hash/internal/hash.h +257 -127
  1215. data/third_party/abseil-cpp/absl/hash/internal/low_level_hash.cc +27 -72
  1216. data/third_party/abseil-cpp/absl/hash/internal/low_level_hash.h +2 -6
  1217. data/third_party/abseil-cpp/absl/hash/internal/weakly_mixed_integer.h +38 -0
  1218. data/third_party/abseil-cpp/absl/log/absl_vlog_is_on.h +2 -0
  1219. data/third_party/abseil-cpp/absl/log/check.h +2 -1
  1220. data/third_party/abseil-cpp/absl/log/globals.h +4 -5
  1221. data/third_party/abseil-cpp/absl/log/internal/append_truncated.h +28 -0
  1222. data/third_party/abseil-cpp/absl/log/internal/check_op.cc +43 -38
  1223. data/third_party/abseil-cpp/absl/log/internal/check_op.h +124 -99
  1224. data/third_party/abseil-cpp/absl/log/internal/conditions.cc +5 -3
  1225. data/third_party/abseil-cpp/absl/log/internal/conditions.h +7 -2
  1226. data/third_party/abseil-cpp/absl/log/internal/log_message.cc +158 -64
  1227. data/third_party/abseil-cpp/absl/log/internal/log_message.h +140 -83
  1228. data/third_party/abseil-cpp/absl/log/internal/nullstream.h +1 -0
  1229. data/third_party/abseil-cpp/absl/log/internal/proto.cc +3 -5
  1230. data/third_party/abseil-cpp/absl/log/internal/proto.h +28 -18
  1231. data/third_party/abseil-cpp/absl/log/internal/strip.h +4 -12
  1232. data/third_party/abseil-cpp/absl/log/internal/structured_proto.cc +115 -0
  1233. data/third_party/abseil-cpp/absl/log/internal/structured_proto.h +107 -0
  1234. data/third_party/abseil-cpp/absl/log/internal/vlog_config.cc +8 -1
  1235. data/third_party/abseil-cpp/absl/log/internal/vlog_config.h +8 -6
  1236. data/third_party/abseil-cpp/absl/log/internal/voidify.h +10 -4
  1237. data/third_party/abseil-cpp/absl/log/log.h +48 -35
  1238. data/third_party/abseil-cpp/absl/log/log_sink_registry.h +5 -2
  1239. data/third_party/abseil-cpp/absl/log/vlog_is_on.h +2 -0
  1240. data/third_party/abseil-cpp/absl/meta/type_traits.h +62 -181
  1241. data/third_party/abseil-cpp/absl/numeric/bits.h +68 -2
  1242. data/third_party/abseil-cpp/absl/numeric/int128.cc +0 -52
  1243. data/third_party/abseil-cpp/absl/numeric/int128.h +15 -3
  1244. data/third_party/abseil-cpp/absl/numeric/int128_have_intrinsic.inc +6 -4
  1245. data/third_party/abseil-cpp/absl/numeric/int128_no_intrinsic.inc +6 -3
  1246. data/third_party/abseil-cpp/absl/numeric/internal/bits.h +7 -3
  1247. data/third_party/abseil-cpp/absl/profiling/internal/exponential_biased.cc +1 -1
  1248. data/third_party/abseil-cpp/absl/random/bernoulli_distribution.h +3 -1
  1249. data/third_party/abseil-cpp/absl/random/beta_distribution.h +3 -1
  1250. data/third_party/abseil-cpp/absl/random/bit_gen_ref.h +12 -12
  1251. data/third_party/abseil-cpp/absl/random/discrete_distribution.cc +10 -0
  1252. data/third_party/abseil-cpp/absl/random/discrete_distribution.h +4 -2
  1253. data/third_party/abseil-cpp/absl/random/distributions.h +6 -8
  1254. data/third_party/abseil-cpp/absl/random/exponential_distribution.h +1 -0
  1255. data/third_party/abseil-cpp/absl/random/gaussian_distribution.h +3 -2
  1256. data/third_party/abseil-cpp/absl/random/internal/distribution_caller.h +8 -7
  1257. data/third_party/abseil-cpp/absl/random/internal/{pool_urbg.cc → entropy_pool.cc} +22 -90
  1258. data/third_party/abseil-cpp/absl/random/internal/entropy_pool.h +35 -0
  1259. data/third_party/abseil-cpp/absl/random/internal/iostream_state_saver.h +5 -2
  1260. data/third_party/abseil-cpp/absl/random/internal/nonsecure_base.h +5 -6
  1261. data/third_party/abseil-cpp/absl/random/internal/platform.h +12 -12
  1262. data/third_party/abseil-cpp/absl/random/internal/randen_detect.cc +57 -6
  1263. data/third_party/abseil-cpp/absl/random/internal/randen_engine.h +2 -1
  1264. data/third_party/abseil-cpp/absl/random/internal/seed_material.cc +20 -12
  1265. data/third_party/abseil-cpp/absl/random/internal/seed_material.h +5 -5
  1266. data/third_party/abseil-cpp/absl/random/internal/uniform_helper.h +2 -2
  1267. data/third_party/abseil-cpp/absl/random/internal/wide_multiply.h +0 -1
  1268. data/third_party/abseil-cpp/absl/random/log_uniform_int_distribution.h +1 -4
  1269. data/third_party/abseil-cpp/absl/random/poisson_distribution.h +4 -3
  1270. data/third_party/abseil-cpp/absl/random/random.h +88 -53
  1271. data/third_party/abseil-cpp/absl/random/seed_gen_exception.cc +2 -3
  1272. data/third_party/abseil-cpp/absl/random/seed_sequences.cc +6 -2
  1273. data/third_party/abseil-cpp/absl/random/seed_sequences.h +1 -2
  1274. data/third_party/abseil-cpp/absl/random/uniform_int_distribution.h +2 -1
  1275. data/third_party/abseil-cpp/absl/random/uniform_real_distribution.h +2 -0
  1276. data/third_party/abseil-cpp/absl/random/zipf_distribution.h +5 -4
  1277. data/third_party/abseil-cpp/absl/status/internal/status_internal.cc +10 -7
  1278. data/third_party/abseil-cpp/absl/status/internal/status_internal.h +3 -4
  1279. data/third_party/abseil-cpp/absl/status/internal/statusor_internal.h +4 -3
  1280. data/third_party/abseil-cpp/absl/status/status.cc +4 -8
  1281. data/third_party/abseil-cpp/absl/status/status.h +8 -8
  1282. data/third_party/abseil-cpp/absl/status/status_payload_printer.h +2 -2
  1283. data/third_party/abseil-cpp/absl/status/statusor.cc +2 -2
  1284. data/third_party/abseil-cpp/absl/status/statusor.h +6 -6
  1285. data/third_party/abseil-cpp/absl/strings/ascii.cc +44 -29
  1286. data/third_party/abseil-cpp/absl/strings/ascii.h +62 -22
  1287. data/third_party/abseil-cpp/absl/strings/charconv.cc +25 -29
  1288. data/third_party/abseil-cpp/absl/strings/charconv.h +5 -5
  1289. data/third_party/abseil-cpp/absl/strings/charset.h +3 -4
  1290. data/third_party/abseil-cpp/absl/strings/cord.cc +54 -58
  1291. data/third_party/abseil-cpp/absl/strings/cord.h +99 -102
  1292. data/third_party/abseil-cpp/absl/strings/cord_analysis.cc +11 -11
  1293. data/third_party/abseil-cpp/absl/strings/cord_analysis.h +3 -3
  1294. data/third_party/abseil-cpp/absl/strings/escaping.cc +186 -197
  1295. data/third_party/abseil-cpp/absl/strings/escaping.h +9 -10
  1296. data/third_party/abseil-cpp/absl/strings/internal/charconv_bigint.cc +1 -1
  1297. data/third_party/abseil-cpp/absl/strings/internal/charconv_bigint.h +1 -1
  1298. data/third_party/abseil-cpp/absl/strings/internal/cord_internal.h +53 -22
  1299. data/third_party/abseil-cpp/absl/strings/internal/cord_rep_btree.cc +0 -4
  1300. data/third_party/abseil-cpp/absl/strings/internal/cordz_info.cc +0 -4
  1301. data/third_party/abseil-cpp/absl/strings/internal/str_format/arg.cc +7 -63
  1302. data/third_party/abseil-cpp/absl/strings/internal/str_format/arg.h +1 -11
  1303. data/third_party/abseil-cpp/absl/strings/internal/str_format/extension.cc +0 -22
  1304. data/third_party/abseil-cpp/absl/strings/internal/str_format/float_conversion.cc +3 -2
  1305. data/third_party/abseil-cpp/absl/strings/internal/str_format/output.cc +5 -3
  1306. data/third_party/abseil-cpp/absl/strings/internal/str_format/parser.h +4 -2
  1307. data/third_party/abseil-cpp/absl/strings/internal/str_join_internal.h +3 -3
  1308. data/third_party/abseil-cpp/absl/strings/internal/str_split_internal.h +35 -0
  1309. data/third_party/abseil-cpp/absl/strings/internal/string_constant.h +0 -5
  1310. data/third_party/abseil-cpp/absl/strings/internal/utf8.cc +96 -1
  1311. data/third_party/abseil-cpp/absl/strings/internal/utf8.h +15 -1
  1312. data/third_party/abseil-cpp/absl/strings/match.h +21 -11
  1313. data/third_party/abseil-cpp/absl/strings/numbers.cc +55 -33
  1314. data/third_party/abseil-cpp/absl/strings/numbers.h +87 -58
  1315. data/third_party/abseil-cpp/absl/strings/str_cat.cc +6 -7
  1316. data/third_party/abseil-cpp/absl/strings/str_cat.h +41 -30
  1317. data/third_party/abseil-cpp/absl/strings/str_format.h +18 -18
  1318. data/third_party/abseil-cpp/absl/strings/str_replace.cc +3 -3
  1319. data/third_party/abseil-cpp/absl/strings/str_replace.h +6 -6
  1320. data/third_party/abseil-cpp/absl/strings/str_split.h +18 -1
  1321. data/third_party/abseil-cpp/absl/strings/string_view.cc +4 -9
  1322. data/third_party/abseil-cpp/absl/strings/string_view.h +46 -50
  1323. data/third_party/abseil-cpp/absl/strings/strip.h +11 -8
  1324. data/third_party/abseil-cpp/absl/strings/substitute.cc +5 -4
  1325. data/third_party/abseil-cpp/absl/strings/substitute.h +66 -64
  1326. data/third_party/abseil-cpp/absl/synchronization/blocking_counter.cc +16 -10
  1327. data/third_party/abseil-cpp/absl/synchronization/blocking_counter.h +6 -0
  1328. data/third_party/abseil-cpp/absl/synchronization/internal/create_thread_identity.cc +5 -1
  1329. data/third_party/abseil-cpp/absl/synchronization/internal/futex_waiter.cc +0 -4
  1330. data/third_party/abseil-cpp/absl/synchronization/internal/kernel_timeout.cc +0 -5
  1331. data/third_party/abseil-cpp/absl/synchronization/internal/pthread_waiter.cc +0 -4
  1332. data/third_party/abseil-cpp/absl/synchronization/internal/sem_waiter.cc +0 -4
  1333. data/third_party/abseil-cpp/absl/synchronization/internal/stdcpp_waiter.cc +0 -4
  1334. data/third_party/abseil-cpp/absl/synchronization/internal/waiter_base.cc +0 -4
  1335. data/third_party/abseil-cpp/absl/synchronization/internal/win32_waiter.cc +0 -4
  1336. data/third_party/abseil-cpp/absl/synchronization/mutex.cc +39 -13
  1337. data/third_party/abseil-cpp/absl/synchronization/mutex.h +97 -69
  1338. data/third_party/abseil-cpp/absl/synchronization/notification.cc +10 -2
  1339. data/third_party/abseil-cpp/absl/synchronization/notification.h +12 -2
  1340. data/third_party/abseil-cpp/absl/time/civil_time.cc +1 -0
  1341. data/third_party/abseil-cpp/absl/time/duration.cc +18 -58
  1342. data/third_party/abseil-cpp/absl/time/internal/cctz/include/cctz/time_zone.h +1 -1
  1343. data/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_fixed.cc +1 -1
  1344. data/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_format.cc +1 -1
  1345. data/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_if.cc +3 -3
  1346. data/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_impl.cc +2 -2
  1347. data/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_impl.h +2 -2
  1348. data/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_info.cc +3 -3
  1349. data/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_info.h +2 -2
  1350. data/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_libc.cc +1 -1
  1351. data/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_libc.h +1 -1
  1352. data/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_lookup.cc +92 -112
  1353. data/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_posix.cc +1 -1
  1354. data/third_party/abseil-cpp/absl/time/internal/cctz/src/tzfile.h +6 -4
  1355. data/third_party/abseil-cpp/absl/time/time.h +89 -23
  1356. data/third_party/abseil-cpp/absl/types/internal/span.h +3 -2
  1357. data/third_party/abseil-cpp/absl/types/optional.h +7 -745
  1358. data/third_party/abseil-cpp/absl/types/span.h +98 -54
  1359. data/third_party/abseil-cpp/absl/types/variant.h +5 -784
  1360. data/third_party/abseil-cpp/absl/utility/utility.h +10 -185
  1361. data/third_party/boringssl-with-bazel/src/crypto/aes/aes.cc +41 -0
  1362. data/third_party/boringssl-with-bazel/src/crypto/asn1/a_bitstr.cc +16 -0
  1363. data/third_party/boringssl-with-bazel/src/crypto/asn1/a_int.cc +15 -0
  1364. data/third_party/boringssl-with-bazel/src/crypto/asn1/internal.h +19 -3
  1365. data/third_party/boringssl-with-bazel/src/crypto/asn1/tasn_dec.cc +79 -48
  1366. data/third_party/boringssl-with-bazel/src/crypto/asn1/tasn_enc.cc +11 -19
  1367. data/third_party/boringssl-with-bazel/src/crypto/asn1/tasn_typ.cc +3 -7
  1368. data/third_party/boringssl-with-bazel/src/crypto/bcm_support.h +0 -35
  1369. data/third_party/boringssl-with-bazel/src/crypto/bio/connect.cc +0 -2
  1370. data/third_party/boringssl-with-bazel/src/crypto/bio/internal.h +3 -5
  1371. data/third_party/boringssl-with-bazel/src/crypto/bio/socket.cc +0 -3
  1372. data/third_party/boringssl-with-bazel/src/crypto/bio/socket_helper.cc +0 -2
  1373. data/third_party/boringssl-with-bazel/src/crypto/bn/convert.cc +31 -47
  1374. data/third_party/boringssl-with-bazel/src/crypto/bn/div.cc +100 -0
  1375. data/third_party/boringssl-with-bazel/src/crypto/bn/exponentiation.cc +166 -0
  1376. data/third_party/boringssl-with-bazel/src/crypto/bn/sqrt.cc +93 -0
  1377. data/third_party/boringssl-with-bazel/src/crypto/bytestring/cbb.cc +14 -8
  1378. data/third_party/boringssl-with-bazel/src/crypto/bytestring/cbs.cc +1 -1
  1379. data/third_party/boringssl-with-bazel/src/crypto/bytestring/internal.h +3 -3
  1380. data/third_party/boringssl-with-bazel/src/crypto/chacha/internal.h +4 -4
  1381. data/third_party/boringssl-with-bazel/src/crypto/cipher/derive_key.cc +13 -15
  1382. data/third_party/boringssl-with-bazel/src/crypto/cipher/e_aeseax.cc +289 -0
  1383. data/third_party/boringssl-with-bazel/src/crypto/cipher/e_aesgcmsiv.cc +179 -102
  1384. data/third_party/boringssl-with-bazel/src/crypto/cipher/internal.h +3 -3
  1385. data/third_party/boringssl-with-bazel/src/crypto/cms/cms.cc +172 -0
  1386. data/third_party/boringssl-with-bazel/src/crypto/cpu_aarch64_apple.cc +0 -2
  1387. data/third_party/boringssl-with-bazel/src/crypto/cpu_aarch64_fuchsia.cc +0 -2
  1388. data/third_party/boringssl-with-bazel/src/crypto/cpu_aarch64_linux.cc +0 -2
  1389. data/third_party/boringssl-with-bazel/src/crypto/cpu_aarch64_openbsd.cc +0 -2
  1390. data/third_party/boringssl-with-bazel/src/crypto/cpu_aarch64_sysreg.cc +0 -2
  1391. data/third_party/boringssl-with-bazel/src/crypto/cpu_aarch64_win.cc +0 -2
  1392. data/third_party/boringssl-with-bazel/src/crypto/cpu_arm_freebsd.cc +0 -1
  1393. data/third_party/boringssl-with-bazel/src/crypto/cpu_arm_linux.cc +28 -6
  1394. data/third_party/boringssl-with-bazel/src/crypto/cpu_arm_linux.h +11 -9
  1395. data/third_party/boringssl-with-bazel/src/crypto/cpu_intel.cc +0 -6
  1396. data/third_party/boringssl-with-bazel/src/crypto/crypto.cc +1 -3
  1397. data/third_party/boringssl-with-bazel/src/crypto/curve25519/internal.h +3 -3
  1398. data/third_party/boringssl-with-bazel/src/crypto/des/internal.h +3 -3
  1399. data/third_party/boringssl-with-bazel/src/crypto/dh/dh_asn1.cc +13 -14
  1400. data/third_party/boringssl-with-bazel/src/crypto/dh/params.cc +27 -61
  1401. data/third_party/boringssl-with-bazel/src/crypto/digest/digest_extra.cc +16 -8
  1402. data/third_party/boringssl-with-bazel/src/crypto/dsa/dsa.cc +112 -122
  1403. data/third_party/boringssl-with-bazel/src/crypto/dsa/dsa_asn1.cc +23 -35
  1404. data/third_party/boringssl-with-bazel/src/crypto/dsa/internal.h +3 -3
  1405. data/third_party/boringssl-with-bazel/src/crypto/ec/ec_asn1.cc +47 -63
  1406. data/third_party/boringssl-with-bazel/src/crypto/ec/hash_to_curve.cc +60 -68
  1407. data/third_party/boringssl-with-bazel/src/crypto/ec/internal.h +3 -3
  1408. data/third_party/boringssl-with-bazel/src/crypto/ecdsa/ecdsa_asn1.cc +11 -17
  1409. data/third_party/boringssl-with-bazel/src/crypto/err/err.cc +0 -2
  1410. data/third_party/boringssl-with-bazel/src/crypto/evp/evp_asn1.cc +10 -11
  1411. data/third_party/boringssl-with-bazel/src/crypto/evp/evp_ctx.cc +10 -11
  1412. data/third_party/boringssl-with-bazel/src/crypto/evp/internal.h +3 -3
  1413. data/third_party/boringssl-with-bazel/src/crypto/evp/p_dsa_asn1.cc +6 -6
  1414. data/third_party/boringssl-with-bazel/src/crypto/evp/p_ec_asn1.cc +6 -6
  1415. data/third_party/boringssl-with-bazel/src/crypto/evp/p_ed25519_asn1.cc +6 -6
  1416. data/third_party/boringssl-with-bazel/src/crypto/evp/p_rsa_asn1.cc +6 -6
  1417. data/third_party/boringssl-with-bazel/src/crypto/evp/p_x25519_asn1.cc +6 -6
  1418. data/third_party/boringssl-with-bazel/src/crypto/evp/sign.cc +23 -42
  1419. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/aes/aes.cc.inc +29 -18
  1420. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/aes/gcm.cc.inc +10 -10
  1421. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/aes/internal.h +16 -45
  1422. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/aes/key_wrap.cc.inc +5 -4
  1423. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/aes/mode_wrappers.cc.inc +15 -6
  1424. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/bcm.cc +3 -3
  1425. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/bcm_interface.h +101 -5
  1426. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/bn/div.cc.inc +96 -187
  1427. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/bn/exponentiation.cc.inc +24 -512
  1428. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/bn/gcd.cc.inc +58 -80
  1429. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/bn/gcd_extra.cc.inc +29 -45
  1430. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/bn/internal.h +27 -25
  1431. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/bn/jacobi.cc.inc +7 -16
  1432. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/bn/montgomery.cc.inc +27 -48
  1433. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/bn/mul.cc.inc +34 -34
  1434. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/bn/prime.cc.inc +102 -154
  1435. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/bn/rsaz_exp.h +3 -3
  1436. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/bn/shift.cc.inc +3 -8
  1437. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/bn/sqrt.cc.inc +1 -78
  1438. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/cipher/e_aes.cc.inc +10 -17
  1439. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/cipher/internal.h +3 -3
  1440. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/delocate.h +15 -8
  1441. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/dh/check.cc.inc +40 -53
  1442. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/dh/dh.cc.inc +57 -76
  1443. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/digest/digest.cc.inc +4 -10
  1444. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/digest/internal.h +3 -3
  1445. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/digest/md32_common.h +3 -3
  1446. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/ec.cc.inc +37 -52
  1447. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/ec_key.cc.inc +13 -20
  1448. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/internal.h +3 -3
  1449. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/oct.cc.inc +28 -39
  1450. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/p256-nistz.h +3 -3
  1451. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/simple.cc.inc +6 -11
  1452. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/keccak/internal.h +3 -3
  1453. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/mldsa/fips_known_values.inc +1345 -0
  1454. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/mldsa/mldsa.cc.inc +335 -28
  1455. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/mlkem/fips_known_values.inc +411 -0
  1456. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/mlkem/mlkem.cc.inc +265 -33
  1457. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/rand/internal.h +3 -3
  1458. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/rand/rand.cc.inc +1 -1
  1459. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/rsa/internal.h +3 -3
  1460. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/rsa/padding.cc.inc +19 -26
  1461. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/rsa/rsa.cc.inc +7 -7
  1462. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/rsa/rsa_impl.cc.inc +121 -138
  1463. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/self_check/self_check.cc.inc +96 -83
  1464. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/service_indicator/internal.h +3 -3
  1465. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/sha/internal.h +8 -20
  1466. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/slhdsa/fips_known_values.inc +674 -0
  1467. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/slhdsa/slhdsa.cc.inc +235 -60
  1468. data/third_party/boringssl-with-bazel/src/crypto/fuzzer_mode.cc +30 -0
  1469. data/third_party/boringssl-with-bazel/src/crypto/hrss/internal.h +3 -3
  1470. data/third_party/boringssl-with-bazel/src/crypto/internal.h +59 -33
  1471. data/third_party/boringssl-with-bazel/src/crypto/lhash/internal.h +3 -3
  1472. data/third_party/boringssl-with-bazel/src/crypto/md5/internal.h +3 -3
  1473. data/third_party/boringssl-with-bazel/src/crypto/mem.cc +0 -2
  1474. data/third_party/boringssl-with-bazel/src/crypto/obj/obj.cc +2 -8
  1475. data/third_party/boringssl-with-bazel/src/crypto/pem/internal.h +3 -3
  1476. data/third_party/boringssl-with-bazel/src/crypto/pem/pem_lib.cc +8 -13
  1477. data/third_party/boringssl-with-bazel/src/crypto/pkcs7/internal.h +22 -8
  1478. data/third_party/boringssl-with-bazel/src/crypto/pkcs7/pkcs7.cc +19 -17
  1479. data/third_party/boringssl-with-bazel/src/crypto/pkcs7/pkcs7_x509.cc +134 -136
  1480. data/third_party/boringssl-with-bazel/src/crypto/pkcs8/internal.h +14 -8
  1481. data/third_party/boringssl-with-bazel/src/crypto/pkcs8/p5_pbev2.cc +25 -21
  1482. data/third_party/boringssl-with-bazel/src/crypto/pkcs8/pkcs8.cc +36 -52
  1483. data/third_party/boringssl-with-bazel/src/crypto/pkcs8/pkcs8_x509.cc +97 -79
  1484. data/third_party/boringssl-with-bazel/src/crypto/poly1305/internal.h +3 -3
  1485. data/third_party/boringssl-with-bazel/src/crypto/pool/internal.h +3 -3
  1486. data/third_party/boringssl-with-bazel/src/crypto/rand/deterministic.cc +1 -1
  1487. data/third_party/boringssl-with-bazel/src/crypto/rand/fork_detect.cc +2 -2
  1488. data/third_party/boringssl-with-bazel/src/crypto/rand/getentropy.cc +1 -1
  1489. data/third_party/boringssl-with-bazel/src/crypto/rand/{sysrand_internal.h → internal.h} +22 -4
  1490. data/third_party/boringssl-with-bazel/src/crypto/rand/ios.cc +1 -1
  1491. data/third_party/boringssl-with-bazel/src/crypto/rand/trusty.cc +1 -1
  1492. data/third_party/boringssl-with-bazel/src/crypto/rand/urandom.cc +1 -1
  1493. data/third_party/boringssl-with-bazel/src/crypto/rand/windows.cc +1 -5
  1494. data/third_party/boringssl-with-bazel/src/crypto/rsa/internal.h +3 -3
  1495. data/third_party/boringssl-with-bazel/src/crypto/rsa/rsa_crypt.cc +14 -22
  1496. data/third_party/boringssl-with-bazel/src/crypto/spake2plus/internal.h +3 -3
  1497. data/third_party/boringssl-with-bazel/src/crypto/thread_win.cc +0 -2
  1498. data/third_party/boringssl-with-bazel/src/crypto/trust_token/internal.h +3 -3
  1499. data/third_party/boringssl-with-bazel/src/crypto/x509/a_sign.cc +3 -5
  1500. data/third_party/boringssl-with-bazel/src/crypto/x509/asn1_gen.cc +8 -12
  1501. data/third_party/boringssl-with-bazel/src/crypto/x509/internal.h +15 -3
  1502. data/third_party/boringssl-with-bazel/src/crypto/x509/v3_conf.cc +16 -24
  1503. data/third_party/boringssl-with-bazel/src/crypto/x509/v3_info.cc +18 -21
  1504. data/third_party/boringssl-with-bazel/src/crypto/x509/x509_vfy.cc +10 -3
  1505. data/third_party/boringssl-with-bazel/src/crypto/x509/x_algor.cc +9 -0
  1506. data/third_party/boringssl-with-bazel/src/crypto/x509/x_name.cc +10 -1
  1507. data/third_party/boringssl-with-bazel/src/crypto/x509/x_x509.cc +64 -85
  1508. data/third_party/boringssl-with-bazel/src/crypto/x509/x_x509a.cc +16 -32
  1509. data/third_party/boringssl-with-bazel/src/gen/crypto/err_data.cc +576 -567
  1510. data/third_party/boringssl-with-bazel/src/include/openssl/aead.h +16 -8
  1511. data/third_party/boringssl-with-bazel/src/include/openssl/aes.h +1 -1
  1512. data/third_party/boringssl-with-bazel/src/include/openssl/arm_arch.h +3 -25
  1513. data/third_party/boringssl-with-bazel/src/include/openssl/asn1.h +6 -54
  1514. data/third_party/boringssl-with-bazel/src/include/openssl/asn1t.h +1 -1
  1515. data/third_party/boringssl-with-bazel/src/include/openssl/base.h +8 -4
  1516. data/third_party/boringssl-with-bazel/src/include/openssl/base64.h +1 -1
  1517. data/third_party/boringssl-with-bazel/src/include/openssl/bcm_public.h +1 -1
  1518. data/third_party/boringssl-with-bazel/src/include/openssl/bio.h +1 -1
  1519. data/third_party/boringssl-with-bazel/src/include/openssl/blake2.h +1 -1
  1520. data/third_party/boringssl-with-bazel/src/include/openssl/blowfish.h +1 -1
  1521. data/third_party/boringssl-with-bazel/src/include/openssl/bn.h +1 -1
  1522. data/third_party/boringssl-with-bazel/src/include/openssl/buf.h +1 -1
  1523. data/third_party/boringssl-with-bazel/src/include/openssl/bytestring.h +7 -1
  1524. data/third_party/boringssl-with-bazel/src/include/openssl/cast.h +1 -1
  1525. data/third_party/boringssl-with-bazel/src/include/openssl/chacha.h +1 -1
  1526. data/third_party/boringssl-with-bazel/src/include/openssl/cipher.h +1 -1
  1527. data/third_party/boringssl-with-bazel/src/include/openssl/cmac.h +1 -1
  1528. data/third_party/boringssl-with-bazel/src/include/openssl/cms.h +146 -0
  1529. data/third_party/boringssl-with-bazel/src/include/openssl/conf.h +1 -1
  1530. data/third_party/boringssl-with-bazel/src/include/openssl/crypto.h +23 -3
  1531. data/third_party/boringssl-with-bazel/src/include/openssl/ctrdrbg.h +1 -1
  1532. data/third_party/boringssl-with-bazel/src/include/openssl/curve25519.h +1 -1
  1533. data/third_party/boringssl-with-bazel/src/include/openssl/des.h +1 -1
  1534. data/third_party/boringssl-with-bazel/src/include/openssl/dh.h +1 -1
  1535. data/third_party/boringssl-with-bazel/src/include/openssl/digest.h +19 -7
  1536. data/third_party/boringssl-with-bazel/src/include/openssl/dsa.h +1 -1
  1537. data/third_party/boringssl-with-bazel/src/include/openssl/e_os2.h +1 -1
  1538. data/third_party/boringssl-with-bazel/src/include/openssl/ec.h +1 -1
  1539. data/third_party/boringssl-with-bazel/src/include/openssl/ec_key.h +1 -1
  1540. data/third_party/boringssl-with-bazel/src/include/openssl/ecdh.h +1 -1
  1541. data/third_party/boringssl-with-bazel/src/include/openssl/ecdsa.h +1 -1
  1542. data/third_party/boringssl-with-bazel/src/include/openssl/engine.h +1 -1
  1543. data/third_party/boringssl-with-bazel/src/include/openssl/err.h +2 -1
  1544. data/third_party/boringssl-with-bazel/src/include/openssl/evp.h +1 -1
  1545. data/third_party/boringssl-with-bazel/src/include/openssl/ex_data.h +1 -1
  1546. data/third_party/boringssl-with-bazel/src/include/openssl/experimental/kyber.h +1 -1
  1547. data/third_party/boringssl-with-bazel/src/include/openssl/hkdf.h +1 -1
  1548. data/third_party/boringssl-with-bazel/src/include/openssl/hmac.h +1 -1
  1549. data/third_party/boringssl-with-bazel/src/include/openssl/hpke.h +4 -4
  1550. data/third_party/boringssl-with-bazel/src/include/openssl/hrss.h +1 -1
  1551. data/third_party/boringssl-with-bazel/src/include/openssl/kdf.h +1 -1
  1552. data/third_party/boringssl-with-bazel/src/include/openssl/lhash.h +1 -1
  1553. data/third_party/boringssl-with-bazel/src/include/openssl/md4.h +1 -1
  1554. data/third_party/boringssl-with-bazel/src/include/openssl/md5.h +1 -1
  1555. data/third_party/boringssl-with-bazel/src/include/openssl/mem.h +1 -1
  1556. data/third_party/boringssl-with-bazel/src/include/openssl/mldsa.h +1 -1
  1557. data/third_party/boringssl-with-bazel/src/include/openssl/mlkem.h +1 -1
  1558. data/third_party/boringssl-with-bazel/src/include/openssl/nid.h +1 -1
  1559. data/third_party/boringssl-with-bazel/src/include/openssl/obj.h +1 -1
  1560. data/third_party/boringssl-with-bazel/src/include/openssl/obj_mac.h +1 -1
  1561. data/third_party/boringssl-with-bazel/src/include/openssl/opensslconf.h +10 -4
  1562. data/third_party/boringssl-with-bazel/src/include/openssl/pkcs7.h +1 -1
  1563. data/third_party/boringssl-with-bazel/src/include/openssl/pkcs8.h +19 -6
  1564. data/third_party/boringssl-with-bazel/src/include/openssl/poly1305.h +1 -1
  1565. data/third_party/boringssl-with-bazel/src/include/openssl/pool.h +1 -1
  1566. data/third_party/boringssl-with-bazel/src/include/openssl/posix_time.h +1 -1
  1567. data/third_party/boringssl-with-bazel/src/include/openssl/rand.h +2 -2
  1568. data/third_party/boringssl-with-bazel/src/include/openssl/rc4.h +1 -1
  1569. data/third_party/boringssl-with-bazel/src/include/openssl/ripemd.h +1 -1
  1570. data/third_party/boringssl-with-bazel/src/include/openssl/rsa.h +2 -2
  1571. data/third_party/boringssl-with-bazel/src/include/openssl/service_indicator.h +1 -1
  1572. data/third_party/boringssl-with-bazel/src/include/openssl/sha.h +1 -1
  1573. data/third_party/boringssl-with-bazel/src/include/openssl/siphash.h +1 -1
  1574. data/third_party/boringssl-with-bazel/src/include/openssl/slhdsa.h +1 -1
  1575. data/third_party/boringssl-with-bazel/src/include/openssl/span.h +1 -1
  1576. data/third_party/boringssl-with-bazel/src/include/openssl/ssl.h +291 -40
  1577. data/third_party/boringssl-with-bazel/src/include/openssl/stack.h +1 -1
  1578. data/third_party/boringssl-with-bazel/src/include/openssl/target.h +0 -5
  1579. data/third_party/boringssl-with-bazel/src/include/openssl/thread.h +1 -1
  1580. data/third_party/boringssl-with-bazel/src/include/openssl/tls1.h +9 -1
  1581. data/third_party/boringssl-with-bazel/src/include/openssl/trust_token.h +1 -1
  1582. data/third_party/boringssl-with-bazel/src/include/openssl/type_check.h +1 -1
  1583. data/third_party/boringssl-with-bazel/src/include/openssl/x509.h +7 -4
  1584. data/third_party/boringssl-with-bazel/src/ssl/dtls_method.cc +2 -0
  1585. data/third_party/boringssl-with-bazel/src/ssl/dtls_record.cc +32 -26
  1586. data/third_party/boringssl-with-bazel/src/ssl/encrypted_client_hello.cc +49 -49
  1587. data/third_party/boringssl-with-bazel/src/ssl/extensions.cc +256 -57
  1588. data/third_party/boringssl-with-bazel/src/ssl/handoff.cc +12 -12
  1589. data/third_party/boringssl-with-bazel/src/ssl/handshake.cc +7 -5
  1590. data/third_party/boringssl-with-bazel/src/ssl/handshake_client.cc +3 -2
  1591. data/third_party/boringssl-with-bazel/src/ssl/handshake_server.cc +25 -33
  1592. data/third_party/boringssl-with-bazel/src/ssl/internal.h +106 -10
  1593. data/third_party/boringssl-with-bazel/src/ssl/ssl_aead_ctx.cc +6 -12
  1594. data/third_party/boringssl-with-bazel/src/ssl/ssl_asn1.cc +18 -4
  1595. data/third_party/boringssl-with-bazel/src/ssl/ssl_credential.cc +85 -8
  1596. data/third_party/boringssl-with-bazel/src/ssl/ssl_key_share.cc +1 -1
  1597. data/third_party/boringssl-with-bazel/src/ssl/ssl_lib.cc +173 -19
  1598. data/third_party/boringssl-with-bazel/src/ssl/ssl_privkey.cc +5 -18
  1599. data/third_party/boringssl-with-bazel/src/ssl/ssl_session.cc +28 -15
  1600. data/third_party/boringssl-with-bazel/src/ssl/t1_enc.cc +1 -1
  1601. data/third_party/boringssl-with-bazel/src/ssl/tls13_both.cc +31 -7
  1602. data/third_party/boringssl-with-bazel/src/ssl/tls13_client.cc +14 -2
  1603. data/third_party/boringssl-with-bazel/src/ssl/tls13_enc.cc +7 -11
  1604. data/third_party/boringssl-with-bazel/src/ssl/tls13_server.cc +14 -12
  1605. data/third_party/boringssl-with-bazel/src/ssl/tls_record.cc +2 -5
  1606. data/third_party/upb/upb/base/internal/log2.h +3 -1
  1607. data/third_party/upb/upb/base/string_view.h +10 -0
  1608. data/third_party/upb/upb/hash/common.c +312 -187
  1609. data/third_party/upb/upb/hash/common.h +44 -43
  1610. data/third_party/upb/upb/hash/int_table.h +29 -5
  1611. data/third_party/upb/upb/hash/str_table.h +6 -0
  1612. data/third_party/upb/upb/json/decode.c +2 -2
  1613. data/third_party/upb/upb/json/decode.h +0 -1
  1614. data/third_party/upb/upb/mem/alloc.h +5 -0
  1615. data/third_party/upb/upb/mem/arena.c +437 -160
  1616. data/third_party/upb/upb/mem/arena.h +57 -11
  1617. data/third_party/upb/upb/mem/arena.hpp +4 -20
  1618. data/third_party/upb/upb/mem/internal/arena.h +65 -29
  1619. data/third_party/upb/upb/message/accessors.c +1 -5
  1620. data/third_party/upb/upb/message/accessors.h +41 -0
  1621. data/third_party/upb/upb/message/array.c +7 -6
  1622. data/third_party/upb/upb/message/array.h +4 -4
  1623. data/third_party/upb/upb/message/compat.c +11 -14
  1624. data/third_party/upb/upb/message/compat.h +4 -3
  1625. data/third_party/upb/upb/message/copy.c +35 -30
  1626. data/third_party/upb/upb/message/internal/accessors.h +142 -13
  1627. data/third_party/upb/upb/message/internal/extension.c +16 -25
  1628. data/third_party/upb/upb/message/internal/extension.h +17 -5
  1629. data/third_party/upb/upb/message/internal/iterator.c +58 -0
  1630. data/third_party/upb/upb/message/internal/iterator.h +29 -0
  1631. data/third_party/upb/upb/message/internal/map.h +76 -22
  1632. data/third_party/upb/upb/message/internal/map_sorter.h +13 -4
  1633. data/third_party/upb/upb/message/internal/message.c +48 -29
  1634. data/third_party/upb/upb/message/internal/message.h +203 -25
  1635. data/third_party/upb/upb/message/map.c +68 -20
  1636. data/third_party/upb/upb/message/map.h +8 -1
  1637. data/third_party/upb/upb/message/map_gencode_util.h +3 -45
  1638. data/third_party/upb/upb/message/map_sorter.c +52 -16
  1639. data/third_party/upb/upb/message/merge.h +3 -3
  1640. data/third_party/upb/upb/message/message.c +200 -42
  1641. data/third_party/upb/upb/message/message.h +69 -4
  1642. data/third_party/upb/upb/message/value.h +9 -0
  1643. data/third_party/upb/upb/mini_descriptor/build_enum.c +16 -6
  1644. data/third_party/upb/upb/mini_descriptor/decode.c +115 -138
  1645. data/third_party/upb/upb/mini_descriptor/decode.h +4 -3
  1646. data/third_party/upb/upb/mini_descriptor/internal/encode.hpp +1 -1
  1647. data/third_party/upb/upb/mini_descriptor/link.c +4 -0
  1648. data/third_party/upb/upb/mini_table/extension.h +8 -1
  1649. data/third_party/upb/upb/mini_table/extension_registry.c +25 -13
  1650. data/third_party/upb/upb/mini_table/extension_registry.h +13 -6
  1651. data/third_party/upb/upb/mini_table/internal/enum.h +1 -1
  1652. data/third_party/upb/upb/mini_table/internal/extension.h +24 -1
  1653. data/third_party/upb/upb/mini_table/internal/field.h +4 -4
  1654. data/third_party/upb/upb/mini_table/internal/message.h +1 -1
  1655. data/third_party/upb/upb/mini_table/message.c +21 -13
  1656. data/third_party/upb/upb/port/atomic.h +134 -7
  1657. data/third_party/upb/upb/port/def.inc +163 -45
  1658. data/third_party/upb/upb/port/undef.inc +12 -1
  1659. data/third_party/upb/upb/reflection/def.hpp +5 -1
  1660. data/third_party/upb/upb/reflection/def_pool.c +10 -3
  1661. data/third_party/upb/upb/reflection/def_pool.h +2 -2
  1662. data/third_party/upb/upb/reflection/descriptor_bootstrap.h +4 -4
  1663. data/third_party/upb/upb/reflection/enum_def.c +4 -4
  1664. data/third_party/upb/upb/reflection/enum_reserved_range.c +1 -1
  1665. data/third_party/upb/upb/reflection/enum_value_def.c +9 -8
  1666. data/third_party/upb/upb/reflection/extension_range.c +1 -2
  1667. data/third_party/upb/upb/reflection/field_def.c +3 -5
  1668. data/third_party/upb/upb/reflection/field_def.h +1 -1
  1669. data/third_party/upb/upb/reflection/file_def.c +16 -10
  1670. data/third_party/upb/upb/reflection/internal/def_builder.c +1 -1
  1671. data/third_party/upb/upb/reflection/internal/def_builder.h +35 -10
  1672. data/third_party/upb/upb/reflection/internal/enum_value_def.h +1 -1
  1673. data/third_party/upb/upb/reflection/internal/upb_edition_defaults.h +1 -1
  1674. data/third_party/upb/upb/reflection/message.c +19 -16
  1675. data/third_party/upb/upb/reflection/message.h +3 -1
  1676. data/third_party/upb/upb/reflection/message_def.c +4 -7
  1677. data/third_party/upb/upb/reflection/message_reserved_range.c +1 -1
  1678. data/third_party/upb/upb/reflection/method_def.c +1 -1
  1679. data/third_party/upb/upb/reflection/oneof_def.c +3 -3
  1680. data/third_party/upb/upb/reflection/service_def.c +2 -5
  1681. data/third_party/upb/upb/text/encode.c +17 -13
  1682. data/third_party/upb/upb/text/internal/encode.c +25 -6
  1683. data/third_party/upb/upb/text/internal/encode.h +6 -1
  1684. data/third_party/upb/upb/wire/decode.c +154 -107
  1685. data/third_party/upb/upb/wire/decode.h +4 -2
  1686. data/third_party/upb/upb/wire/encode.c +114 -55
  1687. data/third_party/upb/upb/wire/encode.h +2 -0
  1688. data/third_party/upb/upb/wire/eps_copy_input_stream.h +18 -20
  1689. data/third_party/upb/upb/wire/internal/decode_fast.c +2 -2
  1690. data/third_party/upb/upb/wire/internal/decode_fast.h +4 -0
  1691. data/third_party/upb/upb/wire/internal/decoder.h +4 -11
  1692. data/third_party/utf8_range/utf8_range.c +15 -275
  1693. data/third_party/utf8_range/utf8_range_neon.inc +117 -0
  1694. data/third_party/utf8_range/utf8_range_sse.inc +272 -0
  1695. data/third_party/zlib/deflate.c +40 -15
  1696. data/third_party/zlib/deflate.h +33 -2
  1697. data/third_party/zlib/gzguts.h +2 -6
  1698. data/third_party/zlib/inflate.c +1 -1
  1699. data/third_party/zlib/inftrees.c +3 -3
  1700. data/third_party/zlib/inftrees.h +2 -2
  1701. data/third_party/zlib/trees.c +18 -4
  1702. data/third_party/zlib/zconf.h +1 -9
  1703. data/third_party/zlib/zlib.h +12 -12
  1704. data/third_party/zlib/zutil.h +4 -25
  1705. metadata +266 -168
  1706. data/include/grpc/grpc_cronet.h +0 -37
  1707. data/src/core/lib/event_engine/forkable.cc +0 -105
  1708. data/src/core/lib/event_engine/forkable.h +0 -67
  1709. data/src/core/lib/iomgr/executor.cc +0 -441
  1710. data/src/core/lib/iomgr/executor.h +0 -119
  1711. data/src/core/lib/iomgr/python_util.h +0 -46
  1712. data/src/core/lib/transport/http2_errors.h +0 -43
  1713. data/third_party/abseil-cpp/absl/base/internal/inline_variable.h +0 -108
  1714. data/third_party/abseil-cpp/absl/base/internal/invoke.h +0 -241
  1715. data/third_party/abseil-cpp/absl/base/internal/nullability_impl.h +0 -108
  1716. data/third_party/abseil-cpp/absl/log/log_entry.cc +0 -41
  1717. data/third_party/abseil-cpp/absl/random/internal/pool_urbg.h +0 -131
  1718. data/third_party/abseil-cpp/absl/types/bad_optional_access.cc +0 -66
  1719. data/third_party/abseil-cpp/absl/types/bad_optional_access.h +0 -78
  1720. data/third_party/abseil-cpp/absl/types/bad_variant_access.cc +0 -82
  1721. data/third_party/abseil-cpp/absl/types/bad_variant_access.h +0 -82
  1722. data/third_party/abseil-cpp/absl/types/internal/optional.h +0 -352
  1723. data/third_party/abseil-cpp/absl/types/internal/variant.h +0 -1622
  1724. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/aes/polyval.cc.inc +0 -89
  1725. data/third_party/upb/upb/message/internal/compare_unknown.c +0 -289
  1726. data/third_party/upb/upb/message/internal/compare_unknown.h +0 -49
@@ -41,12 +41,6 @@
41
41
  // When heterogeneous lookup is disabled, only the explicit `key_type` overloads
42
42
  // exist.
43
43
  //
44
- // find() also supports passing the hash explicitly:
45
- //
46
- // iterator find(const key_type& key, size_t hash);
47
- // template <class U>
48
- // iterator find(const U& key, size_t hash);
49
- //
50
44
  // In addition the pointer to element and iterator stability guarantees are
51
45
  // weaker: all iterators and pointers are invalidated after a new element is
52
46
  // inserted.
@@ -190,6 +184,7 @@
190
184
  #include <cstddef>
191
185
  #include <cstdint>
192
186
  #include <cstring>
187
+ #include <functional>
193
188
  #include <initializer_list>
194
189
  #include <iterator>
195
190
  #include <limits>
@@ -201,6 +196,7 @@
201
196
  #include "absl/base/attributes.h"
202
197
  #include "absl/base/config.h"
203
198
  #include "absl/base/internal/endian.h"
199
+ #include "absl/base/internal/iterator_traits.h"
204
200
  #include "absl/base/internal/raw_logging.h"
205
201
  #include "absl/base/macros.h"
206
202
  #include "absl/base/optimization.h"
@@ -208,32 +204,22 @@
208
204
  #include "absl/base/port.h"
209
205
  #include "absl/base/prefetch.h"
210
206
  #include "absl/container/internal/common.h" // IWYU pragma: export // for node_handle
207
+ #include "absl/container/internal/common_policy_traits.h"
211
208
  #include "absl/container/internal/compressed_tuple.h"
212
209
  #include "absl/container/internal/container_memory.h"
210
+ #include "absl/container/internal/hash_function_defaults.h"
213
211
  #include "absl/container/internal/hash_policy_traits.h"
212
+ #include "absl/container/internal/hashtable_control_bytes.h"
214
213
  #include "absl/container/internal/hashtable_debug_hooks.h"
215
214
  #include "absl/container/internal/hashtablez_sampler.h"
215
+ #include "absl/functional/function_ref.h"
216
+ #include "absl/hash/hash.h"
217
+ #include "absl/hash/internal/weakly_mixed_integer.h"
216
218
  #include "absl/memory/memory.h"
217
219
  #include "absl/meta/type_traits.h"
218
220
  #include "absl/numeric/bits.h"
219
221
  #include "absl/utility/utility.h"
220
222
 
221
- #ifdef ABSL_INTERNAL_HAVE_SSE2
222
- #include <emmintrin.h>
223
- #endif
224
-
225
- #ifdef ABSL_INTERNAL_HAVE_SSSE3
226
- #include <tmmintrin.h>
227
- #endif
228
-
229
- #ifdef _MSC_VER
230
- #include <intrin.h>
231
- #endif
232
-
233
- #ifdef ABSL_INTERNAL_HAVE_ARM_NEON
234
- #include <arm_neon.h>
235
- #endif
236
-
237
223
  namespace absl {
238
224
  ABSL_NAMESPACE_BEGIN
239
225
  namespace container_internal {
@@ -252,6 +238,15 @@ namespace container_internal {
252
238
  #define ABSL_SWISSTABLE_ENABLE_GENERATIONS
253
239
  #endif
254
240
 
241
+ #ifdef ABSL_SWISSTABLE_ASSERT
242
+ #error ABSL_SWISSTABLE_ASSERT cannot be directly set
243
+ #else
244
+ // We use this macro for assertions that users may see when the table is in an
245
+ // invalid state that sanitizers may help diagnose.
246
+ #define ABSL_SWISSTABLE_ASSERT(CONDITION) \
247
+ assert((CONDITION) && "Try enabling sanitizers.")
248
+ #endif
249
+
255
250
  // We use uint8_t so we don't need to worry about padding.
256
251
  using GenerationType = uint8_t;
257
252
 
@@ -271,6 +266,15 @@ constexpr bool SwisstableGenerationsEnabled() { return false; }
271
266
  constexpr size_t NumGenerationBytes() { return 0; }
272
267
  #endif
273
268
 
269
+ // Returns true if we should assert that the table is not accessed after it has
270
+ // been destroyed or during the destruction of the table.
271
+ constexpr bool SwisstableAssertAccessToDestroyedTable() {
272
+ #ifndef NDEBUG
273
+ return true;
274
+ #endif
275
+ return SwisstableGenerationsEnabled();
276
+ }
277
+
274
278
  template <typename AllocType>
275
279
  void SwapAlloc(AllocType& lhs, AllocType& rhs,
276
280
  std::true_type /* propagate_on_container_swap */) {
@@ -322,7 +326,7 @@ class probe_seq {
322
326
  // sequence and `mask` (usually the capacity of the table) as the mask to
323
327
  // apply to each value in the progression.
324
328
  probe_seq(size_t hash, size_t mask) {
325
- assert(((mask + 1) & mask) == 0 && "not a mask");
329
+ ABSL_SWISSTABLE_ASSERT(((mask + 1) & mask) == 0 && "not a mask");
326
330
  mask_ = mask;
327
331
  offset_ = hash & mask_;
328
332
  }
@@ -376,165 +380,20 @@ constexpr bool IsNoThrowSwappable(std::false_type /* is_swappable */) {
376
380
  return false;
377
381
  }
378
382
 
379
- template <typename T>
380
- uint32_t TrailingZeros(T x) {
381
- ABSL_ASSUME(x != 0);
382
- return static_cast<uint32_t>(countr_zero(x));
383
- }
384
-
385
- // 8 bytes bitmask with most significant bit set for every byte.
386
- constexpr uint64_t kMsbs8Bytes = 0x8080808080808080ULL;
387
-
388
- // An abstract bitmask, such as that emitted by a SIMD instruction.
389
- //
390
- // Specifically, this type implements a simple bitset whose representation is
391
- // controlled by `SignificantBits` and `Shift`. `SignificantBits` is the number
392
- // of abstract bits in the bitset, while `Shift` is the log-base-two of the
393
- // width of an abstract bit in the representation.
394
- // This mask provides operations for any number of real bits set in an abstract
395
- // bit. To add iteration on top of that, implementation must guarantee no more
396
- // than the most significant real bit is set in a set abstract bit.
397
- template <class T, int SignificantBits, int Shift = 0>
398
- class NonIterableBitMask {
399
- public:
400
- explicit NonIterableBitMask(T mask) : mask_(mask) {}
401
-
402
- explicit operator bool() const { return this->mask_ != 0; }
403
-
404
- // Returns the index of the lowest *abstract* bit set in `self`.
405
- uint32_t LowestBitSet() const {
406
- return container_internal::TrailingZeros(mask_) >> Shift;
407
- }
408
-
409
- // Returns the index of the highest *abstract* bit set in `self`.
410
- uint32_t HighestBitSet() const {
411
- return static_cast<uint32_t>((bit_width(mask_) - 1) >> Shift);
412
- }
413
-
414
- // Returns the number of trailing zero *abstract* bits.
415
- uint32_t TrailingZeros() const {
416
- return container_internal::TrailingZeros(mask_) >> Shift;
417
- }
418
-
419
- // Returns the number of leading zero *abstract* bits.
420
- uint32_t LeadingZeros() const {
421
- constexpr int total_significant_bits = SignificantBits << Shift;
422
- constexpr int extra_bits = sizeof(T) * 8 - total_significant_bits;
423
- return static_cast<uint32_t>(
424
- countl_zero(static_cast<T>(mask_ << extra_bits))) >>
425
- Shift;
426
- }
427
-
428
- T mask_;
429
- };
430
-
431
- // Mask that can be iterable
432
- //
433
- // For example, when `SignificantBits` is 16 and `Shift` is zero, this is just
434
- // an ordinary 16-bit bitset occupying the low 16 bits of `mask`. When
435
- // `SignificantBits` is 8 and `Shift` is 3, abstract bits are represented as
436
- // the bytes `0x00` and `0x80`, and it occupies all 64 bits of the bitmask.
437
- // If NullifyBitsOnIteration is true (only allowed for Shift == 3),
438
- // non zero abstract bit is allowed to have additional bits
439
- // (e.g., `0xff`, `0x83` and `0x9c` are ok, but `0x6f` is not).
440
- //
441
- // For example:
442
- // for (int i : BitMask<uint32_t, 16>(0b101)) -> yields 0, 2
443
- // for (int i : BitMask<uint64_t, 8, 3>(0x0000000080800000)) -> yields 2, 3
444
- template <class T, int SignificantBits, int Shift = 0,
445
- bool NullifyBitsOnIteration = false>
446
- class BitMask : public NonIterableBitMask<T, SignificantBits, Shift> {
447
- using Base = NonIterableBitMask<T, SignificantBits, Shift>;
448
- static_assert(std::is_unsigned<T>::value, "");
449
- static_assert(Shift == 0 || Shift == 3, "");
450
- static_assert(!NullifyBitsOnIteration || Shift == 3, "");
451
-
452
- public:
453
- explicit BitMask(T mask) : Base(mask) {
454
- if (Shift == 3 && !NullifyBitsOnIteration) {
455
- assert(this->mask_ == (this->mask_ & kMsbs8Bytes));
456
- }
457
- }
458
- // BitMask is an iterator over the indices of its abstract bits.
459
- using value_type = int;
460
- using iterator = BitMask;
461
- using const_iterator = BitMask;
462
-
463
- BitMask& operator++() {
464
- if (Shift == 3 && NullifyBitsOnIteration) {
465
- this->mask_ &= kMsbs8Bytes;
466
- }
467
- this->mask_ &= (this->mask_ - 1);
468
- return *this;
469
- }
470
-
471
- uint32_t operator*() const { return Base::LowestBitSet(); }
472
-
473
- BitMask begin() const { return *this; }
474
- BitMask end() const { return BitMask(0); }
475
-
476
- private:
477
- friend bool operator==(const BitMask& a, const BitMask& b) {
478
- return a.mask_ == b.mask_;
479
- }
480
- friend bool operator!=(const BitMask& a, const BitMask& b) {
481
- return a.mask_ != b.mask_;
482
- }
483
- };
484
-
485
- using h2_t = uint8_t;
383
+ // See definition comment for why this is size 32.
384
+ ABSL_DLL extern const ctrl_t kEmptyGroup[32];
486
385
 
487
- // The values here are selected for maximum performance. See the static asserts
488
- // below for details.
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,
489
392
 
490
- // A `ctrl_t` is a single control byte, which can have one of four
491
- // states: empty, deleted, full (which has an associated seven-bit h2_t value)
492
- // and the sentinel. They have the following bit patterns:
493
- //
494
- // empty: 1 0 0 0 0 0 0 0
495
- // deleted: 1 1 1 1 1 1 1 0
496
- // full: 0 h h h h h h h // h represents the hash bits.
497
- // sentinel: 1 1 1 1 1 1 1 1
498
- //
499
- // These values are specifically tuned for SSE-flavored SIMD.
500
- // The static_asserts below detail the source of these choices.
501
- //
502
- // We use an enum class so that when strict aliasing is enabled, the compiler
503
- // knows ctrl_t doesn't alias other types.
504
- enum class ctrl_t : int8_t {
505
- kEmpty = -128, // 0b10000000
506
- kDeleted = -2, // 0b11111110
507
- kSentinel = -1, // 0b11111111
393
+ // These two must be last because we use `>= kMovedFrom` to mean moved-from.
394
+ kMovedFrom,
395
+ kSelfMovedFrom,
508
396
  };
509
- static_assert(
510
- (static_cast<int8_t>(ctrl_t::kEmpty) &
511
- static_cast<int8_t>(ctrl_t::kDeleted) &
512
- static_cast<int8_t>(ctrl_t::kSentinel) & 0x80) != 0,
513
- "Special markers need to have the MSB to make checking for them efficient");
514
- static_assert(
515
- ctrl_t::kEmpty < ctrl_t::kSentinel && ctrl_t::kDeleted < ctrl_t::kSentinel,
516
- "ctrl_t::kEmpty and ctrl_t::kDeleted must be smaller than "
517
- "ctrl_t::kSentinel to make the SIMD test of IsEmptyOrDeleted() efficient");
518
- static_assert(
519
- ctrl_t::kSentinel == static_cast<ctrl_t>(-1),
520
- "ctrl_t::kSentinel must be -1 to elide loading it from memory into SIMD "
521
- "registers (pcmpeqd xmm, xmm)");
522
- static_assert(ctrl_t::kEmpty == static_cast<ctrl_t>(-128),
523
- "ctrl_t::kEmpty must be -128 to make the SIMD check for its "
524
- "existence efficient (psignb xmm, xmm)");
525
- static_assert(
526
- (~static_cast<int8_t>(ctrl_t::kEmpty) &
527
- ~static_cast<int8_t>(ctrl_t::kDeleted) &
528
- static_cast<int8_t>(ctrl_t::kSentinel) & 0x7F) != 0,
529
- "ctrl_t::kEmpty and ctrl_t::kDeleted must share an unset bit that is not "
530
- "shared by ctrl_t::kSentinel to make the scalar test for "
531
- "MaskEmptyOrDeleted() efficient");
532
- static_assert(ctrl_t::kDeleted == static_cast<ctrl_t>(-2),
533
- "ctrl_t::kDeleted must be -2 to make the implementation of "
534
- "ConvertSpecialToEmptyAndFullToDeleted efficient");
535
-
536
- // See definition comment for why this is size 32.
537
- ABSL_DLL extern const ctrl_t kEmptyGroup[32];
538
397
 
539
398
  // Returns a pointer to a control byte group that can be used by empty tables.
540
399
  inline ctrl_t* EmptyGroup() {
@@ -566,362 +425,117 @@ inline bool IsEmptyGeneration(const GenerationType* generation) {
566
425
  return *generation == SentinelEmptyGeneration();
567
426
  }
568
427
 
569
- // Mixes a randomly generated per-process seed with `hash` and `ctrl` to
570
- // randomize insertion order within groups.
571
- bool ShouldInsertBackwardsForDebug(size_t capacity, size_t hash,
572
- const ctrl_t* ctrl);
573
-
574
- ABSL_ATTRIBUTE_ALWAYS_INLINE inline bool ShouldInsertBackwards(
575
- ABSL_ATTRIBUTE_UNUSED size_t capacity, ABSL_ATTRIBUTE_UNUSED size_t hash,
576
- ABSL_ATTRIBUTE_UNUSED const ctrl_t* ctrl) {
577
- #if defined(NDEBUG)
578
- return false;
579
- #else
580
- return ShouldInsertBackwardsForDebug(capacity, hash, ctrl);
581
- #endif
582
- }
583
-
584
- // Returns insert position for the given mask.
585
- // We want to add entropy even when ASLR is not enabled.
586
- // In debug build we will randomly insert in either the front or back of
587
- // the group.
588
- // TODO(kfm,sbenza): revisit after we do unconditional mixing
589
- template <class Mask>
590
- ABSL_ATTRIBUTE_ALWAYS_INLINE inline auto GetInsertionOffset(
591
- Mask mask, ABSL_ATTRIBUTE_UNUSED size_t capacity,
592
- ABSL_ATTRIBUTE_UNUSED size_t hash,
593
- ABSL_ATTRIBUTE_UNUSED const ctrl_t* ctrl) {
594
- #if defined(NDEBUG)
595
- return mask.LowestBitSet();
596
- #else
597
- return ShouldInsertBackwardsForDebug(capacity, hash, ctrl)
598
- ? mask.HighestBitSet()
599
- : mask.LowestBitSet();
600
- #endif
601
- }
428
+ // We only allow a maximum of 1 SOO element, which makes the implementation
429
+ // much simpler. Complications with multiple SOO elements include:
430
+ // - Satisfying the guarantee that erasing one element doesn't invalidate
431
+ // iterators to other elements means we would probably need actual SOO
432
+ // control bytes.
433
+ // - In order to prevent user code from depending on iteration order for small
434
+ // tables, we would need to randomize the iteration order somehow.
435
+ constexpr size_t SooCapacity() { return 1; }
436
+ // Sentinel type to indicate SOO CommonFields construction.
437
+ struct soo_tag_t {};
438
+ // Sentinel type to indicate SOO CommonFields construction with full size.
439
+ struct full_soo_tag_t {};
440
+ // Sentinel type to indicate non-SOO CommonFields construction.
441
+ struct non_soo_tag_t {};
442
+ // Sentinel value to indicate an uninitialized value explicitly.
443
+ struct uninitialized_tag_t {};
444
+ // Sentinel value to indicate creation of an empty table without a seed.
445
+ struct no_seed_empty_tag_t {};
446
+
447
+ // Per table hash salt. This gets mixed into H1 to randomize iteration order
448
+ // per-table.
449
+ // The seed is needed to ensure non-determinism of iteration order.
450
+ class PerTableSeed {
451
+ public:
452
+ // The number of bits in the seed.
453
+ // It is big enough to ensure non-determinism of iteration order.
454
+ // 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;
602
458
 
603
- // Returns a per-table, hash salt, which changes on resize. This gets mixed into
604
- // H1 to randomize iteration order per-table.
605
- //
606
- // The seed consists of the ctrl_ pointer, which adds enough entropy to ensure
607
- // non-determinism of iteration order in most cases.
608
- inline size_t PerTableSalt(const ctrl_t* ctrl) {
609
- // The low bits of the pointer have little or no entropy because of
610
- // alignment. We shift the pointer to try to use higher entropy bits. A
611
- // good number seems to be 12 bits, because that aligns with page size.
612
- return reinterpret_cast<uintptr_t>(ctrl) >> 12;
613
- }
614
- // Extracts the H1 portion of a hash: 57 bits mixed with a per-table salt.
615
- inline size_t H1(size_t hash, const ctrl_t* ctrl) {
616
- return (hash >> 7) ^ PerTableSalt(ctrl);
617
- }
459
+ // Returns the seed for the table. Only the lowest kBitCount are non zero.
460
+ size_t seed() const { return seed_; }
618
461
 
619
- // Extracts the H2 portion of a hash: the 7 bits not used for H1.
620
- //
621
- // These are used as an occupied control byte.
622
- inline h2_t H2(size_t hash) { return hash & 0x7F; }
462
+ private:
463
+ friend class HashtableSize;
464
+ explicit PerTableSeed(size_t seed) : seed_(seed) {}
623
465
 
624
- // Helpers for checking the state of a control byte.
625
- inline bool IsEmpty(ctrl_t c) { return c == ctrl_t::kEmpty; }
626
- inline bool IsFull(ctrl_t c) {
627
- // Cast `c` to the underlying type instead of casting `0` to `ctrl_t` as `0`
628
- // is not a value in the enum. Both ways are equivalent, but this way makes
629
- // linters happier.
630
- return static_cast<std::underlying_type_t<ctrl_t>>(c) >= 0;
631
- }
632
- inline bool IsDeleted(ctrl_t c) { return c == ctrl_t::kDeleted; }
633
- inline bool IsEmptyOrDeleted(ctrl_t c) { return c < ctrl_t::kSentinel; }
466
+ const size_t seed_;
467
+ };
634
468
 
635
- #ifdef ABSL_INTERNAL_HAVE_SSE2
636
- // Quick reference guide for intrinsics used below:
637
- //
638
- // * __m128i: An XMM (128-bit) word.
639
- //
640
- // * _mm_setzero_si128: Returns a zero vector.
641
- // * _mm_set1_epi8: Returns a vector with the same i8 in each lane.
642
- //
643
- // * _mm_subs_epi8: Saturating-subtracts two i8 vectors.
644
- // * _mm_and_si128: Ands two i128s together.
645
- // * _mm_or_si128: Ors two i128s together.
646
- // * _mm_andnot_si128: And-nots two i128s together.
647
- //
648
- // * _mm_cmpeq_epi8: Component-wise compares two i8 vectors for equality,
649
- // filling each lane with 0x00 or 0xff.
650
- // * _mm_cmpgt_epi8: Same as above, but using > rather than ==.
651
- //
652
- // * _mm_loadu_si128: Performs an unaligned load of an i128.
653
- // * _mm_storeu_si128: Performs an unaligned store of an i128.
654
- //
655
- // * _mm_sign_epi8: Retains, negates, or zeroes each i8 lane of the first
656
- // argument if the corresponding lane of the second
657
- // argument is positive, negative, or zero, respectively.
658
- // * _mm_movemask_epi8: Selects the sign bit out of each i8 lane and produces a
659
- // bitmask consisting of those bits.
660
- // * _mm_shuffle_epi8: Selects i8s from the first argument, using the low
661
- // four bits of each i8 lane in the second argument as
662
- // indices.
663
-
664
- // https://github.com/abseil/abseil-cpp/issues/209
665
- // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87853
666
- // _mm_cmpgt_epi8 is broken under GCC with -funsigned-char
667
- // Work around this by using the portable implementation of Group
668
- // when using -funsigned-char under GCC.
669
- inline __m128i _mm_cmpgt_epi8_fixed(__m128i a, __m128i b) {
670
- #if defined(__GNUC__) && !defined(__clang__)
671
- if (std::is_unsigned<char>::value) {
672
- const __m128i mask = _mm_set1_epi8(0x80);
673
- const __m128i diff = _mm_subs_epi8(b, a);
674
- return _mm_cmpeq_epi8(_mm_and_si128(diff, mask), mask);
675
- }
676
- #endif
677
- return _mm_cmpgt_epi8(a, b);
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;
678
476
  }
679
477
 
680
- struct GroupSse2Impl {
681
- static constexpr size_t kWidth = 16; // the number of slots per group
682
-
683
- explicit GroupSse2Impl(const ctrl_t* pos) {
684
- ctrl = _mm_loadu_si128(reinterpret_cast<const __m128i*>(pos));
685
- }
478
+ // The size and also has additionally
479
+ // 1) one bit that stores whether we have infoz.
480
+ // 2) PerTableSeed::kBitCount bits for the seed.
481
+ class HashtableSize {
482
+ public:
483
+ static constexpr size_t kSizeBitCount = 64 - PerTableSeed::kBitCount - 1;
686
484
 
687
- // Returns a bitmask representing the positions of slots that match hash.
688
- BitMask<uint16_t, kWidth> Match(h2_t hash) const {
689
- auto match = _mm_set1_epi8(static_cast<char>(hash));
690
- BitMask<uint16_t, kWidth> result = BitMask<uint16_t, kWidth>(0);
691
- result = BitMask<uint16_t, kWidth>(
692
- static_cast<uint16_t>(_mm_movemask_epi8(_mm_cmpeq_epi8(match, ctrl))));
693
- return result;
694
- }
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) {}
695
488
 
696
- // Returns a bitmask representing the positions of empty slots.
697
- NonIterableBitMask<uint16_t, kWidth> MaskEmpty() const {
698
- #ifdef ABSL_INTERNAL_HAVE_SSSE3
699
- // This only works because ctrl_t::kEmpty is -128.
700
- return NonIterableBitMask<uint16_t, kWidth>(
701
- static_cast<uint16_t>(_mm_movemask_epi8(_mm_sign_epi8(ctrl, ctrl))));
702
- #else
703
- auto match = _mm_set1_epi8(static_cast<char>(ctrl_t::kEmpty));
704
- return NonIterableBitMask<uint16_t, kWidth>(
705
- static_cast<uint16_t>(_mm_movemask_epi8(_mm_cmpeq_epi8(match, ctrl))));
706
- #endif
489
+ // Returns actual size of the table.
490
+ size_t size() const { return static_cast<size_t>(data_ >> kSizeShift); }
491
+ void increment_size() { data_ += kSizeOneNoMetadata; }
492
+ void increment_size(size_t size) {
493
+ data_ += static_cast<uint64_t>(size) * kSizeOneNoMetadata;
707
494
  }
495
+ void decrement_size() { data_ -= kSizeOneNoMetadata; }
496
+ // Returns true if the table is empty.
497
+ 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; }
708
500
 
709
- // Returns a bitmask representing the positions of full slots.
710
- // Note: for `is_small()` tables group may contain the "same" slot twice:
711
- // original and mirrored.
712
- BitMask<uint16_t, kWidth> MaskFull() const {
713
- return BitMask<uint16_t, kWidth>(
714
- static_cast<uint16_t>(_mm_movemask_epi8(ctrl) ^ 0xffff));
501
+ PerTableSeed seed() const {
502
+ return PerTableSeed(static_cast<size_t>(data_) & kSeedMask);
715
503
  }
716
504
 
717
- // Returns a bitmask representing the positions of non full slots.
718
- // Note: this includes: kEmpty, kDeleted, kSentinel.
719
- // It is useful in contexts when kSentinel is not present.
720
- auto MaskNonFull() const {
721
- return BitMask<uint16_t, kWidth>(
722
- static_cast<uint16_t>(_mm_movemask_epi8(ctrl)));
505
+ void generate_new_seed() {
506
+ data_ = (data_ & ~kSeedMask) ^ uint64_t{NextSeed()};
723
507
  }
724
508
 
725
- // Returns a bitmask representing the positions of empty or deleted slots.
726
- NonIterableBitMask<uint16_t, kWidth> MaskEmptyOrDeleted() const {
727
- auto special = _mm_set1_epi8(static_cast<char>(ctrl_t::kSentinel));
728
- return NonIterableBitMask<uint16_t, kWidth>(static_cast<uint16_t>(
729
- _mm_movemask_epi8(_mm_cmpgt_epi8_fixed(special, ctrl))));
509
+ // Returns true if the table has infoz.
510
+ bool has_infoz() const {
511
+ return ABSL_PREDICT_FALSE((data_ & kHasInfozMask) != 0);
730
512
  }
731
513
 
732
- // Returns the number of trailing empty or deleted elements in the group.
733
- uint32_t CountLeadingEmptyOrDeleted() const {
734
- auto special = _mm_set1_epi8(static_cast<char>(ctrl_t::kSentinel));
735
- return TrailingZeros(static_cast<uint32_t>(
736
- _mm_movemask_epi8(_mm_cmpgt_epi8_fixed(special, ctrl)) + 1));
737
- }
514
+ // Sets the has_infoz bit.
515
+ void set_has_infoz() { data_ |= kHasInfozMask; }
738
516
 
739
- void ConvertSpecialToEmptyAndFullToDeleted(ctrl_t* dst) const {
740
- auto msbs = _mm_set1_epi8(static_cast<char>(-128));
741
- auto x126 = _mm_set1_epi8(126);
742
- #ifdef ABSL_INTERNAL_HAVE_SSSE3
743
- auto res = _mm_or_si128(_mm_shuffle_epi8(x126, ctrl), msbs);
744
- #else
745
- auto zero = _mm_setzero_si128();
746
- auto special_mask = _mm_cmpgt_epi8_fixed(zero, ctrl);
747
- auto res = _mm_or_si128(msbs, _mm_andnot_si128(special_mask, x126));
748
- #endif
749
- _mm_storeu_si128(reinterpret_cast<__m128i*>(dst), res);
750
- }
517
+ void set_no_seed_for_testing() { data_ &= ~kSeedMask; }
751
518
 
752
- __m128i ctrl;
753
- };
754
- #endif // ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSE2
755
-
756
- #if defined(ABSL_INTERNAL_HAVE_ARM_NEON) && defined(ABSL_IS_LITTLE_ENDIAN)
757
- struct GroupAArch64Impl {
758
- static constexpr size_t kWidth = 8;
759
-
760
- explicit GroupAArch64Impl(const ctrl_t* pos) {
761
- ctrl = vld1_u8(reinterpret_cast<const uint8_t*>(pos));
762
- }
763
-
764
- auto Match(h2_t hash) const {
765
- uint8x8_t dup = vdup_n_u8(hash);
766
- auto mask = vceq_u8(ctrl, dup);
767
- return BitMask<uint64_t, kWidth, /*Shift=*/3,
768
- /*NullifyBitsOnIteration=*/true>(
769
- vget_lane_u64(vreinterpret_u64_u8(mask), 0));
770
- }
771
-
772
- NonIterableBitMask<uint64_t, kWidth, 3> MaskEmpty() const {
773
- uint64_t mask =
774
- vget_lane_u64(vreinterpret_u64_u8(vceq_s8(
775
- vdup_n_s8(static_cast<int8_t>(ctrl_t::kEmpty)),
776
- vreinterpret_s8_u8(ctrl))),
777
- 0);
778
- return NonIterableBitMask<uint64_t, kWidth, 3>(mask);
779
- }
780
-
781
- // Returns a bitmask representing the positions of full slots.
782
- // Note: for `is_small()` tables group may contain the "same" slot twice:
783
- // original and mirrored.
784
- auto MaskFull() const {
785
- uint64_t mask = vget_lane_u64(
786
- vreinterpret_u64_u8(vcge_s8(vreinterpret_s8_u8(ctrl),
787
- vdup_n_s8(static_cast<int8_t>(0)))),
788
- 0);
789
- return BitMask<uint64_t, kWidth, /*Shift=*/3,
790
- /*NullifyBitsOnIteration=*/true>(mask);
791
- }
792
-
793
- // Returns a bitmask representing the positions of non full slots.
794
- // Note: this includes: kEmpty, kDeleted, kSentinel.
795
- // It is useful in contexts when kSentinel is not present.
796
- auto MaskNonFull() const {
797
- uint64_t mask = vget_lane_u64(
798
- vreinterpret_u64_u8(vclt_s8(vreinterpret_s8_u8(ctrl),
799
- vdup_n_s8(static_cast<int8_t>(0)))),
800
- 0);
801
- return BitMask<uint64_t, kWidth, /*Shift=*/3,
802
- /*NullifyBitsOnIteration=*/true>(mask);
803
- }
804
-
805
- NonIterableBitMask<uint64_t, kWidth, 3> MaskEmptyOrDeleted() const {
806
- uint64_t mask =
807
- vget_lane_u64(vreinterpret_u64_u8(vcgt_s8(
808
- vdup_n_s8(static_cast<int8_t>(ctrl_t::kSentinel)),
809
- vreinterpret_s8_u8(ctrl))),
810
- 0);
811
- return NonIterableBitMask<uint64_t, kWidth, 3>(mask);
812
- }
813
-
814
- uint32_t CountLeadingEmptyOrDeleted() const {
815
- uint64_t mask =
816
- vget_lane_u64(vreinterpret_u64_u8(vcle_s8(
817
- vdup_n_s8(static_cast<int8_t>(ctrl_t::kSentinel)),
818
- vreinterpret_s8_u8(ctrl))),
819
- 0);
820
- // Similar to MaskEmptyorDeleted() but we invert the logic to invert the
821
- // produced bitfield. We then count number of trailing zeros.
822
- // Clang and GCC optimize countr_zero to rbit+clz without any check for 0,
823
- // so we should be fine.
824
- return static_cast<uint32_t>(countr_zero(mask)) >> 3;
825
- }
826
-
827
- void ConvertSpecialToEmptyAndFullToDeleted(ctrl_t* dst) const {
828
- uint64_t mask = vget_lane_u64(vreinterpret_u64_u8(ctrl), 0);
829
- constexpr uint64_t slsbs = 0x0202020202020202ULL;
830
- constexpr uint64_t midbs = 0x7e7e7e7e7e7e7e7eULL;
831
- auto x = slsbs & (mask >> 6);
832
- auto res = (x + midbs) | kMsbs8Bytes;
833
- little_endian::Store64(dst, res);
834
- }
835
-
836
- uint8x8_t ctrl;
519
+ private:
520
+ static constexpr size_t kSizeShift = 64 - kSizeBitCount;
521
+ static constexpr uint64_t kSizeOneNoMetadata = uint64_t{1} << kSizeShift;
522
+ static constexpr uint64_t kMetadataMask = kSizeOneNoMetadata - 1;
523
+ static constexpr uint64_t kSeedMask =
524
+ (uint64_t{1} << PerTableSeed::kBitCount) - 1;
525
+ // The next bit after the seed.
526
+ static constexpr uint64_t kHasInfozMask = kSeedMask + 1;
527
+ uint64_t data_;
837
528
  };
838
- #endif // ABSL_INTERNAL_HAVE_ARM_NEON && ABSL_IS_LITTLE_ENDIAN
839
529
 
840
- struct GroupPortableImpl {
841
- static constexpr size_t kWidth = 8;
842
-
843
- explicit GroupPortableImpl(const ctrl_t* pos)
844
- : ctrl(little_endian::Load64(pos)) {}
845
-
846
- BitMask<uint64_t, kWidth, 3> Match(h2_t hash) const {
847
- // For the technique, see:
848
- // http://graphics.stanford.edu/~seander/bithacks.html##ValueInWord
849
- // (Determine if a word has a byte equal to n).
850
- //
851
- // Caveat: there are false positives but:
852
- // - they only occur if there is a real match
853
- // - they never occur on ctrl_t::kEmpty, ctrl_t::kDeleted, ctrl_t::kSentinel
854
- // - they will be handled gracefully by subsequent checks in code
855
- //
856
- // Example:
857
- // v = 0x1716151413121110
858
- // hash = 0x12
859
- // retval = (v - lsbs) & ~v & msbs = 0x0000000080800000
860
- constexpr uint64_t lsbs = 0x0101010101010101ULL;
861
- auto x = ctrl ^ (lsbs * hash);
862
- return BitMask<uint64_t, kWidth, 3>((x - lsbs) & ~x & kMsbs8Bytes);
863
- }
864
-
865
- NonIterableBitMask<uint64_t, kWidth, 3> MaskEmpty() const {
866
- return NonIterableBitMask<uint64_t, kWidth, 3>((ctrl & ~(ctrl << 6)) &
867
- kMsbs8Bytes);
868
- }
869
-
870
- // Returns a bitmask representing the positions of full slots.
871
- // Note: for `is_small()` tables group may contain the "same" slot twice:
872
- // original and mirrored.
873
- BitMask<uint64_t, kWidth, 3> MaskFull() const {
874
- return BitMask<uint64_t, kWidth, 3>((ctrl ^ kMsbs8Bytes) & kMsbs8Bytes);
875
- }
876
-
877
- // Returns a bitmask representing the positions of non full slots.
878
- // Note: this includes: kEmpty, kDeleted, kSentinel.
879
- // It is useful in contexts when kSentinel is not present.
880
- auto MaskNonFull() const {
881
- return BitMask<uint64_t, kWidth, 3>(ctrl & kMsbs8Bytes);
882
- }
883
-
884
- NonIterableBitMask<uint64_t, kWidth, 3> MaskEmptyOrDeleted() const {
885
- return NonIterableBitMask<uint64_t, kWidth, 3>((ctrl & ~(ctrl << 7)) &
886
- kMsbs8Bytes);
887
- }
888
-
889
- uint32_t CountLeadingEmptyOrDeleted() const {
890
- // ctrl | ~(ctrl >> 7) will have the lowest bit set to zero for kEmpty and
891
- // kDeleted. We lower all other bits and count number of trailing zeros.
892
- constexpr uint64_t bits = 0x0101010101010101ULL;
893
- return static_cast<uint32_t>(countr_zero((ctrl | ~(ctrl >> 7)) & bits) >>
894
- 3);
895
- }
896
-
897
- void ConvertSpecialToEmptyAndFullToDeleted(ctrl_t* dst) const {
898
- constexpr uint64_t lsbs = 0x0101010101010101ULL;
899
- auto x = ctrl & kMsbs8Bytes;
900
- auto res = (~x + (x >> 7)) & ~lsbs;
901
- little_endian::Store64(dst, res);
902
- }
903
-
904
- uint64_t ctrl;
905
- };
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
+ }
906
534
 
907
- #ifdef ABSL_INTERNAL_HAVE_SSE2
908
- using Group = GroupSse2Impl;
909
- using GroupFullEmptyOrDeleted = GroupSse2Impl;
910
- #elif defined(ABSL_INTERNAL_HAVE_ARM_NEON) && defined(ABSL_IS_LITTLE_ENDIAN)
911
- using Group = GroupAArch64Impl;
912
- // For Aarch64, we use the portable implementation for counting and masking
913
- // full, empty or deleted group elements. This is to avoid the latency of moving
914
- // between data GPRs and Neon registers when it does not provide a benefit.
915
- // Using Neon is profitable when we call Match(), but is not when we don't,
916
- // which is the case when we do *EmptyOrDeleted and MaskFull operations.
917
- // It is difficult to make a similar approach beneficial on other architectures
918
- // such as x86 since they have much lower GPR <-> vector register transfer
919
- // latency and 16-wide Groups.
920
- using GroupFullEmptyOrDeleted = GroupPortableImpl;
921
- #else
922
- using Group = GroupPortableImpl;
923
- using GroupFullEmptyOrDeleted = GroupPortableImpl;
924
- #endif
535
+ // Extracts the H2 portion of a hash: the 7 bits not used for H1.
536
+ //
537
+ // These are used as an occupied control byte.
538
+ inline h2_t H2(size_t hash) { return hash & 0x7F; }
925
539
 
926
540
  // When there is an insertion with no reserved growth, we rehash with
927
541
  // probability `min(1, RehashProbabilityConstant() / capacity())`. Using a
@@ -957,10 +571,10 @@ class CommonFieldsGenerationInfoEnabled {
957
571
  // references. We rehash on the first insertion after reserved_growth_ reaches
958
572
  // 0 after a call to reserve. We also do a rehash with low probability
959
573
  // whenever reserved_growth_ is zero.
960
- bool should_rehash_for_bug_detection_on_insert(const ctrl_t* ctrl,
574
+ bool should_rehash_for_bug_detection_on_insert(PerTableSeed seed,
961
575
  size_t capacity) const;
962
576
  // Similar to above, except that we don't depend on reserved_growth_.
963
- bool should_rehash_for_bug_detection_on_move(const ctrl_t* ctrl,
577
+ bool should_rehash_for_bug_detection_on_move(PerTableSeed seed,
964
578
  size_t capacity) const;
965
579
  void maybe_increment_generation_on_insert() {
966
580
  if (reserved_growth_ == kReservedGrowthJustRanOut) reserved_growth_ = 0;
@@ -1014,10 +628,10 @@ class CommonFieldsGenerationInfoDisabled {
1014
628
  CommonFieldsGenerationInfoDisabled& operator=(
1015
629
  CommonFieldsGenerationInfoDisabled&&) = default;
1016
630
 
1017
- bool should_rehash_for_bug_detection_on_insert(const ctrl_t*, size_t) const {
631
+ bool should_rehash_for_bug_detection_on_insert(PerTableSeed, size_t) const {
1018
632
  return false;
1019
633
  }
1020
- bool should_rehash_for_bug_detection_on_move(const ctrl_t*, size_t) const {
634
+ bool should_rehash_for_bug_detection_on_move(PerTableSeed, size_t) const {
1021
635
  return false;
1022
636
  }
1023
637
  void maybe_increment_generation_on_insert() {}
@@ -1105,19 +719,20 @@ class GrowthInfo {
1105
719
 
1106
720
  // Overwrites single empty slot with a full slot.
1107
721
  void OverwriteEmptyAsFull() {
1108
- assert(GetGrowthLeft() > 0);
722
+ ABSL_SWISSTABLE_ASSERT(GetGrowthLeft() > 0);
1109
723
  --growth_left_info_;
1110
724
  }
1111
725
 
1112
726
  // Overwrites several empty slots with full slots.
1113
- void OverwriteManyEmptyAsFull(size_t cnt) {
1114
- assert(GetGrowthLeft() >= cnt);
1115
- growth_left_info_ -= cnt;
727
+ void OverwriteManyEmptyAsFull(size_t count) {
728
+ ABSL_SWISSTABLE_ASSERT(GetGrowthLeft() >= count);
729
+ growth_left_info_ -= count;
1116
730
  }
1117
731
 
1118
732
  // Overwrites specified control element with full slot.
1119
733
  void OverwriteControlAsFull(ctrl_t ctrl) {
1120
- assert(GetGrowthLeft() >= static_cast<size_t>(IsEmpty(ctrl)));
734
+ ABSL_SWISSTABLE_ASSERT(GetGrowthLeft() >=
735
+ static_cast<size_t>(IsEmpty(ctrl)));
1121
736
  growth_left_info_ -= static_cast<size_t>(IsEmpty(ctrl));
1122
737
  }
1123
738
 
@@ -1136,7 +751,14 @@ class GrowthInfo {
1136
751
  // 2. There is no growth left.
1137
752
  bool HasNoGrowthLeftAndNoDeleted() const { return growth_left_info_ == 0; }
1138
753
 
1139
- // Returns true if table guaranteed to have no k
754
+ // Returns true if GetGrowthLeft() == 0, but must be called only if
755
+ // HasNoDeleted() is false. It is slightly more efficient.
756
+ bool HasNoGrowthLeftAssumingMayHaveDeleted() const {
757
+ ABSL_SWISSTABLE_ASSERT(!HasNoDeleted());
758
+ return growth_left_info_ == kDeletedBit;
759
+ }
760
+
761
+ // Returns true if table guaranteed to have no kDeleted slots.
1140
762
  bool HasNoDeleted() const {
1141
763
  return static_cast<std::make_signed_t<size_t>>(growth_left_info_) >= 0;
1142
764
  }
@@ -1157,7 +779,7 @@ static_assert(alignof(GrowthInfo) == alignof(size_t), "");
1157
779
  // Returns whether `n` is a valid capacity (i.e., number of slots).
1158
780
  //
1159
781
  // A valid capacity is a non-zero integer `2^m - 1`.
1160
- inline bool IsValidCapacity(size_t n) { return ((n + 1) & n) == 0 && n > 0; }
782
+ constexpr bool IsValidCapacity(size_t n) { return ((n + 1) & n) == 0 && n > 0; }
1161
783
 
1162
784
  // Returns the number of "cloned control bytes".
1163
785
  //
@@ -1173,26 +795,32 @@ constexpr size_t NumControlBytes(size_t capacity) {
1173
795
 
1174
796
  // Computes the offset from the start of the backing allocation of control.
1175
797
  // infoz and growth_info are stored at the beginning of the backing array.
1176
- inline static size_t ControlOffset(bool has_infoz) {
798
+ constexpr size_t ControlOffset(bool has_infoz) {
1177
799
  return (has_infoz ? sizeof(HashtablezInfoHandle) : 0) + sizeof(GrowthInfo);
1178
800
  }
1179
801
 
802
+ // Returns the offset of the next item after `offset` that is aligned to `align`
803
+ // bytes. `align` must be a power of two.
804
+ constexpr size_t AlignUpTo(size_t offset, size_t align) {
805
+ return (offset + align - 1) & (~align + 1);
806
+ }
807
+
1180
808
  // Helper class for computing offsets and allocation size of hash set fields.
1181
809
  class RawHashSetLayout {
1182
810
  public:
1183
- explicit RawHashSetLayout(size_t capacity, size_t slot_align, bool has_infoz)
1184
- : capacity_(capacity),
1185
- control_offset_(ControlOffset(has_infoz)),
811
+ explicit RawHashSetLayout(size_t capacity, size_t slot_size,
812
+ size_t slot_align, bool has_infoz)
813
+ : control_offset_(ControlOffset(has_infoz)),
1186
814
  generation_offset_(control_offset_ + NumControlBytes(capacity)),
1187
815
  slot_offset_(
1188
- (generation_offset_ + NumGenerationBytes() + slot_align - 1) &
1189
- (~slot_align + 1)) {
1190
- assert(IsValidCapacity(capacity));
816
+ AlignUpTo(generation_offset_ + NumGenerationBytes(), slot_align)),
817
+ alloc_size_(slot_offset_ + capacity * slot_size) {
818
+ ABSL_SWISSTABLE_ASSERT(IsValidCapacity(capacity));
819
+ ABSL_SWISSTABLE_ASSERT(
820
+ slot_size <=
821
+ ((std::numeric_limits<size_t>::max)() - slot_offset_) / capacity);
1191
822
  }
1192
823
 
1193
- // Returns the capacity of a table.
1194
- size_t capacity() const { return capacity_; }
1195
-
1196
824
  // Returns precomputed offset from the start of the backing allocation of
1197
825
  // control.
1198
826
  size_t control_offset() const { return control_offset_; }
@@ -1207,32 +835,17 @@ class RawHashSetLayout {
1207
835
 
1208
836
  // Given the capacity of a table, computes the total size of the backing
1209
837
  // array.
1210
- size_t alloc_size(size_t slot_size) const {
1211
- return slot_offset_ + capacity_ * slot_size;
1212
- }
838
+ size_t alloc_size() const { return alloc_size_; }
1213
839
 
1214
840
  private:
1215
- size_t capacity_;
1216
841
  size_t control_offset_;
1217
842
  size_t generation_offset_;
1218
843
  size_t slot_offset_;
844
+ size_t alloc_size_;
1219
845
  };
1220
846
 
1221
847
  struct HashtableFreeFunctionsAccess;
1222
848
 
1223
- // We only allow a maximum of 1 SOO element, which makes the implementation
1224
- // much simpler. Complications with multiple SOO elements include:
1225
- // - Satisfying the guarantee that erasing one element doesn't invalidate
1226
- // iterators to other elements means we would probably need actual SOO
1227
- // control bytes.
1228
- // - In order to prevent user code from depending on iteration order for small
1229
- // tables, we would need to randomize the iteration order somehow.
1230
- constexpr size_t SooCapacity() { return 1; }
1231
- // Sentinel type to indicate SOO CommonFields construction.
1232
- struct soo_tag_t {};
1233
- // Sentinel type to indicate SOO CommonFields construction with full size.
1234
- struct full_soo_tag_t {};
1235
-
1236
849
  // Suppress erroneous uninitialized memory errors on GCC. For example, GCC
1237
850
  // thinks that the call to slot_array() in find_or_prepare_insert() is reading
1238
851
  // uninitialized memory, but slot_array is only called there when the table is
@@ -1260,7 +873,7 @@ union MaybeInitializedPtr {
1260
873
  };
1261
874
 
1262
875
  struct HeapPtrs {
1263
- HeapPtrs() = default;
876
+ explicit HeapPtrs(uninitialized_tag_t) {}
1264
877
  explicit HeapPtrs(ctrl_t* c) : control(c) {}
1265
878
 
1266
879
  // The control bytes (and, also, a pointer near to the base of the backing
@@ -1279,10 +892,13 @@ struct HeapPtrs {
1279
892
  MaybeInitializedPtr slot_array;
1280
893
  };
1281
894
 
895
+ // Returns the maximum size of the SOO slot.
896
+ constexpr size_t MaxSooSlotSize() { return sizeof(HeapPtrs); }
897
+
1282
898
  // Manages the backing array pointers or the SOO slot. When raw_hash_set::is_soo
1283
899
  // is true, the SOO slot is stored in `soo_data`. Otherwise, we use `heap`.
1284
900
  union HeapOrSoo {
1285
- HeapOrSoo() = default;
901
+ explicit HeapOrSoo(uninitialized_tag_t) : heap(uninitialized_tag_t{}) {}
1286
902
  explicit HeapOrSoo(ctrl_t* c) : heap(c) {}
1287
903
 
1288
904
  ctrl_t*& control() {
@@ -1305,44 +921,83 @@ union HeapOrSoo {
1305
921
  }
1306
922
 
1307
923
  HeapPtrs heap;
1308
- unsigned char soo_data[sizeof(HeapPtrs)];
924
+ unsigned char soo_data[MaxSooSlotSize()];
1309
925
  };
1310
926
 
927
+ // Returns a reference to the GrowthInfo object stored immediately before
928
+ // `control`.
929
+ inline GrowthInfo& GetGrowthInfoFromControl(ctrl_t* control) {
930
+ auto* gl_ptr = reinterpret_cast<GrowthInfo*>(control) - 1;
931
+ ABSL_SWISSTABLE_ASSERT(
932
+ reinterpret_cast<uintptr_t>(gl_ptr) % alignof(GrowthInfo) == 0);
933
+ return *gl_ptr;
934
+ }
935
+
1311
936
  // CommonFields hold the fields in raw_hash_set that do not depend
1312
937
  // on template parameters. This allows us to conveniently pass all
1313
938
  // of this state to helper functions as a single argument.
1314
939
  class CommonFields : public CommonFieldsGenerationInfo {
1315
940
  public:
1316
- CommonFields() : capacity_(0), size_(0), heap_or_soo_(EmptyGroup()) {}
1317
- explicit CommonFields(soo_tag_t) : capacity_(SooCapacity()), size_(0) {}
941
+ explicit CommonFields(soo_tag_t)
942
+ : capacity_(SooCapacity()),
943
+ size_(no_seed_empty_tag_t{}),
944
+ heap_or_soo_(uninitialized_tag_t{}) {}
1318
945
  explicit CommonFields(full_soo_tag_t)
1319
- : capacity_(SooCapacity()), size_(size_t{1} << HasInfozShift()) {}
946
+ : capacity_(SooCapacity()),
947
+ size_(full_soo_tag_t{}),
948
+ heap_or_soo_(uninitialized_tag_t{}) {}
949
+ explicit CommonFields(non_soo_tag_t)
950
+ : capacity_(0),
951
+ size_(no_seed_empty_tag_t{}),
952
+ heap_or_soo_(EmptyGroup()) {}
953
+ // For use in swapping.
954
+ explicit CommonFields(uninitialized_tag_t)
955
+ : size_(uninitialized_tag_t{}), heap_or_soo_(uninitialized_tag_t{}) {}
1320
956
 
1321
957
  // Not copyable
1322
958
  CommonFields(const CommonFields&) = delete;
1323
959
  CommonFields& operator=(const CommonFields&) = delete;
1324
960
 
961
+ // Copy with guarantee that it is not SOO.
962
+ 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
+ }
967
+
1325
968
  // Movable
1326
969
  CommonFields(CommonFields&& that) = default;
1327
970
  CommonFields& operator=(CommonFields&&) = default;
1328
971
 
1329
972
  template <bool kSooEnabled>
1330
973
  static CommonFields CreateDefault() {
1331
- return kSooEnabled ? CommonFields{soo_tag_t{}} : CommonFields{};
974
+ return kSooEnabled ? CommonFields{soo_tag_t{}}
975
+ : CommonFields{non_soo_tag_t{}};
1332
976
  }
1333
977
 
1334
978
  // The inline data for SOO is written on top of control_/slots_.
1335
979
  const void* soo_data() const { return heap_or_soo_.get_soo_data(); }
1336
980
  void* soo_data() { return heap_or_soo_.get_soo_data(); }
1337
981
 
1338
- HeapOrSoo heap_or_soo() const { return heap_or_soo_; }
1339
- const HeapOrSoo& heap_or_soo_ref() const { return heap_or_soo_; }
1340
-
1341
982
  ctrl_t* control() const { return heap_or_soo_.control(); }
1342
- void set_control(ctrl_t* c) { heap_or_soo_.control() = c; }
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
+ }
1343
997
  void* backing_array_start() const {
1344
998
  // growth_info (and maybe infoz) is stored before control bytes.
1345
- assert(reinterpret_cast<uintptr_t>(control()) % alignof(size_t) == 0);
999
+ ABSL_SWISSTABLE_ASSERT(
1000
+ reinterpret_cast<uintptr_t>(control()) % alignof(size_t) == 0);
1346
1001
  return control() - ControlOffset(has_infoz());
1347
1002
  }
1348
1003
 
@@ -1352,31 +1007,46 @@ class CommonFields : public CommonFieldsGenerationInfo {
1352
1007
  void set_slots(void* s) { heap_or_soo_.slot_array().set(s); }
1353
1008
 
1354
1009
  // The number of filled slots.
1355
- size_t size() const { return size_ >> HasInfozShift(); }
1356
- void set_size(size_t s) {
1357
- size_ = (s << HasInfozShift()) | (size_ & HasInfozMask());
1358
- }
1010
+ size_t size() const { return size_.size(); }
1011
+ // Sets the size to zero, but keeps hashinfoz bit and seed.
1012
+ void set_size_to_zero() { size_.set_size_to_zero_keep_metadata(); }
1359
1013
  void set_empty_soo() {
1360
1014
  AssertInSooMode();
1361
- size_ = 0;
1015
+ size_ = HashtableSize(no_seed_empty_tag_t{});
1362
1016
  }
1363
1017
  void set_full_soo() {
1364
1018
  AssertInSooMode();
1365
- size_ = size_t{1} << HasInfozShift();
1019
+ size_ = HashtableSize(full_soo_tag_t{});
1366
1020
  }
1367
1021
  void increment_size() {
1368
- assert(size() < capacity());
1369
- size_ += size_t{1} << HasInfozShift();
1022
+ ABSL_SWISSTABLE_ASSERT(size() < capacity());
1023
+ size_.increment_size();
1024
+ }
1025
+ void increment_size(size_t n) {
1026
+ ABSL_SWISSTABLE_ASSERT(size() + n <= capacity());
1027
+ size_.increment_size(n);
1370
1028
  }
1371
1029
  void decrement_size() {
1372
- assert(size() > 0);
1373
- size_ -= size_t{1} << HasInfozShift();
1030
+ ABSL_SWISSTABLE_ASSERT(!empty());
1031
+ size_.decrement_size();
1374
1032
  }
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(); }
1375
1043
 
1376
1044
  // The total number of available slots.
1377
1045
  size_t capacity() const { return capacity_; }
1378
1046
  void set_capacity(size_t c) {
1379
- assert(c == 0 || IsValidCapacity(c));
1047
+ // We allow setting above the max valid capacity for debugging purposes.
1048
+ ABSL_SWISSTABLE_ASSERT(c == 0 || IsValidCapacity(c) ||
1049
+ c > kAboveMaxValidCapacity);
1380
1050
  capacity_ = c;
1381
1051
  }
1382
1052
 
@@ -1387,20 +1057,14 @@ class CommonFields : public CommonFieldsGenerationInfo {
1387
1057
  size_t growth_left() const { return growth_info().GetGrowthLeft(); }
1388
1058
 
1389
1059
  GrowthInfo& growth_info() {
1390
- auto* gl_ptr = reinterpret_cast<GrowthInfo*>(control()) - 1;
1391
- assert(reinterpret_cast<uintptr_t>(gl_ptr) % alignof(GrowthInfo) == 0);
1392
- return *gl_ptr;
1060
+ return GetGrowthInfoFromControl(control());
1393
1061
  }
1394
1062
  GrowthInfo growth_info() const {
1395
1063
  return const_cast<CommonFields*>(this)->growth_info();
1396
1064
  }
1397
1065
 
1398
- bool has_infoz() const {
1399
- return ABSL_PREDICT_FALSE((size_ & HasInfozMask()) != 0);
1400
- }
1401
- void set_has_infoz(bool has_infoz) {
1402
- size_ = (size() << HasInfozShift()) | static_cast<size_t>(has_infoz);
1403
- }
1066
+ bool has_infoz() const { return size_.has_infoz(); }
1067
+ void set_has_infoz() { size_.set_has_infoz(); }
1404
1068
 
1405
1069
  HashtablezInfoHandle infoz() {
1406
1070
  return has_infoz()
@@ -1408,17 +1072,23 @@ class CommonFields : public CommonFieldsGenerationInfo {
1408
1072
  : HashtablezInfoHandle();
1409
1073
  }
1410
1074
  void set_infoz(HashtablezInfoHandle infoz) {
1411
- assert(has_infoz());
1075
+ ABSL_SWISSTABLE_ASSERT(has_infoz());
1412
1076
  *reinterpret_cast<HashtablezInfoHandle*>(backing_array_start()) = infoz;
1413
1077
  }
1414
1078
 
1415
1079
  bool should_rehash_for_bug_detection_on_insert() const {
1080
+ if constexpr (!SwisstableGenerationsEnabled()) {
1081
+ return false;
1082
+ }
1083
+ // As an optimization, we avoid calling ShouldRehashForBugDetection if we
1084
+ // will end up rehashing anyways.
1085
+ if (growth_left() == 0) return false;
1416
1086
  return CommonFieldsGenerationInfo::
1417
- should_rehash_for_bug_detection_on_insert(control(), capacity());
1087
+ should_rehash_for_bug_detection_on_insert(seed(), capacity());
1418
1088
  }
1419
1089
  bool should_rehash_for_bug_detection_on_move() const {
1420
1090
  return CommonFieldsGenerationInfo::should_rehash_for_bug_detection_on_move(
1421
- control(), capacity());
1091
+ seed(), capacity());
1422
1092
  }
1423
1093
  void reset_reserved_growth(size_t reservation) {
1424
1094
  CommonFieldsGenerationInfo::reset_reserved_growth(reservation, size());
@@ -1426,8 +1096,8 @@ class CommonFields : public CommonFieldsGenerationInfo {
1426
1096
 
1427
1097
  // The size of the backing array allocation.
1428
1098
  size_t alloc_size(size_t slot_size, size_t slot_align) const {
1429
- return RawHashSetLayout(capacity(), slot_align, has_infoz())
1430
- .alloc_size(slot_size);
1099
+ return RawHashSetLayout(capacity(), slot_size, slot_align, has_infoz())
1100
+ .alloc_size();
1431
1101
  }
1432
1102
 
1433
1103
  // Move fields other than heap_or_soo_.
@@ -1444,6 +1114,20 @@ class CommonFields : public CommonFieldsGenerationInfo {
1444
1114
  std::count(control(), control() + capacity(), ctrl_t::kDeleted));
1445
1115
  }
1446
1116
 
1117
+ // Helper to enable sanitizer mode validation to protect against reentrant
1118
+ // calls during element constructor/destructor.
1119
+ template <typename F>
1120
+ void RunWithReentrancyGuard(F f) {
1121
+ #ifdef NDEBUG
1122
+ f();
1123
+ return;
1124
+ #endif
1125
+ const size_t cap = capacity();
1126
+ set_capacity(InvalidCapacity::kReentrance);
1127
+ f();
1128
+ set_capacity(cap);
1129
+ }
1130
+
1447
1131
  private:
1448
1132
  // We store the has_infoz bit in the lowest bit of size_.
1449
1133
  static constexpr size_t HasInfozShift() { return 1; }
@@ -1454,8 +1138,8 @@ class CommonFields : public CommonFieldsGenerationInfo {
1454
1138
  // We can't assert that SOO is enabled because we don't have SooEnabled(), but
1455
1139
  // we assert what we can.
1456
1140
  void AssertInSooMode() const {
1457
- assert(capacity() == SooCapacity());
1458
- assert(!has_infoz());
1141
+ ABSL_SWISSTABLE_ASSERT(capacity() == SooCapacity());
1142
+ ABSL_SWISSTABLE_ASSERT(!has_infoz());
1459
1143
  }
1460
1144
 
1461
1145
  // The number of slots in the backing array. This is always 2^N-1 for an
@@ -1466,11 +1150,10 @@ class CommonFields : public CommonFieldsGenerationInfo {
1466
1150
  // regressions, presumably because we need capacity to do find operations.
1467
1151
  size_t capacity_;
1468
1152
 
1469
- // The size and also has one bit that stores whether we have infoz.
1470
1153
  // TODO(b/289225379): we could put size_ into HeapOrSoo and make capacity_
1471
1154
  // encode the size in SOO case. We would be making size()/capacity() more
1472
1155
  // expensive in order to have more SOO space.
1473
- size_t size_;
1156
+ HashtableSize size_;
1474
1157
 
1475
1158
  // Either the control/slots pointers or the SOO slot.
1476
1159
  HeapOrSoo heap_or_soo_;
@@ -1480,11 +1163,17 @@ template <class Policy, class Hash, class Eq, class Alloc>
1480
1163
  class raw_hash_set;
1481
1164
 
1482
1165
  // Returns the next valid capacity after `n`.
1483
- inline size_t NextCapacity(size_t n) {
1484
- assert(IsValidCapacity(n) || n == 0);
1166
+ constexpr size_t NextCapacity(size_t n) {
1167
+ ABSL_SWISSTABLE_ASSERT(IsValidCapacity(n) || n == 0);
1485
1168
  return n * 2 + 1;
1486
1169
  }
1487
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
+
1488
1177
  // Applies the following mapping to every byte in the control array:
1489
1178
  // * kDeleted -> kEmpty
1490
1179
  // * kEmpty -> kEmpty
@@ -1496,7 +1185,7 @@ inline size_t NextCapacity(size_t n) {
1496
1185
  void ConvertDeletedToEmptyAndFullToDeleted(ctrl_t* ctrl, size_t capacity);
1497
1186
 
1498
1187
  // Converts `n` into the next valid capacity, per `IsValidCapacity`.
1499
- inline size_t NormalizeCapacity(size_t n) {
1188
+ constexpr size_t NormalizeCapacity(size_t n) {
1500
1189
  return n ? ~size_t{} >> countl_zero(n) : 1;
1501
1190
  }
1502
1191
 
@@ -1510,8 +1199,8 @@ inline size_t NormalizeCapacity(size_t n) {
1510
1199
 
1511
1200
  // Given `capacity`, applies the load factor; i.e., it returns the maximum
1512
1201
  // number of values we should put into the table before a resizing rehash.
1513
- inline size_t CapacityToGrowth(size_t capacity) {
1514
- assert(IsValidCapacity(capacity));
1202
+ constexpr size_t CapacityToGrowth(size_t capacity) {
1203
+ ABSL_SWISSTABLE_ASSERT(IsValidCapacity(capacity));
1515
1204
  // `capacity*7/8`
1516
1205
  if (Group::kWidth == 8 && capacity == 7) {
1517
1206
  // x-x/8 does not work when x==7.
@@ -1520,18 +1209,28 @@ inline size_t CapacityToGrowth(size_t capacity) {
1520
1209
  return capacity - capacity / 8;
1521
1210
  }
1522
1211
 
1523
- // Given `growth`, "unapplies" the load factor to find how large the capacity
1212
+ // Given `size`, "unapplies" the load factor to find how large the capacity
1524
1213
  // should be to stay within the load factor.
1525
1214
  //
1526
- // This might not be a valid capacity and `NormalizeCapacity()` should be
1527
- // called on this.
1528
- inline size_t GrowthToLowerboundCapacity(size_t growth) {
1529
- // `growth*8/7`
1530
- if (Group::kWidth == 8 && growth == 7) {
1531
- // x+(x-1)/7 does not work when x==7.
1532
- return 8;
1533
- }
1534
- return growth + static_cast<size_t>((static_cast<int64_t>(growth) - 1) / 7);
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;
1535
1234
  }
1536
1235
 
1537
1236
  template <class InputIter>
@@ -1540,12 +1239,9 @@ size_t SelectBucketCountForIterRange(InputIter first, InputIter last,
1540
1239
  if (bucket_count != 0) {
1541
1240
  return bucket_count;
1542
1241
  }
1543
- using InputIterCategory =
1544
- typename std::iterator_traits<InputIter>::iterator_category;
1545
- if (std::is_base_of<std::random_access_iterator_tag,
1546
- InputIterCategory>::value) {
1547
- return GrowthToLowerboundCapacity(
1548
- static_cast<size_t>(std::distance(first, last)));
1242
+ if (base_internal::IsAtLeastIterator<std::random_access_iterator_tag,
1243
+ InputIter>()) {
1244
+ return SizeToCapacity(static_cast<size_t>(std::distance(first, last)));
1549
1245
  }
1550
1246
  return 0;
1551
1247
  }
@@ -1618,7 +1314,7 @@ inline void AssertIsValidForComparison(const ctrl_t* ctrl,
1618
1314
  FATAL, "Invalid iterator comparison. The element was likely erased.");
1619
1315
  }
1620
1316
  } else {
1621
- ABSL_HARDENING_ASSERT(
1317
+ ABSL_HARDENING_ASSERT_SLOW(
1622
1318
  ctrl_is_valid_for_comparison &&
1623
1319
  "Invalid iterator comparison. The element might have been erased or "
1624
1320
  "the table might have rehashed. Consider running with --config=asan to "
@@ -1703,7 +1399,7 @@ inline void AssertSameContainer(const ctrl_t* ctrl_a, const ctrl_t* ctrl_b,
1703
1399
  "hashtable.");
1704
1400
  fail_if(true, "Comparing non-end() iterators from different hashtables.");
1705
1401
  } else {
1706
- ABSL_HARDENING_ASSERT(
1402
+ ABSL_HARDENING_ASSERT_SLOW(
1707
1403
  AreItersFromSameContainer(ctrl_a, ctrl_b, slot_a, slot_b) &&
1708
1404
  "Invalid iterator comparison. The iterators may be from different "
1709
1405
  "containers or the container might have rehashed or moved. Consider "
@@ -1716,33 +1412,22 @@ struct FindInfo {
1716
1412
  size_t probe_length;
1717
1413
  };
1718
1414
 
1719
- // Whether a table is "small". A small table fits entirely into a probing
1720
- // group, i.e., has a capacity < `Group::kWidth`.
1721
- //
1722
- // In small mode we are able to use the whole capacity. The extra control
1723
- // bytes give us at least one "empty" control byte to stop the iteration.
1724
- // This is important to make 1 a valid capacity.
1725
- //
1726
- // In small mode only the first `capacity` control bytes after the sentinel
1727
- // are valid. The rest contain dummy ctrl_t::kEmpty values that do not
1728
- // represent a real slot. This is important to take into account on
1729
- // `find_first_non_full()`, where we never try
1730
- // `ShouldInsertBackwards()` for small tables.
1731
- inline bool is_small(size_t capacity) { return capacity < Group::kWidth - 1; }
1732
-
1733
1415
  // Whether a table fits entirely into a probing group.
1734
1416
  // Arbitrary order of elements in such tables is correct.
1735
- inline bool is_single_group(size_t capacity) {
1417
+ constexpr bool is_single_group(size_t capacity) {
1736
1418
  return capacity <= Group::kWidth;
1737
1419
  }
1738
1420
 
1739
1421
  // Begins a probing operation on `common.control`, using `hash`.
1740
- inline probe_seq<Group::kWidth> probe(const ctrl_t* ctrl, const size_t capacity,
1422
+ inline probe_seq<Group::kWidth> probe(size_t h1, size_t capacity) {
1423
+ return probe_seq<Group::kWidth>(h1, capacity);
1424
+ }
1425
+ inline probe_seq<Group::kWidth> probe(PerTableSeed seed, size_t capacity,
1741
1426
  size_t hash) {
1742
- return probe_seq<Group::kWidth>(H1(hash, ctrl), capacity);
1427
+ return probe(H1(hash, seed), capacity);
1743
1428
  }
1744
1429
  inline probe_seq<Group::kWidth> probe(const CommonFields& common, size_t hash) {
1745
- return probe(common.control(), common.capacity(), hash);
1430
+ return probe(common.seed(), common.capacity(), hash);
1746
1431
  }
1747
1432
 
1748
1433
  // Probes an array of control bits using a probe sequence derived from `hash`,
@@ -1752,56 +1437,75 @@ inline probe_seq<Group::kWidth> probe(const CommonFields& common, size_t hash) {
1752
1437
  //
1753
1438
  // NOTE: this function must work with tables having both empty and deleted
1754
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
+ constexpr size_t kProbedElementIndexSentinel = ~size_t{};
1443
+
1444
+ // Implementation detail of transfer_unprobed_elements_to_next_capacity_fn.
1445
+ // Tries to find the new index for an element whose hash corresponds to
1446
+ // `h1` for growth to the next capacity.
1447
+ // Returns kProbedElementIndexSentinel if full probing is required.
1448
+ //
1449
+ // If element is located in the first probing group in the table before growth,
1450
+ // returns one of two positions: `old_index` or `old_index + old_capacity + 1`.
1451
+ //
1452
+ // Otherwise, we will try to insert it into the first probe group of the new
1453
+ // table. We only attempt to do so if the first probe group is already
1454
+ // initialized.
1755
1455
  template <typename = void>
1756
- inline FindInfo find_first_non_full(const CommonFields& common, size_t hash) {
1757
- auto seq = probe(common, hash);
1758
- const ctrl_t* ctrl = common.control();
1759
- if (IsEmptyOrDeleted(ctrl[seq.offset()]) &&
1760
- !ShouldInsertBackwards(common.capacity(), hash, ctrl)) {
1761
- return {seq.offset(), /*probe_length=*/0};
1762
- }
1763
- while (true) {
1764
- GroupFullEmptyOrDeleted g{ctrl + seq.offset()};
1765
- auto mask = g.MaskEmptyOrDeleted();
1766
- if (mask) {
1767
- return {
1768
- seq.offset(GetInsertionOffset(mask, common.capacity(), hash, ctrl)),
1769
- seq.index()};
1770
- }
1771
- seq.next();
1772
- assert(seq.index() <= common.capacity() && "full table!");
1456
+ inline size_t TryFindNewIndexWithoutProbing(size_t h1, size_t old_index,
1457
+ size_t old_capacity,
1458
+ ctrl_t* new_ctrl,
1459
+ size_t new_capacity) {
1460
+ size_t index_diff = old_index - h1;
1461
+ // The first probe group starts with h1 & capacity.
1462
+ // All following groups start at (h1 + Group::kWidth * K) & capacity.
1463
+ // We can find an index within the floating group as index_diff modulo
1464
+ // Group::kWidth.
1465
+ // Both old and new capacity are larger than Group::kWidth so we can avoid
1466
+ // computing `& capacity`.
1467
+ size_t in_floating_group_index = index_diff & (Group::kWidth - 1);
1468
+ // By subtracting we will get the difference between the first probe group
1469
+ // and the probe group corresponding to old_index.
1470
+ index_diff -= in_floating_group_index;
1471
+ if (ABSL_PREDICT_TRUE((index_diff & old_capacity) == 0)) {
1472
+ size_t new_index = (h1 + in_floating_group_index) & new_capacity;
1473
+ ABSL_ASSUME(new_index != kProbedElementIndexSentinel);
1474
+ return new_index;
1475
+ }
1476
+ ABSL_SWISSTABLE_ASSERT(((old_index - h1) & old_capacity) >= Group::kWidth);
1477
+ // Try to insert element into the first probe group.
1478
+ // new_ctrl is not yet fully initialized so we can't use regular search via
1479
+ // find_first_non_full.
1480
+
1481
+ // We can search in the first probe group only if it is located in already
1482
+ // initialized part of the table.
1483
+ if (ABSL_PREDICT_FALSE((h1 & old_capacity) >= old_index)) {
1484
+ return kProbedElementIndexSentinel;
1485
+ }
1486
+ size_t offset = h1 & new_capacity;
1487
+ Group new_g(new_ctrl + offset);
1488
+ if (auto mask = new_g.MaskNonFull(); ABSL_PREDICT_TRUE(mask)) {
1489
+ size_t result = offset + mask.LowestBitSet();
1490
+ ABSL_ASSUME(result != kProbedElementIndexSentinel);
1491
+ return result;
1773
1492
  }
1493
+ return kProbedElementIndexSentinel;
1774
1494
  }
1775
1495
 
1776
- // Extern template for inline function keep possibility of inlining.
1496
+ // Extern template for inline function keeps possibility of inlining.
1777
1497
  // When compiler decided to not inline, no symbols will be added to the
1778
1498
  // corresponding translation unit.
1779
- extern template FindInfo find_first_non_full(const CommonFields&, size_t);
1780
-
1781
- // Non-inlined version of find_first_non_full for use in less
1782
- // performance critical routines.
1783
- FindInfo find_first_non_full_outofline(const CommonFields&, size_t);
1784
-
1785
- inline void ResetGrowthLeft(CommonFields& common) {
1786
- common.growth_info().InitGrowthLeftNoDeleted(
1787
- CapacityToGrowth(common.capacity()) - common.size());
1788
- }
1789
-
1790
- // Sets `ctrl` to `{kEmpty, kSentinel, ..., kEmpty}`, marking the entire
1791
- // array as marked as empty.
1792
- inline void ResetCtrl(CommonFields& common, size_t slot_size) {
1793
- const size_t capacity = common.capacity();
1794
- ctrl_t* ctrl = common.control();
1795
- std::memset(ctrl, static_cast<int8_t>(ctrl_t::kEmpty),
1796
- capacity + 1 + NumClonedBytes());
1797
- ctrl[capacity] = ctrl_t::kSentinel;
1798
- SanitizerPoisonMemoryRegion(common.slot_array(), slot_size * capacity);
1799
- }
1499
+ extern template size_t TryFindNewIndexWithoutProbing(size_t h1,
1500
+ size_t old_index,
1501
+ size_t old_capacity,
1502
+ ctrl_t* new_ctrl,
1503
+ size_t new_capacity);
1800
1504
 
1801
1505
  // Sets sanitizer poisoning for slot corresponding to control byte being set.
1802
1506
  inline void DoSanitizeOnSetCtrl(const CommonFields& c, size_t i, ctrl_t h,
1803
1507
  size_t slot_size) {
1804
- assert(i < c.capacity());
1508
+ ABSL_SWISSTABLE_ASSERT(i < c.capacity());
1805
1509
  auto* slot_i = static_cast<const char*>(c.slot_array()) + i * slot_size;
1806
1510
  if (IsFull(h)) {
1807
1511
  SanitizerUnpoisonMemoryRegion(slot_i, slot_size);
@@ -1831,7 +1535,7 @@ inline void SetCtrl(const CommonFields& c, size_t i, h2_t h, size_t slot_size) {
1831
1535
  // setting the cloned control byte.
1832
1536
  inline void SetCtrlInSingleGroupTable(const CommonFields& c, size_t i, ctrl_t h,
1833
1537
  size_t slot_size) {
1834
- assert(is_single_group(c.capacity()));
1538
+ ABSL_SWISSTABLE_ASSERT(is_single_group(c.capacity()));
1835
1539
  DoSanitizeOnSetCtrl(c, i, h, slot_size);
1836
1540
  ctrl_t* ctrl = c.control();
1837
1541
  ctrl[i] = h;
@@ -1843,6 +1547,22 @@ inline void SetCtrlInSingleGroupTable(const CommonFields& c, size_t i, h2_t h,
1843
1547
  SetCtrlInSingleGroupTable(c, i, static_cast<ctrl_t>(h), slot_size);
1844
1548
  }
1845
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
+
1846
1566
  // growth_info (which is a size_t) is stored with the backing array.
1847
1567
  constexpr size_t BackingArrayAlignment(size_t align_of_slot) {
1848
1568
  return (std::max)(align_of_slot, alignof(GrowthInfo));
@@ -1855,442 +1575,283 @@ inline void* SlotAddress(void* slot_array, size_t slot, size_t slot_size) {
1855
1575
  (slot * slot_size));
1856
1576
  }
1857
1577
 
1858
- // Iterates over all full slots and calls `cb(const ctrl_t*, SlotType*)`.
1859
- // No insertion to the table allowed during Callback call.
1578
+ // Iterates over all full slots and calls `cb(const ctrl_t*, void*)`.
1579
+ // No insertion to the table is allowed during `cb` call.
1860
1580
  // Erasure is allowed only for the element passed to the callback.
1861
- template <class SlotType, class Callback>
1862
- ABSL_ATTRIBUTE_ALWAYS_INLINE inline void IterateOverFullSlots(
1863
- const CommonFields& c, SlotType* slot, Callback cb) {
1864
- const size_t cap = c.capacity();
1865
- const ctrl_t* ctrl = c.control();
1866
- if (is_small(cap)) {
1867
- // Mirrored/cloned control bytes in small table are also located in the
1868
- // first group (starting from position 0). We are taking group from position
1869
- // `capacity` in order to avoid duplicates.
1870
-
1871
- // Small tables capacity fits into portable group, where
1872
- // GroupPortableImpl::MaskFull is more efficient for the
1873
- // capacity <= GroupPortableImpl::kWidth.
1874
- assert(cap <= GroupPortableImpl::kWidth &&
1875
- "unexpectedly large small capacity");
1876
- static_assert(Group::kWidth >= GroupPortableImpl::kWidth,
1877
- "unexpected group width");
1878
- // Group starts from kSentinel slot, so indices in the mask will
1879
- // be increased by 1.
1880
- const auto mask = GroupPortableImpl(ctrl + cap).MaskFull();
1881
- --ctrl;
1882
- --slot;
1883
- for (uint32_t i : mask) {
1884
- cb(ctrl + i, slot + i);
1885
- }
1886
- return;
1887
- }
1888
- size_t remaining = c.size();
1889
- ABSL_ATTRIBUTE_UNUSED const size_t original_size_for_assert = remaining;
1890
- while (remaining != 0) {
1891
- for (uint32_t i : GroupFullEmptyOrDeleted(ctrl).MaskFull()) {
1892
- assert(IsFull(ctrl[i]) && "hash table was modified unexpectedly");
1893
- cb(ctrl + i, slot + i);
1894
- --remaining;
1895
- }
1896
- ctrl += Group::kWidth;
1897
- slot += Group::kWidth;
1898
- assert((remaining == 0 || *(ctrl - 1) != ctrl_t::kSentinel) &&
1899
- "hash table was modified unexpectedly");
1900
- }
1901
- // NOTE: erasure of the current element is allowed in callback for
1902
- // absl::erase_if specialization. So we use `>=`.
1903
- assert(original_size_for_assert >= c.size() &&
1904
- "hash table was modified unexpectedly");
1905
- }
1581
+ // The table must not be in SOO mode.
1582
+ void IterateOverFullSlots(const CommonFields& c, size_t slot_size,
1583
+ absl::FunctionRef<void(const ctrl_t*, void*)> cb);
1906
1584
 
1907
1585
  template <typename CharAlloc>
1908
- constexpr bool ShouldSampleHashtablezInfo() {
1586
+ constexpr bool ShouldSampleHashtablezInfoForAlloc() {
1909
1587
  // Folks with custom allocators often make unwarranted assumptions about the
1910
1588
  // behavior of their classes vis-a-vis trivial destructability and what
1911
1589
  // calls they will or won't make. Avoid sampling for people with custom
1912
1590
  // allocators to get us out of this mess. This is not a hard guarantee but
1913
1591
  // a workaround while we plan the exact guarantee we want to provide.
1914
- return std::is_same<CharAlloc, std::allocator<char>>::value;
1592
+ return std::is_same_v<CharAlloc, std::allocator<char>>;
1915
1593
  }
1916
1594
 
1917
1595
  template <bool kSooEnabled>
1918
- HashtablezInfoHandle SampleHashtablezInfo(size_t sizeof_slot, size_t sizeof_key,
1919
- size_t sizeof_value,
1920
- size_t old_capacity, bool was_soo,
1921
- HashtablezInfoHandle forced_infoz,
1922
- CommonFields& c) {
1923
- if (forced_infoz.IsSampled()) return forced_infoz;
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
+ }
1924
1605
  // In SOO, we sample on the first insertion so if this is an empty SOO case
1925
1606
  // (e.g. when reserve is called), then we still need to sample.
1926
- if (kSooEnabled && was_soo && c.size() == 0) {
1927
- return Sample(sizeof_slot, sizeof_key, sizeof_value, SooCapacity());
1607
+ if (kSooEnabled && old_capacity == SooCapacity() && c.empty()) {
1608
+ return ShouldSampleNextTable();
1928
1609
  }
1929
- // For non-SOO cases, we sample whenever the capacity is increasing from zero
1930
- // to non-zero.
1931
1610
  if (!kSooEnabled && old_capacity == 0) {
1932
- return Sample(sizeof_slot, sizeof_key, sizeof_value, 0);
1611
+ return ShouldSampleNextTable();
1933
1612
  }
1934
- return c.infoz();
1613
+ return false;
1935
1614
  }
1936
1615
 
1937
- // Helper class to perform resize of the hash set.
1938
- //
1939
- // It contains special optimizations for small group resizes.
1940
- // See GrowIntoSingleGroupShuffleControlBytes for details.
1941
- class HashSetResizeHelper {
1942
- public:
1943
- explicit HashSetResizeHelper(CommonFields& c, bool was_soo, bool had_soo_slot,
1944
- HashtablezInfoHandle forced_infoz)
1945
- : old_capacity_(c.capacity()),
1946
- had_infoz_(c.has_infoz()),
1947
- was_soo_(was_soo),
1948
- had_soo_slot_(had_soo_slot),
1949
- forced_infoz_(forced_infoz) {}
1950
-
1951
- // Optimized for small groups version of `find_first_non_full`.
1952
- // Beneficial only right after calling `raw_hash_set::resize`.
1953
- // It is safe to call in case capacity is big or was not changed, but there
1954
- // will be no performance benefit.
1955
- // It has implicit assumption that `resize` will call
1956
- // `GrowSizeIntoSingleGroup*` in case `IsGrowingIntoSingleGroupApplicable`.
1957
- // Falls back to `find_first_non_full` in case of big groups.
1958
- static FindInfo FindFirstNonFullAfterResize(const CommonFields& c,
1959
- size_t old_capacity,
1960
- size_t hash) {
1961
- if (!IsGrowingIntoSingleGroupApplicable(old_capacity, c.capacity())) {
1962
- return find_first_non_full(c, hash);
1963
- }
1964
- // Find a location for the new element non-deterministically.
1965
- // Note that any position is correct.
1966
- // It will located at `half_old_capacity` or one of the other
1967
- // empty slots with approximately 50% probability each.
1968
- size_t offset = probe(c, hash).offset();
1969
-
1970
- // Note that we intentionally use unsigned int underflow.
1971
- if (offset - (old_capacity + 1) >= old_capacity) {
1972
- // Offset fall on kSentinel or into the mostly occupied first half.
1973
- offset = old_capacity / 2;
1974
- }
1975
- assert(IsEmpty(c.control()[offset]));
1976
- return FindInfo{offset, 0};
1977
- }
1978
-
1979
- HeapOrSoo& old_heap_or_soo() { return old_heap_or_soo_; }
1980
- void* old_soo_data() { return old_heap_or_soo_.get_soo_data(); }
1981
- ctrl_t* old_ctrl() const {
1982
- assert(!was_soo_);
1983
- return old_heap_or_soo_.control();
1984
- }
1985
- void* old_slots() const {
1986
- assert(!was_soo_);
1987
- return old_heap_or_soo_.slot_array().get();
1988
- }
1989
- size_t old_capacity() const { return old_capacity_; }
1990
-
1991
- // Returns the index of the SOO slot when growing from SOO to non-SOO in a
1992
- // single group. See also InitControlBytesAfterSoo(). It's important to use
1993
- // index 1 so that when resizing from capacity 1 to 3, we can still have
1994
- // random iteration order between the first two inserted elements.
1995
- // I.e. it allows inserting the second element at either index 0 or 2.
1996
- static size_t SooSlotIndex() { return 1; }
1997
-
1998
- // Allocates a backing array for the hashtable.
1999
- // Reads `capacity` and updates all other fields based on the result of
2000
- // the allocation.
2001
- //
2002
- // It also may do the following actions:
2003
- // 1. initialize control bytes
2004
- // 2. initialize slots
2005
- // 3. deallocate old slots.
2006
- //
2007
- // We are bundling a lot of functionality
2008
- // in one ABSL_ATTRIBUTE_NOINLINE function in order to minimize binary code
2009
- // duplication in raw_hash_set<>::resize.
2010
- //
2011
- // `c.capacity()` must be nonzero.
2012
- // POSTCONDITIONS:
2013
- // 1. CommonFields is initialized.
2014
- //
2015
- // if IsGrowingIntoSingleGroupApplicable && TransferUsesMemcpy
2016
- // Both control bytes and slots are fully initialized.
2017
- // old_slots are deallocated.
2018
- // infoz.RecordRehash is called.
2019
- //
2020
- // if IsGrowingIntoSingleGroupApplicable && !TransferUsesMemcpy
2021
- // Control bytes are fully initialized.
2022
- // infoz.RecordRehash is called.
2023
- // GrowSizeIntoSingleGroup must be called to finish slots initialization.
2024
- //
2025
- // if !IsGrowingIntoSingleGroupApplicable
2026
- // Control bytes are initialized to empty table via ResetCtrl.
2027
- // raw_hash_set<>::resize must insert elements regularly.
2028
- // infoz.RecordRehash is called if old_capacity == 0.
2029
- //
2030
- // Returns IsGrowingIntoSingleGroupApplicable result to avoid recomputation.
2031
- template <typename Alloc, size_t SizeOfSlot, bool TransferUsesMemcpy,
2032
- bool SooEnabled, size_t AlignOfSlot>
2033
- ABSL_ATTRIBUTE_NOINLINE bool InitializeSlots(CommonFields& c, Alloc alloc,
2034
- ctrl_t soo_slot_h2,
2035
- size_t key_size,
2036
- size_t value_size) {
2037
- assert(c.capacity());
2038
- HashtablezInfoHandle infoz =
2039
- ShouldSampleHashtablezInfo<Alloc>()
2040
- ? SampleHashtablezInfo<SooEnabled>(SizeOfSlot, key_size, value_size,
2041
- old_capacity_, was_soo_,
2042
- forced_infoz_, c)
2043
- : HashtablezInfoHandle{};
2044
-
2045
- const bool has_infoz = infoz.IsSampled();
2046
- RawHashSetLayout layout(c.capacity(), AlignOfSlot, has_infoz);
2047
- char* mem = static_cast<char*>(Allocate<BackingArrayAlignment(AlignOfSlot)>(
2048
- &alloc, layout.alloc_size(SizeOfSlot)));
2049
- const GenerationType old_generation = c.generation();
2050
- c.set_generation_ptr(
2051
- reinterpret_cast<GenerationType*>(mem + layout.generation_offset()));
2052
- c.set_generation(NextGeneration(old_generation));
2053
- c.set_control(reinterpret_cast<ctrl_t*>(mem + layout.control_offset()));
2054
- c.set_slots(mem + layout.slot_offset());
2055
- ResetGrowthLeft(c);
2056
-
2057
- const bool grow_single_group =
2058
- IsGrowingIntoSingleGroupApplicable(old_capacity_, layout.capacity());
2059
- if (SooEnabled && was_soo_ && grow_single_group) {
2060
- InitControlBytesAfterSoo(c.control(), soo_slot_h2, layout.capacity());
2061
- if (TransferUsesMemcpy && had_soo_slot_) {
2062
- TransferSlotAfterSoo(c, SizeOfSlot);
2063
- }
2064
- // SooEnabled implies that old_capacity_ != 0.
2065
- } else if ((SooEnabled || old_capacity_ != 0) && grow_single_group) {
2066
- if (TransferUsesMemcpy) {
2067
- GrowSizeIntoSingleGroupTransferable(c, SizeOfSlot);
2068
- DeallocateOld<AlignOfSlot>(alloc, SizeOfSlot);
2069
- } else {
2070
- GrowIntoSingleGroupShuffleControlBytes(c.control(), layout.capacity());
2071
- }
2072
- } else {
2073
- ResetCtrl(c, SizeOfSlot);
2074
- }
2075
-
2076
- c.set_has_infoz(has_infoz);
2077
- if (has_infoz) {
2078
- infoz.RecordStorageChanged(c.size(), layout.capacity());
2079
- if ((SooEnabled && was_soo_) || grow_single_group || old_capacity_ == 0) {
2080
- infoz.RecordRehash(0);
2081
- }
2082
- c.set_infoz(infoz);
2083
- }
2084
- return grow_single_group;
2085
- }
2086
-
2087
- // Relocates slots into new single group consistent with
2088
- // GrowIntoSingleGroupShuffleControlBytes.
2089
- //
2090
- // PRECONDITIONS:
2091
- // 1. GrowIntoSingleGroupShuffleControlBytes was already called.
2092
- template <class PolicyTraits, class Alloc>
2093
- void GrowSizeIntoSingleGroup(CommonFields& c, Alloc& alloc_ref) {
2094
- assert(old_capacity_ < Group::kWidth / 2);
2095
- assert(IsGrowingIntoSingleGroupApplicable(old_capacity_, c.capacity()));
2096
- using slot_type = typename PolicyTraits::slot_type;
2097
- assert(is_single_group(c.capacity()));
2098
-
2099
- auto* new_slots = static_cast<slot_type*>(c.slot_array());
2100
- auto* old_slots_ptr = static_cast<slot_type*>(old_slots());
2101
-
2102
- size_t shuffle_bit = old_capacity_ / 2 + 1;
2103
- for (size_t i = 0; i < old_capacity_; ++i) {
2104
- if (IsFull(old_ctrl()[i])) {
2105
- size_t new_i = i ^ shuffle_bit;
2106
- SanitizerUnpoisonMemoryRegion(new_slots + new_i, sizeof(slot_type));
2107
- PolicyTraits::transfer(&alloc_ref, new_slots + new_i,
2108
- old_slots_ptr + i);
2109
- }
2110
- }
2111
- PoisonSingleGroupEmptySlots(c, sizeof(slot_type));
2112
- }
2113
-
2114
- // Deallocates old backing array.
2115
- template <size_t AlignOfSlot, class CharAlloc>
2116
- void DeallocateOld(CharAlloc alloc_ref, size_t slot_size) {
2117
- SanitizerUnpoisonMemoryRegion(old_slots(), slot_size * old_capacity_);
2118
- auto layout = RawHashSetLayout(old_capacity_, AlignOfSlot, had_infoz_);
2119
- Deallocate<BackingArrayAlignment(AlignOfSlot)>(
2120
- &alloc_ref, old_ctrl() - layout.control_offset(),
2121
- layout.alloc_size(slot_size));
2122
- }
2123
-
2124
- private:
2125
- // Returns true if `GrowSizeIntoSingleGroup` can be used for resizing.
2126
- static bool IsGrowingIntoSingleGroupApplicable(size_t old_capacity,
2127
- size_t new_capacity) {
2128
- // NOTE that `old_capacity < new_capacity` in order to have
2129
- // `old_capacity < Group::kWidth / 2` to make faster copies of 8 bytes.
2130
- return is_single_group(new_capacity) && old_capacity < new_capacity;
2131
- }
2132
-
2133
- // Relocates control bytes and slots into new single group for
2134
- // transferable objects.
2135
- // Must be called only if IsGrowingIntoSingleGroupApplicable returned true.
2136
- void GrowSizeIntoSingleGroupTransferable(CommonFields& c, size_t slot_size);
2137
-
2138
- // If there was an SOO slot and slots are transferable, transfers the SOO slot
2139
- // into the new heap allocation. Must be called only if
2140
- // IsGrowingIntoSingleGroupApplicable returned true.
2141
- void TransferSlotAfterSoo(CommonFields& c, size_t slot_size);
2142
-
2143
- // Shuffle control bits deterministically to the next capacity.
2144
- // Returns offset for newly added element with given hash.
2145
- //
2146
- // PRECONDITIONs:
2147
- // 1. new_ctrl is allocated for new_capacity,
2148
- // but not initialized.
2149
- // 2. new_capacity is a single group.
2150
- //
2151
- // All elements are transferred into the first `old_capacity + 1` positions
2152
- // of the new_ctrl. Elements are rotated by `old_capacity_ / 2 + 1` positions
2153
- // in order to change an order and keep it non deterministic.
2154
- // Although rotation itself deterministic, position of the new added element
2155
- // will be based on `H1` and is not deterministic.
2156
- //
2157
- // Examples:
2158
- // S = kSentinel, E = kEmpty
2159
- //
2160
- // old_ctrl = SEEEEEEEE...
2161
- // new_ctrl = ESEEEEEEE...
2162
- //
2163
- // old_ctrl = 0SEEEEEEE...
2164
- // new_ctrl = E0ESE0EEE...
2165
- //
2166
- // old_ctrl = 012S012EEEEEEEEE...
2167
- // new_ctrl = 2E01EEES2E01EEE...
2168
- //
2169
- // old_ctrl = 0123456S0123456EEEEEEEEEEE...
2170
- // new_ctrl = 456E0123EEEEEES456E0123EEE...
2171
- void GrowIntoSingleGroupShuffleControlBytes(ctrl_t* new_ctrl,
2172
- size_t new_capacity) const;
2173
-
2174
- // If the table was SOO, initializes new control bytes. `h2` is the control
2175
- // byte corresponding to the full slot. Must be called only if
2176
- // IsGrowingIntoSingleGroupApplicable returned true.
2177
- // Requires: `had_soo_slot_ || h2 == ctrl_t::kEmpty`.
2178
- void InitControlBytesAfterSoo(ctrl_t* new_ctrl, ctrl_t h2,
2179
- size_t new_capacity);
2180
-
2181
- // Shuffle trivially transferable slots in the way consistent with
2182
- // GrowIntoSingleGroupShuffleControlBytes.
2183
- //
2184
- // PRECONDITIONs:
2185
- // 1. old_capacity must be non-zero.
2186
- // 2. new_ctrl is fully initialized using
2187
- // GrowIntoSingleGroupShuffleControlBytes.
2188
- // 3. new_slots is allocated and *not* poisoned.
2189
- //
2190
- // POSTCONDITIONS:
2191
- // 1. new_slots are transferred from old_slots_ consistent with
2192
- // GrowIntoSingleGroupShuffleControlBytes.
2193
- // 2. Empty new_slots are *not* poisoned.
2194
- void GrowIntoSingleGroupShuffleTransferableSlots(void* new_slots,
2195
- size_t slot_size) const;
2196
-
2197
- // Poison empty slots that were transferred using the deterministic algorithm
2198
- // described above.
2199
- // PRECONDITIONs:
2200
- // 1. new_ctrl is fully initialized using
2201
- // GrowIntoSingleGroupShuffleControlBytes.
2202
- // 2. new_slots is fully initialized consistent with
2203
- // GrowIntoSingleGroupShuffleControlBytes.
2204
- void PoisonSingleGroupEmptySlots(CommonFields& c, size_t slot_size) const {
2205
- // poison non full items
2206
- for (size_t i = 0; i < c.capacity(); ++i) {
2207
- if (!IsFull(c.control()[i])) {
2208
- SanitizerPoisonMemoryRegion(SlotAddress(c.slot_array(), i, slot_size),
2209
- slot_size);
2210
- }
2211
- }
2212
- }
2213
-
2214
- HeapOrSoo old_heap_or_soo_;
2215
- size_t old_capacity_;
2216
- bool had_infoz_;
2217
- bool was_soo_;
2218
- bool had_soo_slot_;
2219
- // Either null infoz or a pre-sampled forced infoz for SOO tables.
2220
- HashtablezInfoHandle forced_infoz_;
2221
- };
2222
-
2223
- inline void PrepareInsertCommon(CommonFields& common) {
2224
- common.increment_size();
2225
- common.maybe_increment_generation_on_insert();
1616
+ // Allocates `n` bytes for a backing array.
1617
+ template <size_t AlignOfBackingArray, typename Alloc>
1618
+ ABSL_ATTRIBUTE_NOINLINE void* AllocateBackingArray(void* alloc, size_t n) {
1619
+ return Allocate<AlignOfBackingArray>(static_cast<Alloc*>(alloc), n);
2226
1620
  }
2227
1621
 
2228
- // Like prepare_insert, but for the case of inserting into a full SOO table.
2229
- size_t PrepareInsertAfterSoo(size_t hash, size_t slot_size,
2230
- CommonFields& common);
1622
+ template <size_t AlignOfBackingArray, typename Alloc>
1623
+ ABSL_ATTRIBUTE_NOINLINE void DeallocateBackingArray(
1624
+ void* alloc, size_t capacity, ctrl_t* ctrl, size_t slot_size,
1625
+ size_t slot_align, bool had_infoz) {
1626
+ RawHashSetLayout layout(capacity, slot_size, slot_align, had_infoz);
1627
+ void* backing_array = ctrl - layout.control_offset();
1628
+ // Unpoison before returning the memory to the allocator.
1629
+ SanitizerUnpoisonMemoryRegion(backing_array, layout.alloc_size());
1630
+ Deallocate<AlignOfBackingArray>(static_cast<Alloc*>(alloc), backing_array,
1631
+ layout.alloc_size());
1632
+ }
2231
1633
 
2232
1634
  // PolicyFunctions bundles together some information for a particular
2233
1635
  // raw_hash_set<T, ...> instantiation. This information is passed to
2234
1636
  // type-erased functions that want to do small amounts of type-specific
2235
1637
  // work.
2236
1638
  struct PolicyFunctions {
2237
- size_t slot_size;
1639
+ uint32_t key_size;
1640
+ uint32_t value_size;
1641
+ uint32_t slot_size;
1642
+ uint16_t slot_align;
1643
+ bool soo_enabled;
1644
+ bool is_hashtablez_eligible;
2238
1645
 
2239
1646
  // Returns the pointer to the hash function stored in the set.
2240
- const void* (*hash_fn)(const CommonFields& common);
1647
+ void* (*hash_fn)(CommonFields& common);
2241
1648
 
2242
1649
  // Returns the hash of the pointed-to slot.
2243
1650
  size_t (*hash_slot)(const void* hash_fn, void* slot);
2244
1651
 
2245
- // Transfers the contents of src_slot to dst_slot.
2246
- void (*transfer)(void* set, void* dst_slot, void* src_slot);
1652
+ // Transfers the contents of `count` slots from src_slot to dst_slot.
1653
+ // We use ability to transfer several slots in single group table growth.
1654
+ void (*transfer_n)(void* set, void* dst_slot, void* src_slot, size_t count);
2247
1655
 
2248
- // Deallocates the backing store from common.
2249
- void (*dealloc)(CommonFields& common, const PolicyFunctions& policy);
1656
+ // Returns the pointer to the CharAlloc stored in the set.
1657
+ void* (*get_char_alloc)(CommonFields& common);
1658
+
1659
+ // Allocates n bytes for the backing store for common.
1660
+ void* (*alloc)(void* alloc, size_t n);
2250
1661
 
2251
- // Resizes set to the new capacity.
2252
- // Arguments are used as in raw_hash_set::resize_impl.
2253
- void (*resize)(CommonFields& common, size_t new_capacity,
2254
- HashtablezInfoHandle forced_infoz);
1662
+ // Deallocates the backing store from common.
1663
+ void (*dealloc)(void* alloc, size_t capacity, ctrl_t* ctrl, size_t slot_size,
1664
+ size_t slot_align, bool had_infoz);
1665
+
1666
+ // Implementation detail of GrowToNextCapacity.
1667
+ // Iterates over all full slots and transfers unprobed elements.
1668
+ // Initializes the new control bytes except mirrored bytes and kSentinel.
1669
+ // Caller must finish the initialization.
1670
+ // All slots corresponding to the full control bytes are transferred.
1671
+ // Probed elements are reported by `encode_probed_element` callback.
1672
+ // encode_probed_element may overwrite old_ctrl buffer till source_offset.
1673
+ // Different encoding is used depending on the capacity of the table.
1674
+ // See ProbedItem*Bytes classes for details.
1675
+ void (*transfer_unprobed_elements_to_next_capacity)(
1676
+ CommonFields& common, const ctrl_t* old_ctrl, void* old_slots,
1677
+ // TODO(b/382423690): Try to use absl::FunctionRef here.
1678
+ void* probed_storage,
1679
+ void (*encode_probed_element)(void* probed_storage, h2_t h2,
1680
+ size_t source_offset, size_t h1));
1681
+
1682
+ uint8_t soo_capacity() const {
1683
+ return static_cast<uint8_t>(soo_enabled ? SooCapacity() : 0);
1684
+ }
2255
1685
  };
2256
1686
 
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.
1690
+ 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
+ }
1699
+ }
1700
+
1701
+ // Returns the maximum valid size for a table with provided slot size.
1702
+ // Template parameter is only used to enable testing.
1703
+ template <size_t kSizeOfSizeT = sizeof(size_t)>
1704
+ constexpr size_t MaxValidSize(size_t slot_size) {
1705
+ 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>();
1709
+ }
1710
+ return (size_t{1} << (kSizeOfSizeT * 8 - 2)) / slot_size;
1711
+ } else {
1712
+ return MaxValidSizeFor1ByteSlot<kSizeOfSizeT>() / slot_size;
1713
+ }
1714
+ }
1715
+
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.
1718
+ // Template parameter is only used to enable testing.
1719
+ 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
+ }
1732
+ }
1733
+
1734
+ // Returns the index of the SOO slot when growing from SOO to non-SOO in a
1735
+ // single group. See also InitializeSmallControlBytesAfterSoo(). It's important
1736
+ // to use index 1 so that when resizing from capacity 1 to 3, we can still have
1737
+ // random iteration order between the first two inserted elements.
1738
+ // I.e. it allows inserting the second element at either index 0 or 2.
1739
+ constexpr size_t SooSlotIndex() { return 1; }
1740
+
1741
+ // Maximum capacity for the algorithm for small table after SOO.
1742
+ // Note that typical size after SOO is 3, but we allow up to 7.
1743
+ // Allowing till 16 would require additional store that can be avoided.
1744
+ constexpr size_t MaxSmallAfterSooCapacity() { return 7; }
1745
+
1746
+ // Type erased version of raw_hash_set::reserve.
1747
+ // Requires: `new_size > policy.soo_capacity`.
1748
+ void ReserveTableToFitNewSize(CommonFields& common,
1749
+ const PolicyFunctions& policy, size_t new_size);
1750
+
1751
+ // Resizes empty non-allocated table to the next valid capacity after
1752
+ // `bucket_count`. Requires:
1753
+ // 1. `c.capacity() == policy.soo_capacity`.
1754
+ // 2. `c.empty()`.
1755
+ // 3. `new_size > policy.soo_capacity`.
1756
+ // The table will be attempted to be sampled.
1757
+ void ReserveEmptyNonAllocatedTableToFitBucketCount(
1758
+ CommonFields& common, const PolicyFunctions& policy, size_t bucket_count);
1759
+
1760
+ // Type erased version of raw_hash_set::rehash.
1761
+ void Rehash(CommonFields& common, const PolicyFunctions& policy, size_t n);
1762
+
1763
+ // Type erased version of copy constructor.
1764
+ void Copy(CommonFields& common, const PolicyFunctions& policy,
1765
+ const CommonFields& other,
1766
+ absl::FunctionRef<void(void*, const void*)> copy_fn);
1767
+
1768
+ // Returns the optimal size for memcpy when transferring SOO slot.
1769
+ // Otherwise, returns the optimal size for memcpy SOO slot transfer
1770
+ // to SooSlotIndex().
1771
+ // At the destination we are allowed to copy upto twice more bytes,
1772
+ // because there is at least one more slot after SooSlotIndex().
1773
+ // The result must not exceed MaxSooSlotSize().
1774
+ // Some of the cases are merged to minimize the number of function
1775
+ // instantiations.
1776
+ constexpr size_t OptimalMemcpySizeForSooSlotTransfer(
1777
+ size_t slot_size, size_t max_soo_slot_size = MaxSooSlotSize()) {
1778
+ static_assert(MaxSooSlotSize() >= 8, "unexpectedly small SOO slot size");
1779
+ if (slot_size == 1) {
1780
+ return 1;
1781
+ }
1782
+ if (slot_size <= 3) {
1783
+ return 4;
1784
+ }
1785
+ // We are merging 4 and 8 into one case because we expect them to be the
1786
+ // hottest cases. Copying 8 bytes is as fast on common architectures.
1787
+ if (slot_size <= 8) {
1788
+ return 8;
1789
+ }
1790
+ if (max_soo_slot_size <= 16) {
1791
+ return max_soo_slot_size;
1792
+ }
1793
+ if (slot_size <= 16) {
1794
+ return 16;
1795
+ }
1796
+ if (max_soo_slot_size <= 24) {
1797
+ return max_soo_slot_size;
1798
+ }
1799
+ static_assert(MaxSooSlotSize() <= 24, "unexpectedly large SOO slot size");
1800
+ return 24;
1801
+ }
1802
+
1803
+ // Resizes SOO table to the NextCapacity(SooCapacity()) and prepares insert for
1804
+ // 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
+ // All possible template combinations are defined in cc file to improve
1810
+ // compilation time.
1811
+ 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);
1822
+
1823
+ // Resizes table with allocated slots and change the table seed.
1824
+ // Tables with SOO enabled must have capacity > policy.soo_capacity.
1825
+ // No sampling will be performed since table is already allocated.
1826
+ void ResizeAllocatedTableWithSeedChange(CommonFields& common,
1827
+ const PolicyFunctions& policy,
1828
+ size_t new_capacity);
1829
+
2257
1830
  // ClearBackingArray clears the backing array, either modifying it in place,
2258
1831
  // or creating a new one based on the value of "reuse".
2259
1832
  // REQUIRES: c.capacity > 0
2260
1833
  void ClearBackingArray(CommonFields& c, const PolicyFunctions& policy,
2261
- bool reuse, bool soo_enabled);
1834
+ void* alloc, bool reuse, bool soo_enabled);
2262
1835
 
2263
1836
  // Type-erased version of raw_hash_set::erase_meta_only.
2264
1837
  void EraseMetaOnly(CommonFields& c, size_t index, size_t slot_size);
2265
1838
 
2266
- // Function to place in PolicyFunctions::dealloc for raw_hash_sets
2267
- // that are using std::allocator. This allows us to share the same
2268
- // function body for raw_hash_set instantiations that have the
2269
- // same slot alignment.
2270
- template <size_t AlignOfSlot>
2271
- ABSL_ATTRIBUTE_NOINLINE void DeallocateStandard(CommonFields& common,
2272
- const PolicyFunctions& policy) {
2273
- // Unpoison before returning the memory to the allocator.
2274
- SanitizerUnpoisonMemoryRegion(common.slot_array(),
2275
- policy.slot_size * common.capacity());
2276
-
2277
- std::allocator<char> alloc;
2278
- common.infoz().Unregister();
2279
- Deallocate<BackingArrayAlignment(AlignOfSlot)>(
2280
- &alloc, common.backing_array_start(),
2281
- common.alloc_size(policy.slot_size, AlignOfSlot));
2282
- }
2283
-
2284
1839
  // For trivially relocatable types we use memcpy directly. This allows us to
2285
1840
  // share the same function body for raw_hash_set instantiations that have the
2286
1841
  // same slot size as long as they are relocatable.
1842
+ // Separate function for relocating single slot cause significant binary bloat.
2287
1843
  template <size_t SizeOfSlot>
2288
- ABSL_ATTRIBUTE_NOINLINE void TransferRelocatable(void*, void* dst, void* src) {
2289
- memcpy(dst, src, SizeOfSlot);
1844
+ ABSL_ATTRIBUTE_NOINLINE void TransferNRelocatable(void*, void* dst, void* src,
1845
+ size_t count) {
1846
+ // TODO(b/382423690): Experiment with making specialization for power of 2 and
1847
+ // non power of 2. This would require passing the size of the slot.
1848
+ memcpy(dst, src, SizeOfSlot * count);
2290
1849
  }
2291
1850
 
2292
- // Type erased raw_hash_set::get_hash_ref_fn for the empty hash function case.
2293
- const void* GetHashRefForEmptyHasher(const CommonFields& common);
1851
+ // Returns a pointer to `common`. This is used to implement type erased
1852
+ // raw_hash_set::get_hash_ref_fn and raw_hash_set::get_alloc_ref_fn for the
1853
+ // empty class cases.
1854
+ void* GetRefForEmptyClass(CommonFields& common);
2294
1855
 
2295
1856
  // Given the hash of a value not currently in the table and the first empty
2296
1857
  // slot in the probe sequence, finds a viable slot index to insert it at.
@@ -2307,8 +1868,8 @@ const void* GetHashRefForEmptyHasher(const CommonFields& common);
2307
1868
  // REQUIRES: Table is not SOO.
2308
1869
  // REQUIRES: At least one non-full slot available.
2309
1870
  // REQUIRES: `target` is a valid empty position to insert.
2310
- size_t PrepareInsertNonSoo(CommonFields& common, size_t hash, FindInfo target,
2311
- const PolicyFunctions& policy);
1871
+ size_t PrepareInsertNonSoo(CommonFields& common, const PolicyFunctions& policy,
1872
+ size_t hash, FindInfo target);
2312
1873
 
2313
1874
  // A SwissTable.
2314
1875
  //
@@ -2339,9 +1900,6 @@ class raw_hash_set {
2339
1900
  public:
2340
1901
  using init_type = typename PolicyTraits::init_type;
2341
1902
  using key_type = typename PolicyTraits::key_type;
2342
- // TODO(sbenza): Hide slot_type as it is an implementation detail. Needs user
2343
- // code fixes!
2344
- using slot_type = typename PolicyTraits::slot_type;
2345
1903
  using allocator_type = Alloc;
2346
1904
  using size_type = size_t;
2347
1905
  using difference_type = ptrdiff_t;
@@ -2356,6 +1914,7 @@ class raw_hash_set {
2356
1914
  using const_pointer = typename absl::allocator_traits<
2357
1915
  allocator_type>::template rebind_traits<value_type>::const_pointer;
2358
1916
 
1917
+ private:
2359
1918
  // Alias used for heterogeneous lookup functions.
2360
1919
  // `key_arg<K>` evaluates to `K` when the functors are transparent and to
2361
1920
  // `key_type` otherwise. It permits template argument deduction on `K` for the
@@ -2363,7 +1922,8 @@ class raw_hash_set {
2363
1922
  template <class K>
2364
1923
  using key_arg = typename KeyArgImpl::template type<K, key_type>;
2365
1924
 
2366
- private:
1925
+ using slot_type = typename PolicyTraits::slot_type;
1926
+
2367
1927
  // TODO(b/289225379): we could add extra SOO space inside raw_hash_set
2368
1928
  // after CommonFields to allow inlining larger slot_types (e.g. std::string),
2369
1929
  // but it's a bit complicated if we want to support incomplete mapped_type in
@@ -2376,6 +1936,10 @@ class raw_hash_set {
2376
1936
  alignof(slot_type) <= alignof(HeapOrSoo);
2377
1937
  }
2378
1938
 
1939
+ constexpr static size_t DefaultCapacity() {
1940
+ return SooEnabled() ? SooCapacity() : 0;
1941
+ }
1942
+
2379
1943
  // Whether `size` fits in the SOO capacity of this table.
2380
1944
  bool fits_in_soo(size_t size) const {
2381
1945
  return SooEnabled() && size <= SooCapacity();
@@ -2402,23 +1966,14 @@ class raw_hash_set {
2402
1966
  static_assert(std::is_lvalue_reference<reference>::value,
2403
1967
  "Policy::element() must return a reference");
2404
1968
 
2405
- template <typename T>
2406
- struct SameAsElementReference
2407
- : std::is_same<typename std::remove_cv<
2408
- typename std::remove_reference<reference>::type>::type,
2409
- typename std::remove_cv<
2410
- typename std::remove_reference<T>::type>::type> {};
2411
-
2412
1969
  // An enabler for insert(T&&): T must be convertible to init_type or be the
2413
1970
  // same as [cv] value_type [ref].
2414
- // Note: we separate SameAsElementReference into its own type to avoid using
2415
- // reference unless we need to. MSVC doesn't seem to like it in some
2416
- // cases.
2417
1971
  template <class T>
2418
- using RequiresInsertable = typename std::enable_if<
2419
- absl::disjunction<std::is_convertible<T, init_type>,
2420
- SameAsElementReference<T>>::value,
2421
- int>::type;
1972
+ using Insertable = absl::disjunction<
1973
+ std::is_same<absl::remove_cvref_t<reference>, absl::remove_cvref_t<T>>,
1974
+ std::is_convertible<T, init_type>>;
1975
+ template <class T>
1976
+ using IsNotBitField = std::is_pointer<T*>;
2422
1977
 
2423
1978
  // RequiresNotInit is a workaround for gcc prior to 7.1.
2424
1979
  // See https://godbolt.org/g/Y4xsUh.
@@ -2429,6 +1984,17 @@ class raw_hash_set {
2429
1984
  template <class... Ts>
2430
1985
  using IsDecomposable = IsDecomposable<void, PolicyTraits, Hash, Eq, Ts...>;
2431
1986
 
1987
+ template <class T>
1988
+ using IsDecomposableAndInsertable =
1989
+ IsDecomposable<std::enable_if_t<Insertable<T>::value, T>>;
1990
+
1991
+ // Evaluates to true if an assignment from the given type would require the
1992
+ // source object to remain alive for the life of the element.
1993
+ template <class U>
1994
+ using IsLifetimeBoundAssignmentFrom = std::conditional_t<
1995
+ policy_trait_element_is_owner<Policy>::value, std::false_type,
1996
+ type_traits_internal::IsLifetimeBoundAssignment<init_type, U>>;
1997
+
2432
1998
  public:
2433
1999
  static_assert(std::is_same<pointer, value_type*>::value,
2434
2000
  "Allocators with custom pointer types are not supported");
@@ -2607,14 +2173,15 @@ class raw_hash_set {
2607
2173
  std::is_nothrow_default_constructible<key_equal>::value &&
2608
2174
  std::is_nothrow_default_constructible<allocator_type>::value) {}
2609
2175
 
2610
- ABSL_ATTRIBUTE_NOINLINE explicit raw_hash_set(
2176
+ explicit raw_hash_set(
2611
2177
  size_t bucket_count, const hasher& hash = hasher(),
2612
2178
  const key_equal& eq = key_equal(),
2613
2179
  const allocator_type& alloc = allocator_type())
2614
2180
  : settings_(CommonFields::CreateDefault<SooEnabled()>(), hash, eq,
2615
2181
  alloc) {
2616
- if (bucket_count > (SooEnabled() ? SooCapacity() : 0)) {
2617
- resize(NormalizeCapacity(bucket_count));
2182
+ if (bucket_count > DefaultCapacity()) {
2183
+ ReserveEmptyNonAllocatedTableToFitBucketCount(
2184
+ common(), GetPolicyFunctions(), bucket_count);
2618
2185
  }
2619
2186
  }
2620
2187
 
@@ -2672,7 +2239,8 @@ class raw_hash_set {
2672
2239
  // absl::flat_hash_set<int> a, b{a};
2673
2240
  //
2674
2241
  // RequiresNotInit<T> is a workaround for gcc prior to 7.1.
2675
- template <class T, RequiresNotInit<T> = 0, RequiresInsertable<T> = 0>
2242
+ template <class T, RequiresNotInit<T> = 0,
2243
+ std::enable_if_t<Insertable<T>::value, int> = 0>
2676
2244
  raw_hash_set(std::initializer_list<T> init, size_t bucket_count = 0,
2677
2245
  const hasher& hash = hasher(), const key_equal& eq = key_equal(),
2678
2246
  const allocator_type& alloc = allocator_type())
@@ -2683,7 +2251,8 @@ class raw_hash_set {
2683
2251
  const allocator_type& alloc = allocator_type())
2684
2252
  : raw_hash_set(init.begin(), init.end(), bucket_count, hash, eq, alloc) {}
2685
2253
 
2686
- template <class T, RequiresNotInit<T> = 0, RequiresInsertable<T> = 0>
2254
+ template <class T, RequiresNotInit<T> = 0,
2255
+ std::enable_if_t<Insertable<T>::value, int> = 0>
2687
2256
  raw_hash_set(std::initializer_list<T> init, size_t bucket_count,
2688
2257
  const hasher& hash, const allocator_type& alloc)
2689
2258
  : raw_hash_set(init, bucket_count, hash, key_equal(), alloc) {}
@@ -2692,7 +2261,8 @@ class raw_hash_set {
2692
2261
  const hasher& hash, const allocator_type& alloc)
2693
2262
  : raw_hash_set(init, bucket_count, hash, key_equal(), alloc) {}
2694
2263
 
2695
- template <class T, RequiresNotInit<T> = 0, RequiresInsertable<T> = 0>
2264
+ template <class T, RequiresNotInit<T> = 0,
2265
+ std::enable_if_t<Insertable<T>::value, int> = 0>
2696
2266
  raw_hash_set(std::initializer_list<T> init, size_t bucket_count,
2697
2267
  const allocator_type& alloc)
2698
2268
  : raw_hash_set(init, bucket_count, hasher(), key_equal(), alloc) {}
@@ -2701,7 +2271,8 @@ class raw_hash_set {
2701
2271
  const allocator_type& alloc)
2702
2272
  : raw_hash_set(init, bucket_count, hasher(), key_equal(), alloc) {}
2703
2273
 
2704
- template <class T, RequiresNotInit<T> = 0, RequiresInsertable<T> = 0>
2274
+ template <class T, RequiresNotInit<T> = 0,
2275
+ std::enable_if_t<Insertable<T>::value, int> = 0>
2705
2276
  raw_hash_set(std::initializer_list<T> init, const allocator_type& alloc)
2706
2277
  : raw_hash_set(init, 0, hasher(), key_equal(), alloc) {}
2707
2278
 
@@ -2711,72 +2282,20 @@ class raw_hash_set {
2711
2282
 
2712
2283
  raw_hash_set(const raw_hash_set& that)
2713
2284
  : raw_hash_set(that, AllocTraits::select_on_container_copy_construction(
2714
- that.alloc_ref())) {}
2285
+ allocator_type(that.char_alloc_ref()))) {}
2715
2286
 
2716
2287
  raw_hash_set(const raw_hash_set& that, const allocator_type& a)
2717
- : raw_hash_set(GrowthToLowerboundCapacity(that.size()), that.hash_ref(),
2718
- that.eq_ref(), a) {
2719
- const size_t size = that.size();
2720
- if (size == 0) {
2721
- return;
2722
- }
2723
- // We don't use `that.is_soo()` here because `that` can have non-SOO
2724
- // capacity but have a size that fits into SOO capacity.
2725
- if (fits_in_soo(size)) {
2726
- assert(size == 1);
2727
- common().set_full_soo();
2728
- emplace_at(soo_iterator(), *that.begin());
2729
- const HashtablezInfoHandle infoz = try_sample_soo();
2730
- if (infoz.IsSampled()) resize_with_soo_infoz(infoz);
2731
- return;
2732
- }
2733
- assert(!that.is_soo());
2734
- const size_t cap = capacity();
2735
- // Note about single group tables:
2736
- // 1. It is correct to have any order of elements.
2737
- // 2. Order has to be non deterministic.
2738
- // 3. We are assigning elements with arbitrary `shift` starting from
2739
- // `capacity + shift` position.
2740
- // 4. `shift` must be coprime with `capacity + 1` in order to be able to use
2741
- // modular arithmetic to traverse all positions, instead if cycling
2742
- // through a subset of positions. Odd numbers are coprime with any
2743
- // `capacity + 1` (2^N).
2744
- size_t offset = cap;
2745
- const size_t shift =
2746
- is_single_group(cap) ? (PerTableSalt(control()) | 1) : 0;
2747
- IterateOverFullSlots(
2748
- that.common(), that.slot_array(),
2749
- [&](const ctrl_t* that_ctrl,
2750
- slot_type* that_slot) ABSL_ATTRIBUTE_ALWAYS_INLINE {
2751
- if (shift == 0) {
2752
- // Big tables case. Position must be searched via probing.
2753
- // The table is guaranteed to be empty, so we can do faster than
2754
- // a full `insert`.
2755
- const size_t hash = PolicyTraits::apply(
2756
- HashElement{hash_ref()}, PolicyTraits::element(that_slot));
2757
- FindInfo target = find_first_non_full_outofline(common(), hash);
2758
- infoz().RecordInsert(hash, target.probe_length);
2759
- offset = target.offset;
2760
- } else {
2761
- // Small tables case. Next position is computed via shift.
2762
- offset = (offset + shift) & cap;
2763
- }
2764
- const h2_t h2 = static_cast<h2_t>(*that_ctrl);
2765
- assert( // We rely that hash is not changed for small tables.
2766
- H2(PolicyTraits::apply(HashElement{hash_ref()},
2767
- PolicyTraits::element(that_slot))) == h2 &&
2768
- "hash function value changed unexpectedly during the copy");
2769
- SetCtrl(common(), offset, h2, sizeof(slot_type));
2770
- emplace_at(iterator_at(offset), PolicyTraits::element(that_slot));
2771
- common().maybe_increment_generation_on_insert();
2772
- });
2773
- if (shift != 0) {
2774
- // On small table copy we do not record individual inserts.
2775
- // RecordInsert requires hash, but it is unknown for small tables.
2776
- infoz().RecordStorageChanged(size, cap);
2777
- }
2778
- common().set_size(size);
2779
- growth_info().OverwriteManyEmptyAsFull(size);
2288
+ : raw_hash_set(0, that.hash_ref(), that.eq_ref(), a) {
2289
+ that.AssertNotDebugCapacity();
2290
+ if (that.empty()) return;
2291
+ Copy(common(), GetPolicyFunctions(), that.common(),
2292
+ [this](void* dst, const void* src) {
2293
+ // TODO(b/413598253): type erase for trivially copyable types via
2294
+ // PolicyTraits.
2295
+ construct(to_slot(dst),
2296
+ PolicyTraits::element(
2297
+ static_cast<slot_type*>(const_cast<void*>(src))));
2298
+ });
2780
2299
  }
2781
2300
 
2782
2301
  ABSL_ATTRIBUTE_NOINLINE raw_hash_set(raw_hash_set&& that) noexcept(
@@ -2786,31 +2305,31 @@ class raw_hash_set {
2786
2305
  : // Hash, equality and allocator are copied instead of moved because
2787
2306
  // `that` must be left valid. If Hash is std::function<Key>, moving it
2788
2307
  // would create a nullptr functor that cannot be called.
2789
- // TODO(b/296061262): move instead of copying hash/eq/alloc.
2790
2308
  // Note: we avoid using exchange for better generated code.
2791
2309
  settings_(PolicyTraits::transfer_uses_memcpy() || !that.is_full_soo()
2792
2310
  ? std::move(that.common())
2793
2311
  : CommonFields{full_soo_tag_t{}},
2794
- that.hash_ref(), that.eq_ref(), that.alloc_ref()) {
2312
+ that.hash_ref(), that.eq_ref(), that.char_alloc_ref()) {
2795
2313
  if (!PolicyTraits::transfer_uses_memcpy() && that.is_full_soo()) {
2796
2314
  transfer(soo_slot(), that.soo_slot());
2797
2315
  }
2798
2316
  that.common() = CommonFields::CreateDefault<SooEnabled()>();
2799
- maybe_increment_generation_or_rehash_on_move();
2317
+ annotate_for_bug_detection_on_move(that);
2800
2318
  }
2801
2319
 
2802
2320
  raw_hash_set(raw_hash_set&& that, const allocator_type& a)
2803
2321
  : settings_(CommonFields::CreateDefault<SooEnabled()>(), that.hash_ref(),
2804
2322
  that.eq_ref(), a) {
2805
- if (a == that.alloc_ref()) {
2323
+ if (CharAlloc(a) == that.char_alloc_ref()) {
2806
2324
  swap_common(that);
2807
- maybe_increment_generation_or_rehash_on_move();
2325
+ annotate_for_bug_detection_on_move(that);
2808
2326
  } else {
2809
2327
  move_elements_allocs_unequal(std::move(that));
2810
2328
  }
2811
2329
  }
2812
2330
 
2813
2331
  raw_hash_set& operator=(const raw_hash_set& that) {
2332
+ that.AssertNotDebugCapacity();
2814
2333
  if (ABSL_PREDICT_FALSE(this == &that)) return *this;
2815
2334
  constexpr bool propagate_alloc =
2816
2335
  AllocTraits::propagate_on_container_copy_assignment::value;
@@ -2818,7 +2337,9 @@ class raw_hash_set {
2818
2337
  // is an exact match for that.size(). If this->capacity() is too big, then
2819
2338
  // it would make iteration very slow to reuse the allocation. Maybe we can
2820
2339
  // do the same heuristic as clear() and reuse if it's small enough.
2821
- raw_hash_set tmp(that, propagate_alloc ? that.alloc_ref() : alloc_ref());
2340
+ allocator_type alloc(propagate_alloc ? that.char_alloc_ref()
2341
+ : char_alloc_ref());
2342
+ raw_hash_set tmp(that, alloc);
2822
2343
  // NOLINTNEXTLINE: not returning *this for performance.
2823
2344
  return assign_impl<propagate_alloc>(std::move(tmp));
2824
2345
  }
@@ -2835,18 +2356,24 @@ class raw_hash_set {
2835
2356
  typename AllocTraits::propagate_on_container_move_assignment());
2836
2357
  }
2837
2358
 
2838
- ~raw_hash_set() { destructor_impl(); }
2359
+ ~raw_hash_set() {
2360
+ destructor_impl();
2361
+ if constexpr (SwisstableAssertAccessToDestroyedTable()) {
2362
+ common().set_capacity(InvalidCapacity::kDestroyed);
2363
+ }
2364
+ }
2839
2365
 
2840
2366
  iterator begin() ABSL_ATTRIBUTE_LIFETIME_BOUND {
2841
2367
  if (ABSL_PREDICT_FALSE(empty())) return end();
2842
- if (is_soo()) return soo_iterator();
2368
+ if (capacity() == 1) return single_iterator();
2843
2369
  iterator it = {control(), common().slots_union(),
2844
2370
  common().generation_ptr()};
2845
2371
  it.skip_empty_or_deleted();
2846
- assert(IsFull(*it.control()));
2372
+ ABSL_SWISSTABLE_ASSERT(IsFull(*it.control()));
2847
2373
  return it;
2848
2374
  }
2849
2375
  iterator end() ABSL_ATTRIBUTE_LIFETIME_BOUND {
2376
+ AssertNotDebugCapacity();
2850
2377
  return iterator(common().generation_ptr());
2851
2378
  }
2852
2379
 
@@ -2854,7 +2381,7 @@ class raw_hash_set {
2854
2381
  return const_cast<raw_hash_set*>(this)->begin();
2855
2382
  }
2856
2383
  const_iterator end() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
2857
- return iterator(common().generation_ptr());
2384
+ return const_cast<raw_hash_set*>(this)->end();
2858
2385
  }
2859
2386
  const_iterator cbegin() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
2860
2387
  return begin();
@@ -2862,18 +2389,26 @@ class raw_hash_set {
2862
2389
  const_iterator cend() const ABSL_ATTRIBUTE_LIFETIME_BOUND { return end(); }
2863
2390
 
2864
2391
  bool empty() const { return !size(); }
2865
- size_t size() const { return common().size(); }
2392
+ size_t size() const {
2393
+ AssertNotDebugCapacity();
2394
+ return common().size();
2395
+ }
2866
2396
  size_t capacity() const {
2867
2397
  const size_t cap = common().capacity();
2868
- // Compiler complains when using functions in assume so use local variables.
2869
- ABSL_ATTRIBUTE_UNUSED static constexpr bool kEnabled = SooEnabled();
2870
- ABSL_ATTRIBUTE_UNUSED static constexpr size_t kCapacity = SooCapacity();
2871
- ABSL_ASSUME(!kEnabled || cap >= kCapacity);
2398
+ // Compiler complains when using functions in ASSUME so use local variable.
2399
+ ABSL_ATTRIBUTE_UNUSED static constexpr size_t kDefaultCapacity =
2400
+ DefaultCapacity();
2401
+ ABSL_ASSUME(cap >= kDefaultCapacity);
2872
2402
  return cap;
2873
2403
  }
2874
- size_t max_size() const { return (std::numeric_limits<size_t>::max)(); }
2404
+ size_t max_size() const { return MaxValidSize(sizeof(slot_type)); }
2875
2405
 
2876
2406
  ABSL_ATTRIBUTE_REINITIALIZES void clear() {
2407
+ if (SwisstableGenerationsEnabled() &&
2408
+ capacity() >= InvalidCapacity::kMovedFrom) {
2409
+ common().set_capacity(DefaultCapacity());
2410
+ }
2411
+ AssertNotDebugCapacity();
2877
2412
  // Iterating over this container is O(bucket_count()). When bucket_count()
2878
2413
  // is much greater than size(), iteration becomes prohibitively expensive.
2879
2414
  // For clear() it is more important to reuse the allocated array when the
@@ -2889,8 +2424,7 @@ class raw_hash_set {
2889
2424
  common().set_empty_soo();
2890
2425
  } else {
2891
2426
  destroy_slots();
2892
- ClearBackingArray(common(), GetPolicyFunctions(), /*reuse=*/cap < 128,
2893
- SooEnabled());
2427
+ clear_backing_array(/*reuse=*/cap < 128);
2894
2428
  }
2895
2429
  common().set_reserved_growth(0);
2896
2430
  common().set_reservation_size(0);
@@ -2901,15 +2435,26 @@ class raw_hash_set {
2901
2435
  //
2902
2436
  // flat_hash_map<std::string, int> m;
2903
2437
  // m.insert(std::make_pair("abc", 42));
2904
- // TODO(cheshire): A type alias T2 is introduced as a workaround for the nvcc
2905
- // bug.
2906
- template <class T, RequiresInsertable<T> = 0, class T2 = T,
2907
- typename std::enable_if<IsDecomposable<T2>::value, int>::type = 0,
2908
- T* = nullptr>
2438
+ template <class T,
2439
+ int = std::enable_if_t<IsDecomposableAndInsertable<T>::value &&
2440
+ IsNotBitField<T>::value &&
2441
+ !IsLifetimeBoundAssignmentFrom<T>::value,
2442
+ int>()>
2909
2443
  std::pair<iterator, bool> insert(T&& value) ABSL_ATTRIBUTE_LIFETIME_BOUND {
2910
2444
  return emplace(std::forward<T>(value));
2911
2445
  }
2912
2446
 
2447
+ template <class T, int&...,
2448
+ std::enable_if_t<IsDecomposableAndInsertable<T>::value &&
2449
+ IsNotBitField<T>::value &&
2450
+ IsLifetimeBoundAssignmentFrom<T>::value,
2451
+ int> = 0>
2452
+ std::pair<iterator, bool> insert(
2453
+ T&& value ABSL_INTERNAL_ATTRIBUTE_CAPTURED_BY(this))
2454
+ ABSL_ATTRIBUTE_LIFETIME_BOUND {
2455
+ return this->template insert<T, 0>(std::forward<T>(value));
2456
+ }
2457
+
2913
2458
  // This overload kicks in when the argument is a bitfield or an lvalue of
2914
2459
  // insertable and decomposable type.
2915
2460
  //
@@ -2921,13 +2466,23 @@ class raw_hash_set {
2921
2466
  // const char* p = "hello";
2922
2467
  // s.insert(p);
2923
2468
  //
2924
- template <
2925
- class T, RequiresInsertable<const T&> = 0,
2926
- typename std::enable_if<IsDecomposable<const T&>::value, int>::type = 0>
2469
+ template <class T, int = std::enable_if_t<
2470
+ IsDecomposableAndInsertable<const T&>::value &&
2471
+ !IsLifetimeBoundAssignmentFrom<const T&>::value,
2472
+ int>()>
2927
2473
  std::pair<iterator, bool> insert(const T& value)
2928
2474
  ABSL_ATTRIBUTE_LIFETIME_BOUND {
2929
2475
  return emplace(value);
2930
2476
  }
2477
+ template <class T, int&...,
2478
+ std::enable_if_t<IsDecomposableAndInsertable<const T&>::value &&
2479
+ IsLifetimeBoundAssignmentFrom<const T&>::value,
2480
+ int> = 0>
2481
+ std::pair<iterator, bool> insert(
2482
+ const T& value ABSL_INTERNAL_ATTRIBUTE_CAPTURED_BY(this))
2483
+ ABSL_ATTRIBUTE_LIFETIME_BOUND {
2484
+ return this->template insert<T, 0>(value);
2485
+ }
2931
2486
 
2932
2487
  // This overload kicks in when the argument is an rvalue of init_type. Its
2933
2488
  // purpose is to handle brace-init-list arguments.
@@ -2935,22 +2490,44 @@ class raw_hash_set {
2935
2490
  // flat_hash_map<std::string, int> s;
2936
2491
  // s.insert({"abc", 42});
2937
2492
  std::pair<iterator, bool> insert(init_type&& value)
2938
- ABSL_ATTRIBUTE_LIFETIME_BOUND {
2493
+ ABSL_ATTRIBUTE_LIFETIME_BOUND
2494
+ #if __cplusplus >= 202002L
2495
+ requires(!IsLifetimeBoundAssignmentFrom<init_type>::value)
2496
+ #endif
2497
+ {
2939
2498
  return emplace(std::move(value));
2940
2499
  }
2500
+ #if __cplusplus >= 202002L
2501
+ std::pair<iterator, bool> insert(
2502
+ init_type&& value ABSL_INTERNAL_ATTRIBUTE_CAPTURED_BY(this))
2503
+ ABSL_ATTRIBUTE_LIFETIME_BOUND
2504
+ requires(IsLifetimeBoundAssignmentFrom<init_type>::value)
2505
+ {
2506
+ return emplace(std::move(value));
2507
+ }
2508
+ #endif
2941
2509
 
2942
- // TODO(cheshire): A type alias T2 is introduced as a workaround for the nvcc
2943
- // bug.
2944
- template <class T, RequiresInsertable<T> = 0, class T2 = T,
2945
- typename std::enable_if<IsDecomposable<T2>::value, int>::type = 0,
2946
- T* = nullptr>
2510
+ template <class T,
2511
+ int = std::enable_if_t<IsDecomposableAndInsertable<T>::value &&
2512
+ IsNotBitField<T>::value &&
2513
+ !IsLifetimeBoundAssignmentFrom<T>::value,
2514
+ int>()>
2947
2515
  iterator insert(const_iterator, T&& value) ABSL_ATTRIBUTE_LIFETIME_BOUND {
2948
2516
  return insert(std::forward<T>(value)).first;
2949
2517
  }
2518
+ template <class T, int&...,
2519
+ std::enable_if_t<IsDecomposableAndInsertable<T>::value &&
2520
+ IsNotBitField<T>::value &&
2521
+ IsLifetimeBoundAssignmentFrom<T>::value,
2522
+ int> = 0>
2523
+ iterator insert(const_iterator hint,
2524
+ T&& value ABSL_INTERNAL_ATTRIBUTE_CAPTURED_BY(this))
2525
+ ABSL_ATTRIBUTE_LIFETIME_BOUND {
2526
+ return this->template insert<T, 0>(hint, std::forward<T>(value));
2527
+ }
2950
2528
 
2951
- template <
2952
- class T, RequiresInsertable<const T&> = 0,
2953
- typename std::enable_if<IsDecomposable<const T&>::value, int>::type = 0>
2529
+ template <class T, std::enable_if_t<
2530
+ IsDecomposableAndInsertable<const T&>::value, int> = 0>
2954
2531
  iterator insert(const_iterator,
2955
2532
  const T& value) ABSL_ATTRIBUTE_LIFETIME_BOUND {
2956
2533
  return insert(value).first;
@@ -2966,7 +2543,8 @@ class raw_hash_set {
2966
2543
  for (; first != last; ++first) emplace(*first);
2967
2544
  }
2968
2545
 
2969
- template <class T, RequiresNotInit<T> = 0, RequiresInsertable<const T&> = 0>
2546
+ template <class T, RequiresNotInit<T> = 0,
2547
+ std::enable_if_t<Insertable<const T&>::value, int> = 0>
2970
2548
  void insert(std::initializer_list<T> ilist) {
2971
2549
  insert(ilist.begin(), ilist.end());
2972
2550
  }
@@ -3005,8 +2583,8 @@ class raw_hash_set {
3005
2583
  // flat_hash_map<std::string, std::string> m = {{"abc", "def"}};
3006
2584
  // // Creates no std::string copies and makes no heap allocations.
3007
2585
  // m.emplace("abc", "xyz");
3008
- template <class... Args, typename std::enable_if<
3009
- IsDecomposable<Args...>::value, int>::type = 0>
2586
+ template <class... Args,
2587
+ std::enable_if_t<IsDecomposable<Args...>::value, int> = 0>
3010
2588
  std::pair<iterator, bool> emplace(Args&&... args)
3011
2589
  ABSL_ATTRIBUTE_LIFETIME_BOUND {
3012
2590
  return PolicyTraits::apply(EmplaceDecomposable{*this},
@@ -3016,8 +2594,8 @@ class raw_hash_set {
3016
2594
  // This overload kicks in if we cannot deduce the key from args. It constructs
3017
2595
  // value_type unconditionally and then either moves it into the table or
3018
2596
  // destroys.
3019
- template <class... Args, typename std::enable_if<
3020
- !IsDecomposable<Args...>::value, int>::type = 0>
2597
+ template <class... Args,
2598
+ std::enable_if_t<!IsDecomposable<Args...>::value, int> = 0>
3021
2599
  std::pair<iterator, bool> emplace(Args&&... args)
3022
2600
  ABSL_ATTRIBUTE_LIFETIME_BOUND {
3023
2601
  alignas(slot_type) unsigned char raw[sizeof(slot_type)];
@@ -3068,7 +2646,7 @@ class raw_hash_set {
3068
2646
  public:
3069
2647
  template <class... Args>
3070
2648
  void operator()(Args&&... args) const {
3071
- assert(*slot_);
2649
+ ABSL_SWISSTABLE_ASSERT(*slot_);
3072
2650
  PolicyTraits::construct(alloc_, *slot_, std::forward<Args>(args)...);
3073
2651
  *slot_ = nullptr;
3074
2652
  }
@@ -3086,8 +2664,9 @@ class raw_hash_set {
3086
2664
  auto res = find_or_prepare_insert(key);
3087
2665
  if (res.second) {
3088
2666
  slot_type* slot = res.first.slot();
3089
- std::forward<F>(f)(constructor(&alloc_ref(), &slot));
3090
- assert(!slot);
2667
+ allocator_type alloc(char_alloc_ref());
2668
+ std::forward<F>(f)(constructor(&alloc, &slot));
2669
+ ABSL_SWISSTABLE_ASSERT(!slot);
3091
2670
  }
3092
2671
  return res.first;
3093
2672
  }
@@ -3109,24 +2688,16 @@ class raw_hash_set {
3109
2688
  return 1;
3110
2689
  }
3111
2690
 
3112
- // Erases the element pointed to by `it`. Unlike `std::unordered_set::erase`,
3113
- // this method returns void to reduce algorithmic complexity to O(1). The
3114
- // iterator is invalidated, so any increment should be done before calling
3115
- // erase. In order to erase while iterating across a map, use the following
3116
- // idiom (which also works for some standard containers):
3117
- //
3118
- // for (auto it = m.begin(), end = m.end(); it != end;) {
3119
- // // `erase()` will invalidate `it`, so advance `it` first.
3120
- // auto copy_it = it++;
3121
- // if (<pred>) {
3122
- // m.erase(copy_it);
3123
- // }
3124
- // }
2691
+ // Erases the element pointed to by `it`. Unlike `std::unordered_set::erase`,
2692
+ // this method returns void to reduce algorithmic complexity to O(1). The
2693
+ // iterator is invalidated so any increment should be done before calling
2694
+ // erase (e.g. `erase(it++)`).
3125
2695
  void erase(const_iterator cit) { erase(cit.inner_); }
3126
2696
 
3127
2697
  // This overload is necessary because otherwise erase<K>(const K&) would be
3128
2698
  // a better match if non-const iterator is passed as an argument.
3129
2699
  void erase(iterator it) {
2700
+ AssertNotDebugCapacity();
3130
2701
  AssertIsFull(it.control(), it.generation(), it.generation_ptr(), "erase()");
3131
2702
  destroy(it.slot());
3132
2703
  if (is_soo()) {
@@ -3138,7 +2709,8 @@ class raw_hash_set {
3138
2709
 
3139
2710
  iterator erase(const_iterator first,
3140
2711
  const_iterator last) ABSL_ATTRIBUTE_LIFETIME_BOUND {
3141
- // We check for empty first because ClearBackingArray requires that
2712
+ AssertNotDebugCapacity();
2713
+ // We check for empty first because clear_backing_array requires that
3142
2714
  // capacity() > 0 as a precondition.
3143
2715
  if (empty()) return end();
3144
2716
  if (first == last) return last.inner_;
@@ -3149,11 +2721,10 @@ class raw_hash_set {
3149
2721
  }
3150
2722
  if (first == begin() && last == end()) {
3151
2723
  // TODO(ezb): we access control bytes in destroy_slots so it could make
3152
- // sense to combine destroy_slots and ClearBackingArray to avoid cache
2724
+ // sense to combine destroy_slots and clear_backing_array to avoid cache
3153
2725
  // misses when the table is large. Note that we also do this in clear().
3154
2726
  destroy_slots();
3155
- ClearBackingArray(common(), GetPolicyFunctions(), /*reuse=*/true,
3156
- SooEnabled());
2727
+ clear_backing_array(/*reuse=*/true);
3157
2728
  common().set_reserved_growth(common().reservation_size());
3158
2729
  return end();
3159
2730
  }
@@ -3167,6 +2738,8 @@ class raw_hash_set {
3167
2738
  // If the element already exists in `this`, it is left unmodified in `src`.
3168
2739
  template <typename H, typename E>
3169
2740
  void merge(raw_hash_set<Policy, H, E, Alloc>& src) { // NOLINT
2741
+ AssertNotDebugCapacity();
2742
+ src.AssertNotDebugCapacity();
3170
2743
  assert(this != &src);
3171
2744
  // Returns whether insertion took place.
3172
2745
  const auto insert_slot = [this](slot_type* src_slot) {
@@ -3193,9 +2766,11 @@ class raw_hash_set {
3193
2766
  }
3194
2767
 
3195
2768
  node_type extract(const_iterator position) {
2769
+ AssertNotDebugCapacity();
3196
2770
  AssertIsFull(position.control(), position.inner_.generation(),
3197
2771
  position.inner_.generation_ptr(), "extract()");
3198
- auto node = CommonAccess::Transfer<node_type>(alloc_ref(), position.slot());
2772
+ allocator_type alloc(char_alloc_ref());
2773
+ auto node = CommonAccess::Transfer<node_type>(alloc, position.slot());
3199
2774
  if (is_soo()) {
3200
2775
  common().set_empty_soo();
3201
2776
  } else {
@@ -3204,9 +2779,8 @@ class raw_hash_set {
3204
2779
  return node;
3205
2780
  }
3206
2781
 
3207
- template <
3208
- class K = key_type,
3209
- typename std::enable_if<!std::is_same<K, iterator>::value, int>::type = 0>
2782
+ template <class K = key_type,
2783
+ std::enable_if_t<!std::is_same<K, iterator>::value, int> = 0>
3210
2784
  node_type extract(const key_arg<K>& key) {
3211
2785
  auto it = find(key);
3212
2786
  return it == end() ? node_type() : extract(const_iterator{it});
@@ -3216,71 +2790,22 @@ class raw_hash_set {
3216
2790
  IsNoThrowSwappable<hasher>() && IsNoThrowSwappable<key_equal>() &&
3217
2791
  IsNoThrowSwappable<allocator_type>(
3218
2792
  typename AllocTraits::propagate_on_container_swap{})) {
2793
+ AssertNotDebugCapacity();
2794
+ that.AssertNotDebugCapacity();
3219
2795
  using std::swap;
3220
2796
  swap_common(that);
3221
2797
  swap(hash_ref(), that.hash_ref());
3222
2798
  swap(eq_ref(), that.eq_ref());
3223
- SwapAlloc(alloc_ref(), that.alloc_ref(),
2799
+ SwapAlloc(char_alloc_ref(), that.char_alloc_ref(),
3224
2800
  typename AllocTraits::propagate_on_container_swap{});
3225
2801
  }
3226
2802
 
3227
- void rehash(size_t n) {
3228
- const size_t cap = capacity();
3229
- if (n == 0) {
3230
- if (cap == 0 || is_soo()) return;
3231
- if (empty()) {
3232
- ClearBackingArray(common(), GetPolicyFunctions(), /*reuse=*/false,
3233
- SooEnabled());
3234
- return;
3235
- }
3236
- if (fits_in_soo(size())) {
3237
- // When the table is already sampled, we keep it sampled.
3238
- if (infoz().IsSampled()) {
3239
- const size_t kInitialSampledCapacity = NextCapacity(SooCapacity());
3240
- if (capacity() > kInitialSampledCapacity) {
3241
- resize(kInitialSampledCapacity);
3242
- }
3243
- // This asserts that we didn't lose sampling coverage in `resize`.
3244
- assert(infoz().IsSampled());
3245
- return;
3246
- }
3247
- alignas(slot_type) unsigned char slot_space[sizeof(slot_type)];
3248
- slot_type* tmp_slot = to_slot(slot_space);
3249
- transfer(tmp_slot, begin().slot());
3250
- ClearBackingArray(common(), GetPolicyFunctions(), /*reuse=*/false,
3251
- SooEnabled());
3252
- transfer(soo_slot(), tmp_slot);
3253
- common().set_full_soo();
3254
- return;
3255
- }
3256
- }
3257
-
3258
- // bitor is a faster way of doing `max` here. We will round up to the next
3259
- // power-of-2-minus-1, so bitor is good enough.
3260
- auto m = NormalizeCapacity(n | GrowthToLowerboundCapacity(size()));
3261
- // n == 0 unconditionally rehashes as per the standard.
3262
- if (n == 0 || m > cap) {
3263
- resize(m);
3264
-
3265
- // This is after resize, to ensure that we have completed the allocation
3266
- // and have potentially sampled the hashtable.
3267
- infoz().RecordReservation(n);
3268
- }
3269
- }
2803
+ void rehash(size_t n) { Rehash(common(), GetPolicyFunctions(), n); }
3270
2804
 
3271
2805
  void reserve(size_t n) {
3272
- const size_t max_size_before_growth =
3273
- is_soo() ? SooCapacity() : size() + growth_left();
3274
- if (n > max_size_before_growth) {
3275
- size_t m = GrowthToLowerboundCapacity(n);
3276
- resize(NormalizeCapacity(m));
3277
-
3278
- // This is after resize, to ensure that we have completed the allocation
3279
- // and have potentially sampled the hashtable.
3280
- infoz().RecordReservation(n);
2806
+ if (ABSL_PREDICT_TRUE(n > DefaultCapacity())) {
2807
+ ReserveTableToFitNewSize(common(), GetPolicyFunctions(), n);
3281
2808
  }
3282
- common().reset_reserved_growth(n);
3283
- common().set_reservation_size(n);
3284
2809
  }
3285
2810
 
3286
2811
  // Extension API: support for heterogeneous keys.
@@ -3304,43 +2829,38 @@ class raw_hash_set {
3304
2829
  // specific benchmarks indicating its importance.
3305
2830
  template <class K = key_type>
3306
2831
  void prefetch(const key_arg<K>& key) const {
3307
- if (SooEnabled() ? is_soo() : capacity() == 0) return;
2832
+ if (capacity() == DefaultCapacity()) return;
3308
2833
  (void)key;
3309
2834
  // Avoid probing if we won't be able to prefetch the addresses received.
3310
2835
  #ifdef ABSL_HAVE_PREFETCH
3311
2836
  prefetch_heap_block();
3312
- auto seq = probe(common(), hash_ref()(key));
2837
+ auto seq = probe(common(), hash_of(key));
3313
2838
  PrefetchToLocalCache(control() + seq.offset());
3314
2839
  PrefetchToLocalCache(slot_array() + seq.offset());
3315
2840
  #endif // ABSL_HAVE_PREFETCH
3316
2841
  }
3317
2842
 
3318
- // The API of find() has two extensions.
3319
- //
3320
- // 1. The hash can be passed by the user. It must be equal to the hash of the
3321
- // key.
3322
- //
3323
- // 2. The type of the key argument doesn't have to be key_type. This is so
3324
- // called heterogeneous key support.
3325
2843
  template <class K = key_type>
2844
+ ABSL_DEPRECATE_AND_INLINE()
3326
2845
  iterator find(const key_arg<K>& key,
3327
- size_t hash) ABSL_ATTRIBUTE_LIFETIME_BOUND {
3328
- AssertHashEqConsistent(key);
3329
- if (is_soo()) return find_soo(key);
3330
- return find_non_soo(key, hash);
2846
+ size_t) ABSL_ATTRIBUTE_LIFETIME_BOUND {
2847
+ return find(key);
3331
2848
  }
2849
+ // The API of find() has one extension: the type of the key argument doesn't
2850
+ // have to be key_type. This is so called heterogeneous key support.
3332
2851
  template <class K = key_type>
3333
2852
  iterator find(const key_arg<K>& key) ABSL_ATTRIBUTE_LIFETIME_BOUND {
3334
- AssertHashEqConsistent(key);
3335
- if (is_soo()) return find_soo(key);
2853
+ AssertOnFind(key);
2854
+ if (capacity() <= 1) return find_small(key);
3336
2855
  prefetch_heap_block();
3337
- return find_non_soo(key, hash_ref()(key));
2856
+ return find_large(key, hash_of(key));
3338
2857
  }
3339
2858
 
3340
2859
  template <class K = key_type>
2860
+ ABSL_DEPRECATE_AND_INLINE()
3341
2861
  const_iterator find(const key_arg<K>& key,
3342
- size_t hash) const ABSL_ATTRIBUTE_LIFETIME_BOUND {
3343
- return const_cast<raw_hash_set*>(this)->find(key, hash);
2862
+ size_t) const ABSL_ATTRIBUTE_LIFETIME_BOUND {
2863
+ return find(key);
3344
2864
  }
3345
2865
  template <class K = key_type>
3346
2866
  const_iterator find(const key_arg<K>& key) const
@@ -3383,7 +2903,9 @@ class raw_hash_set {
3383
2903
 
3384
2904
  hasher hash_function() const { return hash_ref(); }
3385
2905
  key_equal key_eq() const { return eq_ref(); }
3386
- allocator_type get_allocator() const { return alloc_ref(); }
2906
+ allocator_type get_allocator() const {
2907
+ return allocator_type(char_alloc_ref());
2908
+ }
3387
2909
 
3388
2910
  friend bool operator==(const raw_hash_set& a, const raw_hash_set& b) {
3389
2911
  if (a.size() != b.size()) return false;
@@ -3392,7 +2914,16 @@ class raw_hash_set {
3392
2914
  if (outer->capacity() > inner->capacity()) std::swap(outer, inner);
3393
2915
  for (const value_type& elem : *outer) {
3394
2916
  auto it = PolicyTraits::apply(FindElement{*inner}, elem);
3395
- if (it == inner->end() || !(*it == elem)) return false;
2917
+ if (it == inner->end()) return false;
2918
+ // Note: we used key_equal to check for key equality in FindElement, but
2919
+ // we may need to do an additional comparison using
2920
+ // value_type::operator==. E.g. the keys could be equal and the
2921
+ // mapped_types could be unequal in a map or even in a set, key_equal
2922
+ // could ignore some fields that aren't ignored by operator==.
2923
+ static constexpr bool kKeyEqIsValueEq =
2924
+ std::is_same<key_type, value_type>::value &&
2925
+ std::is_same<key_equal, hash_default_eq<key_type>>::value;
2926
+ if (!kKeyEqIsValueEq && !(*it == elem)) return false;
3396
2927
  }
3397
2928
  return true;
3398
2929
  }
@@ -3406,7 +2937,7 @@ class raw_hash_set {
3406
2937
  H>::type
3407
2938
  AbslHashValue(H h, const raw_hash_set& s) {
3408
2939
  return H::combine(H::combine_unordered(std::move(h), s.begin(), s.end()),
3409
- s.size());
2940
+ hash_internal::WeaklyMixedInteger{s.size()});
3410
2941
  }
3411
2942
 
3412
2943
  friend void swap(raw_hash_set& a,
@@ -3441,7 +2972,7 @@ class raw_hash_set {
3441
2972
  struct EqualElement {
3442
2973
  template <class K2, class... Args>
3443
2974
  bool operator()(const K2& lhs, Args&&...) const {
3444
- return eq(lhs, rhs);
2975
+ ABSL_SWISSTABLE_IGNORE_UNINITIALIZED_RETURN(eq(lhs, rhs));
3445
2976
  }
3446
2977
  const K1& rhs;
3447
2978
  const key_equal& eq;
@@ -3476,37 +3007,51 @@ class raw_hash_set {
3476
3007
  slot_type&& slot;
3477
3008
  };
3478
3009
 
3479
- // TODO(b/303305702): re-enable reentrant validation.
3480
3010
  template <typename... Args>
3481
3011
  inline void construct(slot_type* slot, Args&&... args) {
3482
- PolicyTraits::construct(&alloc_ref(), slot, std::forward<Args>(args)...);
3012
+ common().RunWithReentrancyGuard([&] {
3013
+ allocator_type alloc(char_alloc_ref());
3014
+ PolicyTraits::construct(&alloc, slot, std::forward<Args>(args)...);
3015
+ });
3483
3016
  }
3484
3017
  inline void destroy(slot_type* slot) {
3485
- PolicyTraits::destroy(&alloc_ref(), slot);
3018
+ common().RunWithReentrancyGuard([&] {
3019
+ allocator_type alloc(char_alloc_ref());
3020
+ PolicyTraits::destroy(&alloc, slot);
3021
+ });
3486
3022
  }
3487
3023
  inline void transfer(slot_type* to, slot_type* from) {
3488
- PolicyTraits::transfer(&alloc_ref(), to, from);
3024
+ common().RunWithReentrancyGuard([&] {
3025
+ allocator_type alloc(char_alloc_ref());
3026
+ PolicyTraits::transfer(&alloc, to, from);
3027
+ });
3489
3028
  }
3490
3029
 
3491
3030
  // TODO(b/289225379): consider having a helper class that has the impls for
3492
3031
  // SOO functionality.
3493
3032
  template <class K = key_type>
3494
- iterator find_soo(const key_arg<K>& key) {
3495
- assert(is_soo());
3496
- return empty() || !PolicyTraits::apply(EqualElement<K>{key, eq_ref()},
3497
- PolicyTraits::element(soo_slot()))
3033
+ 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()))
3498
3038
  ? end()
3499
- : soo_iterator();
3039
+ : single_iterator();
3500
3040
  }
3501
3041
 
3502
3042
  template <class K = key_type>
3503
- iterator find_non_soo(const key_arg<K>& key, size_t hash) {
3504
- assert(!is_soo());
3043
+ iterator find_large(const key_arg<K>& key, size_t hash) {
3044
+ ABSL_SWISSTABLE_ASSERT(capacity() > 1);
3045
+ ABSL_SWISSTABLE_ASSERT(!is_soo());
3505
3046
  auto seq = probe(common(), hash);
3047
+ const h2_t h2 = H2(hash);
3506
3048
  const ctrl_t* ctrl = control();
3507
3049
  while (true) {
3050
+ #ifndef ABSL_HAVE_MEMORY_SANITIZER
3051
+ absl::PrefetchToLocalCache(slot_array() + seq.offset());
3052
+ #endif
3508
3053
  Group g{ctrl + seq.offset()};
3509
- for (uint32_t i : g.Match(H2(hash))) {
3054
+ for (uint32_t i : g.Match(h2)) {
3510
3055
  if (ABSL_PREDICT_TRUE(PolicyTraits::apply(
3511
3056
  EqualElement<K>{key, eq_ref()},
3512
3057
  PolicyTraits::element(slot_array() + seq.offset(i)))))
@@ -3514,40 +3059,57 @@ class raw_hash_set {
3514
3059
  }
3515
3060
  if (ABSL_PREDICT_TRUE(g.MaskEmpty())) return end();
3516
3061
  seq.next();
3517
- assert(seq.index() <= capacity() && "full table!");
3062
+ ABSL_SWISSTABLE_ASSERT(seq.index() <= capacity() && "full table!");
3518
3063
  }
3519
3064
  }
3520
3065
 
3521
- // Conditionally samples hashtablez for SOO tables. This should be called on
3522
- // insertion into an empty SOO table and in copy construction when the size
3523
- // can fit in SOO capacity.
3524
- inline HashtablezInfoHandle try_sample_soo() {
3525
- assert(is_soo());
3526
- if (!ShouldSampleHashtablezInfo<CharAlloc>()) return HashtablezInfoHandle{};
3527
- return Sample(sizeof(slot_type), sizeof(key_type), sizeof(value_type),
3528
- SooCapacity());
3066
+ // Returns true if the table needs to be sampled.
3067
+ // This should be called on insertion into an empty SOO table and in copy
3068
+ // construction when the size can fit in SOO capacity.
3069
+ bool should_sample_soo() const {
3070
+ ABSL_SWISSTABLE_ASSERT(is_soo());
3071
+ if (!ShouldSampleHashtablezInfoForAlloc<CharAlloc>()) return false;
3072
+ return ABSL_PREDICT_FALSE(ShouldSampleNextTable());
3073
+ }
3074
+
3075
+ void clear_backing_array(bool reuse) {
3076
+ ABSL_SWISSTABLE_ASSERT(capacity() > DefaultCapacity());
3077
+ ClearBackingArray(common(), GetPolicyFunctions(), &char_alloc_ref(), reuse,
3078
+ SooEnabled());
3529
3079
  }
3530
3080
 
3531
- inline void destroy_slots() {
3532
- assert(!is_soo());
3081
+ void destroy_slots() {
3082
+ ABSL_SWISSTABLE_ASSERT(!is_soo());
3533
3083
  if (PolicyTraits::template destroy_is_trivial<Alloc>()) return;
3534
- IterateOverFullSlots(
3535
- common(), slot_array(),
3536
- [&](const ctrl_t*, slot_type* slot)
3537
- ABSL_ATTRIBUTE_ALWAYS_INLINE { this->destroy(slot); });
3084
+ auto destroy_slot = [&](const ctrl_t*, void* slot) {
3085
+ this->destroy(static_cast<slot_type*>(slot));
3086
+ };
3087
+ if constexpr (SwisstableAssertAccessToDestroyedTable()) {
3088
+ CommonFields common_copy(non_soo_tag_t{}, this->common());
3089
+ common().set_capacity(InvalidCapacity::kDestroyed);
3090
+ IterateOverFullSlots(common_copy, sizeof(slot_type), destroy_slot);
3091
+ common().set_capacity(common_copy.capacity());
3092
+ } else {
3093
+ IterateOverFullSlots(common(), sizeof(slot_type), destroy_slot);
3094
+ }
3538
3095
  }
3539
3096
 
3540
- inline void dealloc() {
3541
- assert(capacity() != 0);
3097
+ void dealloc() {
3098
+ ABSL_SWISSTABLE_ASSERT(capacity() > DefaultCapacity());
3542
3099
  // Unpoison before returning the memory to the allocator.
3543
3100
  SanitizerUnpoisonMemoryRegion(slot_array(), sizeof(slot_type) * capacity());
3544
3101
  infoz().Unregister();
3545
- Deallocate<BackingArrayAlignment(alignof(slot_type))>(
3546
- &alloc_ref(), common().backing_array_start(),
3547
- common().alloc_size(sizeof(slot_type), alignof(slot_type)));
3102
+ DeallocateBackingArray<BackingArrayAlignment(alignof(slot_type)),
3103
+ CharAlloc>(&char_alloc_ref(), capacity(), control(),
3104
+ sizeof(slot_type), alignof(slot_type),
3105
+ common().has_infoz());
3548
3106
  }
3549
3107
 
3550
- inline void destructor_impl() {
3108
+ void destructor_impl() {
3109
+ if (SwisstableGenerationsEnabled() &&
3110
+ capacity() >= InvalidCapacity::kMovedFrom) {
3111
+ return;
3112
+ }
3551
3113
  if (capacity() == 0) return;
3552
3114
  if (is_soo()) {
3553
3115
  if (!empty()) {
@@ -3564,141 +3126,37 @@ class raw_hash_set {
3564
3126
  // This merely updates the pertinent control byte. This can be used in
3565
3127
  // conjunction with Policy::transfer to move the object to another place.
3566
3128
  void erase_meta_only(const_iterator it) {
3567
- assert(!is_soo());
3129
+ ABSL_SWISSTABLE_ASSERT(!is_soo());
3568
3130
  EraseMetaOnly(common(), static_cast<size_t>(it.control() - control()),
3569
3131
  sizeof(slot_type));
3570
3132
  }
3571
3133
 
3134
+ template <class K>
3135
+ size_t hash_of(const K& key) const {
3136
+ return hash_ref()(key);
3137
+ }
3572
3138
  size_t hash_of(slot_type* slot) const {
3573
3139
  return PolicyTraits::apply(HashElement{hash_ref()},
3574
3140
  PolicyTraits::element(slot));
3575
3141
  }
3576
3142
 
3577
- // Resizes table to the new capacity and move all elements to the new
3578
- // positions accordingly.
3579
- //
3580
- // Note that for better performance instead of
3581
- // find_first_non_full(common(), hash),
3582
- // HashSetResizeHelper::FindFirstNonFullAfterResize(
3583
- // common(), old_capacity, hash)
3584
- // can be called right after `resize`.
3585
- void resize(size_t new_capacity) {
3586
- raw_hash_set::resize_impl(common(), new_capacity, HashtablezInfoHandle{});
3587
- }
3588
-
3589
- // As above, except that we also accept a pre-sampled, forced infoz for
3590
- // SOO tables, since they need to switch from SOO to heap in order to
3591
- // store the infoz.
3592
- void resize_with_soo_infoz(HashtablezInfoHandle forced_infoz) {
3593
- assert(forced_infoz.IsSampled());
3594
- raw_hash_set::resize_impl(common(), NextCapacity(SooCapacity()),
3595
- forced_infoz);
3596
- }
3597
-
3598
- // Resizes set to the new capacity.
3599
- // It is a static function in order to use its pointer in GetPolicyFunctions.
3600
- ABSL_ATTRIBUTE_NOINLINE static void resize_impl(
3601
- CommonFields& common, size_t new_capacity,
3602
- HashtablezInfoHandle forced_infoz) {
3603
- raw_hash_set* set = reinterpret_cast<raw_hash_set*>(&common);
3604
- assert(IsValidCapacity(new_capacity));
3605
- assert(!set->fits_in_soo(new_capacity));
3606
- const bool was_soo = set->is_soo();
3607
- const bool had_soo_slot = was_soo && !set->empty();
3608
- const ctrl_t soo_slot_h2 =
3609
- had_soo_slot ? static_cast<ctrl_t>(H2(set->hash_of(set->soo_slot())))
3610
- : ctrl_t::kEmpty;
3611
- HashSetResizeHelper resize_helper(common, was_soo, had_soo_slot,
3612
- forced_infoz);
3613
- // Initialize HashSetResizeHelper::old_heap_or_soo_. We can't do this in
3614
- // HashSetResizeHelper constructor because it can't transfer slots when
3615
- // transfer_uses_memcpy is false.
3616
- // TODO(b/289225379): try to handle more of the SOO cases inside
3617
- // InitializeSlots. See comment on cl/555990034 snapshot #63.
3618
- if (PolicyTraits::transfer_uses_memcpy() || !had_soo_slot) {
3619
- resize_helper.old_heap_or_soo() = common.heap_or_soo();
3620
- } else {
3621
- set->transfer(set->to_slot(resize_helper.old_soo_data()),
3622
- set->soo_slot());
3623
- }
3624
- common.set_capacity(new_capacity);
3625
- // Note that `InitializeSlots` does different number initialization steps
3626
- // depending on the values of `transfer_uses_memcpy` and capacities.
3627
- // Refer to the comment in `InitializeSlots` for more details.
3628
- const bool grow_single_group =
3629
- resize_helper.InitializeSlots<CharAlloc, sizeof(slot_type),
3630
- PolicyTraits::transfer_uses_memcpy(),
3631
- SooEnabled(), alignof(slot_type)>(
3632
- common, CharAlloc(set->alloc_ref()), soo_slot_h2, sizeof(key_type),
3633
- sizeof(value_type));
3634
-
3635
- // In the SooEnabled() case, capacity is never 0 so we don't check.
3636
- if (!SooEnabled() && resize_helper.old_capacity() == 0) {
3637
- // InitializeSlots did all the work including infoz().RecordRehash().
3638
- return;
3639
- }
3640
- assert(resize_helper.old_capacity() > 0);
3641
- // Nothing more to do in this case.
3642
- if (was_soo && !had_soo_slot) return;
3643
-
3644
- slot_type* new_slots = set->slot_array();
3645
- if (grow_single_group) {
3646
- if (PolicyTraits::transfer_uses_memcpy()) {
3647
- // InitializeSlots did all the work.
3648
- return;
3649
- }
3650
- if (was_soo) {
3651
- set->transfer(new_slots + resize_helper.SooSlotIndex(),
3652
- to_slot(resize_helper.old_soo_data()));
3653
- return;
3654
- } else {
3655
- // We want GrowSizeIntoSingleGroup to be called here in order to make
3656
- // InitializeSlots not depend on PolicyTraits.
3657
- resize_helper.GrowSizeIntoSingleGroup<PolicyTraits>(common,
3658
- set->alloc_ref());
3659
- }
3660
- } else {
3661
- // InitializeSlots prepares control bytes to correspond to empty table.
3662
- const auto insert_slot = [&](slot_type* slot) {
3663
- size_t hash = PolicyTraits::apply(HashElement{set->hash_ref()},
3664
- PolicyTraits::element(slot));
3665
- auto target = find_first_non_full(common, hash);
3666
- SetCtrl(common, target.offset, H2(hash), sizeof(slot_type));
3667
- set->transfer(new_slots + target.offset, slot);
3668
- return target.probe_length;
3669
- };
3670
- if (was_soo) {
3671
- insert_slot(to_slot(resize_helper.old_soo_data()));
3672
- return;
3673
- } else {
3674
- auto* old_slots = static_cast<slot_type*>(resize_helper.old_slots());
3675
- size_t total_probe_length = 0;
3676
- for (size_t i = 0; i != resize_helper.old_capacity(); ++i) {
3677
- if (IsFull(resize_helper.old_ctrl()[i])) {
3678
- total_probe_length += insert_slot(old_slots + i);
3679
- }
3680
- }
3681
- common.infoz().RecordRehash(total_probe_length);
3682
- }
3683
- }
3684
- resize_helper.DeallocateOld<alignof(slot_type)>(CharAlloc(set->alloc_ref()),
3685
- sizeof(slot_type));
3686
- }
3687
-
3688
3143
  // Casting directly from e.g. char* to slot_type* can cause compilation errors
3689
3144
  // on objective-C. This function converts to void* first, avoiding the issue.
3690
3145
  static slot_type* to_slot(void* buf) { return static_cast<slot_type*>(buf); }
3691
3146
 
3692
3147
  // Requires that lhs does not have a full SOO slot.
3693
- static void move_common(bool that_is_full_soo, allocator_type& rhs_alloc,
3148
+ static void move_common(bool rhs_is_full_soo, CharAlloc& rhs_alloc,
3694
3149
  CommonFields& lhs, CommonFields&& rhs) {
3695
- if (PolicyTraits::transfer_uses_memcpy() || !that_is_full_soo) {
3150
+ if (PolicyTraits::transfer_uses_memcpy() || !rhs_is_full_soo) {
3696
3151
  lhs = std::move(rhs);
3697
3152
  } else {
3698
3153
  lhs.move_non_heap_or_soo_fields(rhs);
3699
- // TODO(b/303305702): add reentrancy guard.
3700
- PolicyTraits::transfer(&rhs_alloc, to_slot(lhs.soo_data()),
3701
- to_slot(rhs.soo_data()));
3154
+ rhs.RunWithReentrancyGuard([&] {
3155
+ lhs.RunWithReentrancyGuard([&] {
3156
+ PolicyTraits::transfer(&rhs_alloc, to_slot(lhs.soo_data()),
3157
+ to_slot(rhs.soo_data()));
3158
+ });
3159
+ });
3702
3160
  }
3703
3161
  }
3704
3162
 
@@ -3710,21 +3168,33 @@ class raw_hash_set {
3710
3168
  swap(common(), that.common());
3711
3169
  return;
3712
3170
  }
3713
- CommonFields tmp = CommonFields::CreateDefault<SooEnabled()>();
3171
+ CommonFields tmp = CommonFields(uninitialized_tag_t{});
3714
3172
  const bool that_is_full_soo = that.is_full_soo();
3715
- move_common(that_is_full_soo, that.alloc_ref(), tmp,
3173
+ move_common(that_is_full_soo, that.char_alloc_ref(), tmp,
3716
3174
  std::move(that.common()));
3717
- move_common(is_full_soo(), alloc_ref(), that.common(), std::move(common()));
3718
- move_common(that_is_full_soo, that.alloc_ref(), common(), std::move(tmp));
3719
- }
3720
-
3721
- void maybe_increment_generation_or_rehash_on_move() {
3722
- if (!SwisstableGenerationsEnabled() || capacity() == 0 || is_soo()) {
3175
+ move_common(is_full_soo(), char_alloc_ref(), that.common(),
3176
+ std::move(common()));
3177
+ move_common(that_is_full_soo, that.char_alloc_ref(), common(),
3178
+ std::move(tmp));
3179
+ }
3180
+
3181
+ void annotate_for_bug_detection_on_move(
3182
+ ABSL_ATTRIBUTE_UNUSED raw_hash_set& that) {
3183
+ // We only enable moved-from validation when generations are enabled (rather
3184
+ // than using NDEBUG) to avoid issues in which NDEBUG is enabled in some
3185
+ // translation units but not in others.
3186
+ if (SwisstableGenerationsEnabled()) {
3187
+ that.common().set_capacity(this == &that ? InvalidCapacity::kSelfMovedFrom
3188
+ : InvalidCapacity::kMovedFrom);
3189
+ }
3190
+ if (!SwisstableGenerationsEnabled() || capacity() == DefaultCapacity() ||
3191
+ capacity() > kAboveMaxValidCapacity) {
3723
3192
  return;
3724
3193
  }
3725
3194
  common().increment_generation();
3726
3195
  if (!empty() && common().should_rehash_for_bug_detection_on_move()) {
3727
- resize(capacity());
3196
+ ResizeAllocatedTableWithSeedChange(common(), GetPolicyFunctions(),
3197
+ capacity());
3728
3198
  }
3729
3199
  }
3730
3200
 
@@ -3733,15 +3203,14 @@ class raw_hash_set {
3733
3203
  // We don't bother checking for this/that aliasing. We just need to avoid
3734
3204
  // breaking the invariants in that case.
3735
3205
  destructor_impl();
3736
- move_common(that.is_full_soo(), that.alloc_ref(), common(),
3206
+ move_common(that.is_full_soo(), that.char_alloc_ref(), common(),
3737
3207
  std::move(that.common()));
3738
- // TODO(b/296061262): move instead of copying hash/eq/alloc.
3739
3208
  hash_ref() = that.hash_ref();
3740
3209
  eq_ref() = that.eq_ref();
3741
- CopyAlloc(alloc_ref(), that.alloc_ref(),
3210
+ CopyAlloc(char_alloc_ref(), that.char_alloc_ref(),
3742
3211
  std::integral_constant<bool, propagate_alloc>());
3743
3212
  that.common() = CommonFields::CreateDefault<SooEnabled()>();
3744
- maybe_increment_generation_or_rehash_on_move();
3213
+ annotate_for_bug_detection_on_move(that);
3745
3214
  return *this;
3746
3215
  }
3747
3216
 
@@ -3755,7 +3224,7 @@ class raw_hash_set {
3755
3224
  }
3756
3225
  if (!that.is_soo()) that.dealloc();
3757
3226
  that.common() = CommonFields::CreateDefault<SooEnabled()>();
3758
- maybe_increment_generation_or_rehash_on_move();
3227
+ annotate_for_bug_detection_on_move(that);
3759
3228
  return *this;
3760
3229
  }
3761
3230
 
@@ -3765,7 +3234,7 @@ class raw_hash_set {
3765
3234
  }
3766
3235
  raw_hash_set& move_assign(raw_hash_set&& that,
3767
3236
  std::false_type /*propagate_alloc*/) {
3768
- if (alloc_ref() == that.alloc_ref()) {
3237
+ if (char_alloc_ref() == that.char_alloc_ref()) {
3769
3238
  return assign_impl<false>(std::move(that));
3770
3239
  }
3771
3240
  // Aliasing can't happen here because allocs would compare equal above.
@@ -3774,7 +3243,6 @@ class raw_hash_set {
3774
3243
  // We can't take over that's memory so we need to move each element.
3775
3244
  // While moving elements, this should have that's hash/eq so copy hash/eq
3776
3245
  // before moving elements.
3777
- // TODO(b/296061262): move instead of copying hash/eq.
3778
3246
  hash_ref() = that.hash_ref();
3779
3247
  eq_ref() = that.eq_ref();
3780
3248
  return move_elements_allocs_unequal(std::move(that));
@@ -3782,35 +3250,42 @@ class raw_hash_set {
3782
3250
 
3783
3251
  template <class K>
3784
3252
  std::pair<iterator, bool> find_or_prepare_insert_soo(const K& key) {
3253
+ ctrl_t soo_slot_ctrl;
3785
3254
  if (empty()) {
3786
- const HashtablezInfoHandle infoz = try_sample_soo();
3787
- if (infoz.IsSampled()) {
3788
- resize_with_soo_infoz(infoz);
3789
- } else {
3255
+ if (!should_sample_soo()) {
3790
3256
  common().set_full_soo();
3791
3257
  return {soo_iterator(), true};
3792
3258
  }
3259
+ soo_slot_ctrl = ctrl_t::kEmpty;
3793
3260
  } else if (PolicyTraits::apply(EqualElement<K>{key, eq_ref()},
3794
3261
  PolicyTraits::element(soo_slot()))) {
3795
3262
  return {soo_iterator(), false};
3796
3263
  } else {
3797
- resize(NextCapacity(SooCapacity()));
3798
- }
3799
- const size_t index =
3800
- PrepareInsertAfterSoo(hash_ref()(key), sizeof(slot_type), common());
3264
+ soo_slot_ctrl = static_cast<ctrl_t>(H2(hash_of(soo_slot())));
3265
+ }
3266
+ constexpr bool kUseMemcpy =
3267
+ PolicyTraits::transfer_uses_memcpy() && SooEnabled();
3268
+ size_t index = GrowSooTableToNextCapacityAndPrepareInsert<
3269
+ kUseMemcpy ? OptimalMemcpySizeForSooSlotTransfer(sizeof(slot_type)) : 0,
3270
+ kUseMemcpy>(common(), GetPolicyFunctions(), hash_of(key),
3271
+ soo_slot_ctrl);
3801
3272
  return {iterator_at(index), true};
3802
3273
  }
3803
3274
 
3804
3275
  template <class K>
3805
3276
  std::pair<iterator, bool> find_or_prepare_insert_non_soo(const K& key) {
3806
- assert(!is_soo());
3277
+ ABSL_SWISSTABLE_ASSERT(!is_soo());
3807
3278
  prefetch_heap_block();
3808
- auto hash = hash_ref()(key);
3279
+ const size_t hash = hash_of(key);
3809
3280
  auto seq = probe(common(), hash);
3281
+ const h2_t h2 = H2(hash);
3810
3282
  const ctrl_t* ctrl = control();
3811
3283
  while (true) {
3284
+ #ifndef ABSL_HAVE_MEMORY_SANITIZER
3285
+ absl::PrefetchToLocalCache(slot_array() + seq.offset());
3286
+ #endif
3812
3287
  Group g{ctrl + seq.offset()};
3813
- for (uint32_t i : g.Match(H2(hash))) {
3288
+ for (uint32_t i : g.Match(h2)) {
3814
3289
  if (ABSL_PREDICT_TRUE(PolicyTraits::apply(
3815
3290
  EqualElement<K>{key, eq_ref()},
3816
3291
  PolicyTraits::element(slot_array() + seq.offset(i)))))
@@ -3818,50 +3293,86 @@ class raw_hash_set {
3818
3293
  }
3819
3294
  auto mask_empty = g.MaskEmpty();
3820
3295
  if (ABSL_PREDICT_TRUE(mask_empty)) {
3821
- size_t target = seq.offset(
3822
- GetInsertionOffset(mask_empty, capacity(), hash, control()));
3823
- return {iterator_at(PrepareInsertNonSoo(common(), hash,
3824
- FindInfo{target, seq.index()},
3825
- GetPolicyFunctions())),
3296
+ size_t target = seq.offset(mask_empty.LowestBitSet());
3297
+ return {iterator_at(PrepareInsertNonSoo(common(), GetPolicyFunctions(),
3298
+ hash,
3299
+ FindInfo{target, seq.index()})),
3826
3300
  true};
3827
3301
  }
3828
3302
  seq.next();
3829
- assert(seq.index() <= capacity() && "full table!");
3303
+ ABSL_SWISSTABLE_ASSERT(seq.index() <= capacity() && "full table!");
3830
3304
  }
3831
3305
  }
3832
3306
 
3833
3307
  protected:
3308
+ // Asserts for correctness that we run on find/find_or_prepare_insert.
3309
+ template <class K>
3310
+ void AssertOnFind(ABSL_ATTRIBUTE_UNUSED const K& key) {
3311
+ AssertHashEqConsistent(key);
3312
+ AssertNotDebugCapacity();
3313
+ }
3314
+
3315
+ // Asserts that the capacity is not a sentinel invalid value.
3316
+ void AssertNotDebugCapacity() const {
3317
+ #ifdef NDEBUG
3318
+ if (!SwisstableGenerationsEnabled()) {
3319
+ return;
3320
+ }
3321
+ #endif
3322
+ if (ABSL_PREDICT_TRUE(capacity() <
3323
+ InvalidCapacity::kAboveMaxValidCapacity)) {
3324
+ return;
3325
+ }
3326
+ assert(capacity() != InvalidCapacity::kReentrance &&
3327
+ "Reentrant container access during element construction/destruction "
3328
+ "is not allowed.");
3329
+ if constexpr (SwisstableAssertAccessToDestroyedTable()) {
3330
+ if (capacity() == InvalidCapacity::kDestroyed) {
3331
+ ABSL_RAW_LOG(FATAL, "Use of destroyed hash table.");
3332
+ }
3333
+ }
3334
+ if (SwisstableGenerationsEnabled() &&
3335
+ ABSL_PREDICT_FALSE(capacity() >= InvalidCapacity::kMovedFrom)) {
3336
+ if (capacity() == InvalidCapacity::kSelfMovedFrom) {
3337
+ // If this log triggers, then a hash table was move-assigned to itself
3338
+ // and then used again later without being reinitialized.
3339
+ ABSL_RAW_LOG(FATAL, "Use of self-move-assigned hash table.");
3340
+ }
3341
+ ABSL_RAW_LOG(FATAL, "Use of moved-from hash table.");
3342
+ }
3343
+ }
3344
+
3834
3345
  // Asserts that hash and equal functors provided by the user are consistent,
3835
3346
  // meaning that `eq(k1, k2)` implies `hash(k1)==hash(k2)`.
3836
3347
  template <class K>
3837
- void AssertHashEqConsistent(ABSL_ATTRIBUTE_UNUSED const K& key) {
3838
- #ifndef NDEBUG
3348
+ void AssertHashEqConsistent(const K& key) {
3349
+ #ifdef NDEBUG
3350
+ return;
3351
+ #endif
3352
+ // If the hash/eq functors are known to be consistent, then skip validation.
3353
+ if (std::is_same<hasher, absl::container_internal::StringHash>::value &&
3354
+ std::is_same<key_equal, absl::container_internal::StringEq>::value) {
3355
+ return;
3356
+ }
3357
+ if (std::is_scalar<key_type>::value &&
3358
+ std::is_same<hasher, absl::Hash<key_type>>::value &&
3359
+ std::is_same<key_equal, std::equal_to<key_type>>::value) {
3360
+ return;
3361
+ }
3839
3362
  if (empty()) return;
3840
3363
 
3841
- const size_t hash_of_arg = hash_ref()(key);
3842
- const auto assert_consistent = [&](const ctrl_t*, slot_type* slot) {
3843
- const value_type& element = PolicyTraits::element(slot);
3364
+ const size_t hash_of_arg = hash_of(key);
3365
+ const auto assert_consistent = [&](const ctrl_t*, void* slot) {
3366
+ const value_type& element =
3367
+ PolicyTraits::element(static_cast<slot_type*>(slot));
3844
3368
  const bool is_key_equal =
3845
3369
  PolicyTraits::apply(EqualElement<K>{key, eq_ref()}, element);
3846
3370
  if (!is_key_equal) return;
3847
3371
 
3848
3372
  const size_t hash_of_slot =
3849
3373
  PolicyTraits::apply(HashElement{hash_ref()}, element);
3850
- const bool is_hash_equal = hash_of_arg == hash_of_slot;
3851
- if (!is_hash_equal) {
3852
- // In this case, we're going to crash. Do a couple of other checks for
3853
- // idempotence issues. Recalculating hash/eq here is also convenient for
3854
- // debugging with gdb/lldb.
3855
- const size_t once_more_hash_arg = hash_ref()(key);
3856
- assert(hash_of_arg == once_more_hash_arg && "hash is not idempotent.");
3857
- const size_t once_more_hash_slot =
3858
- PolicyTraits::apply(HashElement{hash_ref()}, element);
3859
- assert(hash_of_slot == once_more_hash_slot &&
3860
- "hash is not idempotent.");
3861
- const bool once_more_eq =
3862
- PolicyTraits::apply(EqualElement<K>{key, eq_ref()}, element);
3863
- assert(is_key_equal == once_more_eq && "equality is not idempotent.");
3864
- }
3374
+ ABSL_ATTRIBUTE_UNUSED const bool is_hash_equal =
3375
+ hash_of_arg == hash_of_slot;
3865
3376
  assert((!is_key_equal || is_hash_equal) &&
3866
3377
  "eq(k1, k2) must imply that hash(k1) == hash(k2). "
3867
3378
  "hash/eq functors are inconsistent.");
@@ -3873,8 +3384,7 @@ class raw_hash_set {
3873
3384
  }
3874
3385
  // We only do validation for small tables so that it's constant time.
3875
3386
  if (capacity() > 16) return;
3876
- IterateOverFullSlots(common(), slot_array(), assert_consistent);
3877
- #endif
3387
+ IterateOverFullSlots(common(), sizeof(slot_type), assert_consistent);
3878
3388
  }
3879
3389
 
3880
3390
  // Attempts to find `key` in the table; if it isn't found, returns an iterator
@@ -3882,7 +3392,7 @@ class raw_hash_set {
3882
3392
  // `key`'s H2. Returns a bool indicating whether an insertion can take place.
3883
3393
  template <class K>
3884
3394
  std::pair<iterator, bool> find_or_prepare_insert(const K& key) {
3885
- AssertHashEqConsistent(key);
3395
+ AssertOnFind(key);
3886
3396
  if (is_soo()) return find_or_prepare_insert_soo(key);
3887
3397
  return find_or_prepare_insert_non_soo(key);
3888
3398
  }
@@ -3899,7 +3409,10 @@ class raw_hash_set {
3899
3409
  void emplace_at(iterator iter, Args&&... args) {
3900
3410
  construct(iter.slot(), std::forward<Args>(args)...);
3901
3411
 
3902
- assert(PolicyTraits::apply(FindElement{*this}, *iter) == iter &&
3412
+ // When capacity is 1, find calls find_small and if size is 0, then it will
3413
+ // return an end iterator. This can happen in the raw_hash_set copy ctor.
3414
+ assert((capacity() == 1 ||
3415
+ PolicyTraits::apply(FindElement{*this}, *iter) == iter) &&
3903
3416
  "constructed value does not match the lookup key");
3904
3417
  }
3905
3418
 
@@ -3926,16 +3439,16 @@ class raw_hash_set {
3926
3439
  //
3927
3440
  // See `CapacityToGrowth()`.
3928
3441
  size_t growth_left() const {
3929
- assert(!is_soo());
3442
+ ABSL_SWISSTABLE_ASSERT(!is_soo());
3930
3443
  return common().growth_left();
3931
3444
  }
3932
3445
 
3933
3446
  GrowthInfo& growth_info() {
3934
- assert(!is_soo());
3447
+ ABSL_SWISSTABLE_ASSERT(!is_soo());
3935
3448
  return common().growth_info();
3936
3449
  }
3937
3450
  GrowthInfo growth_info() const {
3938
- assert(!is_soo());
3451
+ ABSL_SWISSTABLE_ASSERT(!is_soo());
3939
3452
  return common().growth_info();
3940
3453
  }
3941
3454
 
@@ -3943,7 +3456,7 @@ class raw_hash_set {
3943
3456
  // cache misses. This is intended to overlap with execution of calculating the
3944
3457
  // hash for a key.
3945
3458
  void prefetch_heap_block() const {
3946
- assert(!is_soo());
3459
+ ABSL_SWISSTABLE_ASSERT(!is_soo());
3947
3460
  #if ABSL_HAVE_BUILTIN(__builtin_prefetch) || defined(__GNUC__)
3948
3461
  __builtin_prefetch(control(), 0, 1);
3949
3462
  #endif
@@ -3953,19 +3466,21 @@ class raw_hash_set {
3953
3466
  const CommonFields& common() const { return settings_.template get<0>(); }
3954
3467
 
3955
3468
  ctrl_t* control() const {
3956
- assert(!is_soo());
3469
+ ABSL_SWISSTABLE_ASSERT(!is_soo());
3957
3470
  return common().control();
3958
3471
  }
3959
3472
  slot_type* slot_array() const {
3960
- assert(!is_soo());
3473
+ ABSL_SWISSTABLE_ASSERT(!is_soo());
3961
3474
  return static_cast<slot_type*>(common().slot_array());
3962
3475
  }
3963
3476
  slot_type* soo_slot() {
3964
- assert(is_soo());
3965
- return static_cast<slot_type*>(common().soo_data());
3477
+ ABSL_SWISSTABLE_ASSERT(is_soo());
3478
+ ABSL_SWISSTABLE_IGNORE_UNINITIALIZED_RETURN(
3479
+ static_cast<slot_type*>(common().soo_data()));
3966
3480
  }
3967
3481
  const slot_type* soo_slot() const {
3968
- return const_cast<raw_hash_set*>(this)->soo_slot();
3482
+ ABSL_SWISSTABLE_IGNORE_UNINITIALIZED_RETURN(
3483
+ const_cast<raw_hash_set*>(this)->soo_slot());
3969
3484
  }
3970
3485
  iterator soo_iterator() {
3971
3486
  return {SooControl(), soo_slot(), common().generation_ptr()};
@@ -3973,8 +3488,22 @@ class raw_hash_set {
3973
3488
  const_iterator soo_iterator() const {
3974
3489
  return const_cast<raw_hash_set*>(this)->soo_iterator();
3975
3490
  }
3491
+ slot_type* single_slot() {
3492
+ ABSL_SWISSTABLE_ASSERT(capacity() <= 1);
3493
+ return SooEnabled() ? soo_slot() : slot_array();
3494
+ }
3495
+ const slot_type* single_slot() const {
3496
+ return const_cast<raw_hash_set*>(this)->single_slot();
3497
+ }
3498
+ iterator single_iterator() {
3499
+ return {SooEnabled() ? SooControl() : control(), single_slot(),
3500
+ common().generation_ptr()};
3501
+ }
3502
+ const_iterator single_iterator() const {
3503
+ return const_cast<raw_hash_set*>(this)->single_iterator();
3504
+ }
3976
3505
  HashtablezInfoHandle infoz() {
3977
- assert(!is_soo());
3506
+ ABSL_SWISSTABLE_ASSERT(!is_soo());
3978
3507
  return common().infoz();
3979
3508
  }
3980
3509
 
@@ -3982,49 +3511,118 @@ class raw_hash_set {
3982
3511
  const hasher& hash_ref() const { return settings_.template get<1>(); }
3983
3512
  key_equal& eq_ref() { return settings_.template get<2>(); }
3984
3513
  const key_equal& eq_ref() const { return settings_.template get<2>(); }
3985
- allocator_type& alloc_ref() { return settings_.template get<3>(); }
3986
- const allocator_type& alloc_ref() const {
3514
+ CharAlloc& char_alloc_ref() { return settings_.template get<3>(); }
3515
+ const CharAlloc& char_alloc_ref() const {
3987
3516
  return settings_.template get<3>();
3988
3517
  }
3989
3518
 
3990
- static const void* get_hash_ref_fn(const CommonFields& common) {
3991
- auto* h = reinterpret_cast<const raw_hash_set*>(&common);
3992
- return &h->hash_ref();
3519
+ static void* get_char_alloc_ref_fn(CommonFields& common) {
3520
+ auto* h = reinterpret_cast<raw_hash_set*>(&common);
3521
+ return &h->char_alloc_ref();
3522
+ }
3523
+ static void* get_hash_ref_fn(CommonFields& common) {
3524
+ auto* h = reinterpret_cast<raw_hash_set*>(&common);
3525
+ // TODO(b/397453582): Remove support for const hasher.
3526
+ return const_cast<std::remove_const_t<hasher>*>(&h->hash_ref());
3993
3527
  }
3994
- static void transfer_slot_fn(void* set, void* dst, void* src) {
3528
+ static void transfer_n_slots_fn(void* set, void* dst, void* src,
3529
+ size_t count) {
3530
+ auto* src_slot = to_slot(src);
3531
+ auto* dst_slot = to_slot(dst);
3532
+
3995
3533
  auto* h = static_cast<raw_hash_set*>(set);
3996
- h->transfer(static_cast<slot_type*>(dst), static_cast<slot_type*>(src));
3534
+ for (; count > 0; --count, ++src_slot, ++dst_slot) {
3535
+ h->transfer(dst_slot, src_slot);
3536
+ }
3997
3537
  }
3998
- // Note: dealloc_fn will only be used if we have a non-standard allocator.
3999
- static void dealloc_fn(CommonFields& common, const PolicyFunctions&) {
4000
- auto* set = reinterpret_cast<raw_hash_set*>(&common);
4001
3538
 
4002
- // Unpoison before returning the memory to the allocator.
4003
- SanitizerUnpoisonMemoryRegion(common.slot_array(),
4004
- sizeof(slot_type) * common.capacity());
3539
+ // TODO(b/382423690): Try to type erase entire function or at least type erase
3540
+ // by GetKey + Hash for memcpyable types.
3541
+ // TODO(b/382423690): Try to type erase for big slots: sizeof(slot_type) > 16.
3542
+ static void transfer_unprobed_elements_to_next_capacity_fn(
3543
+ CommonFields& common, const ctrl_t* old_ctrl, void* old_slots,
3544
+ void* probed_storage,
3545
+ void (*encode_probed_element)(void* probed_storage, h2_t h2,
3546
+ size_t source_offset, size_t h1)) {
3547
+ const size_t new_capacity = common.capacity();
3548
+ const size_t old_capacity = PreviousCapacity(new_capacity);
3549
+ ABSL_ASSUME(old_capacity + 1 >= Group::kWidth);
3550
+ ABSL_ASSUME((old_capacity + 1) % Group::kWidth == 0);
4005
3551
 
4006
- common.infoz().Unregister();
4007
- Deallocate<BackingArrayAlignment(alignof(slot_type))>(
4008
- &set->alloc_ref(), common.backing_array_start(),
4009
- common.alloc_size(sizeof(slot_type), alignof(slot_type)));
3552
+ auto* set = reinterpret_cast<raw_hash_set*>(&common);
3553
+ slot_type* old_slots_ptr = to_slot(old_slots);
3554
+ ctrl_t* new_ctrl = common.control();
3555
+ slot_type* new_slots = set->slot_array();
3556
+
3557
+ const PerTableSeed seed = common.seed();
3558
+
3559
+ for (size_t group_index = 0; group_index < old_capacity;
3560
+ group_index += Group::kWidth) {
3561
+ GroupFullEmptyOrDeleted old_g(old_ctrl + group_index);
3562
+ std::memset(new_ctrl + group_index, static_cast<int8_t>(ctrl_t::kEmpty),
3563
+ Group::kWidth);
3564
+ std::memset(new_ctrl + group_index + old_capacity + 1,
3565
+ static_cast<int8_t>(ctrl_t::kEmpty), Group::kWidth);
3566
+ // TODO(b/382423690): try to type erase everything outside of the loop.
3567
+ // We will share a lot of code in expense of one function call per group.
3568
+ for (auto in_fixed_group_index : old_g.MaskFull()) {
3569
+ size_t old_index = group_index + in_fixed_group_index;
3570
+ slot_type* old_slot = old_slots_ptr + old_index;
3571
+ // TODO(b/382423690): try to avoid entire hash calculation since we need
3572
+ // only one new bit of h1.
3573
+ size_t hash = set->hash_of(old_slot);
3574
+ size_t h1 = H1(hash, seed);
3575
+ h2_t h2 = H2(hash);
3576
+ size_t new_index = TryFindNewIndexWithoutProbing(
3577
+ h1, old_index, old_capacity, new_ctrl, new_capacity);
3578
+ // Note that encode_probed_element is allowed to use old_ctrl buffer
3579
+ // till and included the old_index.
3580
+ if (ABSL_PREDICT_FALSE(new_index == kProbedElementIndexSentinel)) {
3581
+ encode_probed_element(probed_storage, h2, old_index, h1);
3582
+ continue;
3583
+ }
3584
+ ABSL_SWISSTABLE_ASSERT((new_index & old_capacity) <= old_index);
3585
+ ABSL_SWISSTABLE_ASSERT(IsEmpty(new_ctrl[new_index]));
3586
+ new_ctrl[new_index] = static_cast<ctrl_t>(h2);
3587
+ auto* new_slot = new_slots + new_index;
3588
+ SanitizerUnpoisonMemoryRegion(new_slot, sizeof(slot_type));
3589
+ set->transfer(new_slot, old_slot);
3590
+ SanitizerPoisonMemoryRegion(old_slot, sizeof(slot_type));
3591
+ }
3592
+ }
4010
3593
  }
4011
3594
 
4012
3595
  static const PolicyFunctions& GetPolicyFunctions() {
3596
+ static_assert(sizeof(slot_type) <= (std::numeric_limits<uint32_t>::max)(),
3597
+ "Slot size is too large. Use std::unique_ptr for value type "
3598
+ "or use absl::node_hash_{map,set}.");
3599
+ static_assert(alignof(slot_type) <=
3600
+ size_t{(std::numeric_limits<uint16_t>::max)()});
3601
+ static_assert(sizeof(key_type) <=
3602
+ size_t{(std::numeric_limits<uint32_t>::max)()});
3603
+ static_assert(sizeof(value_type) <=
3604
+ size_t{(std::numeric_limits<uint32_t>::max)()});
3605
+ static constexpr size_t kBackingArrayAlignment =
3606
+ BackingArrayAlignment(alignof(slot_type));
4013
3607
  static constexpr PolicyFunctions value = {
4014
- sizeof(slot_type),
3608
+ static_cast<uint32_t>(sizeof(key_type)),
3609
+ static_cast<uint32_t>(sizeof(value_type)),
3610
+ static_cast<uint32_t>(sizeof(slot_type)),
3611
+ static_cast<uint16_t>(alignof(slot_type)), SooEnabled(),
3612
+ ShouldSampleHashtablezInfoForAlloc<CharAlloc>(),
4015
3613
  // TODO(b/328722020): try to type erase
4016
3614
  // for standard layout and alignof(Hash) <= alignof(CommonFields).
4017
- std::is_empty<hasher>::value ? &GetHashRefForEmptyHasher
4018
- : &raw_hash_set::get_hash_ref_fn,
3615
+ std::is_empty_v<hasher> ? &GetRefForEmptyClass
3616
+ : &raw_hash_set::get_hash_ref_fn,
4019
3617
  PolicyTraits::template get_hash_slot_fn<hasher>(),
4020
3618
  PolicyTraits::transfer_uses_memcpy()
4021
- ? TransferRelocatable<sizeof(slot_type)>
4022
- : &raw_hash_set::transfer_slot_fn,
4023
- (std::is_same<SlotAlloc, std::allocator<slot_type>>::value
4024
- ? &DeallocateStandard<alignof(slot_type)>
4025
- : &raw_hash_set::dealloc_fn),
4026
- &raw_hash_set::resize_impl,
4027
- };
3619
+ ? TransferNRelocatable<sizeof(slot_type)>
3620
+ : &raw_hash_set::transfer_n_slots_fn,
3621
+ std::is_empty_v<Alloc> ? &GetRefForEmptyClass
3622
+ : &raw_hash_set::get_char_alloc_ref_fn,
3623
+ &AllocateBackingArray<kBackingArrayAlignment, CharAlloc>,
3624
+ &DeallocateBackingArray<kBackingArrayAlignment, CharAlloc>,
3625
+ &raw_hash_set::transfer_unprobed_elements_to_next_capacity_fn};
4028
3626
  return value;
4029
3627
  }
4030
3628
 
@@ -4032,9 +3630,9 @@ class raw_hash_set {
4032
3630
  // CompressedTuple will ensure that sizeof is not affected by any of the empty
4033
3631
  // fields that occur after CommonFields.
4034
3632
  absl::container_internal::CompressedTuple<CommonFields, hasher, key_equal,
4035
- allocator_type>
3633
+ CharAlloc>
4036
3634
  settings_{CommonFields::CreateDefault<SooEnabled()>(), hasher{},
4037
- key_equal{}, allocator_type{}};
3635
+ key_equal{}, CharAlloc{}};
4038
3636
  };
4039
3637
 
4040
3638
  // Friend access for free functions in raw_hash_set.h.
@@ -4047,7 +3645,8 @@ struct HashtableFreeFunctionsAccess {
4047
3645
  if (c->is_soo()) {
4048
3646
  auto it = c->soo_iterator();
4049
3647
  if (!pred(*it)) {
4050
- assert(c->size() == 1 && "hash table was modified unexpectedly");
3648
+ ABSL_SWISSTABLE_ASSERT(c->size() == 1 &&
3649
+ "hash table was modified unexpectedly");
4051
3650
  return 0;
4052
3651
  }
4053
3652
  c->destroy(it.slot());
@@ -4056,8 +3655,11 @@ struct HashtableFreeFunctionsAccess {
4056
3655
  }
4057
3656
  ABSL_ATTRIBUTE_UNUSED const size_t original_size_for_assert = c->size();
4058
3657
  size_t num_deleted = 0;
3658
+ using SlotType = typename Set::slot_type;
4059
3659
  IterateOverFullSlots(
4060
- c->common(), c->slot_array(), [&](const ctrl_t* ctrl, auto* slot) {
3660
+ c->common(), sizeof(SlotType),
3661
+ [&](const ctrl_t* ctrl, void* slot_void) {
3662
+ auto* slot = static_cast<SlotType*>(slot_void);
4061
3663
  if (pred(Set::PolicyTraits::element(slot))) {
4062
3664
  c->destroy(slot);
4063
3665
  EraseMetaOnly(c->common(), static_cast<size_t>(ctrl - c->control()),
@@ -4067,8 +3669,9 @@ struct HashtableFreeFunctionsAccess {
4067
3669
  });
4068
3670
  // NOTE: IterateOverFullSlots allow removal of the current element, so we
4069
3671
  // verify the size additionally here.
4070
- assert(original_size_for_assert - num_deleted == c->size() &&
4071
- "hash table was modified unexpectedly");
3672
+ ABSL_SWISSTABLE_ASSERT(original_size_for_assert - num_deleted ==
3673
+ c->size() &&
3674
+ "hash table was modified unexpectedly");
4072
3675
  return num_deleted;
4073
3676
  }
4074
3677
 
@@ -4081,10 +3684,12 @@ struct HashtableFreeFunctionsAccess {
4081
3684
  cb(*c->soo_iterator());
4082
3685
  return;
4083
3686
  }
3687
+ using SlotType = typename Set::slot_type;
4084
3688
  using ElementTypeWithConstness = decltype(*c->begin());
4085
3689
  IterateOverFullSlots(
4086
- c->common(), c->slot_array(), [&cb](const ctrl_t*, auto* slot) {
4087
- ElementTypeWithConstness& element = Set::PolicyTraits::element(slot);
3690
+ c->common(), sizeof(SlotType), [&cb](const ctrl_t*, void* slot) {
3691
+ ElementTypeWithConstness& element =
3692
+ Set::PolicyTraits::element(static_cast<SlotType*>(slot));
4088
3693
  cb(element);
4089
3694
  });
4090
3695
  }
@@ -4117,12 +3722,13 @@ struct HashtableDebugAccess<Set, absl::void_t<typename Set::raw_hash_set>> {
4117
3722
  const typename Set::key_type& key) {
4118
3723
  if (set.is_soo()) return 0;
4119
3724
  size_t num_probes = 0;
4120
- size_t hash = set.hash_ref()(key);
3725
+ const size_t hash = set.hash_of(key);
4121
3726
  auto seq = probe(set.common(), hash);
3727
+ const h2_t h2 = H2(hash);
4122
3728
  const ctrl_t* ctrl = set.control();
4123
3729
  while (true) {
4124
3730
  container_internal::Group g{ctrl + seq.offset()};
4125
- for (uint32_t i : g.Match(container_internal::H2(hash))) {
3731
+ for (uint32_t i : g.Match(h2)) {
4126
3732
  if (Traits::apply(
4127
3733
  typename Set::template EqualElement<typename Set::key_type>{
4128
3734
  key, set.eq_ref()},
@@ -4155,6 +3761,22 @@ struct HashtableDebugAccess<Set, absl::void_t<typename Set::raw_hash_set>> {
4155
3761
  };
4156
3762
 
4157
3763
  } // namespace hashtable_debug_internal
3764
+
3765
+ // Extern template instantiations reduce binary size and linker input size.
3766
+ // Function definition is in raw_hash_set.cc.
3767
+ extern template size_t GrowSooTableToNextCapacityAndPrepareInsert<0, false>(
3768
+ CommonFields&, const PolicyFunctions&, size_t, ctrl_t);
3769
+ extern template size_t GrowSooTableToNextCapacityAndPrepareInsert<1, true>(
3770
+ CommonFields&, const PolicyFunctions&, size_t, ctrl_t);
3771
+ extern template size_t GrowSooTableToNextCapacityAndPrepareInsert<4, true>(
3772
+ CommonFields&, const PolicyFunctions&, size_t, ctrl_t);
3773
+ extern template size_t GrowSooTableToNextCapacityAndPrepareInsert<8, true>(
3774
+ CommonFields&, const PolicyFunctions&, size_t, ctrl_t);
3775
+ #if UINTPTR_MAX == UINT64_MAX
3776
+ extern template size_t GrowSooTableToNextCapacityAndPrepareInsert<16, true>(
3777
+ CommonFields&, const PolicyFunctions&, size_t, ctrl_t);
3778
+ #endif
3779
+
4158
3780
  } // namespace container_internal
4159
3781
  ABSL_NAMESPACE_END
4160
3782
  } // namespace absl
@@ -4162,5 +3784,6 @@ ABSL_NAMESPACE_END
4162
3784
  #undef ABSL_SWISSTABLE_ENABLE_GENERATIONS
4163
3785
  #undef ABSL_SWISSTABLE_IGNORE_UNINITIALIZED
4164
3786
  #undef ABSL_SWISSTABLE_IGNORE_UNINITIALIZED_RETURN
3787
+ #undef ABSL_SWISSTABLE_ASSERT
4165
3788
 
4166
3789
  #endif // ABSL_CONTAINER_INTERNAL_RAW_HASH_SET_H_