grpc 1.37.1 → 1.38.0.pre1

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 (544) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +64 -58
  3. data/include/grpc/event_engine/README.md +38 -0
  4. data/include/grpc/event_engine/channel_args.h +28 -0
  5. data/include/grpc/event_engine/event_engine.h +336 -0
  6. data/include/grpc/event_engine/port.h +39 -0
  7. data/include/grpc/event_engine/slice_allocator.h +81 -0
  8. data/include/grpc/grpc.h +2 -2
  9. data/include/grpc/grpc_security_constants.h +14 -0
  10. data/include/grpc/impl/codegen/grpc_types.h +11 -0
  11. data/include/grpc/impl/codegen/port_platform.h +5 -0
  12. data/include/grpc/module.modulemap +14 -14
  13. data/src/core/ext/filters/client_channel/backup_poller.cc +3 -3
  14. data/src/core/ext/filters/client_channel/channel_connectivity.cc +177 -202
  15. data/src/core/ext/filters/client_channel/client_channel.cc +628 -3101
  16. data/src/core/ext/filters/client_channel/client_channel.h +489 -55
  17. data/src/core/ext/filters/client_channel/client_channel_channelz.h +1 -1
  18. data/src/core/ext/filters/client_channel/client_channel_plugin.cc +4 -1
  19. data/src/core/ext/filters/client_channel/config_selector.h +1 -1
  20. data/src/core/ext/filters/client_channel/connector.h +1 -1
  21. data/src/core/ext/filters/client_channel/dynamic_filters.cc +9 -10
  22. data/src/core/ext/filters/client_channel/dynamic_filters.h +3 -3
  23. data/src/core/ext/filters/client_channel/health/health_check_client.cc +26 -27
  24. data/src/core/ext/filters/client_channel/health/health_check_client.h +27 -26
  25. data/src/core/ext/filters/client_channel/http_connect_handshaker.cc +24 -21
  26. data/src/core/ext/filters/client_channel/lb_policy.cc +1 -1
  27. data/src/core/ext/filters/client_channel/lb_policy.h +4 -4
  28. data/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc +6 -6
  29. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +46 -43
  30. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc +1 -1
  31. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h +2 -1
  32. data/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +5 -5
  33. data/src/core/ext/filters/client_channel/lb_policy/priority/priority.cc +14 -12
  34. data/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +4 -4
  35. data/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +1 -1
  36. data/src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc +15 -15
  37. data/src/core/ext/filters/client_channel/lb_policy/xds/cds.cc +36 -30
  38. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_impl.cc +23 -23
  39. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_manager.cc +31 -46
  40. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_resolver.cc +84 -61
  41. data/src/core/ext/filters/client_channel/lb_policy_factory.h +1 -1
  42. data/src/core/ext/filters/client_channel/lb_policy_registry.cc +4 -4
  43. data/src/core/ext/filters/client_channel/lb_policy_registry.h +1 -1
  44. data/src/core/ext/filters/client_channel/resolver.h +2 -2
  45. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +23 -15
  46. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h +1 -1
  47. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc +3 -3
  48. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc +2 -2
  49. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc +14 -14
  50. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc +33 -24
  51. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h +1 -1
  52. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc +1 -1
  53. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc +1 -1
  54. data/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc +17 -9
  55. data/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc +20 -28
  56. data/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h +7 -5
  57. data/src/core/ext/filters/client_channel/resolver/google_c2p/google_c2p_resolver.cc +13 -11
  58. data/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc +1 -1
  59. data/src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc +43 -28
  60. data/src/core/ext/filters/client_channel/resolver_result_parsing.cc +32 -239
  61. data/src/core/ext/filters/client_channel/resolver_result_parsing.h +20 -49
  62. data/src/core/ext/filters/client_channel/retry_filter.cc +2188 -0
  63. data/src/core/ext/filters/client_channel/retry_filter.h +30 -0
  64. data/src/core/ext/filters/client_channel/retry_service_config.cc +287 -0
  65. data/src/core/ext/filters/client_channel/retry_service_config.h +90 -0
  66. data/src/core/ext/filters/client_channel/server_address.cc +1 -1
  67. data/src/core/ext/filters/client_channel/service_config.cc +15 -14
  68. data/src/core/ext/filters/client_channel/service_config.h +7 -6
  69. data/src/core/ext/filters/client_channel/service_config_channel_arg_filter.cc +5 -4
  70. data/src/core/ext/filters/client_channel/service_config_parser.cc +6 -6
  71. data/src/core/ext/filters/client_channel/service_config_parser.h +7 -4
  72. data/src/core/ext/filters/client_channel/subchannel.cc +17 -16
  73. data/src/core/ext/filters/client_channel/subchannel.h +7 -6
  74. data/src/core/ext/filters/client_idle/client_idle_filter.cc +16 -15
  75. data/src/core/ext/filters/deadline/deadline_filter.cc +10 -10
  76. data/src/core/ext/filters/fault_injection/fault_injection_filter.cc +19 -18
  77. data/src/core/ext/filters/fault_injection/service_config_parser.cc +5 -5
  78. data/src/core/ext/filters/fault_injection/service_config_parser.h +1 -1
  79. data/src/core/ext/filters/http/client/http_client_filter.cc +28 -21
  80. data/src/core/ext/filters/http/client_authority_filter.cc +3 -3
  81. data/src/core/ext/filters/http/message_compress/message_compress_filter.cc +23 -22
  82. data/src/core/ext/filters/http/message_compress/message_decompress_filter.cc +21 -21
  83. data/src/core/ext/filters/http/server/http_server_filter.cc +27 -23
  84. data/src/core/ext/filters/max_age/max_age_filter.cc +12 -10
  85. data/src/core/ext/filters/message_size/message_size_filter.cc +14 -11
  86. data/src/core/ext/filters/message_size/message_size_filter.h +1 -1
  87. data/src/core/ext/filters/workarounds/workaround_cronet_compression_filter.cc +4 -3
  88. data/src/core/ext/transport/chttp2/client/chttp2_connector.cc +7 -7
  89. data/src/core/ext/transport/chttp2/client/chttp2_connector.h +7 -7
  90. data/src/core/ext/transport/chttp2/client/insecure/channel_create.cc +2 -2
  91. data/src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc +1 -1
  92. data/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc +3 -3
  93. data/src/core/ext/transport/chttp2/server/chttp2_server.cc +44 -45
  94. data/src/core/ext/transport/chttp2/server/chttp2_server.h +2 -2
  95. data/src/core/ext/transport/chttp2/server/insecure/server_chttp2.cc +3 -4
  96. data/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc +2 -2
  97. data/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.cc +3 -4
  98. data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +129 -116
  99. data/src/core/ext/transport/chttp2/transport/context_list.cc +4 -5
  100. data/src/core/ext/transport/chttp2/transport/context_list.h +4 -4
  101. data/src/core/ext/transport/chttp2/transport/flow_control.cc +3 -3
  102. data/src/core/ext/transport/chttp2/transport/flow_control.h +8 -8
  103. data/src/core/ext/transport/chttp2/transport/frame_data.cc +8 -8
  104. data/src/core/ext/transport/chttp2/transport/frame_data.h +10 -10
  105. data/src/core/ext/transport/chttp2/transport/frame_goaway.cc +7 -8
  106. data/src/core/ext/transport/chttp2/transport/frame_goaway.h +6 -6
  107. data/src/core/ext/transport/chttp2/transport/frame_ping.cc +7 -8
  108. data/src/core/ext/transport/chttp2/transport/frame_ping.h +7 -6
  109. data/src/core/ext/transport/chttp2/transport/frame_rst_stream.cc +7 -7
  110. data/src/core/ext/transport/chttp2/transport/frame_rst_stream.h +6 -6
  111. data/src/core/ext/transport/chttp2/transport/frame_settings.cc +6 -5
  112. data/src/core/ext/transport/chttp2/transport/frame_settings.h +6 -6
  113. data/src/core/ext/transport/chttp2/transport/frame_window_update.cc +4 -6
  114. data/src/core/ext/transport/chttp2/transport/frame_window_update.h +4 -6
  115. data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +237 -208
  116. data/src/core/ext/transport/chttp2/transport/hpack_parser.h +10 -10
  117. data/src/core/ext/transport/chttp2/transport/hpack_table.cc +4 -3
  118. data/src/core/ext/transport/chttp2/transport/hpack_table.h +4 -4
  119. data/src/core/ext/transport/chttp2/transport/incoming_metadata.cc +2 -2
  120. data/src/core/ext/transport/chttp2/transport/incoming_metadata.h +2 -2
  121. data/src/core/ext/transport/chttp2/transport/internal.h +31 -27
  122. data/src/core/ext/transport/chttp2/transport/parsing.cc +63 -56
  123. data/src/core/ext/transport/chttp2/transport/writing.cc +7 -3
  124. data/src/core/ext/transport/inproc/inproc_transport.cc +30 -29
  125. data/src/core/ext/xds/certificate_provider_factory.h +1 -1
  126. data/src/core/ext/xds/certificate_provider_store.h +3 -3
  127. data/src/core/ext/xds/file_watcher_certificate_provider_factory.cc +3 -3
  128. data/src/core/ext/xds/file_watcher_certificate_provider_factory.h +2 -2
  129. data/src/core/ext/xds/xds_api.cc +101 -93
  130. data/src/core/ext/xds/xds_api.h +6 -6
  131. data/src/core/ext/xds/xds_bootstrap.cc +97 -159
  132. data/src/core/ext/xds/xds_bootstrap.h +19 -24
  133. data/src/core/ext/xds/xds_certificate_provider.cc +4 -4
  134. data/src/core/ext/xds/xds_certificate_provider.h +4 -4
  135. data/src/core/ext/xds/xds_channel_args.h +5 -2
  136. data/src/core/ext/xds/xds_client.cc +310 -178
  137. data/src/core/ext/xds/xds_client.h +41 -27
  138. data/src/core/ext/xds/xds_client_stats.h +3 -2
  139. data/src/core/ext/xds/xds_server_config_fetcher.cc +34 -20
  140. data/src/core/lib/{iomgr → address_utils}/parse_address.cc +17 -17
  141. data/src/core/lib/{iomgr → address_utils}/parse_address.h +7 -7
  142. data/src/core/lib/{iomgr → address_utils}/sockaddr_utils.cc +3 -20
  143. data/src/core/lib/{iomgr → address_utils}/sockaddr_utils.h +6 -11
  144. data/src/core/lib/channel/channel_stack.cc +10 -9
  145. data/src/core/lib/channel/channel_stack.h +10 -9
  146. data/src/core/lib/channel/channel_stack_builder.cc +2 -2
  147. data/src/core/lib/channel/channel_stack_builder.h +1 -1
  148. data/src/core/lib/channel/channelz.cc +21 -13
  149. data/src/core/lib/channel/connected_channel.cc +4 -4
  150. data/src/core/lib/channel/handshaker.cc +7 -6
  151. data/src/core/lib/channel/handshaker.h +5 -5
  152. data/src/core/lib/event_engine/slice_allocator.cc +59 -0
  153. data/src/core/lib/event_engine/sockaddr.cc +38 -0
  154. data/src/core/lib/gprpp/ref_counted.h +28 -14
  155. data/src/core/lib/gprpp/status_helper.cc +407 -0
  156. data/src/core/lib/gprpp/status_helper.h +180 -0
  157. data/src/core/lib/http/httpcli.cc +11 -11
  158. data/src/core/lib/http/httpcli_security_connector.cc +11 -7
  159. data/src/core/lib/http/parser.cc +16 -16
  160. data/src/core/lib/http/parser.h +4 -4
  161. data/src/core/lib/iomgr/buffer_list.cc +7 -9
  162. data/src/core/lib/iomgr/buffer_list.h +4 -5
  163. data/src/core/lib/iomgr/call_combiner.cc +15 -12
  164. data/src/core/lib/iomgr/call_combiner.h +12 -14
  165. data/src/core/lib/iomgr/cfstream_handle.cc +3 -3
  166. data/src/core/lib/iomgr/cfstream_handle.h +1 -1
  167. data/src/core/lib/iomgr/closure.h +7 -6
  168. data/src/core/lib/iomgr/combiner.cc +14 -12
  169. data/src/core/lib/iomgr/combiner.h +2 -2
  170. data/src/core/lib/iomgr/endpoint.cc +1 -1
  171. data/src/core/lib/iomgr/endpoint.h +2 -2
  172. data/src/core/lib/iomgr/endpoint_cfstream.cc +11 -13
  173. data/src/core/lib/iomgr/endpoint_pair_windows.cc +1 -1
  174. data/src/core/lib/iomgr/error.cc +167 -61
  175. data/src/core/lib/iomgr/error.h +217 -106
  176. data/src/core/lib/iomgr/error_cfstream.cc +3 -2
  177. data/src/core/lib/iomgr/error_cfstream.h +2 -2
  178. data/src/core/lib/iomgr/error_internal.h +5 -1
  179. data/src/core/lib/iomgr/ev_apple.cc +5 -5
  180. data/src/core/lib/iomgr/ev_epoll1_linux.cc +19 -19
  181. data/src/core/lib/iomgr/ev_epollex_linux.cc +48 -45
  182. data/src/core/lib/iomgr/ev_poll_posix.cc +26 -23
  183. data/src/core/lib/iomgr/ev_posix.cc +9 -8
  184. data/src/core/lib/iomgr/ev_posix.h +9 -9
  185. data/src/core/lib/iomgr/exec_ctx.cc +4 -4
  186. data/src/core/lib/iomgr/exec_ctx.h +1 -1
  187. data/src/core/lib/iomgr/executor.cc +8 -8
  188. data/src/core/lib/iomgr/executor.h +2 -2
  189. data/src/core/lib/iomgr/iomgr.cc +1 -1
  190. data/src/core/lib/iomgr/iomgr.h +1 -1
  191. data/src/core/lib/iomgr/iomgr_custom.cc +1 -1
  192. data/src/core/lib/iomgr/iomgr_internal.cc +2 -2
  193. data/src/core/lib/iomgr/iomgr_internal.h +3 -3
  194. data/src/core/lib/iomgr/iomgr_posix.cc +1 -1
  195. data/src/core/lib/iomgr/iomgr_posix_cfstream.cc +2 -2
  196. data/src/core/lib/iomgr/iomgr_windows.cc +1 -1
  197. data/src/core/lib/iomgr/load_file.cc +4 -4
  198. data/src/core/lib/iomgr/load_file.h +2 -2
  199. data/src/core/lib/iomgr/lockfree_event.cc +5 -5
  200. data/src/core/lib/iomgr/lockfree_event.h +1 -1
  201. data/src/core/lib/iomgr/pollset.cc +5 -5
  202. data/src/core/lib/iomgr/pollset.h +9 -9
  203. data/src/core/lib/iomgr/pollset_custom.cc +5 -5
  204. data/src/core/lib/iomgr/pollset_windows.cc +5 -5
  205. data/src/core/lib/iomgr/port.h +1 -1
  206. data/src/core/lib/iomgr/python_util.h +1 -1
  207. data/src/core/lib/iomgr/resolve_address.cc +3 -3
  208. data/src/core/lib/iomgr/resolve_address.h +6 -6
  209. data/src/core/lib/iomgr/resolve_address_custom.cc +10 -9
  210. data/src/core/lib/iomgr/resolve_address_custom.h +3 -3
  211. data/src/core/lib/iomgr/resolve_address_posix.cc +3 -3
  212. data/src/core/lib/iomgr/resolve_address_windows.cc +4 -4
  213. data/src/core/lib/iomgr/resource_quota.cc +11 -10
  214. data/src/core/lib/iomgr/socket_utils_common_posix.cc +22 -20
  215. data/src/core/lib/iomgr/socket_utils_posix.h +20 -20
  216. data/src/core/lib/iomgr/tcp_client_cfstream.cc +4 -4
  217. data/src/core/lib/iomgr/tcp_client_custom.cc +5 -6
  218. data/src/core/lib/iomgr/tcp_client_posix.cc +15 -17
  219. data/src/core/lib/iomgr/tcp_client_posix.h +3 -4
  220. data/src/core/lib/iomgr/tcp_client_windows.cc +5 -5
  221. data/src/core/lib/iomgr/tcp_custom.cc +14 -16
  222. data/src/core/lib/iomgr/tcp_custom.h +13 -12
  223. data/src/core/lib/iomgr/tcp_posix.cc +36 -34
  224. data/src/core/lib/iomgr/tcp_server.cc +6 -6
  225. data/src/core/lib/iomgr/tcp_server.h +12 -11
  226. data/src/core/lib/iomgr/tcp_server_custom.cc +23 -21
  227. data/src/core/lib/iomgr/tcp_server_posix.cc +22 -21
  228. data/src/core/lib/iomgr/tcp_server_utils_posix.h +13 -12
  229. data/src/core/lib/iomgr/tcp_server_utils_posix_common.cc +19 -17
  230. data/src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.cc +9 -9
  231. data/src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.cc +4 -4
  232. data/src/core/lib/iomgr/tcp_server_windows.cc +26 -25
  233. data/src/core/lib/iomgr/tcp_uv.cc +25 -23
  234. data/src/core/lib/iomgr/tcp_windows.cc +13 -13
  235. data/src/core/lib/iomgr/tcp_windows.h +2 -2
  236. data/src/core/lib/iomgr/timer_custom.cc +2 -1
  237. data/src/core/lib/iomgr/timer_custom.h +1 -1
  238. data/src/core/lib/iomgr/timer_generic.cc +6 -6
  239. data/src/core/lib/iomgr/udp_server.cc +21 -20
  240. data/src/core/lib/iomgr/unix_sockets_posix.cc +3 -3
  241. data/src/core/lib/iomgr/unix_sockets_posix.h +2 -2
  242. data/src/core/lib/iomgr/unix_sockets_posix_noop.cc +10 -7
  243. data/src/core/lib/iomgr/wakeup_fd_eventfd.cc +3 -3
  244. data/src/core/lib/iomgr/wakeup_fd_pipe.cc +4 -4
  245. data/src/core/lib/iomgr/wakeup_fd_posix.cc +3 -3
  246. data/src/core/lib/iomgr/wakeup_fd_posix.h +8 -6
  247. data/src/core/lib/iomgr/work_serializer.h +17 -1
  248. data/src/core/lib/json/json.h +1 -1
  249. data/src/core/lib/json/json_reader.cc +4 -4
  250. data/src/core/lib/matchers/matchers.cc +39 -39
  251. data/src/core/lib/matchers/matchers.h +28 -28
  252. data/src/core/lib/security/credentials/composite/composite_credentials.cc +4 -4
  253. data/src/core/lib/security/credentials/composite/composite_credentials.h +2 -2
  254. data/src/core/lib/security/credentials/credentials.h +2 -2
  255. data/src/core/lib/security/credentials/external/aws_external_account_credentials.cc +17 -13
  256. data/src/core/lib/security/credentials/external/aws_external_account_credentials.h +13 -11
  257. data/src/core/lib/security/credentials/external/aws_request_signer.cc +2 -1
  258. data/src/core/lib/security/credentials/external/aws_request_signer.h +1 -1
  259. data/src/core/lib/security/credentials/external/external_account_credentials.cc +15 -12
  260. data/src/core/lib/security/credentials/external/external_account_credentials.h +9 -8
  261. data/src/core/lib/security/credentials/external/file_external_account_credentials.cc +5 -4
  262. data/src/core/lib/security/credentials/external/file_external_account_credentials.h +4 -3
  263. data/src/core/lib/security/credentials/external/url_external_account_credentials.cc +8 -8
  264. data/src/core/lib/security/credentials/external/url_external_account_credentials.h +9 -7
  265. data/src/core/lib/security/credentials/fake/fake_credentials.cc +2 -2
  266. data/src/core/lib/security/credentials/fake/fake_credentials.h +2 -2
  267. data/src/core/lib/security/credentials/google_default/google_default_credentials.cc +9 -9
  268. data/src/core/lib/security/credentials/iam/iam_credentials.cc +2 -2
  269. data/src/core/lib/security/credentials/iam/iam_credentials.h +2 -2
  270. data/src/core/lib/security/credentials/jwt/json_token.cc +2 -2
  271. data/src/core/lib/security/credentials/jwt/jwt_credentials.cc +3 -3
  272. data/src/core/lib/security/credentials/jwt/jwt_credentials.h +2 -2
  273. data/src/core/lib/security/credentials/jwt/jwt_verifier.cc +7 -5
  274. data/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc +21 -19
  275. data/src/core/lib/security/credentials/oauth2/oauth2_credentials.h +5 -5
  276. data/src/core/lib/security/credentials/plugin/plugin_credentials.cc +5 -5
  277. data/src/core/lib/security/credentials/plugin/plugin_credentials.h +2 -2
  278. data/src/core/lib/security/credentials/tls/grpc_tls_certificate_distributor.cc +8 -7
  279. data/src/core/lib/security/credentials/tls/grpc_tls_certificate_distributor.h +9 -9
  280. data/src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.cc +19 -13
  281. data/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc +4 -0
  282. data/src/core/lib/security/credentials/xds/xds_credentials.cc +3 -3
  283. data/src/core/lib/security/security_connector/alts/alts_security_connector.cc +13 -3
  284. data/src/core/lib/security/security_connector/fake/fake_security_connector.cc +13 -3
  285. data/src/core/lib/security/security_connector/insecure/insecure_security_connector.cc +2 -2
  286. data/src/core/lib/security/security_connector/insecure/insecure_security_connector.h +12 -2
  287. data/src/core/lib/security/security_connector/load_system_roots_linux.cc +1 -1
  288. data/src/core/lib/security/security_connector/local/local_security_connector.cc +14 -4
  289. data/src/core/lib/security/security_connector/security_connector.h +9 -4
  290. data/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc +16 -6
  291. data/src/core/lib/security/security_connector/ssl_utils.cc +22 -4
  292. data/src/core/lib/security/security_connector/ssl_utils.h +4 -4
  293. data/src/core/lib/security/security_connector/tls/tls_security_connector.cc +56 -60
  294. data/src/core/lib/security/security_connector/tls/tls_security_connector.h +66 -48
  295. data/src/core/lib/security/transport/client_auth_filter.cc +18 -10
  296. data/src/core/lib/security/transport/secure_endpoint.cc +4 -4
  297. data/src/core/lib/security/transport/security_handshaker.cc +33 -32
  298. data/src/core/lib/security/transport/server_auth_filter.cc +19 -13
  299. data/src/core/lib/security/transport/tsi_error.cc +2 -1
  300. data/src/core/lib/security/transport/tsi_error.h +2 -1
  301. data/src/core/lib/security/util/json_util.cc +2 -2
  302. data/src/core/lib/security/util/json_util.h +1 -1
  303. data/src/core/lib/surface/call.cc +46 -45
  304. data/src/core/lib/surface/call.h +2 -2
  305. data/src/core/lib/surface/channel.cc +6 -6
  306. data/src/core/lib/surface/channel.h +3 -2
  307. data/src/core/lib/surface/channel_ping.cc +1 -1
  308. data/src/core/lib/surface/completion_queue.cc +46 -47
  309. data/src/core/lib/surface/completion_queue.h +2 -1
  310. data/src/core/lib/surface/lame_client.cc +11 -11
  311. data/src/core/lib/surface/lame_client.h +1 -1
  312. data/src/core/lib/surface/server.cc +28 -22
  313. data/src/core/lib/surface/server.h +16 -15
  314. data/src/core/lib/surface/validate_metadata.cc +7 -7
  315. data/src/core/lib/surface/validate_metadata.h +3 -2
  316. data/src/core/lib/surface/version.cc +4 -2
  317. data/src/core/lib/transport/byte_stream.cc +5 -5
  318. data/src/core/lib/transport/byte_stream.h +8 -8
  319. data/src/core/lib/transport/connectivity_state.cc +1 -1
  320. data/src/core/lib/transport/error_utils.cc +19 -8
  321. data/src/core/lib/transport/error_utils.h +11 -5
  322. data/src/core/lib/transport/metadata_batch.cc +37 -37
  323. data/src/core/lib/transport/metadata_batch.h +19 -18
  324. data/src/core/lib/transport/transport.cc +4 -3
  325. data/src/core/lib/transport/transport.h +4 -4
  326. data/src/core/lib/transport/transport_op_string.cc +5 -5
  327. data/src/core/tsi/alts/crypt/gsec.h +4 -0
  328. data/src/core/tsi/alts/handshaker/alts_handshaker_client.cc +5 -4
  329. data/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc +7 -6
  330. data/src/core/tsi/alts/handshaker/alts_tsi_handshaker_private.h +2 -1
  331. data/src/core/tsi/ssl_transport_security.cc +32 -14
  332. data/src/core/tsi/ssl_transport_security.h +3 -4
  333. data/src/ruby/bin/math_services_pb.rb +1 -1
  334. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +1 -1
  335. data/src/ruby/lib/grpc/version.rb +1 -1
  336. data/src/ruby/pb/grpc/health/v1/health_services_pb.rb +1 -1
  337. data/src/ruby/pb/src/proto/grpc/testing/test_services_pb.rb +6 -6
  338. data/third_party/abseil-cpp/absl/algorithm/container.h +3 -3
  339. data/third_party/abseil-cpp/absl/base/attributes.h +24 -4
  340. data/third_party/abseil-cpp/absl/base/call_once.h +2 -9
  341. data/third_party/abseil-cpp/absl/base/config.h +37 -9
  342. data/third_party/abseil-cpp/absl/base/dynamic_annotations.h +24 -10
  343. data/third_party/abseil-cpp/absl/base/internal/direct_mmap.h +4 -1
  344. data/third_party/abseil-cpp/absl/base/internal/endian.h +61 -0
  345. data/third_party/abseil-cpp/absl/base/internal/low_level_scheduling.h +2 -3
  346. data/third_party/abseil-cpp/absl/base/internal/raw_logging.cc +34 -32
  347. data/third_party/abseil-cpp/absl/base/internal/raw_logging.h +16 -6
  348. data/third_party/abseil-cpp/absl/base/internal/spinlock.cc +11 -2
  349. data/third_party/abseil-cpp/absl/base/internal/spinlock.h +14 -5
  350. data/third_party/abseil-cpp/absl/base/internal/spinlock_akaros.inc +2 -2
  351. data/third_party/abseil-cpp/absl/base/internal/spinlock_linux.inc +3 -3
  352. data/third_party/abseil-cpp/absl/base/internal/spinlock_posix.inc +2 -2
  353. data/third_party/abseil-cpp/absl/base/internal/spinlock_wait.h +11 -11
  354. data/third_party/abseil-cpp/absl/base/internal/spinlock_win32.inc +5 -5
  355. data/third_party/abseil-cpp/absl/base/internal/sysinfo.cc +1 -1
  356. data/third_party/abseil-cpp/absl/base/internal/thread_identity.cc +5 -2
  357. data/third_party/abseil-cpp/absl/base/internal/thread_identity.h +43 -42
  358. data/third_party/abseil-cpp/absl/base/internal/throw_delegate.cc +111 -7
  359. data/third_party/abseil-cpp/absl/base/internal/unaligned_access.h +0 -76
  360. data/third_party/abseil-cpp/absl/base/internal/unscaledcycleclock.cc +1 -3
  361. data/third_party/abseil-cpp/absl/base/log_severity.h +4 -4
  362. data/third_party/abseil-cpp/absl/base/macros.h +11 -0
  363. data/third_party/abseil-cpp/absl/base/optimization.h +10 -7
  364. data/third_party/abseil-cpp/absl/base/options.h +1 -1
  365. data/third_party/abseil-cpp/absl/base/port.h +0 -1
  366. data/third_party/abseil-cpp/absl/base/thread_annotations.h +1 -1
  367. data/third_party/abseil-cpp/absl/container/fixed_array.h +2 -2
  368. data/third_party/abseil-cpp/absl/container/inlined_vector.h +5 -3
  369. data/third_party/abseil-cpp/absl/container/internal/compressed_tuple.h +1 -1
  370. data/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler.cc +5 -1
  371. data/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler.h +2 -1
  372. data/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler_force_weak_definition.cc +2 -1
  373. data/third_party/abseil-cpp/absl/container/internal/inlined_vector.h +141 -66
  374. data/third_party/abseil-cpp/absl/container/internal/layout.h +4 -4
  375. data/third_party/abseil-cpp/absl/container/internal/raw_hash_set.cc +14 -1
  376. data/third_party/abseil-cpp/absl/container/internal/raw_hash_set.h +136 -136
  377. data/third_party/abseil-cpp/absl/debugging/internal/demangle.cc +16 -12
  378. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_aarch64-inl.inc +5 -2
  379. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_config.h +3 -12
  380. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_powerpc-inl.inc +6 -1
  381. data/third_party/abseil-cpp/absl/debugging/internal/symbolize.h +3 -5
  382. data/third_party/abseil-cpp/absl/debugging/symbolize_darwin.inc +2 -2
  383. data/third_party/abseil-cpp/absl/debugging/symbolize_elf.inc +2 -2
  384. data/third_party/abseil-cpp/absl/hash/internal/city.cc +15 -12
  385. data/third_party/abseil-cpp/absl/hash/internal/city.h +1 -19
  386. data/third_party/abseil-cpp/absl/hash/internal/hash.cc +25 -10
  387. data/third_party/abseil-cpp/absl/hash/internal/hash.h +86 -37
  388. data/third_party/abseil-cpp/absl/hash/internal/wyhash.cc +111 -0
  389. data/third_party/abseil-cpp/absl/hash/internal/wyhash.h +48 -0
  390. data/third_party/abseil-cpp/absl/meta/type_traits.h +16 -2
  391. data/third_party/abseil-cpp/absl/numeric/bits.h +177 -0
  392. data/third_party/abseil-cpp/absl/numeric/int128.cc +3 -3
  393. data/third_party/abseil-cpp/absl/numeric/internal/bits.h +358 -0
  394. data/third_party/abseil-cpp/absl/numeric/internal/representation.h +55 -0
  395. data/third_party/abseil-cpp/absl/status/internal/status_internal.h +18 -0
  396. data/third_party/abseil-cpp/absl/status/internal/statusor_internal.h +4 -7
  397. data/third_party/abseil-cpp/absl/status/status.cc +29 -22
  398. data/third_party/abseil-cpp/absl/status/status.h +81 -20
  399. data/third_party/abseil-cpp/absl/status/statusor.h +3 -3
  400. data/third_party/abseil-cpp/absl/strings/charconv.cc +5 -5
  401. data/third_party/abseil-cpp/absl/strings/cord.cc +326 -371
  402. data/third_party/abseil-cpp/absl/strings/cord.h +182 -64
  403. data/third_party/abseil-cpp/absl/strings/escaping.cc +4 -4
  404. data/third_party/abseil-cpp/absl/strings/internal/charconv_parse.cc +6 -6
  405. data/third_party/abseil-cpp/absl/strings/internal/cord_internal.cc +83 -0
  406. data/third_party/abseil-cpp/absl/strings/internal/cord_internal.h +387 -17
  407. data/third_party/abseil-cpp/absl/strings/internal/cord_rep_flat.h +146 -0
  408. data/third_party/abseil-cpp/absl/strings/internal/cord_rep_ring.cc +897 -0
  409. data/third_party/abseil-cpp/absl/strings/internal/cord_rep_ring.h +589 -0
  410. data/third_party/abseil-cpp/absl/strings/internal/cord_rep_ring_reader.h +114 -0
  411. data/third_party/abseil-cpp/absl/strings/internal/str_format/arg.cc +14 -0
  412. data/third_party/abseil-cpp/absl/strings/internal/str_format/arg.h +14 -0
  413. data/third_party/abseil-cpp/absl/strings/internal/str_format/bind.cc +15 -1
  414. data/third_party/abseil-cpp/absl/strings/internal/str_format/bind.h +19 -4
  415. data/third_party/abseil-cpp/absl/strings/internal/str_format/checker.h +14 -0
  416. data/third_party/abseil-cpp/absl/strings/internal/str_format/float_conversion.cc +36 -18
  417. data/third_party/abseil-cpp/absl/strings/internal/str_format/float_conversion.h +14 -0
  418. data/third_party/abseil-cpp/absl/strings/internal/str_format/parser.cc +14 -0
  419. data/third_party/abseil-cpp/absl/strings/internal/str_format/parser.h +14 -0
  420. data/third_party/abseil-cpp/absl/strings/internal/str_split_internal.h +15 -40
  421. data/third_party/abseil-cpp/absl/strings/internal/string_constant.h +64 -0
  422. data/third_party/abseil-cpp/absl/strings/match.cc +6 -3
  423. data/third_party/abseil-cpp/absl/strings/match.h +16 -6
  424. data/third_party/abseil-cpp/absl/strings/numbers.cc +132 -4
  425. data/third_party/abseil-cpp/absl/strings/numbers.h +10 -10
  426. data/third_party/abseil-cpp/absl/strings/str_join.h +1 -1
  427. data/third_party/abseil-cpp/absl/strings/str_split.h +38 -4
  428. data/third_party/abseil-cpp/absl/synchronization/internal/futex.h +154 -0
  429. data/third_party/abseil-cpp/absl/synchronization/internal/kernel_timeout.h +2 -1
  430. data/third_party/abseil-cpp/absl/synchronization/internal/per_thread_sem.cc +2 -2
  431. data/third_party/abseil-cpp/absl/synchronization/internal/per_thread_sem.h +4 -4
  432. data/third_party/abseil-cpp/absl/synchronization/internal/waiter.cc +1 -65
  433. data/third_party/abseil-cpp/absl/synchronization/internal/waiter.h +2 -6
  434. data/third_party/abseil-cpp/absl/synchronization/mutex.cc +71 -59
  435. data/third_party/abseil-cpp/absl/synchronization/mutex.h +79 -62
  436. data/third_party/abseil-cpp/absl/time/clock.cc +146 -130
  437. data/third_party/abseil-cpp/absl/time/clock.h +2 -2
  438. data/third_party/abseil-cpp/absl/time/duration.cc +3 -2
  439. data/third_party/abseil-cpp/absl/time/internal/cctz/include/cctz/civil_time_detail.h +7 -11
  440. data/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_libc.cc +7 -1
  441. data/third_party/abseil-cpp/absl/time/internal/cctz/src/tzfile.h +4 -4
  442. data/third_party/abseil-cpp/absl/time/time.cc +4 -3
  443. data/third_party/abseil-cpp/absl/time/time.h +26 -24
  444. data/third_party/abseil-cpp/absl/types/internal/variant.h +1 -1
  445. data/third_party/abseil-cpp/absl/types/variant.h +9 -4
  446. data/third_party/boringssl-with-bazel/err_data.c +477 -461
  447. data/third_party/boringssl-with-bazel/src/crypto/asn1/a_bool.c +1 -1
  448. data/third_party/boringssl-with-bazel/src/crypto/asn1/a_object.c +1 -1
  449. data/third_party/boringssl-with-bazel/src/crypto/asn1/a_type.c +18 -8
  450. data/third_party/boringssl-with-bazel/src/crypto/asn1/asn1_lib.c +1 -2
  451. data/third_party/boringssl-with-bazel/src/crypto/asn1/asn1_locl.h +5 -0
  452. data/third_party/boringssl-with-bazel/src/crypto/asn1/tasn_enc.c +1 -1
  453. data/third_party/boringssl-with-bazel/src/crypto/asn1/tasn_fre.c +1 -1
  454. data/third_party/boringssl-with-bazel/src/crypto/cipher_extra/e_tls.c +1 -88
  455. data/third_party/boringssl-with-bazel/src/crypto/cipher_extra/internal.h +14 -3
  456. data/third_party/boringssl-with-bazel/src/crypto/cipher_extra/tls_cbc.c +119 -273
  457. data/third_party/boringssl-with-bazel/src/crypto/err/err.c +87 -80
  458. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/bcm.c +1 -0
  459. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/bn/internal.h +1 -1
  460. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/cipher/cipher.c +11 -3
  461. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/cipher/e_aes.c +25 -2
  462. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/digest/digests.c +10 -2
  463. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/digest/md32_common.h +4 -43
  464. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/ec.c +4 -0
  465. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/ec_key.c +0 -1
  466. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/internal.h +0 -4
  467. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/ecdsa/ecdsa.c +104 -93
  468. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/ecdsa/internal.h +39 -0
  469. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/md4/md4.c +43 -46
  470. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/md5/md5.c +43 -46
  471. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/modes/cbc.c +33 -22
  472. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/modes/cfb.c +9 -8
  473. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/modes/ctr.c +9 -8
  474. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/modes/gcm.c +17 -13
  475. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/modes/internal.h +1 -22
  476. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/modes/ofb.c +2 -1
  477. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/rand/urandom.c +26 -7
  478. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/self_check/fips.c +79 -0
  479. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/self_check/self_check.c +14 -9
  480. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/sha/sha1.c +45 -48
  481. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/sha/sha256.c +38 -43
  482. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/sha/sha512.c +37 -45
  483. data/third_party/boringssl-with-bazel/src/crypto/hpke/hpke.c +103 -42
  484. data/third_party/boringssl-with-bazel/src/crypto/hpke/internal.h +58 -37
  485. data/third_party/boringssl-with-bazel/src/crypto/internal.h +65 -0
  486. data/third_party/boringssl-with-bazel/src/crypto/mem.c +14 -0
  487. data/third_party/boringssl-with-bazel/src/crypto/obj/obj.c +3 -3
  488. data/third_party/boringssl-with-bazel/src/crypto/pkcs7/pkcs7_x509.c +1 -1
  489. data/third_party/boringssl-with-bazel/src/crypto/pkcs8/pkcs8_x509.c +95 -48
  490. data/third_party/boringssl-with-bazel/src/crypto/rand_extra/rand_extra.c +1 -1
  491. data/third_party/boringssl-with-bazel/src/crypto/thread_pthread.c +0 -28
  492. data/third_party/boringssl-with-bazel/src/crypto/x509/internal.h +19 -0
  493. data/third_party/boringssl-with-bazel/src/crypto/x509/t_req.c +2 -0
  494. data/third_party/boringssl-with-bazel/src/crypto/x509/x509_att.c +19 -25
  495. data/third_party/boringssl-with-bazel/src/crypto/x509/x509_cmp.c +3 -2
  496. data/third_party/boringssl-with-bazel/src/crypto/x509/x509_req.c +39 -89
  497. data/third_party/boringssl-with-bazel/src/crypto/x509/x509_set.c +9 -16
  498. data/third_party/boringssl-with-bazel/src/crypto/x509/x509_vfy.c +1 -1
  499. data/third_party/boringssl-with-bazel/src/crypto/x509/x_algor.c +21 -17
  500. data/third_party/boringssl-with-bazel/src/crypto/x509/x_attrib.c +7 -25
  501. data/third_party/boringssl-with-bazel/src/crypto/x509/x_crl.c +5 -0
  502. data/third_party/boringssl-with-bazel/src/crypto/x509/x_pubkey.c +25 -22
  503. data/third_party/boringssl-with-bazel/src/crypto/x509/x_val.c +2 -0
  504. data/third_party/boringssl-with-bazel/src/crypto/x509v3/v3_cpols.c +2 -4
  505. data/third_party/boringssl-with-bazel/src/crypto/x509v3/v3_purp.c +1 -1
  506. data/third_party/boringssl-with-bazel/src/crypto/x509v3/v3_skey.c +1 -0
  507. data/third_party/boringssl-with-bazel/src/include/openssl/aead.h +0 -3
  508. data/third_party/boringssl-with-bazel/src/include/openssl/asn1.h +120 -41
  509. data/third_party/boringssl-with-bazel/src/include/openssl/base.h +9 -0
  510. data/third_party/boringssl-with-bazel/src/include/openssl/cipher.h +0 -8
  511. data/third_party/boringssl-with-bazel/src/include/openssl/crypto.h +24 -4
  512. data/third_party/boringssl-with-bazel/src/include/openssl/ec.h +5 -2
  513. data/third_party/boringssl-with-bazel/src/include/openssl/ecdsa.h +19 -0
  514. data/third_party/boringssl-with-bazel/src/include/openssl/err.h +3 -2
  515. data/third_party/boringssl-with-bazel/src/include/openssl/evp.h +1 -38
  516. data/third_party/boringssl-with-bazel/src/{crypto/x509/x509_r2x.c → include/openssl/evp_errors.h} +41 -58
  517. data/third_party/boringssl-with-bazel/src/include/openssl/obj.h +24 -5
  518. data/third_party/boringssl-with-bazel/src/include/openssl/pkcs7.h +2 -0
  519. data/third_party/boringssl-with-bazel/src/include/openssl/pkcs8.h +9 -1
  520. data/third_party/boringssl-with-bazel/src/include/openssl/rand.h +2 -2
  521. data/third_party/boringssl-with-bazel/src/include/openssl/ssl.h +185 -17
  522. data/third_party/boringssl-with-bazel/src/include/openssl/tls1.h +1 -0
  523. data/third_party/boringssl-with-bazel/src/include/openssl/x509.h +416 -121
  524. data/third_party/boringssl-with-bazel/src/include/openssl/x509v3.h +2 -0
  525. data/third_party/boringssl-with-bazel/src/ssl/d1_both.cc +5 -0
  526. data/third_party/boringssl-with-bazel/src/ssl/encrypted_client_hello.cc +444 -0
  527. data/third_party/boringssl-with-bazel/src/ssl/handoff.cc +244 -1
  528. data/third_party/boringssl-with-bazel/src/ssl/handshake.cc +43 -12
  529. data/third_party/boringssl-with-bazel/src/ssl/handshake_server.cc +149 -8
  530. data/third_party/boringssl-with-bazel/src/ssl/internal.h +220 -46
  531. data/third_party/boringssl-with-bazel/src/ssl/s3_both.cc +7 -1
  532. data/third_party/boringssl-with-bazel/src/ssl/ssl_cert.cc +4 -6
  533. data/third_party/boringssl-with-bazel/src/ssl/ssl_key_share.cc +23 -26
  534. data/third_party/boringssl-with-bazel/src/ssl/ssl_lib.cc +74 -15
  535. data/third_party/boringssl-with-bazel/src/ssl/t1_lib.cc +98 -64
  536. data/third_party/boringssl-with-bazel/src/ssl/tls13_both.cc +34 -4
  537. data/third_party/boringssl-with-bazel/src/ssl/tls13_server.cc +205 -100
  538. data/third_party/boringssl-with-bazel/src/ssl/tls_method.cc +4 -2
  539. metadata +68 -45
  540. data/src/core/lib/iomgr/poller/eventmanager_libuv.cc +0 -88
  541. data/src/core/lib/iomgr/poller/eventmanager_libuv.h +0 -88
  542. data/third_party/abseil-cpp/absl/base/internal/bits.h +0 -219
  543. data/third_party/abseil-cpp/absl/synchronization/internal/mutex_nonprod.inc +0 -249
  544. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/is_fips.c +0 -29
