grpc 1.52.0 → 1.53.0.pre2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of grpc might be problematic. Click here for more details.

Files changed (892) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +50 -5
  3. data/include/grpc/event_engine/event_engine.h +24 -2
  4. data/include/grpc/event_engine/slice_buffer.h +13 -1
  5. data/include/grpc/impl/grpc_types.h +3 -0
  6. data/include/grpc/support/time.h +6 -4
  7. data/src/core/ext/filters/backend_metrics/backend_metric_filter.cc +148 -0
  8. data/src/core/ext/filters/backend_metrics/backend_metric_filter.h +52 -0
  9. data/src/core/ext/filters/backend_metrics/backend_metric_provider.h +29 -0
  10. data/src/core/ext/filters/channel_idle/channel_idle_filter.h +3 -3
  11. data/src/core/ext/filters/channel_idle/idle_filter_state.h +3 -3
  12. data/src/core/ext/filters/client_channel/backend_metric.h +3 -3
  13. data/src/core/ext/filters/client_channel/backup_poller.h +3 -3
  14. data/src/core/ext/filters/client_channel/channel_connectivity.cc +1 -1
  15. data/src/core/ext/filters/client_channel/client_channel.cc +29 -33
  16. data/src/core/ext/filters/client_channel/client_channel.h +3 -3
  17. data/src/core/ext/filters/client_channel/client_channel_channelz.h +3 -3
  18. data/src/core/ext/filters/client_channel/client_channel_factory.h +3 -3
  19. data/src/core/ext/filters/client_channel/client_channel_service_config.h +3 -3
  20. data/src/core/ext/filters/client_channel/config_selector.h +3 -3
  21. data/src/core/ext/filters/client_channel/connector.h +8 -4
  22. data/src/core/ext/filters/client_channel/dynamic_filters.h +3 -3
  23. data/src/core/ext/filters/client_channel/global_subchannel_pool.h +3 -3
  24. data/src/core/ext/filters/client_channel/health/health_check_client.h +3 -3
  25. data/src/core/ext/filters/client_channel/http_proxy.h +3 -3
  26. data/src/core/ext/filters/client_channel/lb_call_state_internal.h +3 -3
  27. data/src/core/ext/filters/client_channel/lb_policy/address_filtering.h +3 -3
  28. data/src/core/ext/filters/client_channel/lb_policy/backend_metric_data.h +3 -3
  29. data/src/core/ext/filters/client_channel/lb_policy/child_policy_handler.h +3 -3
  30. data/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc +14 -7
  31. data/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h +3 -3
  32. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +1 -0
  33. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h +3 -3
  34. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.h +3 -3
  35. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h +3 -3
  36. data/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h +3 -3
  37. data/src/core/ext/filters/client_channel/lb_policy/oob_backend_metric.cc +1 -78
  38. data/src/core/ext/filters/client_channel/lb_policy/oob_backend_metric.h +3 -3
  39. data/src/core/ext/filters/client_channel/lb_policy/oob_backend_metric_internal.h +117 -0
  40. data/src/core/ext/filters/client_channel/lb_policy/outlier_detection/outlier_detection.h +3 -3
  41. data/src/core/ext/filters/client_channel/lb_policy/ring_hash/ring_hash.h +3 -3
  42. data/src/core/ext/filters/client_channel/lb_policy/rls/rls.cc +1 -0
  43. data/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +3 -3
  44. data/src/core/ext/filters/client_channel/lb_policy/weighted_round_robin/static_stride_scheduler.cc +128 -0
  45. data/src/core/ext/filters/client_channel/lb_policy/weighted_round_robin/static_stride_scheduler.h +71 -0
  46. data/src/core/ext/filters/client_channel/lb_policy/weighted_round_robin/weighted_round_robin.cc +972 -0
  47. data/src/core/ext/filters/client_channel/lb_policy/xds/cds.cc +3 -6
  48. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_attributes.h +3 -3
  49. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_args.h +3 -3
  50. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_resolver.cc +12 -7
  51. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_override_host.cc +275 -107
  52. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_override_host.h +10 -3
  53. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_wrr_locality.cc +5 -0
  54. data/src/core/ext/filters/client_channel/local_subchannel_pool.h +3 -3
  55. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h +3 -3
  56. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc +6 -1
  57. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc +1 -2
  58. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h +3 -3
  59. data/src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h +3 -3
  60. data/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h +3 -3
  61. data/src/core/ext/filters/client_channel/resolver/google_c2p/google_c2p_resolver.cc +1 -0
  62. data/src/core/ext/filters/client_channel/resolver/polling_resolver.h +3 -3
  63. data/src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc +3 -7
  64. data/src/core/ext/filters/client_channel/resolver/xds/xds_resolver.h +3 -3
  65. data/src/core/ext/filters/client_channel/retry_filter.cc +10 -13
  66. data/src/core/ext/filters/client_channel/retry_filter.h +3 -3
  67. data/src/core/ext/filters/client_channel/retry_service_config.h +3 -3
  68. data/src/core/ext/filters/client_channel/retry_throttle.h +3 -3
  69. data/src/core/ext/filters/client_channel/service_config_channel_arg_filter.cc +4 -4
  70. data/src/core/ext/filters/client_channel/subchannel.cc +5 -1
  71. data/src/core/ext/filters/client_channel/subchannel.h +3 -3
  72. data/src/core/ext/filters/client_channel/subchannel_interface_internal.h +3 -3
  73. data/src/core/ext/filters/client_channel/subchannel_pool_interface.h +3 -3
  74. data/src/core/ext/filters/client_channel/subchannel_stream_client.h +3 -3
  75. data/src/core/ext/filters/deadline/deadline_filter.cc +40 -48
  76. data/src/core/ext/filters/deadline/deadline_filter.h +6 -10
  77. data/src/core/ext/filters/fault_injection/fault_injection_filter.h +3 -3
  78. data/src/core/ext/filters/fault_injection/fault_injection_service_config_parser.h +3 -3
  79. data/src/core/ext/filters/http/client/http_client_filter.cc +26 -21
  80. data/src/core/ext/filters/http/client/http_client_filter.h +3 -3
  81. data/src/core/ext/filters/http/client_authority_filter.h +3 -3
  82. data/src/core/ext/filters/http/message_compress/compression_filter.cc +109 -117
  83. data/src/core/ext/filters/http/message_compress/compression_filter.h +17 -10
  84. data/src/core/ext/filters/http/server/http_server_filter.cc +25 -24
  85. data/src/core/ext/filters/http/server/http_server_filter.h +3 -3
  86. data/src/core/ext/filters/message_size/message_size_filter.cc +2 -1
  87. data/src/core/ext/filters/message_size/message_size_filter.h +3 -3
  88. data/src/core/ext/filters/rbac/rbac_filter.cc +4 -3
  89. data/src/core/ext/filters/rbac/rbac_filter.h +3 -3
  90. data/src/core/ext/filters/rbac/rbac_service_config_parser.h +3 -3
  91. data/src/core/ext/filters/server_config_selector/server_config_selector.h +3 -3
  92. data/src/core/ext/filters/server_config_selector/server_config_selector_filter.h +3 -3
  93. data/src/core/ext/filters/stateful_session/stateful_session_filter.cc +27 -37
  94. data/src/core/ext/filters/stateful_session/stateful_session_filter.h +5 -5
  95. data/src/core/ext/filters/stateful_session/stateful_session_service_config_parser.h +3 -3
  96. data/src/core/ext/transport/chttp2/alpn/alpn.h +3 -3
  97. data/src/core/ext/transport/chttp2/client/chttp2_connector.cc +2 -7
  98. data/src/core/ext/transport/chttp2/client/chttp2_connector.h +3 -3
  99. data/src/core/ext/transport/chttp2/server/chttp2_server.cc +1 -0
  100. data/src/core/ext/transport/chttp2/server/chttp2_server.h +3 -3
  101. data/src/core/ext/transport/chttp2/transport/bin_decoder.h +3 -3
  102. data/src/core/ext/transport/chttp2/transport/bin_encoder.h +3 -3
  103. data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +195 -111
  104. data/src/core/ext/transport/chttp2/transport/chttp2_transport.h +3 -3
  105. data/src/core/ext/transport/chttp2/transport/context_list.h +3 -3
  106. data/src/core/ext/transport/chttp2/transport/decode_huff.h +3 -3
  107. data/src/core/ext/transport/chttp2/transport/flow_control.cc +1 -0
  108. data/src/core/ext/transport/chttp2/transport/flow_control.h +3 -3
  109. data/src/core/ext/transport/chttp2/transport/frame.h +3 -3
  110. data/src/core/ext/transport/chttp2/transport/frame_data.cc +2 -0
  111. data/src/core/ext/transport/chttp2/transport/frame_data.h +3 -3
  112. data/src/core/ext/transport/chttp2/transport/frame_goaway.cc +2 -0
  113. data/src/core/ext/transport/chttp2/transport/frame_goaway.h +3 -3
  114. data/src/core/ext/transport/chttp2/transport/frame_ping.cc +1 -0
  115. data/src/core/ext/transport/chttp2/transport/frame_ping.h +3 -3
  116. data/src/core/ext/transport/chttp2/transport/frame_rst_stream.cc +2 -0
  117. data/src/core/ext/transport/chttp2/transport/frame_rst_stream.h +3 -3
  118. data/src/core/ext/transport/chttp2/transport/frame_settings.cc +1 -0
  119. data/src/core/ext/transport/chttp2/transport/frame_settings.h +3 -3
  120. data/src/core/ext/transport/chttp2/transport/frame_window_update.cc +2 -0
  121. data/src/core/ext/transport/chttp2/transport/frame_window_update.h +3 -3
  122. data/src/core/ext/transport/chttp2/transport/hpack_constants.h +3 -3
  123. data/src/core/ext/transport/chttp2/transport/hpack_encoder.h +3 -3
  124. data/src/core/ext/transport/chttp2/transport/hpack_encoder_table.h +3 -3
  125. data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +18 -407
  126. data/src/core/ext/transport/chttp2/transport/hpack_parser.h +3 -3
  127. data/src/core/ext/transport/chttp2/transport/hpack_parser_table.cc +1 -0
  128. data/src/core/ext/transport/chttp2/transport/hpack_parser_table.h +3 -3
  129. data/src/core/ext/transport/chttp2/transport/http2_settings.h +3 -3
  130. data/src/core/ext/transport/chttp2/transport/http_trace.h +3 -3
  131. data/src/core/ext/transport/chttp2/transport/huffsyms.h +3 -3
  132. data/src/core/ext/transport/chttp2/transport/internal.h +28 -23
  133. data/src/core/ext/transport/chttp2/transport/parsing.cc +111 -31
  134. data/src/core/ext/transport/chttp2/transport/stream_map.h +3 -3
  135. data/src/core/ext/transport/chttp2/transport/varint.h +3 -3
  136. data/src/core/ext/transport/chttp2/transport/writing.cc +9 -8
  137. data/src/core/ext/transport/inproc/inproc_transport.h +3 -3
  138. data/src/core/ext/upb-generated/envoy/admin/v3/clusters.upb.c +3 -2
  139. data/src/core/ext/upb-generated/envoy/admin/v3/clusters.upb.h +9 -0
  140. data/src/core/ext/upb-generated/envoy/admin/v3/config_dump_shared.upb.c +38 -2
  141. data/src/core/ext/upb-generated/envoy/admin/v3/config_dump_shared.upb.h +185 -0
  142. data/src/core/ext/upb-generated/envoy/config/bootstrap/v3/bootstrap.upb.c +7 -3
  143. data/src/core/ext/upb-generated/envoy/config/bootstrap/v3/bootstrap.upb.h +44 -0
  144. data/src/core/ext/upb-generated/envoy/config/cluster/v3/cluster.upb.c +16 -25
  145. data/src/core/ext/upb-generated/envoy/config/cluster/v3/cluster.upb.h +48 -74
  146. data/src/core/ext/upb-generated/envoy/config/core/v3/address.upb.c +30 -7
  147. data/src/core/ext/upb-generated/envoy/config/core/v3/address.upb.h +137 -0
  148. data/src/core/ext/upb-generated/envoy/config/core/v3/health_check.upb.c +15 -12
  149. data/src/core/ext/upb-generated/envoy/config/core/v3/health_check.upb.h +83 -51
  150. data/src/core/ext/upb-generated/envoy/config/core/v3/protocol.upb.c +3 -2
  151. data/src/core/ext/upb-generated/envoy/config/core/v3/protocol.upb.h +15 -0
  152. data/src/core/ext/upb-generated/envoy/config/core/v3/socket_option.upb.c +17 -2
  153. data/src/core/ext/upb-generated/envoy/config/core/v3/socket_option.upb.h +61 -0
  154. data/src/core/ext/upb-generated/envoy/config/endpoint/v3/endpoint_components.upb.c +11 -5
  155. data/src/core/ext/upb-generated/envoy/config/endpoint/v3/endpoint_components.upb.h +37 -6
  156. data/src/core/ext/upb-generated/envoy/config/listener/v3/listener.upb.c +5 -3
  157. data/src/core/ext/upb-generated/envoy/config/listener/v3/listener.upb.h +24 -0
  158. data/src/core/ext/upb-generated/envoy/config/listener/v3/quic_config.upb.c +5 -3
  159. data/src/core/ext/upb-generated/envoy/config/listener/v3/quic_config.upb.h +22 -0
  160. data/src/core/ext/upb-generated/envoy/config/rbac/v3/rbac.upb.c +6 -3
  161. data/src/core/ext/upb-generated/envoy/config/rbac/v3/rbac.upb.h +24 -0
  162. data/src/core/ext/upb-generated/envoy/config/route/v3/route.upb.c +24 -5
  163. data/src/core/ext/upb-generated/envoy/config/route/v3/route.upb.h +50 -0
  164. data/src/core/ext/upb-generated/envoy/config/route/v3/route_components.upb.c +57 -16
  165. data/src/core/ext/upb-generated/envoy/config/route/v3/route_components.upb.h +254 -17
  166. data/src/core/ext/upb-generated/envoy/config/trace/v3/datadog.upb.c +3 -2
  167. data/src/core/ext/upb-generated/envoy/config/trace/v3/datadog.upb.h +9 -0
  168. data/src/core/ext/upb-generated/envoy/config/trace/v3/opentelemetry.upb.c +3 -2
  169. data/src/core/ext/upb-generated/envoy/config/trace/v3/opentelemetry.upb.h +9 -0
  170. data/src/core/ext/upb-generated/envoy/config/trace/v3/zipkin.upb.c +7 -6
  171. data/src/core/ext/upb-generated/envoy/config/trace/v3/zipkin.upb.h +21 -12
  172. data/src/core/ext/upb-generated/envoy/extensions/filters/http/router/v3/router.upb.c +6 -3
  173. data/src/core/ext/upb-generated/envoy/extensions/filters/http/router/v3/router.upb.h +23 -0
  174. data/src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.c +10 -7
  175. data/src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.h +42 -12
  176. data/src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/client_side_weighted_round_robin/v3/client_side_weighted_round_robin.upb.c +54 -0
  177. data/src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/client_side_weighted_round_robin/v3/client_side_weighted_round_robin.upb.h +188 -0
  178. data/src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/common/v3/common.upb.c +111 -0
  179. data/src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/common/v3/common.upb.h +444 -0
  180. data/src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/ring_hash/v3/ring_hash.upb.c +7 -3
  181. data/src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/ring_hash/v3/ring_hash.upb.h +24 -0
  182. data/src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/tls.upb.c +8 -6
  183. data/src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/tls.upb.h +31 -9
  184. data/src/core/ext/upb-generated/envoy/service/discovery/v3/discovery.upb.c +5 -3
  185. data/src/core/ext/upb-generated/envoy/service/discovery/v3/discovery.upb.h +24 -0
  186. data/src/core/ext/upb-generated/envoy/type/matcher/v3/filter_state.upb.c +47 -0
  187. data/src/core/ext/upb-generated/envoy/type/matcher/v3/filter_state.upb.h +113 -0
  188. data/src/core/ext/upb-generated/envoy/type/matcher/v3/status_code_input.upb.c +43 -0
  189. data/src/core/ext/upb-generated/envoy/type/matcher/v3/status_code_input.upb.h +114 -0
  190. data/src/core/ext/upb-generated/envoy/type/v3/ratelimit_unit.upb.h +3 -1
  191. data/src/core/ext/upbdefs-generated/envoy/admin/v3/clusters.upbdefs.c +54 -53
  192. data/src/core/ext/upbdefs-generated/envoy/admin/v3/config_dump_shared.upbdefs.c +34 -13
  193. data/src/core/ext/upbdefs-generated/envoy/admin/v3/config_dump_shared.upbdefs.h +10 -0
  194. data/src/core/ext/upbdefs-generated/envoy/config/bootstrap/v3/bootstrap.upbdefs.c +195 -187
  195. data/src/core/ext/upbdefs-generated/envoy/config/cluster/v3/cluster.upbdefs.c +232 -224
  196. data/src/core/ext/upbdefs-generated/envoy/config/cluster/v3/cluster.upbdefs.h +0 -5
  197. data/src/core/ext/upbdefs-generated/envoy/config/core/v3/address.upbdefs.c +95 -75
  198. data/src/core/ext/upbdefs-generated/envoy/config/core/v3/address.upbdefs.h +5 -0
  199. data/src/core/ext/upbdefs-generated/envoy/config/core/v3/base.upbdefs.c +94 -93
  200. data/src/core/ext/upbdefs-generated/envoy/config/core/v3/health_check.upbdefs.c +81 -75
  201. data/src/core/ext/upbdefs-generated/envoy/config/core/v3/protocol.upbdefs.c +189 -187
  202. data/src/core/ext/upbdefs-generated/envoy/config/core/v3/socket_option.upbdefs.c +7 -3
  203. data/src/core/ext/upbdefs-generated/envoy/config/core/v3/socket_option.upbdefs.h +5 -0
  204. data/src/core/ext/upbdefs-generated/envoy/config/endpoint/v3/endpoint_components.upbdefs.c +71 -66
  205. data/src/core/ext/upbdefs-generated/envoy/config/listener/v3/listener.upbdefs.c +137 -133
  206. data/src/core/ext/upbdefs-generated/envoy/config/listener/v3/quic_config.upbdefs.c +16 -12
  207. data/src/core/ext/upbdefs-generated/envoy/config/rbac/v3/rbac.upbdefs.c +140 -133
  208. data/src/core/ext/upbdefs-generated/envoy/config/route/v3/route.upbdefs.c +81 -70
  209. data/src/core/ext/upbdefs-generated/envoy/config/route/v3/route.upbdefs.h +5 -0
  210. data/src/core/ext/upbdefs-generated/envoy/config/route/v3/route_components.upbdefs.c +771 -741
  211. data/src/core/ext/upbdefs-generated/envoy/config/route/v3/route_components.upbdefs.h +10 -0
  212. data/src/core/ext/upbdefs-generated/envoy/config/trace/v3/datadog.upbdefs.c +16 -14
  213. data/src/core/ext/upbdefs-generated/envoy/config/trace/v3/opentelemetry.upbdefs.c +14 -13
  214. data/src/core/ext/upbdefs-generated/envoy/config/trace/v3/zipkin.upbdefs.c +20 -18
  215. data/src/core/ext/upbdefs-generated/envoy/extensions/filters/http/router/v3/router.upbdefs.c +53 -42
  216. data/src/core/ext/upbdefs-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upbdefs.c +363 -356
  217. data/src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/tls.upbdefs.c +149 -145
  218. data/src/core/ext/upbdefs-generated/envoy/service/discovery/v3/discovery.upbdefs.c +16 -13
  219. data/src/core/ext/upbdefs-generated/envoy/type/matcher/v3/filter_state.upbdefs.c +48 -0
  220. data/src/core/ext/upbdefs-generated/envoy/type/matcher/v3/filter_state.upbdefs.h +35 -0
  221. data/src/core/ext/upbdefs-generated/envoy/type/matcher/v3/regex.upbdefs.c +14 -14
  222. data/src/core/ext/upbdefs-generated/envoy/type/matcher/v3/status_code_input.upbdefs.c +40 -0
  223. data/src/core/ext/upbdefs-generated/envoy/type/matcher/v3/status_code_input.upbdefs.h +40 -0
  224. data/src/core/ext/upbdefs-generated/envoy/type/v3/ratelimit_unit.upbdefs.c +10 -9
  225. data/src/core/ext/xds/certificate_provider_store.h +3 -3
  226. data/src/core/ext/xds/file_watcher_certificate_provider_factory.cc +1 -0
  227. data/src/core/ext/xds/file_watcher_certificate_provider_factory.h +3 -3
  228. data/src/core/ext/xds/upb_utils.h +3 -3
  229. data/src/core/ext/xds/xds_api.h +3 -3
  230. data/src/core/ext/xds/xds_bootstrap.h +3 -3
  231. data/src/core/ext/xds/xds_bootstrap_grpc.cc +1 -0
  232. data/src/core/ext/xds/xds_bootstrap_grpc.h +3 -3
  233. data/src/core/ext/xds/xds_certificate_provider.h +3 -3
  234. data/src/core/ext/xds/xds_channel_args.h +3 -3
  235. data/src/core/ext/xds/xds_channel_stack_modifier.h +3 -3
  236. data/src/core/ext/xds/xds_client.cc +8 -3
  237. data/src/core/ext/xds/xds_client.h +3 -3
  238. data/src/core/ext/xds/xds_client_grpc.cc +0 -1
  239. data/src/core/ext/xds/xds_client_grpc.h +3 -3
  240. data/src/core/ext/xds/xds_client_stats.h +4 -3
  241. data/src/core/ext/xds/xds_cluster.cc +11 -7
  242. data/src/core/ext/xds/xds_cluster.h +6 -6
  243. data/src/core/ext/xds/xds_cluster_specifier_plugin.h +3 -3
  244. data/src/core/ext/xds/xds_common_types.cc +1 -0
  245. data/src/core/ext/xds/xds_common_types.h +3 -3
  246. data/src/core/ext/xds/xds_endpoint.cc +1 -1
  247. data/src/core/ext/xds/xds_endpoint.h +3 -3
  248. data/src/core/ext/xds/xds_health_status.h +30 -3
  249. data/src/core/ext/xds/xds_http_fault_filter.h +3 -3
  250. data/src/core/ext/xds/xds_http_filters.cc +1 -1
  251. data/src/core/ext/xds/xds_http_filters.h +3 -3
  252. data/src/core/ext/xds/xds_http_rbac_filter.h +3 -3
  253. data/src/core/ext/xds/xds_http_stateful_session_filter.h +3 -3
  254. data/src/core/ext/xds/xds_lb_policy_registry.cc +95 -0
  255. data/src/core/ext/xds/xds_lb_policy_registry.h +3 -3
  256. data/src/core/ext/xds/xds_listener.cc +1 -0
  257. data/src/core/ext/xds/xds_listener.h +3 -3
  258. data/src/core/ext/xds/xds_resource_type.h +3 -3
  259. data/src/core/ext/xds/xds_resource_type_impl.h +3 -3
  260. data/src/core/ext/xds/xds_route_config.cc +6 -0
  261. data/src/core/ext/xds/xds_route_config.h +3 -3
  262. data/src/core/ext/xds/xds_routing.h +3 -3
  263. data/src/core/ext/xds/xds_transport.h +3 -3
  264. data/src/core/ext/xds/xds_transport_grpc.h +3 -3
  265. data/src/core/lib/address_utils/parse_address.h +3 -3
  266. data/src/core/lib/address_utils/sockaddr_utils.cc +1 -0
  267. data/src/core/lib/address_utils/sockaddr_utils.h +3 -3
  268. data/src/core/lib/avl/avl.h +3 -3
  269. data/src/core/lib/backoff/backoff.h +3 -3
  270. data/src/core/lib/channel/call_finalization.h +3 -3
  271. data/src/core/lib/channel/call_tracer.h +3 -3
  272. data/src/core/lib/channel/channel_args.cc +1 -0
  273. data/src/core/lib/channel/channel_args.h +11 -5
  274. data/src/core/lib/channel/channel_args_preconditioning.h +3 -3
  275. data/src/core/lib/channel/channel_fwd.h +3 -3
  276. data/src/core/lib/channel/channel_stack.cc +1 -2
  277. data/src/core/lib/channel/channel_stack.h +4 -4
  278. data/src/core/lib/channel/channel_stack_builder.h +3 -3
  279. data/src/core/lib/channel/channel_stack_builder_impl.cc +14 -1
  280. data/src/core/lib/channel/channel_stack_builder_impl.h +3 -3
  281. data/src/core/lib/channel/channel_trace.h +3 -3
  282. data/src/core/lib/channel/channelz.h +3 -3
  283. data/src/core/lib/channel/channelz_registry.h +3 -3
  284. data/src/core/lib/channel/connected_channel.cc +883 -354
  285. data/src/core/lib/channel/connected_channel.h +3 -3
  286. data/src/core/lib/channel/context.h +7 -3
  287. data/src/core/lib/channel/promise_based_filter.cc +532 -260
  288. data/src/core/lib/channel/promise_based_filter.h +124 -44
  289. data/src/core/lib/channel/status_util.h +3 -3
  290. data/src/core/lib/compression/compression_internal.h +3 -3
  291. data/src/core/lib/compression/message_compress.h +3 -3
  292. data/src/core/lib/config/core_configuration.h +3 -3
  293. data/src/core/lib/debug/event_log.h +3 -3
  294. data/src/core/lib/debug/histogram_view.h +3 -3
  295. data/src/core/lib/debug/stats.h +3 -3
  296. data/src/core/lib/debug/stats_data.cc +66 -65
  297. data/src/core/lib/debug/stats_data.h +42 -33
  298. data/src/core/lib/debug/trace.h +4 -26
  299. data/src/core/lib/event_engine/channel_args_endpoint_config.cc +5 -0
  300. data/src/core/lib/event_engine/channel_args_endpoint_config.h +3 -3
  301. data/src/core/lib/event_engine/common_closures.h +3 -3
  302. data/src/core/lib/event_engine/default_event_engine.cc +9 -4
  303. data/src/core/lib/event_engine/default_event_engine.h +30 -6
  304. data/src/core/lib/event_engine/default_event_engine_factory.h +3 -3
  305. data/src/core/lib/event_engine/event_engine.cc +25 -0
  306. data/src/core/lib/event_engine/executor/executor.h +3 -3
  307. data/src/core/lib/event_engine/forkable.cc +11 -6
  308. data/src/core/lib/event_engine/forkable.h +3 -3
  309. data/src/core/lib/event_engine/handle_containers.h +10 -3
  310. data/src/core/lib/event_engine/poller.h +3 -3
  311. data/src/core/lib/event_engine/posix.h +158 -0
  312. data/src/core/lib/event_engine/posix_engine/ev_epoll1_linux.cc +44 -16
  313. data/src/core/lib/event_engine/posix_engine/ev_epoll1_linux.h +14 -4
  314. data/src/core/lib/event_engine/posix_engine/ev_poll_posix.cc +6 -7
  315. data/src/core/lib/event_engine/posix_engine/ev_poll_posix.h +3 -3
  316. data/src/core/lib/event_engine/posix_engine/event_poller.h +3 -3
  317. data/src/core/lib/event_engine/posix_engine/event_poller_posix_default.h +3 -3
  318. data/src/core/lib/event_engine/posix_engine/internal_errqueue.h +3 -3
  319. data/src/core/lib/event_engine/posix_engine/lockfree_event.h +3 -3
  320. data/src/core/lib/event_engine/posix_engine/posix_endpoint.cc +52 -55
  321. data/src/core/lib/event_engine/posix_engine/posix_endpoint.h +46 -13
  322. data/src/core/lib/event_engine/posix_engine/posix_engine.cc +82 -12
  323. data/src/core/lib/event_engine/posix_engine/posix_engine.h +23 -9
  324. data/src/core/lib/event_engine/posix_engine/posix_engine_closure.h +3 -3
  325. data/src/core/lib/event_engine/posix_engine/posix_engine_listener.cc +60 -7
  326. data/src/core/lib/event_engine/posix_engine/posix_engine_listener.h +65 -14
  327. data/src/core/lib/event_engine/posix_engine/posix_engine_listener_utils.cc +0 -1
  328. data/src/core/lib/event_engine/posix_engine/posix_engine_listener_utils.h +6 -6
  329. data/src/core/lib/event_engine/posix_engine/tcp_socket_utils.h +3 -3
  330. data/src/core/lib/event_engine/posix_engine/timer.h +3 -3
  331. data/src/core/lib/event_engine/posix_engine/timer_heap.h +3 -3
  332. data/src/core/lib/event_engine/posix_engine/timer_manager.h +3 -3
  333. data/src/core/lib/event_engine/posix_engine/traced_buffer_list.h +3 -3
  334. data/src/core/lib/event_engine/posix_engine/wakeup_fd_eventfd.h +3 -3
  335. data/src/core/lib/event_engine/posix_engine/wakeup_fd_pipe.h +3 -3
  336. data/src/core/lib/event_engine/posix_engine/wakeup_fd_posix.h +3 -3
  337. data/src/core/lib/event_engine/posix_engine/wakeup_fd_posix_default.h +3 -3
  338. data/src/core/lib/event_engine/resolved_address.cc +19 -0
  339. data/src/core/lib/event_engine/resolved_address_internal.h +34 -0
  340. data/src/core/lib/event_engine/shim.cc +56 -0
  341. data/src/core/lib/event_engine/shim.h +33 -0
  342. data/src/core/lib/event_engine/slice.cc +1 -1
  343. data/src/core/lib/event_engine/tcp_socket_utils.cc +18 -2
  344. data/src/core/lib/event_engine/tcp_socket_utils.h +8 -3
  345. data/src/core/lib/event_engine/thread_local.cc +29 -0
  346. data/src/core/lib/event_engine/thread_local.h +32 -0
  347. data/src/core/lib/event_engine/thread_pool.cc +41 -65
  348. data/src/core/lib/event_engine/thread_pool.h +21 -17
  349. data/src/core/lib/event_engine/time_util.h +3 -3
  350. data/src/core/lib/event_engine/trace.cc +6 -0
  351. data/src/core/lib/event_engine/trace.h +16 -3
  352. data/src/core/lib/event_engine/utils.cc +2 -2
  353. data/src/core/lib/event_engine/utils.h +12 -4
  354. data/src/core/lib/event_engine/windows/iocp.cc +24 -40
  355. data/src/core/lib/event_engine/windows/iocp.h +3 -3
  356. data/src/core/lib/event_engine/windows/win_socket.cc +56 -33
  357. data/src/core/lib/event_engine/windows/win_socket.h +34 -25
  358. data/src/core/lib/event_engine/windows/windows_endpoint.cc +331 -0
  359. data/src/core/lib/event_engine/windows/windows_endpoint.h +103 -0
  360. data/src/core/lib/event_engine/windows/windows_engine.cc +243 -20
  361. data/src/core/lib/event_engine/windows/windows_engine.h +62 -23
  362. data/src/core/lib/experiments/config.cc +16 -1
  363. data/src/core/lib/experiments/config.h +13 -3
  364. data/src/core/lib/experiments/experiments.cc +14 -8
  365. data/src/core/lib/experiments/experiments.h +80 -21
  366. data/src/core/lib/gpr/alloc.h +3 -3
  367. data/src/core/lib/gpr/spinlock.h +3 -3
  368. data/src/core/lib/gpr/string.h +3 -3
  369. data/src/core/lib/gpr/sync_abseil.cc +15 -7
  370. data/src/core/lib/gpr/time_precise.h +3 -3
  371. data/src/core/lib/gpr/tmpfile.h +3 -3
  372. data/src/core/lib/gpr/useful.h +3 -3
  373. data/src/core/lib/gprpp/atomic_utils.h +3 -3
  374. data/src/core/lib/gprpp/bitset.h +3 -3
  375. data/src/core/lib/gprpp/chunked_vector.h +3 -3
  376. data/src/core/lib/gprpp/construct_destruct.h +3 -3
  377. data/src/core/lib/gprpp/cpp_impl_of.h +3 -3
  378. data/src/core/lib/gprpp/crash.h +3 -3
  379. data/src/core/lib/gprpp/debug_location.h +3 -6
  380. data/src/core/lib/gprpp/dual_ref_counted.h +3 -3
  381. data/src/core/lib/gprpp/env.h +3 -3
  382. data/src/core/lib/gprpp/examine_stack.h +3 -3
  383. data/src/core/lib/gprpp/fork.cc +21 -4
  384. data/src/core/lib/gprpp/fork.h +7 -5
  385. data/src/core/lib/gprpp/global_config.h +3 -3
  386. data/src/core/lib/gprpp/global_config_custom.h +3 -3
  387. data/src/core/lib/gprpp/global_config_env.cc +1 -0
  388. data/src/core/lib/gprpp/global_config_env.h +3 -3
  389. data/src/core/lib/gprpp/global_config_generic.h +3 -3
  390. data/src/core/lib/gprpp/host_port.cc +2 -0
  391. data/src/core/lib/gprpp/host_port.h +3 -3
  392. data/src/core/lib/gprpp/load_file.h +3 -3
  393. data/src/core/lib/gprpp/manual_constructor.h +3 -3
  394. data/src/core/lib/gprpp/match.h +3 -3
  395. data/src/core/lib/gprpp/memory.h +3 -3
  396. data/src/core/lib/gprpp/mpscq.h +3 -3
  397. data/src/core/lib/gprpp/no_destruct.h +3 -3
  398. data/src/core/lib/gprpp/notification.h +3 -3
  399. data/src/core/lib/gprpp/orphanable.h +3 -3
  400. data/src/core/lib/gprpp/overload.h +3 -3
  401. data/src/core/lib/gprpp/packed_table.h +3 -3
  402. data/src/core/lib/gprpp/per_cpu.h +3 -3
  403. data/src/core/lib/gprpp/ref_counted.h +3 -3
  404. data/src/core/lib/gprpp/ref_counted_ptr.h +3 -3
  405. data/src/core/lib/gprpp/single_set_ptr.h +3 -3
  406. data/src/core/lib/gprpp/sorted_pack.h +3 -3
  407. data/src/core/lib/gprpp/stat.h +3 -3
  408. data/src/core/lib/gprpp/status_helper.h +3 -3
  409. data/src/core/lib/gprpp/strerror.cc +2 -0
  410. data/src/core/lib/gprpp/strerror.h +3 -3
  411. data/src/core/lib/gprpp/sync.h +3 -3
  412. data/src/core/lib/gprpp/table.h +3 -3
  413. data/src/core/lib/gprpp/tchar.h +3 -3
  414. data/src/core/lib/gprpp/thd.h +3 -3
  415. data/src/core/lib/gprpp/time.cc +1 -0
  416. data/src/core/lib/gprpp/time.h +3 -3
  417. data/src/core/lib/gprpp/time_averaged_stats.h +3 -3
  418. data/src/core/lib/gprpp/time_util.h +3 -3
  419. data/src/core/lib/gprpp/unique_type_name.h +3 -3
  420. data/src/core/lib/gprpp/validation_errors.h +3 -3
  421. data/src/core/lib/gprpp/work_serializer.h +3 -3
  422. data/src/core/lib/handshaker/proxy_mapper.h +3 -3
  423. data/src/core/lib/handshaker/proxy_mapper_registry.h +3 -3
  424. data/src/core/lib/http/format_request.cc +1 -0
  425. data/src/core/lib/http/format_request.h +3 -3
  426. data/src/core/lib/http/httpcli.cc +1 -0
  427. data/src/core/lib/http/httpcli.h +3 -3
  428. data/src/core/lib/http/httpcli_ssl_credentials.h +3 -3
  429. data/src/core/lib/http/parser.h +3 -3
  430. data/src/core/lib/iomgr/block_annotate.h +3 -3
  431. data/src/core/lib/iomgr/buffer_list.h +3 -3
  432. data/src/core/lib/iomgr/call_combiner.cc +4 -4
  433. data/src/core/lib/iomgr/call_combiner.h +3 -3
  434. data/src/core/lib/iomgr/cfstream_handle.h +3 -3
  435. data/src/core/lib/iomgr/closure.cc +27 -0
  436. data/src/core/lib/iomgr/closure.h +5 -3
  437. data/src/core/lib/iomgr/combiner.h +3 -3
  438. data/src/core/lib/iomgr/dynamic_annotations.h +3 -3
  439. data/src/core/lib/iomgr/endpoint.h +3 -3
  440. data/src/core/lib/iomgr/endpoint_cfstream.h +3 -3
  441. data/src/core/lib/iomgr/endpoint_pair.h +3 -3
  442. data/src/core/lib/iomgr/endpoint_pair_windows.cc +10 -2
  443. data/src/core/lib/iomgr/error.h +3 -3
  444. data/src/core/lib/iomgr/error_cfstream.h +3 -3
  445. data/src/core/lib/iomgr/ev_apple.h +3 -3
  446. data/src/core/lib/iomgr/ev_epoll1_linux.h +3 -3
  447. data/src/core/lib/iomgr/ev_poll_posix.h +3 -3
  448. data/src/core/lib/iomgr/ev_posix.h +3 -3
  449. data/src/core/lib/iomgr/event_engine_shims/closure.cc +62 -0
  450. data/src/core/lib/iomgr/event_engine_shims/closure.h +39 -0
  451. data/src/core/lib/iomgr/event_engine_shims/endpoint.cc +430 -0
  452. data/src/core/lib/iomgr/event_engine_shims/endpoint.h +43 -0
  453. data/src/core/lib/iomgr/event_engine_shims/tcp_client.cc +91 -0
  454. data/src/core/lib/iomgr/event_engine_shims/tcp_client.h +44 -0
  455. data/src/core/lib/iomgr/exec_ctx.h +3 -3
  456. data/src/core/lib/iomgr/executor.h +3 -3
  457. data/src/core/lib/iomgr/fork_posix.cc +5 -4
  458. data/src/core/lib/iomgr/gethostname.h +3 -3
  459. data/src/core/lib/iomgr/grpc_if_nametoindex.h +3 -3
  460. data/src/core/lib/iomgr/internal_errqueue.h +3 -3
  461. data/src/core/lib/iomgr/iocp_windows.h +3 -3
  462. data/src/core/lib/iomgr/iomgr.h +3 -3
  463. data/src/core/lib/iomgr/iomgr_fwd.h +3 -3
  464. data/src/core/lib/iomgr/iomgr_internal.h +3 -3
  465. data/src/core/lib/iomgr/load_file.h +3 -3
  466. data/src/core/lib/iomgr/lockfree_event.h +3 -3
  467. data/src/core/lib/iomgr/nameser.h +3 -3
  468. data/src/core/lib/iomgr/polling_entity.h +3 -3
  469. data/src/core/lib/iomgr/pollset.h +3 -3
  470. data/src/core/lib/iomgr/pollset_set.h +3 -3
  471. data/src/core/lib/iomgr/pollset_set_windows.h +3 -3
  472. data/src/core/lib/iomgr/pollset_windows.cc +2 -2
  473. data/src/core/lib/iomgr/pollset_windows.h +3 -3
  474. data/src/core/lib/iomgr/port.h +3 -3
  475. data/src/core/lib/iomgr/python_util.h +3 -3
  476. data/src/core/lib/iomgr/resolve_address.h +3 -3
  477. data/src/core/lib/iomgr/resolve_address_impl.h +3 -3
  478. data/src/core/lib/iomgr/resolve_address_posix.h +3 -3
  479. data/src/core/lib/iomgr/resolve_address_windows.h +3 -3
  480. data/src/core/lib/iomgr/resolved_address.h +3 -3
  481. data/src/core/lib/iomgr/sockaddr.h +3 -3
  482. data/src/core/lib/iomgr/sockaddr_posix.h +3 -3
  483. data/src/core/lib/iomgr/sockaddr_windows.h +3 -3
  484. data/src/core/lib/iomgr/socket_factory_posix.h +3 -3
  485. data/src/core/lib/iomgr/socket_mutator.h +3 -3
  486. data/src/core/lib/iomgr/socket_utils.h +3 -3
  487. data/src/core/lib/iomgr/socket_utils_posix.h +3 -3
  488. data/src/core/lib/iomgr/socket_windows.h +3 -3
  489. data/src/core/lib/iomgr/systemd_utils.cc +19 -19
  490. data/src/core/lib/iomgr/systemd_utils.h +24 -24
  491. data/src/core/lib/iomgr/tcp_client.h +3 -3
  492. data/src/core/lib/iomgr/tcp_client_posix.cc +12 -0
  493. data/src/core/lib/iomgr/tcp_client_posix.h +3 -3
  494. data/src/core/lib/iomgr/tcp_client_windows.cc +13 -1
  495. data/src/core/lib/iomgr/tcp_posix.cc +49 -65
  496. data/src/core/lib/iomgr/tcp_posix.h +3 -3
  497. data/src/core/lib/iomgr/tcp_server.h +3 -3
  498. data/src/core/lib/iomgr/tcp_server_posix.cc +219 -4
  499. data/src/core/lib/iomgr/tcp_server_utils_posix.h +13 -3
  500. data/src/core/lib/iomgr/tcp_server_windows.cc +4 -6
  501. data/src/core/lib/iomgr/tcp_windows.h +3 -3
  502. data/src/core/lib/iomgr/timer.h +3 -3
  503. data/src/core/lib/iomgr/timer_generic.h +3 -3
  504. data/src/core/lib/iomgr/timer_heap.h +3 -3
  505. data/src/core/lib/iomgr/timer_manager.h +3 -3
  506. data/src/core/lib/iomgr/unix_sockets_posix.h +3 -3
  507. data/src/core/lib/iomgr/wakeup_fd_pipe.h +3 -3
  508. data/src/core/lib/iomgr/wakeup_fd_posix.h +3 -3
  509. data/src/core/lib/json/json.h +3 -3
  510. data/src/core/lib/json/json_args.h +3 -3
  511. data/src/core/lib/json/json_channel_args.h +3 -3
  512. data/src/core/lib/json/json_object_loader.h +3 -3
  513. data/src/core/lib/json/json_reader.cc +1 -0
  514. data/src/core/lib/json/json_util.h +3 -3
  515. data/src/core/lib/load_balancing/lb_policy.cc +9 -0
  516. data/src/core/lib/load_balancing/lb_policy.h +9 -5
  517. data/src/core/lib/load_balancing/lb_policy_factory.h +3 -3
  518. data/src/core/lib/load_balancing/lb_policy_registry.cc +1 -0
  519. data/src/core/lib/load_balancing/lb_policy_registry.h +3 -3
  520. data/src/core/lib/load_balancing/subchannel_interface.h +8 -6
  521. data/src/core/lib/matchers/matchers.cc +1 -0
  522. data/src/core/lib/matchers/matchers.h +3 -3
  523. data/src/core/lib/promise/activity.cc +8 -6
  524. data/src/core/lib/promise/activity.h +52 -66
  525. data/src/core/lib/promise/arena_promise.h +3 -3
  526. data/src/core/lib/promise/context.h +3 -3
  527. data/src/core/lib/promise/detail/basic_join.h +197 -0
  528. data/src/core/lib/promise/detail/basic_seq.h +10 -16
  529. data/src/core/lib/promise/detail/promise_factory.h +3 -3
  530. data/src/core/lib/promise/detail/promise_like.h +3 -3
  531. data/src/core/lib/promise/detail/status.h +3 -3
  532. data/src/core/lib/promise/detail/switch.h +3 -3
  533. data/src/core/lib/promise/exec_ctx_wakeup_scheduler.h +3 -3
  534. data/src/core/lib/promise/if.h +195 -0
  535. data/src/core/lib/promise/interceptor_list.h +308 -0
  536. data/src/core/lib/promise/intra_activity_waiter.h +9 -3
  537. data/src/core/lib/promise/latch.h +99 -5
  538. data/src/core/lib/promise/loop.h +4 -4
  539. data/src/core/lib/promise/map.h +4 -6
  540. data/src/core/lib/promise/pipe.h +296 -193
  541. data/src/core/lib/promise/poll.h +113 -14
  542. data/src/core/lib/promise/promise.h +4 -5
  543. data/src/core/lib/promise/race.h +6 -9
  544. data/src/core/lib/promise/seq.h +3 -3
  545. data/src/core/lib/promise/sleep.h +3 -3
  546. data/src/core/lib/promise/{pipe.cc → trace.cc} +3 -2
  547. data/src/core/lib/promise/trace.h +24 -0
  548. data/src/core/lib/promise/try_join.h +82 -0
  549. data/src/core/lib/promise/try_seq.h +3 -3
  550. data/src/core/lib/resolver/resolver.h +3 -3
  551. data/src/core/lib/resolver/resolver_factory.h +4 -4
  552. data/src/core/lib/resolver/resolver_registry.cc +15 -0
  553. data/src/core/lib/resolver/resolver_registry.h +3 -3
  554. data/src/core/lib/resolver/server_address.cc +1 -0
  555. data/src/core/lib/resolver/server_address.h +3 -3
  556. data/src/core/lib/resource_quota/api.h +3 -3
  557. data/src/core/lib/resource_quota/arena.cc +36 -9
  558. data/src/core/lib/resource_quota/arena.h +84 -22
  559. data/src/core/lib/resource_quota/memory_quota.h +3 -3
  560. data/src/core/lib/resource_quota/periodic_update.h +3 -3
  561. data/src/core/lib/resource_quota/resource_quota.h +3 -3
  562. data/src/core/lib/resource_quota/thread_quota.h +3 -3
  563. data/src/core/lib/resource_quota/trace.h +3 -3
  564. data/src/core/lib/security/authorization/authorization_engine.h +3 -3
  565. data/src/core/lib/security/authorization/authorization_policy_provider.h +3 -3
  566. data/src/core/lib/security/authorization/evaluate_args.h +3 -3
  567. data/src/core/lib/security/authorization/grpc_authorization_engine.h +3 -3
  568. data/src/core/lib/security/authorization/grpc_server_authz_filter.h +3 -3
  569. data/src/core/lib/security/authorization/matchers.h +3 -3
  570. data/src/core/lib/security/authorization/rbac_policy.cc +1 -0
  571. data/src/core/lib/security/authorization/rbac_policy.h +3 -3
  572. data/src/core/lib/security/certificate_provider/certificate_provider_factory.h +3 -3
  573. data/src/core/lib/security/certificate_provider/certificate_provider_registry.h +3 -3
  574. data/src/core/lib/security/context/security_context.h +3 -3
  575. data/src/core/lib/security/credentials/alts/alts_credentials.h +3 -3
  576. data/src/core/lib/security/credentials/alts/check_gcp_environment.h +3 -3
  577. data/src/core/lib/security/credentials/alts/grpc_alts_credentials_options.h +3 -3
  578. data/src/core/lib/security/credentials/call_creds_util.h +3 -3
  579. data/src/core/lib/security/credentials/channel_creds_registry.h +3 -3
  580. data/src/core/lib/security/credentials/composite/composite_credentials.h +3 -3
  581. data/src/core/lib/security/credentials/credentials.h +3 -3
  582. data/src/core/lib/security/credentials/external/aws_external_account_credentials.cc +1 -0
  583. data/src/core/lib/security/credentials/external/aws_external_account_credentials.h +3 -3
  584. data/src/core/lib/security/credentials/external/aws_request_signer.cc +1 -0
  585. data/src/core/lib/security/credentials/external/aws_request_signer.h +3 -3
  586. data/src/core/lib/security/credentials/external/external_account_credentials.cc +1 -0
  587. data/src/core/lib/security/credentials/external/external_account_credentials.h +3 -3
  588. data/src/core/lib/security/credentials/external/file_external_account_credentials.h +3 -3
  589. data/src/core/lib/security/credentials/external/url_external_account_credentials.cc +1 -0
  590. data/src/core/lib/security/credentials/external/url_external_account_credentials.h +3 -3
  591. data/src/core/lib/security/credentials/fake/fake_credentials.h +3 -3
  592. data/src/core/lib/security/credentials/google_default/google_default_credentials.h +3 -3
  593. data/src/core/lib/security/credentials/iam/iam_credentials.cc +1 -0
  594. data/src/core/lib/security/credentials/iam/iam_credentials.h +3 -3
  595. data/src/core/lib/security/credentials/insecure/insecure_credentials.h +3 -3
  596. data/src/core/lib/security/credentials/jwt/json_token.h +3 -3
  597. data/src/core/lib/security/credentials/jwt/jwt_credentials.h +4 -3
  598. data/src/core/lib/security/credentials/jwt/jwt_verifier.h +3 -3
  599. data/src/core/lib/security/credentials/local/local_credentials.h +3 -3
  600. data/src/core/lib/security/credentials/oauth2/oauth2_credentials.h +4 -3
  601. data/src/core/lib/security/credentials/plugin/plugin_credentials.h +3 -3
  602. data/src/core/lib/security/credentials/ssl/ssl_credentials.h +3 -3
  603. data/src/core/lib/security/credentials/tls/grpc_tls_certificate_distributor.h +3 -3
  604. data/src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.cc +1 -1
  605. data/src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.h +3 -3
  606. data/src/core/lib/security/credentials/tls/grpc_tls_certificate_verifier.h +3 -3
  607. data/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h +3 -3
  608. data/src/core/lib/security/credentials/tls/tls_credentials.h +3 -3
  609. data/src/core/lib/security/credentials/tls/tls_utils.h +3 -3
  610. data/src/core/lib/security/credentials/xds/xds_credentials.h +3 -3
  611. data/src/core/lib/security/security_connector/alts/alts_security_connector.h +3 -3
  612. data/src/core/lib/security/security_connector/fake/fake_security_connector.cc +1 -0
  613. data/src/core/lib/security/security_connector/fake/fake_security_connector.h +3 -3
  614. data/src/core/lib/security/security_connector/insecure/insecure_security_connector.h +3 -3
  615. data/src/core/lib/security/security_connector/load_system_roots.h +3 -3
  616. data/src/core/lib/security/security_connector/load_system_roots_supported.h +3 -3
  617. data/src/core/lib/security/security_connector/local/local_security_connector.h +3 -3
  618. data/src/core/lib/security/security_connector/security_connector.h +3 -3
  619. data/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc +1 -0
  620. data/src/core/lib/security/security_connector/ssl/ssl_security_connector.h +3 -3
  621. data/src/core/lib/security/security_connector/ssl_utils.h +3 -3
  622. data/src/core/lib/security/security_connector/ssl_utils_config.h +3 -3
  623. data/src/core/lib/security/security_connector/tls/tls_security_connector.h +3 -3
  624. data/src/core/lib/security/transport/auth_filters.h +27 -5
  625. data/src/core/lib/security/transport/secure_endpoint.h +3 -3
  626. data/src/core/lib/security/transport/security_handshaker.cc +9 -0
  627. data/src/core/lib/security/transport/security_handshaker.h +3 -3
  628. data/src/core/lib/security/transport/server_auth_filter.cc +120 -251
  629. data/src/core/lib/security/transport/tsi_error.h +3 -3
  630. data/src/core/lib/security/util/json_util.h +3 -3
  631. data/src/core/lib/service_config/service_config.h +3 -3
  632. data/src/core/lib/service_config/service_config_call_data.h +3 -3
  633. data/src/core/lib/service_config/service_config_impl.h +3 -3
  634. data/src/core/lib/service_config/service_config_parser.h +3 -3
  635. data/src/core/lib/slice/b64.h +3 -3
  636. data/src/core/lib/slice/percent_encoding.h +3 -3
  637. data/src/core/lib/slice/slice.cc +3 -3
  638. data/src/core/lib/slice/slice.h +14 -21
  639. data/src/core/lib/slice/slice_buffer.h +10 -4
  640. data/src/core/lib/slice/slice_internal.h +3 -3
  641. data/src/core/lib/slice/slice_refcount.cc +20 -0
  642. data/src/core/lib/slice/slice_refcount.h +26 -6
  643. data/src/core/lib/slice/slice_string_helpers.h +3 -3
  644. data/src/core/lib/surface/api_trace.h +3 -3
  645. data/src/core/lib/surface/builtins.h +3 -3
  646. data/src/core/lib/surface/call.cc +866 -252
  647. data/src/core/lib/surface/call.h +31 -3
  648. data/src/core/lib/surface/call_log_batch.cc +1 -0
  649. data/src/core/lib/surface/call_test_only.h +3 -3
  650. data/src/core/lib/surface/call_trace.cc +21 -11
  651. data/src/core/lib/surface/call_trace.h +3 -3
  652. data/src/core/lib/surface/channel.h +3 -3
  653. data/src/core/lib/surface/channel_init.h +3 -3
  654. data/src/core/lib/surface/channel_stack_type.h +3 -3
  655. data/src/core/lib/surface/completion_queue.cc +1 -0
  656. data/src/core/lib/surface/completion_queue.h +3 -3
  657. data/src/core/lib/surface/completion_queue_factory.h +3 -3
  658. data/src/core/lib/surface/event_string.cc +1 -0
  659. data/src/core/lib/surface/event_string.h +3 -3
  660. data/src/core/lib/surface/init.cc +1 -1
  661. data/src/core/lib/surface/init.h +3 -3
  662. data/src/core/lib/surface/init_internally.h +3 -3
  663. data/src/core/lib/surface/lame_client.cc +3 -1
  664. data/src/core/lib/surface/lame_client.h +3 -3
  665. data/src/core/lib/surface/server.cc +273 -27
  666. data/src/core/lib/surface/server.h +6 -3
  667. data/src/core/lib/surface/validate_metadata.h +3 -3
  668. data/src/core/lib/surface/version.cc +2 -2
  669. data/src/core/lib/transport/bdp_estimator.h +3 -3
  670. data/src/core/lib/transport/connectivity_state.h +3 -3
  671. data/src/core/lib/transport/error_utils.h +3 -3
  672. data/src/core/lib/transport/handshaker.cc +11 -0
  673. data/src/core/lib/transport/handshaker.h +4 -4
  674. data/src/core/lib/transport/handshaker_factory.h +3 -3
  675. data/src/core/lib/transport/handshaker_registry.h +3 -3
  676. data/src/core/lib/transport/http2_errors.h +3 -3
  677. data/src/core/lib/transport/http_connect_handshaker.h +3 -3
  678. data/src/core/lib/transport/metadata_batch.cc +11 -0
  679. data/src/core/lib/transport/metadata_batch.h +24 -3
  680. data/src/core/lib/transport/parsed_metadata.h +3 -3
  681. data/src/core/lib/transport/pid_controller.h +3 -3
  682. data/src/core/lib/transport/status_conversion.h +3 -3
  683. data/src/core/lib/transport/tcp_connect_handshaker.cc +0 -1
  684. data/src/core/lib/transport/tcp_connect_handshaker.h +3 -3
  685. data/src/core/lib/transport/timeout_encoding.h +3 -3
  686. data/src/core/lib/transport/transport.cc +3 -8
  687. data/src/core/lib/transport/transport.h +16 -8
  688. data/src/core/lib/transport/transport_fwd.h +3 -3
  689. data/src/core/lib/transport/transport_impl.h +3 -3
  690. data/src/core/lib/transport/transport_op_string.cc +1 -0
  691. data/src/core/lib/uri/uri_parser.cc +1 -1
  692. data/src/core/lib/uri/uri_parser.h +3 -3
  693. data/src/core/plugin_registry/grpc_plugin_registry.cc +5 -0
  694. data/src/core/tsi/alts/crypt/gsec.h +3 -3
  695. data/src/core/tsi/alts/frame_protector/alts_counter.h +3 -3
  696. data/src/core/tsi/alts/frame_protector/alts_crypter.h +3 -3
  697. data/src/core/tsi/alts/frame_protector/alts_frame_protector.h +3 -3
  698. data/src/core/tsi/alts/frame_protector/alts_record_protocol_crypter_common.h +3 -3
  699. data/src/core/tsi/alts/frame_protector/frame_handler.h +3 -3
  700. data/src/core/tsi/alts/handshaker/alts_handshaker_client.h +3 -3
  701. data/src/core/tsi/alts/handshaker/alts_shared_resource.h +3 -3
  702. data/src/core/tsi/alts/handshaker/alts_tsi_handshaker.h +3 -3
  703. data/src/core/tsi/alts/handshaker/alts_tsi_handshaker_private.h +3 -3
  704. data/src/core/tsi/alts/handshaker/alts_tsi_utils.h +3 -3
  705. data/src/core/tsi/alts/handshaker/transport_security_common_api.h +3 -3
  706. data/src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.h +3 -3
  707. data/src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_privacy_integrity_record_protocol.h +3 -3
  708. data/src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol.h +3 -3
  709. data/src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol_common.h +3 -3
  710. data/src/core/tsi/alts/zero_copy_frame_protector/alts_iovec_record_protocol.h +3 -3
  711. data/src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.h +3 -3
  712. data/src/core/tsi/fake_transport_security.h +3 -3
  713. data/src/core/tsi/local_transport_security.h +3 -3
  714. data/src/core/tsi/ssl/key_logging/ssl_key_logging.cc +1 -1
  715. data/src/core/tsi/ssl/key_logging/ssl_key_logging.h +3 -3
  716. data/src/core/tsi/ssl/session_cache/ssl_session.h +3 -3
  717. data/src/core/tsi/ssl/session_cache/ssl_session_cache.h +3 -3
  718. data/src/core/tsi/ssl_transport_security.cc +113 -24
  719. data/src/core/tsi/ssl_transport_security.h +5 -3
  720. data/src/core/tsi/ssl_transport_security_utils.h +3 -3
  721. data/src/core/tsi/ssl_types.h +3 -3
  722. data/src/core/tsi/transport_security.h +3 -3
  723. data/src/core/tsi/transport_security_grpc.h +3 -3
  724. data/src/core/tsi/transport_security_interface.h +3 -3
  725. data/src/ruby/lib/grpc/version.rb +1 -1
  726. data/src/ruby/pb/generate_proto_ruby.sh +0 -6
  727. data/third_party/abseil-cpp/absl/algorithm/container.h +56 -57
  728. data/third_party/abseil-cpp/absl/base/attributes.h +39 -19
  729. data/third_party/abseil-cpp/absl/base/config.h +44 -3
  730. data/third_party/abseil-cpp/absl/base/internal/cycleclock.h +3 -18
  731. data/third_party/abseil-cpp/absl/base/internal/cycleclock_config.h +55 -0
  732. data/third_party/abseil-cpp/absl/base/internal/direct_mmap.h +2 -1
  733. data/third_party/abseil-cpp/absl/base/internal/inline_variable.h +3 -3
  734. data/third_party/abseil-cpp/absl/base/internal/low_level_alloc.cc +2 -2
  735. data/third_party/abseil-cpp/absl/base/internal/low_level_alloc.h +1 -1
  736. data/third_party/abseil-cpp/absl/base/internal/raw_logging.cc +10 -6
  737. data/third_party/abseil-cpp/absl/base/internal/raw_logging.h +23 -24
  738. data/third_party/abseil-cpp/absl/base/internal/spinlock.cc +3 -3
  739. data/third_party/abseil-cpp/absl/base/internal/spinlock.h +2 -6
  740. data/third_party/abseil-cpp/absl/base/internal/spinlock_win32.inc +4 -1
  741. data/third_party/abseil-cpp/absl/base/internal/strerror.cc +4 -4
  742. data/third_party/abseil-cpp/absl/base/internal/sysinfo.cc +14 -10
  743. data/third_party/abseil-cpp/absl/base/internal/thread_annotations.h +9 -0
  744. data/third_party/abseil-cpp/absl/base/internal/thread_identity.h +4 -0
  745. data/third_party/abseil-cpp/absl/base/internal/unscaledcycleclock.h +3 -40
  746. data/third_party/abseil-cpp/absl/base/internal/unscaledcycleclock_config.h +62 -0
  747. data/third_party/abseil-cpp/absl/base/macros.h +4 -21
  748. data/third_party/abseil-cpp/absl/base/optimization.h +58 -6
  749. data/third_party/abseil-cpp/absl/base/options.h +1 -7
  750. data/third_party/abseil-cpp/absl/base/policy_checks.h +15 -13
  751. data/third_party/abseil-cpp/absl/container/fixed_array.h +7 -5
  752. data/third_party/abseil-cpp/absl/container/flat_hash_set.h +0 -7
  753. data/third_party/abseil-cpp/absl/container/inlined_vector.h +66 -18
  754. data/third_party/abseil-cpp/absl/container/internal/common.h +3 -3
  755. data/third_party/abseil-cpp/absl/container/internal/common_policy_traits.h +132 -0
  756. data/third_party/abseil-cpp/absl/container/internal/container_memory.h +13 -1
  757. data/third_party/abseil-cpp/absl/container/internal/hash_policy_traits.h +4 -55
  758. data/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler.cc +50 -5
  759. data/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler.h +14 -46
  760. data/third_party/abseil-cpp/absl/container/internal/inlined_vector.h +110 -32
  761. data/third_party/abseil-cpp/absl/container/internal/raw_hash_set.cc +155 -4
  762. data/third_party/abseil-cpp/absl/container/internal/raw_hash_set.h +661 -341
  763. data/third_party/abseil-cpp/absl/crc/crc32c.cc +99 -0
  764. data/third_party/abseil-cpp/absl/crc/crc32c.h +183 -0
  765. data/third_party/abseil-cpp/absl/crc/internal/cpu_detect.cc +256 -0
  766. data/third_party/abseil-cpp/absl/crc/internal/cpu_detect.h +57 -0
  767. data/third_party/abseil-cpp/absl/crc/internal/crc.cc +468 -0
  768. data/third_party/abseil-cpp/absl/crc/internal/crc.h +91 -0
  769. data/third_party/abseil-cpp/absl/crc/internal/crc32_x86_arm_combined_simd.h +269 -0
  770. data/third_party/abseil-cpp/absl/crc/internal/crc32c.h +39 -0
  771. data/third_party/abseil-cpp/absl/crc/internal/crc32c_inline.h +72 -0
  772. data/third_party/abseil-cpp/absl/crc/internal/crc_cord_state.cc +130 -0
  773. data/third_party/abseil-cpp/absl/crc/internal/crc_cord_state.h +159 -0
  774. data/third_party/abseil-cpp/absl/crc/internal/crc_internal.h +179 -0
  775. data/third_party/abseil-cpp/absl/crc/internal/crc_memcpy.h +119 -0
  776. data/third_party/abseil-cpp/absl/crc/internal/crc_memcpy_fallback.cc +75 -0
  777. data/third_party/abseil-cpp/absl/crc/internal/crc_memcpy_x86_64.cc +434 -0
  778. data/third_party/abseil-cpp/absl/crc/internal/crc_non_temporal_memcpy.cc +93 -0
  779. data/third_party/abseil-cpp/absl/crc/internal/crc_x86_arm_combined.cc +725 -0
  780. data/third_party/abseil-cpp/absl/crc/internal/non_temporal_arm_intrinsics.h +79 -0
  781. data/third_party/abseil-cpp/absl/crc/internal/non_temporal_memcpy.h +180 -0
  782. data/third_party/abseil-cpp/absl/debugging/internal/address_is_readable.cc +1 -1
  783. data/third_party/abseil-cpp/absl/debugging/internal/demangle.cc +67 -38
  784. data/third_party/abseil-cpp/absl/debugging/internal/demangle.h +1 -1
  785. data/third_party/abseil-cpp/absl/debugging/internal/elf_mem_image.cc +12 -13
  786. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_aarch64-inl.inc +11 -9
  787. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_generic-inl.inc +1 -1
  788. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_riscv-inl.inc +40 -85
  789. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_win32-inl.inc +5 -4
  790. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_x86-inl.inc +33 -8
  791. data/third_party/abseil-cpp/absl/debugging/internal/vdso_support.cc +3 -2
  792. data/third_party/abseil-cpp/absl/debugging/symbolize_darwin.inc +3 -2
  793. data/third_party/abseil-cpp/absl/debugging/symbolize_elf.inc +118 -94
  794. data/third_party/abseil-cpp/absl/debugging/symbolize_win32.inc +7 -6
  795. data/third_party/abseil-cpp/absl/functional/any_invocable.h +5 -2
  796. data/third_party/abseil-cpp/absl/functional/internal/any_invocable.h +47 -26
  797. data/third_party/abseil-cpp/absl/hash/internal/city.cc +10 -10
  798. data/third_party/abseil-cpp/absl/hash/internal/hash.h +18 -4
  799. data/third_party/abseil-cpp/absl/hash/internal/low_level_hash.cc +3 -14
  800. data/third_party/abseil-cpp/absl/memory/memory.h +26 -447
  801. data/third_party/abseil-cpp/absl/meta/type_traits.h +104 -12
  802. data/third_party/abseil-cpp/absl/numeric/bits.h +2 -3
  803. data/third_party/abseil-cpp/absl/numeric/int128.cc +10 -8
  804. data/third_party/abseil-cpp/absl/profiling/internal/sample_recorder.h +14 -6
  805. data/third_party/abseil-cpp/absl/random/internal/fast_uniform_bits.h +2 -1
  806. data/third_party/abseil-cpp/absl/random/internal/nonsecure_base.h +1 -1
  807. data/third_party/abseil-cpp/absl/random/internal/pcg_engine.h +2 -23
  808. data/third_party/abseil-cpp/absl/random/internal/pool_urbg.cc +9 -9
  809. data/third_party/abseil-cpp/absl/random/internal/seed_material.cc +2 -2
  810. data/third_party/abseil-cpp/absl/random/random.h +6 -6
  811. data/third_party/abseil-cpp/absl/status/internal/status_internal.h +1 -0
  812. data/third_party/abseil-cpp/absl/status/status.cc +19 -12
  813. data/third_party/abseil-cpp/absl/status/status.h +2 -2
  814. data/third_party/abseil-cpp/absl/strings/ascii.cc +5 -5
  815. data/third_party/abseil-cpp/absl/strings/charconv.cc +534 -96
  816. data/third_party/abseil-cpp/absl/strings/cord.cc +92 -40
  817. data/third_party/abseil-cpp/absl/strings/cord.h +71 -80
  818. data/third_party/abseil-cpp/absl/strings/cord_buffer.h +8 -5
  819. data/third_party/abseil-cpp/absl/strings/escaping.cc +73 -62
  820. data/third_party/abseil-cpp/absl/strings/escaping.h +24 -19
  821. data/third_party/abseil-cpp/absl/strings/internal/char_map.h +14 -12
  822. data/third_party/abseil-cpp/absl/strings/internal/charconv_bigint.cc +4 -4
  823. data/third_party/abseil-cpp/absl/strings/internal/charconv_parse.cc +2 -2
  824. data/third_party/abseil-cpp/absl/strings/internal/cord_internal.h +326 -70
  825. data/third_party/abseil-cpp/absl/strings/internal/cord_rep_btree.cc +8 -4
  826. data/third_party/abseil-cpp/absl/strings/internal/cord_rep_btree.h +26 -14
  827. data/third_party/abseil-cpp/absl/strings/internal/cord_rep_btree_navigator.cc +5 -5
  828. data/third_party/abseil-cpp/absl/strings/internal/cord_rep_crc.cc +9 -7
  829. data/third_party/abseil-cpp/absl/strings/internal/cord_rep_crc.h +5 -4
  830. data/third_party/abseil-cpp/absl/strings/internal/cordz_functions.h +7 -15
  831. data/third_party/abseil-cpp/absl/strings/internal/cordz_handle.h +3 -3
  832. data/third_party/abseil-cpp/absl/strings/internal/cordz_info.cc +8 -5
  833. data/third_party/abseil-cpp/absl/strings/internal/cordz_info.h +7 -7
  834. data/third_party/abseil-cpp/absl/strings/internal/cordz_statistics.h +4 -4
  835. data/third_party/abseil-cpp/absl/strings/internal/damerau_levenshtein_distance.cc +93 -0
  836. data/third_party/abseil-cpp/absl/strings/internal/damerau_levenshtein_distance.h +34 -0
  837. data/third_party/abseil-cpp/absl/strings/internal/escaping.cc +12 -10
  838. data/third_party/abseil-cpp/absl/strings/internal/escaping.h +7 -9
  839. data/third_party/abseil-cpp/absl/strings/internal/has_absl_stringify.h +55 -0
  840. data/third_party/abseil-cpp/absl/strings/internal/memutil.cc +9 -6
  841. data/third_party/abseil-cpp/absl/strings/internal/ostringstream.cc +14 -7
  842. data/third_party/abseil-cpp/absl/strings/internal/ostringstream.h +35 -10
  843. data/third_party/abseil-cpp/absl/strings/internal/str_format/arg.cc +113 -46
  844. data/third_party/abseil-cpp/absl/strings/internal/str_format/arg.h +126 -29
  845. data/third_party/abseil-cpp/absl/strings/internal/str_format/bind.cc +3 -2
  846. data/third_party/abseil-cpp/absl/strings/internal/str_format/bind.h +4 -3
  847. data/third_party/abseil-cpp/absl/strings/internal/str_format/checker.h +49 -287
  848. data/third_party/abseil-cpp/absl/strings/internal/str_format/constexpr_parser.h +351 -0
  849. data/third_party/abseil-cpp/absl/strings/internal/str_format/extension.cc +2 -1
  850. data/third_party/abseil-cpp/absl/strings/internal/str_format/extension.h +4 -2
  851. data/third_party/abseil-cpp/absl/strings/internal/str_format/float_conversion.cc +215 -181
  852. data/third_party/abseil-cpp/absl/strings/internal/str_format/parser.cc +10 -209
  853. data/third_party/abseil-cpp/absl/strings/internal/str_format/parser.h +10 -101
  854. data/third_party/abseil-cpp/absl/strings/internal/str_split_internal.h +2 -1
  855. data/third_party/abseil-cpp/absl/strings/internal/stringify_sink.cc +28 -0
  856. data/third_party/abseil-cpp/absl/strings/internal/stringify_sink.h +57 -0
  857. data/third_party/abseil-cpp/absl/strings/numbers.cc +34 -31
  858. data/third_party/abseil-cpp/absl/strings/str_cat.cc +9 -6
  859. data/third_party/abseil-cpp/absl/strings/str_cat.h +50 -3
  860. data/third_party/abseil-cpp/absl/strings/str_format.h +71 -9
  861. data/third_party/abseil-cpp/absl/strings/string_view.cc +6 -6
  862. data/third_party/abseil-cpp/absl/strings/string_view.h +3 -10
  863. data/third_party/abseil-cpp/absl/strings/substitute.cc +8 -6
  864. data/third_party/abseil-cpp/absl/strings/substitute.h +46 -20
  865. data/third_party/abseil-cpp/absl/synchronization/internal/futex.h +20 -17
  866. data/third_party/abseil-cpp/absl/synchronization/internal/graphcycles.cc +37 -31
  867. data/third_party/abseil-cpp/absl/synchronization/internal/kernel_timeout.h +22 -8
  868. data/third_party/abseil-cpp/absl/synchronization/mutex.cc +104 -55
  869. data/third_party/abseil-cpp/absl/synchronization/mutex.h +85 -46
  870. data/third_party/abseil-cpp/absl/synchronization/notification.cc +0 -1
  871. data/third_party/abseil-cpp/absl/synchronization/notification.h +0 -1
  872. data/third_party/abseil-cpp/absl/time/civil_time.cc +26 -0
  873. data/third_party/abseil-cpp/absl/time/civil_time.h +25 -0
  874. data/third_party/abseil-cpp/absl/time/clock.cc +17 -11
  875. data/third_party/abseil-cpp/absl/time/duration.cc +7 -7
  876. data/third_party/abseil-cpp/absl/time/format.cc +2 -1
  877. data/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_format.cc +1 -1
  878. data/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_info.cc +26 -5
  879. data/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_lookup.cc +7 -6
  880. data/third_party/abseil-cpp/absl/time/internal/cctz/src/zone_info_source.cc +36 -35
  881. data/third_party/abseil-cpp/absl/time/time.cc +2 -2
  882. data/third_party/abseil-cpp/absl/time/time.h +253 -158
  883. data/third_party/abseil-cpp/absl/types/internal/span.h +30 -19
  884. data/third_party/abseil-cpp/absl/types/internal/variant.h +28 -40
  885. data/third_party/abseil-cpp/absl/types/span.h +29 -7
  886. data/third_party/boringssl-with-bazel/src/crypto/x509v3/v3_genn.c +1 -1
  887. data/third_party/boringssl-with-bazel/src/include/openssl/x509v3.h +1 -2
  888. metadata +75 -10
  889. data/src/core/lib/event_engine/socket_notifier.h +0 -55
  890. data/src/core/lib/promise/for_each.h +0 -155
  891. data/src/core/lib/promise/map_pipe.h +0 -88
  892. data/src/core/lib/promise/try_concurrently.h +0 -342
