grpc 1.42.0 → 1.43.1

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 (739) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +85 -34
  3. data/include/grpc/event_engine/event_engine.h +37 -13
  4. data/include/grpc/event_engine/internal/memory_allocator_impl.h +1 -31
  5. data/include/grpc/event_engine/memory_allocator.h +27 -11
  6. data/include/grpc/event_engine/memory_request.h +57 -0
  7. data/include/grpc/grpc_security.h +276 -145
  8. data/include/grpc/grpc_security_constants.h +1 -14
  9. data/include/grpc/impl/codegen/port_platform.h +7 -3
  10. data/src/core/ext/filters/client_channel/backend_metric.cc +6 -7
  11. data/src/core/ext/filters/client_channel/backend_metric.h +3 -2
  12. data/src/core/ext/filters/client_channel/client_channel.cc +81 -40
  13. data/src/core/ext/filters/client_channel/client_channel.h +5 -4
  14. data/src/core/ext/filters/client_channel/client_channel_plugin.cc +1 -2
  15. data/src/core/ext/filters/client_channel/dynamic_filters.cc +4 -4
  16. data/src/core/ext/filters/client_channel/health/health_check_client.h +1 -1
  17. data/src/core/ext/filters/client_channel/http_connect_handshaker.cc +12 -14
  18. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +1 -2
  19. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc +1 -2
  20. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h +2 -2
  21. data/src/core/ext/filters/client_channel/lb_policy/ring_hash/ring_hash.cc +2 -3
  22. data/src/core/ext/filters/client_channel/lb_policy/xds/cds.cc +27 -80
  23. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_impl.cc +82 -34
  24. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_resolver.cc +47 -91
  25. data/src/core/ext/filters/client_channel/lb_policy.h +75 -59
  26. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +3 -3
  27. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h +2 -2
  28. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc +8 -12
  29. data/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc +3 -3
  30. data/src/core/ext/filters/client_channel/resolver/google_c2p/google_c2p_resolver.cc +6 -12
  31. data/src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc +222 -294
  32. data/src/core/ext/filters/client_channel/resolver_registry.cc +6 -7
  33. data/src/core/ext/filters/client_channel/resolver_registry.h +1 -2
  34. data/src/core/ext/filters/client_channel/subchannel.cc +4 -4
  35. data/src/core/ext/filters/fault_injection/fault_injection_filter.cc +1 -1
  36. data/src/core/ext/filters/http/client/http_client_filter.cc +14 -30
  37. data/src/core/ext/filters/http/http_filters_plugin.cc +3 -5
  38. data/src/core/ext/filters/http/server/http_server_filter.cc +11 -28
  39. data/src/core/ext/filters/server_config_selector/server_config_selector.cc +67 -0
  40. data/src/core/ext/filters/server_config_selector/server_config_selector.h +70 -0
  41. data/src/core/ext/filters/server_config_selector/server_config_selector_filter.cc +265 -0
  42. data/src/core/ext/filters/server_config_selector/server_config_selector_filter.h +32 -0
  43. data/src/core/ext/transport/chttp2/client/chttp2_connector.cc +4 -20
  44. data/src/core/ext/transport/chttp2/client/chttp2_connector.h +0 -2
  45. data/src/core/ext/transport/chttp2/client/insecure/channel_create.cc +8 -5
  46. data/src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc +11 -14
  47. data/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc +6 -3
  48. data/src/core/ext/transport/chttp2/server/chttp2_server.cc +54 -79
  49. data/src/core/ext/transport/chttp2/server/insecure/server_chttp2.cc +2 -3
  50. data/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc +9 -13
  51. data/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.cc +6 -6
  52. data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +53 -62
  53. data/src/core/ext/transport/chttp2/transport/chttp2_transport.h +1 -2
  54. data/src/core/ext/transport/chttp2/transport/context_list.cc +2 -3
  55. data/src/core/ext/transport/chttp2/transport/context_list.h +2 -3
  56. data/src/core/ext/transport/chttp2/transport/flow_control.cc +8 -8
  57. data/src/core/ext/transport/chttp2/transport/flow_control.h +2 -2
  58. data/src/core/ext/transport/chttp2/transport/hpack_encoder.cc +83 -19
  59. data/src/core/ext/transport/chttp2/transport/hpack_encoder.h +33 -1
  60. data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +66 -92
  61. data/src/core/ext/transport/chttp2/transport/internal.h +8 -4
  62. data/src/core/ext/transport/inproc/inproc_transport.cc +16 -7
  63. data/src/core/ext/transport/inproc/inproc_transport.h +1 -1
  64. data/src/core/ext/upb-generated/envoy/admin/v3/config_dump.upb.c +197 -165
  65. data/src/core/ext/upb-generated/envoy/admin/v3/config_dump.upb.h +2 -0
  66. data/src/core/ext/upb-generated/envoy/annotations/deprecation.upb.c +41 -0
  67. data/src/core/ext/upb-generated/envoy/annotations/deprecation.upb.h +18 -0
  68. data/src/core/ext/upb-generated/envoy/annotations/resource.upb.c +26 -2
  69. data/src/core/ext/upb-generated/envoy/annotations/resource.upb.h +7 -0
  70. data/src/core/ext/upb-generated/envoy/config/accesslog/v3/accesslog.upb.c +107 -82
  71. data/src/core/ext/upb-generated/envoy/config/accesslog/v3/accesslog.upb.h +2 -0
  72. data/src/core/ext/upb-generated/envoy/config/bootstrap/v3/bootstrap.upb.c +188 -160
  73. data/src/core/ext/upb-generated/envoy/config/bootstrap/v3/bootstrap.upb.h +2 -0
  74. data/src/core/ext/upb-generated/envoy/config/cluster/v3/circuit_breaker.upb.c +35 -22
  75. data/src/core/ext/upb-generated/envoy/config/cluster/v3/circuit_breaker.upb.h +2 -0
  76. data/src/core/ext/upb-generated/envoy/config/cluster/v3/cluster.upb.c +253 -218
  77. data/src/core/ext/upb-generated/envoy/config/cluster/v3/cluster.upb.h +2 -0
  78. data/src/core/ext/upb-generated/envoy/config/cluster/v3/filter.upb.c +16 -5
  79. data/src/core/ext/upb-generated/envoy/config/cluster/v3/filter.upb.h +2 -0
  80. data/src/core/ext/upb-generated/envoy/config/cluster/v3/outlier_detection.upb.c +36 -25
  81. data/src/core/ext/upb-generated/envoy/config/cluster/v3/outlier_detection.upb.h +2 -0
  82. data/src/core/ext/upb-generated/envoy/config/core/v3/address.upb.c +56 -39
  83. data/src/core/ext/upb-generated/envoy/config/core/v3/address.upb.h +2 -0
  84. data/src/core/ext/upb-generated/envoy/config/core/v3/backoff.upb.c +16 -5
  85. data/src/core/ext/upb-generated/envoy/config/core/v3/backoff.upb.h +2 -0
  86. data/src/core/ext/upb-generated/envoy/config/core/v3/base.upb.c +162 -128
  87. data/src/core/ext/upb-generated/envoy/config/core/v3/base.upb.h +2 -0
  88. data/src/core/ext/upb-generated/envoy/config/core/v3/config_source.upb.c +51 -36
  89. data/src/core/ext/upb-generated/envoy/config/core/v3/config_source.upb.h +2 -0
  90. data/src/core/ext/upb-generated/envoy/config/core/v3/event_service_config.upb.c +15 -4
  91. data/src/core/ext/upb-generated/envoy/config/core/v3/event_service_config.upb.h +2 -0
  92. data/src/core/ext/upb-generated/envoy/config/core/v3/extension.upb.c +25 -13
  93. data/src/core/ext/upb-generated/envoy/config/core/v3/extension.upb.h +2 -0
  94. data/src/core/ext/upb-generated/envoy/config/core/v3/grpc_service.upb.c +114 -90
  95. data/src/core/ext/upb-generated/envoy/config/core/v3/grpc_service.upb.h +2 -0
  96. data/src/core/ext/upb-generated/envoy/config/core/v3/health_check.upb.c +89 -71
  97. data/src/core/ext/upb-generated/envoy/config/core/v3/health_check.upb.h +2 -0
  98. data/src/core/ext/upb-generated/envoy/config/core/v3/http_uri.upb.c +17 -6
  99. data/src/core/ext/upb-generated/envoy/config/core/v3/http_uri.upb.h +2 -0
  100. data/src/core/ext/upb-generated/envoy/config/core/v3/protocol.upb.c +117 -93
  101. data/src/core/ext/upb-generated/envoy/config/core/v3/protocol.upb.h +2 -0
  102. data/src/core/ext/upb-generated/envoy/config/core/v3/proxy_protocol.upb.c +13 -2
  103. data/src/core/ext/upb-generated/envoy/config/core/v3/proxy_protocol.upb.h +2 -0
  104. data/src/core/ext/upb-generated/envoy/config/core/v3/resolver.upb.c +21 -9
  105. data/src/core/ext/upb-generated/envoy/config/core/v3/resolver.upb.h +2 -0
  106. data/src/core/ext/upb-generated/envoy/config/core/v3/socket_option.upb.c +18 -7
  107. data/src/core/ext/upb-generated/envoy/config/core/v3/socket_option.upb.h +2 -0
  108. data/src/core/ext/upb-generated/envoy/config/core/v3/substitution_format_string.upb.c +22 -11
  109. data/src/core/ext/upb-generated/envoy/config/core/v3/substitution_format_string.upb.h +2 -0
  110. data/src/core/ext/upb-generated/envoy/config/core/v3/udp_socket_config.upb.c +17 -6
  111. data/src/core/ext/upb-generated/envoy/config/core/v3/udp_socket_config.upb.h +2 -0
  112. data/src/core/ext/upb-generated/envoy/config/endpoint/v3/endpoint.upb.c +41 -27
  113. data/src/core/ext/upb-generated/envoy/config/endpoint/v3/endpoint.upb.h +2 -0
  114. data/src/core/ext/upb-generated/envoy/config/endpoint/v3/endpoint_components.upb.c +59 -43
  115. data/src/core/ext/upb-generated/envoy/config/endpoint/v3/endpoint_components.upb.h +2 -0
  116. data/src/core/ext/upb-generated/envoy/config/endpoint/v3/load_report.upb.c +58 -43
  117. data/src/core/ext/upb-generated/envoy/config/endpoint/v3/load_report.upb.h +2 -0
  118. data/src/core/ext/upb-generated/envoy/config/listener/v3/api_listener.upb.c +15 -4
  119. data/src/core/ext/upb-generated/envoy/config/listener/v3/api_listener.upb.h +2 -0
  120. data/src/core/ext/upb-generated/envoy/config/listener/v3/listener.upb.c +73 -57
  121. data/src/core/ext/upb-generated/envoy/config/listener/v3/listener.upb.h +2 -0
  122. data/src/core/ext/upb-generated/envoy/config/listener/v3/listener_components.upb.c +81 -64
  123. data/src/core/ext/upb-generated/envoy/config/listener/v3/listener_components.upb.h +2 -0
  124. data/src/core/ext/upb-generated/envoy/config/listener/v3/quic_config.upb.c +25 -14
  125. data/src/core/ext/upb-generated/envoy/config/listener/v3/quic_config.upb.h +2 -0
  126. data/src/core/ext/upb-generated/envoy/config/listener/v3/udp_listener_config.upb.c +19 -7
  127. data/src/core/ext/upb-generated/envoy/config/listener/v3/udp_listener_config.upb.h +2 -0
  128. data/src/core/ext/upb-generated/envoy/config/metrics/v3/stats.upb.c +63 -45
  129. data/src/core/ext/upb-generated/envoy/config/metrics/v3/stats.upb.h +2 -0
  130. data/src/core/ext/upb-generated/envoy/config/overload/v3/overload.upb.c +66 -47
  131. data/src/core/ext/upb-generated/envoy/config/overload/v3/overload.upb.h +2 -0
  132. data/src/core/ext/upb-generated/envoy/config/rbac/v3/rbac.upb.c +93 -75
  133. data/src/core/ext/upb-generated/envoy/config/rbac/v3/rbac.upb.h +2 -0
  134. data/src/core/ext/upb-generated/envoy/config/route/v3/route.upb.c +41 -28
  135. data/src/core/ext/upb-generated/envoy/config/route/v3/route.upb.h +2 -0
  136. data/src/core/ext/upb-generated/envoy/config/route/v3/route_components.upb.c +503 -440
  137. data/src/core/ext/upb-generated/envoy/config/route/v3/route_components.upb.h +2 -0
  138. data/src/core/ext/upb-generated/envoy/config/route/v3/scoped_route.upb.c +26 -13
  139. data/src/core/ext/upb-generated/envoy/config/route/v3/scoped_route.upb.h +2 -0
  140. data/src/core/ext/upb-generated/envoy/config/trace/v3/http_tracer.upb.c +21 -9
  141. data/src/core/ext/upb-generated/envoy/config/trace/v3/http_tracer.upb.h +2 -0
  142. data/src/core/ext/upb-generated/envoy/extensions/clusters/aggregate/v3/cluster.upb.c +13 -2
  143. data/src/core/ext/upb-generated/envoy/extensions/clusters/aggregate/v3/cluster.upb.h +2 -0
  144. data/src/core/ext/upb-generated/envoy/extensions/filters/common/fault/v3/fault.upb.c +35 -20
  145. data/src/core/ext/upb-generated/envoy/extensions/filters/common/fault/v3/fault.upb.h +2 -0
  146. data/src/core/ext/upb-generated/envoy/extensions/filters/http/fault/v3/fault.upb.c +44 -31
  147. data/src/core/ext/upb-generated/envoy/extensions/filters/http/fault/v3/fault.upb.h +2 -0
  148. data/src/core/ext/upb-generated/envoy/extensions/filters/http/router/v3/router.upb.c +22 -11
  149. data/src/core/ext/upb-generated/envoy/extensions/filters/http/router/v3/router.upb.h +2 -0
  150. data/src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.c +210 -181
  151. data/src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.h +2 -0
  152. data/src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/cert.upb.c +7 -0
  153. data/src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/cert.upb.h +5 -3
  154. data/src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/common.upb.c +64 -48
  155. data/src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/common.upb.h +2 -0
  156. data/src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/secret.upb.c +33 -20
  157. data/src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/secret.upb.h +2 -0
  158. data/src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/tls.upb.c +81 -65
  159. data/src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/tls.upb.h +2 -0
  160. data/src/core/ext/upb-generated/envoy/service/cluster/v3/cds.upb.c +12 -1
  161. data/src/core/ext/upb-generated/envoy/service/cluster/v3/cds.upb.h +2 -0
  162. data/src/core/ext/upb-generated/envoy/service/discovery/v3/ads.upb.c +12 -1
  163. data/src/core/ext/upb-generated/envoy/service/discovery/v3/ads.upb.h +2 -0
  164. data/src/core/ext/upb-generated/envoy/service/discovery/v3/discovery.upb.c +75 -58
  165. data/src/core/ext/upb-generated/envoy/service/discovery/v3/discovery.upb.h +2 -0
  166. data/src/core/ext/upb-generated/envoy/service/endpoint/v3/eds.upb.c +12 -1
  167. data/src/core/ext/upb-generated/envoy/service/endpoint/v3/eds.upb.h +2 -0
  168. data/src/core/ext/upb-generated/envoy/service/listener/v3/lds.upb.c +12 -1
  169. data/src/core/ext/upb-generated/envoy/service/listener/v3/lds.upb.h +2 -0
  170. data/src/core/ext/upb-generated/envoy/service/load_stats/v3/lrs.upb.c +25 -13
  171. data/src/core/ext/upb-generated/envoy/service/load_stats/v3/lrs.upb.h +2 -0
  172. data/src/core/ext/upb-generated/envoy/service/route/v3/rds.upb.c +12 -1
  173. data/src/core/ext/upb-generated/envoy/service/route/v3/rds.upb.h +2 -0
  174. data/src/core/ext/upb-generated/envoy/service/route/v3/srds.upb.c +12 -1
  175. data/src/core/ext/upb-generated/envoy/service/route/v3/srds.upb.h +2 -0
  176. data/src/core/ext/upb-generated/envoy/service/status/v3/csds.upb.c +61 -46
  177. data/src/core/ext/upb-generated/envoy/service/status/v3/csds.upb.h +2 -0
  178. data/src/core/ext/upb-generated/envoy/type/http/v3/path_transformation.upb.c +26 -12
  179. data/src/core/ext/upb-generated/envoy/type/http/v3/path_transformation.upb.h +2 -0
  180. data/src/core/ext/upb-generated/envoy/type/matcher/v3/metadata.upb.c +22 -10
  181. data/src/core/ext/upb-generated/envoy/type/matcher/v3/metadata.upb.h +2 -0
  182. data/src/core/ext/upb-generated/envoy/type/matcher/v3/node.upb.c +17 -6
  183. data/src/core/ext/upb-generated/envoy/type/matcher/v3/node.upb.h +2 -0
  184. data/src/core/ext/upb-generated/envoy/type/matcher/v3/number.upb.c +16 -5
  185. data/src/core/ext/upb-generated/envoy/type/matcher/v3/number.upb.h +2 -0
  186. data/src/core/ext/upb-generated/envoy/type/matcher/v3/path.upb.c +15 -4
  187. data/src/core/ext/upb-generated/envoy/type/matcher/v3/path.upb.h +2 -0
  188. data/src/core/ext/upb-generated/envoy/type/matcher/v3/regex.upb.c +27 -14
  189. data/src/core/ext/upb-generated/envoy/type/matcher/v3/regex.upb.h +2 -0
  190. data/src/core/ext/upb-generated/envoy/type/matcher/v3/string.upb.c +25 -13
  191. data/src/core/ext/upb-generated/envoy/type/matcher/v3/string.upb.h +2 -0
  192. data/src/core/ext/upb-generated/envoy/type/matcher/v3/struct.upb.c +20 -8
  193. data/src/core/ext/upb-generated/envoy/type/matcher/v3/struct.upb.h +2 -0
  194. data/src/core/ext/upb-generated/envoy/type/matcher/v3/value.upb.c +30 -17
  195. data/src/core/ext/upb-generated/envoy/type/matcher/v3/value.upb.h +2 -0
  196. data/src/core/ext/upb-generated/envoy/type/metadata/v3/metadata.upb.c +38 -21
  197. data/src/core/ext/upb-generated/envoy/type/metadata/v3/metadata.upb.h +2 -0
  198. data/src/core/ext/upb-generated/envoy/type/tracing/v3/custom_tag.upb.c +41 -26
  199. data/src/core/ext/upb-generated/envoy/type/tracing/v3/custom_tag.upb.h +2 -0
  200. data/src/core/ext/upb-generated/envoy/type/v3/http.upb.c +7 -0
  201. data/src/core/ext/upb-generated/envoy/type/v3/http.upb.h +2 -0
  202. data/src/core/ext/upb-generated/envoy/type/v3/percent.upb.c +17 -5
  203. data/src/core/ext/upb-generated/envoy/type/v3/percent.upb.h +2 -0
  204. data/src/core/ext/upb-generated/envoy/type/v3/range.upb.c +22 -9
  205. data/src/core/ext/upb-generated/envoy/type/v3/range.upb.h +2 -0
  206. data/src/core/ext/upb-generated/envoy/type/v3/semantic_version.upb.c +15 -4
  207. data/src/core/ext/upb-generated/envoy/type/v3/semantic_version.upb.h +2 -0
  208. data/src/core/ext/upb-generated/google/api/annotations.upb.c +20 -0
  209. data/src/core/ext/upb-generated/google/api/annotations.upb.h +7 -0
  210. data/src/core/ext/upb-generated/google/api/expr/v1alpha1/checked.upb.c +116 -93
  211. data/src/core/ext/upb-generated/google/api/expr/v1alpha1/checked.upb.h +2 -0
  212. data/src/core/ext/upb-generated/google/api/expr/v1alpha1/eval.upb.c +102 -0
  213. data/src/core/ext/upb-generated/google/api/expr/v1alpha1/eval.upb.h +306 -0
  214. data/src/core/ext/upb-generated/google/api/expr/v1alpha1/explain.upb.c +56 -0
  215. data/src/core/ext/upb-generated/google/api/expr/v1alpha1/explain.upb.h +135 -0
  216. data/src/core/ext/upb-generated/google/api/expr/v1alpha1/syntax.upb.c +122 -98
  217. data/src/core/ext/upb-generated/google/api/expr/v1alpha1/syntax.upb.h +2 -0
  218. data/src/core/ext/upb-generated/google/api/expr/v1alpha1/value.upb.c +115 -0
  219. data/src/core/ext/upb-generated/google/api/expr/v1alpha1/value.upb.h +371 -0
  220. data/src/core/ext/upb-generated/google/api/http.upb.c +35 -22
  221. data/src/core/ext/upb-generated/google/api/http.upb.h +2 -0
  222. data/src/core/ext/upb-generated/google/protobuf/any.upb.c +14 -3
  223. data/src/core/ext/upb-generated/google/protobuf/any.upb.h +2 -0
  224. data/src/core/ext/upb-generated/google/protobuf/descriptor.upb.c +247 -210
  225. data/src/core/ext/upb-generated/google/protobuf/descriptor.upb.h +2 -0
  226. data/src/core/ext/upb-generated/google/protobuf/duration.upb.c +14 -3
  227. data/src/core/ext/upb-generated/google/protobuf/duration.upb.h +2 -0
  228. data/src/core/ext/upb-generated/google/protobuf/empty.upb.c +12 -1
  229. data/src/core/ext/upb-generated/google/protobuf/empty.upb.h +2 -0
  230. data/src/core/ext/upb-generated/google/protobuf/struct.upb.c +37 -23
  231. data/src/core/ext/upb-generated/google/protobuf/struct.upb.h +2 -0
  232. data/src/core/ext/upb-generated/google/protobuf/timestamp.upb.c +14 -3
  233. data/src/core/ext/upb-generated/google/protobuf/timestamp.upb.h +2 -0
  234. data/src/core/ext/upb-generated/google/protobuf/wrappers.upb.c +37 -18
  235. data/src/core/ext/upb-generated/google/protobuf/wrappers.upb.h +2 -0
  236. data/src/core/ext/upb-generated/google/rpc/status.upb.c +17 -6
  237. data/src/core/ext/upb-generated/google/rpc/status.upb.h +2 -0
  238. data/src/core/ext/upb-generated/src/proto/grpc/gcp/altscontext.upb.c +26 -14
  239. data/src/core/ext/upb-generated/src/proto/grpc/gcp/altscontext.upb.h +2 -0
  240. data/src/core/ext/upb-generated/src/proto/grpc/gcp/handshaker.upb.c +105 -83
  241. data/src/core/ext/upb-generated/src/proto/grpc/gcp/handshaker.upb.h +2 -0
  242. data/src/core/ext/upb-generated/src/proto/grpc/gcp/transport_security_common.upb.c +20 -8
  243. data/src/core/ext/upb-generated/src/proto/grpc/gcp/transport_security_common.upb.h +2 -0
  244. data/src/core/ext/upb-generated/src/proto/grpc/health/v1/health.upb.c +16 -4
  245. data/src/core/ext/upb-generated/src/proto/grpc/health/v1/health.upb.h +2 -0
  246. data/src/core/ext/upb-generated/src/proto/grpc/lb/v1/load_balancer.upb.c +65 -47
  247. data/src/core/ext/upb-generated/src/proto/grpc/lb/v1/load_balancer.upb.h +34 -36
  248. data/src/core/ext/upb-generated/src/proto/grpc/lookup/v1/rls.upb.c +26 -13
  249. data/src/core/ext/upb-generated/src/proto/grpc/lookup/v1/rls.upb.h +2 -0
  250. data/src/core/ext/upb-generated/udpa/annotations/migrate.upb.c +67 -7
  251. data/src/core/ext/upb-generated/udpa/annotations/migrate.upb.h +27 -0
  252. data/src/core/ext/upb-generated/udpa/annotations/security.upb.c +27 -3
  253. data/src/core/ext/upb-generated/udpa/annotations/security.upb.h +7 -0
  254. data/src/core/ext/upb-generated/udpa/annotations/sensitive.upb.c +19 -0
  255. data/src/core/ext/upb-generated/udpa/annotations/sensitive.upb.h +7 -0
  256. data/src/core/ext/upb-generated/udpa/annotations/status.upb.c +27 -3
  257. data/src/core/ext/upb-generated/udpa/annotations/status.upb.h +7 -0
  258. data/src/core/ext/upb-generated/udpa/annotations/versioning.upb.c +26 -2
  259. data/src/core/ext/upb-generated/udpa/annotations/versioning.upb.h +7 -0
  260. data/src/core/ext/upb-generated/validate/validate.upb.c +320 -251
  261. data/src/core/ext/upb-generated/validate/validate.upb.h +20 -0
  262. data/src/core/ext/upb-generated/xds/annotations/v3/status.upb.c +54 -9
  263. data/src/core/ext/upb-generated/xds/annotations/v3/status.upb.h +17 -0
  264. data/src/core/ext/upb-generated/xds/core/v3/authority.upb.c +13 -2
  265. data/src/core/ext/upb-generated/xds/core/v3/authority.upb.h +2 -0
  266. data/src/core/ext/upb-generated/xds/core/v3/collection_entry.upb.c +24 -12
  267. data/src/core/ext/upb-generated/xds/core/v3/collection_entry.upb.h +2 -0
  268. data/src/core/ext/upb-generated/xds/core/v3/context_params.upb.c +19 -7
  269. data/src/core/ext/upb-generated/xds/core/v3/context_params.upb.h +2 -0
  270. data/src/core/ext/upb-generated/xds/core/v3/resource.upb.c +18 -7
  271. data/src/core/ext/upb-generated/xds/core/v3/resource.upb.h +2 -0
  272. data/src/core/ext/upb-generated/xds/core/v3/resource_locator.upb.c +27 -15
  273. data/src/core/ext/upb-generated/xds/core/v3/resource_locator.upb.h +2 -0
  274. data/src/core/ext/upb-generated/xds/core/v3/resource_name.upb.c +18 -7
  275. data/src/core/ext/upb-generated/xds/core/v3/resource_name.upb.h +2 -0
  276. data/src/core/ext/upb-generated/xds/data/orca/v3/orca_load_report.upb.c +28 -15
  277. data/src/core/ext/upb-generated/xds/data/orca/v3/orca_load_report.upb.h +2 -0
  278. data/src/core/ext/upb-generated/xds/type/v3/typed_struct.upb.c +16 -5
  279. data/src/core/ext/upb-generated/xds/type/v3/typed_struct.upb.h +2 -0
  280. data/src/core/ext/upbdefs-generated/envoy/admin/v3/config_dump.upbdefs.c +2 -49
  281. data/src/core/ext/upbdefs-generated/envoy/annotations/deprecation.upbdefs.c +2 -2
  282. data/src/core/ext/upbdefs-generated/envoy/annotations/resource.upbdefs.c +2 -7
  283. data/src/core/ext/upbdefs-generated/envoy/config/accesslog/v3/accesslog.upbdefs.c +2 -35
  284. data/src/core/ext/upbdefs-generated/envoy/config/bootstrap/v3/bootstrap.upbdefs.c +2 -41
  285. data/src/core/ext/upbdefs-generated/envoy/config/cluster/v3/circuit_breaker.upbdefs.c +2 -11
  286. data/src/core/ext/upbdefs-generated/envoy/config/cluster/v3/cluster.upbdefs.c +2 -55
  287. data/src/core/ext/upbdefs-generated/envoy/config/cluster/v3/filter.upbdefs.c +2 -7
  288. data/src/core/ext/upbdefs-generated/envoy/config/cluster/v3/outlier_detection.upbdefs.c +2 -7
  289. data/src/core/ext/upbdefs-generated/envoy/config/core/v3/address.upbdefs.c +2 -19
  290. data/src/core/ext/upbdefs-generated/envoy/config/core/v3/backoff.upbdefs.c +2 -7
  291. data/src/core/ext/upbdefs-generated/envoy/config/core/v3/base.upbdefs.c +2 -53
  292. data/src/core/ext/upbdefs-generated/envoy/config/core/v3/config_source.upbdefs.c +2 -15
  293. data/src/core/ext/upbdefs-generated/envoy/config/core/v3/event_service_config.upbdefs.c +2 -7
  294. data/src/core/ext/upbdefs-generated/envoy/config/core/v3/extension.upbdefs.c +2 -9
  295. data/src/core/ext/upbdefs-generated/envoy/config/core/v3/grpc_service.upbdefs.c +2 -33
  296. data/src/core/ext/upbdefs-generated/envoy/config/core/v3/health_check.upbdefs.c +2 -21
  297. data/src/core/ext/upbdefs-generated/envoy/config/core/v3/http_uri.upbdefs.c +2 -7
  298. data/src/core/ext/upbdefs-generated/envoy/config/core/v3/protocol.upbdefs.c +2 -33
  299. data/src/core/ext/upbdefs-generated/envoy/config/core/v3/proxy_protocol.upbdefs.c +2 -7
  300. data/src/core/ext/upbdefs-generated/envoy/config/core/v3/resolver.upbdefs.c +2 -9
  301. data/src/core/ext/upbdefs-generated/envoy/config/core/v3/socket_option.upbdefs.c +2 -7
  302. data/src/core/ext/upbdefs-generated/envoy/config/core/v3/substitution_format_string.upbdefs.c +2 -7
  303. data/src/core/ext/upbdefs-generated/envoy/config/core/v3/udp_socket_config.upbdefs.c +2 -7
  304. data/src/core/ext/upbdefs-generated/envoy/config/endpoint/v3/endpoint.upbdefs.c +2 -13
  305. data/src/core/ext/upbdefs-generated/envoy/config/endpoint/v3/endpoint_components.upbdefs.c +2 -17
  306. data/src/core/ext/upbdefs-generated/envoy/config/endpoint/v3/load_report.upbdefs.c +2 -15
  307. data/src/core/ext/upbdefs-generated/envoy/config/listener/v3/api_listener.upbdefs.c +2 -7
  308. data/src/core/ext/upbdefs-generated/envoy/config/listener/v3/listener.upbdefs.c +2 -17
  309. data/src/core/ext/upbdefs-generated/envoy/config/listener/v3/listener_components.upbdefs.c +2 -19
  310. data/src/core/ext/upbdefs-generated/envoy/config/listener/v3/quic_config.upbdefs.c +2 -7
  311. data/src/core/ext/upbdefs-generated/envoy/config/listener/v3/udp_listener_config.upbdefs.c +2 -9
  312. data/src/core/ext/upbdefs-generated/envoy/config/metrics/v3/stats.upbdefs.c +2 -21
  313. data/src/core/ext/upbdefs-generated/envoy/config/overload/v3/overload.upbdefs.c +2 -23
  314. data/src/core/ext/upbdefs-generated/envoy/config/route/v3/route.upbdefs.c +2 -11
  315. data/src/core/ext/upbdefs-generated/envoy/config/route/v3/route_components.upbdefs.c +2 -111
  316. data/src/core/ext/upbdefs-generated/envoy/config/route/v3/scoped_route.upbdefs.c +2 -11
  317. data/src/core/ext/upbdefs-generated/envoy/config/trace/v3/http_tracer.upbdefs.c +2 -9
  318. data/src/core/ext/upbdefs-generated/envoy/extensions/clusters/aggregate/v3/cluster.upbdefs.c +2 -7
  319. data/src/core/ext/upbdefs-generated/envoy/extensions/filters/common/fault/v3/fault.upbdefs.c +2 -15
  320. data/src/core/ext/upbdefs-generated/envoy/extensions/filters/http/fault/v3/fault.upbdefs.c +2 -11
  321. data/src/core/ext/upbdefs-generated/envoy/extensions/filters/http/router/v3/router.upbdefs.c +2 -7
  322. data/src/core/ext/upbdefs-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upbdefs.c +2 -43
  323. data/src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/cert.upbdefs.c +2 -2
  324. data/src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/common.upbdefs.c +2 -17
  325. data/src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/secret.upbdefs.c +2 -11
  326. data/src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/tls.upbdefs.c +2 -17
  327. data/src/core/ext/upbdefs-generated/envoy/service/cluster/v3/cds.upbdefs.c +2 -7
  328. data/src/core/ext/upbdefs-generated/envoy/service/discovery/v3/ads.upbdefs.c +2 -7
  329. data/src/core/ext/upbdefs-generated/envoy/service/discovery/v3/discovery.upbdefs.c +2 -19
  330. data/src/core/ext/upbdefs-generated/envoy/service/endpoint/v3/eds.upbdefs.c +2 -7
  331. data/src/core/ext/upbdefs-generated/envoy/service/listener/v3/lds.upbdefs.c +2 -7
  332. data/src/core/ext/upbdefs-generated/envoy/service/load_stats/v3/lrs.upbdefs.c +2 -9
  333. data/src/core/ext/upbdefs-generated/envoy/service/route/v3/rds.upbdefs.c +2 -7
  334. data/src/core/ext/upbdefs-generated/envoy/service/route/v3/srds.upbdefs.c +2 -7
  335. data/src/core/ext/upbdefs-generated/envoy/service/status/v3/csds.upbdefs.c +2 -15
  336. data/src/core/ext/upbdefs-generated/envoy/type/http/v3/path_transformation.upbdefs.c +2 -13
  337. data/src/core/ext/upbdefs-generated/envoy/type/matcher/v3/metadata.upbdefs.c +2 -9
  338. data/src/core/ext/upbdefs-generated/envoy/type/matcher/v3/node.upbdefs.c +2 -7
  339. data/src/core/ext/upbdefs-generated/envoy/type/matcher/v3/number.upbdefs.c +2 -7
  340. data/src/core/ext/upbdefs-generated/envoy/type/matcher/v3/path.upbdefs.c +2 -7
  341. data/src/core/ext/upbdefs-generated/envoy/type/matcher/v3/regex.upbdefs.c +2 -11
  342. data/src/core/ext/upbdefs-generated/envoy/type/matcher/v3/string.upbdefs.c +2 -9
  343. data/src/core/ext/upbdefs-generated/envoy/type/matcher/v3/struct.upbdefs.c +2 -9
  344. data/src/core/ext/upbdefs-generated/envoy/type/matcher/v3/value.upbdefs.c +2 -11
  345. data/src/core/ext/upbdefs-generated/envoy/type/metadata/v3/metadata.upbdefs.c +2 -19
  346. data/src/core/ext/upbdefs-generated/envoy/type/tracing/v3/custom_tag.upbdefs.c +2 -15
  347. data/src/core/ext/upbdefs-generated/envoy/type/v3/http.upbdefs.c +2 -2
  348. data/src/core/ext/upbdefs-generated/envoy/type/v3/percent.upbdefs.c +2 -9
  349. data/src/core/ext/upbdefs-generated/envoy/type/v3/range.upbdefs.c +2 -11
  350. data/src/core/ext/upbdefs-generated/envoy/type/v3/semantic_version.upbdefs.c +2 -7
  351. data/src/core/ext/upbdefs-generated/google/api/annotations.upbdefs.c +2 -2
  352. data/src/core/ext/upbdefs-generated/google/api/http.upbdefs.c +2 -11
  353. data/src/core/ext/upbdefs-generated/google/protobuf/any.upbdefs.c +2 -7
  354. data/src/core/ext/upbdefs-generated/google/protobuf/descriptor.upbdefs.c +2 -59
  355. data/src/core/ext/upbdefs-generated/google/protobuf/duration.upbdefs.c +2 -7
  356. data/src/core/ext/upbdefs-generated/google/protobuf/empty.upbdefs.c +2 -7
  357. data/src/core/ext/upbdefs-generated/google/protobuf/struct.upbdefs.c +2 -13
  358. data/src/core/ext/upbdefs-generated/google/protobuf/timestamp.upbdefs.c +2 -7
  359. data/src/core/ext/upbdefs-generated/google/protobuf/wrappers.upbdefs.c +2 -23
  360. data/src/core/ext/upbdefs-generated/google/rpc/status.upbdefs.c +2 -7
  361. data/src/core/ext/upbdefs-generated/udpa/annotations/migrate.upbdefs.c +2 -11
  362. data/src/core/ext/upbdefs-generated/udpa/annotations/security.upbdefs.c +2 -7
  363. data/src/core/ext/upbdefs-generated/udpa/annotations/sensitive.upbdefs.c +2 -2
  364. data/src/core/ext/upbdefs-generated/udpa/annotations/status.upbdefs.c +2 -7
  365. data/src/core/ext/upbdefs-generated/udpa/annotations/versioning.upbdefs.c +2 -7
  366. data/src/core/ext/upbdefs-generated/validate/validate.upbdefs.c +2 -51
  367. data/src/core/ext/upbdefs-generated/xds/annotations/v3/status.upbdefs.c +2 -13
  368. data/src/core/ext/upbdefs-generated/xds/core/v3/authority.upbdefs.c +2 -7
  369. data/src/core/ext/upbdefs-generated/xds/core/v3/collection_entry.upbdefs.c +2 -9
  370. data/src/core/ext/upbdefs-generated/xds/core/v3/context_params.upbdefs.c +2 -9
  371. data/src/core/ext/upbdefs-generated/xds/core/v3/resource.upbdefs.c +2 -7
  372. data/src/core/ext/upbdefs-generated/xds/core/v3/resource_locator.upbdefs.c +2 -9
  373. data/src/core/ext/upbdefs-generated/xds/core/v3/resource_name.upbdefs.c +2 -7
  374. data/src/core/ext/upbdefs-generated/xds/type/v3/typed_struct.upbdefs.c +2 -7
  375. data/src/core/ext/xds/certificate_provider_registry.cc +1 -1
  376. data/src/core/ext/xds/certificate_provider_store.h +1 -1
  377. data/src/core/ext/xds/xds_api.cc +409 -304
  378. data/src/core/ext/xds/xds_api.h +3 -1
  379. data/src/core/ext/xds/xds_bootstrap.cc +6 -3
  380. data/src/core/ext/xds/xds_certificate_provider.h +1 -2
  381. data/src/core/ext/xds/xds_channel_stack_modifier.cc +3 -4
  382. data/src/core/ext/xds/xds_client.cc +395 -291
  383. data/src/core/ext/xds/xds_client.h +47 -38
  384. data/src/core/ext/xds/xds_routing.cc +247 -0
  385. data/src/core/ext/xds/xds_routing.h +98 -0
  386. data/src/core/ext/xds/xds_server_config_fetcher.cc +975 -261
  387. data/src/core/lib/avl/avl.h +389 -88
  388. data/src/core/lib/backoff/backoff.cc +2 -2
  389. data/src/core/lib/channel/channel_args.cc +17 -17
  390. data/src/core/lib/channel/channel_args.h +11 -10
  391. data/src/core/lib/channel/channel_args_preconditioning.cc +47 -0
  392. data/src/core/lib/channel/channel_args_preconditioning.h +62 -0
  393. data/src/core/lib/channel/channel_stack_builder.cc +0 -2
  394. data/src/core/lib/channel/channel_trace.cc +6 -6
  395. data/src/core/lib/channel/channelz.cc +1 -1
  396. data/src/core/lib/compression/compression_args.cc +7 -5
  397. data/src/core/lib/compression/compression_args.h +6 -4
  398. data/src/core/lib/config/core_configuration.cc +3 -1
  399. data/src/core/lib/config/core_configuration.h +11 -0
  400. data/src/core/lib/debug/trace.h +2 -2
  401. data/src/core/lib/event_engine/{endpoint_config.cc → channel_args_endpoint_config.cc} +2 -1
  402. data/src/core/lib/event_engine/{endpoint_config_internal.h → channel_args_endpoint_config.h} +3 -3
  403. data/src/core/lib/event_engine/event_engine.cc +0 -13
  404. data/src/core/lib/event_engine/event_engine_factory.cc +49 -0
  405. data/src/core/lib/event_engine/event_engine_factory.h +33 -0
  406. data/src/core/lib/event_engine/memory_allocator.cc +70 -0
  407. data/src/core/lib/gpr/tls.h +6 -0
  408. data/src/core/lib/gprpp/cpp_impl_of.h +45 -0
  409. data/src/core/lib/gprpp/global_config_env.cc +7 -7
  410. data/src/core/lib/gprpp/global_config_env.h +2 -2
  411. data/src/core/lib/gprpp/manual_constructor.h +2 -3
  412. data/src/core/lib/gprpp/orphanable.h +1 -1
  413. data/src/core/lib/gprpp/ref_counted.h +1 -1
  414. data/src/core/lib/gprpp/ref_counted_ptr.h +2 -4
  415. data/src/core/lib/gprpp/status_helper.h +1 -1
  416. data/src/core/lib/gprpp/table.h +13 -1
  417. data/src/core/lib/http/httpcli.cc +30 -26
  418. data/src/core/lib/http/httpcli.h +14 -12
  419. data/src/core/lib/iomgr/buffer_list.cc +9 -9
  420. data/src/core/lib/iomgr/buffer_list.h +13 -13
  421. data/src/core/lib/iomgr/call_combiner.cc +2 -3
  422. data/src/core/lib/iomgr/endpoint.h +0 -1
  423. data/src/core/lib/iomgr/endpoint_cfstream.cc +7 -24
  424. data/src/core/lib/iomgr/endpoint_cfstream.h +4 -4
  425. data/src/core/lib/iomgr/endpoint_pair_posix.cc +9 -11
  426. data/src/core/lib/iomgr/endpoint_pair_windows.cc +5 -14
  427. data/src/core/lib/iomgr/event_engine/endpoint.cc +2 -3
  428. data/src/core/lib/iomgr/event_engine/iomgr.cc +5 -25
  429. data/src/core/lib/iomgr/event_engine/resolver.cc +3 -2
  430. data/src/core/lib/iomgr/event_engine/tcp.cc +7 -5
  431. data/src/core/lib/iomgr/event_engine/timer.cc +4 -3
  432. data/src/core/lib/iomgr/exec_ctx.h +11 -11
  433. data/src/core/lib/iomgr/executor.cc +12 -15
  434. data/src/core/lib/iomgr/executor.h +1 -1
  435. data/src/core/lib/iomgr/tcp_client.cc +2 -4
  436. data/src/core/lib/iomgr/tcp_client.h +1 -3
  437. data/src/core/lib/iomgr/tcp_client_cfstream.cc +1 -9
  438. data/src/core/lib/iomgr/tcp_client_custom.cc +4 -10
  439. data/src/core/lib/iomgr/tcp_client_posix.cc +7 -23
  440. data/src/core/lib/iomgr/tcp_client_posix.h +3 -4
  441. data/src/core/lib/iomgr/tcp_client_windows.cc +1 -10
  442. data/src/core/lib/iomgr/tcp_custom.cc +9 -36
  443. data/src/core/lib/iomgr/tcp_custom.h +0 -1
  444. data/src/core/lib/iomgr/tcp_posix.cc +28 -33
  445. data/src/core/lib/iomgr/tcp_posix.h +1 -3
  446. data/src/core/lib/iomgr/tcp_server.cc +4 -6
  447. data/src/core/lib/iomgr/tcp_server.h +6 -8
  448. data/src/core/lib/iomgr/tcp_server_custom.cc +5 -15
  449. data/src/core/lib/iomgr/tcp_server_posix.cc +18 -22
  450. data/src/core/lib/iomgr/tcp_server_utils_posix.h +19 -18
  451. data/src/core/lib/iomgr/tcp_server_windows.cc +5 -12
  452. data/src/core/lib/iomgr/tcp_windows.cc +2 -7
  453. data/src/core/lib/iomgr/tcp_windows.h +1 -2
  454. data/src/core/lib/iomgr/unix_sockets_posix.cc +1 -1
  455. data/src/core/lib/iomgr/unix_sockets_posix.h +1 -1
  456. data/src/core/lib/iomgr/unix_sockets_posix_noop.cc +1 -1
  457. data/src/core/lib/iomgr/work_serializer.cc +115 -44
  458. data/src/core/lib/iomgr/work_serializer.h +16 -4
  459. data/src/core/lib/json/json_reader.cc +83 -35
  460. data/src/core/lib/json/json_util.cc +1 -1
  461. data/src/core/lib/promise/activity.cc +115 -0
  462. data/src/core/lib/promise/activity.h +499 -0
  463. data/src/core/lib/promise/context.h +86 -0
  464. data/src/core/lib/promise/detail/basic_seq.h +407 -0
  465. data/src/core/lib/promise/detail/promise_factory.h +189 -0
  466. data/src/core/lib/promise/detail/promise_like.h +85 -0
  467. data/src/core/lib/promise/detail/status.h +44 -0
  468. data/src/core/lib/promise/detail/switch.h +1455 -0
  469. data/src/core/lib/promise/exec_ctx_wakeup_scheduler.h +48 -0
  470. data/src/core/lib/promise/loop.h +108 -0
  471. data/src/core/lib/promise/map.h +88 -0
  472. data/src/core/lib/promise/poll.h +60 -0
  473. data/src/core/lib/promise/race.h +84 -0
  474. data/src/core/lib/promise/seq.h +71 -0
  475. data/src/core/lib/resource_quota/api.cc +108 -0
  476. data/src/core/lib/resource_quota/api.h +41 -0
  477. data/src/core/lib/resource_quota/memory_quota.cc +454 -0
  478. data/src/core/lib/resource_quota/memory_quota.h +421 -0
  479. data/src/core/lib/resource_quota/resource_quota.cc +33 -0
  480. data/src/core/lib/resource_quota/resource_quota.h +58 -0
  481. data/src/core/lib/resource_quota/thread_quota.cc +43 -0
  482. data/src/core/lib/resource_quota/thread_quota.h +57 -0
  483. data/src/core/lib/resource_quota/trace.cc +19 -0
  484. data/src/core/lib/resource_quota/trace.h +24 -0
  485. data/src/core/lib/security/authorization/evaluate_args.cc +13 -19
  486. data/src/core/lib/security/authorization/evaluate_args.h +2 -1
  487. data/src/core/lib/security/authorization/sdk_server_authz_filter.cc +3 -1
  488. data/src/core/lib/security/credentials/external/aws_external_account_credentials.cc +11 -12
  489. data/src/core/lib/security/credentials/external/external_account_credentials.cc +9 -10
  490. data/src/core/lib/security/credentials/external/url_external_account_credentials.cc +3 -4
  491. data/src/core/lib/security/credentials/google_default/google_default_credentials.cc +4 -6
  492. data/src/core/lib/security/credentials/jwt/jwt_credentials.cc +1 -1
  493. data/src/core/lib/security/credentials/jwt/jwt_verifier.cc +4 -6
  494. data/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc +18 -22
  495. data/src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.cc +11 -12
  496. data/src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.h +7 -8
  497. data/src/core/lib/security/credentials/tls/grpc_tls_certificate_verifier.cc +201 -0
  498. data/src/core/lib/security/credentials/tls/grpc_tls_certificate_verifier.h +106 -0
  499. data/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc +11 -90
  500. data/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h +19 -82
  501. data/src/core/lib/security/credentials/tls/tls_credentials.cc +21 -10
  502. data/src/core/lib/security/credentials/xds/xds_credentials.cc +28 -33
  503. data/src/core/lib/security/security_connector/alts/alts_security_connector.cc +3 -3
  504. data/src/core/lib/security/security_connector/alts/alts_security_connector.h +2 -2
  505. data/src/core/lib/security/security_connector/fake/fake_security_connector.cc +3 -4
  506. data/src/core/lib/security/security_connector/insecure/insecure_security_connector.cc +2 -2
  507. data/src/core/lib/security/security_connector/insecure/insecure_security_connector.h +7 -7
  508. data/src/core/lib/security/security_connector/load_system_roots_linux.cc +1 -2
  509. data/src/core/lib/security/security_connector/local/local_security_connector.cc +4 -1
  510. data/src/core/lib/security/security_connector/ssl_utils.cc +10 -2
  511. data/src/core/lib/security/security_connector/ssl_utils.h +1 -1
  512. data/src/core/lib/security/security_connector/tls/tls_security_connector.cc +344 -195
  513. data/src/core/lib/security/security_connector/tls/tls_security_connector.h +64 -41
  514. data/src/core/lib/security/transport/security_handshaker.cc +2 -2
  515. data/src/core/lib/slice/percent_encoding.cc +30 -86
  516. data/src/core/lib/slice/percent_encoding.h +5 -11
  517. data/src/core/lib/slice/slice.cc +7 -7
  518. data/src/core/lib/slice/slice.h +341 -0
  519. data/src/core/lib/slice/slice_buffer.cc +4 -0
  520. data/src/core/lib/slice/slice_intern.cc +1 -1
  521. data/src/core/lib/slice/slice_refcount.h +5 -1
  522. data/src/core/lib/slice/slice_refcount_base.h +19 -11
  523. data/src/core/lib/slice/static_slice.cc +331 -483
  524. data/src/core/lib/slice/static_slice.h +101 -132
  525. data/src/core/lib/surface/builtins.cc +1 -1
  526. data/src/core/lib/surface/call.cc +85 -59
  527. data/src/core/lib/surface/channel.cc +4 -29
  528. data/src/core/lib/surface/channel.h +2 -12
  529. data/src/core/lib/surface/completion_queue.cc +2 -2
  530. data/src/core/lib/surface/init.cc +0 -1
  531. data/src/core/lib/surface/lame_client.cc +24 -17
  532. data/src/core/lib/surface/server.cc +22 -22
  533. data/src/core/lib/surface/server.h +8 -9
  534. data/src/core/lib/surface/validate_metadata.cc +2 -2
  535. data/src/core/lib/surface/version.cc +2 -2
  536. data/src/core/lib/transport/bdp_estimator.cc +1 -1
  537. data/src/core/lib/transport/byte_stream.cc +4 -0
  538. data/src/core/lib/transport/metadata.h +4 -4
  539. data/src/core/lib/transport/metadata_batch.cc +5 -0
  540. data/src/core/lib/transport/metadata_batch.h +174 -99
  541. data/src/core/lib/transport/parsed_metadata.cc +35 -0
  542. data/src/core/lib/transport/parsed_metadata.h +180 -61
  543. data/src/core/lib/transport/pid_controller.cc +4 -4
  544. data/src/core/lib/transport/static_metadata.cc +529 -614
  545. data/src/core/lib/transport/static_metadata.h +0 -18
  546. data/src/core/lib/transport/transport.cc +4 -26
  547. data/src/core/lib/transport/transport.h +0 -1
  548. data/src/core/lib/transport/transport_op_string.cc +1 -1
  549. data/src/core/lib/uri/uri_parser.cc +19 -19
  550. data/src/core/lib/uri/uri_parser.h +2 -0
  551. data/src/core/plugin_registry/grpc_plugin_registry.cc +4 -2
  552. data/src/core/tsi/alts/handshaker/alts_handshaker_client.cc +1 -1
  553. data/src/core/tsi/local_transport_security.cc +15 -15
  554. data/src/core/tsi/ssl_transport_security.cc +30 -1
  555. data/src/core/tsi/ssl_transport_security.h +1 -0
  556. data/src/ruby/ext/grpc/extconf.rb +1 -1
  557. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +6 -10
  558. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +9 -15
  559. data/src/ruby/lib/grpc/version.rb +1 -1
  560. data/third_party/abseil-cpp/absl/algorithm/container.h +101 -91
  561. data/third_party/abseil-cpp/absl/base/attributes.h +64 -31
  562. data/third_party/abseil-cpp/absl/base/config.h +67 -37
  563. data/third_party/abseil-cpp/absl/base/dynamic_annotations.h +1 -26
  564. data/third_party/abseil-cpp/absl/base/internal/spinlock.h +3 -1
  565. data/third_party/abseil-cpp/absl/base/internal/spinlock_wait.h +2 -0
  566. data/third_party/abseil-cpp/absl/base/internal/sysinfo.cc +69 -0
  567. data/third_party/abseil-cpp/absl/base/internal/thread_identity.h +4 -4
  568. data/third_party/abseil-cpp/absl/base/internal/unscaledcycleclock.cc +16 -0
  569. data/third_party/abseil-cpp/absl/base/internal/unscaledcycleclock.h +4 -4
  570. data/third_party/abseil-cpp/absl/base/options.h +1 -1
  571. data/third_party/abseil-cpp/absl/container/fixed_array.h +0 -5
  572. data/third_party/abseil-cpp/absl/container/inlined_vector.h +105 -97
  573. data/third_party/abseil-cpp/absl/container/internal/hash_function_defaults.h +17 -15
  574. data/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler.cc +18 -102
  575. data/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler.h +37 -78
  576. data/third_party/abseil-cpp/absl/container/internal/inlined_vector.h +388 -423
  577. data/third_party/abseil-cpp/absl/container/internal/raw_hash_map.h +3 -2
  578. data/third_party/abseil-cpp/absl/container/internal/raw_hash_set.cc +14 -8
  579. data/third_party/abseil-cpp/absl/container/internal/raw_hash_set.h +251 -120
  580. data/third_party/abseil-cpp/absl/debugging/internal/demangle.cc +11 -1
  581. data/third_party/abseil-cpp/absl/debugging/internal/elf_mem_image.cc +12 -11
  582. data/third_party/abseil-cpp/absl/debugging/internal/elf_mem_image.h +6 -2
  583. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_config.h +12 -5
  584. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_emscripten-inl.inc +110 -0
  585. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_riscv-inl.inc +234 -0
  586. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_x86-inl.inc +25 -7
  587. data/third_party/abseil-cpp/absl/debugging/internal/symbolize.h +8 -2
  588. data/third_party/abseil-cpp/absl/debugging/internal/vdso_support.cc +21 -3
  589. data/third_party/abseil-cpp/absl/debugging/stacktrace.cc +2 -0
  590. data/third_party/abseil-cpp/absl/debugging/symbolize.cc +2 -0
  591. data/third_party/abseil-cpp/absl/debugging/symbolize_elf.inc +14 -0
  592. data/third_party/abseil-cpp/absl/debugging/symbolize_emscripten.inc +72 -0
  593. data/third_party/abseil-cpp/absl/functional/function_ref.h +4 -1
  594. data/third_party/abseil-cpp/absl/hash/hash.h +22 -0
  595. data/third_party/abseil-cpp/absl/hash/internal/hash.cc +15 -16
  596. data/third_party/abseil-cpp/absl/hash/internal/hash.h +88 -37
  597. data/third_party/abseil-cpp/absl/hash/internal/{wyhash.cc → low_level_hash.cc} +23 -11
  598. data/third_party/abseil-cpp/absl/hash/internal/{wyhash.h → low_level_hash.h} +14 -12
  599. data/third_party/abseil-cpp/absl/memory/memory.h +1 -1
  600. data/third_party/abseil-cpp/absl/meta/type_traits.h +32 -2
  601. data/third_party/abseil-cpp/absl/numeric/int128.cc +3 -10
  602. data/third_party/abseil-cpp/absl/numeric/int128.h +146 -73
  603. data/third_party/abseil-cpp/absl/numeric/int128_have_intrinsic.inc +19 -25
  604. data/third_party/abseil-cpp/absl/numeric/int128_no_intrinsic.inc +73 -70
  605. data/third_party/abseil-cpp/absl/{base → profiling}/internal/exponential_biased.cc +4 -4
  606. data/third_party/abseil-cpp/absl/{base → profiling}/internal/exponential_biased.h +6 -6
  607. data/third_party/abseil-cpp/absl/profiling/internal/sample_recorder.h +230 -0
  608. data/third_party/abseil-cpp/absl/status/internal/status_internal.h +5 -5
  609. data/third_party/abseil-cpp/absl/status/status.cc +9 -17
  610. data/third_party/abseil-cpp/absl/status/status.h +19 -15
  611. data/third_party/abseil-cpp/absl/status/statusor.cc +34 -2
  612. data/third_party/abseil-cpp/absl/status/statusor.h +31 -21
  613. data/third_party/abseil-cpp/absl/strings/charconv.cc +3 -3
  614. data/third_party/abseil-cpp/absl/strings/charconv.h +3 -2
  615. data/third_party/abseil-cpp/absl/strings/cord.cc +453 -359
  616. data/third_party/abseil-cpp/absl/strings/cord.h +197 -70
  617. data/third_party/abseil-cpp/absl/strings/internal/charconv_parse.cc +1 -1
  618. data/third_party/abseil-cpp/absl/strings/internal/cord_internal.cc +6 -0
  619. data/third_party/abseil-cpp/absl/strings/internal/cord_internal.h +140 -63
  620. data/third_party/abseil-cpp/absl/strings/internal/cord_rep_btree.cc +1128 -0
  621. data/third_party/abseil-cpp/absl/strings/internal/cord_rep_btree.h +939 -0
  622. data/third_party/abseil-cpp/absl/strings/internal/cord_rep_btree_navigator.cc +185 -0
  623. data/third_party/abseil-cpp/absl/strings/internal/cord_rep_btree_navigator.h +265 -0
  624. data/third_party/abseil-cpp/absl/strings/internal/cord_rep_btree_reader.cc +68 -0
  625. data/third_party/abseil-cpp/absl/strings/internal/cord_rep_btree_reader.h +211 -0
  626. data/third_party/abseil-cpp/absl/strings/internal/cord_rep_consume.cc +129 -0
  627. data/third_party/abseil-cpp/absl/strings/internal/cord_rep_consume.h +50 -0
  628. data/third_party/abseil-cpp/absl/strings/internal/cord_rep_flat.h +7 -7
  629. data/third_party/abseil-cpp/absl/strings/internal/cord_rep_ring.cc +55 -181
  630. data/third_party/abseil-cpp/absl/strings/internal/cord_rep_ring.h +42 -24
  631. data/third_party/abseil-cpp/absl/strings/internal/cord_rep_ring_reader.h +4 -0
  632. data/third_party/abseil-cpp/absl/strings/internal/cordz_functions.cc +96 -0
  633. data/third_party/abseil-cpp/absl/strings/internal/cordz_functions.h +85 -0
  634. data/third_party/abseil-cpp/absl/strings/internal/cordz_handle.cc +139 -0
  635. data/third_party/abseil-cpp/absl/strings/internal/cordz_handle.h +131 -0
  636. data/third_party/abseil-cpp/absl/strings/internal/cordz_info.cc +445 -0
  637. data/third_party/abseil-cpp/absl/strings/internal/cordz_info.h +298 -0
  638. data/third_party/abseil-cpp/absl/strings/internal/cordz_statistics.h +87 -0
  639. data/third_party/abseil-cpp/absl/strings/internal/cordz_update_scope.h +71 -0
  640. data/third_party/abseil-cpp/absl/strings/internal/cordz_update_tracker.h +121 -0
  641. data/third_party/abseil-cpp/absl/strings/internal/resize_uninitialized.h +48 -2
  642. data/third_party/abseil-cpp/absl/strings/internal/str_format/arg.h +8 -0
  643. data/third_party/abseil-cpp/absl/strings/internal/str_format/bind.cc +3 -4
  644. data/third_party/abseil-cpp/absl/strings/internal/str_format/bind.h +1 -1
  645. data/third_party/abseil-cpp/absl/strings/internal/str_format/extension.cc +6 -6
  646. data/third_party/abseil-cpp/absl/strings/internal/str_format/extension.h +36 -18
  647. data/third_party/abseil-cpp/absl/strings/internal/str_format/parser.cc +62 -73
  648. data/third_party/abseil-cpp/absl/strings/internal/str_format/parser.h +24 -16
  649. data/third_party/abseil-cpp/absl/strings/internal/str_split_internal.h +35 -35
  650. data/third_party/abseil-cpp/absl/strings/numbers.cc +1 -1
  651. data/third_party/abseil-cpp/absl/strings/numbers.h +34 -0
  652. data/third_party/abseil-cpp/absl/strings/str_cat.cc +4 -4
  653. data/third_party/abseil-cpp/absl/strings/str_format.h +1 -2
  654. data/third_party/abseil-cpp/absl/strings/string_view.cc +16 -21
  655. data/third_party/abseil-cpp/absl/strings/string_view.h +120 -39
  656. data/third_party/abseil-cpp/absl/strings/substitute.cc +2 -1
  657. data/third_party/abseil-cpp/absl/strings/substitute.h +99 -74
  658. data/third_party/abseil-cpp/absl/synchronization/blocking_counter.cc +25 -15
  659. data/third_party/abseil-cpp/absl/synchronization/blocking_counter.h +5 -3
  660. data/third_party/abseil-cpp/absl/synchronization/internal/waiter.cc +1 -1
  661. data/third_party/abseil-cpp/absl/synchronization/mutex.h +3 -3
  662. data/third_party/abseil-cpp/absl/time/civil_time.cc +1 -3
  663. data/third_party/abseil-cpp/absl/time/internal/cctz/include/cctz/time_zone.h +93 -20
  664. data/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_fixed.cc +1 -1
  665. data/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_if.h +2 -1
  666. data/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_info.cc +83 -21
  667. data/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_lookup.cc +49 -0
  668. data/third_party/abseil-cpp/absl/time/internal/cctz/src/tzfile.h +1 -1
  669. data/third_party/abseil-cpp/absl/time/internal/cctz/src/zone_info_source.cc +2 -3
  670. data/third_party/abseil-cpp/absl/time/time.h +67 -36
  671. data/third_party/abseil-cpp/absl/types/bad_optional_access.h +1 -1
  672. data/third_party/abseil-cpp/absl/types/bad_variant_access.h +2 -2
  673. data/third_party/abseil-cpp/absl/types/span.h +3 -3
  674. data/third_party/boringssl-with-bazel/err_data.c +681 -677
  675. data/third_party/boringssl-with-bazel/src/crypto/asn1/a_bitstr.c +19 -11
  676. data/third_party/boringssl-with-bazel/src/crypto/asn1/a_object.c +41 -30
  677. data/third_party/boringssl-with-bazel/src/crypto/asn1/a_time.c +1 -1
  678. data/third_party/boringssl-with-bazel/src/crypto/asn1/asn1_lib.c +59 -47
  679. data/third_party/boringssl-with-bazel/src/crypto/asn1/asn_pack.c +24 -28
  680. data/third_party/boringssl-with-bazel/src/crypto/asn1/f_int.c +5 -0
  681. data/third_party/boringssl-with-bazel/src/crypto/asn1/internal.h +28 -0
  682. data/third_party/boringssl-with-bazel/src/crypto/asn1/tasn_dec.c +48 -272
  683. data/third_party/boringssl-with-bazel/src/crypto/asn1/tasn_typ.c +8 -6
  684. data/third_party/boringssl-with-bazel/src/crypto/bytestring/ber.c +3 -1
  685. data/third_party/boringssl-with-bazel/src/crypto/evp/evp_asn1.c +2 -2
  686. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/self_check/self_check.c +7 -7
  687. data/third_party/boringssl-with-bazel/src/crypto/mem.c +18 -0
  688. data/third_party/boringssl-with-bazel/src/crypto/pool/internal.h +5 -1
  689. data/third_party/boringssl-with-bazel/src/crypto/pool/pool.c +59 -23
  690. data/third_party/boringssl-with-bazel/src/crypto/x509/asn1_gen.c +2 -18
  691. data/third_party/boringssl-with-bazel/src/crypto/x509/internal.h +8 -2
  692. data/third_party/boringssl-with-bazel/src/crypto/x509v3/internal.h +216 -11
  693. data/third_party/boringssl-with-bazel/src/crypto/x509v3/pcy_cache.c +1 -1
  694. data/third_party/boringssl-with-bazel/src/crypto/x509v3/pcy_data.c +1 -1
  695. data/third_party/boringssl-with-bazel/src/crypto/x509v3/pcy_lib.c +1 -1
  696. data/third_party/boringssl-with-bazel/src/crypto/x509v3/pcy_map.c +1 -1
  697. data/third_party/boringssl-with-bazel/src/crypto/x509v3/pcy_node.c +1 -1
  698. data/third_party/boringssl-with-bazel/src/crypto/x509v3/pcy_tree.c +1 -1
  699. data/third_party/boringssl-with-bazel/src/crypto/x509v3/v3_alt.c +1 -0
  700. data/third_party/boringssl-with-bazel/src/crypto/x509v3/v3_cpols.c +0 -1
  701. data/third_party/boringssl-with-bazel/src/crypto/x509v3/v3_lib.c +21 -4
  702. data/third_party/boringssl-with-bazel/src/include/openssl/asn1.h +971 -253
  703. data/third_party/boringssl-with-bazel/src/include/openssl/asn1t.h +3 -3
  704. data/third_party/boringssl-with-bazel/src/include/openssl/base.h +0 -1
  705. data/third_party/boringssl-with-bazel/src/include/openssl/dh.h +4 -12
  706. data/third_party/boringssl-with-bazel/src/include/openssl/dsa.h +17 -41
  707. data/third_party/boringssl-with-bazel/src/include/openssl/ec_key.h +12 -27
  708. data/third_party/boringssl-with-bazel/src/include/openssl/ecdsa.h +8 -10
  709. data/third_party/boringssl-with-bazel/src/include/openssl/evp.h +29 -55
  710. data/third_party/boringssl-with-bazel/src/include/openssl/pkcs7.h +3 -9
  711. data/third_party/boringssl-with-bazel/src/include/openssl/pool.h +7 -1
  712. data/third_party/boringssl-with-bazel/src/include/openssl/rsa.h +24 -28
  713. data/third_party/boringssl-with-bazel/src/include/openssl/ssl.h +6 -9
  714. data/third_party/boringssl-with-bazel/src/include/openssl/x509.h +12 -43
  715. data/third_party/boringssl-with-bazel/src/include/openssl/x509v3.h +4 -3
  716. data/third_party/boringssl-with-bazel/src/ssl/internal.h +3 -3
  717. data/third_party/boringssl-with-bazel/src/ssl/ssl_versions.cc +4 -0
  718. data/third_party/upb/upb/decode.c +309 -178
  719. data/third_party/upb/upb/decode_fast.c +1 -1
  720. data/third_party/upb/upb/decode_internal.h +1 -0
  721. data/third_party/upb/upb/def.c +330 -85
  722. data/third_party/upb/upb/def.h +45 -14
  723. data/third_party/upb/upb/def.hpp +17 -4
  724. data/third_party/upb/upb/encode.c +100 -40
  725. data/third_party/upb/upb/msg.c +22 -9
  726. data/third_party/upb/upb/msg_internal.h +90 -8
  727. data/third_party/upb/upb/reflection.c +98 -58
  728. data/third_party/upb/upb/reflection.h +6 -2
  729. data/third_party/upb/upb/text_encode.c +3 -3
  730. data/third_party/upb/upb/upb.c +8 -0
  731. metadata +116 -56
  732. data/src/core/lib/avl/avl.cc +0 -306
  733. data/src/core/lib/gprpp/match.h +0 -73
  734. data/src/core/lib/gprpp/overload.h +0 -59
  735. data/src/core/lib/iomgr/event_engine/iomgr.h +0 -42
  736. data/src/core/lib/iomgr/resource_quota.cc +0 -1106
  737. data/src/core/lib/iomgr/resource_quota.h +0 -226
  738. data/third_party/boringssl-with-bazel/src/crypto/asn1/f_enum.c +0 -93
  739. data/third_party/boringssl-with-bazel/src/crypto/x509v3/pcy_int.h +0 -217