@@ -0,0 +1,146 @@
1
+ // Copyright 2020 The Abseil Authors
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // https://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ #ifndef ABSL_STRINGS_INTERNAL_CORD_REP_FLAT_H_
16
+ #define ABSL_STRINGS_INTERNAL_CORD_REP_FLAT_H_
17
+
18
+ #include <cassert>
19
+ #include <cstddef>
20
+ #include <cstdint>
21
+ #include <memory>
22
+
23
+ #include "absl/strings/internal/cord_internal.h"
24
+
25
+ namespace absl {
26
+ ABSL_NAMESPACE_BEGIN
27
+ namespace cord_internal {
28
+
29
+ // Note: all constants below are never ODR used and internal to cord, we define
30
+ // these as static constexpr to avoid 'in struct' definition and usage clutter.
31
+
32
+ // Largest and smallest flat node lengths we are willing to allocate
33
+ // Flat allocation size is stored in tag, which currently can encode sizes up
34
+ // to 4K, encoded as multiple of either 8 or 32 bytes.
35
+ // If we allow for larger sizes, we need to change this to 8/64, 16/128, etc.
36
+ // kMinFlatSize is bounded by tag needing to be at least FLAT * 8 bytes, and
37
+ // ideally a 'nice' size aligning with allocation and cacheline sizes like 32.
38
+ // kMaxFlatSize is bounded by the size resulting in a computed tag no greater
39
+ // than MAX_FLAT_TAG. MAX_FLAT_TAG provides for additional 'high' tag values.
40
+ static constexpr size_t kFlatOverhead = offsetof(CordRep, storage);
41
+ static constexpr size_t kMinFlatSize = 32;
42
+ static constexpr size_t kMaxFlatSize = 4096;
43
+ static constexpr size_t kMaxFlatLength = kMaxFlatSize - kFlatOverhead;
44
+ static constexpr size_t kMinFlatLength = kMinFlatSize - kFlatOverhead;
45
+
46
+ constexpr uint8_t AllocatedSizeToTagUnchecked(size_t size) {
47
+ return static_cast<uint8_t>((size <= 1024) ? size / 8
48
+ : 128 + size / 32 - 1024 / 32);
49
+ }
50
+
51
+ static_assert(kMinFlatSize / 8 >= FLAT, "");
52
+ static_assert(AllocatedSizeToTagUnchecked(kMaxFlatSize) <= MAX_FLAT_TAG, "");
53
+
54
+ // Helper functions for rounded div, and rounding to exact sizes.
55
+ constexpr size_t DivUp(size_t n, size_t m) { return (n + m - 1) / m; }
56
+ constexpr size_t RoundUp(size_t n, size_t m) { return DivUp(n, m) * m; }
57
+
58
+ // Returns the size to the nearest equal or larger value that can be
59
+ // expressed exactly as a tag value.
60
+ inline size_t RoundUpForTag(size_t size) {
61
+ return RoundUp(size, (size <= 1024) ? 8 : 32);
62
+ }
63
+
64
+ // Converts the allocated size to a tag, rounding down if the size
65
+ // does not exactly match a 'tag expressible' size value. The result is
66
+ // undefined if the size exceeds the maximum size that can be encoded in
67
+ // a tag, i.e., if size is larger than TagToAllocatedSize(<max tag>).
68
+ inline uint8_t AllocatedSizeToTag(size_t size) {
69
+ const uint8_t tag = AllocatedSizeToTagUnchecked(size);
70
+ assert(tag <= MAX_FLAT_TAG);
71
+ return tag;
72
+ }
73
+
74
+ // Converts the provided tag to the corresponding allocated size
75
+ constexpr size_t TagToAllocatedSize(uint8_t tag) {
76
+ return (tag <= 128) ? (tag * 8) : (1024 + (tag - 128) * 32);
77
+ }
78
+
79
+ // Converts the provided tag to the corresponding available data length
80
+ constexpr size_t TagToLength(uint8_t tag) {
81
+ return TagToAllocatedSize(tag) - kFlatOverhead;
82
+ }
83
+
84
+ // Enforce that kMaxFlatSize maps to a well-known exact tag value.
85
+ static_assert(TagToAllocatedSize(224) == kMaxFlatSize, "Bad tag logic");
86
+
87
+ struct CordRepFlat : public CordRep {
88
+ // Creates a new flat node.
89
+ static CordRepFlat* New(size_t len) {
90
+ if (len <= kMinFlatLength) {
91
+ len = kMinFlatLength;
92
+ } else if (len > kMaxFlatLength) {
93
+ len = kMaxFlatLength;
94
+ }
95
+
96
+ // Round size up so it matches a size we can exactly express in a tag.
97
+ const size_t size = RoundUpForTag(len + kFlatOverhead);
98
+ void* const raw_rep = ::operator new(size);
99
+ CordRepFlat* rep = new (raw_rep) CordRepFlat();
100
+ rep->tag = AllocatedSizeToTag(size);
101
+ return rep;
102
+ }
103
+
104
+ // Deletes a CordRepFlat instance created previously through a call to New().
105
+ // Flat CordReps are allocated and constructed with raw ::operator new and
106
+ // placement new, and must be destructed and deallocated accordingly.
107
+ static void Delete(CordRep*rep) {
108
+ assert(rep->tag >= FLAT && rep->tag <= MAX_FLAT_TAG);
109
+
110
+ #if defined(__cpp_sized_deallocation)
111
+ size_t size = TagToAllocatedSize(rep->tag);
112
+ rep->~CordRep();
113
+ ::operator delete(rep, size);
114
+ #else
115
+ rep->~CordRep();
116
+ ::operator delete(rep);
117
+ #endif
118
+ }
119
+
120
+ // Returns a pointer to the data inside this flat rep.
121
+ char* Data() { return storage; }
122
+ const char* Data() const { return storage; }
123
+
124
+ // Returns the maximum capacity (payload size) of this instance.
125
+ size_t Capacity() const { return TagToLength(tag); }
126
+
127
+ // Returns the allocated size (payload + overhead) of this instance.
128
+ size_t AllocatedSize() const { return TagToAllocatedSize(tag); }
129
+ };
130
+
131
+ // Now that CordRepFlat is defined, we can define CordRep's helper casts:
132
+ inline CordRepFlat* CordRep::flat() {
133
+ assert(tag >= FLAT && tag <= MAX_FLAT_TAG);
134
+ return reinterpret_cast<CordRepFlat*>(this);
135
+ }
136
+
137
+ inline const CordRepFlat* CordRep::flat() const {
138
+ assert(tag >= FLAT && tag <= MAX_FLAT_TAG);
139
+ return reinterpret_cast<const CordRepFlat*>(this);
140
+ }
141
+
142
+ } // namespace cord_internal
143
+ ABSL_NAMESPACE_END
144
+ } // namespace absl
145
+
146
+ #endif // ABSL_STRINGS_INTERNAL_CORD_REP_FLAT_H_
@@ -0,0 +1,897 @@
1
+ // Copyright 2020 The Abseil Authors
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // https://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+ #include "absl/strings/internal/cord_rep_ring.h"
15
+
16
+ #include <cassert>
17
+ #include <cstddef>
18
+ #include <cstdint>
19
+ #include <iostream>
20
+ #include <limits>
21
+ #include <memory>
22
+ #include <string>
23
+
24
+ #include "absl/base/internal/raw_logging.h"
25
+ #include "absl/base/internal/throw_delegate.h"
26
+ #include "absl/base/macros.h"
27
+ #include "absl/container/inlined_vector.h"
28
+ #include "absl/strings/internal/cord_internal.h"
29
+ #include "absl/strings/internal/cord_rep_flat.h"
30
+
31
+ namespace absl {
32
+ ABSL_NAMESPACE_BEGIN
33
+ namespace cord_internal {
34
+
35
+ // See https://bugs.llvm.org/show_bug.cgi?id=48477
36
+ #ifdef __clang__
37
+ #pragma clang diagnostic push
38
+ #pragma clang diagnostic ignored "-Wshadow"
39
+ #if __has_warning("-Wshadow-field")
40
+ #pragma clang diagnostic ignored "-Wshadow-field"
41
+ #endif
42
+ #endif
43
+
44
+ namespace {
45
+
46
+ using index_type = CordRepRing::index_type;
47
+
48
+ enum class Direction { kForward, kReversed };
49
+
50
+ inline bool IsFlatOrExternal(CordRep* rep) {
51
+ return rep->tag >= FLAT || rep->tag == EXTERNAL;
52
+ }
53
+
54
+ // Verifies that n + extra <= kMaxCapacity: throws std::length_error otherwise.
55
+ inline void CheckCapacity(size_t n, size_t extra) {
56
+ if (ABSL_PREDICT_FALSE(extra > CordRepRing::kMaxCapacity - n)) {
57
+ base_internal::ThrowStdLengthError("Maximum capacity exceeded");
58
+ }
59
+ }
60
+
61
+ // Removes a reference from `rep` only.
62
+ // Asserts that the refcount after decrement is not zero.
63
+ inline bool UnrefNeverOne(CordRep* rep) {
64
+ bool result = rep->refcount.Decrement();
65
+ assert(result);
66
+ return result;
67
+ }
68
+
69
+ // Creates a flat from the provided string data, allocating up to `extra`
70
+ // capacity in the returned flat depending on kMaxFlatLength limitations.
71
+ // Requires `len` to be less or equal to `kMaxFlatLength`
72
+ CordRepFlat* CreateFlat(const char* s, size_t n, size_t extra = 0) { // NOLINT
73
+ assert(n <= kMaxFlatLength);
74
+ auto* rep = CordRepFlat::New(n + extra);
75
+ rep->length = n;
76
+ memcpy(rep->Data(), s, n);
77
+ return rep;
78
+ }
79
+
80
+ // Unrefs the provided `substring`, and returns `substring->child`
81
+ // Adds or assumes a reference on `substring->child`
82
+ CordRep* ClipSubstring(CordRepSubstring* substring) {
83
+ CordRep* child = substring->child;
84
+ if (substring->refcount.IsOne()) {
85
+ delete substring;
86
+ } else {
87
+ CordRep::Ref(child);
88
+ if (ABSL_PREDICT_FALSE(!substring->refcount.Decrement())) {
89
+ UnrefNeverOne(child);
90
+ delete substring;
91
+ }
92
+ }
93
+ return child;
94
+ }
95
+
96
+ // Unrefs the provided `concat`, and returns `{concat->left, concat->right}`
97
+ // Adds or assumes a reference on `concat->left` and `concat->right`.
98
+ std::pair<CordRep*, CordRep*> ClipConcat(CordRepConcat* concat) {
99
+ auto result = std::make_pair(concat->left, concat->right);
100
+ if (concat->refcount.IsOne()) {
101
+ delete concat;
102
+ } else {
103
+ CordRep::Ref(result.first);
104
+ CordRep::Ref(result.second);
105
+ if (ABSL_PREDICT_FALSE(!concat->refcount.Decrement())) {
106
+ UnrefNeverOne(result.first);
107
+ UnrefNeverOne(result.second);
108
+ delete concat;
109
+ }
110
+ }
111
+ return result;
112
+ }
113
+
114
+ // Unrefs the entries in `[head, tail)`.
115
+ // Requires all entries to be a FLAT or EXTERNAL node.
116
+ void UnrefEntries(const CordRepRing* rep, index_type head, index_type tail) {
117
+ rep->ForEach(head, tail, [rep](index_type ix) {
118
+ CordRep* child = rep->entry_child(ix);
119
+ if (!child->refcount.Decrement()) {
120
+ if (child->tag >= FLAT) {
121
+ CordRepFlat::Delete(child->flat());
122
+ } else {
123
+ CordRepExternal::Delete(child->external());
124
+ }
125
+ }
126
+ });
127
+ }
128
+
129
+ template <typename F>
130
+ void Consume(Direction direction, CordRep* rep, F&& fn) {
131
+ size_t offset = 0;
132
+ size_t length = rep->length;
133
+ struct Entry {
134
+ CordRep* rep;
135
+ size_t offset;
136
+ size_t length;
137
+ };
138
+ absl::InlinedVector<Entry, 40> stack;
139
+
140
+ for (;;) {
141
+ if (rep->tag >= FLAT || rep->tag == EXTERNAL || rep->tag == RING) {
142
+ fn(rep, offset, length);
143
+ if (stack.empty()) return;
144
+
145
+ rep = stack.back().rep;
146
+ offset = stack.back().offset;
147
+ length = stack.back().length;
148
+ stack.pop_back();
149
+ } else if (rep->tag == SUBSTRING) {
150
+ offset += rep->substring()->start;
151
+ rep = ClipSubstring(rep->substring());
152
+ } else if (rep->tag == CONCAT) {
153
+ auto res = ClipConcat(rep->concat());
154
+ CordRep* left = res.first;
155
+ CordRep* right = res.second;
156
+
157
+ if (left->length <= offset) {
158
+ // Don't need left node
159
+ offset -= left->length;
160
+ CordRep::Unref(left);
161
+ rep = right;
162
+ continue;
163
+ }
164
+
165
+ size_t length_left = left->length - offset;
166
+ if (length_left >= length) {
167
+ // Don't need right node
168
+ CordRep::Unref(right);
169
+ rep = left;
170
+ continue;
171
+ }
172
+
173
+ // Need both nodes
174
+ size_t length_right = length - length_left;
175
+ if (direction == Direction::kReversed) {
176
+ stack.push_back({left, offset, length_left});
177
+ rep = right;
178
+ offset = 0;
179
+ length = length_right;
180
+ } else {
181
+ stack.push_back({right, 0, length_right});
182
+ rep = left;
183
+ length = length_left;
184
+ }
185
+ } else {
186
+ assert("Valid tag" == nullptr);
187
+ return;
188
+ }
189
+ }
190
+ }
191
+
192
+ template <typename F>
193
+ void Consume(CordRep* rep, F&& fn) {
194
+ return Consume(Direction::kForward, rep, std::forward<F>(fn));
195
+ }
196
+
197
+ template <typename F>
198
+ void RConsume(CordRep* rep, F&& fn) {
199
+ return Consume(Direction::kReversed, rep, std::forward<F>(fn));
200
+ }
201
+
202
+ } // namespace
203
+
204
+ std::ostream& operator<<(std::ostream& s, const CordRepRing& rep) {
205
+ // Note: 'pos' values are defined as size_t (for overflow reasons), but that
206
+ // prints really awkward for small prepended values such as -5. ssize_t is not
207
+ // portable (POSIX), so we use ptrdiff_t instead to cast to signed values.
208
+ s << " CordRepRing(" << &rep << ", length = " << rep.length
209
+ << ", head = " << rep.head_ << ", tail = " << rep.tail_
210
+ << ", cap = " << rep.capacity_ << ", rc = " << rep.refcount.Get()
211
+ << ", begin_pos_ = " << static_cast<ptrdiff_t>(rep.begin_pos_) << ") {\n";
212
+ CordRepRing::index_type head = rep.head();
213
+ do {
214
+ CordRep* child = rep.entry_child(head);
215
+ s << " entry[" << head << "] length = " << rep.entry_length(head)
216
+ << ", child " << child << ", clen = " << child->length
217
+ << ", tag = " << static_cast<int>(child->tag)
218
+ << ", rc = " << child->refcount.Get()
219
+ << ", offset = " << rep.entry_data_offset(head)
220
+ << ", end_pos = " << static_cast<ptrdiff_t>(rep.entry_end_pos(head))
221
+ << "\n";
222
+ head = rep.advance(head);
223
+ } while (head != rep.tail());
224
+ return s << "}\n";
225
+ }
226
+
227
+ void CordRepRing::AddDataOffset(index_type index, size_t n) {
228
+ entry_data_offset()[index] += static_cast<offset_type>(n);
229
+ }
230
+
231
+ void CordRepRing::SubLength(index_type index, size_t n) {
232
+ entry_end_pos()[index] -= n;
233
+ }
234
+
235
+ class CordRepRing::Filler {
236
+ public:
237
+ Filler(CordRepRing* rep, index_type pos) : rep_(rep), head_(pos), pos_(pos) {}
238
+
239
+ index_type head() const { return head_; }
240
+ index_type pos() const { return pos_; }
241
+
242
+ void Add(CordRep* child, size_t offset, pos_type end_pos) {
243
+ rep_->entry_end_pos()[pos_] = end_pos;
244
+ rep_->entry_child()[pos_] = child;
245
+ rep_->entry_data_offset()[pos_] = static_cast<offset_type>(offset);
246
+ pos_ = rep_->advance(pos_);
247
+ }
248
+
249
+ private:
250
+ CordRepRing* rep_;
251
+ index_type head_;
252
+ index_type pos_;
253
+ };
254
+
255
+ constexpr size_t CordRepRing::kMaxCapacity; // NOLINT: needed for c++11
256
+
257
+ bool CordRepRing::IsValid(std::ostream& output) const {
258
+ if (capacity_ == 0) {
259
+ output << "capacity == 0";
260
+ return false;
261
+ }
262
+
263
+ if (head_ >= capacity_ || tail_ >= capacity_) {
264
+ output << "head " << head_ << " and/or tail " << tail_ << "exceed capacity "
265
+ << capacity_;
266
+ return false;
267
+ }
268
+
269
+ const index_type back = retreat(tail_);
270
+ size_t pos_length = Distance(begin_pos_, entry_end_pos(back));
271
+ if (pos_length != length) {
272
+ output << "length " << length << " does not match positional length "
273
+ << pos_length << " from begin_pos " << begin_pos_ << " and entry["
274
+ << back << "].end_pos " << entry_end_pos(back);
275
+ return false;
276
+ }
277
+
278
+ index_type head = head_;
279
+ pos_type begin_pos = begin_pos_;
280
+ do {
281
+ pos_type end_pos = entry_end_pos(head);
282
+ size_t entry_length = Distance(begin_pos, end_pos);
283
+ if (entry_length == 0) {
284
+ output << "entry[" << head << "] has an invalid length " << entry_length
285
+ << " from begin_pos " << begin_pos << " and end_pos " << end_pos;
286
+ return false;
287
+ }
288
+
289
+ CordRep* child = entry_child(head);
290
+ if (child == nullptr) {
291
+ output << "entry[" << head << "].child == nullptr";
292
+ return false;
293
+ }
294
+ if (child->tag < FLAT && child->tag != EXTERNAL) {
295
+ output << "entry[" << head << "].child has an invalid tag "
296
+ << static_cast<int>(child->tag);
297
+ return false;
298
+ }
299
+
300
+ size_t offset = entry_data_offset(head);
301
+ if (offset >= child->length || entry_length > child->length - offset) {
302
+ output << "entry[" << head << "] has offset " << offset
303
+ << " and entry length " << entry_length
304
+ << " which are outside of the childs length of " << child->length;
305
+ return false;
306
+ }
307
+
308
+ begin_pos = end_pos;
309
+ head = advance(head);
310
+ } while (head != tail_);
311
+
312
+ return true;
313
+ }
314
+
315
+ #ifdef EXTRA_CORD_RING_VALIDATION
316
+ CordRepRing* CordRepRing::Validate(CordRepRing* rep, const char* file,
317
+ int line) {
318
+ if (!rep->IsValid(std::cerr)) {
319
+ std::cerr << "\nERROR: CordRepRing corrupted";
320
+ if (line) std::cerr << " at line " << line;
321
+ if (file) std::cerr << " in file " << file;
322
+ std::cerr << "\nContent = " << *rep;
323
+ abort();
324
+ }
325
+ return rep;
326
+ }
327
+ #endif // EXTRA_CORD_RING_VALIDATION
328
+
329
+ CordRepRing* CordRepRing::New(size_t capacity, size_t extra) {
330
+ CheckCapacity(capacity, extra);
331
+
332
+ size_t size = AllocSize(capacity += extra);
333
+ void* mem = ::operator new(size);
334
+ auto* rep = new (mem) CordRepRing(static_cast<index_type>(capacity));
335
+ rep->tag = RING;
336
+ rep->capacity_ = static_cast<index_type>(capacity);
337
+ rep->begin_pos_ = 0;
338
+ return rep;
339
+ }
340
+
341
+ void CordRepRing::SetCapacityForTesting(size_t capacity) {
342
+ // Adjust for the changed layout
343
+ assert(capacity <= capacity_);
344
+ assert(head() == 0 || head() < tail());
345
+ memmove(Layout::Partial(capacity).Pointer<1>(data_) + head(),
346
+ Layout::Partial(capacity_).Pointer<1>(data_) + head(),
347
+ entries() * sizeof(Layout::ElementType<1>));
348
+ memmove(Layout::Partial(capacity, capacity).Pointer<2>(data_) + head(),
349
+ Layout::Partial(capacity_, capacity_).Pointer<2>(data_) + head(),
350
+ entries() * sizeof(Layout::ElementType<2>));
351
+ capacity_ = static_cast<index_type>(capacity);
352
+ }
353
+
354
+ void CordRepRing::Delete(CordRepRing* rep) {
355
+ assert(rep != nullptr && rep->tag == RING);
356
+ #if defined(__cpp_sized_deallocation)
357
+ size_t size = AllocSize(rep->capacity_);
358
+ rep->~CordRepRing();
359
+ ::operator delete(rep, size);
360
+ #else
361
+ rep->~CordRepRing();
362
+ ::operator delete(rep);
363
+ #endif
364
+ }
365
+
366
+ void CordRepRing::Destroy(CordRepRing* rep) {
367
+ UnrefEntries(rep, rep->head(), rep->tail());
368
+ Delete(rep);
369
+ }
370
+
371
+ template <bool ref>
372
+ void CordRepRing::Fill(const CordRepRing* src, index_type head,
373
+ index_type tail) {
374
+ this->length = src->length;
375
+ head_ = 0;
376
+ tail_ = advance(0, src->entries(head, tail));
377
+ begin_pos_ = src->begin_pos_;
378
+
379
+ // TODO(mvels): there may be opportunities here for large buffers.
380
+ auto* dst_pos = entry_end_pos();
381
+ auto* dst_child = entry_child();
382
+ auto* dst_offset = entry_data_offset();
383
+ src->ForEach(head, tail, [&](index_type index) {
384
+ *dst_pos++ = src->entry_end_pos(index);
385
+ CordRep* child = src->entry_child(index);
386
+ *dst_child++ = ref ? CordRep::Ref(child) : child;
387
+ *dst_offset++ = src->entry_data_offset(index);
388
+ });
389
+ }
390
+
391
+ CordRepRing* CordRepRing::Copy(CordRepRing* rep, index_type head,
392
+ index_type tail, size_t extra) {
393
+ CordRepRing* newrep = CordRepRing::New(rep->entries(head, tail), extra);
394
+ newrep->Fill<true>(rep, head, tail);
395
+ CordRep::Unref(rep);
396
+ return newrep;
397
+ }
398
+
399
+ CordRepRing* CordRepRing::Mutable(CordRepRing* rep, size_t extra) {
400
+ // Get current number of entries, and check for max capacity.
401
+ size_t entries = rep->entries();
402
+
403
+ size_t min_extra = (std::max)(extra, rep->capacity() * 2 - entries);
404
+ if (!rep->refcount.IsOne()) {
405
+ return Copy(rep, rep->head(), rep->tail(), min_extra);
406
+ } else if (entries + extra > rep->capacity()) {
407
+ CordRepRing* newrep = CordRepRing::New(entries, min_extra);
408
+ newrep->Fill<false>(rep, rep->head(), rep->tail());
409
+ CordRepRing::Delete(rep);
410
+ return newrep;
411
+ } else {
412
+ return rep;
413
+ }
414
+ }
415
+
416
+ Span<char> CordRepRing::GetAppendBuffer(size_t size) {
417
+ assert(refcount.IsOne());
418
+ index_type back = retreat(tail_);
419
+ CordRep* child = entry_child(back);
420
+ if (child->tag >= FLAT && child->refcount.IsOne()) {
421
+ size_t capacity = child->flat()->Capacity();
422
+ pos_type end_pos = entry_end_pos(back);
423
+ size_t data_offset = entry_data_offset(back);
424
+ size_t entry_length = Distance(entry_begin_pos(back), end_pos);
425
+ size_t used = data_offset + entry_length;
426
+ if (size_t n = (std::min)(capacity - used, size)) {
427
+ child->length = data_offset + entry_length + n;
428
+ entry_end_pos()[back] = end_pos + n;
429
+ this->length += n;
430
+ return {child->flat()->Data() + used, n};
431
+ }
432
+ }
433
+ return {nullptr, 0};
434
+ }
435
+
436
+ Span<char> CordRepRing::GetPrependBuffer(size_t size) {
437
+ assert(refcount.IsOne());
438
+ CordRep* child = entry_child(head_);
439
+ size_t data_offset = entry_data_offset(head_);
440
+ if (data_offset && child->refcount.IsOne() && child->tag >= FLAT) {
441
+ size_t n = (std::min)(data_offset, size);
442
+ this->length += n;
443
+ begin_pos_ -= n;
444
+ data_offset -= n;
445
+ entry_data_offset()[head_] = static_cast<offset_type>(data_offset);
446
+ return {child->flat()->Data() + data_offset, n};
447
+ }
448
+ return {nullptr, 0};
449
+ }
450
+
451
+ CordRepRing* CordRepRing::CreateFromLeaf(CordRep* child, size_t offset,
452
+ size_t length, size_t extra) {
453
+ CordRepRing* rep = CordRepRing::New(1, extra);
454
+ rep->head_ = 0;
455
+ rep->tail_ = rep->advance(0);
456
+ rep->length = length;
457
+ rep->entry_end_pos()[0] = length;
458
+ rep->entry_child()[0] = child;
459
+ rep->entry_data_offset()[0] = static_cast<offset_type>(offset);
460
+ return Validate(rep);
461
+ }
462
+
463
+ CordRepRing* CordRepRing::CreateSlow(CordRep* child, size_t extra) {
464
+ CordRepRing* rep = nullptr;
465
+ Consume(child, [&](CordRep* child, size_t offset, size_t length) {
466
+ if (IsFlatOrExternal(child)) {
467
+ rep = rep ? AppendLeaf(rep, child, offset, length)
468
+ : CreateFromLeaf(child, offset, length, extra);
469
+ } else if (rep) {
470
+ rep = AddRing<AddMode::kAppend>(rep, child->ring(), offset, length);
471
+ } else if (offset == 0 && child->length == length) {
472
+ rep = Mutable(child->ring(), extra);
473
+ } else {
474
+ rep = SubRing(child->ring(), offset, length, extra);
475
+ }
476
+ });
477
+ return Validate(rep, nullptr, __LINE__);
478
+ }
479
+
480
+ CordRepRing* CordRepRing::Create(CordRep* child, size_t extra) {
481
+ size_t length = child->length;
482
+ if (IsFlatOrExternal(child)) {
483
+ return CreateFromLeaf(child, 0, length, extra);
484
+ }
485
+ if (child->tag == RING) {
486
+ return Mutable(child->ring(), extra);
487
+ }
488
+ return CreateSlow(child, extra);
489
+ }
490
+
491
+ template <CordRepRing::AddMode mode>
492
+ CordRepRing* CordRepRing::AddRing(CordRepRing* rep, CordRepRing* ring,
493
+ size_t offset, size_t length) {
494
+ assert(offset < ring->length);
495
+ constexpr bool append = mode == AddMode::kAppend;
496
+ Position head = ring->Find(offset);
497
+ Position tail = ring->FindTail(head.index, offset + length);
498
+ const index_type entries = ring->entries(head.index, tail.index);
499
+
500
+ rep = Mutable(rep, entries);
501
+
502
+ // The delta for making ring[head].end_pos into 'len - offset'
503
+ const pos_type delta_length =
504
+ (append ? rep->begin_pos_ + rep->length : rep->begin_pos_ - length) -
505
+ ring->entry_begin_pos(head.index) - head.offset;
506
+
507
+ // Start filling at `tail`, or `entries` before `head`
508
+ Filler filler(rep, append ? rep->tail_ : rep->retreat(rep->head_, entries));
509
+
510
+ if (ring->refcount.IsOne()) {
511
+ // Copy entries from source stealing the ref and adjusting the end position.
512
+ // Commit the filler as this is no-op.
513
+ ring->ForEach(head.index, tail.index, [&](index_type ix) {
514
+ filler.Add(ring->entry_child(ix), ring->entry_data_offset(ix),
515
+ ring->entry_end_pos(ix) + delta_length);
516
+ });
517
+
518
+ // Unref entries we did not copy over, and delete source.
519
+ if (head.index != ring->head_) UnrefEntries(ring, ring->head_, head.index);
520
+ if (tail.index != ring->tail_) UnrefEntries(ring, tail.index, ring->tail_);
521
+ CordRepRing::Delete(ring);
522
+ } else {
523
+ ring->ForEach(head.index, tail.index, [&](index_type ix) {
524
+ CordRep* child = ring->entry_child(ix);
525
+ filler.Add(child, ring->entry_data_offset(ix),
526
+ ring->entry_end_pos(ix) + delta_length);
527
+ CordRep::Ref(child);
528
+ });
529
+ CordRepRing::Unref(ring);
530
+ }
531
+
532
+ if (head.offset) {
533
+ // Increase offset of first 'source' entry appended or prepended.
534
+ // This is always the entry in `filler.head()`
535
+ rep->AddDataOffset(filler.head(), head.offset);
536
+ }
537
+
538
+ if (tail.offset) {
539
+ // Reduce length of last 'source' entry appended or prepended.
540
+ // This is always the entry tailed by `filler.pos()`
541
+ rep->SubLength(rep->retreat(filler.pos()), tail.offset);
542
+ }
543
+
544
+ // Commit changes
545
+ rep->length += length;
546
+ if (append) {
547
+ rep->tail_ = filler.pos();
548
+ } else {
549
+ rep->head_ = filler.head();
550
+ rep->begin_pos_ -= length;
551
+ }
552
+
553
+ return Validate(rep);
554
+ }
555
+
556
+ CordRepRing* CordRepRing::AppendSlow(CordRepRing* rep, CordRep* child) {
557
+ Consume(child, [&rep](CordRep* child, size_t offset, size_t length) {
558
+ if (child->tag == RING) {
559
+ rep = AddRing<AddMode::kAppend>(rep, child->ring(), offset, length);
560
+ } else {
561
+ rep = AppendLeaf(rep, child, offset, length);
562
+ }
563
+ });
564
+ return rep;
565
+ }
566
+
567
+ CordRepRing* CordRepRing::AppendLeaf(CordRepRing* rep, CordRep* child,
568
+ size_t offset, size_t length) {
569
+ rep = Mutable(rep, 1);
570
+ index_type back = rep->tail_;
571
+ const pos_type begin_pos = rep->begin_pos_ + rep->length;
572
+ rep->tail_ = rep->advance(rep->tail_);
573
+ rep->length += length;
574
+ rep->entry_end_pos()[back] = begin_pos + length;
575
+ rep->entry_child()[back] = child;
576
+ rep->entry_data_offset()[back] = static_cast<offset_type>(offset);
577
+ return Validate(rep, nullptr, __LINE__);
578
+ }
579
+
580
+ CordRepRing* CordRepRing::Append(CordRepRing* rep, CordRep* child) {
581
+ size_t length = child->length;
582
+ if (IsFlatOrExternal(child)) {
583
+ return AppendLeaf(rep, child, 0, length);
584
+ }
585
+ if (child->tag == RING) {
586
+ return AddRing<AddMode::kAppend>(rep, child->ring(), 0, length);
587
+ }
588
+ return AppendSlow(rep, child);
589
+ }
590
+
591
+ CordRepRing* CordRepRing::PrependSlow(CordRepRing* rep, CordRep* child) {
592
+ RConsume(child, [&](CordRep* child, size_t offset, size_t length) {
593
+ if (IsFlatOrExternal(child)) {
594
+ rep = PrependLeaf(rep, child, offset, length);
595
+ } else {
596
+ rep = AddRing<AddMode::kPrepend>(rep, child->ring(), offset, length);
597
+ }
598
+ });
599
+ return Validate(rep);
600
+ }
601
+
602
+ CordRepRing* CordRepRing::PrependLeaf(CordRepRing* rep, CordRep* child,
603
+ size_t offset, size_t length) {
604
+ rep = Mutable(rep, 1);
605
+ index_type head = rep->retreat(rep->head_);
606
+ pos_type end_pos = rep->begin_pos_;
607
+ rep->head_ = head;
608
+ rep->length += length;
609
+ rep->begin_pos_ -= length;
610
+ rep->entry_end_pos()[head] = end_pos;
611
+ rep->entry_child()[head] = child;
612
+ rep->entry_data_offset()[head] = static_cast<offset_type>(offset);
613
+ return Validate(rep);
614
+ }
615
+
616
+ CordRepRing* CordRepRing::Prepend(CordRepRing* rep, CordRep* child) {
617
+ size_t length = child->length;
618
+ if (IsFlatOrExternal(child)) {
619
+ return PrependLeaf(rep, child, 0, length);
620
+ }
621
+ if (child->tag == RING) {
622
+ return AddRing<AddMode::kPrepend>(rep, child->ring(), 0, length);
623
+ }
624
+ return PrependSlow(rep, child);
625
+ }
626
+
627
+ CordRepRing* CordRepRing::Append(CordRepRing* rep, absl::string_view data,
628
+ size_t extra) {
629
+ if (rep->refcount.IsOne()) {
630
+ Span<char> avail = rep->GetAppendBuffer(data.length());
631
+ if (!avail.empty()) {
632
+ memcpy(avail.data(), data.data(), avail.length());
633
+ data.remove_prefix(avail.length());
634
+ }
635
+ }
636
+ if (data.empty()) return Validate(rep);
637
+
638
+ const size_t flats = (data.length() - 1) / kMaxFlatLength + 1;
639
+ rep = Mutable(rep, flats);
640
+
641
+ Filler filler(rep, rep->tail_);
642
+ pos_type pos = rep->begin_pos_ + rep->length;
643
+
644
+ while (data.length() >= kMaxFlatLength) {
645
+ auto* flat = CreateFlat(data.data(), kMaxFlatLength);
646
+ filler.Add(flat, 0, pos += kMaxFlatLength);
647
+ data.remove_prefix(kMaxFlatLength);
648
+ }
649
+
650
+ if (data.length()) {
651
+ auto* flat = CreateFlat(data.data(), data.length(), extra);
652
+ filler.Add(flat, 0, pos += data.length());
653
+ }
654
+
655
+ rep->length = pos - rep->begin_pos_;
656
+ rep->tail_ = filler.pos();
657
+
658
+ return Validate(rep);
659
+ }
660
+
661
+ CordRepRing* CordRepRing::Prepend(CordRepRing* rep, absl::string_view data,
662
+ size_t extra) {
663
+ if (rep->refcount.IsOne()) {
664
+ Span<char> avail = rep->GetPrependBuffer(data.length());
665
+ if (!avail.empty()) {
666
+ const char* tail = data.data() + data.length() - avail.length();
667
+ memcpy(avail.data(), tail, avail.length());
668
+ data.remove_suffix(avail.length());
669
+ }
670
+ }
671
+ if (data.empty()) return rep;
672
+
673
+ const size_t flats = (data.length() - 1) / kMaxFlatLength + 1;
674
+ rep = Mutable(rep, flats);
675
+ pos_type pos = rep->begin_pos_;
676
+ Filler filler(rep, rep->retreat(rep->head_, static_cast<index_type>(flats)));
677
+
678
+ size_t first_size = data.size() - (flats - 1) * kMaxFlatLength;
679
+ CordRepFlat* flat = CordRepFlat::New(first_size + extra);
680
+ flat->length = first_size + extra;
681
+ memcpy(flat->Data() + extra, data.data(), first_size);
682
+ data.remove_prefix(first_size);
683
+ filler.Add(flat, extra, pos);
684
+ pos -= first_size;
685
+
686
+ while (!data.empty()) {
687
+ assert(data.size() >= kMaxFlatLength);
688
+ flat = CreateFlat(data.data(), kMaxFlatLength);
689
+ filler.Add(flat, 0, pos);
690
+ pos -= kMaxFlatLength;
691
+ data.remove_prefix(kMaxFlatLength);
692
+ }
693
+
694
+ rep->head_ = filler.head();
695
+ rep->length += rep->begin_pos_ - pos;
696
+ rep->begin_pos_ = pos;
697
+
698
+ return Validate(rep);
699
+ }
700
+
701
+ // 32 entries is 32 * sizeof(pos_type) = 4 cache lines on x86
702
+ static constexpr index_type kBinarySearchThreshold = 32;
703
+ static constexpr index_type kBinarySearchEndCount = 8;
704
+
705
+ template <bool wrap>
706
+ CordRepRing::index_type CordRepRing::FindBinary(index_type head,
707
+ index_type tail,
708
+ size_t offset) const {
709
+ index_type count = tail + (wrap ? capacity_ : 0) - head;
710
+ do {
711
+ count = (count - 1) / 2;
712
+ assert(count < entries(head, tail_));
713
+ index_type mid = wrap ? advance(head, count) : head + count;
714
+ index_type after_mid = wrap ? advance(mid) : mid + 1;
715
+ bool larger = (offset >= entry_end_offset(mid));
716
+ head = larger ? after_mid : head;
717
+ tail = larger ? tail : mid;
718
+ assert(head != tail);
719
+ } while (ABSL_PREDICT_TRUE(count > kBinarySearchEndCount));
720
+ return head;
721
+ }
722
+
723
+ CordRepRing::Position CordRepRing::FindSlow(index_type head,
724
+ size_t offset) const {
725
+ index_type tail = tail_;
726
+
727
+ // Binary search until we are good for linear search
728
+ // Optimize for branchless / non wrapping ops
729
+ if (tail > head) {
730
+ index_type count = tail - head;
731
+ if (count > kBinarySearchThreshold) {
732
+ head = FindBinary<false>(head, tail, offset);
733
+ }
734
+ } else {
735
+ index_type count = capacity_ + tail - head;
736
+ if (count > kBinarySearchThreshold) {
737
+ head = FindBinary<true>(head, tail, offset);
738
+ }
739
+ }
740
+
741
+ pos_type pos = entry_begin_pos(head);
742
+ pos_type end_pos = entry_end_pos(head);
743
+ while (offset >= Distance(begin_pos_, end_pos)) {
744
+ head = advance(head);
745
+ pos = end_pos;
746
+ end_pos = entry_end_pos(head);
747
+ }
748
+
749
+ return {head, offset - Distance(begin_pos_, pos)};
750
+ }
751
+
752
+ CordRepRing::Position CordRepRing::FindTailSlow(index_type head,
753
+ size_t offset) const {
754
+ index_type tail = tail_;
755
+ const size_t tail_offset = offset - 1;
756
+
757
+ // Binary search until we are good for linear search
758
+ // Optimize for branchless / non wrapping ops
759
+ if (tail > head) {
760
+ index_type count = tail - head;
761
+ if (count > kBinarySearchThreshold) {
762
+ head = FindBinary<false>(head, tail, tail_offset);
763
+ }
764
+ } else {
765
+ index_type count = capacity_ + tail - head;
766
+ if (count > kBinarySearchThreshold) {
767
+ head = FindBinary<true>(head, tail, tail_offset);
768
+ }
769
+ }
770
+
771
+ size_t end_offset = entry_end_offset(head);
772
+ while (tail_offset >= end_offset) {
773
+ head = advance(head);
774
+ end_offset = entry_end_offset(head);
775
+ }
776
+
777
+ return {advance(head), end_offset - offset};
778
+ }
779
+
780
+ char CordRepRing::GetCharacter(size_t offset) const {
781
+ assert(offset < length);
782
+
783
+ Position pos = Find(offset);
784
+ size_t data_offset = entry_data_offset(pos.index) + pos.offset;
785
+ return GetRepData(entry_child(pos.index))[data_offset];
786
+ }
787
+
788
+ CordRepRing* CordRepRing::SubRing(CordRepRing* rep, size_t offset,
789
+ size_t length, size_t extra) {
790
+ assert(offset <= rep->length);
791
+ assert(offset <= rep->length - length);
792
+
793
+ if (length == 0) {
794
+ CordRep::Unref(rep);
795
+ return nullptr;
796
+ }
797
+
798
+ // Find position of first byte
799
+ Position head = rep->Find(offset);
800
+ Position tail = rep->FindTail(head.index, offset + length);
801
+ const size_t new_entries = rep->entries(head.index, tail.index);
802
+
803
+ if (rep->refcount.IsOne() && extra <= (rep->capacity() - new_entries)) {
804
+ // We adopt a privately owned rep and no extra entries needed.
805
+ if (head.index != rep->head_) UnrefEntries(rep, rep->head_, head.index);
806
+ if (tail.index != rep->tail_) UnrefEntries(rep, tail.index, rep->tail_);
807
+ rep->head_ = head.index;
808
+ rep->tail_ = tail.index;
809
+ } else {
810
+ // Copy subset to new rep
811
+ rep = Copy(rep, head.index, tail.index, extra);
812
+ head.index = rep->head_;
813
+ tail.index = rep->tail_;
814
+ }
815
+
816
+ // Adjust begin_pos and length
817
+ rep->length = length;
818
+ rep->begin_pos_ += offset;
819
+
820
+ // Adjust head and tail blocks
821
+ if (head.offset) {
822
+ rep->AddDataOffset(head.index, head.offset);
823
+ }
824
+ if (tail.offset) {
825
+ rep->SubLength(rep->retreat(tail.index), tail.offset);
826
+ }
827
+
828
+ return Validate(rep);
829
+ }
830
+
831
+ CordRepRing* CordRepRing::RemovePrefix(CordRepRing* rep, size_t len,
832
+ size_t extra) {
833
+ assert(len <= rep->length);
834
+ if (len == rep->length) {
835
+ CordRep::Unref(rep);
836
+ return nullptr;
837
+ }
838
+
839
+ Position head = rep->Find(len);
840
+ if (rep->refcount.IsOne()) {
841
+ if (head.index != rep->head_) UnrefEntries(rep, rep->head_, head.index);
842
+ rep->head_ = head.index;
843
+ } else {
844
+ rep = Copy(rep, head.index, rep->tail_, extra);
845
+ head.index = rep->head_;
846
+ }
847
+
848
+ // Adjust begin_pos and length
849
+ rep->length -= len;
850
+ rep->begin_pos_ += len;
851
+
852
+ // Adjust head block
853
+ if (head.offset) {
854
+ rep->AddDataOffset(head.index, head.offset);
855
+ }
856
+
857
+ return Validate(rep);
858
+ }
859
+
860
+ CordRepRing* CordRepRing::RemoveSuffix(CordRepRing* rep, size_t len,
861
+ size_t extra) {
862
+ assert(len <= rep->length);
863
+
864
+ if (len == rep->length) {
865
+ CordRep::Unref(rep);
866
+ return nullptr;
867
+ }
868
+
869
+ Position tail = rep->FindTail(rep->length - len);
870
+ if (rep->refcount.IsOne()) {
871
+ // We adopt a privately owned rep, scrub.
872
+ if (tail.index != rep->tail_) UnrefEntries(rep, tail.index, rep->tail_);
873
+ rep->tail_ = tail.index;
874
+ } else {
875
+ // Copy subset to new rep
876
+ rep = Copy(rep, rep->head_, tail.index, extra);
877
+ tail.index = rep->tail_;
878
+ }
879
+
880
+ // Adjust length
881
+ rep->length -= len;
882
+
883
+ // Adjust tail block
884
+ if (tail.offset) {
885
+ rep->SubLength(rep->retreat(tail.index), tail.offset);
886
+ }
887
+
888
+ return Validate(rep);
889
+ }
890
+
891
+ #ifdef __clang__
892
+ #pragma clang diagnostic pop
893
+ #endif
894
+
895
+ } // namespace cord_internal
896
+ ABSL_NAMESPACE_END
897
+ } // namespace absl