@@ -186,6 +186,7 @@
186
186
  #include "absl/base/config.h"
187
187
  #include "absl/base/internal/endian.h"
188
188
  #include "absl/base/internal/prefetch.h"
189
+ #include "absl/base/internal/raw_logging.h"
189
190
  #include "absl/base/optimization.h"
190
191
  #include "absl/base/port.h"
191
192
  #include "absl/container/internal/common.h"
@@ -219,6 +220,29 @@ namespace absl {
219
220
  ABSL_NAMESPACE_BEGIN
220
221
  namespace container_internal {
221
222
 
223
+ #ifdef ABSL_SWISSTABLE_ENABLE_GENERATIONS
224
+ #error ABSL_SWISSTABLE_ENABLE_GENERATIONS cannot be directly set
225
+ #elif defined(ABSL_HAVE_ADDRESS_SANITIZER) || \
226
+ defined(ABSL_HAVE_MEMORY_SANITIZER)
227
+ // When compiled in sanitizer mode, we add generation integers to the backing
228
+ // array and iterators. In the backing array, we store the generation between
229
+ // the control bytes and the slots. When iterators are dereferenced, we assert
230
+ // that the container has not been mutated in a way that could cause iterator
231
+ // invalidation since the iterator was initialized.
232
+ #define ABSL_SWISSTABLE_ENABLE_GENERATIONS
233
+ #endif
234
+
235
+ // We use uint8_t so we don't need to worry about padding.
236
+ using GenerationType = uint8_t;
237
+
238
+ #ifdef ABSL_SWISSTABLE_ENABLE_GENERATIONS
239
+ constexpr bool SwisstableGenerationsEnabled() { return true; }
240
+ constexpr size_t NumGenerationBytes() { return sizeof(GenerationType); }
241
+ #else
242
+ constexpr bool SwisstableGenerationsEnabled() { return false; }
243
+ constexpr size_t NumGenerationBytes() { return 0; }
244
+ #endif
245
+
222
246
  template <typename AllocType>
223
247
  void SwapAlloc(AllocType& lhs, AllocType& rhs,
224
248
  std::true_type /* propagate_on_container_swap */) {
@@ -451,7 +475,7 @@ static_assert(ctrl_t::kDeleted == static_cast<ctrl_t>(-2),
451
475
  "ctrl_t::kDeleted must be -2 to make the implementation of "
452
476
  "ConvertSpecialToEmptyAndFullToDeleted efficient");
453
477
 
454
- ABSL_DLL extern const ctrl_t kEmptyGroup[16];
478
+ ABSL_DLL extern const ctrl_t kEmptyGroup[17];
455
479
 
456
480
  // Returns a pointer to a control byte group that can be used by empty tables.
457
481
  inline ctrl_t* EmptyGroup() {
@@ -460,6 +484,12 @@ inline ctrl_t* EmptyGroup() {
460
484
  return const_cast<ctrl_t*>(kEmptyGroup);
461
485
  }
462
486
 
487
+ // Returns a pointer to the generation byte at the end of the empty group, if it
488
+ // exists.
489
+ inline GenerationType* EmptyGeneration() {
490
+ return reinterpret_cast<GenerationType*>(EmptyGroup() + 16);
491
+ }
492
+
463
493
  // Mixes a randomly generated per-process seed with `hash` and `ctrl` to
464
494
  // randomize insertion order within groups.
465
495
  bool ShouldInsertBackwards(size_t hash, const ctrl_t* ctrl);
@@ -545,7 +575,7 @@ struct GroupSse2Impl {
545
575
 
546
576
  // Returns a bitmask representing the positions of slots that match hash.
547
577
  BitMask<uint32_t, kWidth> Match(h2_t hash) const {
548
- auto match = _mm_set1_epi8(hash);
578
+ auto match = _mm_set1_epi8(static_cast<char>(hash));
549
579
  return BitMask<uint32_t, kWidth>(
550
580
  static_cast<uint32_t>(_mm_movemask_epi8(_mm_cmpeq_epi8(match, ctrl))));
551
581
  }
@@ -557,7 +587,7 @@ struct GroupSse2Impl {
557
587
  return NonIterableBitMask<uint32_t, kWidth>(
558
588
  static_cast<uint32_t>(_mm_movemask_epi8(_mm_sign_epi8(ctrl, ctrl))));
559
589
  #else
560
- auto match = _mm_set1_epi8(static_cast<h2_t>(ctrl_t::kEmpty));
590
+ auto match = _mm_set1_epi8(static_cast<char>(ctrl_t::kEmpty));
561
591
  return NonIterableBitMask<uint32_t, kWidth>(
562
592
  static_cast<uint32_t>(_mm_movemask_epi8(_mm_cmpeq_epi8(match, ctrl))));
563
593
  #endif
@@ -565,14 +595,14 @@ struct GroupSse2Impl {
565
595
 
566
596
  // Returns a bitmask representing the positions of empty or deleted slots.
567
597
  NonIterableBitMask<uint32_t, kWidth> MaskEmptyOrDeleted() const {
568
- auto special = _mm_set1_epi8(static_cast<uint8_t>(ctrl_t::kSentinel));
598
+ auto special = _mm_set1_epi8(static_cast<char>(ctrl_t::kSentinel));
569
599
  return NonIterableBitMask<uint32_t, kWidth>(static_cast<uint32_t>(
570
600
  _mm_movemask_epi8(_mm_cmpgt_epi8_fixed(special, ctrl))));
571
601
  }
572
602
 
573
603
  // Returns the number of trailing empty or deleted elements in the group.
574
604
  uint32_t CountLeadingEmptyOrDeleted() const {
575
- auto special = _mm_set1_epi8(static_cast<uint8_t>(ctrl_t::kSentinel));
605
+ auto special = _mm_set1_epi8(static_cast<char>(ctrl_t::kSentinel));
576
606
  return TrailingZeros(static_cast<uint32_t>(
577
607
  _mm_movemask_epi8(_mm_cmpgt_epi8_fixed(special, ctrl)) + 1));
578
608
  }
@@ -612,9 +642,9 @@ struct GroupAArch64Impl {
612
642
 
613
643
  NonIterableBitMask<uint64_t, kWidth, 3> MaskEmpty() const {
614
644
  uint64_t mask =
615
- vget_lane_u64(vreinterpret_u64_u8(
616
- vceq_s8(vdup_n_s8(static_cast<h2_t>(ctrl_t::kEmpty)),
617
- vreinterpret_s8_u8(ctrl))),
645
+ vget_lane_u64(vreinterpret_u64_u8(vceq_s8(
646
+ vdup_n_s8(static_cast<int8_t>(ctrl_t::kEmpty)),
647
+ vreinterpret_s8_u8(ctrl))),
618
648
  0);
619
649
  return NonIterableBitMask<uint64_t, kWidth, 3>(mask);
620
650
  }
@@ -629,13 +659,16 @@ struct GroupAArch64Impl {
629
659
  }
630
660
 
631
661
  uint32_t CountLeadingEmptyOrDeleted() const {
632
- uint64_t mask = vget_lane_u64(vreinterpret_u64_u8(ctrl), 0);
633
- // ctrl | ~(ctrl >> 7) will have the lowest bit set to zero for kEmpty and
634
- // kDeleted. We lower all other bits and count number of trailing zeros.
662
+ uint64_t mask =
663
+ vget_lane_u64(vreinterpret_u64_u8(vcle_s8(
664
+ vdup_n_s8(static_cast<int8_t>(ctrl_t::kSentinel)),
665
+ vreinterpret_s8_u8(ctrl))),
666
+ 0);
667
+ // Similar to MaskEmptyorDeleted() but we invert the logic to invert the
668
+ // produced bitfield. We then count number of trailing zeros.
635
669
  // Clang and GCC optimize countr_zero to rbit+clz without any check for 0,
636
670
  // so we should be fine.
637
- constexpr uint64_t bits = 0x0101010101010101ULL;
638
- return countr_zero((mask | ~(mask >> 7)) & bits) >> 3;
671
+ return static_cast<uint32_t>(countr_zero(mask)) >> 3;
639
672
  }
640
673
 
641
674
  void ConvertSpecialToEmptyAndFullToDeleted(ctrl_t* dst) const {
@@ -693,7 +726,8 @@ struct GroupPortableImpl {
693
726
  // ctrl | ~(ctrl >> 7) will have the lowest bit set to zero for kEmpty and
694
727
  // kDeleted. We lower all other bits and count number of trailing zeros.
695
728
  constexpr uint64_t bits = 0x0101010101010101ULL;
696
- return countr_zero((ctrl | ~(ctrl >> 7)) & bits) >> 3;
729
+ return static_cast<uint32_t>(countr_zero((ctrl | ~(ctrl >> 7)) & bits) >>
730
+ 3);
697
731
  }
698
732
 
699
733
  void ConvertSpecialToEmptyAndFullToDeleted(ctrl_t* dst) const {
@@ -715,6 +749,192 @@ using Group = GroupAArch64Impl;
715
749
  using Group = GroupPortableImpl;
716
750
  #endif
717
751
 
752
+ class CommonFieldsGenerationInfoEnabled {
753
+ // A sentinel value for reserved_growth_ indicating that we just ran out of
754
+ // reserved growth on the last insertion. When reserve is called and then
755
+ // insertions take place, reserved_growth_'s state machine is N, ..., 1,
756
+ // kReservedGrowthJustRanOut, 0.
757
+ static constexpr size_t kReservedGrowthJustRanOut =
758
+ (std::numeric_limits<size_t>::max)();
759
+
760
+ public:
761
+ CommonFieldsGenerationInfoEnabled() = default;
762
+ CommonFieldsGenerationInfoEnabled(CommonFieldsGenerationInfoEnabled&& that)
763
+ : reserved_growth_(that.reserved_growth_), generation_(that.generation_) {
764
+ that.reserved_growth_ = 0;
765
+ that.generation_ = EmptyGeneration();
766
+ }
767
+ CommonFieldsGenerationInfoEnabled& operator=(
768
+ CommonFieldsGenerationInfoEnabled&&) = default;
769
+
770
+ // Whether we should rehash on insert in order to detect bugs of using invalid
771
+ // references. We rehash on the first insertion after reserved_growth_ reaches
772
+ // 0 after a call to reserve.
773
+ // TODO(b/254649633): we could potentially do a rehash with low probability
774
+ // whenever reserved_growth_ is zero.
775
+ bool should_rehash_for_bug_detection_on_insert() const {
776
+ return reserved_growth_ == kReservedGrowthJustRanOut;
777
+ }
778
+ void maybe_increment_generation_on_insert() {
779
+ if (reserved_growth_ == kReservedGrowthJustRanOut) reserved_growth_ = 0;
780
+
781
+ if (reserved_growth_ > 0) {
782
+ if (--reserved_growth_ == 0) reserved_growth_ = kReservedGrowthJustRanOut;
783
+ } else {
784
+ ++*generation_;
785
+ }
786
+ }
787
+ void reset_reserved_growth(size_t reservation, size_t size) {
788
+ reserved_growth_ = reservation - size;
789
+ }
790
+ size_t reserved_growth() const { return reserved_growth_; }
791
+ void set_reserved_growth(size_t r) { reserved_growth_ = r; }
792
+ GenerationType generation() const { return *generation_; }
793
+ void set_generation(GenerationType g) { *generation_ = g; }
794
+ GenerationType* generation_ptr() const { return generation_; }
795
+ void set_generation_ptr(GenerationType* g) { generation_ = g; }
796
+
797
+ private:
798
+ // The number of insertions remaining that are guaranteed to not rehash due to
799
+ // a prior call to reserve. Note: we store reserved growth rather than
800
+ // reservation size because calls to erase() decrease size_ but don't decrease
801
+ // reserved growth.
802
+ size_t reserved_growth_ = 0;
803
+ // Pointer to the generation counter, which is used to validate iterators and
804
+ // is stored in the backing array between the control bytes and the slots.
805
+ // Note that we can't store the generation inside the container itself and
806
+ // keep a pointer to the container in the iterators because iterators must
807
+ // remain valid when the container is moved.
808
+ // Note: we could derive this pointer from the control pointer, but it makes
809
+ // the code more complicated, and there's a benefit in having the sizes of
810
+ // raw_hash_set in sanitizer mode and non-sanitizer mode a bit more different,
811
+ // which is that tests are less likely to rely on the size remaining the same.
812
+ GenerationType* generation_ = EmptyGeneration();
813
+ };
814
+
815
+ class CommonFieldsGenerationInfoDisabled {
816
+ public:
817
+ CommonFieldsGenerationInfoDisabled() = default;
818
+ CommonFieldsGenerationInfoDisabled(CommonFieldsGenerationInfoDisabled&&) =
819
+ default;
820
+ CommonFieldsGenerationInfoDisabled& operator=(
821
+ CommonFieldsGenerationInfoDisabled&&) = default;
822
+
823
+ bool should_rehash_for_bug_detection_on_insert() const { return false; }
824
+ void maybe_increment_generation_on_insert() {}
825
+ void reset_reserved_growth(size_t, size_t) {}
826
+ size_t reserved_growth() const { return 0; }
827
+ void set_reserved_growth(size_t) {}
828
+ GenerationType generation() const { return 0; }
829
+ void set_generation(GenerationType) {}
830
+ GenerationType* generation_ptr() const { return nullptr; }
831
+ void set_generation_ptr(GenerationType*) {}
832
+ };
833
+
834
+ class HashSetIteratorGenerationInfoEnabled {
835
+ public:
836
+ HashSetIteratorGenerationInfoEnabled() = default;
837
+ explicit HashSetIteratorGenerationInfoEnabled(
838
+ const GenerationType* generation_ptr)
839
+ : generation_ptr_(generation_ptr), generation_(*generation_ptr) {}
840
+
841
+ GenerationType generation() const { return generation_; }
842
+ void reset_generation() { generation_ = *generation_ptr_; }
843
+ const GenerationType* generation_ptr() const { return generation_ptr_; }
844
+ void set_generation_ptr(const GenerationType* ptr) { generation_ptr_ = ptr; }
845
+
846
+ private:
847
+ const GenerationType* generation_ptr_ = EmptyGeneration();
848
+ GenerationType generation_ = *generation_ptr_;
849
+ };
850
+
851
+ class HashSetIteratorGenerationInfoDisabled {
852
+ public:
853
+ HashSetIteratorGenerationInfoDisabled() = default;
854
+ explicit HashSetIteratorGenerationInfoDisabled(const GenerationType*) {}
855
+
856
+ GenerationType generation() const { return 0; }
857
+ void reset_generation() {}
858
+ const GenerationType* generation_ptr() const { return nullptr; }
859
+ void set_generation_ptr(const GenerationType*) {}
860
+ };
861
+
862
+ #ifdef ABSL_SWISSTABLE_ENABLE_GENERATIONS
863
+ using CommonFieldsGenerationInfo = CommonFieldsGenerationInfoEnabled;
864
+ using HashSetIteratorGenerationInfo = HashSetIteratorGenerationInfoEnabled;
865
+ #else
866
+ using CommonFieldsGenerationInfo = CommonFieldsGenerationInfoDisabled;
867
+ using HashSetIteratorGenerationInfo = HashSetIteratorGenerationInfoDisabled;
868
+ #endif
869
+
870
+ // CommonFields hold the fields in raw_hash_set that do not depend
871
+ // on template parameters. This allows us to conveniently pass all
872
+ // of this state to helper functions as a single argument.
873
+ class CommonFields : public CommonFieldsGenerationInfo {
874
+ public:
875
+ CommonFields() = default;
876
+
877
+ // Not copyable
878
+ CommonFields(const CommonFields&) = delete;
879
+ CommonFields& operator=(const CommonFields&) = delete;
880
+
881
+ // Movable
882
+ CommonFields(CommonFields&& that)
883
+ : CommonFieldsGenerationInfo(
884
+ std::move(static_cast<CommonFieldsGenerationInfo&&>(that))),
885
+ // Explicitly copying fields into "this" and then resetting "that"
886
+ // fields generates less code then calling absl::exchange per field.
887
+ control_(that.control_),
888
+ slots_(that.slots_),
889
+ size_(that.size_),
890
+ capacity_(that.capacity_),
891
+ compressed_tuple_(that.growth_left(), std::move(that.infoz())) {
892
+ that.control_ = EmptyGroup();
893
+ that.slots_ = nullptr;
894
+ that.size_ = 0;
895
+ that.capacity_ = 0;
896
+ that.growth_left() = 0;
897
+ }
898
+ CommonFields& operator=(CommonFields&&) = default;
899
+
900
+ // The number of slots we can still fill without needing to rehash.
901
+ size_t& growth_left() { return compressed_tuple_.template get<0>(); }
902
+
903
+ HashtablezInfoHandle& infoz() { return compressed_tuple_.template get<1>(); }
904
+ const HashtablezInfoHandle& infoz() const {
905
+ return compressed_tuple_.template get<1>();
906
+ }
907
+
908
+ void reset_reserved_growth(size_t reservation) {
909
+ CommonFieldsGenerationInfo::reset_reserved_growth(reservation, size_);
910
+ }
911
+
912
+ // TODO(b/259599413): Investigate removing some of these fields:
913
+ // - control/slots can be derived from each other
914
+ // - size can be moved into the slot array
915
+
916
+ // The control bytes (and, also, a pointer to the base of the backing array).
917
+ //
918
+ // This contains `capacity + 1 + NumClonedBytes()` entries, even
919
+ // when the table is empty (hence EmptyGroup).
920
+ ctrl_t* control_ = EmptyGroup();
921
+
922
+ // The beginning of the slots, located at `SlotOffset()` bytes after
923
+ // `control`. May be null for empty tables.
924
+ void* slots_ = nullptr;
925
+
926
+ // The number of filled slots.
927
+ size_t size_ = 0;
928
+
929
+ // The total number of available slots.
930
+ size_t capacity_ = 0;
931
+
932
+ // Bundle together growth_left and HashtablezInfoHandle to ensure EBO for
933
+ // HashtablezInfoHandle when sampling is turned off.
934
+ absl::container_internal::CompressedTuple<size_t, HashtablezInfoHandle>
935
+ compressed_tuple_{0u, HashtablezInfoHandle{}};
936
+ };
937
+
718
938
  // Returns he number of "cloned control bytes".
719
939
  //
720
940
  // This is the number of control bytes that are present both at the beginning
@@ -730,6 +950,12 @@ class raw_hash_set;
730
950
  // A valid capacity is a non-zero integer `2^m - 1`.
731
951
  inline bool IsValidCapacity(size_t n) { return ((n + 1) & n) == 0 && n > 0; }
732
952
 
953
+ // Returns the next valid capacity after `n`.
954
+ inline size_t NextCapacity(size_t n) {
955
+ assert(IsValidCapacity(n) || n == 0);
956
+ return n * 2 + 1;
957
+ }
958
+
733
959
  // Applies the following mapping to every byte in the control array:
734
960
  // * kDeleted -> kEmpty
735
961
  // * kEmpty -> kEmpty
@@ -795,15 +1021,69 @@ size_t SelectBucketCountForIterRange(InputIter first, InputIter last,
795
1021
  return 0;
796
1022
  }
797
1023
 
798
- #define ABSL_INTERNAL_ASSERT_IS_FULL(ctrl, msg) \
799
- ABSL_HARDENING_ASSERT((ctrl != nullptr && IsFull(*ctrl)) && msg)
1024
+ #define ABSL_INTERNAL_ASSERT_IS_FULL(ctrl, generation, generation_ptr, \
1025
+ operation) \
1026
+ do { \
1027
+ ABSL_HARDENING_ASSERT( \
1028
+ (ctrl != nullptr) && operation \
1029
+ " called on invalid iterator. The iterator might be an end() " \
1030
+ "iterator or may have been default constructed."); \
1031
+ if (SwisstableGenerationsEnabled() && generation != *generation_ptr) \
1032
+ ABSL_INTERNAL_LOG(FATAL, operation \
1033
+ " called on invalidated iterator. The table could " \
1034
+ "have rehashed since this iterator was initialized."); \
1035
+ ABSL_HARDENING_ASSERT( \
1036
+ (IsFull(*ctrl)) && operation \
1037
+ " called on invalid iterator. The element might have been erased or " \
1038
+ "the table might have rehashed."); \
1039
+ } while (0)
1040
+
1041
+ // Note that for comparisons, null/end iterators are valid.
1042
+ inline void AssertIsValidForComparison(const ctrl_t* ctrl,
1043
+ GenerationType generation,
1044
+ const GenerationType* generation_ptr) {
1045
+ ABSL_HARDENING_ASSERT((ctrl == nullptr || IsFull(*ctrl)) &&
1046
+ "Invalid iterator comparison. The element might have "
1047
+ "been erased or the table might have rehashed.");
1048
+ if (SwisstableGenerationsEnabled() && generation != *generation_ptr) {
1049
+ ABSL_INTERNAL_LOG(FATAL,
1050
+ "Invalid iterator comparison. The table could have "
1051
+ "rehashed since this iterator was initialized.");
1052
+ }
1053
+ }
1054
+
1055
+ // If the two iterators come from the same container, then their pointers will
1056
+ // interleave such that ctrl_a <= ctrl_b < slot_a <= slot_b or vice/versa.
1057
+ // Note: we take slots by reference so that it's not UB if they're uninitialized
1058
+ // as long as we don't read them (when ctrl is null).
1059
+ inline bool AreItersFromSameContainer(const ctrl_t* ctrl_a,
1060
+ const ctrl_t* ctrl_b,
1061
+ const void* const& slot_a,
1062
+ const void* const& slot_b) {
1063
+ // If either control byte is null, then we can't tell.
1064
+ if (ctrl_a == nullptr || ctrl_b == nullptr) return true;
1065
+ const void* low_slot = slot_a;
1066
+ const void* hi_slot = slot_b;
1067
+ if (ctrl_a > ctrl_b) {
1068
+ std::swap(ctrl_a, ctrl_b);
1069
+ std::swap(low_slot, hi_slot);
1070
+ }
1071
+ return ctrl_b < low_slot && low_slot <= hi_slot;
1072
+ }
800
1073
 
801
- inline void AssertIsValid(ctrl_t* ctrl) {
1074
+ // Asserts that two iterators come from the same container.
1075
+ // Note: we take slots by reference so that it's not UB if they're uninitialized
1076
+ // as long as we don't read them (when ctrl is null).
1077
+ // TODO(b/254649633): when generations are enabled, we can detect more cases of
1078
+ // different containers by comparing the pointers to the generations - this
1079
+ // can cover cases of end iterators that we would otherwise miss.
1080
+ inline void AssertSameContainer(const ctrl_t* ctrl_a, const ctrl_t* ctrl_b,
1081
+ const void* const& slot_a,
1082
+ const void* const& slot_b) {
802
1083
  ABSL_HARDENING_ASSERT(
803
- (ctrl == nullptr || IsFull(*ctrl)) &&
804
- "Invalid operation on iterator. The element might have "
805
- "been erased, the table might have rehashed, or this may "
806
- "be an end() iterator.");
1084
+ AreItersFromSameContainer(ctrl_a, ctrl_b, slot_a, slot_b) &&
1085
+ "Invalid iterator comparison. The iterators may be from different "
1086
+ "containers or the container might have rehashed.");
807
1087
  }
808
1088
 
809
1089
  struct FindInfo {
@@ -825,9 +1105,10 @@ struct FindInfo {
825
1105
  // `ShouldInsertBackwards()` for small tables.
826
1106
  inline bool is_small(size_t capacity) { return capacity < Group::kWidth - 1; }
827
1107
 
828
- // Begins a probing operation on `ctrl`, using `hash`.
829
- inline probe_seq<Group::kWidth> probe(const ctrl_t* ctrl, size_t hash,
830
- size_t capacity) {
1108
+ // Begins a probing operation on `common.control`, using `hash`.
1109
+ inline probe_seq<Group::kWidth> probe(const CommonFields& common, size_t hash) {
1110
+ const ctrl_t* ctrl = common.control_;
1111
+ const size_t capacity = common.capacity_;
831
1112
  return probe_seq<Group::kWidth>(H1(hash, ctrl), capacity);
832
1113
  }
833
1114
 
@@ -839,9 +1120,9 @@ inline probe_seq<Group::kWidth> probe(const ctrl_t* ctrl, size_t hash,
839
1120
  // NOTE: this function must work with tables having both empty and deleted
840
1121
  // slots in the same group. Such tables appear during `erase()`.
841
1122
  template <typename = void>
842
- inline FindInfo find_first_non_full(const ctrl_t* ctrl, size_t hash,
843
- size_t capacity) {
844
- auto seq = probe(ctrl, hash, capacity);
1123
+ inline FindInfo find_first_non_full(const CommonFields& common, size_t hash) {
1124
+ auto seq = probe(common, hash);
1125
+ const ctrl_t* ctrl = common.control_;
845
1126
  while (true) {
846
1127
  Group g{ctrl + seq.offset()};
847
1128
  auto mask = g.MaskEmptyOrDeleted();
@@ -851,55 +1132,75 @@ inline FindInfo find_first_non_full(const ctrl_t* ctrl, size_t hash,
851
1132
  // In debug build we will randomly insert in either the front or back of
852
1133
  // the group.
853
1134
  // TODO(kfm,sbenza): revisit after we do unconditional mixing
854
- if (!is_small(capacity) && ShouldInsertBackwards(hash, ctrl)) {
1135
+ if (!is_small(common.capacity_) && ShouldInsertBackwards(hash, ctrl)) {
855
1136
  return {seq.offset(mask.HighestBitSet()), seq.index()};
856
1137
  }
857
1138
  #endif
858
1139
  return {seq.offset(mask.LowestBitSet()), seq.index()};
859
1140
  }
860
1141
  seq.next();
861
- assert(seq.index() <= capacity && "full table!");
1142
+ assert(seq.index() <= common.capacity_ && "full table!");
862
1143
  }
863
1144
  }
864
1145
 
865
1146
  // Extern template for inline function keep possibility of inlining.
866
1147
  // When compiler decided to not inline, no symbols will be added to the
867
1148
  // corresponding translation unit.
868
- extern template FindInfo find_first_non_full(const ctrl_t*, size_t, size_t);
1149
+ extern template FindInfo find_first_non_full(const CommonFields&, size_t);
1150
+
1151
+ // Non-inlined version of find_first_non_full for use in less
1152
+ // performance critical routines.
1153
+ FindInfo find_first_non_full_outofline(const CommonFields&, size_t);
1154
+
1155
+ inline void ResetGrowthLeft(CommonFields& common) {
1156
+ common.growth_left() = CapacityToGrowth(common.capacity_) - common.size_;
1157
+ }
869
1158
 
870
1159
  // Sets `ctrl` to `{kEmpty, kSentinel, ..., kEmpty}`, marking the entire
871
1160
  // array as marked as empty.
872
- inline void ResetCtrl(size_t capacity, ctrl_t* ctrl, const void* slot,
873
- size_t slot_size) {
1161
+ inline void ResetCtrl(CommonFields& common, size_t slot_size) {
1162
+ const size_t capacity = common.capacity_;
1163
+ ctrl_t* ctrl = common.control_;
874
1164
  std::memset(ctrl, static_cast<int8_t>(ctrl_t::kEmpty),
875
1165
  capacity + 1 + NumClonedBytes());
876
1166
  ctrl[capacity] = ctrl_t::kSentinel;
877
- SanitizerPoisonMemoryRegion(slot, slot_size * capacity);
1167
+ SanitizerPoisonMemoryRegion(common.slots_, slot_size * capacity);
1168
+ ResetGrowthLeft(common);
878
1169
  }
879
1170
 
880
1171
  // Sets `ctrl[i]` to `h`.
881
1172
  //
882
1173
  // Unlike setting it directly, this function will perform bounds checks and
883
1174
  // mirror the value to the cloned tail if necessary.
884
- inline void SetCtrl(size_t i, ctrl_t h, size_t capacity, ctrl_t* ctrl,
885
- const void* slot, size_t slot_size) {
1175
+ inline void SetCtrl(const CommonFields& common, size_t i, ctrl_t h,
1176
+ size_t slot_size) {
1177
+ const size_t capacity = common.capacity_;
886
1178
  assert(i < capacity);
887
1179
 
888
- auto* slot_i = static_cast<const char*>(slot) + i * slot_size;
1180
+ auto* slot_i = static_cast<const char*>(common.slots_) + i * slot_size;
889
1181
  if (IsFull(h)) {
890
1182
  SanitizerUnpoisonMemoryRegion(slot_i, slot_size);
891
1183
  } else {
892
1184
  SanitizerPoisonMemoryRegion(slot_i, slot_size);
893
1185
  }
894
1186
 
1187
+ ctrl_t* ctrl = common.control_;
895
1188
  ctrl[i] = h;
896
1189
  ctrl[((i - NumClonedBytes()) & capacity) + (NumClonedBytes() & capacity)] = h;
897
1190
  }
898
1191
 
899
1192
  // Overload for setting to an occupied `h2_t` rather than a special `ctrl_t`.
900
- inline void SetCtrl(size_t i, h2_t h, size_t capacity, ctrl_t* ctrl,
901
- const void* slot, size_t slot_size) {
902
- SetCtrl(i, static_cast<ctrl_t>(h), capacity, ctrl, slot, slot_size);
1193
+ inline void SetCtrl(const CommonFields& common, size_t i, h2_t h,
1194
+ size_t slot_size) {
1195
+ SetCtrl(common, i, static_cast<ctrl_t>(h), slot_size);
1196
+ }
1197
+
1198
+ // Given the capacity of a table, computes the offset (from the start of the
1199
+ // backing allocation) of the generation counter (if it exists).
1200
+ inline size_t GenerationOffset(size_t capacity) {
1201
+ assert(IsValidCapacity(capacity));
1202
+ const size_t num_control_bytes = capacity + 1 + NumClonedBytes();
1203
+ return num_control_bytes;
903
1204
  }
904
1205
 
905
1206
  // Given the capacity of a table, computes the offset (from the start of the
@@ -907,7 +1208,8 @@ inline void SetCtrl(size_t i, h2_t h, size_t capacity, ctrl_t* ctrl,
907
1208
  inline size_t SlotOffset(size_t capacity, size_t slot_align) {
908
1209
  assert(IsValidCapacity(capacity));
909
1210
  const size_t num_control_bytes = capacity + 1 + NumClonedBytes();
910
- return (num_control_bytes + slot_align - 1) & (~slot_align + 1);
1211
+ return (num_control_bytes + NumGenerationBytes() + slot_align - 1) &
1212
+ (~slot_align + 1);
911
1213
  }
912
1214
 
913
1215
  // Given the capacity of a table, computes the total size of the backing
@@ -916,6 +1218,91 @@ inline size_t AllocSize(size_t capacity, size_t slot_size, size_t slot_align) {
916
1218
  return SlotOffset(capacity, slot_align) + capacity * slot_size;
917
1219
  }
918
1220
 
1221
+ template <typename Alloc, size_t SizeOfSlot, size_t AlignOfSlot>
1222
+ ABSL_ATTRIBUTE_NOINLINE void InitializeSlots(CommonFields& c, Alloc alloc) {
1223
+ assert(c.capacity_);
1224
+ // Folks with custom allocators often make unwarranted assumptions about the
1225
+ // behavior of their classes vis-a-vis trivial destructability and what
1226
+ // calls they will or won't make. Avoid sampling for people with custom
1227
+ // allocators to get us out of this mess. This is not a hard guarantee but
1228
+ // a workaround while we plan the exact guarantee we want to provide.
1229
+ const size_t sample_size =
1230
+ (std::is_same<Alloc, std::allocator<char>>::value && c.slots_ == nullptr)
1231
+ ? SizeOfSlot
1232
+ : 0;
1233
+
1234
+ const size_t cap = c.capacity_;
1235
+ char* mem = static_cast<char*>(
1236
+ Allocate<AlignOfSlot>(&alloc, AllocSize(cap, SizeOfSlot, AlignOfSlot)));
1237
+ const GenerationType old_generation = c.generation();
1238
+ c.set_generation_ptr(
1239
+ reinterpret_cast<GenerationType*>(mem + GenerationOffset(cap)));
1240
+ c.set_generation(old_generation + 1);
1241
+ c.control_ = reinterpret_cast<ctrl_t*>(mem);
1242
+ c.slots_ = mem + SlotOffset(cap, AlignOfSlot);
1243
+ ResetCtrl(c, SizeOfSlot);
1244
+ if (sample_size) {
1245
+ c.infoz() = Sample(sample_size);
1246
+ }
1247
+ c.infoz().RecordStorageChanged(c.size_, cap);
1248
+ }
1249
+
1250
+ // PolicyFunctions bundles together some information for a particular
1251
+ // raw_hash_set<T, ...> instantiation. This information is passed to
1252
+ // type-erased functions that want to do small amounts of type-specific
1253
+ // work.
1254
+ struct PolicyFunctions {
1255
+ size_t slot_size;
1256
+
1257
+ // Return the hash of the pointed-to slot.
1258
+ size_t (*hash_slot)(void* set, void* slot);
1259
+
1260
+ // Transfer the contents of src_slot to dst_slot.
1261
+ void (*transfer)(void* set, void* dst_slot, void* src_slot);
1262
+
1263
+ // Deallocate the specified backing store which is sized for n slots.
1264
+ void (*dealloc)(void* set, const PolicyFunctions& policy, ctrl_t* ctrl,
1265
+ void* slot_array, size_t n);
1266
+ };
1267
+
1268
+ // ClearBackingArray clears the backing array, either modifying it in place,
1269
+ // or creating a new one based on the value of "reuse".
1270
+ // REQUIRES: c.capacity > 0
1271
+ void ClearBackingArray(CommonFields& c, const PolicyFunctions& policy,
1272
+ bool reuse);
1273
+
1274
+ // Type-erased version of raw_hash_set::erase_meta_only.
1275
+ void EraseMetaOnly(CommonFields& c, ctrl_t* it, size_t slot_size);
1276
+
1277
+ // Function to place in PolicyFunctions::dealloc for raw_hash_sets
1278
+ // that are using std::allocator. This allows us to share the same
1279
+ // function body for raw_hash_set instantiations that have the
1280
+ // same slot alignment.
1281
+ template <size_t AlignOfSlot>
1282
+ ABSL_ATTRIBUTE_NOINLINE void DeallocateStandard(void*,
1283
+ const PolicyFunctions& policy,
1284
+ ctrl_t* ctrl, void* slot_array,
1285
+ size_t n) {
1286
+ // Unpoison before returning the memory to the allocator.
1287
+ SanitizerUnpoisonMemoryRegion(slot_array, policy.slot_size * n);
1288
+
1289
+ std::allocator<char> alloc;
1290
+ Deallocate<AlignOfSlot>(&alloc, ctrl,
1291
+ AllocSize(n, policy.slot_size, AlignOfSlot));
1292
+ }
1293
+
1294
+ // For trivially relocatable types we use memcpy directly. This allows us to
1295
+ // share the same function body for raw_hash_set instantiations that have the
1296
+ // same slot size as long as they are relocatable.
1297
+ template <size_t SizeOfSlot>
1298
+ ABSL_ATTRIBUTE_NOINLINE void TransferRelocatable(void*, void* dst, void* src) {
1299
+ memcpy(dst, src, SizeOfSlot);
1300
+ }
1301
+
1302
+ // Type-erased version of raw_hash_set::drop_deletes_without_resize.
1303
+ void DropDeletesWithoutResize(CommonFields& common,
1304
+ const PolicyFunctions& policy, void* tmp_space);
1305
+
919
1306
  // A SwissTable.
920
1307
  //
921
1308
  // Policy: a policy defines how to perform different operations on
@@ -1016,7 +1403,7 @@ class raw_hash_set {
1016
1403
  static_assert(std::is_same<const_pointer, const value_type*>::value,
1017
1404
  "Allocators with custom pointer types are not supported");
1018
1405
 
1019
- class iterator {
1406
+ class iterator : private HashSetIteratorGenerationInfo {
1020
1407
  friend class raw_hash_set;
1021
1408
 
1022
1409
  public:
@@ -1032,22 +1419,22 @@ class raw_hash_set {
1032
1419
 
1033
1420
  // PRECONDITION: not an end() iterator.
1034
1421
  reference operator*() const {
1035
- ABSL_INTERNAL_ASSERT_IS_FULL(ctrl_,
1036
- "operator*() called on invalid iterator.");
1422
+ ABSL_INTERNAL_ASSERT_IS_FULL(ctrl_, generation(), generation_ptr(),
1423
+ "operator*()");
1037
1424
  return PolicyTraits::element(slot_);
1038
1425
  }
1039
1426
 
1040
1427
  // PRECONDITION: not an end() iterator.
1041
1428
  pointer operator->() const {
1042
- ABSL_INTERNAL_ASSERT_IS_FULL(ctrl_,
1043
- "operator-> called on invalid iterator.");
1429
+ ABSL_INTERNAL_ASSERT_IS_FULL(ctrl_, generation(), generation_ptr(),
1430
+ "operator->");
1044
1431
  return &operator*();
1045
1432
  }
1046
1433
 
1047
1434
  // PRECONDITION: not an end() iterator.
1048
1435
  iterator& operator++() {
1049
- ABSL_INTERNAL_ASSERT_IS_FULL(ctrl_,
1050
- "operator++ called on invalid iterator.");
1436
+ ABSL_INTERNAL_ASSERT_IS_FULL(ctrl_, generation(), generation_ptr(),
1437
+ "operator++");
1051
1438
  ++ctrl_;
1052
1439
  ++slot_;
1053
1440
  skip_empty_or_deleted();
@@ -1061,8 +1448,9 @@ class raw_hash_set {
1061
1448
  }
1062
1449
 
1063
1450
  friend bool operator==(const iterator& a, const iterator& b) {
1064
- AssertIsValid(a.ctrl_);
1065
- AssertIsValid(b.ctrl_);
1451
+ AssertSameContainer(a.ctrl_, b.ctrl_, a.slot_, b.slot_);
1452
+ AssertIsValidForComparison(a.ctrl_, a.generation(), a.generation_ptr());
1453
+ AssertIsValidForComparison(b.ctrl_, b.generation(), b.generation_ptr());
1066
1454
  return a.ctrl_ == b.ctrl_;
1067
1455
  }
1068
1456
  friend bool operator!=(const iterator& a, const iterator& b) {
@@ -1070,16 +1458,23 @@ class raw_hash_set {
1070
1458
  }
1071
1459
 
1072
1460
  private:
1073
- iterator(ctrl_t* ctrl, slot_type* slot) : ctrl_(ctrl), slot_(slot) {
1461
+ iterator(ctrl_t* ctrl, slot_type* slot,
1462
+ const GenerationType* generation_ptr)
1463
+ : HashSetIteratorGenerationInfo(generation_ptr),
1464
+ ctrl_(ctrl),
1465
+ slot_(slot) {
1074
1466
  // This assumption helps the compiler know that any non-end iterator is
1075
1467
  // not equal to any end iterator.
1076
1468
  ABSL_ASSUME(ctrl != nullptr);
1077
1469
  }
1470
+ // For end() iterators.
1471
+ explicit iterator(const GenerationType* generation_ptr)
1472
+ : HashSetIteratorGenerationInfo(generation_ptr) {}
1078
1473
 
1079
1474
  // Fixes up `ctrl_` to point to a full by advancing it and `slot_` until
1080
1475
  // they reach one.
1081
1476
  //
1082
- // If a sentinel is reached, we null both of them out instead.
1477
+ // If a sentinel is reached, we null `ctrl_` out instead.
1083
1478
  void skip_empty_or_deleted() {
1084
1479
  while (IsEmptyOrDeleted(*ctrl_)) {
1085
1480
  uint32_t shift = Group{ctrl_}.CountLeadingEmptyOrDeleted();
@@ -1107,9 +1502,9 @@ class raw_hash_set {
1107
1502
  using pointer = typename raw_hash_set::const_pointer;
1108
1503
  using difference_type = typename raw_hash_set::difference_type;
1109
1504
 
1110
- const_iterator() {}
1505
+ const_iterator() = default;
1111
1506
  // Implicit construction from iterator.
1112
- const_iterator(iterator i) : inner_(std::move(i)) {}
1507
+ const_iterator(iterator i) : inner_(std::move(i)) {} // NOLINT
1113
1508
 
1114
1509
  reference operator*() const { return *inner_; }
1115
1510
  pointer operator->() const { return inner_.operator->(); }
@@ -1128,8 +1523,10 @@ class raw_hash_set {
1128
1523
  }
1129
1524
 
1130
1525
  private:
1131
- const_iterator(const ctrl_t* ctrl, const slot_type* slot)
1132
- : inner_(const_cast<ctrl_t*>(ctrl), const_cast<slot_type*>(slot)) {}
1526
+ const_iterator(const ctrl_t* ctrl, const slot_type* slot,
1527
+ const GenerationType* gen)
1528
+ : inner_(const_cast<ctrl_t*>(ctrl), const_cast<slot_type*>(slot), gen) {
1529
+ }
1133
1530
 
1134
1531
  iterator inner_;
1135
1532
  };
@@ -1137,18 +1534,20 @@ class raw_hash_set {
1137
1534
  using node_type = node_handle<Policy, hash_policy_traits<Policy>, Alloc>;
1138
1535
  using insert_return_type = InsertReturnType<iterator, node_type>;
1139
1536
 
1537
+ // Note: can't use `= default` due to non-default noexcept (causes
1538
+ // problems for some compilers). NOLINTNEXTLINE
1140
1539
  raw_hash_set() noexcept(
1141
1540
  std::is_nothrow_default_constructible<hasher>::value&&
1142
1541
  std::is_nothrow_default_constructible<key_equal>::value&&
1143
1542
  std::is_nothrow_default_constructible<allocator_type>::value) {}
1144
1543
 
1145
- explicit raw_hash_set(size_t bucket_count, const hasher& hash = hasher(),
1146
- const key_equal& eq = key_equal(),
1147
- const allocator_type& alloc = allocator_type())
1148
- : ctrl_(EmptyGroup()),
1149
- settings_(0, HashtablezInfoHandle(), hash, eq, alloc) {
1544
+ ABSL_ATTRIBUTE_NOINLINE explicit raw_hash_set(
1545
+ size_t bucket_count, const hasher& hash = hasher(),
1546
+ const key_equal& eq = key_equal(),
1547
+ const allocator_type& alloc = allocator_type())
1548
+ : settings_(CommonFields{}, hash, eq, alloc) {
1150
1549
  if (bucket_count) {
1151
- capacity_ = NormalizeCapacity(bucket_count);
1550
+ common().capacity_ = NormalizeCapacity(bucket_count);
1152
1551
  initialize_slots();
1153
1552
  }
1154
1553
  }
@@ -1255,45 +1654,30 @@ class raw_hash_set {
1255
1654
  // than a full `insert`.
1256
1655
  for (const auto& v : that) {
1257
1656
  const size_t hash = PolicyTraits::apply(HashElement{hash_ref()}, v);
1258
- auto target = find_first_non_full(ctrl_, hash, capacity_);
1259
- SetCtrl(target.offset, H2(hash), capacity_, ctrl_, slots_,
1260
- sizeof(slot_type));
1657
+ auto target = find_first_non_full_outofline(common(), hash);
1658
+ SetCtrl(common(), target.offset, H2(hash), sizeof(slot_type));
1261
1659
  emplace_at(target.offset, v);
1660
+ common().maybe_increment_generation_on_insert();
1262
1661
  infoz().RecordInsert(hash, target.probe_length);
1263
1662
  }
1264
- size_ = that.size();
1663
+ common().size_ = that.size();
1265
1664
  growth_left() -= that.size();
1266
1665
  }
1267
1666
 
1268
- raw_hash_set(raw_hash_set&& that) noexcept(
1667
+ ABSL_ATTRIBUTE_NOINLINE raw_hash_set(raw_hash_set&& that) noexcept(
1269
1668
  std::is_nothrow_copy_constructible<hasher>::value&&
1270
1669
  std::is_nothrow_copy_constructible<key_equal>::value&&
1271
1670
  std::is_nothrow_copy_constructible<allocator_type>::value)
1272
- : ctrl_(absl::exchange(that.ctrl_, EmptyGroup())),
1273
- slots_(absl::exchange(that.slots_, nullptr)),
1274
- size_(absl::exchange(that.size_, 0)),
1275
- capacity_(absl::exchange(that.capacity_, 0)),
1276
- // Hash, equality and allocator are copied instead of moved because
1277
- // `that` must be left valid. If Hash is std::function<Key>, moving it
1278
- // would create a nullptr functor that cannot be called.
1279
- settings_(absl::exchange(that.growth_left(), 0),
1280
- absl::exchange(that.infoz(), HashtablezInfoHandle()),
1671
+ : // Hash, equality and allocator are copied instead of moved because
1672
+ // `that` must be left valid. If Hash is std::function<Key>, moving it
1673
+ // would create a nullptr functor that cannot be called.
1674
+ settings_(absl::exchange(that.common(), CommonFields{}),
1281
1675
  that.hash_ref(), that.eq_ref(), that.alloc_ref()) {}
1282
1676
 
1283
1677
  raw_hash_set(raw_hash_set&& that, const allocator_type& a)
1284
- : ctrl_(EmptyGroup()),
1285
- slots_(nullptr),
1286
- size_(0),
1287
- capacity_(0),
1288
- settings_(0, HashtablezInfoHandle(), that.hash_ref(), that.eq_ref(),
1289
- a) {
1678
+ : settings_(CommonFields{}, that.hash_ref(), that.eq_ref(), a) {
1290
1679
  if (a == that.alloc_ref()) {
1291
- std::swap(ctrl_, that.ctrl_);
1292
- std::swap(slots_, that.slots_);
1293
- std::swap(size_, that.size_);
1294
- std::swap(capacity_, that.capacity_);
1295
- std::swap(growth_left(), that.growth_left());
1296
- std::swap(infoz(), that.infoz());
1680
+ std::swap(common(), that.common());
1297
1681
  } else {
1298
1682
  reserve(that.size());
1299
1683
  // Note: this will copy elements of dense_set and unordered_set instead of
@@ -1317,30 +1701,43 @@ class raw_hash_set {
1317
1701
  std::is_nothrow_move_assignable<key_equal>::value) {
1318
1702
  // TODO(sbenza): We should only use the operations from the noexcept clause
1319
1703
  // to make sure we actually adhere to that contract.
1704
+ // NOLINTNEXTLINE: not returning *this for performance.
1320
1705
  return move_assign(
1321
1706
  std::move(that),
1322
1707
  typename AllocTraits::propagate_on_container_move_assignment());
1323
1708
  }
1324
1709
 
1325
- ~raw_hash_set() { destroy_slots(); }
1710
+ ~raw_hash_set() {
1711
+ const size_t cap = capacity();
1712
+ if (!cap) return;
1713
+ destroy_slots();
1714
+
1715
+ // Unpoison before returning the memory to the allocator.
1716
+ SanitizerUnpoisonMemoryRegion(slot_array(), sizeof(slot_type) * cap);
1717
+ Deallocate<alignof(slot_type)>(
1718
+ &alloc_ref(), control(),
1719
+ AllocSize(cap, sizeof(slot_type), alignof(slot_type)));
1720
+
1721
+ infoz().Unregister();
1722
+ }
1326
1723
 
1327
1724
  iterator begin() {
1328
1725
  auto it = iterator_at(0);
1329
1726
  it.skip_empty_or_deleted();
1330
1727
  return it;
1331
1728
  }
1332
- iterator end() { return {}; }
1729
+ iterator end() { return iterator(common().generation_ptr()); }
1333
1730
 
1334
1731
  const_iterator begin() const {
1335
1732
  return const_cast<raw_hash_set*>(this)->begin();
1336
1733
  }
1337
- const_iterator end() const { return {}; }
1734
+ const_iterator end() const { return iterator(common().generation_ptr()); }
1338
1735
  const_iterator cbegin() const { return begin(); }
1339
1736
  const_iterator cend() const { return end(); }
1340
1737
 
1341
1738
  bool empty() const { return !size(); }
1342
- size_t size() const { return size_; }
1343
- size_t capacity() const { return capacity_; }
1739
+ size_t size() const { return common().size_; }
1740
+ size_t capacity() const { return common().capacity_; }
1344
1741
  size_t max_size() const { return (std::numeric_limits<size_t>::max)(); }
1345
1742
 
1346
1743
  ABSL_ATTRIBUTE_REINITIALIZES void clear() {
@@ -1351,22 +1748,26 @@ class raw_hash_set {
1351
1748
  // compared to destruction of the elements of the container. So we pick the
1352
1749
  // largest bucket_count() threshold for which iteration is still fast and
1353
1750
  // past that we simply deallocate the array.
1354
- if (capacity_ > 127) {
1751
+ const size_t cap = capacity();
1752
+ if (cap == 0) {
1753
+ // Already guaranteed to be empty; so nothing to do.
1754
+ } else {
1355
1755
  destroy_slots();
1756
+ ClearBackingArray(common(), GetPolicyFunctions(),
1757
+ /*reuse=*/cap < 128);
1758
+ }
1759
+ common().set_reserved_growth(0);
1760
+ }
1356
1761
 
1357
- infoz().RecordClearedReservation();
1358
- } else if (capacity_) {
1359
- for (size_t i = 0; i != capacity_; ++i) {
1360
- if (IsFull(ctrl_[i])) {
1361
- PolicyTraits::destroy(&alloc_ref(), slots_ + i);
1362
- }
1762
+ inline void destroy_slots() {
1763
+ const size_t cap = capacity();
1764
+ const ctrl_t* ctrl = control();
1765
+ slot_type* slot = slot_array();
1766
+ for (size_t i = 0; i != cap; ++i) {
1767
+ if (IsFull(ctrl[i])) {
1768
+ PolicyTraits::destroy(&alloc_ref(), slot + i);
1363
1769
  }
1364
- size_ = 0;
1365
- ResetCtrl(capacity_, ctrl_, slots_, sizeof(slot_type));
1366
- reset_growth_left();
1367
1770
  }
1368
- assert(empty());
1369
- infoz().RecordStorageChanged(0, capacity_);
1370
1771
  }
1371
1772
 
1372
1773
  // This overload kicks in when the argument is an rvalue of insertable and
@@ -1554,7 +1955,7 @@ class raw_hash_set {
1554
1955
  iterator lazy_emplace(const key_arg<K>& key, F&& f) {
1555
1956
  auto res = find_or_prepare_insert(key);
1556
1957
  if (res.second) {
1557
- slot_type* slot = slots_ + res.first;
1958
+ slot_type* slot = slot_array() + res.first;
1558
1959
  std::forward<F>(f)(constructor(&alloc_ref(), &slot));
1559
1960
  assert(!slot);
1560
1961
  }
@@ -1596,8 +1997,8 @@ class raw_hash_set {
1596
1997
  // This overload is necessary because otherwise erase<K>(const K&) would be
1597
1998
  // a better match if non-const iterator is passed as an argument.
1598
1999
  void erase(iterator it) {
1599
- ABSL_INTERNAL_ASSERT_IS_FULL(it.ctrl_,
1600
- "erase() called on invalid iterator.");
2000
+ ABSL_INTERNAL_ASSERT_IS_FULL(it.ctrl_, it.generation(), it.generation_ptr(),
2001
+ "erase()");
1601
2002
  PolicyTraits::destroy(&alloc_ref(), it.slot_);
1602
2003
  erase_meta_only(it);
1603
2004
  }
@@ -1632,7 +2033,8 @@ class raw_hash_set {
1632
2033
 
1633
2034
  node_type extract(const_iterator position) {
1634
2035
  ABSL_INTERNAL_ASSERT_IS_FULL(position.inner_.ctrl_,
1635
- "extract() called on invalid iterator.");
2036
+ position.inner_.generation(),
2037
+ position.inner_.generation_ptr(), "extract()");
1636
2038
  auto node =
1637
2039
  CommonAccess::Transfer<node_type>(alloc_ref(), position.inner_.slot_);
1638
2040
  erase_meta_only(position);
@@ -1652,24 +2054,18 @@ class raw_hash_set {
1652
2054
  IsNoThrowSwappable<allocator_type>(
1653
2055
  typename AllocTraits::propagate_on_container_swap{})) {
1654
2056
  using std::swap;
1655
- swap(ctrl_, that.ctrl_);
1656
- swap(slots_, that.slots_);
1657
- swap(size_, that.size_);
1658
- swap(capacity_, that.capacity_);
1659
- swap(growth_left(), that.growth_left());
2057
+ swap(common(), that.common());
1660
2058
  swap(hash_ref(), that.hash_ref());
1661
2059
  swap(eq_ref(), that.eq_ref());
1662
- swap(infoz(), that.infoz());
1663
2060
  SwapAlloc(alloc_ref(), that.alloc_ref(),
1664
2061
  typename AllocTraits::propagate_on_container_swap{});
1665
2062
  }
1666
2063
 
1667
2064
  void rehash(size_t n) {
1668
- if (n == 0 && capacity_ == 0) return;
1669
- if (n == 0 && size_ == 0) {
1670
- destroy_slots();
1671
- infoz().RecordStorageChanged(0, 0);
1672
- infoz().RecordClearedReservation();
2065
+ if (n == 0 && capacity() == 0) return;
2066
+ if (n == 0 && size() == 0) {
2067
+ ClearBackingArray(common(), GetPolicyFunctions(),
2068
+ /*reuse=*/false);
1673
2069
  return;
1674
2070
  }
1675
2071
 
@@ -1677,7 +2073,7 @@ class raw_hash_set {
1677
2073
  // power-of-2-minus-1, so bitor is good enough.
1678
2074
  auto m = NormalizeCapacity(n | GrowthToLowerboundCapacity(size()));
1679
2075
  // n == 0 unconditionally rehashes as per the standard.
1680
- if (n == 0 || m > capacity_) {
2076
+ if (n == 0 || m > capacity()) {
1681
2077
  resize(m);
1682
2078
 
1683
2079
  // This is after resize, to ensure that we have completed the allocation
@@ -1695,6 +2091,7 @@ class raw_hash_set {
1695
2091
  // and have potentially sampled the hashtable.
1696
2092
  infoz().RecordReservation(n);
1697
2093
  }
2094
+ common().reset_reserved_growth(n);
1698
2095
  }
1699
2096
 
1700
2097
  // Extension API: support for heterogeneous keys.
@@ -1722,9 +2119,9 @@ class raw_hash_set {
1722
2119
  // Avoid probing if we won't be able to prefetch the addresses received.
1723
2120
  #ifdef ABSL_INTERNAL_HAVE_PREFETCH
1724
2121
  prefetch_heap_block();
1725
- auto seq = probe(ctrl_, hash_ref()(key), capacity_);
1726
- base_internal::PrefetchT0(ctrl_ + seq.offset());
1727
- base_internal::PrefetchT0(slots_ + seq.offset());
2122
+ auto seq = probe(common(), hash_ref()(key));
2123
+ base_internal::PrefetchT0(control() + seq.offset());
2124
+ base_internal::PrefetchT0(slot_array() + seq.offset());
1728
2125
  #endif // ABSL_INTERNAL_HAVE_PREFETCH
1729
2126
  }
1730
2127
 
@@ -1737,18 +2134,20 @@ class raw_hash_set {
1737
2134
  // called heterogeneous key support.
1738
2135
  template <class K = key_type>
1739
2136
  iterator find(const key_arg<K>& key, size_t hash) {
1740
- auto seq = probe(ctrl_, hash, capacity_);
2137
+ auto seq = probe(common(), hash);
2138
+ slot_type* slot_ptr = slot_array();
2139
+ const ctrl_t* ctrl = control();
1741
2140
  while (true) {
1742
- Group g{ctrl_ + seq.offset()};
2141
+ Group g{ctrl + seq.offset()};
1743
2142
  for (uint32_t i : g.Match(H2(hash))) {
1744
2143
  if (ABSL_PREDICT_TRUE(PolicyTraits::apply(
1745
2144
  EqualElement<K>{key, eq_ref()},
1746
- PolicyTraits::element(slots_ + seq.offset(i)))))
2145
+ PolicyTraits::element(slot_ptr + seq.offset(i)))))
1747
2146
  return iterator_at(seq.offset(i));
1748
2147
  }
1749
2148
  if (ABSL_PREDICT_TRUE(g.MaskEmpty())) return end();
1750
2149
  seq.next();
1751
- assert(seq.index() <= capacity_ && "full table!");
2150
+ assert(seq.index() <= capacity() && "full table!");
1752
2151
  }
1753
2152
  }
1754
2153
  template <class K = key_type>
@@ -1786,9 +2185,9 @@ class raw_hash_set {
1786
2185
  return {it, it};
1787
2186
  }
1788
2187
 
1789
- size_t bucket_count() const { return capacity_; }
2188
+ size_t bucket_count() const { return capacity(); }
1790
2189
  float load_factor() const {
1791
- return capacity_ ? static_cast<double>(size()) / capacity_ : 0.0;
2190
+ return capacity() ? static_cast<double>(size()) / capacity() : 0.0;
1792
2191
  }
1793
2192
  float max_load_factor() const { return 1.0f; }
1794
2193
  void max_load_factor(float) {
@@ -1875,7 +2274,8 @@ class raw_hash_set {
1875
2274
  std::pair<iterator, bool> operator()(const K& key, Args&&...) && {
1876
2275
  auto res = s.find_or_prepare_insert(key);
1877
2276
  if (res.second) {
1878
- PolicyTraits::transfer(&s.alloc_ref(), s.slots_ + res.first, &slot);
2277
+ PolicyTraits::transfer(&s.alloc_ref(), s.slot_array() + res.first,
2278
+ &slot);
1879
2279
  } else if (do_destroy) {
1880
2280
  PolicyTraits::destroy(&s.alloc_ref(), &slot);
1881
2281
  }
@@ -1891,102 +2291,43 @@ class raw_hash_set {
1891
2291
  // This merely updates the pertinent control byte. This can be used in
1892
2292
  // conjunction with Policy::transfer to move the object to another place.
1893
2293
  void erase_meta_only(const_iterator it) {
1894
- assert(IsFull(*it.inner_.ctrl_) && "erasing a dangling iterator");
1895
- --size_;
1896
- const size_t index = static_cast<size_t>(it.inner_.ctrl_ - ctrl_);
1897
- const size_t index_before = (index - Group::kWidth) & capacity_;
1898
- const auto empty_after = Group(it.inner_.ctrl_).MaskEmpty();
1899
- const auto empty_before = Group(ctrl_ + index_before).MaskEmpty();
1900
-
1901
- // We count how many consecutive non empties we have to the right and to the
1902
- // left of `it`. If the sum is >= kWidth then there is at least one probe
1903
- // window that might have seen a full group.
1904
- bool was_never_full =
1905
- empty_before && empty_after &&
1906
- static_cast<size_t>(empty_after.TrailingZeros() +
1907
- empty_before.LeadingZeros()) < Group::kWidth;
1908
-
1909
- SetCtrl(index, was_never_full ? ctrl_t::kEmpty : ctrl_t::kDeleted,
1910
- capacity_, ctrl_, slots_, sizeof(slot_type));
1911
- growth_left() += was_never_full;
1912
- infoz().RecordErase();
2294
+ EraseMetaOnly(common(), it.inner_.ctrl_, sizeof(slot_type));
1913
2295
  }
1914
2296
 
1915
2297
  // Allocates a backing array for `self` and initializes its control bytes.
1916
- // This reads `capacity_` and updates all other fields based on the result of
2298
+ // This reads `capacity` and updates all other fields based on the result of
1917
2299
  // the allocation.
1918
2300
  //
1919
- // This does not free the currently held array; `capacity_` must be nonzero.
1920
- void initialize_slots() {
1921
- assert(capacity_);
1922
- // Folks with custom allocators often make unwarranted assumptions about the
1923
- // behavior of their classes vis-a-vis trivial destructability and what
1924
- // calls they will or wont make. Avoid sampling for people with custom
1925
- // allocators to get us out of this mess. This is not a hard guarantee but
1926
- // a workaround while we plan the exact guarantee we want to provide.
1927
- //
2301
+ // This does not free the currently held array; `capacity` must be nonzero.
2302
+ inline void initialize_slots() {
1928
2303
  // People are often sloppy with the exact type of their allocator (sometimes
1929
2304
  // it has an extra const or is missing the pair, but rebinds made it work
1930
- // anyway). To avoid the ambiguity, we work off SlotAlloc which we have
1931
- // bound more carefully.
1932
- if (std::is_same<SlotAlloc, std::allocator<slot_type>>::value &&
1933
- slots_ == nullptr) {
1934
- infoz() = Sample(sizeof(slot_type));
1935
- }
1936
-
1937
- char* mem = static_cast<char*>(Allocate<alignof(slot_type)>(
1938
- &alloc_ref(),
1939
- AllocSize(capacity_, sizeof(slot_type), alignof(slot_type))));
1940
- ctrl_ = reinterpret_cast<ctrl_t*>(mem);
1941
- slots_ = reinterpret_cast<slot_type*>(
1942
- mem + SlotOffset(capacity_, alignof(slot_type)));
1943
- ResetCtrl(capacity_, ctrl_, slots_, sizeof(slot_type));
1944
- reset_growth_left();
1945
- infoz().RecordStorageChanged(size_, capacity_);
1946
- }
1947
-
1948
- // Destroys all slots in the backing array, frees the backing array, and
1949
- // clears all top-level book-keeping data.
1950
- //
1951
- // This essentially implements `map = raw_hash_set();`.
1952
- void destroy_slots() {
1953
- if (!capacity_) return;
1954
- for (size_t i = 0; i != capacity_; ++i) {
1955
- if (IsFull(ctrl_[i])) {
1956
- PolicyTraits::destroy(&alloc_ref(), slots_ + i);
1957
- }
1958
- }
1959
-
1960
- // Unpoison before returning the memory to the allocator.
1961
- SanitizerUnpoisonMemoryRegion(slots_, sizeof(slot_type) * capacity_);
1962
- Deallocate<alignof(slot_type)>(
1963
- &alloc_ref(), ctrl_,
1964
- AllocSize(capacity_, sizeof(slot_type), alignof(slot_type)));
1965
- ctrl_ = EmptyGroup();
1966
- slots_ = nullptr;
1967
- size_ = 0;
1968
- capacity_ = 0;
1969
- growth_left() = 0;
2305
+ // anyway).
2306
+ using CharAlloc =
2307
+ typename absl::allocator_traits<Alloc>::template rebind_alloc<char>;
2308
+ InitializeSlots<CharAlloc, sizeof(slot_type), alignof(slot_type)>(
2309
+ common(), CharAlloc(alloc_ref()));
1970
2310
  }
1971
2311
 
1972
- void resize(size_t new_capacity) {
2312
+ ABSL_ATTRIBUTE_NOINLINE void resize(size_t new_capacity) {
1973
2313
  assert(IsValidCapacity(new_capacity));
1974
- auto* old_ctrl = ctrl_;
1975
- auto* old_slots = slots_;
1976
- const size_t old_capacity = capacity_;
1977
- capacity_ = new_capacity;
2314
+ auto* old_ctrl = control();
2315
+ auto* old_slots = slot_array();
2316
+ const size_t old_capacity = common().capacity_;
2317
+ common().capacity_ = new_capacity;
1978
2318
  initialize_slots();
1979
2319
 
2320
+ auto* new_slots = slot_array();
1980
2321
  size_t total_probe_length = 0;
1981
2322
  for (size_t i = 0; i != old_capacity; ++i) {
1982
2323
  if (IsFull(old_ctrl[i])) {
1983
2324
  size_t hash = PolicyTraits::apply(HashElement{hash_ref()},
1984
2325
  PolicyTraits::element(old_slots + i));
1985
- auto target = find_first_non_full(ctrl_, hash, capacity_);
2326
+ auto target = find_first_non_full(common(), hash);
1986
2327
  size_t new_i = target.offset;
1987
2328
  total_probe_length += target.probe_length;
1988
- SetCtrl(new_i, H2(hash), capacity_, ctrl_, slots_, sizeof(slot_type));
1989
- PolicyTraits::transfer(&alloc_ref(), slots_ + new_i, old_slots + i);
2329
+ SetCtrl(common(), new_i, H2(hash), sizeof(slot_type));
2330
+ PolicyTraits::transfer(&alloc_ref(), new_slots + new_i, old_slots + i);
1990
2331
  }
1991
2332
  }
1992
2333
  if (old_capacity) {
@@ -2002,70 +2343,10 @@ class raw_hash_set {
2002
2343
  // Prunes control bytes to remove as many tombstones as possible.
2003
2344
  //
2004
2345
  // See the comment on `rehash_and_grow_if_necessary()`.
2005
- void drop_deletes_without_resize() ABSL_ATTRIBUTE_NOINLINE {
2006
- assert(IsValidCapacity(capacity_));
2007
- assert(!is_small(capacity_));
2008
- // Algorithm:
2009
- // - mark all DELETED slots as EMPTY
2010
- // - mark all FULL slots as DELETED
2011
- // - for each slot marked as DELETED
2012
- // hash = Hash(element)
2013
- // target = find_first_non_full(hash)
2014
- // if target is in the same group
2015
- // mark slot as FULL
2016
- // else if target is EMPTY
2017
- // transfer element to target
2018
- // mark slot as EMPTY
2019
- // mark target as FULL
2020
- // else if target is DELETED
2021
- // swap current element with target element
2022
- // mark target as FULL
2023
- // repeat procedure for current slot with moved from element (target)
2024
- ConvertDeletedToEmptyAndFullToDeleted(ctrl_, capacity_);
2025
- alignas(slot_type) unsigned char raw[sizeof(slot_type)];
2026
- size_t total_probe_length = 0;
2027
- slot_type* slot = reinterpret_cast<slot_type*>(&raw);
2028
- for (size_t i = 0; i != capacity_; ++i) {
2029
- if (!IsDeleted(ctrl_[i])) continue;
2030
- const size_t hash = PolicyTraits::apply(
2031
- HashElement{hash_ref()}, PolicyTraits::element(slots_ + i));
2032
- const FindInfo target = find_first_non_full(ctrl_, hash, capacity_);
2033
- const size_t new_i = target.offset;
2034
- total_probe_length += target.probe_length;
2035
-
2036
- // Verify if the old and new i fall within the same group wrt the hash.
2037
- // If they do, we don't need to move the object as it falls already in the
2038
- // best probe we can.
2039
- const size_t probe_offset = probe(ctrl_, hash, capacity_).offset();
2040
- const auto probe_index = [probe_offset, this](size_t pos) {
2041
- return ((pos - probe_offset) & capacity_) / Group::kWidth;
2042
- };
2043
-
2044
- // Element doesn't move.
2045
- if (ABSL_PREDICT_TRUE(probe_index(new_i) == probe_index(i))) {
2046
- SetCtrl(i, H2(hash), capacity_, ctrl_, slots_, sizeof(slot_type));
2047
- continue;
2048
- }
2049
- if (IsEmpty(ctrl_[new_i])) {
2050
- // Transfer element to the empty spot.
2051
- // SetCtrl poisons/unpoisons the slots so we have to call it at the
2052
- // right time.
2053
- SetCtrl(new_i, H2(hash), capacity_, ctrl_, slots_, sizeof(slot_type));
2054
- PolicyTraits::transfer(&alloc_ref(), slots_ + new_i, slots_ + i);
2055
- SetCtrl(i, ctrl_t::kEmpty, capacity_, ctrl_, slots_, sizeof(slot_type));
2056
- } else {
2057
- assert(IsDeleted(ctrl_[new_i]));
2058
- SetCtrl(new_i, H2(hash), capacity_, ctrl_, slots_, sizeof(slot_type));
2059
- // Until we are done rehashing, DELETED marks previously FULL slots.
2060
- // Swap i and new_i elements.
2061
- PolicyTraits::transfer(&alloc_ref(), slot, slots_ + i);
2062
- PolicyTraits::transfer(&alloc_ref(), slots_ + i, slots_ + new_i);
2063
- PolicyTraits::transfer(&alloc_ref(), slots_ + new_i, slot);
2064
- --i; // repeat
2065
- }
2066
- }
2067
- reset_growth_left();
2068
- infoz().RecordRehash(total_probe_length);
2346
+ inline void drop_deletes_without_resize() {
2347
+ // Stack-allocate space for swapping elements.
2348
+ alignas(slot_type) unsigned char tmp[sizeof(slot_type)];
2349
+ DropDeletesWithoutResize(common(), GetPolicyFunctions(), tmp);
2069
2350
  }
2070
2351
 
2071
2352
  // Called whenever the table *might* need to conditionally grow.
@@ -2074,14 +2355,13 @@ class raw_hash_set {
2074
2355
  // growth is unnecessary, because vacating tombstones is beneficial for
2075
2356
  // performance in the long-run.
2076
2357
  void rehash_and_grow_if_necessary() {
2077
- if (capacity_ == 0) {
2078
- resize(1);
2079
- } else if (capacity_ > Group::kWidth &&
2080
- // Do these calcuations in 64-bit to avoid overflow.
2081
- size() * uint64_t{32} <= capacity_ * uint64_t{25}) {
2358
+ const size_t cap = capacity();
2359
+ if (cap > Group::kWidth &&
2360
+ // Do these calcuations in 64-bit to avoid overflow.
2361
+ size() * uint64_t{32} <= cap* uint64_t{25}) {
2082
2362
  // Squash DELETED without growing if there is enough capacity.
2083
2363
  //
2084
- // Rehash in place if the current size is <= 25/32 of capacity_.
2364
+ // Rehash in place if the current size is <= 25/32 of capacity.
2085
2365
  // Rationale for such a high factor: 1) drop_deletes_without_resize() is
2086
2366
  // faster than resize, and 2) it takes quite a bit of work to add
2087
2367
  // tombstones. In the worst case, seems to take approximately 4
@@ -2099,8 +2379,8 @@ class raw_hash_set {
2099
2379
  //
2100
2380
  // Here is output of an experiment using the BM_CacheInSteadyState
2101
2381
  // benchmark running the old case (where we rehash-in-place only if we can
2102
- // reclaim at least 7/16*capacity_) vs. this code (which rehashes in place
2103
- // if we can recover 3/32*capacity_).
2382
+ // reclaim at least 7/16*capacity) vs. this code (which rehashes in place
2383
+ // if we can recover 3/32*capacity).
2104
2384
  //
2105
2385
  // Note that although in the worst-case number of rehashes jumped up from
2106
2386
  // 15 to 190, but the number of operations per second is almost the same.
@@ -2123,23 +2403,24 @@ class raw_hash_set {
2123
2403
  drop_deletes_without_resize();
2124
2404
  } else {
2125
2405
  // Otherwise grow the container.
2126
- resize(capacity_ * 2 + 1);
2406
+ resize(NextCapacity(cap));
2127
2407
  }
2128
2408
  }
2129
2409
 
2130
2410
  bool has_element(const value_type& elem) const {
2131
2411
  size_t hash = PolicyTraits::apply(HashElement{hash_ref()}, elem);
2132
- auto seq = probe(ctrl_, hash, capacity_);
2412
+ auto seq = probe(common(), hash);
2413
+ const ctrl_t* ctrl = control();
2133
2414
  while (true) {
2134
- Group g{ctrl_ + seq.offset()};
2415
+ Group g{ctrl + seq.offset()};
2135
2416
  for (uint32_t i : g.Match(H2(hash))) {
2136
- if (ABSL_PREDICT_TRUE(PolicyTraits::element(slots_ + seq.offset(i)) ==
2137
- elem))
2417
+ if (ABSL_PREDICT_TRUE(
2418
+ PolicyTraits::element(slot_array() + seq.offset(i)) == elem))
2138
2419
  return true;
2139
2420
  }
2140
2421
  if (ABSL_PREDICT_TRUE(g.MaskEmpty())) return false;
2141
2422
  seq.next();
2142
- assert(seq.index() <= capacity_ && "full table!");
2423
+ assert(seq.index() <= capacity() && "full table!");
2143
2424
  }
2144
2425
  return false;
2145
2426
  }
@@ -2164,18 +2445,19 @@ class raw_hash_set {
2164
2445
  std::pair<size_t, bool> find_or_prepare_insert(const K& key) {
2165
2446
  prefetch_heap_block();
2166
2447
  auto hash = hash_ref()(key);
2167
- auto seq = probe(ctrl_, hash, capacity_);
2448
+ auto seq = probe(common(), hash);
2449
+ const ctrl_t* ctrl = control();
2168
2450
  while (true) {
2169
- Group g{ctrl_ + seq.offset()};
2451
+ Group g{ctrl + seq.offset()};
2170
2452
  for (uint32_t i : g.Match(H2(hash))) {
2171
2453
  if (ABSL_PREDICT_TRUE(PolicyTraits::apply(
2172
2454
  EqualElement<K>{key, eq_ref()},
2173
- PolicyTraits::element(slots_ + seq.offset(i)))))
2455
+ PolicyTraits::element(slot_array() + seq.offset(i)))))
2174
2456
  return {seq.offset(i), false};
2175
2457
  }
2176
2458
  if (ABSL_PREDICT_TRUE(g.MaskEmpty())) break;
2177
2459
  seq.next();
2178
- assert(seq.index() <= capacity_ && "full table!");
2460
+ assert(seq.index() <= capacity() && "full table!");
2179
2461
  }
2180
2462
  return {prepare_insert(hash), true};
2181
2463
  }
@@ -2185,16 +2467,24 @@ class raw_hash_set {
2185
2467
  //
2186
2468
  // REQUIRES: At least one non-full slot available.
2187
2469
  size_t prepare_insert(size_t hash) ABSL_ATTRIBUTE_NOINLINE {
2188
- auto target = find_first_non_full(ctrl_, hash, capacity_);
2189
- if (ABSL_PREDICT_FALSE(growth_left() == 0 &&
2190
- !IsDeleted(ctrl_[target.offset]))) {
2470
+ const bool rehash_for_bug_detection =
2471
+ common().should_rehash_for_bug_detection_on_insert();
2472
+ if (rehash_for_bug_detection) {
2473
+ // Move to a different heap allocation in order to detect bugs.
2474
+ const size_t cap = capacity();
2475
+ resize(growth_left() > 0 ? cap : NextCapacity(cap));
2476
+ }
2477
+ auto target = find_first_non_full(common(), hash);
2478
+ if (!rehash_for_bug_detection &&
2479
+ ABSL_PREDICT_FALSE(growth_left() == 0 &&
2480
+ !IsDeleted(control()[target.offset]))) {
2191
2481
  rehash_and_grow_if_necessary();
2192
- target = find_first_non_full(ctrl_, hash, capacity_);
2482
+ target = find_first_non_full(common(), hash);
2193
2483
  }
2194
- ++size_;
2195
- growth_left() -= IsEmpty(ctrl_[target.offset]);
2196
- SetCtrl(target.offset, H2(hash), capacity_, ctrl_, slots_,
2197
- sizeof(slot_type));
2484
+ ++common().size_;
2485
+ growth_left() -= IsEmpty(control()[target.offset]);
2486
+ SetCtrl(common(), target.offset, H2(hash), sizeof(slot_type));
2487
+ common().maybe_increment_generation_on_insert();
2198
2488
  infoz().RecordInsert(hash, target.probe_length);
2199
2489
  return target.offset;
2200
2490
  }
@@ -2209,7 +2499,7 @@ class raw_hash_set {
2209
2499
  // POSTCONDITION: *m.iterator_at(i) == value_type(forward<Args>(args)...).
2210
2500
  template <class... Args>
2211
2501
  void emplace_at(size_t i, Args&&... args) {
2212
- PolicyTraits::construct(&alloc_ref(), slots_ + i,
2502
+ PolicyTraits::construct(&alloc_ref(), slot_array() + i,
2213
2503
  std::forward<Args>(args)...);
2214
2504
 
2215
2505
  assert(PolicyTraits::apply(FindElement{*this}, *iterator_at(i)) ==
@@ -2217,16 +2507,16 @@ class raw_hash_set {
2217
2507
  "constructed value does not match the lookup key");
2218
2508
  }
2219
2509
 
2220
- iterator iterator_at(size_t i) { return {ctrl_ + i, slots_ + i}; }
2221
- const_iterator iterator_at(size_t i) const { return {ctrl_ + i, slots_ + i}; }
2510
+ iterator iterator_at(size_t i) {
2511
+ return {control() + i, slot_array() + i, common().generation_ptr()};
2512
+ }
2513
+ const_iterator iterator_at(size_t i) const {
2514
+ return {control() + i, slot_array() + i, common().generation_ptr()};
2515
+ }
2222
2516
 
2223
2517
  private:
2224
2518
  friend struct RawHashSetTestOnlyAccess;
2225
2519
 
2226
- void reset_growth_left() {
2227
- growth_left() = CapacityToGrowth(capacity()) - size_;
2228
- }
2229
-
2230
2520
  // The number of slots we can still fill without needing to rehash.
2231
2521
  //
2232
2522
  // This is stored separately due to tombstones: we do not include tombstones
@@ -2237,49 +2527,76 @@ class raw_hash_set {
2237
2527
  // side-effect.
2238
2528
  //
2239
2529
  // See `CapacityToGrowth()`.
2240
- size_t& growth_left() { return settings_.template get<0>(); }
2530
+ size_t& growth_left() { return common().growth_left(); }
2241
2531
 
2242
2532
  // Prefetch the heap-allocated memory region to resolve potential TLB misses.
2243
2533
  // This is intended to overlap with execution of calculating the hash for a
2244
2534
  // key.
2245
- void prefetch_heap_block() const {
2246
- base_internal::PrefetchT2(ctrl_);
2247
- }
2535
+ void prefetch_heap_block() const { base_internal::PrefetchT2(control()); }
2536
+
2537
+ CommonFields& common() { return settings_.template get<0>(); }
2538
+ const CommonFields& common() const { return settings_.template get<0>(); }
2248
2539
 
2249
- HashtablezInfoHandle& infoz() { return settings_.template get<1>(); }
2540
+ ctrl_t* control() const { return common().control_; }
2541
+ slot_type* slot_array() const {
2542
+ return static_cast<slot_type*>(common().slots_);
2543
+ }
2544
+ HashtablezInfoHandle& infoz() { return common().infoz(); }
2250
2545
 
2251
- hasher& hash_ref() { return settings_.template get<2>(); }
2252
- const hasher& hash_ref() const { return settings_.template get<2>(); }
2253
- key_equal& eq_ref() { return settings_.template get<3>(); }
2254
- const key_equal& eq_ref() const { return settings_.template get<3>(); }
2255
- allocator_type& alloc_ref() { return settings_.template get<4>(); }
2546
+ hasher& hash_ref() { return settings_.template get<1>(); }
2547
+ const hasher& hash_ref() const { return settings_.template get<1>(); }
2548
+ key_equal& eq_ref() { return settings_.template get<2>(); }
2549
+ const key_equal& eq_ref() const { return settings_.template get<2>(); }
2550
+ allocator_type& alloc_ref() { return settings_.template get<3>(); }
2256
2551
  const allocator_type& alloc_ref() const {
2257
- return settings_.template get<4>();
2552
+ return settings_.template get<3>();
2258
2553
  }
2259
2554
 
2260
- // TODO(alkis): Investigate removing some of these fields:
2261
- // - ctrl/slots can be derived from each other
2262
- // - size can be moved into the slot array
2555
+ // Make type-specific functions for this type's PolicyFunctions struct.
2556
+ static size_t hash_slot_fn(void* set, void* slot) {
2557
+ auto* h = static_cast<raw_hash_set*>(set);
2558
+ return PolicyTraits::apply(
2559
+ HashElement{h->hash_ref()},
2560
+ PolicyTraits::element(static_cast<slot_type*>(slot)));
2561
+ }
2562
+ static void transfer_slot_fn(void* set, void* dst, void* src) {
2563
+ auto* h = static_cast<raw_hash_set*>(set);
2564
+ PolicyTraits::transfer(&h->alloc_ref(), static_cast<slot_type*>(dst),
2565
+ static_cast<slot_type*>(src));
2566
+ }
2567
+ // Note: dealloc_fn will only be used if we have a non-standard allocator.
2568
+ static void dealloc_fn(void* set, const PolicyFunctions&, ctrl_t* ctrl,
2569
+ void* slot_mem, size_t n) {
2570
+ auto* h = static_cast<raw_hash_set*>(set);
2263
2571
 
2264
- // The control bytes (and, also, a pointer to the base of the backing array).
2265
- //
2266
- // This contains `capacity_ + 1 + NumClonedBytes()` entries, even
2267
- // when the table is empty (hence EmptyGroup).
2268
- ctrl_t* ctrl_ = EmptyGroup();
2269
- // The beginning of the slots, located at `SlotOffset()` bytes after
2270
- // `ctrl_`. May be null for empty tables.
2271
- slot_type* slots_ = nullptr;
2572
+ // Unpoison before returning the memory to the allocator.
2573
+ SanitizerUnpoisonMemoryRegion(slot_mem, sizeof(slot_type) * n);
2272
2574
 
2273
- // The number of filled slots.
2274
- size_t size_ = 0;
2575
+ Deallocate<alignof(slot_type)>(
2576
+ &h->alloc_ref(), ctrl,
2577
+ AllocSize(n, sizeof(slot_type), alignof(slot_type)));
2578
+ }
2579
+
2580
+ static const PolicyFunctions& GetPolicyFunctions() {
2581
+ static constexpr PolicyFunctions value = {
2582
+ sizeof(slot_type),
2583
+ &raw_hash_set::hash_slot_fn,
2584
+ PolicyTraits::transfer_uses_memcpy()
2585
+ ? TransferRelocatable<sizeof(slot_type)>
2586
+ : &raw_hash_set::transfer_slot_fn,
2587
+ (std::is_same<SlotAlloc, std::allocator<slot_type>>::value
2588
+ ? &DeallocateStandard<alignof(slot_type)>
2589
+ : &raw_hash_set::dealloc_fn),
2590
+ };
2591
+ return value;
2592
+ }
2275
2593
 
2276
- // The total number of available slots.
2277
- size_t capacity_ = 0;
2278
- absl::container_internal::CompressedTuple<size_t /* growth_left */,
2279
- HashtablezInfoHandle, hasher,
2280
- key_equal, allocator_type>
2281
- settings_{0u, HashtablezInfoHandle{}, hasher{}, key_equal{},
2282
- allocator_type{}};
2594
+ // Bundle together CommonFields plus other objects which might be empty.
2595
+ // CompressedTuple will ensure that sizeof is not affected by any of the empty
2596
+ // fields that occur after CommonFields.
2597
+ absl::container_internal::CompressedTuple<CommonFields, hasher, key_equal,
2598
+ allocator_type>
2599
+ settings_{CommonFields{}, hasher{}, key_equal{}, allocator_type{}};
2283
2600
  };
2284
2601
 
2285
2602
  // Erases all elements that satisfy the predicate `pred` from the container `c`.
@@ -2307,14 +2624,15 @@ struct HashtableDebugAccess<Set, absl::void_t<typename Set::raw_hash_set>> {
2307
2624
  const typename Set::key_type& key) {
2308
2625
  size_t num_probes = 0;
2309
2626
  size_t hash = set.hash_ref()(key);
2310
- auto seq = probe(set.ctrl_, hash, set.capacity_);
2627
+ auto seq = probe(set.common(), hash);
2628
+ const ctrl_t* ctrl = set.control();
2311
2629
  while (true) {
2312
- container_internal::Group g{set.ctrl_ + seq.offset()};
2630
+ container_internal::Group g{ctrl + seq.offset()};
2313
2631
  for (uint32_t i : g.Match(container_internal::H2(hash))) {
2314
2632
  if (Traits::apply(
2315
2633
  typename Set::template EqualElement<typename Set::key_type>{
2316
2634
  key, set.eq_ref()},
2317
- Traits::element(set.slots_ + seq.offset(i))))
2635
+ Traits::element(set.slot_array() + seq.offset(i))))
2318
2636
  return num_probes;
2319
2637
  ++num_probes;
2320
2638
  }
@@ -2325,7 +2643,7 @@ struct HashtableDebugAccess<Set, absl::void_t<typename Set::raw_hash_set>> {
2325
2643
  }
2326
2644
 
2327
2645
  static size_t AllocatedByteSize(const Set& c) {
2328
- size_t capacity = c.capacity_;
2646
+ size_t capacity = c.capacity();
2329
2647
  if (capacity == 0) return 0;
2330
2648
  size_t m = AllocSize(capacity, sizeof(Slot), alignof(Slot));
2331
2649
 
@@ -2333,9 +2651,10 @@ struct HashtableDebugAccess<Set, absl::void_t<typename Set::raw_hash_set>> {
2333
2651
  if (per_slot != ~size_t{}) {
2334
2652
  m += per_slot * c.size();
2335
2653
  } else {
2654
+ const ctrl_t* ctrl = c.control();
2336
2655
  for (size_t i = 0; i != capacity; ++i) {
2337
- if (container_internal::IsFull(c.ctrl_[i])) {
2338
- m += Traits::space_used(c.slots_ + i);
2656
+ if (container_internal::IsFull(ctrl[i])) {
2657
+ m += Traits::space_used(c.slot_array() + i);
2339
2658
  }
2340
2659
  }
2341
2660
  }
@@ -2360,6 +2679,7 @@ struct HashtableDebugAccess<Set, absl::void_t<typename Set::raw_hash_set>> {
2360
2679
  ABSL_NAMESPACE_END
2361
2680
  } // namespace absl
2362
2681
 
2682
+ #undef ABSL_SWISSTABLE_ENABLE_GENERATIONS
2363
2683
  #undef ABSL_INTERNAL_ASSERT_IS_FULL
2364
2684
 
2365
2685
  #endif // ABSL_CONTAINER_INTERNAL_RAW_HASH_SET_H_