@@ -36,8 +36,11 @@
36
36
  #include "absl/container/inlined_vector.h"
37
37
  #include "absl/strings/escaping.h"
38
38
  #include "absl/strings/internal/cord_internal.h"
39
+ #include "absl/strings/internal/cord_rep_btree.h"
39
40
  #include "absl/strings/internal/cord_rep_flat.h"
40
- #include "absl/strings/internal/cord_rep_ring.h"
41
+ #include "absl/strings/internal/cordz_statistics.h"
42
+ #include "absl/strings/internal/cordz_update_scope.h"
43
+ #include "absl/strings/internal/cordz_update_tracker.h"
41
44
  #include "absl/strings/internal/resize_uninitialized.h"
42
45
  #include "absl/strings/str_cat.h"
43
46
  #include "absl/strings/str_format.h"
@@ -48,19 +51,15 @@ namespace absl {
48
51
  ABSL_NAMESPACE_BEGIN
49
52
 
50
53
  using ::absl::cord_internal::CordRep;
54
+ using ::absl::cord_internal::CordRepBtree;
51
55
  using ::absl::cord_internal::CordRepConcat;
52
56
  using ::absl::cord_internal::CordRepExternal;
53
57
  using ::absl::cord_internal::CordRepFlat;
54
- using ::absl::cord_internal::CordRepRing;
55
58
  using ::absl::cord_internal::CordRepSubstring;
56
- using ::absl::cord_internal::kMinFlatLength;
59
+ using ::absl::cord_internal::CordzUpdateTracker;
60
+ using ::absl::cord_internal::InlineData;
57
61
  using ::absl::cord_internal::kMaxFlatLength;
58
-
59
- using ::absl::cord_internal::CONCAT;
60
- using ::absl::cord_internal::EXTERNAL;
61
- using ::absl::cord_internal::FLAT;
62
- using ::absl::cord_internal::RING;
63
- using ::absl::cord_internal::SUBSTRING;
62
+ using ::absl::cord_internal::kMinFlatLength;
64
63
 
65
64
  using ::absl::cord_internal::kInlinedVectorSize;
66
65
  using ::absl::cord_internal::kMaxBytesToCopy;
@@ -95,13 +94,13 @@ static constexpr uint64_t min_length[] = {
95
94
 
96
95
  static const int kMinLengthSize = ABSL_ARRAYSIZE(min_length);
97
96
 
98
- static inline bool cord_ring_enabled() {
99
- return cord_internal::cord_ring_buffer_enabled.load(
97
+ static inline bool btree_enabled() {
98
+ return cord_internal::cord_btree_enabled.load(
100
99
  std::memory_order_relaxed);
101
100
  }
102
101
 
103
102
  static inline bool IsRootBalanced(CordRep* node) {
104
- if (node->tag != CONCAT) {
103
+ if (!node->IsConcat()) {
105
104
  return true;
106
105
  } else if (node->concat()->depth() <= 15) {
107
106
  return true;
@@ -138,7 +137,7 @@ static inline CordRep* VerifyTree(CordRep* node) {
138
137
 
139
138
  // Return the depth of a node
140
139
  static int Depth(const CordRep* rep) {
141
- if (rep->tag == CONCAT) {
140
+ if (rep->IsConcat()) {
142
141
  return rep->concat()->depth();
143
142
  } else {
144
143
  return 0;
@@ -171,7 +170,7 @@ static CordRep* RawConcat(CordRep* left, CordRep* right) {
171
170
  }
172
171
 
173
172
  CordRepConcat* rep = new CordRepConcat();
174
- rep->tag = CONCAT;
173
+ rep->tag = cord_internal::CONCAT;
175
174
  SetConcatChildren(rep, left, right);
176
175
 
177
176
  return rep;
@@ -206,36 +205,32 @@ static CordRep* MakeBalancedTree(CordRep** reps, size_t n) {
206
205
  }
207
206
 
208
207
  static CordRepFlat* CreateFlat(const char* data, size_t length,
209
- size_t alloc_hint) {
208
+ size_t alloc_hint) {
210
209
  CordRepFlat* flat = CordRepFlat::New(length + alloc_hint);
211
210
  flat->length = length;
212
211
  memcpy(flat->Data(), data, length);
213
212
  return flat;
214
213
  }
215
214
 
216
- // Creates a new flat or ringbuffer out of the specified array.
215
+ // Creates a new flat or Btree out of the specified array.
217
216
  // The returned node has a refcount of 1.
218
- static CordRep* RingNewTree(const char* data, size_t length,
219
- size_t alloc_hint) {
217
+ static CordRep* NewBtree(const char* data, size_t length, size_t alloc_hint) {
220
218
  if (length <= kMaxFlatLength) {
221
219
  return CreateFlat(data, length, alloc_hint);
222
220
  }
223
221
  CordRepFlat* flat = CreateFlat(data, kMaxFlatLength, 0);
224
222
  data += kMaxFlatLength;
225
223
  length -= kMaxFlatLength;
226
- size_t extra = (length - 1) / kMaxFlatLength + 1;
227
- auto* root = CordRepRing::Create(flat, extra);
228
- return CordRepRing::Append(root, {data, length}, alloc_hint);
224
+ auto* root = CordRepBtree::Create(flat);
225
+ return CordRepBtree::Append(root, {data, length}, alloc_hint);
229
226
  }
230
227
 
231
228
  // Create a new tree out of the specified array.
232
229
  // The returned node has a refcount of 1.
233
- static CordRep* NewTree(const char* data,
234
- size_t length,
235
- size_t alloc_hint) {
230
+ static CordRep* NewTree(const char* data, size_t length, size_t alloc_hint) {
236
231
  if (length == 0) return nullptr;
237
- if (cord_ring_enabled()) {
238
- return RingNewTree(data, length, alloc_hint);
232
+ if (btree_enabled()) {
233
+ return NewBtree(data, length, alloc_hint);
239
234
  }
240
235
  absl::FixedArray<CordRep*> reps((length - 1) / kMaxFlatLength + 1);
241
236
  size_t n = 0;
@@ -272,13 +267,42 @@ static CordRep* NewSubstring(CordRep* child, size_t offset, size_t length) {
272
267
  CordRepSubstring* rep = new CordRepSubstring();
273
268
  assert((offset + length) <= child->length);
274
269
  rep->length = length;
275
- rep->tag = SUBSTRING;
270
+ rep->tag = cord_internal::SUBSTRING;
276
271
  rep->start = offset;
277
272
  rep->child = child;
278
273
  return VerifyTree(rep);
279
274
  }
280
275
  }
281
276
 
277
+ // Creates a CordRep from the provided string. If the string is large enough,
278
+ // and not wasteful, we move the string into an external cord rep, preserving
279
+ // the already allocated string contents.
280
+ // Requires the provided string length to be larger than `kMaxInline`.
281
+ static CordRep* CordRepFromString(std::string&& src) {
282
+ assert(src.length() > cord_internal::kMaxInline);
283
+ if (
284
+ // String is short: copy data to avoid external block overhead.
285
+ src.size() <= kMaxBytesToCopy ||
286
+ // String is wasteful: copy data to avoid pinning too much unused memory.
287
+ src.size() < src.capacity() / 2
288
+ ) {
289
+ return NewTree(src.data(), src.size(), 0);
290
+ }
291
+
292
+ struct StringReleaser {
293
+ void operator()(absl::string_view /* data */) {}
294
+ std::string data;
295
+ };
296
+ const absl::string_view original_data = src;
297
+ auto* rep =
298
+ static_cast<::absl::cord_internal::CordRepExternalImpl<StringReleaser>*>(
299
+ absl::cord_internal::NewExternalRep(original_data,
300
+ StringReleaser{std::move(src)}));
301
+ // Moving src may have invalidated its data pointer, so adjust it.
302
+ rep->base = rep->template get<0>().data.data();
303
+ return rep;
304
+ }
305
+
282
306
  // --------------------------------------------------------------------
283
307
  // Cord::InlineRep functions
284
308
 
@@ -299,20 +323,6 @@ inline char* Cord::InlineRep::set_data(size_t n) {
299
323
  return data_.as_chars();
300
324
  }
301
325
 
302
- inline CordRep* Cord::InlineRep::force_tree(size_t extra_hint) {
303
- if (data_.is_tree()) {
304
- return data_.as_tree();
305
- }
306
-
307
- size_t len = inline_size();
308
- CordRepFlat* result = CordRepFlat::New(len + extra_hint);
309
- result->length = len;
310
- static_assert(kMinFlatLength >= sizeof(data_), "");
311
- memcpy(result->Data(), data_.as_chars(), sizeof(data_));
312
- set_tree(result);
313
- return result;
314
- }
315
-
316
326
  inline void Cord::InlineRep::reduce_size(size_t n) {
317
327
  size_t tag = inline_size();
318
328
  assert(tag <= kMaxInline);
@@ -328,31 +338,78 @@ inline void Cord::InlineRep::remove_prefix(size_t n) {
328
338
  reduce_size(n);
329
339
  }
330
340
 
331
- // Returns `rep` converted into a CordRepRing.
332
- // Directly returns `rep` if `rep` is already a CordRepRing.
333
- static CordRepRing* ForceRing(CordRep* rep, size_t extra) {
334
- return (rep->tag == RING) ? rep->ring() : CordRepRing::Create(rep, extra);
341
+ // Returns `rep` converted into a CordRepBtree.
342
+ // Directly returns `rep` if `rep` is already a CordRepBtree.
343
+ static CordRepBtree* ForceBtree(CordRep* rep) {
344
+ return rep->IsBtree() ? rep->btree() : CordRepBtree::Create(rep);
335
345
  }
336
346
 
337
- void Cord::InlineRep::AppendTree(CordRep* tree) {
347
+ void Cord::InlineRep::AppendTreeToInlined(CordRep* tree,
348
+ MethodIdentifier method) {
349
+ assert(!is_tree());
350
+ if (!data_.is_empty()) {
351
+ CordRepFlat* flat = MakeFlatWithExtraCapacity(0);
352
+ if (btree_enabled()) {
353
+ tree = CordRepBtree::Append(CordRepBtree::Create(flat), tree);
354
+ } else {
355
+ tree = Concat(flat, tree);
356
+ }
357
+ }
358
+ EmplaceTree(tree, method);
359
+ }
360
+
361
+ void Cord::InlineRep::AppendTreeToTree(CordRep* tree, MethodIdentifier method) {
362
+ assert(is_tree());
363
+ const CordzUpdateScope scope(data_.cordz_info(), method);
364
+ if (btree_enabled()) {
365
+ tree = CordRepBtree::Append(ForceBtree(data_.as_tree()), tree);
366
+ } else {
367
+ tree = Concat(data_.as_tree(), tree);
368
+ }
369
+ SetTree(tree, scope);
370
+ }
371
+
372
+ void Cord::InlineRep::AppendTree(CordRep* tree, MethodIdentifier method) {
338
373
  if (tree == nullptr) return;
339
- if (data_.is_empty()) {
340
- set_tree(tree);
341
- } else if (cord_ring_enabled()) {
342
- set_tree(CordRepRing::Append(ForceRing(force_tree(0), 1), tree));
374
+ if (data_.is_tree()) {
375
+ AppendTreeToTree(tree, method);
343
376
  } else {
344
- set_tree(Concat(force_tree(0), tree));
377
+ AppendTreeToInlined(tree, method);
378
+ }
379
+ }
380
+
381
+ void Cord::InlineRep::PrependTreeToInlined(CordRep* tree,
382
+ MethodIdentifier method) {
383
+ assert(!is_tree());
384
+ if (!data_.is_empty()) {
385
+ CordRepFlat* flat = MakeFlatWithExtraCapacity(0);
386
+ if (btree_enabled()) {
387
+ tree = CordRepBtree::Prepend(CordRepBtree::Create(flat), tree);
388
+ } else {
389
+ tree = Concat(tree, flat);
390
+ }
345
391
  }
392
+ EmplaceTree(tree, method);
346
393
  }
347
394
 
348
- void Cord::InlineRep::PrependTree(CordRep* tree) {
395
+ void Cord::InlineRep::PrependTreeToTree(CordRep* tree,
396
+ MethodIdentifier method) {
397
+ assert(is_tree());
398
+ const CordzUpdateScope scope(data_.cordz_info(), method);
399
+ if (btree_enabled()) {
400
+ tree = CordRepBtree::Prepend(ForceBtree(data_.as_tree()), tree);
401
+ } else {
402
+ tree = Concat(tree, data_.as_tree());
403
+ }
404
+ SetTree(tree, scope);
405
+ }
406
+
407
+ void Cord::InlineRep::PrependTree(CordRep* tree, MethodIdentifier method) {
349
408
  assert(tree != nullptr);
350
- if (data_.is_empty()) {
351
- set_tree(tree);
352
- } else if (cord_ring_enabled()) {
353
- set_tree(CordRepRing::Prepend(ForceRing(force_tree(0), 1), tree));
409
+ if (data_.is_tree()) {
410
+ PrependTreeToTree(tree, method);
354
411
  } else {
355
- set_tree(Concat(tree, force_tree(0)));
412
+ PrependTreeToInlined(tree, method);
356
413
  }
357
414
  }
358
415
 
@@ -362,8 +419,8 @@ void Cord::InlineRep::PrependTree(CordRep* tree) {
362
419
  // written to region and the actual size increase will be written to size.
363
420
  static inline bool PrepareAppendRegion(CordRep* root, char** region,
364
421
  size_t* size, size_t max_length) {
365
- if (root->tag == RING && root->refcount.IsOne()) {
366
- Span<char> span = root->ring()->GetAppendBuffer(max_length);
422
+ if (root->IsBtree() && root->refcount.IsMutable()) {
423
+ Span<char> span = root->btree()->GetAppendBuffer(max_length);
367
424
  if (!span.empty()) {
368
425
  *region = span.data();
369
426
  *size = span.size();
@@ -373,11 +430,11 @@ static inline bool PrepareAppendRegion(CordRep* root, char** region,
373
430
 
374
431
  // Search down the right-hand path for a non-full FLAT node.
375
432
  CordRep* dst = root;
376
- while (dst->tag == CONCAT && dst->refcount.IsOne()) {
433
+ while (dst->IsConcat() && dst->refcount.IsMutable()) {
377
434
  dst = dst->concat()->right;
378
435
  }
379
436
 
380
- if (dst->tag < FLAT || !dst->refcount.IsOne()) {
437
+ if (!dst->IsFlat() || !dst->refcount.IsMutable()) {
381
438
  *region = nullptr;
382
439
  *size = 0;
383
440
  return false;
@@ -404,148 +461,140 @@ static inline bool PrepareAppendRegion(CordRep* root, char** region,
404
461
  return true;
405
462
  }
406
463
 
464
+ template <bool has_length>
407
465
  void Cord::InlineRep::GetAppendRegion(char** region, size_t* size,
408
- size_t max_length) {
409
- if (max_length == 0) {
410
- *region = nullptr;
411
- *size = 0;
412
- return;
413
- }
414
-
415
- // Try to fit in the inline buffer if possible.
416
- if (!is_tree()) {
417
- size_t inline_length = inline_size();
418
- if (max_length <= kMaxInline - inline_length) {
419
- *region = data_.as_chars() + inline_length;
420
- *size = max_length;
421
- set_inline_size(inline_length + max_length);
466
+ size_t length) {
467
+ auto constexpr method = CordzUpdateTracker::kGetAppendRegion;
468
+
469
+ CordRep* root = tree();
470
+ size_t sz = root ? root->length : inline_size();
471
+ if (root == nullptr) {
472
+ size_t available = kMaxInline - sz;
473
+ if (available >= (has_length ? length : 1)) {
474
+ *region = data_.as_chars() + sz;
475
+ *size = has_length ? length : available;
476
+ set_inline_size(has_length ? sz + length : kMaxInline);
422
477
  return;
423
478
  }
424
479
  }
425
480
 
426
- CordRep* root = force_tree(max_length);
427
-
428
- if (PrepareAppendRegion(root, region, size, max_length)) {
481
+ size_t extra = has_length ? length : (std::max)(sz, kMinFlatLength);
482
+ CordRep* rep = root ? root : MakeFlatWithExtraCapacity(extra);
483
+ CordzUpdateScope scope(root ? data_.cordz_info() : nullptr, method);
484
+ if (PrepareAppendRegion(rep, region, size, length)) {
485
+ CommitTree(root, rep, scope, method);
429
486
  return;
430
487
  }
431
488
 
432
489
  // Allocate new node.
433
- CordRepFlat* new_node =
434
- CordRepFlat::New(std::max(static_cast<size_t>(root->length), max_length));
435
- new_node->length = std::min(new_node->Capacity(), max_length);
490
+ CordRepFlat* new_node = CordRepFlat::New(extra);
491
+ new_node->length = std::min(new_node->Capacity(), length);
436
492
  *region = new_node->Data();
437
493
  *size = new_node->length;
438
494
 
439
- if (cord_ring_enabled()) {
440
- replace_tree(CordRepRing::Append(ForceRing(root, 1), new_node));
441
- return;
495
+ if (btree_enabled()) {
496
+ rep = CordRepBtree::Append(ForceBtree(rep), new_node);
497
+ } else {
498
+ rep = Concat(rep, new_node);
442
499
  }
443
- replace_tree(Concat(root, new_node));
500
+ CommitTree(root, rep, scope, method);
444
501
  }
445
502
 
446
- void Cord::InlineRep::GetAppendRegion(char** region, size_t* size) {
447
- const size_t max_length = std::numeric_limits<size_t>::max();
448
-
449
- // Try to fit in the inline buffer if possible.
450
- if (!data_.is_tree()) {
451
- size_t inline_length = inline_size();
452
- if (inline_length < kMaxInline) {
453
- *region = data_.as_chars() + inline_length;
454
- *size = kMaxInline - inline_length;
455
- set_inline_size(kMaxInline);
456
- return;
457
- }
503
+ // Computes the memory side of the provided edge which must be a valid data edge
504
+ // for a btrtee, i.e., a FLAT, EXTERNAL or SUBSTRING of a FLAT or EXTERNAL node.
505
+ static bool RepMemoryUsageDataEdge(const CordRep* rep,
506
+ size_t* total_mem_usage) {
507
+ size_t maybe_sub_size = 0;
508
+ if (ABSL_PREDICT_FALSE(rep->IsSubstring())) {
509
+ maybe_sub_size = sizeof(cord_internal::CordRepSubstring);
510
+ rep = rep->substring()->child;
458
511
  }
459
-
460
- CordRep* root = force_tree(max_length);
461
-
462
- if (PrepareAppendRegion(root, region, size, max_length)) {
463
- return;
512
+ if (rep->IsFlat()) {
513
+ *total_mem_usage += maybe_sub_size + rep->flat()->AllocatedSize();
514
+ return true;
464
515
  }
465
-
466
- // Allocate new node.
467
- CordRepFlat* new_node = CordRepFlat::New(root->length);
468
- new_node->length = new_node->Capacity();
469
- *region = new_node->Data();
470
- *size = new_node->length;
471
-
472
- if (cord_ring_enabled()) {
473
- replace_tree(CordRepRing::Append(ForceRing(root, 1), new_node));
474
- return;
516
+ if (rep->IsExternal()) {
517
+ // We don't know anything about the embedded / bound data, but we can safely
518
+ // assume it is 'at least' a word / pointer to data. In the future we may
519
+ // choose to use the 'data' byte as a tag to identify the types of some
520
+ // well-known externals, such as a std::string instance.
521
+ *total_mem_usage += maybe_sub_size +
522
+ sizeof(cord_internal::CordRepExternalImpl<intptr_t>) +
523
+ rep->length;
524
+ return true;
475
525
  }
476
- replace_tree(Concat(root, new_node));
526
+ return false;
477
527
  }
478
528
 
479
529
  // If the rep is a leaf, this will increment the value at total_mem_usage and
480
530
  // will return true.
481
531
  static bool RepMemoryUsageLeaf(const CordRep* rep, size_t* total_mem_usage) {
482
- if (rep->tag >= FLAT) {
532
+ if (rep->IsFlat()) {
483
533
  *total_mem_usage += rep->flat()->AllocatedSize();
484
534
  return true;
485
535
  }
486
- if (rep->tag == EXTERNAL) {
487
- *total_mem_usage += sizeof(CordRepConcat) + rep->length;
536
+ if (rep->IsExternal()) {
537
+ // We don't know anything about the embedded / bound data, but we can safely
538
+ // assume it is 'at least' a word / pointer to data. In the future we may
539
+ // choose to use the 'data' byte as a tag to identify the types of some
540
+ // well-known externals, such as a std::string instance.
541
+ *total_mem_usage +=
542
+ sizeof(cord_internal::CordRepExternalImpl<intptr_t>) + rep->length;
488
543
  return true;
489
544
  }
490
545
  return false;
491
546
  }
492
547
 
493
548
  void Cord::InlineRep::AssignSlow(const Cord::InlineRep& src) {
494
- ClearSlow();
549
+ assert(&src != this);
550
+ assert(is_tree() || src.is_tree());
551
+ auto constexpr method = CordzUpdateTracker::kAssignCord;
552
+ if (ABSL_PREDICT_TRUE(!is_tree())) {
553
+ EmplaceTree(CordRep::Ref(src.as_tree()), src.data_, method);
554
+ return;
555
+ }
495
556
 
496
- data_ = src.data_;
497
- if (is_tree()) {
498
- data_.set_profiled(false);
499
- CordRep::Ref(tree());
500
- clear_cordz_info();
557
+ CordRep* tree = as_tree();
558
+ if (CordRep* src_tree = src.tree()) {
559
+ // Leave any existing `cordz_info` in place, and let MaybeTrackCord()
560
+ // decide if this cord should be (or remains to be) sampled or not.
561
+ data_.set_tree(CordRep::Ref(src_tree));
562
+ CordzInfo::MaybeTrackCord(data_, src.data_, method);
563
+ } else {
564
+ CordzInfo::MaybeUntrackCord(data_.cordz_info());
565
+ data_ = src.data_;
501
566
  }
567
+ CordRep::Unref(tree);
502
568
  }
503
569
 
504
- void Cord::InlineRep::ClearSlow() {
570
+ void Cord::InlineRep::UnrefTree() {
505
571
  if (is_tree()) {
572
+ CordzInfo::MaybeUntrackCord(data_.cordz_info());
506
573
  CordRep::Unref(tree());
507
574
  }
508
- ResetToEmpty();
509
575
  }
510
576
 
511
577
  // --------------------------------------------------------------------
512
578
  // Constructors and destructors
513
579
 
514
- Cord::Cord(absl::string_view src) {
580
+ Cord::Cord(absl::string_view src, MethodIdentifier method)
581
+ : contents_(InlineData::kDefaultInit) {
515
582
  const size_t n = src.size();
516
583
  if (n <= InlineRep::kMaxInline) {
517
- contents_.set_data(src.data(), n, false);
584
+ contents_.set_data(src.data(), n, true);
518
585
  } else {
519
- contents_.set_tree(NewTree(src.data(), n, 0));
586
+ CordRep* rep = NewTree(src.data(), n, 0);
587
+ contents_.EmplaceTree(rep, method);
520
588
  }
521
589
  }
522
590
 
523
591
  template <typename T, Cord::EnableIfString<T>>
524
- Cord::Cord(T&& src) {
525
- if (
526
- // String is short: copy data to avoid external block overhead.
527
- src.size() <= kMaxBytesToCopy ||
528
- // String is wasteful: copy data to avoid pinning too much unused memory.
529
- src.size() < src.capacity() / 2
530
- ) {
531
- if (src.size() <= InlineRep::kMaxInline) {
532
- contents_.set_data(src.data(), src.size(), false);
533
- } else {
534
- contents_.set_tree(NewTree(src.data(), src.size(), 0));
535
- }
592
+ Cord::Cord(T&& src) : contents_(InlineData::kDefaultInit) {
593
+ if (src.size() <= InlineRep::kMaxInline) {
594
+ contents_.set_data(src.data(), src.size(), true);
536
595
  } else {
537
- struct StringReleaser {
538
- void operator()(absl::string_view /* data */) {}
539
- std::string data;
540
- };
541
- const absl::string_view original_data = src;
542
- auto* rep = static_cast<
543
- ::absl::cord_internal::CordRepExternalImpl<StringReleaser>*>(
544
- absl::cord_internal::NewExternalRep(
545
- original_data, StringReleaser{std::forward<T>(src)}));
546
- // Moving src may have invalidated its data pointer, so adjust it.
547
- rep->base = rep->template get<0>().data.data();
548
- contents_.set_tree(rep);
596
+ CordRep* rep = CordRepFromString(std::forward<T>(src));
597
+ contents_.EmplaceTree(rep, CordzUpdateTracker::kConstructorString);
549
598
  }
550
599
  }
551
600
 
@@ -554,9 +603,9 @@ template Cord::Cord(std::string&& src);
554
603
  // The destruction code is separate so that the compiler can determine
555
604
  // that it does not need to call the destructor on a moved-from Cord.
556
605
  void Cord::DestroyCordSlow() {
557
- if (CordRep* tree = contents_.tree()) {
558
- CordRep::Unref(VerifyTree(tree));
559
- }
606
+ assert(contents_.is_tree());
607
+ CordzInfo::MaybeUntrackCord(contents_.cordz_info());
608
+ CordRep::Unref(VerifyTree(contents_.as_tree()));
560
609
  }
561
610
 
562
611
  // --------------------------------------------------------------------
@@ -568,109 +617,116 @@ void Cord::Clear() {
568
617
  }
569
618
  }
570
619
 
571
- Cord& Cord::operator=(absl::string_view src) {
620
+ Cord& Cord::AssignLargeString(std::string&& src) {
621
+ auto constexpr method = CordzUpdateTracker::kAssignString;
622
+ assert(src.size() > kMaxBytesToCopy);
623
+ CordRep* rep = CordRepFromString(std::move(src));
624
+ if (CordRep* tree = contents_.tree()) {
625
+ CordzUpdateScope scope(contents_.cordz_info(), method);
626
+ contents_.SetTree(rep, scope);
627
+ CordRep::Unref(tree);
628
+ } else {
629
+ contents_.EmplaceTree(rep, method);
630
+ }
631
+ return *this;
632
+ }
572
633
 
634
+ Cord& Cord::operator=(absl::string_view src) {
635
+ auto constexpr method = CordzUpdateTracker::kAssignString;
573
636
  const char* data = src.data();
574
637
  size_t length = src.size();
575
638
  CordRep* tree = contents_.tree();
576
639
  if (length <= InlineRep::kMaxInline) {
577
- // Embed into this->contents_
640
+ // Embed into this->contents_, which is somewhat subtle:
641
+ // - MaybeUntrackCord must be called before Unref(tree).
642
+ // - MaybeUntrackCord must be called before set_data() clobbers cordz_info.
643
+ // - set_data() must be called before Unref(tree) as it may reference tree.
644
+ if (tree != nullptr) CordzInfo::MaybeUntrackCord(contents_.cordz_info());
578
645
  contents_.set_data(data, length, true);
579
- if (tree) CordRep::Unref(tree);
580
- return *this;
581
- }
582
- if (tree != nullptr && tree->tag >= FLAT &&
583
- tree->flat()->Capacity() >= length &&
584
- tree->refcount.IsOne()) {
585
- // Copy in place if the existing FLAT node is reusable.
586
- memmove(tree->flat()->Data(), data, length);
587
- tree->length = length;
588
- VerifyTree(tree);
646
+ if (tree != nullptr) CordRep::Unref(tree);
589
647
  return *this;
590
648
  }
591
- contents_.set_tree(NewTree(data, length, 0));
592
- if (tree) CordRep::Unref(tree);
593
- return *this;
594
- }
595
-
596
- template <typename T, Cord::EnableIfString<T>>
597
- Cord& Cord::operator=(T&& src) {
598
- if (src.size() <= kMaxBytesToCopy) {
599
- *this = absl::string_view(src);
649
+ if (tree != nullptr) {
650
+ CordzUpdateScope scope(contents_.cordz_info(), method);
651
+ if (tree->IsFlat() && tree->flat()->Capacity() >= length &&
652
+ tree->refcount.IsMutable()) {
653
+ // Copy in place if the existing FLAT node is reusable.
654
+ memmove(tree->flat()->Data(), data, length);
655
+ tree->length = length;
656
+ VerifyTree(tree);
657
+ return *this;
658
+ }
659
+ contents_.SetTree(NewTree(data, length, 0), scope);
660
+ CordRep::Unref(tree);
600
661
  } else {
601
- *this = Cord(std::forward<T>(src));
662
+ contents_.EmplaceTree(NewTree(data, length, 0), method);
602
663
  }
603
664
  return *this;
604
665
  }
605
666
 
606
- template Cord& Cord::operator=(std::string&& src);
607
-
608
667
  // TODO(sanjay): Move to Cord::InlineRep section of file. For now,
609
668
  // we keep it here to make diffs easier.
610
- void Cord::InlineRep::AppendArray(const char* src_data, size_t src_size) {
611
- if (src_size == 0) return; // memcpy(_, nullptr, 0) is undefined.
669
+ void Cord::InlineRep::AppendArray(absl::string_view src,
670
+ MethodIdentifier method) {
671
+ if (src.empty()) return; // memcpy(_, nullptr, 0) is undefined.
612
672
 
613
673
  size_t appended = 0;
614
- CordRep* root = nullptr;
615
- if (is_tree()) {
616
- root = data_.as_tree();
674
+ CordRep* rep = tree();
675
+ const CordRep* const root = rep;
676
+ CordzUpdateScope scope(root ? cordz_info() : nullptr, method);
677
+ if (root != nullptr) {
617
678
  char* region;
618
- if (PrepareAppendRegion(root, &region, &appended, src_size)) {
619
- memcpy(region, src_data, appended);
679
+ if (PrepareAppendRegion(rep, &region, &appended, src.size())) {
680
+ memcpy(region, src.data(), appended);
620
681
  }
621
682
  } else {
622
683
  // Try to fit in the inline buffer if possible.
623
684
  size_t inline_length = inline_size();
624
- if (src_size <= kMaxInline - inline_length) {
685
+ if (src.size() <= kMaxInline - inline_length) {
625
686
  // Append new data to embedded array
626
- memcpy(data_.as_chars() + inline_length, src_data, src_size);
627
- set_inline_size(inline_length + src_size);
687
+ memcpy(data_.as_chars() + inline_length, src.data(), src.size());
688
+ set_inline_size(inline_length + src.size());
628
689
  return;
629
690
  }
630
691
 
631
- // It is possible that src_data == data_, but when we transition from an
632
- // InlineRep to a tree we need to assign data_ = root via set_tree. To
633
- // avoid corrupting the source data before we copy it, delay calling
634
- // set_tree until after we've copied data.
635
- // We are going from an inline size to beyond inline size. Make the new size
636
- // either double the inlined size, or the added size + 10%.
637
- const size_t size1 = inline_length * 2 + src_size;
638
- const size_t size2 = inline_length + src_size / 10;
639
- root = CordRepFlat::New(std::max<size_t>(size1, size2));
640
- appended = std::min(
641
- src_size, root->flat()->Capacity() - inline_length);
642
- memcpy(root->flat()->Data(), data_.as_chars(), inline_length);
643
- memcpy(root->flat()->Data() + inline_length, src_data, appended);
644
- root->length = inline_length + appended;
645
- set_tree(root);
646
- }
647
-
648
- src_data += appended;
649
- src_size -= appended;
650
- if (src_size == 0) {
651
- return;
692
+ // Allocate flat to be a perfect fit on first append exceeding inlined size.
693
+ // Subsequent growth will use amortized growth until we reach maximum flat
694
+ // size.
695
+ rep = CordRepFlat::New(inline_length + src.size());
696
+ appended = std::min(src.size(), rep->flat()->Capacity() - inline_length);
697
+ memcpy(rep->flat()->Data(), data_.as_chars(), inline_length);
698
+ memcpy(rep->flat()->Data() + inline_length, src.data(), appended);
699
+ rep->length = inline_length + appended;
652
700
  }
653
701
 
654
- if (cord_ring_enabled()) {
655
- absl::string_view data(src_data, src_size);
656
- root = ForceRing(root, (data.size() - 1) / kMaxFlatLength + 1);
657
- replace_tree(CordRepRing::Append(root->ring(), data));
702
+ src.remove_prefix(appended);
703
+ if (src.empty()) {
704
+ CommitTree(root, rep, scope, method);
658
705
  return;
659
706
  }
660
707
 
661
- // Use new block(s) for any remaining bytes that were not handled above.
662
- // Alloc extra memory only if the right child of the root of the new tree is
663
- // going to be a FLAT node, which will permit further inplace appends.
664
- size_t length = src_size;
665
- if (src_size < kMaxFlatLength) {
666
- // The new length is either
667
- // - old size + 10%
668
- // - old_size + src_size
669
- // This will cause a reasonable conservative step-up in size that is still
670
- // large enough to avoid excessive amounts of small fragments being added.
671
- length = std::max<size_t>(root->length / 10, src_size);
708
+ if (btree_enabled()) {
709
+ // TODO(b/192061034): keep legacy 10% growth rate: consider other rates.
710
+ rep = ForceBtree(rep);
711
+ const size_t min_growth = std::max<size_t>(rep->length / 10, src.size());
712
+ rep = CordRepBtree::Append(rep->btree(), src, min_growth - src.size());
713
+ } else {
714
+ // Use new block(s) for any remaining bytes that were not handled above.
715
+ // Alloc extra memory only if the right child of the root of the new tree
716
+ // is going to be a FLAT node, which will permit further inplace appends.
717
+ size_t length = src.size();
718
+ if (src.size() < kMaxFlatLength) {
719
+ // The new length is either
720
+ // - old size + 10%
721
+ // - old_size + src.size()
722
+ // This will cause a reasonable conservative step-up in size that is
723
+ // still large enough to avoid excessive amounts of small fragments
724
+ // being added.
725
+ length = std::max<size_t>(rep->length / 10, src.size());
726
+ }
727
+ rep = Concat(rep, NewTree(src.data(), src.size(), length - src.size()));
672
728
  }
673
- set_tree(Concat(root, NewTree(src_data, src_size, length - src_size)));
729
+ CommitTree(root, rep, scope, method);
674
730
  }
675
731
 
676
732
  inline CordRep* Cord::TakeRep() const& {
@@ -685,10 +741,17 @@ inline CordRep* Cord::TakeRep() && {
685
741
 
686
742
  template <typename C>
687
743
  inline void Cord::AppendImpl(C&& src) {
744
+ auto constexpr method = CordzUpdateTracker::kAppendCord;
688
745
  if (empty()) {
689
- // In case of an empty destination avoid allocating a new node, do not copy
690
- // data.
691
- *this = std::forward<C>(src);
746
+ // Since destination is empty, we can avoid allocating a node,
747
+ if (src.contents_.is_tree()) {
748
+ // by taking the tree directly
749
+ CordRep* rep = std::forward<C>(src).TakeRep();
750
+ contents_.EmplaceTree(rep, method);
751
+ } else {
752
+ // or copying over inline data
753
+ contents_.data_ = src.contents_.data_;
754
+ }
692
755
  return;
693
756
  }
694
757
 
@@ -698,12 +761,12 @@ inline void Cord::AppendImpl(C&& src) {
698
761
  CordRep* src_tree = src.contents_.tree();
699
762
  if (src_tree == nullptr) {
700
763
  // src has embedded data.
701
- contents_.AppendArray(src.contents_.data(), src_size);
764
+ contents_.AppendArray({src.contents_.data(), src_size}, method);
702
765
  return;
703
766
  }
704
- if (src_tree->tag >= FLAT) {
767
+ if (src_tree->IsFlat()) {
705
768
  // src tree just has one flat node.
706
- contents_.AppendArray(src_tree->flat()->Data(), src_size);
769
+ contents_.AppendArray({src_tree->flat()->Data(), src_size}, method);
707
770
  return;
708
771
  }
709
772
  if (&src == this) {
@@ -719,19 +782,25 @@ inline void Cord::AppendImpl(C&& src) {
719
782
  }
720
783
 
721
784
  // Guaranteed to be a tree (kMaxBytesToCopy > kInlinedSize)
722
- contents_.AppendTree(std::forward<C>(src).TakeRep());
785
+ CordRep* rep = std::forward<C>(src).TakeRep();
786
+ contents_.AppendTree(rep, CordzUpdateTracker::kAppendCord);
723
787
  }
724
788
 
725
- void Cord::Append(const Cord& src) { AppendImpl(src); }
789
+ void Cord::Append(const Cord& src) {
790
+ AppendImpl(src);
791
+ }
726
792
 
727
- void Cord::Append(Cord&& src) { AppendImpl(std::move(src)); }
793
+ void Cord::Append(Cord&& src) {
794
+ AppendImpl(std::move(src));
795
+ }
728
796
 
729
797
  template <typename T, Cord::EnableIfString<T>>
730
798
  void Cord::Append(T&& src) {
731
799
  if (src.size() <= kMaxBytesToCopy) {
732
800
  Append(absl::string_view(src));
733
801
  } else {
734
- Append(Cord(std::forward<T>(src)));
802
+ CordRep* rep = CordRepFromString(std::forward<T>(src));
803
+ contents_.AppendTree(rep, CordzUpdateTracker::kAppendString);
735
804
  }
736
805
  }
737
806
 
@@ -741,7 +810,7 @@ void Cord::Prepend(const Cord& src) {
741
810
  CordRep* src_tree = src.contents_.tree();
742
811
  if (src_tree != nullptr) {
743
812
  CordRep::Ref(src_tree);
744
- contents_.PrependTree(src_tree);
813
+ contents_.PrependTree(src_tree, CordzUpdateTracker::kPrependCord);
745
814
  return;
746
815
  }
747
816
 
@@ -750,7 +819,7 @@ void Cord::Prepend(const Cord& src) {
750
819
  return Prepend(src_contents);
751
820
  }
752
821
 
753
- void Cord::Prepend(absl::string_view src) {
822
+ void Cord::PrependArray(absl::string_view src, MethodIdentifier method) {
754
823
  if (src.empty()) return; // memcpy(_, nullptr, 0) is undefined.
755
824
  if (!contents_.is_tree()) {
756
825
  size_t cur_size = contents_.inline_size();
@@ -764,7 +833,8 @@ void Cord::Prepend(absl::string_view src) {
764
833
  return;
765
834
  }
766
835
  }
767
- contents_.PrependTree(NewTree(src.data(), src.size(), 0));
836
+ CordRep* rep = NewTree(src.data(), src.size(), 0);
837
+ contents_.PrependTree(rep, method);
768
838
  }
769
839
 
770
840
  template <typename T, Cord::EnableIfString<T>>
@@ -772,7 +842,8 @@ inline void Cord::Prepend(T&& src) {
772
842
  if (src.size() <= kMaxBytesToCopy) {
773
843
  Prepend(absl::string_view(src));
774
844
  } else {
775
- Prepend(Cord(std::forward<T>(src)));
845
+ CordRep* rep = CordRepFromString(std::forward<T>(src));
846
+ contents_.PrependTree(rep, CordzUpdateTracker::kPrependString);
776
847
  }
777
848
  }
778
849
 
@@ -783,7 +854,7 @@ static CordRep* RemovePrefixFrom(CordRep* node, size_t n) {
783
854
  if (n == 0) return CordRep::Ref(node);
784
855
  absl::InlinedVector<CordRep*, kInlinedVectorSize> rhs_stack;
785
856
 
786
- while (node->tag == CONCAT) {
857
+ while (node->IsConcat()) {
787
858
  assert(n <= node->length);
788
859
  if (n < node->concat()->left->length) {
789
860
  // Push right to stack, descend left.
@@ -802,7 +873,7 @@ static CordRep* RemovePrefixFrom(CordRep* node, size_t n) {
802
873
  } else {
803
874
  size_t start = n;
804
875
  size_t len = node->length - n;
805
- if (node->tag == SUBSTRING) {
876
+ if (node->IsSubstring()) {
806
877
  // Consider in-place update of node, similar to in RemoveSuffixFrom().
807
878
  start += node->substring()->start;
808
879
  node = node->substring()->child;
@@ -823,9 +894,9 @@ static CordRep* RemoveSuffixFrom(CordRep* node, size_t n) {
823
894
  if (n >= node->length) return nullptr;
824
895
  if (n == 0) return CordRep::Ref(node);
825
896
  absl::InlinedVector<CordRep*, kInlinedVectorSize> lhs_stack;
826
- bool inplace_ok = node->refcount.IsOne();
897
+ bool inplace_ok = node->refcount.IsMutable();
827
898
 
828
- while (node->tag == CONCAT) {
899
+ while (node->IsConcat()) {
829
900
  assert(n <= node->length);
830
901
  if (n < node->concat()->right->length) {
831
902
  // Push left to stack, descend right.
@@ -836,13 +907,13 @@ static CordRep* RemoveSuffixFrom(CordRep* node, size_t n) {
836
907
  n -= node->concat()->right->length;
837
908
  node = node->concat()->left;
838
909
  }
839
- inplace_ok = inplace_ok && node->refcount.IsOne();
910
+ inplace_ok = inplace_ok && node->refcount.IsMutable();
840
911
  }
841
912
  assert(n <= node->length);
842
913
 
843
914
  if (n == 0) {
844
915
  CordRep::Ref(node);
845
- } else if (inplace_ok && node->tag != EXTERNAL) {
916
+ } else if (inplace_ok && !node->IsExternal()) {
846
917
  // Consider making a new buffer if the current node capacity is much
847
918
  // larger than the new length.
848
919
  CordRep::Ref(node);
@@ -850,7 +921,7 @@ static CordRep* RemoveSuffixFrom(CordRep* node, size_t n) {
850
921
  } else {
851
922
  size_t start = 0;
852
923
  size_t len = node->length - n;
853
- if (node->tag == SUBSTRING) {
924
+ if (node->IsSubstring()) {
854
925
  start = node->substring()->start;
855
926
  node = node->substring()->child;
856
927
  }
@@ -870,12 +941,19 @@ void Cord::RemovePrefix(size_t n) {
870
941
  CordRep* tree = contents_.tree();
871
942
  if (tree == nullptr) {
872
943
  contents_.remove_prefix(n);
873
- } else if (tree->tag == RING) {
874
- contents_.replace_tree(CordRepRing::RemovePrefix(tree->ring(), n));
875
944
  } else {
876
- CordRep* newrep = RemovePrefixFrom(tree, n);
877
- CordRep::Unref(tree);
878
- contents_.replace_tree(VerifyTree(newrep));
945
+ auto constexpr method = CordzUpdateTracker::kRemovePrefix;
946
+ CordzUpdateScope scope(contents_.cordz_info(), method);
947
+ if (tree->IsBtree()) {
948
+ CordRep* old = tree;
949
+ tree = tree->btree()->SubTree(n, tree->length - n);
950
+ CordRep::Unref(old);
951
+ } else {
952
+ CordRep* newrep = RemovePrefixFrom(tree, n);
953
+ CordRep::Unref(tree);
954
+ tree = VerifyTree(newrep);
955
+ }
956
+ contents_.SetTreeOrEmpty(tree, scope);
879
957
  }
880
958
  }
881
959
 
@@ -886,12 +964,17 @@ void Cord::RemoveSuffix(size_t n) {
886
964
  CordRep* tree = contents_.tree();
887
965
  if (tree == nullptr) {
888
966
  contents_.reduce_size(n);
889
- } else if (tree->tag == RING) {
890
- contents_.replace_tree(CordRepRing::RemoveSuffix(tree->ring(), n));
891
967
  } else {
892
- CordRep* newrep = RemoveSuffixFrom(tree, n);
893
- CordRep::Unref(tree);
894
- contents_.replace_tree(VerifyTree(newrep));
968
+ auto constexpr method = CordzUpdateTracker::kRemoveSuffix;
969
+ CordzUpdateScope scope(contents_.cordz_info(), method);
970
+ if (tree->IsBtree()) {
971
+ tree = CordRepBtree::RemoveSuffix(tree->btree(), n);
972
+ } else {
973
+ CordRep* newrep = RemoveSuffixFrom(tree, n);
974
+ CordRep::Unref(tree);
975
+ tree = VerifyTree(newrep);
976
+ }
977
+ contents_.SetTreeOrEmpty(tree, scope);
895
978
  }
896
979
  }
897
980
 
@@ -924,8 +1007,8 @@ static CordRep* NewSubRange(CordRep* node, size_t pos, size_t n) {
924
1007
  results.push_back(Concat(left, right));
925
1008
  } else if (pos == 0 && n == node->length) {
926
1009
  results.push_back(CordRep::Ref(node));
927
- } else if (node->tag != CONCAT) {
928
- if (node->tag == SUBSTRING) {
1010
+ } else if (!node->IsConcat()) {
1011
+ if (node->IsSubstring()) {
929
1012
  pos += node->substring()->start;
930
1013
  node = node->substring()->child;
931
1014
  }
@@ -951,17 +1034,20 @@ Cord Cord::Subcord(size_t pos, size_t new_size) const {
951
1034
  size_t length = size();
952
1035
  if (pos > length) pos = length;
953
1036
  if (new_size > length - pos) new_size = length - pos;
1037
+ if (new_size == 0) return sub_cord;
1038
+
954
1039
  CordRep* tree = contents_.tree();
955
1040
  if (tree == nullptr) {
956
1041
  // sub_cord is newly constructed, no need to re-zero-out the tail of
957
1042
  // contents_ memory.
958
1043
  sub_cord.contents_.set_data(contents_.data() + pos, new_size, false);
959
- } else if (new_size == 0) {
960
- // We want to return empty subcord, so nothing to do.
961
- } else if (new_size <= InlineRep::kMaxInline) {
1044
+ return sub_cord;
1045
+ }
1046
+
1047
+ if (new_size <= InlineRep::kMaxInline) {
1048
+ char* dest = sub_cord.contents_.data_.as_chars();
962
1049
  Cord::ChunkIterator it = chunk_begin();
963
1050
  it.AdvanceBytes(pos);
964
- char* dest = sub_cord.contents_.data_.as_chars();
965
1051
  size_t remaining_size = new_size;
966
1052
  while (remaining_size > it->size()) {
967
1053
  cord_internal::SmallMemmove(dest, it->data(), it->size());
@@ -971,12 +1057,16 @@ Cord Cord::Subcord(size_t pos, size_t new_size) const {
971
1057
  }
972
1058
  cord_internal::SmallMemmove(dest, it->data(), remaining_size);
973
1059
  sub_cord.contents_.set_inline_size(new_size);
974
- } else if (tree->tag == RING) {
975
- tree = CordRepRing::SubRing(CordRep::Ref(tree)->ring(), pos, new_size);
976
- sub_cord.contents_.set_tree(tree);
1060
+ return sub_cord;
1061
+ }
1062
+
1063
+ if (tree->IsBtree()) {
1064
+ tree = tree->btree()->SubTree(pos, new_size);
977
1065
  } else {
978
- sub_cord.contents_.set_tree(NewSubRange(tree, pos, new_size));
1066
+ tree = NewSubRange(tree, pos, new_size);
979
1067
  }
1068
+ sub_cord.contents_.EmplaceTree(tree, contents_.data_,
1069
+ CordzUpdateTracker::kSubCord);
980
1070
  return sub_cord;
981
1071
  }
982
1072
 
@@ -995,7 +1085,7 @@ class CordForest {
995
1085
  CordRep* node = pending.back();
996
1086
  pending.pop_back();
997
1087
  CheckNode(node);
998
- if (ABSL_PREDICT_FALSE(node->tag != CONCAT)) {
1088
+ if (ABSL_PREDICT_FALSE(!node->IsConcat())) {
999
1089
  AddNode(node);
1000
1090
  continue;
1001
1091
  }
@@ -1089,7 +1179,7 @@ class CordForest {
1089
1179
 
1090
1180
  static void CheckNode(CordRep* node) {
1091
1181
  ABSL_INTERNAL_CHECK(node->length != 0u, "");
1092
- if (node->tag == CONCAT) {
1182
+ if (node->IsConcat()) {
1093
1183
  ABSL_INTERNAL_CHECK(node->concat()->left != nullptr, "");
1094
1184
  ABSL_INTERNAL_CHECK(node->concat()->right != nullptr, "");
1095
1185
  ABSL_INTERNAL_CHECK(node->length == (node->concat()->left->length +
@@ -1109,7 +1199,7 @@ class CordForest {
1109
1199
 
1110
1200
  static CordRep* Rebalance(CordRep* node) {
1111
1201
  VerifyTree(node);
1112
- assert(node->tag == CONCAT);
1202
+ assert(node->IsConcat());
1113
1203
 
1114
1204
  if (node->length == 0) {
1115
1205
  return nullptr;
@@ -1159,28 +1249,33 @@ bool ComputeCompareResult<bool>(int memcmp_res) {
1159
1249
 
1160
1250
  } // namespace
1161
1251
 
1162
- // Helper routine. Locates the first flat chunk of the Cord without
1163
- // initializing the iterator.
1252
+ // Helper routine. Locates the first flat or external chunk of the Cord without
1253
+ // initializing the iterator, and returns a string_view referencing the data.
1164
1254
  inline absl::string_view Cord::InlineRep::FindFlatStartPiece() const {
1165
1255
  if (!is_tree()) {
1166
1256
  return absl::string_view(data_.as_chars(), data_.inline_size());
1167
1257
  }
1168
1258
 
1169
1259
  CordRep* node = tree();
1170
- if (node->tag >= FLAT) {
1260
+ if (node->IsFlat()) {
1171
1261
  return absl::string_view(node->flat()->Data(), node->length);
1172
1262
  }
1173
1263
 
1174
- if (node->tag == EXTERNAL) {
1264
+ if (node->IsExternal()) {
1175
1265
  return absl::string_view(node->external()->base, node->length);
1176
1266
  }
1177
1267
 
1178
- if (node->tag == RING) {
1179
- return node->ring()->entry_data(node->ring()->head());
1268
+ if (node->IsBtree()) {
1269
+ CordRepBtree* tree = node->btree();
1270
+ int height = tree->height();
1271
+ while (--height >= 0) {
1272
+ tree = tree->Edge(CordRepBtree::kFront)->btree();
1273
+ }
1274
+ return tree->Data(tree->begin());
1180
1275
  }
1181
1276
 
1182
1277
  // Walk down the left branches until we hit a non-CONCAT node.
1183
- while (node->tag == CONCAT) {
1278
+ while (node->IsConcat()) {
1184
1279
  node = node->concat()->left;
1185
1280
  }
1186
1281
 
@@ -1189,16 +1284,16 @@ inline absl::string_view Cord::InlineRep::FindFlatStartPiece() const {
1189
1284
  size_t length = node->length;
1190
1285
  assert(length != 0);
1191
1286
 
1192
- if (node->tag == SUBSTRING) {
1287
+ if (node->IsSubstring()) {
1193
1288
  offset = node->substring()->start;
1194
1289
  node = node->substring()->child;
1195
1290
  }
1196
1291
 
1197
- if (node->tag >= FLAT) {
1292
+ if (node->IsFlat()) {
1198
1293
  return absl::string_view(node->flat()->Data() + offset, length);
1199
1294
  }
1200
1295
 
1201
- assert((node->tag == EXTERNAL) && "Expect FLAT or EXTERNAL node here");
1296
+ assert(node->IsExternal() && "Expect FLAT or EXTERNAL node here");
1202
1297
 
1203
1298
  return absl::string_view(node->external()->base + offset, length);
1204
1299
  }
@@ -1392,7 +1487,7 @@ Cord::ChunkIterator& Cord::ChunkIterator::AdvanceStack() {
1392
1487
 
1393
1488
  // Walk down the left branches until we hit a non-CONCAT node. Save the
1394
1489
  // right children to the stack for subsequent traversal.
1395
- while (node->tag == CONCAT) {
1490
+ while (node->IsConcat()) {
1396
1491
  stack_of_right_children.push_back(node->concat()->right);
1397
1492
  node = node->concat()->left;
1398
1493
  }
@@ -1400,15 +1495,15 @@ Cord::ChunkIterator& Cord::ChunkIterator::AdvanceStack() {
1400
1495
  // Get the child node if we encounter a SUBSTRING.
1401
1496
  size_t offset = 0;
1402
1497
  size_t length = node->length;
1403
- if (node->tag == SUBSTRING) {
1498
+ if (node->IsSubstring()) {
1404
1499
  offset = node->substring()->start;
1405
1500
  node = node->substring()->child;
1406
1501
  }
1407
1502
 
1408
- assert(node->tag == EXTERNAL || node->tag >= FLAT);
1503
+ assert(node->IsExternal() || node->IsFlat());
1409
1504
  assert(length != 0);
1410
1505
  const char* data =
1411
- node->tag == EXTERNAL ? node->external()->base : node->flat()->Data();
1506
+ node->IsExternal() ? node->external()->base : node->flat()->Data();
1412
1507
  current_chunk_ = absl::string_view(data + offset, length);
1413
1508
  current_leaf_ = node;
1414
1509
  return *this;
@@ -1418,6 +1513,7 @@ Cord Cord::ChunkIterator::AdvanceAndReadBytes(size_t n) {
1418
1513
  ABSL_HARDENING_ASSERT(bytes_remaining_ >= n &&
1419
1514
  "Attempted to iterate past `end()`");
1420
1515
  Cord subcord;
1516
+ auto constexpr method = CordzUpdateTracker::kCordReader;
1421
1517
 
1422
1518
  if (n <= InlineRep::kMaxInline) {
1423
1519
  // Range to read fits in inline data. Flatten it.
@@ -1437,21 +1533,21 @@ Cord Cord::ChunkIterator::AdvanceAndReadBytes(size_t n) {
1437
1533
  return subcord;
1438
1534
  }
1439
1535
 
1440
- if (ring_reader_) {
1536
+ if (btree_reader_) {
1441
1537
  size_t chunk_size = current_chunk_.size();
1442
1538
  if (n <= chunk_size && n <= kMaxBytesToCopy) {
1443
- subcord = Cord(current_chunk_.substr(0, n));
1444
- } else {
1445
- auto* ring = CordRep::Ref(ring_reader_.ring())->ring();
1446
- size_t offset = ring_reader_.length() - bytes_remaining_;
1447
- subcord.contents_.set_tree(CordRepRing::SubRing(ring, offset, n));
1448
- }
1449
- if (n < chunk_size) {
1450
- bytes_remaining_ -= n;
1451
- current_chunk_.remove_prefix(n);
1539
+ subcord = Cord(current_chunk_.substr(0, n), method);
1540
+ if (n < chunk_size) {
1541
+ current_chunk_.remove_prefix(n);
1542
+ } else {
1543
+ current_chunk_ = btree_reader_.Next();
1544
+ }
1452
1545
  } else {
1453
- AdvanceBytesRing(n);
1546
+ CordRep* rep;
1547
+ current_chunk_ = btree_reader_.Read(n, chunk_size, rep);
1548
+ subcord.contents_.EmplaceTree(rep, method);
1454
1549
  }
1550
+ bytes_remaining_ -= n;
1455
1551
  return subcord;
1456
1552
  }
1457
1553
 
@@ -1460,10 +1556,10 @@ Cord Cord::ChunkIterator::AdvanceAndReadBytes(size_t n) {
1460
1556
  // Range to read is a proper subrange of the current chunk.
1461
1557
  assert(current_leaf_ != nullptr);
1462
1558
  CordRep* subnode = CordRep::Ref(current_leaf_);
1463
- const char* data = subnode->tag == EXTERNAL ? subnode->external()->base
1464
- : subnode->flat()->Data();
1559
+ const char* data = subnode->IsExternal() ? subnode->external()->base
1560
+ : subnode->flat()->Data();
1465
1561
  subnode = NewSubstring(subnode, current_chunk_.data() - data, n);
1466
- subcord.contents_.set_tree(VerifyTree(subnode));
1562
+ subcord.contents_.EmplaceTree(VerifyTree(subnode), method);
1467
1563
  RemoveChunkPrefix(n);
1468
1564
  return subcord;
1469
1565
  }
@@ -1473,8 +1569,8 @@ Cord Cord::ChunkIterator::AdvanceAndReadBytes(size_t n) {
1473
1569
  assert(current_leaf_ != nullptr);
1474
1570
  CordRep* subnode = CordRep::Ref(current_leaf_);
1475
1571
  if (current_chunk_.size() < subnode->length) {
1476
- const char* data = subnode->tag == EXTERNAL ? subnode->external()->base
1477
- : subnode->flat()->Data();
1572
+ const char* data = subnode->IsExternal() ? subnode->external()->base
1573
+ : subnode->flat()->Data();
1478
1574
  subnode = NewSubstring(subnode, current_chunk_.data() - data,
1479
1575
  current_chunk_.size());
1480
1576
  }
@@ -1506,13 +1602,13 @@ Cord Cord::ChunkIterator::AdvanceAndReadBytes(size_t n) {
1506
1602
  if (node == nullptr) {
1507
1603
  // We have reached the end of the Cord.
1508
1604
  assert(bytes_remaining_ == 0);
1509
- subcord.contents_.set_tree(VerifyTree(subnode));
1605
+ subcord.contents_.EmplaceTree(VerifyTree(subnode), method);
1510
1606
  return subcord;
1511
1607
  }
1512
1608
 
1513
1609
  // Walk down the appropriate branches until we hit a non-CONCAT node. Save the
1514
1610
  // right children to the stack for subsequent traversal.
1515
- while (node->tag == CONCAT) {
1611
+ while (node->IsConcat()) {
1516
1612
  if (node->concat()->left->length > n) {
1517
1613
  // Push right, descend left.
1518
1614
  stack_of_right_children.push_back(node->concat()->right);
@@ -1529,24 +1625,24 @@ Cord Cord::ChunkIterator::AdvanceAndReadBytes(size_t n) {
1529
1625
  // Get the child node if we encounter a SUBSTRING.
1530
1626
  size_t offset = 0;
1531
1627
  size_t length = node->length;
1532
- if (node->tag == SUBSTRING) {
1628
+ if (node->IsSubstring()) {
1533
1629
  offset = node->substring()->start;
1534
1630
  node = node->substring()->child;
1535
1631
  }
1536
1632
 
1537
1633
  // Range to read ends with a proper (possibly empty) subrange of the current
1538
1634
  // chunk.
1539
- assert(node->tag == EXTERNAL || node->tag >= FLAT);
1635
+ assert(node->IsExternal() || node->IsFlat());
1540
1636
  assert(length > n);
1541
1637
  if (n > 0) {
1542
1638
  subnode = Concat(subnode, NewSubstring(CordRep::Ref(node), offset, n));
1543
1639
  }
1544
1640
  const char* data =
1545
- node->tag == EXTERNAL ? node->external()->base : node->flat()->Data();
1641
+ node->IsExternal() ? node->external()->base : node->flat()->Data();
1546
1642
  current_chunk_ = absl::string_view(data + offset + n, length - n);
1547
1643
  current_leaf_ = node;
1548
1644
  bytes_remaining_ -= n;
1549
- subcord.contents_.set_tree(VerifyTree(subnode));
1645
+ subcord.contents_.EmplaceTree(VerifyTree(subnode), method);
1550
1646
  return subcord;
1551
1647
  }
1552
1648
 
@@ -1585,7 +1681,7 @@ void Cord::ChunkIterator::AdvanceBytesSlowPath(size_t n) {
1585
1681
 
1586
1682
  // Walk down the appropriate branches until we hit a non-CONCAT node. Save the
1587
1683
  // right children to the stack for subsequent traversal.
1588
- while (node->tag == CONCAT) {
1684
+ while (node->IsConcat()) {
1589
1685
  if (node->concat()->left->length > n) {
1590
1686
  // Push right, descend left.
1591
1687
  stack_of_right_children.push_back(node->concat()->right);
@@ -1601,15 +1697,15 @@ void Cord::ChunkIterator::AdvanceBytesSlowPath(size_t n) {
1601
1697
  // Get the child node if we encounter a SUBSTRING.
1602
1698
  size_t offset = 0;
1603
1699
  size_t length = node->length;
1604
- if (node->tag == SUBSTRING) {
1700
+ if (node->IsSubstring()) {
1605
1701
  offset = node->substring()->start;
1606
1702
  node = node->substring()->child;
1607
1703
  }
1608
1704
 
1609
- assert(node->tag == EXTERNAL || node->tag >= FLAT);
1705
+ assert(node->IsExternal() || node->IsFlat());
1610
1706
  assert(length > n);
1611
1707
  const char* data =
1612
- node->tag == EXTERNAL ? node->external()->base : node->flat()->Data();
1708
+ node->IsExternal() ? node->external()->base : node->flat()->Data();
1613
1709
  current_chunk_ = absl::string_view(data + offset + n, length - n);
1614
1710
  current_leaf_ = node;
1615
1711
  bytes_remaining_ -= n;
@@ -1625,15 +1721,15 @@ char Cord::operator[](size_t i) const {
1625
1721
  while (true) {
1626
1722
  assert(rep != nullptr);
1627
1723
  assert(offset < rep->length);
1628
- if (rep->tag >= FLAT) {
1724
+ if (rep->IsFlat()) {
1629
1725
  // Get the "i"th character directly from the flat array.
1630
1726
  return rep->flat()->Data()[offset];
1631
- } else if (rep->tag == RING) {
1632
- return rep->ring()->GetCharacter(offset);
1633
- } else if (rep->tag == EXTERNAL) {
1727
+ } else if (rep->IsBtree()) {
1728
+ return rep->btree()->GetCharacter(offset);
1729
+ } else if (rep->IsExternal()) {
1634
1730
  // Get the "i"th character from the external array.
1635
1731
  return rep->external()->base[offset];
1636
- } else if (rep->tag == CONCAT) {
1732
+ } else if (rep->IsConcat()) {
1637
1733
  // Recursively branch to the side of the concatenation that the "i"th
1638
1734
  // character is on.
1639
1735
  size_t left_length = rep->concat()->left->length;
@@ -1645,7 +1741,7 @@ char Cord::operator[](size_t i) const {
1645
1741
  }
1646
1742
  } else {
1647
1743
  // This must be a substring a node, so bypass it to get to the child.
1648
- assert(rep->tag == SUBSTRING);
1744
+ assert(rep->IsSubstring());
1649
1745
  offset += rep->substring()->start;
1650
1746
  rep = rep->substring()->child;
1651
1747
  }
@@ -1653,6 +1749,7 @@ char Cord::operator[](size_t i) const {
1653
1749
  }
1654
1750
 
1655
1751
  absl::string_view Cord::FlattenSlowPath() {
1752
+ assert(contents_.is_tree());
1656
1753
  size_t total_size = size();
1657
1754
  CordRep* new_rep;
1658
1755
  char* new_buffer;
@@ -1673,31 +1770,35 @@ absl::string_view Cord::FlattenSlowPath() {
1673
1770
  s.size());
1674
1771
  });
1675
1772
  }
1676
- if (CordRep* tree = contents_.tree()) {
1677
- CordRep::Unref(tree);
1678
- }
1679
- contents_.set_tree(new_rep);
1773
+ CordzUpdateScope scope(contents_.cordz_info(), CordzUpdateTracker::kFlatten);
1774
+ CordRep::Unref(contents_.as_tree());
1775
+ contents_.SetTree(new_rep, scope);
1680
1776
  return absl::string_view(new_buffer, total_size);
1681
1777
  }
1682
1778
 
1683
1779
  /* static */ bool Cord::GetFlatAux(CordRep* rep, absl::string_view* fragment) {
1684
1780
  assert(rep != nullptr);
1685
- if (rep->tag >= FLAT) {
1781
+ if (rep->IsFlat()) {
1686
1782
  *fragment = absl::string_view(rep->flat()->Data(), rep->length);
1687
1783
  return true;
1688
- } else if (rep->tag == EXTERNAL) {
1784
+ } else if (rep->IsExternal()) {
1689
1785
  *fragment = absl::string_view(rep->external()->base, rep->length);
1690
1786
  return true;
1691
- } else if (rep->tag == SUBSTRING) {
1787
+ } else if (rep->IsBtree()) {
1788
+ return rep->btree()->IsFlat(fragment);
1789
+ } else if (rep->IsSubstring()) {
1692
1790
  CordRep* child = rep->substring()->child;
1693
- if (child->tag >= FLAT) {
1791
+ if (child->IsFlat()) {
1694
1792
  *fragment = absl::string_view(
1695
1793
  child->flat()->Data() + rep->substring()->start, rep->length);
1696
1794
  return true;
1697
- } else if (child->tag == EXTERNAL) {
1795
+ } else if (child->IsExternal()) {
1698
1796
  *fragment = absl::string_view(
1699
1797
  child->external()->base + rep->substring()->start, rep->length);
1700
1798
  return true;
1799
+ } else if (child->IsBtree()) {
1800
+ return child->btree()->IsFlat(rep->substring()->start, rep->length,
1801
+ fragment);
1701
1802
  }
1702
1803
  }
1703
1804
  return false;
@@ -1706,7 +1807,7 @@ absl::string_view Cord::FlattenSlowPath() {
1706
1807
  /* static */ void Cord::ForEachChunkAux(
1707
1808
  absl::cord_internal::CordRep* rep,
1708
1809
  absl::FunctionRef<void(absl::string_view)> callback) {
1709
- if (rep->tag == RING) {
1810
+ if (rep->IsBtree()) {
1710
1811
  ChunkIterator it(rep), end;
1711
1812
  while (it != end) {
1712
1813
  callback(*it);
@@ -1722,7 +1823,7 @@ absl::string_view Cord::FlattenSlowPath() {
1722
1823
  absl::cord_internal::CordRep* stack[stack_max];
1723
1824
  absl::cord_internal::CordRep* current_node = rep;
1724
1825
  while (true) {
1725
- if (current_node->tag == CONCAT) {
1826
+ if (current_node->IsConcat()) {
1726
1827
  if (stack_pos == stack_max) {
1727
1828
  // There's no more room on our stack array to add another right branch,
1728
1829
  // and the idea is to avoid allocations, so call this function
@@ -1769,38 +1870,29 @@ static void DumpNode(CordRep* rep, bool include_data, std::ostream* os,
1769
1870
  *os << "]";
1770
1871
  *os << " " << (IsRootBalanced(rep) ? 'b' : 'u');
1771
1872
  *os << " " << std::setw(indent) << "";
1772
- if (rep->tag == CONCAT) {
1873
+ if (rep->IsConcat()) {
1773
1874
  *os << "CONCAT depth=" << Depth(rep) << "\n";
1774
1875
  indent += kIndentStep;
1775
1876
  indents.push_back(indent);
1776
1877
  stack.push_back(rep->concat()->right);
1777
1878
  rep = rep->concat()->left;
1778
- } else if (rep->tag == SUBSTRING) {
1879
+ } else if (rep->IsSubstring()) {
1779
1880
  *os << "SUBSTRING @ " << rep->substring()->start << "\n";
1780
1881
  indent += kIndentStep;
1781
1882
  rep = rep->substring()->child;
1782
1883
  } else { // Leaf or ring
1783
- if (rep->tag == EXTERNAL) {
1884
+ if (rep->IsExternal()) {
1784
1885
  *os << "EXTERNAL [";
1785
1886
  if (include_data)
1786
1887
  *os << absl::CEscape(std::string(rep->external()->base, rep->length));
1787
1888
  *os << "]\n";
1788
- } else if (rep->tag >= FLAT) {
1789
- *os << "FLAT cap=" << rep->flat()->Capacity()
1790
- << " [";
1889
+ } else if (rep->IsFlat()) {
1890
+ *os << "FLAT cap=" << rep->flat()->Capacity() << " [";
1791
1891
  if (include_data)
1792
1892
  *os << absl::CEscape(std::string(rep->flat()->Data(), rep->length));
1793
1893
  *os << "]\n";
1794
1894
  } else {
1795
- assert(rep->tag == RING);
1796
- auto* ring = rep->ring();
1797
- *os << "RING, entries = " << ring->entries() << "\n";
1798
- CordRepRing::index_type head = ring->head();
1799
- do {
1800
- DumpNode(ring->entry_child(head), include_data, os,
1801
- indent + kIndentStep);
1802
- head = ring->advance(head);;
1803
- } while (head != ring->tail());
1895
+ CordRepBtree::Dump(rep, /*label=*/ "", include_data, *os);
1804
1896
  }
1805
1897
  if (stack.empty()) break;
1806
1898
  rep = stack.back();
@@ -1832,7 +1924,7 @@ static bool VerifyNode(CordRep* root, CordRep* start_node,
1832
1924
  ABSL_INTERNAL_CHECK(node->length != 0, ReportError(root, node));
1833
1925
  }
1834
1926
 
1835
- if (node->tag == CONCAT) {
1927
+ if (node->IsConcat()) {
1836
1928
  ABSL_INTERNAL_CHECK(node->concat()->left != nullptr,
1837
1929
  ReportError(root, node));
1838
1930
  ABSL_INTERNAL_CHECK(node->concat()->right != nullptr,
@@ -1844,14 +1936,13 @@ static bool VerifyNode(CordRep* root, CordRep* start_node,
1844
1936
  worklist.push_back(node->concat()->right);
1845
1937
  worklist.push_back(node->concat()->left);
1846
1938
  }
1847
- } else if (node->tag >= FLAT) {
1848
- ABSL_INTERNAL_CHECK(
1849
- node->length <= node->flat()->Capacity(),
1850
- ReportError(root, node));
1851
- } else if (node->tag == EXTERNAL) {
1939
+ } else if (node->IsFlat()) {
1940
+ ABSL_INTERNAL_CHECK(node->length <= node->flat()->Capacity(),
1941
+ ReportError(root, node));
1942
+ } else if (node->IsExternal()) {
1852
1943
  ABSL_INTERNAL_CHECK(node->external()->base != nullptr,
1853
1944
  ReportError(root, node));
1854
- } else if (node->tag == SUBSTRING) {
1945
+ } else if (node->IsSubstring()) {
1855
1946
  ABSL_INTERNAL_CHECK(
1856
1947
  node->substring()->start < node->substring()->child->length,
1857
1948
  ReportError(root, node));
@@ -1880,7 +1971,7 @@ static bool VerifyNode(CordRep* root, CordRep* start_node,
1880
1971
  while (true) {
1881
1972
  const CordRep* next_node = nullptr;
1882
1973
 
1883
- if (cur_node->tag == CONCAT) {
1974
+ if (cur_node->IsConcat()) {
1884
1975
  total_mem_usage += sizeof(CordRepConcat);
1885
1976
  const CordRep* left = cur_node->concat()->left;
1886
1977
  if (!RepMemoryUsageLeaf(left, &total_mem_usage)) {
@@ -1894,18 +1985,21 @@ static bool VerifyNode(CordRep* root, CordRep* start_node,
1894
1985
  }
1895
1986
  next_node = right;
1896
1987
  }
1897
- } else if (cur_node->tag == RING) {
1898
- total_mem_usage += CordRepRing::AllocSize(cur_node->ring()->capacity());
1899
- const CordRepRing* ring = cur_node->ring();
1900
- CordRepRing::index_type pos = ring->head(), tail = ring->tail();
1901
- do {
1902
- CordRep* node = ring->entry_child(pos);
1903
- assert(node->tag >= FLAT || node->tag == EXTERNAL);
1904
- RepMemoryUsageLeaf(node, &total_mem_usage);
1905
- } while ((pos = ring->advance(pos)) != tail);
1988
+ } else if (cur_node->IsBtree()) {
1989
+ total_mem_usage += sizeof(CordRepBtree);
1990
+ const CordRepBtree* node = cur_node->btree();
1991
+ if (node->height() == 0) {
1992
+ for (const CordRep* edge : node->Edges()) {
1993
+ RepMemoryUsageDataEdge(edge, &total_mem_usage);
1994
+ }
1995
+ } else {
1996
+ for (const CordRep* edge : node->Edges()) {
1997
+ tree_stack.push_back(edge);
1998
+ }
1999
+ }
1906
2000
  } else {
1907
2001
  // Since cur_node is not a leaf or a concat node it must be a substring.
1908
- assert(cur_node->tag == SUBSTRING);
2002
+ assert(cur_node->IsSubstring());
1909
2003
  total_mem_usage += sizeof(CordRepSubstring);
1910
2004
  next_node = cur_node->substring()->child;
1911
2005
  if (RepMemoryUsageLeaf(next_node, &total_mem_usage)) {