grpc 1.47.0 → 1.48.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.
- checksums.yaml +4 -4
- data/Makefile +105 -47
- data/include/grpc/compression.h +1 -1
- data/include/grpc/event_engine/event_engine.h +20 -11
- data/include/grpc/event_engine/slice_buffer.h +8 -2
- data/include/grpc/grpc.h +3 -3
- data/include/grpc/impl/codegen/compression_types.h +2 -1
- data/include/grpc/impl/codegen/connectivity_state.h +2 -1
- data/include/grpc/impl/codegen/gpr_types.h +2 -1
- data/include/grpc/impl/codegen/grpc_types.h +2 -1
- data/include/grpc/impl/codegen/port_platform.h +6 -3
- data/src/core/ext/filters/census/grpc_context.cc +3 -0
- data/src/core/ext/filters/channel_idle/channel_idle_filter.cc +17 -5
- data/src/core/ext/filters/channel_idle/channel_idle_filter.h +16 -0
- data/src/core/ext/filters/channel_idle/idle_filter_state.h +2 -0
- data/src/core/ext/filters/client_channel/backup_poller.cc +3 -1
- data/src/core/ext/filters/client_channel/channel_connectivity.cc +2 -2
- data/src/core/ext/filters/client_channel/client_channel.cc +51 -65
- data/src/core/ext/filters/client_channel/client_channel.h +19 -4
- data/src/core/ext/filters/client_channel/config_selector.h +1 -1
- data/src/core/ext/filters/client_channel/connector.h +1 -1
- data/src/core/ext/filters/client_channel/dynamic_filters.cc +6 -4
- data/src/core/ext/filters/client_channel/dynamic_filters.h +1 -1
- data/src/core/ext/filters/client_channel/lb_policy/address_filtering.cc +1 -1
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc +2 -2
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h +1 -0
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +73 -43
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.cc +1 -1
- data/src/core/ext/filters/client_channel/lb_policy/oob_backend_metric.cc +0 -1
- data/src/core/ext/filters/client_channel/lb_policy/outlier_detection/outlier_detection.cc +33 -35
- data/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +106 -112
- data/src/core/ext/filters/client_channel/lb_policy/priority/priority.cc +91 -42
- data/src/core/ext/filters/client_channel/lb_policy/ring_hash/ring_hash.cc +177 -138
- data/src/core/ext/filters/client_channel/lb_policy/ring_hash/ring_hash.h +4 -1
- data/src/core/ext/filters/client_channel/lb_policy/rls/rls.cc +47 -44
- data/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +118 -103
- data/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +83 -78
- data/src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc +57 -67
- data/src/core/ext/filters/client_channel/lb_policy/xds/cds.cc +2 -2
- data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_impl.cc +5 -7
- data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_manager.cc +13 -17
- data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_resolver.cc +3 -3
- data/src/core/ext/filters/client_channel/lb_policy.h +0 -7
- data/src/core/ext/filters/client_channel/lb_policy_registry.cc +3 -5
- data/src/core/ext/filters/client_channel/proxy_mapper_registry.cc +0 -1
- data/src/core/ext/filters/client_channel/resolver/binder/binder_resolver.cc +3 -1
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +6 -6
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc +5 -5
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc +10 -5
- data/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc +12 -3
- data/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc +5 -5
- data/src/core/ext/filters/client_channel/resolver/google_c2p/google_c2p_resolver.cc +3 -4
- data/src/core/ext/filters/client_channel/resolver/polling_resolver.cc +1 -1
- data/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc +1 -0
- data/src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc +24 -15
- data/src/core/ext/filters/client_channel/resolver/xds/xds_resolver.h +3 -1
- data/src/core/ext/filters/client_channel/resolver_result_parsing.cc +7 -7
- data/src/core/ext/filters/client_channel/retry_filter.cc +35 -36
- data/src/core/ext/filters/client_channel/retry_filter.h +1 -0
- data/src/core/ext/filters/client_channel/retry_service_config.cc +4 -4
- data/src/core/ext/filters/client_channel/service_config_channel_arg_filter.cc +2 -1
- data/src/core/ext/filters/client_channel/subchannel.cc +53 -50
- data/src/core/ext/filters/client_channel/subchannel.h +6 -22
- data/src/core/ext/filters/client_channel/subchannel_interface.h +10 -18
- data/src/core/ext/filters/client_channel/subchannel_stream_client.cc +12 -97
- data/src/core/ext/filters/client_channel/subchannel_stream_client.h +5 -9
- data/src/core/ext/filters/deadline/deadline_filter.cc +12 -7
- data/src/core/ext/filters/deadline/deadline_filter.h +8 -1
- data/src/core/ext/filters/fault_injection/fault_injection_filter.cc +21 -2
- data/src/core/ext/filters/fault_injection/fault_injection_filter.h +8 -3
- data/src/core/ext/filters/fault_injection/service_config_parser.cc +7 -4
- data/src/core/ext/filters/fault_injection/service_config_parser.h +17 -3
- data/src/core/ext/filters/http/client/http_client_filter.cc +16 -5
- data/src/core/ext/filters/http/client/http_client_filter.h +8 -1
- data/src/core/ext/filters/http/client_authority_filter.cc +11 -10
- data/src/core/ext/filters/http/client_authority_filter.h +5 -2
- data/src/core/ext/filters/http/http_filters_plugin.cc +9 -1
- data/src/core/ext/filters/http/message_compress/message_compress_filter.cc +64 -187
- data/src/core/ext/filters/http/message_compress/message_compress_filter.h +1 -2
- data/src/core/ext/filters/http/message_compress/message_decompress_filter.cc +42 -106
- data/src/core/ext/filters/http/message_compress/message_decompress_filter.h +1 -0
- data/src/core/ext/filters/http/server/http_server_filter.cc +16 -9
- data/src/core/ext/filters/http/server/http_server_filter.h +6 -1
- data/src/core/ext/filters/message_size/message_size_filter.cc +25 -15
- data/src/core/ext/filters/message_size/message_size_filter.h +13 -0
- data/src/core/ext/filters/rbac/rbac_filter.cc +14 -3
- data/src/core/ext/filters/rbac/rbac_filter.h +8 -0
- data/src/core/ext/filters/rbac/rbac_service_config_parser.cc +13 -2
- data/src/core/ext/filters/rbac/rbac_service_config_parser.h +14 -2
- data/src/core/ext/filters/server_config_selector/server_config_selector.cc +1 -0
- data/src/core/ext/filters/server_config_selector/server_config_selector.h +9 -0
- data/src/core/ext/filters/server_config_selector/server_config_selector_filter.cc +22 -2
- data/src/core/ext/filters/server_config_selector/server_config_selector_filter.h +1 -0
- data/src/core/ext/transport/chttp2/client/chttp2_connector.cc +4 -4
- data/src/core/ext/transport/chttp2/server/chttp2_server.cc +15 -15
- data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +196 -476
- data/src/core/ext/transport/chttp2/transport/chttp2_transport.h +1 -1
- data/src/core/ext/transport/chttp2/transport/flow_control.cc +141 -261
- data/src/core/ext/transport/chttp2/transport/flow_control.h +176 -289
- data/src/core/ext/transport/chttp2/transport/frame_data.cc +57 -215
- data/src/core/ext/transport/chttp2/transport/frame_data.h +10 -36
- data/src/core/ext/transport/chttp2/transport/frame_settings.cc +0 -41
- data/src/core/ext/transport/chttp2/transport/frame_window_update.cc +7 -12
- data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +7 -6
- data/src/core/ext/transport/chttp2/transport/hpack_parser_table.cc +0 -2
- data/src/core/ext/transport/chttp2/transport/internal.h +9 -111
- data/src/core/ext/transport/chttp2/transport/parsing.cc +51 -38
- data/src/core/ext/transport/chttp2/transport/stream_lists.cc +0 -4
- data/src/core/ext/transport/chttp2/transport/writing.cc +18 -21
- data/src/core/ext/transport/inproc/inproc_plugin.cc +0 -1
- data/src/core/ext/transport/inproc/inproc_transport.cc +85 -81
- data/src/core/ext/transport/inproc/inproc_transport.h +3 -1
- data/src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/ring_hash/v3/ring_hash.upb.c +52 -0
- data/src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/ring_hash/v3/ring_hash.upb.h +164 -0
- data/src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/wrr_locality/v3/wrr_locality.upb.c +46 -0
- data/src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/wrr_locality/v3/wrr_locality.upb.h +94 -0
- data/src/core/ext/xds/certificate_provider_factory.h +6 -1
- data/src/core/ext/xds/certificate_provider_registry.cc +8 -8
- data/src/core/ext/xds/certificate_provider_registry.h +3 -1
- data/src/core/ext/xds/certificate_provider_store.cc +2 -0
- data/src/core/ext/xds/certificate_provider_store.h +9 -0
- data/src/core/ext/xds/file_watcher_certificate_provider_factory.cc +9 -0
- data/src/core/ext/xds/file_watcher_certificate_provider_factory.h +8 -0
- data/src/core/ext/xds/upb_utils.h +1 -2
- data/src/core/ext/xds/xds_api.cc +16 -18
- data/src/core/ext/xds/xds_api.h +12 -5
- data/src/core/ext/xds/xds_bootstrap.cc +37 -24
- data/src/core/ext/xds/xds_bootstrap.h +9 -11
- data/src/core/ext/xds/xds_certificate_provider.cc +12 -3
- data/src/core/ext/xds/xds_certificate_provider.h +16 -1
- data/src/core/ext/xds/xds_channel_stack_modifier.cc +9 -0
- data/src/core/ext/xds/xds_channel_stack_modifier.h +5 -1
- data/src/core/ext/xds/xds_client.cc +71 -22
- data/src/core/ext/xds/xds_client.h +17 -3
- data/src/core/ext/xds/xds_client_stats.cc +3 -4
- data/src/core/ext/xds/xds_client_stats.h +4 -3
- data/src/core/ext/xds/xds_cluster.cc +21 -10
- data/src/core/ext/xds/xds_cluster.h +9 -1
- data/src/core/ext/xds/xds_cluster_specifier_plugin.cc +16 -7
- data/src/core/ext/xds/xds_cluster_specifier_plugin.h +1 -8
- data/src/core/ext/xds/xds_common_types.cc +36 -22
- data/src/core/ext/xds/xds_common_types.h +12 -4
- data/src/core/ext/xds/xds_endpoint.cc +25 -15
- data/src/core/ext/xds/xds_endpoint.h +13 -5
- data/src/core/ext/xds/xds_http_fault_filter.cc +7 -5
- data/src/core/ext/xds/xds_http_fault_filter.h +3 -1
- data/src/core/ext/xds/xds_http_filters.cc +7 -0
- data/src/core/ext/xds/xds_http_filters.h +3 -3
- data/src/core/ext/xds/xds_http_rbac_filter.cc +16 -0
- data/src/core/ext/xds/xds_http_rbac_filter.h +7 -0
- data/src/core/ext/xds/xds_lb_policy_registry.cc +291 -0
- data/src/core/ext/xds/xds_lb_policy_registry.h +72 -0
- data/src/core/ext/xds/xds_listener.cc +51 -33
- data/src/core/ext/xds/xds_listener.h +10 -1
- data/src/core/ext/xds/xds_resource_type.h +3 -3
- data/src/core/ext/xds/xds_resource_type_impl.h +7 -3
- data/src/core/ext/xds/xds_route_config.cc +56 -28
- data/src/core/ext/xds/xds_route_config.h +11 -2
- data/src/core/ext/xds/xds_routing.cc +16 -0
- data/src/core/ext/xds/xds_routing.h +7 -2
- data/src/core/ext/xds/xds_server_config_fetcher.cc +54 -6
- data/src/core/lib/address_utils/parse_address.cc +5 -8
- data/src/core/lib/address_utils/parse_address.h +3 -2
- data/src/core/lib/address_utils/sockaddr_utils.cc +8 -7
- data/src/core/lib/address_utils/sockaddr_utils.h +2 -0
- data/src/core/lib/avl/avl.h +3 -3
- data/src/core/lib/backoff/backoff.cc +1 -1
- data/src/core/lib/backoff/backoff.h +1 -1
- data/src/core/lib/channel/call_tracer.h +3 -3
- data/src/core/lib/channel/channel_args.h +1 -0
- data/src/core/lib/channel/channel_args_preconditioning.cc +1 -0
- data/src/core/lib/channel/channel_fwd.h +26 -0
- data/src/core/lib/channel/channel_stack.cc +4 -4
- data/src/core/lib/channel/channel_stack.h +1 -11
- data/src/core/lib/channel/channel_stack_builder.h +2 -5
- data/src/core/lib/channel/channel_stack_builder_impl.cc +1 -1
- data/src/core/lib/channel/channel_stack_builder_impl.h +1 -0
- data/src/core/lib/channel/channelz.cc +2 -1
- data/src/core/lib/channel/channelz.h +2 -3
- data/src/core/lib/channel/channelz_registry.cc +4 -5
- data/src/core/lib/channel/connected_channel.cc +1 -0
- data/src/core/lib/channel/connected_channel.h +1 -0
- data/src/core/lib/channel/promise_based_filter.cc +11 -5
- data/src/core/lib/channel/promise_based_filter.h +2 -0
- data/src/core/lib/compression/compression.cc +6 -1
- data/src/core/lib/compression/compression_internal.cc +3 -6
- data/src/core/lib/compression/compression_internal.h +3 -2
- data/src/core/lib/compression/message_compress.cc +3 -1
- data/src/core/lib/compression/message_compress.h +2 -3
- data/src/core/lib/debug/stats.cc +9 -9
- data/src/core/lib/debug/stats.h +2 -1
- data/src/core/lib/debug/stats_data.cc +2 -1
- data/src/core/lib/debug/stats_data.h +0 -4
- data/src/core/lib/debug/trace.h +13 -12
- data/src/core/lib/event_engine/default_event_engine_factory.cc +1 -1
- data/src/core/lib/event_engine/event_engine.cc +24 -19
- data/src/core/lib/event_engine/event_engine_factory.h +2 -2
- data/src/core/lib/event_engine/{iomgr_engine.cc → iomgr_engine/iomgr_engine.cc} +44 -91
- data/src/core/lib/event_engine/{iomgr_engine.h → iomgr_engine/iomgr_engine.h} +20 -16
- data/src/core/lib/event_engine/iomgr_engine/thread_pool.cc +123 -0
- data/src/core/lib/event_engine/iomgr_engine/thread_pool.h +70 -0
- data/src/core/lib/event_engine/iomgr_engine/time_averaged_stats.cc +62 -0
- data/src/core/lib/event_engine/iomgr_engine/time_averaged_stats.h +81 -0
- data/src/core/lib/event_engine/iomgr_engine/timer.cc +312 -0
- data/src/core/lib/event_engine/iomgr_engine/timer.h +193 -0
- data/src/core/lib/event_engine/iomgr_engine/timer_heap.cc +107 -0
- data/src/core/lib/event_engine/iomgr_engine/timer_heap.h +56 -0
- data/src/core/lib/event_engine/iomgr_engine/timer_manager.cc +254 -0
- data/src/core/lib/event_engine/iomgr_engine/timer_manager.h +111 -0
- data/src/core/lib/event_engine/promise.h +69 -0
- data/src/core/lib/gpr/time_posix.cc +6 -9
- data/src/core/lib/gpr/time_windows.cc +10 -7
- data/src/core/lib/gprpp/manual_constructor.h +0 -67
- data/src/core/lib/gprpp/status_helper.cc +44 -30
- data/src/core/lib/gprpp/time.cc +8 -0
- data/src/core/lib/gprpp/time.h +4 -0
- data/src/core/lib/http/format_request.cc +5 -4
- data/src/core/lib/http/format_request.h +1 -1
- data/src/core/lib/http/httpcli.cc +18 -12
- data/src/core/lib/http/httpcli.h +19 -3
- data/src/core/lib/http/httpcli_security_connector.cc +16 -4
- data/src/core/lib/http/httpcli_ssl_credentials.h +3 -1
- data/src/core/lib/http/parser.cc +6 -7
- data/src/core/lib/http/parser.h +3 -0
- data/src/core/lib/iomgr/call_combiner.cc +2 -2
- data/src/core/lib/iomgr/endpoint.h +1 -1
- data/src/core/lib/iomgr/endpoint_cfstream.cc +2 -2
- data/src/core/lib/iomgr/error.cc +11 -9
- data/src/core/lib/iomgr/error.h +9 -5
- data/src/core/lib/iomgr/ev_epoll1_linux.cc +57 -18
- data/src/core/lib/iomgr/ev_epoll1_linux.h +1 -1
- data/src/core/lib/iomgr/ev_poll_posix.cc +77 -52
- data/src/core/lib/iomgr/ev_poll_posix.h +2 -2
- data/src/core/lib/iomgr/ev_posix.cc +54 -92
- data/src/core/lib/iomgr/ev_posix.h +5 -3
- data/src/core/lib/iomgr/fork_posix.cc +1 -1
- data/src/core/lib/iomgr/iomgr.cc +7 -0
- data/src/core/lib/iomgr/iomgr_posix.cc +1 -0
- data/src/core/lib/iomgr/iomgr_posix_cfstream.cc +1 -0
- data/src/core/lib/iomgr/load_file.cc +1 -1
- data/src/core/lib/iomgr/resolve_address_posix.cc +1 -1
- data/src/core/lib/iomgr/resolve_address_windows.cc +1 -1
- data/src/core/lib/iomgr/tcp_client.cc +12 -7
- data/src/core/lib/iomgr/tcp_client.h +24 -13
- data/src/core/lib/iomgr/tcp_client_cfstream.cc +15 -9
- data/src/core/lib/iomgr/tcp_client_posix.cc +143 -25
- data/src/core/lib/iomgr/tcp_client_posix.h +1 -1
- data/src/core/lib/iomgr/tcp_client_windows.cc +14 -10
- data/src/core/lib/iomgr/tcp_posix.cc +91 -29
- data/src/core/lib/iomgr/tcp_server_posix.cc +7 -7
- data/src/core/lib/iomgr/tcp_server_utils_posix_common.cc +12 -12
- data/src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.cc +2 -2
- data/src/core/lib/iomgr/tcp_server_windows.cc +7 -7
- data/src/core/lib/iomgr/tcp_windows.cc +5 -5
- data/src/core/lib/iomgr/unix_sockets_posix.cc +2 -2
- data/src/core/lib/iomgr/wakeup_fd_pipe.cc +2 -2
- data/src/core/lib/iomgr/wakeup_fd_posix.cc +15 -12
- data/src/core/lib/iomgr/wakeup_fd_posix.h +0 -2
- data/src/core/lib/iomgr/work_serializer.h +2 -3
- data/src/core/lib/matchers/matchers.cc +6 -3
- data/src/core/lib/matchers/matchers.h +2 -0
- data/src/core/lib/promise/activity.cc +0 -1
- data/src/core/lib/promise/activity.h +7 -13
- data/src/core/lib/promise/loop.h +1 -0
- data/src/core/lib/promise/promise.h +1 -0
- data/src/core/lib/promise/sleep.cc +36 -31
- data/src/core/lib/promise/sleep.h +25 -25
- data/src/core/lib/resolver/resolver.cc +5 -0
- data/src/core/lib/resolver/resolver.h +3 -0
- data/src/core/lib/resolver/resolver_factory.h +5 -2
- data/src/core/lib/resolver/resolver_registry.cc +2 -9
- data/src/core/lib/resolver/resolver_registry.h +12 -1
- data/src/core/lib/resolver/server_address.cc +8 -0
- data/src/core/lib/resolver/server_address.h +9 -2
- data/src/core/lib/resource_quota/memory_quota.cc +18 -60
- data/src/core/lib/resource_quota/memory_quota.h +11 -25
- data/src/core/lib/security/authorization/authorization_policy_provider.h +7 -0
- data/src/core/lib/security/authorization/authorization_policy_provider_vtable.cc +4 -0
- data/src/core/lib/security/authorization/evaluate_args.cc +9 -3
- data/src/core/lib/security/authorization/evaluate_args.h +6 -3
- data/src/core/lib/security/authorization/grpc_authorization_engine.cc +6 -0
- data/src/core/lib/security/authorization/grpc_authorization_engine.h +7 -0
- data/src/core/lib/security/authorization/grpc_server_authz_filter.cc +12 -0
- data/src/core/lib/security/authorization/grpc_server_authz_filter.h +12 -1
- data/src/core/lib/security/authorization/matchers.cc +9 -1
- data/src/core/lib/security/authorization/matchers.h +7 -0
- data/src/core/lib/security/authorization/rbac_policy.cc +5 -0
- data/src/core/lib/security/authorization/rbac_policy.h +7 -0
- data/src/core/lib/security/context/security_context.cc +5 -2
- data/src/core/lib/security/context/security_context.h +14 -2
- data/src/core/lib/security/credentials/alts/alts_credentials.cc +4 -2
- data/src/core/lib/security/credentials/alts/alts_credentials.h +6 -1
- data/src/core/lib/security/credentials/alts/grpc_alts_credentials_client_options.cc +1 -3
- data/src/core/lib/security/credentials/alts/grpc_alts_credentials_server_options.cc +1 -4
- data/src/core/lib/security/credentials/call_creds_util.cc +8 -0
- data/src/core/lib/security/credentials/call_creds_util.h +1 -0
- data/src/core/lib/security/credentials/channel_creds_registry.h +6 -1
- data/src/core/lib/security/credentials/channel_creds_registry_init.cc +10 -0
- data/src/core/lib/security/credentials/composite/composite_credentials.cc +4 -4
- data/src/core/lib/security/credentials/composite/composite_credentials.h +16 -2
- data/src/core/lib/security/credentials/credentials.cc +4 -8
- data/src/core/lib/security/credentials/credentials.h +10 -8
- data/src/core/lib/security/credentials/external/aws_external_account_credentials.cc +28 -10
- data/src/core/lib/security/credentials/external/aws_external_account_credentials.h +10 -0
- data/src/core/lib/security/credentials/external/aws_request_signer.cc +9 -0
- data/src/core/lib/security/credentials/external/external_account_credentials.cc +24 -9
- data/src/core/lib/security/credentials/external/external_account_credentials.h +11 -0
- data/src/core/lib/security/credentials/external/file_external_account_credentials.cc +12 -4
- data/src/core/lib/security/credentials/external/file_external_account_credentials.h +6 -0
- data/src/core/lib/security/credentials/external/url_external_account_credentials.cc +20 -4
- data/src/core/lib/security/credentials/external/url_external_account_credentials.h +10 -0
- data/src/core/lib/security/credentials/fake/fake_credentials.cc +8 -6
- data/src/core/lib/security/credentials/fake/fake_credentials.h +13 -1
- data/src/core/lib/security/credentials/google_default/credentials_generic.cc +1 -0
- data/src/core/lib/security/credentials/google_default/google_default_credentials.cc +27 -10
- data/src/core/lib/security/credentials/google_default/google_default_credentials.h +10 -1
- data/src/core/lib/security/credentials/iam/iam_credentials.cc +9 -3
- data/src/core/lib/security/credentials/iam/iam_credentials.h +10 -0
- data/src/core/lib/security/credentials/insecure/insecure_credentials.cc +4 -0
- data/src/core/lib/security/credentials/insecure/insecure_credentials.h +5 -0
- data/src/core/lib/security/credentials/jwt/json_token.cc +5 -2
- data/src/core/lib/security/credentials/jwt/json_token.h +2 -2
- data/src/core/lib/security/credentials/jwt/jwt_credentials.cc +11 -5
- data/src/core/lib/security/credentials/jwt/jwt_credentials.h +14 -0
- data/src/core/lib/security/credentials/jwt/jwt_verifier.cc +28 -3
- data/src/core/lib/security/credentials/jwt/jwt_verifier.h +4 -2
- data/src/core/lib/security/credentials/local/local_credentials.cc +4 -3
- data/src/core/lib/security/credentials/local/local_credentials.h +7 -0
- data/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc +26 -13
- data/src/core/lib/security/credentials/oauth2/oauth2_credentials.h +20 -0
- data/src/core/lib/security/credentials/plugin/plugin_credentials.cc +8 -7
- data/src/core/lib/security/credentials/plugin/plugin_credentials.h +24 -0
- data/src/core/lib/security/credentials/ssl/ssl_credentials.cc +5 -0
- data/src/core/lib/security/credentials/ssl/ssl_credentials.h +13 -0
- data/src/core/lib/security/credentials/tls/grpc_tls_certificate_distributor.cc +6 -6
- data/src/core/lib/security/credentials/tls/grpc_tls_certificate_distributor.h +9 -3
- data/src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.cc +29 -10
- data/src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.h +9 -4
- data/src/core/lib/security/credentials/tls/grpc_tls_certificate_verifier.cc +9 -2
- data/src/core/lib/security/credentials/tls/grpc_tls_certificate_verifier.h +6 -7
- data/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc +4 -5
- data/src/core/lib/security/credentials/tls/tls_credentials.cc +7 -2
- data/src/core/lib/security/credentials/tls/tls_credentials.h +5 -1
- data/src/core/lib/security/credentials/tls/tls_utils.cc +2 -0
- data/src/core/lib/security/credentials/tls/tls_utils.h +1 -1
- data/src/core/lib/security/credentials/xds/xds_credentials.cc +8 -1
- data/src/core/lib/security/credentials/xds/xds_credentials.h +14 -0
- data/src/core/lib/security/security_connector/alts/alts_security_connector.cc +22 -2
- data/src/core/lib/security/security_connector/alts/alts_security_connector.h +6 -3
- data/src/core/lib/security/security_connector/fake/fake_security_connector.cc +17 -1
- data/src/core/lib/security/security_connector/fake/fake_security_connector.h +2 -2
- data/src/core/lib/security/security_connector/insecure/insecure_security_connector.cc +9 -0
- data/src/core/lib/security/security_connector/insecure/insecure_security_connector.h +17 -2
- data/src/core/lib/security/security_connector/load_system_roots_fallback.cc +5 -3
- data/src/core/lib/security/security_connector/{load_system_roots_linux.cc → load_system_roots_supported.cc} +27 -19
- data/src/core/lib/security/security_connector/{load_system_roots_linux.h → load_system_roots_supported.h} +5 -5
- data/src/core/lib/security/security_connector/local/local_security_connector.cc +22 -3
- data/src/core/lib/security/security_connector/local/local_security_connector.h +6 -2
- data/src/core/lib/security/security_connector/security_connector.cc +20 -18
- data/src/core/lib/security/security_connector/security_connector.h +18 -6
- data/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc +18 -6
- data/src/core/lib/security/security_connector/ssl/ssl_security_connector.h +4 -2
- data/src/core/lib/security/security_connector/ssl_utils.cc +12 -2
- data/src/core/lib/security/security_connector/ssl_utils.h +10 -7
- data/src/core/lib/security/security_connector/ssl_utils_config.h +1 -1
- data/src/core/lib/security/security_connector/tls/tls_security_connector.cc +21 -13
- data/src/core/lib/security/security_connector/tls/tls_security_connector.h +23 -3
- data/src/core/lib/security/transport/auth_filters.h +7 -0
- data/src/core/lib/security/transport/client_auth_filter.cc +18 -9
- data/src/core/lib/security/transport/secure_endpoint.cc +63 -13
- data/src/core/lib/security/transport/secure_endpoint.h +4 -3
- data/src/core/lib/security/transport/security_handshaker.cc +44 -11
- data/src/core/lib/security/transport/security_handshaker.h +4 -0
- data/src/core/lib/security/transport/server_auth_filter.cc +26 -4
- data/src/core/lib/security/util/json_util.cc +3 -2
- data/src/core/lib/security/util/json_util.h +0 -2
- data/src/core/lib/service_config/service_config_call_data.h +2 -1
- data/src/core/lib/service_config/service_config_impl.cc +6 -6
- data/src/core/lib/service_config/service_config_impl.h +1 -3
- data/src/core/lib/service_config/service_config_parser.cc +2 -4
- data/src/core/lib/slice/slice_buffer.cc +30 -1
- data/src/core/lib/slice/slice_buffer.h +37 -6
- data/src/core/lib/slice/slice_string_helpers.cc +0 -20
- data/src/core/lib/slice/slice_string_helpers.h +0 -4
- data/src/core/lib/surface/call.cc +53 -115
- data/src/core/lib/surface/call.h +5 -1
- data/src/core/lib/surface/channel.h +2 -0
- data/src/core/lib/surface/channel_ping.cc +1 -1
- data/src/core/lib/surface/completion_queue.cc +15 -14
- data/src/core/lib/surface/completion_queue.h +2 -1
- data/src/core/lib/surface/init.cc +0 -1
- data/src/core/lib/surface/lame_client.cc +1 -1
- data/src/core/lib/surface/lame_client.h +1 -1
- data/src/core/lib/surface/server.cc +14 -8
- data/src/core/lib/surface/server.h +4 -1
- data/src/core/lib/surface/validate_metadata.cc +1 -1
- data/src/core/lib/surface/version.cc +2 -2
- data/src/core/lib/transport/error_utils.cc +13 -7
- data/src/core/lib/transport/handshaker.cc +3 -3
- data/src/core/lib/transport/http_connect_handshaker.cc +4 -4
- data/src/core/lib/transport/tcp_connect_handshaker.cc +2 -2
- data/src/core/lib/transport/transport.cc +0 -3
- data/src/core/lib/transport/transport.h +20 -14
- data/src/core/lib/transport/transport_fwd.h +20 -0
- data/src/core/lib/transport/transport_impl.h +1 -0
- data/src/core/lib/transport/transport_op_string.cc +9 -9
- data/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc +1 -1
- data/src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc +9 -1
- data/src/core/tsi/fake_transport_security.cc +13 -1
- data/src/core/tsi/fake_transport_security.h +6 -0
- data/src/core/tsi/ssl_transport_security.cc +1 -1
- data/src/core/tsi/transport_security_grpc.cc +3 -2
- data/src/core/tsi/transport_security_grpc.h +5 -2
- data/src/ruby/ext/grpc/ext-export-truffleruby.clang +2 -0
- data/src/ruby/ext/grpc/ext-export-truffleruby.gcc +7 -0
- data/src/ruby/ext/grpc/ext-export.clang +1 -0
- data/src/ruby/ext/grpc/ext-export.gcc +1 -0
- data/src/ruby/ext/grpc/extconf.rb +49 -18
- data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +1 -1
- data/src/ruby/lib/grpc/errors.rb +1 -1
- data/src/ruby/lib/grpc/version.rb +1 -1
- data/src/ruby/spec/generic/client_stub_spec.rb +23 -23
- data/third_party/abseil-cpp/absl/algorithm/container.h +1 -1
- data/third_party/abseil-cpp/absl/base/attributes.h +49 -22
- data/third_party/abseil-cpp/absl/base/casts.h +61 -68
- data/third_party/abseil-cpp/absl/base/config.h +182 -41
- data/third_party/abseil-cpp/absl/base/internal/cycleclock.cc +12 -42
- data/third_party/abseil-cpp/absl/base/internal/cycleclock.h +67 -2
- data/third_party/abseil-cpp/absl/base/internal/direct_mmap.h +3 -3
- data/third_party/abseil-cpp/absl/base/internal/endian.h +17 -62
- data/third_party/abseil-cpp/absl/base/internal/fast_type_id.h +2 -0
- data/third_party/abseil-cpp/absl/base/internal/invoke.h +54 -0
- data/third_party/abseil-cpp/absl/base/internal/prefetch.h +138 -0
- data/third_party/abseil-cpp/absl/base/internal/raw_logging.cc +29 -22
- data/third_party/abseil-cpp/absl/base/internal/raw_logging.h +13 -12
- data/third_party/abseil-cpp/absl/base/internal/spinlock.cc +3 -0
- data/third_party/abseil-cpp/absl/base/internal/spinlock.h +8 -0
- data/third_party/abseil-cpp/absl/base/internal/spinlock_linux.inc +2 -5
- data/third_party/abseil-cpp/absl/base/internal/strerror.cc +88 -0
- data/third_party/abseil-cpp/absl/base/internal/strerror.h +39 -0
- data/third_party/abseil-cpp/absl/base/internal/sysinfo.cc +0 -1
- data/third_party/abseil-cpp/absl/base/internal/thread_identity.cc +2 -1
- data/third_party/abseil-cpp/absl/base/internal/unscaledcycleclock.cc +6 -7
- data/third_party/abseil-cpp/absl/base/internal/unscaledcycleclock.h +12 -3
- data/third_party/abseil-cpp/absl/base/log_severity.cc +28 -0
- data/third_party/abseil-cpp/absl/base/log_severity.h +51 -0
- data/third_party/abseil-cpp/absl/base/optimization.h +19 -11
- data/third_party/abseil-cpp/absl/base/options.h +1 -1
- data/third_party/abseil-cpp/absl/base/thread_annotations.h +2 -2
- data/third_party/abseil-cpp/absl/container/fixed_array.h +2 -0
- data/third_party/abseil-cpp/absl/container/flat_hash_map.h +11 -4
- data/third_party/abseil-cpp/absl/container/flat_hash_set.h +15 -9
- data/third_party/abseil-cpp/absl/container/inlined_vector.h +20 -9
- data/third_party/abseil-cpp/absl/container/internal/common.h +6 -5
- data/third_party/abseil-cpp/absl/container/internal/container_memory.h +10 -28
- data/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler.cc +68 -20
- data/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler.h +29 -11
- data/third_party/abseil-cpp/absl/container/internal/inlined_vector.h +59 -38
- data/third_party/abseil-cpp/absl/container/internal/raw_hash_set.cc +4 -0
- data/third_party/abseil-cpp/absl/container/internal/raw_hash_set.h +515 -184
- data/third_party/abseil-cpp/absl/debugging/internal/address_is_readable.cc +45 -88
- data/third_party/abseil-cpp/absl/debugging/internal/elf_mem_image.cc +4 -0
- data/third_party/abseil-cpp/absl/debugging/internal/elf_mem_image.h +3 -2
- data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_aarch64-inl.inc +8 -3
- data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_arm-inl.inc +8 -3
- data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_config.h +2 -1
- data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_powerpc-inl.inc +8 -3
- data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_riscv-inl.inc +20 -18
- data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_x86-inl.inc +8 -3
- data/third_party/abseil-cpp/absl/debugging/internal/vdso_support.cc +15 -2
- data/third_party/abseil-cpp/absl/debugging/symbolize.cc +6 -1
- data/third_party/abseil-cpp/absl/debugging/symbolize_elf.inc +46 -7
- data/third_party/abseil-cpp/absl/functional/bind_front.h +10 -1
- data/third_party/abseil-cpp/absl/functional/function_ref.h +2 -1
- data/third_party/abseil-cpp/absl/hash/hash.h +82 -8
- data/third_party/abseil-cpp/absl/hash/internal/hash.h +218 -23
- data/third_party/abseil-cpp/absl/numeric/bits.h +2 -1
- data/third_party/abseil-cpp/absl/numeric/int128.cc +4 -2
- data/third_party/abseil-cpp/absl/numeric/int128.h +2 -2
- data/third_party/abseil-cpp/absl/profiling/internal/sample_recorder.h +21 -6
- data/third_party/abseil-cpp/absl/random/bernoulli_distribution.h +4 -4
- data/third_party/abseil-cpp/absl/random/distributions.h +3 -3
- data/third_party/abseil-cpp/absl/random/internal/distribution_caller.h +3 -0
- data/third_party/abseil-cpp/absl/random/internal/fast_uniform_bits.h +2 -1
- data/third_party/abseil-cpp/absl/random/internal/generate_real.h +2 -2
- data/third_party/abseil-cpp/absl/random/internal/nonsecure_base.h +59 -48
- data/third_party/abseil-cpp/absl/random/internal/pcg_engine.h +1 -1
- data/third_party/abseil-cpp/absl/random/internal/randen.h +5 -11
- data/third_party/abseil-cpp/absl/random/internal/randen_detect.cc +6 -2
- data/third_party/abseil-cpp/absl/random/internal/randen_engine.h +48 -23
- data/third_party/abseil-cpp/absl/random/internal/salted_seed_seq.h +24 -26
- data/third_party/abseil-cpp/absl/random/internal/traits.h +53 -5
- data/third_party/abseil-cpp/absl/random/internal/uniform_helper.h +5 -5
- data/third_party/abseil-cpp/absl/random/internal/wide_multiply.h +33 -48
- data/third_party/abseil-cpp/absl/random/log_uniform_int_distribution.h +9 -10
- data/third_party/abseil-cpp/absl/random/poisson_distribution.h +7 -4
- data/third_party/abseil-cpp/absl/random/seed_sequences.h +1 -0
- data/third_party/abseil-cpp/absl/random/uniform_int_distribution.h +2 -2
- data/third_party/abseil-cpp/absl/random/uniform_real_distribution.h +1 -1
- data/third_party/abseil-cpp/absl/random/zipf_distribution.h +4 -3
- data/third_party/abseil-cpp/absl/status/internal/status_internal.h +17 -0
- data/third_party/abseil-cpp/absl/status/status.cc +174 -2
- data/third_party/abseil-cpp/absl/status/status.h +22 -12
- data/third_party/abseil-cpp/absl/status/statusor.h +9 -3
- data/third_party/abseil-cpp/absl/strings/ascii.h +4 -4
- data/third_party/abseil-cpp/absl/strings/cord.cc +194 -913
- data/third_party/abseil-cpp/absl/strings/cord.h +202 -81
- data/third_party/abseil-cpp/absl/strings/cord_analysis.cc +188 -0
- data/third_party/abseil-cpp/absl/strings/cord_analysis.h +44 -0
- data/third_party/abseil-cpp/absl/strings/cord_buffer.cc +30 -0
- data/third_party/abseil-cpp/absl/strings/cord_buffer.h +572 -0
- data/third_party/abseil-cpp/absl/strings/internal/cord_data_edge.h +63 -0
- data/third_party/abseil-cpp/absl/strings/internal/cord_internal.cc +20 -32
- data/third_party/abseil-cpp/absl/strings/internal/cord_internal.h +123 -88
- data/third_party/abseil-cpp/absl/strings/internal/cord_rep_btree.cc +149 -49
- data/third_party/abseil-cpp/absl/strings/internal/cord_rep_btree.h +44 -59
- data/third_party/abseil-cpp/absl/strings/internal/cord_rep_btree_navigator.cc +3 -1
- data/third_party/abseil-cpp/absl/strings/internal/cord_rep_btree_navigator.h +4 -2
- data/third_party/abseil-cpp/absl/strings/internal/cord_rep_btree_reader.cc +3 -2
- data/third_party/abseil-cpp/absl/strings/internal/cord_rep_btree_reader.h +5 -4
- data/third_party/abseil-cpp/absl/strings/internal/cord_rep_consume.cc +7 -74
- data/third_party/abseil-cpp/absl/strings/internal/cord_rep_crc.cc +54 -0
- data/third_party/abseil-cpp/absl/strings/internal/cord_rep_crc.h +102 -0
- data/third_party/abseil-cpp/absl/strings/internal/cord_rep_flat.h +58 -17
- data/third_party/abseil-cpp/absl/strings/internal/cord_rep_ring.cc +13 -11
- data/third_party/abseil-cpp/absl/strings/internal/cordz_info.cc +11 -38
- data/third_party/abseil-cpp/absl/strings/internal/cordz_statistics.h +1 -0
- data/third_party/abseil-cpp/absl/strings/internal/cordz_update_tracker.h +4 -2
- data/third_party/abseil-cpp/absl/strings/internal/escaping.cc +6 -5
- data/third_party/abseil-cpp/absl/strings/internal/ostringstream.cc +1 -1
- data/third_party/abseil-cpp/absl/strings/internal/str_format/arg.cc +1 -1
- data/third_party/abseil-cpp/absl/strings/internal/str_format/arg.h +1 -1
- data/third_party/abseil-cpp/absl/strings/internal/str_format/bind.h +38 -7
- data/third_party/abseil-cpp/absl/strings/internal/str_format/checker.h +7 -2
- data/third_party/abseil-cpp/absl/strings/internal/str_format/extension.cc +4 -5
- data/third_party/abseil-cpp/absl/strings/internal/str_format/extension.h +5 -2
- data/third_party/abseil-cpp/absl/strings/internal/str_format/output.h +2 -1
- data/third_party/abseil-cpp/absl/strings/internal/str_format/parser.h +4 -2
- data/third_party/abseil-cpp/absl/strings/internal/str_join_internal.h +9 -6
- data/third_party/abseil-cpp/absl/strings/internal/string_constant.h +10 -2
- data/third_party/abseil-cpp/absl/strings/internal/utf8.cc +9 -9
- data/third_party/abseil-cpp/absl/strings/numbers.cc +8 -8
- data/third_party/abseil-cpp/absl/strings/numbers.h +26 -23
- data/third_party/abseil-cpp/absl/strings/str_cat.h +20 -13
- data/third_party/abseil-cpp/absl/strings/str_join.h +9 -15
- data/third_party/abseil-cpp/absl/strings/str_split.h +1 -2
- data/third_party/abseil-cpp/absl/strings/string_view.cc +2 -13
- data/third_party/abseil-cpp/absl/strings/string_view.h +3 -2
- data/third_party/abseil-cpp/absl/strings/strip.h +8 -6
- data/third_party/abseil-cpp/absl/strings/substitute.h +10 -2
- data/third_party/abseil-cpp/absl/synchronization/internal/create_thread_identity.cc +9 -6
- data/third_party/abseil-cpp/absl/synchronization/internal/create_thread_identity.h +0 -4
- data/third_party/abseil-cpp/absl/synchronization/internal/per_thread_sem.cc +0 -4
- data/third_party/abseil-cpp/absl/synchronization/internal/per_thread_sem.h +1 -6
- data/third_party/abseil-cpp/absl/synchronization/internal/waiter.cc +0 -25
- data/third_party/abseil-cpp/absl/synchronization/internal/waiter.h +10 -4
- data/third_party/abseil-cpp/absl/synchronization/mutex.cc +75 -40
- data/third_party/abseil-cpp/absl/synchronization/mutex.h +17 -9
- data/third_party/abseil-cpp/absl/synchronization/notification.h +3 -2
- data/third_party/abseil-cpp/absl/time/duration.cc +5 -4
- data/third_party/abseil-cpp/absl/time/internal/cctz/include/cctz/civil_time_detail.h +11 -7
- data/third_party/abseil-cpp/absl/time/time.h +16 -12
- data/third_party/abseil-cpp/absl/types/internal/optional.h +8 -0
- data/third_party/abseil-cpp/absl/types/internal/variant.h +3 -3
- data/third_party/abseil-cpp/absl/types/optional.h +17 -14
- data/third_party/abseil-cpp/absl/types/span.h +2 -1
- metadata +39 -15
- data/src/core/lib/slice/slice_split.cc +0 -103
- data/src/core/lib/slice/slice_split.h +0 -36
- data/src/core/lib/transport/byte_stream.cc +0 -165
- data/src/core/lib/transport/byte_stream.h +0 -170
- data/third_party/abseil-cpp/absl/cleanup/cleanup.h +0 -140
- data/third_party/abseil-cpp/absl/cleanup/internal/cleanup.h +0 -100
- data/third_party/abseil-cpp/absl/container/internal/have_sse.h +0 -50
@@ -34,9 +34,12 @@
|
|
34
34
|
#include "absl/base/port.h"
|
35
35
|
#include "absl/container/fixed_array.h"
|
36
36
|
#include "absl/container/inlined_vector.h"
|
37
|
+
#include "absl/strings/cord_buffer.h"
|
37
38
|
#include "absl/strings/escaping.h"
|
39
|
+
#include "absl/strings/internal/cord_data_edge.h"
|
38
40
|
#include "absl/strings/internal/cord_internal.h"
|
39
41
|
#include "absl/strings/internal/cord_rep_btree.h"
|
42
|
+
#include "absl/strings/internal/cord_rep_crc.h"
|
40
43
|
#include "absl/strings/internal/cord_rep_flat.h"
|
41
44
|
#include "absl/strings/internal/cordz_statistics.h"
|
42
45
|
#include "absl/strings/internal/cordz_update_scope.h"
|
@@ -52,7 +55,7 @@ ABSL_NAMESPACE_BEGIN
|
|
52
55
|
|
53
56
|
using ::absl::cord_internal::CordRep;
|
54
57
|
using ::absl::cord_internal::CordRepBtree;
|
55
|
-
using ::absl::cord_internal::
|
58
|
+
using ::absl::cord_internal::CordRepCrc;
|
56
59
|
using ::absl::cord_internal::CordRepExternal;
|
57
60
|
using ::absl::cord_internal::CordRepFlat;
|
58
61
|
using ::absl::cord_internal::CordRepSubstring;
|
@@ -64,56 +67,6 @@ using ::absl::cord_internal::kMinFlatLength;
|
|
64
67
|
using ::absl::cord_internal::kInlinedVectorSize;
|
65
68
|
using ::absl::cord_internal::kMaxBytesToCopy;
|
66
69
|
|
67
|
-
constexpr uint64_t Fibonacci(unsigned char n, uint64_t a = 0, uint64_t b = 1) {
|
68
|
-
return n == 0 ? a : Fibonacci(n - 1, b, a + b);
|
69
|
-
}
|
70
|
-
|
71
|
-
static_assert(Fibonacci(63) == 6557470319842,
|
72
|
-
"Fibonacci values computed incorrectly");
|
73
|
-
|
74
|
-
// Minimum length required for a given depth tree -- a tree is considered
|
75
|
-
// balanced if
|
76
|
-
// length(t) >= min_length[depth(t)]
|
77
|
-
// The root node depth is allowed to become twice as large to reduce rebalancing
|
78
|
-
// for larger strings (see IsRootBalanced).
|
79
|
-
static constexpr uint64_t min_length[] = {
|
80
|
-
Fibonacci(2), Fibonacci(3), Fibonacci(4), Fibonacci(5),
|
81
|
-
Fibonacci(6), Fibonacci(7), Fibonacci(8), Fibonacci(9),
|
82
|
-
Fibonacci(10), Fibonacci(11), Fibonacci(12), Fibonacci(13),
|
83
|
-
Fibonacci(14), Fibonacci(15), Fibonacci(16), Fibonacci(17),
|
84
|
-
Fibonacci(18), Fibonacci(19), Fibonacci(20), Fibonacci(21),
|
85
|
-
Fibonacci(22), Fibonacci(23), Fibonacci(24), Fibonacci(25),
|
86
|
-
Fibonacci(26), Fibonacci(27), Fibonacci(28), Fibonacci(29),
|
87
|
-
Fibonacci(30), Fibonacci(31), Fibonacci(32), Fibonacci(33),
|
88
|
-
Fibonacci(34), Fibonacci(35), Fibonacci(36), Fibonacci(37),
|
89
|
-
Fibonacci(38), Fibonacci(39), Fibonacci(40), Fibonacci(41),
|
90
|
-
Fibonacci(42), Fibonacci(43), Fibonacci(44), Fibonacci(45),
|
91
|
-
Fibonacci(46), Fibonacci(47),
|
92
|
-
0xffffffffffffffffull, // Avoid overflow
|
93
|
-
};
|
94
|
-
|
95
|
-
static const int kMinLengthSize = ABSL_ARRAYSIZE(min_length);
|
96
|
-
|
97
|
-
static inline bool btree_enabled() {
|
98
|
-
return cord_internal::cord_btree_enabled.load(
|
99
|
-
std::memory_order_relaxed);
|
100
|
-
}
|
101
|
-
|
102
|
-
static inline bool IsRootBalanced(CordRep* node) {
|
103
|
-
if (!node->IsConcat()) {
|
104
|
-
return true;
|
105
|
-
} else if (node->concat()->depth() <= 15) {
|
106
|
-
return true;
|
107
|
-
} else if (node->concat()->depth() > kMinLengthSize) {
|
108
|
-
return false;
|
109
|
-
} else {
|
110
|
-
// Allow depth to become twice as large as implied by fibonacci rule to
|
111
|
-
// reduce rebalancing for larger strings.
|
112
|
-
return (node->length >= min_length[node->concat()->depth() / 2]);
|
113
|
-
}
|
114
|
-
}
|
115
|
-
|
116
|
-
static CordRep* Rebalance(CordRep* node);
|
117
70
|
static void DumpNode(CordRep* rep, bool include_data, std::ostream* os,
|
118
71
|
int indent = 0);
|
119
72
|
static bool VerifyNode(CordRep* root, CordRep* start_node,
|
@@ -135,75 +88,6 @@ static inline CordRep* VerifyTree(CordRep* node) {
|
|
135
88
|
return node;
|
136
89
|
}
|
137
90
|
|
138
|
-
// Return the depth of a node
|
139
|
-
static int Depth(const CordRep* rep) {
|
140
|
-
if (rep->IsConcat()) {
|
141
|
-
return rep->concat()->depth();
|
142
|
-
} else {
|
143
|
-
return 0;
|
144
|
-
}
|
145
|
-
}
|
146
|
-
|
147
|
-
static void SetConcatChildren(CordRepConcat* concat, CordRep* left,
|
148
|
-
CordRep* right) {
|
149
|
-
concat->left = left;
|
150
|
-
concat->right = right;
|
151
|
-
|
152
|
-
concat->length = left->length + right->length;
|
153
|
-
concat->set_depth(1 + std::max(Depth(left), Depth(right)));
|
154
|
-
}
|
155
|
-
|
156
|
-
// Create a concatenation of the specified nodes.
|
157
|
-
// Does not change the refcounts of "left" and "right".
|
158
|
-
// The returned node has a refcount of 1.
|
159
|
-
static CordRep* RawConcat(CordRep* left, CordRep* right) {
|
160
|
-
// Avoid making degenerate concat nodes (one child is empty)
|
161
|
-
if (left == nullptr) return right;
|
162
|
-
if (right == nullptr) return left;
|
163
|
-
if (left->length == 0) {
|
164
|
-
CordRep::Unref(left);
|
165
|
-
return right;
|
166
|
-
}
|
167
|
-
if (right->length == 0) {
|
168
|
-
CordRep::Unref(right);
|
169
|
-
return left;
|
170
|
-
}
|
171
|
-
|
172
|
-
CordRepConcat* rep = new CordRepConcat();
|
173
|
-
rep->tag = cord_internal::CONCAT;
|
174
|
-
SetConcatChildren(rep, left, right);
|
175
|
-
|
176
|
-
return rep;
|
177
|
-
}
|
178
|
-
|
179
|
-
static CordRep* Concat(CordRep* left, CordRep* right) {
|
180
|
-
CordRep* rep = RawConcat(left, right);
|
181
|
-
if (rep != nullptr && !IsRootBalanced(rep)) {
|
182
|
-
rep = Rebalance(rep);
|
183
|
-
}
|
184
|
-
return VerifyTree(rep);
|
185
|
-
}
|
186
|
-
|
187
|
-
// Make a balanced tree out of an array of leaf nodes.
|
188
|
-
static CordRep* MakeBalancedTree(CordRep** reps, size_t n) {
|
189
|
-
// Make repeated passes over the array, merging adjacent pairs
|
190
|
-
// until we are left with just a single node.
|
191
|
-
while (n > 1) {
|
192
|
-
size_t dst = 0;
|
193
|
-
for (size_t src = 0; src < n; src += 2) {
|
194
|
-
if (src + 1 < n) {
|
195
|
-
reps[dst] = Concat(reps[src], reps[src + 1]);
|
196
|
-
} else {
|
197
|
-
reps[dst] = reps[src];
|
198
|
-
}
|
199
|
-
dst++;
|
200
|
-
}
|
201
|
-
n = dst;
|
202
|
-
}
|
203
|
-
|
204
|
-
return reps[0];
|
205
|
-
}
|
206
|
-
|
207
91
|
static CordRepFlat* CreateFlat(const char* data, size_t length,
|
208
92
|
size_t alloc_hint) {
|
209
93
|
CordRepFlat* flat = CordRepFlat::New(length + alloc_hint);
|
@@ -229,21 +113,7 @@ static CordRep* NewBtree(const char* data, size_t length, size_t alloc_hint) {
|
|
229
113
|
// The returned node has a refcount of 1.
|
230
114
|
static CordRep* NewTree(const char* data, size_t length, size_t alloc_hint) {
|
231
115
|
if (length == 0) return nullptr;
|
232
|
-
|
233
|
-
return NewBtree(data, length, alloc_hint);
|
234
|
-
}
|
235
|
-
absl::FixedArray<CordRep*> reps((length - 1) / kMaxFlatLength + 1);
|
236
|
-
size_t n = 0;
|
237
|
-
do {
|
238
|
-
const size_t len = std::min(length, kMaxFlatLength);
|
239
|
-
CordRepFlat* rep = CordRepFlat::New(len + alloc_hint);
|
240
|
-
rep->length = len;
|
241
|
-
memcpy(rep->Data(), data, len);
|
242
|
-
reps[n++] = VerifyTree(rep);
|
243
|
-
data += len;
|
244
|
-
length -= len;
|
245
|
-
} while (length != 0);
|
246
|
-
return MakeBalancedTree(reps.data(), n);
|
116
|
+
return NewBtree(data, length, alloc_hint);
|
247
117
|
}
|
248
118
|
|
249
119
|
namespace cord_internal {
|
@@ -258,22 +128,6 @@ void InitializeCordRepExternal(absl::string_view data, CordRepExternal* rep) {
|
|
258
128
|
|
259
129
|
} // namespace cord_internal
|
260
130
|
|
261
|
-
static CordRep* NewSubstring(CordRep* child, size_t offset, size_t length) {
|
262
|
-
// Never create empty substring nodes
|
263
|
-
if (length == 0) {
|
264
|
-
CordRep::Unref(child);
|
265
|
-
return nullptr;
|
266
|
-
} else {
|
267
|
-
CordRepSubstring* rep = new CordRepSubstring();
|
268
|
-
assert((offset + length) <= child->length);
|
269
|
-
rep->length = length;
|
270
|
-
rep->tag = cord_internal::SUBSTRING;
|
271
|
-
rep->start = offset;
|
272
|
-
rep->child = child;
|
273
|
-
return VerifyTree(rep);
|
274
|
-
}
|
275
|
-
}
|
276
|
-
|
277
131
|
// Creates a CordRep from the provided string. If the string is large enough,
|
278
132
|
// and not wasteful, we move the string into an external cord rep, preserving
|
279
133
|
// the already allocated string contents.
|
@@ -306,13 +160,14 @@ static CordRep* CordRepFromString(std::string&& src) {
|
|
306
160
|
// --------------------------------------------------------------------
|
307
161
|
// Cord::InlineRep functions
|
308
162
|
|
163
|
+
#ifdef ABSL_INTERNAL_NEED_REDUNDANT_CONSTEXPR_DECL
|
309
164
|
constexpr unsigned char Cord::InlineRep::kMaxInline;
|
165
|
+
#endif
|
310
166
|
|
311
|
-
inline void Cord::InlineRep::set_data(const char* data, size_t n
|
312
|
-
bool nullify_tail) {
|
167
|
+
inline void Cord::InlineRep::set_data(const char* data, size_t n) {
|
313
168
|
static_assert(kMaxInline == 15, "set_data is hard-coded for a length of 15");
|
314
169
|
|
315
|
-
cord_internal::SmallMemmove(data_.as_chars(), data, n
|
170
|
+
cord_internal::SmallMemmove<true>(data_.as_chars(), data, n);
|
316
171
|
set_inline_size(n);
|
317
172
|
}
|
318
173
|
|
@@ -341,7 +196,9 @@ inline void Cord::InlineRep::remove_prefix(size_t n) {
|
|
341
196
|
// Returns `rep` converted into a CordRepBtree.
|
342
197
|
// Directly returns `rep` if `rep` is already a CordRepBtree.
|
343
198
|
static CordRepBtree* ForceBtree(CordRep* rep) {
|
344
|
-
return rep->IsBtree()
|
199
|
+
return rep->IsBtree()
|
200
|
+
? rep->btree()
|
201
|
+
: CordRepBtree::Create(cord_internal::RemoveCrcNode(rep));
|
345
202
|
}
|
346
203
|
|
347
204
|
void Cord::InlineRep::AppendTreeToInlined(CordRep* tree,
|
@@ -349,11 +206,7 @@ void Cord::InlineRep::AppendTreeToInlined(CordRep* tree,
|
|
349
206
|
assert(!is_tree());
|
350
207
|
if (!data_.is_empty()) {
|
351
208
|
CordRepFlat* flat = MakeFlatWithExtraCapacity(0);
|
352
|
-
|
353
|
-
tree = CordRepBtree::Append(CordRepBtree::Create(flat), tree);
|
354
|
-
} else {
|
355
|
-
tree = Concat(flat, tree);
|
356
|
-
}
|
209
|
+
tree = CordRepBtree::Append(CordRepBtree::Create(flat), tree);
|
357
210
|
}
|
358
211
|
EmplaceTree(tree, method);
|
359
212
|
}
|
@@ -361,16 +214,14 @@ void Cord::InlineRep::AppendTreeToInlined(CordRep* tree,
|
|
361
214
|
void Cord::InlineRep::AppendTreeToTree(CordRep* tree, MethodIdentifier method) {
|
362
215
|
assert(is_tree());
|
363
216
|
const CordzUpdateScope scope(data_.cordz_info(), method);
|
364
|
-
|
365
|
-
tree = CordRepBtree::Append(ForceBtree(data_.as_tree()), tree);
|
366
|
-
} else {
|
367
|
-
tree = Concat(data_.as_tree(), tree);
|
368
|
-
}
|
217
|
+
tree = CordRepBtree::Append(ForceBtree(data_.as_tree()), tree);
|
369
218
|
SetTree(tree, scope);
|
370
219
|
}
|
371
220
|
|
372
221
|
void Cord::InlineRep::AppendTree(CordRep* tree, MethodIdentifier method) {
|
373
|
-
|
222
|
+
assert(tree != nullptr);
|
223
|
+
assert(tree->length != 0);
|
224
|
+
assert(!tree->IsCrc());
|
374
225
|
if (data_.is_tree()) {
|
375
226
|
AppendTreeToTree(tree, method);
|
376
227
|
} else {
|
@@ -383,11 +234,7 @@ void Cord::InlineRep::PrependTreeToInlined(CordRep* tree,
|
|
383
234
|
assert(!is_tree());
|
384
235
|
if (!data_.is_empty()) {
|
385
236
|
CordRepFlat* flat = MakeFlatWithExtraCapacity(0);
|
386
|
-
|
387
|
-
tree = CordRepBtree::Prepend(CordRepBtree::Create(flat), tree);
|
388
|
-
} else {
|
389
|
-
tree = Concat(tree, flat);
|
390
|
-
}
|
237
|
+
tree = CordRepBtree::Prepend(CordRepBtree::Create(flat), tree);
|
391
238
|
}
|
392
239
|
EmplaceTree(tree, method);
|
393
240
|
}
|
@@ -396,16 +243,14 @@ void Cord::InlineRep::PrependTreeToTree(CordRep* tree,
|
|
396
243
|
MethodIdentifier method) {
|
397
244
|
assert(is_tree());
|
398
245
|
const CordzUpdateScope scope(data_.cordz_info(), method);
|
399
|
-
|
400
|
-
tree = CordRepBtree::Prepend(ForceBtree(data_.as_tree()), tree);
|
401
|
-
} else {
|
402
|
-
tree = Concat(tree, data_.as_tree());
|
403
|
-
}
|
246
|
+
tree = CordRepBtree::Prepend(ForceBtree(data_.as_tree()), tree);
|
404
247
|
SetTree(tree, scope);
|
405
248
|
}
|
406
249
|
|
407
250
|
void Cord::InlineRep::PrependTree(CordRep* tree, MethodIdentifier method) {
|
408
251
|
assert(tree != nullptr);
|
252
|
+
assert(tree->length != 0);
|
253
|
+
assert(!tree->IsCrc());
|
409
254
|
if (data_.is_tree()) {
|
410
255
|
PrependTreeToTree(tree, method);
|
411
256
|
} else {
|
@@ -419,7 +264,7 @@ void Cord::InlineRep::PrependTree(CordRep* tree, MethodIdentifier method) {
|
|
419
264
|
// written to region and the actual size increase will be written to size.
|
420
265
|
static inline bool PrepareAppendRegion(CordRep* root, char** region,
|
421
266
|
size_t* size, size_t max_length) {
|
422
|
-
if (root->IsBtree() && root->refcount.
|
267
|
+
if (root->IsBtree() && root->refcount.IsOne()) {
|
423
268
|
Span<char> span = root->btree()->GetAppendBuffer(max_length);
|
424
269
|
if (!span.empty()) {
|
425
270
|
*region = span.data();
|
@@ -428,13 +273,8 @@ static inline bool PrepareAppendRegion(CordRep* root, char** region,
|
|
428
273
|
}
|
429
274
|
}
|
430
275
|
|
431
|
-
// Search down the right-hand path for a non-full FLAT node.
|
432
276
|
CordRep* dst = root;
|
433
|
-
|
434
|
-
dst = dst->concat()->right;
|
435
|
-
}
|
436
|
-
|
437
|
-
if (!dst->IsFlat() || !dst->refcount.IsMutable()) {
|
277
|
+
if (!dst->IsFlat() || !dst->refcount.IsOne()) {
|
438
278
|
*region = nullptr;
|
439
279
|
*size = 0;
|
440
280
|
return false;
|
@@ -448,12 +288,7 @@ static inline bool PrepareAppendRegion(CordRep* root, char** region,
|
|
448
288
|
return false;
|
449
289
|
}
|
450
290
|
|
451
|
-
size_t size_increase = std::min(capacity - in_use, max_length);
|
452
|
-
|
453
|
-
// We need to update the length fields for all nodes, including the leaf node.
|
454
|
-
for (CordRep* rep = root; rep != dst; rep = rep->concat()->right) {
|
455
|
-
rep->length += size_increase;
|
456
|
-
}
|
291
|
+
const size_t size_increase = std::min(capacity - in_use, max_length);
|
457
292
|
dst->length += size_increase;
|
458
293
|
|
459
294
|
*region = dst->flat()->Data() + in_use;
|
@@ -461,90 +296,6 @@ static inline bool PrepareAppendRegion(CordRep* root, char** region,
|
|
461
296
|
return true;
|
462
297
|
}
|
463
298
|
|
464
|
-
template <bool has_length>
|
465
|
-
void Cord::InlineRep::GetAppendRegion(char** region, size_t* size,
|
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);
|
477
|
-
return;
|
478
|
-
}
|
479
|
-
}
|
480
|
-
|
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);
|
486
|
-
return;
|
487
|
-
}
|
488
|
-
|
489
|
-
// Allocate new node.
|
490
|
-
CordRepFlat* new_node = CordRepFlat::New(extra);
|
491
|
-
new_node->length = std::min(new_node->Capacity(), length);
|
492
|
-
*region = new_node->Data();
|
493
|
-
*size = new_node->length;
|
494
|
-
|
495
|
-
if (btree_enabled()) {
|
496
|
-
rep = CordRepBtree::Append(ForceBtree(rep), new_node);
|
497
|
-
} else {
|
498
|
-
rep = Concat(rep, new_node);
|
499
|
-
}
|
500
|
-
CommitTree(root, rep, scope, method);
|
501
|
-
}
|
502
|
-
|
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;
|
511
|
-
}
|
512
|
-
if (rep->IsFlat()) {
|
513
|
-
*total_mem_usage += maybe_sub_size + rep->flat()->AllocatedSize();
|
514
|
-
return true;
|
515
|
-
}
|
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;
|
525
|
-
}
|
526
|
-
return false;
|
527
|
-
}
|
528
|
-
|
529
|
-
// If the rep is a leaf, this will increment the value at total_mem_usage and
|
530
|
-
// will return true.
|
531
|
-
static bool RepMemoryUsageLeaf(const CordRep* rep, size_t* total_mem_usage) {
|
532
|
-
if (rep->IsFlat()) {
|
533
|
-
*total_mem_usage += rep->flat()->AllocatedSize();
|
534
|
-
return true;
|
535
|
-
}
|
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;
|
543
|
-
return true;
|
544
|
-
}
|
545
|
-
return false;
|
546
|
-
}
|
547
|
-
|
548
299
|
void Cord::InlineRep::AssignSlow(const Cord::InlineRep& src) {
|
549
300
|
assert(&src != this);
|
550
301
|
assert(is_tree() || src.is_tree());
|
@@ -581,7 +332,7 @@ Cord::Cord(absl::string_view src, MethodIdentifier method)
|
|
581
332
|
: contents_(InlineData::kDefaultInit) {
|
582
333
|
const size_t n = src.size();
|
583
334
|
if (n <= InlineRep::kMaxInline) {
|
584
|
-
contents_.set_data(src.data(), n
|
335
|
+
contents_.set_data(src.data(), n);
|
585
336
|
} else {
|
586
337
|
CordRep* rep = NewTree(src.data(), n, 0);
|
587
338
|
contents_.EmplaceTree(rep, method);
|
@@ -591,7 +342,7 @@ Cord::Cord(absl::string_view src, MethodIdentifier method)
|
|
591
342
|
template <typename T, Cord::EnableIfString<T>>
|
592
343
|
Cord::Cord(T&& src) : contents_(InlineData::kDefaultInit) {
|
593
344
|
if (src.size() <= InlineRep::kMaxInline) {
|
594
|
-
contents_.set_data(src.data(), src.size()
|
345
|
+
contents_.set_data(src.data(), src.size());
|
595
346
|
} else {
|
596
347
|
CordRep* rep = CordRepFromString(std::forward<T>(src));
|
597
348
|
contents_.EmplaceTree(rep, CordzUpdateTracker::kConstructorString);
|
@@ -642,14 +393,14 @@ Cord& Cord::operator=(absl::string_view src) {
|
|
642
393
|
// - MaybeUntrackCord must be called before set_data() clobbers cordz_info.
|
643
394
|
// - set_data() must be called before Unref(tree) as it may reference tree.
|
644
395
|
if (tree != nullptr) CordzInfo::MaybeUntrackCord(contents_.cordz_info());
|
645
|
-
contents_.set_data(data, length
|
396
|
+
contents_.set_data(data, length);
|
646
397
|
if (tree != nullptr) CordRep::Unref(tree);
|
647
398
|
return *this;
|
648
399
|
}
|
649
400
|
if (tree != nullptr) {
|
650
401
|
CordzUpdateScope scope(contents_.cordz_info(), method);
|
651
402
|
if (tree->IsFlat() && tree->flat()->Capacity() >= length &&
|
652
|
-
tree->refcount.
|
403
|
+
tree->refcount.IsOne()) {
|
653
404
|
// Copy in place if the existing FLAT node is reusable.
|
654
405
|
memmove(tree->flat()->Data(), data, length);
|
655
406
|
tree->length = length;
|
@@ -675,6 +426,7 @@ void Cord::InlineRep::AppendArray(absl::string_view src,
|
|
675
426
|
const CordRep* const root = rep;
|
676
427
|
CordzUpdateScope scope(root ? cordz_info() : nullptr, method);
|
677
428
|
if (root != nullptr) {
|
429
|
+
rep = cord_internal::RemoveCrcNode(rep);
|
678
430
|
char* region;
|
679
431
|
if (PrepareAppendRegion(rep, ®ion, &appended, src.size())) {
|
680
432
|
memcpy(region, src.data(), appended);
|
@@ -705,27 +457,11 @@ void Cord::InlineRep::AppendArray(absl::string_view src,
|
|
705
457
|
return;
|
706
458
|
}
|
707
459
|
|
708
|
-
|
709
|
-
|
710
|
-
|
711
|
-
|
712
|
-
|
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()));
|
728
|
-
}
|
460
|
+
// TODO(b/192061034): keep legacy 10% growth rate: consider other rates.
|
461
|
+
rep = ForceBtree(rep);
|
462
|
+
const size_t min_growth = std::max<size_t>(rep->length / 10, src.size());
|
463
|
+
rep = CordRepBtree::Append(rep->btree(), src, min_growth - src.size());
|
464
|
+
|
729
465
|
CommitTree(root, rep, scope, method);
|
730
466
|
}
|
731
467
|
|
@@ -746,7 +482,8 @@ inline void Cord::AppendImpl(C&& src) {
|
|
746
482
|
// Since destination is empty, we can avoid allocating a node,
|
747
483
|
if (src.contents_.is_tree()) {
|
748
484
|
// by taking the tree directly
|
749
|
-
CordRep* rep =
|
485
|
+
CordRep* rep =
|
486
|
+
cord_internal::RemoveCrcNode(std::forward<C>(src).TakeRep());
|
750
487
|
contents_.EmplaceTree(rep, method);
|
751
488
|
} else {
|
752
489
|
// or copying over inline data
|
@@ -782,10 +519,50 @@ inline void Cord::AppendImpl(C&& src) {
|
|
782
519
|
}
|
783
520
|
|
784
521
|
// Guaranteed to be a tree (kMaxBytesToCopy > kInlinedSize)
|
785
|
-
CordRep* rep = std::forward<C>(src).TakeRep();
|
522
|
+
CordRep* rep = cord_internal::RemoveCrcNode(std::forward<C>(src).TakeRep());
|
786
523
|
contents_.AppendTree(rep, CordzUpdateTracker::kAppendCord);
|
787
524
|
}
|
788
525
|
|
526
|
+
static CordRep::ExtractResult ExtractAppendBuffer(CordRep* rep,
|
527
|
+
size_t min_capacity) {
|
528
|
+
switch (rep->tag) {
|
529
|
+
case cord_internal::BTREE:
|
530
|
+
return CordRepBtree::ExtractAppendBuffer(rep->btree(), min_capacity);
|
531
|
+
default:
|
532
|
+
if (rep->IsFlat() && rep->refcount.IsOne() &&
|
533
|
+
rep->flat()->Capacity() - rep->length >= min_capacity) {
|
534
|
+
return {nullptr, rep};
|
535
|
+
}
|
536
|
+
return {rep, nullptr};
|
537
|
+
}
|
538
|
+
}
|
539
|
+
|
540
|
+
static CordBuffer CreateAppendBuffer(InlineData& data, size_t capacity) {
|
541
|
+
// Watch out for overflow, people can ask for size_t::max().
|
542
|
+
const size_t size = data.inline_size();
|
543
|
+
capacity = (std::min)(std::numeric_limits<size_t>::max() - size, capacity);
|
544
|
+
CordBuffer buffer = CordBuffer::CreateWithDefaultLimit(size + capacity);
|
545
|
+
cord_internal::SmallMemmove(buffer.data(), data.as_chars(), size);
|
546
|
+
buffer.SetLength(size);
|
547
|
+
data = {};
|
548
|
+
return buffer;
|
549
|
+
}
|
550
|
+
|
551
|
+
CordBuffer Cord::GetAppendBufferSlowPath(size_t capacity, size_t min_capacity) {
|
552
|
+
auto constexpr method = CordzUpdateTracker::kGetAppendBuffer;
|
553
|
+
CordRep* tree = contents_.tree();
|
554
|
+
if (tree != nullptr) {
|
555
|
+
CordzUpdateScope scope(contents_.cordz_info(), method);
|
556
|
+
CordRep::ExtractResult result = ExtractAppendBuffer(tree, min_capacity);
|
557
|
+
if (result.extracted != nullptr) {
|
558
|
+
contents_.SetTreeOrEmpty(result.tree, scope);
|
559
|
+
return CordBuffer(result.extracted->flat());
|
560
|
+
}
|
561
|
+
return CordBuffer::CreateWithDefaultLimit(capacity);
|
562
|
+
}
|
563
|
+
return CreateAppendBuffer(contents_.data_, capacity);
|
564
|
+
}
|
565
|
+
|
789
566
|
void Cord::Append(const Cord& src) {
|
790
567
|
AppendImpl(src);
|
791
568
|
}
|
@@ -810,7 +587,8 @@ void Cord::Prepend(const Cord& src) {
|
|
810
587
|
CordRep* src_tree = src.contents_.tree();
|
811
588
|
if (src_tree != nullptr) {
|
812
589
|
CordRep::Ref(src_tree);
|
813
|
-
contents_.PrependTree(src_tree,
|
590
|
+
contents_.PrependTree(cord_internal::RemoveCrcNode(src_tree),
|
591
|
+
CordzUpdateTracker::kPrependCord);
|
814
592
|
return;
|
815
593
|
}
|
816
594
|
|
@@ -837,103 +615,45 @@ void Cord::PrependArray(absl::string_view src, MethodIdentifier method) {
|
|
837
615
|
contents_.PrependTree(rep, method);
|
838
616
|
}
|
839
617
|
|
840
|
-
|
841
|
-
|
842
|
-
|
843
|
-
|
618
|
+
void Cord::AppendPrecise(absl::string_view src, MethodIdentifier method) {
|
619
|
+
assert(!src.empty());
|
620
|
+
assert(src.size() <= cord_internal::kMaxFlatLength);
|
621
|
+
if (contents_.remaining_inline_capacity() >= src.size()) {
|
622
|
+
const size_t inline_length = contents_.inline_size();
|
623
|
+
memcpy(contents_.data_.as_chars() + inline_length, src.data(), src.size());
|
624
|
+
contents_.set_inline_size(inline_length + src.size());
|
844
625
|
} else {
|
845
|
-
|
846
|
-
contents_.PrependTree(rep, CordzUpdateTracker::kPrependString);
|
626
|
+
contents_.AppendTree(CordRepFlat::Create(src), method);
|
847
627
|
}
|
848
628
|
}
|
849
629
|
|
850
|
-
|
851
|
-
|
852
|
-
|
853
|
-
if (
|
854
|
-
|
855
|
-
|
856
|
-
|
857
|
-
|
858
|
-
|
859
|
-
|
860
|
-
// Push right to stack, descend left.
|
861
|
-
rhs_stack.push_back(node->concat()->right);
|
862
|
-
node = node->concat()->left;
|
863
|
-
} else {
|
864
|
-
// Drop left, descend right.
|
865
|
-
n -= node->concat()->left->length;
|
866
|
-
node = node->concat()->right;
|
867
|
-
}
|
868
|
-
}
|
869
|
-
assert(n <= node->length);
|
870
|
-
|
871
|
-
if (n == 0) {
|
872
|
-
CordRep::Ref(node);
|
630
|
+
void Cord::PrependPrecise(absl::string_view src, MethodIdentifier method) {
|
631
|
+
assert(!src.empty());
|
632
|
+
assert(src.size() <= cord_internal::kMaxFlatLength);
|
633
|
+
if (contents_.remaining_inline_capacity() >= src.size()) {
|
634
|
+
const size_t inline_length = contents_.inline_size();
|
635
|
+
char data[InlineRep::kMaxInline + 1] = {0};
|
636
|
+
memcpy(data, src.data(), src.size());
|
637
|
+
memcpy(data + src.size(), contents_.data(), inline_length);
|
638
|
+
memcpy(contents_.data_.as_chars(), data, InlineRep::kMaxInline + 1);
|
639
|
+
contents_.set_inline_size(inline_length + src.size());
|
873
640
|
} else {
|
874
|
-
|
875
|
-
size_t len = node->length - n;
|
876
|
-
if (node->IsSubstring()) {
|
877
|
-
// Consider in-place update of node, similar to in RemoveSuffixFrom().
|
878
|
-
start += node->substring()->start;
|
879
|
-
node = node->substring()->child;
|
880
|
-
}
|
881
|
-
node = NewSubstring(CordRep::Ref(node), start, len);
|
882
|
-
}
|
883
|
-
while (!rhs_stack.empty()) {
|
884
|
-
node = Concat(node, CordRep::Ref(rhs_stack.back()));
|
885
|
-
rhs_stack.pop_back();
|
641
|
+
contents_.PrependTree(CordRepFlat::Create(src), method);
|
886
642
|
}
|
887
|
-
return node;
|
888
643
|
}
|
889
644
|
|
890
|
-
|
891
|
-
|
892
|
-
|
893
|
-
|
894
|
-
if (n >= node->length) return nullptr;
|
895
|
-
if (n == 0) return CordRep::Ref(node);
|
896
|
-
absl::InlinedVector<CordRep*, kInlinedVectorSize> lhs_stack;
|
897
|
-
bool inplace_ok = node->refcount.IsMutable();
|
898
|
-
|
899
|
-
while (node->IsConcat()) {
|
900
|
-
assert(n <= node->length);
|
901
|
-
if (n < node->concat()->right->length) {
|
902
|
-
// Push left to stack, descend right.
|
903
|
-
lhs_stack.push_back(node->concat()->left);
|
904
|
-
node = node->concat()->right;
|
905
|
-
} else {
|
906
|
-
// Drop right, descend left.
|
907
|
-
n -= node->concat()->right->length;
|
908
|
-
node = node->concat()->left;
|
909
|
-
}
|
910
|
-
inplace_ok = inplace_ok && node->refcount.IsMutable();
|
911
|
-
}
|
912
|
-
assert(n <= node->length);
|
913
|
-
|
914
|
-
if (n == 0) {
|
915
|
-
CordRep::Ref(node);
|
916
|
-
} else if (inplace_ok && !node->IsExternal()) {
|
917
|
-
// Consider making a new buffer if the current node capacity is much
|
918
|
-
// larger than the new length.
|
919
|
-
CordRep::Ref(node);
|
920
|
-
node->length -= n;
|
645
|
+
template <typename T, Cord::EnableIfString<T>>
|
646
|
+
inline void Cord::Prepend(T&& src) {
|
647
|
+
if (src.size() <= kMaxBytesToCopy) {
|
648
|
+
Prepend(absl::string_view(src));
|
921
649
|
} else {
|
922
|
-
|
923
|
-
|
924
|
-
if (node->IsSubstring()) {
|
925
|
-
start = node->substring()->start;
|
926
|
-
node = node->substring()->child;
|
927
|
-
}
|
928
|
-
node = NewSubstring(CordRep::Ref(node), start, len);
|
929
|
-
}
|
930
|
-
while (!lhs_stack.empty()) {
|
931
|
-
node = Concat(CordRep::Ref(lhs_stack.back()), node);
|
932
|
-
lhs_stack.pop_back();
|
650
|
+
CordRep* rep = CordRepFromString(std::forward<T>(src));
|
651
|
+
contents_.PrependTree(rep, CordzUpdateTracker::kPrependString);
|
933
652
|
}
|
934
|
-
return node;
|
935
653
|
}
|
936
654
|
|
655
|
+
template void Cord::Prepend(std::string&& src);
|
656
|
+
|
937
657
|
void Cord::RemovePrefix(size_t n) {
|
938
658
|
ABSL_INTERNAL_CHECK(n <= size(),
|
939
659
|
absl::StrCat("Requested prefix size ", n,
|
@@ -944,14 +664,21 @@ void Cord::RemovePrefix(size_t n) {
|
|
944
664
|
} else {
|
945
665
|
auto constexpr method = CordzUpdateTracker::kRemovePrefix;
|
946
666
|
CordzUpdateScope scope(contents_.cordz_info(), method);
|
947
|
-
|
667
|
+
tree = cord_internal::RemoveCrcNode(tree);
|
668
|
+
if (n >= tree->length) {
|
669
|
+
CordRep::Unref(tree);
|
670
|
+
tree = nullptr;
|
671
|
+
} else if (tree->IsBtree()) {
|
948
672
|
CordRep* old = tree;
|
949
673
|
tree = tree->btree()->SubTree(n, tree->length - n);
|
950
674
|
CordRep::Unref(old);
|
675
|
+
} else if (tree->IsSubstring() && tree->refcount.IsOne()) {
|
676
|
+
tree->substring()->start += n;
|
677
|
+
tree->length -= n;
|
951
678
|
} else {
|
952
|
-
CordRep*
|
679
|
+
CordRep* rep = CordRepSubstring::Substring(tree, n, tree->length - n);
|
953
680
|
CordRep::Unref(tree);
|
954
|
-
tree =
|
681
|
+
tree = rep;
|
955
682
|
}
|
956
683
|
contents_.SetTreeOrEmpty(tree, scope);
|
957
684
|
}
|
@@ -967,68 +694,24 @@ void Cord::RemoveSuffix(size_t n) {
|
|
967
694
|
} else {
|
968
695
|
auto constexpr method = CordzUpdateTracker::kRemoveSuffix;
|
969
696
|
CordzUpdateScope scope(contents_.cordz_info(), method);
|
970
|
-
|
697
|
+
tree = cord_internal::RemoveCrcNode(tree);
|
698
|
+
if (n >= tree->length) {
|
699
|
+
CordRep::Unref(tree);
|
700
|
+
tree = nullptr;
|
701
|
+
} else if (tree->IsBtree()) {
|
971
702
|
tree = CordRepBtree::RemoveSuffix(tree->btree(), n);
|
703
|
+
} else if (!tree->IsExternal() && tree->refcount.IsOne()) {
|
704
|
+
assert(tree->IsFlat() || tree->IsSubstring());
|
705
|
+
tree->length -= n;
|
972
706
|
} else {
|
973
|
-
CordRep*
|
707
|
+
CordRep* rep = CordRepSubstring::Substring(tree, 0, tree->length - n);
|
974
708
|
CordRep::Unref(tree);
|
975
|
-
tree =
|
709
|
+
tree = rep;
|
976
710
|
}
|
977
711
|
contents_.SetTreeOrEmpty(tree, scope);
|
978
712
|
}
|
979
713
|
}
|
980
714
|
|
981
|
-
// Work item for NewSubRange().
|
982
|
-
struct SubRange {
|
983
|
-
SubRange(CordRep* a_node, size_t a_pos, size_t a_n)
|
984
|
-
: node(a_node), pos(a_pos), n(a_n) {}
|
985
|
-
CordRep* node; // nullptr means concat last 2 results.
|
986
|
-
size_t pos;
|
987
|
-
size_t n;
|
988
|
-
};
|
989
|
-
|
990
|
-
static CordRep* NewSubRange(CordRep* node, size_t pos, size_t n) {
|
991
|
-
absl::InlinedVector<CordRep*, kInlinedVectorSize> results;
|
992
|
-
absl::InlinedVector<SubRange, kInlinedVectorSize> todo;
|
993
|
-
todo.push_back(SubRange(node, pos, n));
|
994
|
-
do {
|
995
|
-
const SubRange& sr = todo.back();
|
996
|
-
node = sr.node;
|
997
|
-
pos = sr.pos;
|
998
|
-
n = sr.n;
|
999
|
-
todo.pop_back();
|
1000
|
-
|
1001
|
-
if (node == nullptr) {
|
1002
|
-
assert(results.size() >= 2);
|
1003
|
-
CordRep* right = results.back();
|
1004
|
-
results.pop_back();
|
1005
|
-
CordRep* left = results.back();
|
1006
|
-
results.pop_back();
|
1007
|
-
results.push_back(Concat(left, right));
|
1008
|
-
} else if (pos == 0 && n == node->length) {
|
1009
|
-
results.push_back(CordRep::Ref(node));
|
1010
|
-
} else if (!node->IsConcat()) {
|
1011
|
-
if (node->IsSubstring()) {
|
1012
|
-
pos += node->substring()->start;
|
1013
|
-
node = node->substring()->child;
|
1014
|
-
}
|
1015
|
-
results.push_back(NewSubstring(CordRep::Ref(node), pos, n));
|
1016
|
-
} else if (pos + n <= node->concat()->left->length) {
|
1017
|
-
todo.push_back(SubRange(node->concat()->left, pos, n));
|
1018
|
-
} else if (pos >= node->concat()->left->length) {
|
1019
|
-
pos -= node->concat()->left->length;
|
1020
|
-
todo.push_back(SubRange(node->concat()->right, pos, n));
|
1021
|
-
} else {
|
1022
|
-
size_t left_n = node->concat()->left->length - pos;
|
1023
|
-
todo.push_back(SubRange(nullptr, 0, 0)); // Concat()
|
1024
|
-
todo.push_back(SubRange(node->concat()->right, 0, n - left_n));
|
1025
|
-
todo.push_back(SubRange(node->concat()->left, pos, left_n));
|
1026
|
-
}
|
1027
|
-
} while (!todo.empty());
|
1028
|
-
assert(results.size() == 1);
|
1029
|
-
return results[0];
|
1030
|
-
}
|
1031
|
-
|
1032
715
|
Cord Cord::Subcord(size_t pos, size_t new_size) const {
|
1033
716
|
Cord sub_cord;
|
1034
717
|
size_t length = size();
|
@@ -1038,9 +721,7 @@ Cord Cord::Subcord(size_t pos, size_t new_size) const {
|
|
1038
721
|
|
1039
722
|
CordRep* tree = contents_.tree();
|
1040
723
|
if (tree == nullptr) {
|
1041
|
-
|
1042
|
-
// contents_ memory.
|
1043
|
-
sub_cord.contents_.set_data(contents_.data() + pos, new_size, false);
|
724
|
+
sub_cord.contents_.set_data(contents_.data() + pos, new_size);
|
1044
725
|
return sub_cord;
|
1045
726
|
}
|
1046
727
|
|
@@ -1060,156 +741,17 @@ Cord Cord::Subcord(size_t pos, size_t new_size) const {
|
|
1060
741
|
return sub_cord;
|
1061
742
|
}
|
1062
743
|
|
744
|
+
tree = cord_internal::SkipCrcNode(tree);
|
1063
745
|
if (tree->IsBtree()) {
|
1064
746
|
tree = tree->btree()->SubTree(pos, new_size);
|
1065
747
|
} else {
|
1066
|
-
tree =
|
748
|
+
tree = CordRepSubstring::Substring(tree, pos, new_size);
|
1067
749
|
}
|
1068
750
|
sub_cord.contents_.EmplaceTree(tree, contents_.data_,
|
1069
751
|
CordzUpdateTracker::kSubCord);
|
1070
752
|
return sub_cord;
|
1071
753
|
}
|
1072
754
|
|
1073
|
-
// --------------------------------------------------------------------
|
1074
|
-
// Balancing
|
1075
|
-
|
1076
|
-
class CordForest {
|
1077
|
-
public:
|
1078
|
-
explicit CordForest(size_t length)
|
1079
|
-
: root_length_(length), trees_(kMinLengthSize, nullptr) {}
|
1080
|
-
|
1081
|
-
void Build(CordRep* cord_root) {
|
1082
|
-
std::vector<CordRep*> pending = {cord_root};
|
1083
|
-
|
1084
|
-
while (!pending.empty()) {
|
1085
|
-
CordRep* node = pending.back();
|
1086
|
-
pending.pop_back();
|
1087
|
-
CheckNode(node);
|
1088
|
-
if (ABSL_PREDICT_FALSE(!node->IsConcat())) {
|
1089
|
-
AddNode(node);
|
1090
|
-
continue;
|
1091
|
-
}
|
1092
|
-
|
1093
|
-
CordRepConcat* concat_node = node->concat();
|
1094
|
-
if (concat_node->depth() >= kMinLengthSize ||
|
1095
|
-
concat_node->length < min_length[concat_node->depth()]) {
|
1096
|
-
pending.push_back(concat_node->right);
|
1097
|
-
pending.push_back(concat_node->left);
|
1098
|
-
|
1099
|
-
if (concat_node->refcount.IsOne()) {
|
1100
|
-
concat_node->left = concat_freelist_;
|
1101
|
-
concat_freelist_ = concat_node;
|
1102
|
-
} else {
|
1103
|
-
CordRep::Ref(concat_node->right);
|
1104
|
-
CordRep::Ref(concat_node->left);
|
1105
|
-
CordRep::Unref(concat_node);
|
1106
|
-
}
|
1107
|
-
} else {
|
1108
|
-
AddNode(node);
|
1109
|
-
}
|
1110
|
-
}
|
1111
|
-
}
|
1112
|
-
|
1113
|
-
CordRep* ConcatNodes() {
|
1114
|
-
CordRep* sum = nullptr;
|
1115
|
-
for (auto* node : trees_) {
|
1116
|
-
if (node == nullptr) continue;
|
1117
|
-
|
1118
|
-
sum = PrependNode(node, sum);
|
1119
|
-
root_length_ -= node->length;
|
1120
|
-
if (root_length_ == 0) break;
|
1121
|
-
}
|
1122
|
-
ABSL_INTERNAL_CHECK(sum != nullptr, "Failed to locate sum node");
|
1123
|
-
return VerifyTree(sum);
|
1124
|
-
}
|
1125
|
-
|
1126
|
-
private:
|
1127
|
-
CordRep* AppendNode(CordRep* node, CordRep* sum) {
|
1128
|
-
return (sum == nullptr) ? node : MakeConcat(sum, node);
|
1129
|
-
}
|
1130
|
-
|
1131
|
-
CordRep* PrependNode(CordRep* node, CordRep* sum) {
|
1132
|
-
return (sum == nullptr) ? node : MakeConcat(node, sum);
|
1133
|
-
}
|
1134
|
-
|
1135
|
-
void AddNode(CordRep* node) {
|
1136
|
-
CordRep* sum = nullptr;
|
1137
|
-
|
1138
|
-
// Collect together everything with which we will merge with node
|
1139
|
-
int i = 0;
|
1140
|
-
for (; node->length > min_length[i + 1]; ++i) {
|
1141
|
-
auto& tree_at_i = trees_[i];
|
1142
|
-
|
1143
|
-
if (tree_at_i == nullptr) continue;
|
1144
|
-
sum = PrependNode(tree_at_i, sum);
|
1145
|
-
tree_at_i = nullptr;
|
1146
|
-
}
|
1147
|
-
|
1148
|
-
sum = AppendNode(node, sum);
|
1149
|
-
|
1150
|
-
// Insert sum into appropriate place in the forest
|
1151
|
-
for (; sum->length >= min_length[i]; ++i) {
|
1152
|
-
auto& tree_at_i = trees_[i];
|
1153
|
-
if (tree_at_i == nullptr) continue;
|
1154
|
-
|
1155
|
-
sum = MakeConcat(tree_at_i, sum);
|
1156
|
-
tree_at_i = nullptr;
|
1157
|
-
}
|
1158
|
-
|
1159
|
-
// min_length[0] == 1, which means sum->length >= min_length[0]
|
1160
|
-
assert(i > 0);
|
1161
|
-
trees_[i - 1] = sum;
|
1162
|
-
}
|
1163
|
-
|
1164
|
-
// Make concat node trying to resue existing CordRepConcat nodes we
|
1165
|
-
// already collected in the concat_freelist_.
|
1166
|
-
CordRep* MakeConcat(CordRep* left, CordRep* right) {
|
1167
|
-
if (concat_freelist_ == nullptr) return RawConcat(left, right);
|
1168
|
-
|
1169
|
-
CordRepConcat* rep = concat_freelist_;
|
1170
|
-
if (concat_freelist_->left == nullptr) {
|
1171
|
-
concat_freelist_ = nullptr;
|
1172
|
-
} else {
|
1173
|
-
concat_freelist_ = concat_freelist_->left->concat();
|
1174
|
-
}
|
1175
|
-
SetConcatChildren(rep, left, right);
|
1176
|
-
|
1177
|
-
return rep;
|
1178
|
-
}
|
1179
|
-
|
1180
|
-
static void CheckNode(CordRep* node) {
|
1181
|
-
ABSL_INTERNAL_CHECK(node->length != 0u, "");
|
1182
|
-
if (node->IsConcat()) {
|
1183
|
-
ABSL_INTERNAL_CHECK(node->concat()->left != nullptr, "");
|
1184
|
-
ABSL_INTERNAL_CHECK(node->concat()->right != nullptr, "");
|
1185
|
-
ABSL_INTERNAL_CHECK(node->length == (node->concat()->left->length +
|
1186
|
-
node->concat()->right->length),
|
1187
|
-
"");
|
1188
|
-
}
|
1189
|
-
}
|
1190
|
-
|
1191
|
-
size_t root_length_;
|
1192
|
-
|
1193
|
-
// use an inlined vector instead of a flat array to get bounds checking
|
1194
|
-
absl::InlinedVector<CordRep*, kInlinedVectorSize> trees_;
|
1195
|
-
|
1196
|
-
// List of concat nodes we can re-use for Cord balancing.
|
1197
|
-
CordRepConcat* concat_freelist_ = nullptr;
|
1198
|
-
};
|
1199
|
-
|
1200
|
-
static CordRep* Rebalance(CordRep* node) {
|
1201
|
-
VerifyTree(node);
|
1202
|
-
assert(node->IsConcat());
|
1203
|
-
|
1204
|
-
if (node->length == 0) {
|
1205
|
-
return nullptr;
|
1206
|
-
}
|
1207
|
-
|
1208
|
-
CordForest forest(node->length);
|
1209
|
-
forest.Build(node);
|
1210
|
-
return forest.ConcatNodes();
|
1211
|
-
}
|
1212
|
-
|
1213
755
|
// --------------------------------------------------------------------
|
1214
756
|
// Comparators
|
1215
757
|
|
@@ -1256,7 +798,7 @@ inline absl::string_view Cord::InlineRep::FindFlatStartPiece() const {
|
|
1256
798
|
return absl::string_view(data_.as_chars(), data_.inline_size());
|
1257
799
|
}
|
1258
800
|
|
1259
|
-
CordRep* node = tree();
|
801
|
+
CordRep* node = cord_internal::SkipCrcNode(tree());
|
1260
802
|
if (node->IsFlat()) {
|
1261
803
|
return absl::string_view(node->flat()->Data(), node->length);
|
1262
804
|
}
|
@@ -1274,11 +816,6 @@ inline absl::string_view Cord::InlineRep::FindFlatStartPiece() const {
|
|
1274
816
|
return tree->Data(tree->begin());
|
1275
817
|
}
|
1276
818
|
|
1277
|
-
// Walk down the left branches until we hit a non-CONCAT node.
|
1278
|
-
while (node->IsConcat()) {
|
1279
|
-
node = node->concat()->left;
|
1280
|
-
}
|
1281
|
-
|
1282
819
|
// Get the child node if we encounter a SUBSTRING.
|
1283
820
|
size_t offset = 0;
|
1284
821
|
size_t length = node->length;
|
@@ -1298,6 +835,28 @@ inline absl::string_view Cord::InlineRep::FindFlatStartPiece() const {
|
|
1298
835
|
return absl::string_view(node->external()->base + offset, length);
|
1299
836
|
}
|
1300
837
|
|
838
|
+
void Cord::SetExpectedChecksum(uint32_t crc) {
|
839
|
+
auto constexpr method = CordzUpdateTracker::kSetExpectedChecksum;
|
840
|
+
if (empty()) return;
|
841
|
+
|
842
|
+
if (!contents_.is_tree()) {
|
843
|
+
CordRep* rep = contents_.MakeFlatWithExtraCapacity(0);
|
844
|
+
rep = CordRepCrc::New(rep, crc);
|
845
|
+
contents_.EmplaceTree(rep, method);
|
846
|
+
} else {
|
847
|
+
const CordzUpdateScope scope(contents_.data_.cordz_info(), method);
|
848
|
+
CordRep* rep = CordRepCrc::New(contents_.data_.as_tree(), crc);
|
849
|
+
contents_.SetTree(rep, scope);
|
850
|
+
}
|
851
|
+
}
|
852
|
+
|
853
|
+
absl::optional<uint32_t> Cord::ExpectedChecksum() const {
|
854
|
+
if (!contents_.is_tree() || !contents_.tree()->IsCrc()) {
|
855
|
+
return absl::nullopt;
|
856
|
+
}
|
857
|
+
return contents_.tree()->crc()->crc;
|
858
|
+
}
|
859
|
+
|
1301
860
|
inline int Cord::CompareSlowPath(absl::string_view rhs, size_t compared_size,
|
1302
861
|
size_t size_to_compare) const {
|
1303
862
|
auto advance = [](Cord::ChunkIterator* it, absl::string_view* chunk) {
|
@@ -1473,42 +1032,6 @@ void Cord::CopyToArraySlowPath(char* dst) const {
|
|
1473
1032
|
}
|
1474
1033
|
}
|
1475
1034
|
|
1476
|
-
Cord::ChunkIterator& Cord::ChunkIterator::AdvanceStack() {
|
1477
|
-
auto& stack_of_right_children = stack_of_right_children_;
|
1478
|
-
if (stack_of_right_children.empty()) {
|
1479
|
-
assert(!current_chunk_.empty()); // Called on invalid iterator.
|
1480
|
-
// We have reached the end of the Cord.
|
1481
|
-
return *this;
|
1482
|
-
}
|
1483
|
-
|
1484
|
-
// Process the next node on the stack.
|
1485
|
-
CordRep* node = stack_of_right_children.back();
|
1486
|
-
stack_of_right_children.pop_back();
|
1487
|
-
|
1488
|
-
// Walk down the left branches until we hit a non-CONCAT node. Save the
|
1489
|
-
// right children to the stack for subsequent traversal.
|
1490
|
-
while (node->IsConcat()) {
|
1491
|
-
stack_of_right_children.push_back(node->concat()->right);
|
1492
|
-
node = node->concat()->left;
|
1493
|
-
}
|
1494
|
-
|
1495
|
-
// Get the child node if we encounter a SUBSTRING.
|
1496
|
-
size_t offset = 0;
|
1497
|
-
size_t length = node->length;
|
1498
|
-
if (node->IsSubstring()) {
|
1499
|
-
offset = node->substring()->start;
|
1500
|
-
node = node->substring()->child;
|
1501
|
-
}
|
1502
|
-
|
1503
|
-
assert(node->IsExternal() || node->IsFlat());
|
1504
|
-
assert(length != 0);
|
1505
|
-
const char* data =
|
1506
|
-
node->IsExternal() ? node->external()->base : node->flat()->Data();
|
1507
|
-
current_chunk_ = absl::string_view(data + offset, length);
|
1508
|
-
current_leaf_ = node;
|
1509
|
-
return *this;
|
1510
|
-
}
|
1511
|
-
|
1512
1035
|
Cord Cord::ChunkIterator::AdvanceAndReadBytes(size_t n) {
|
1513
1036
|
ABSL_HARDENING_ASSERT(bytes_remaining_ >= n &&
|
1514
1037
|
"Attempted to iterate past `end()`");
|
@@ -1551,166 +1074,33 @@ Cord Cord::ChunkIterator::AdvanceAndReadBytes(size_t n) {
|
|
1551
1074
|
return subcord;
|
1552
1075
|
}
|
1553
1076
|
|
1554
|
-
|
1555
|
-
if (n < current_chunk_.size()) {
|
1556
|
-
// Range to read is a proper subrange of the current chunk.
|
1557
|
-
assert(current_leaf_ != nullptr);
|
1558
|
-
CordRep* subnode = CordRep::Ref(current_leaf_);
|
1559
|
-
const char* data = subnode->IsExternal() ? subnode->external()->base
|
1560
|
-
: subnode->flat()->Data();
|
1561
|
-
subnode = NewSubstring(subnode, current_chunk_.data() - data, n);
|
1562
|
-
subcord.contents_.EmplaceTree(VerifyTree(subnode), method);
|
1563
|
-
RemoveChunkPrefix(n);
|
1564
|
-
return subcord;
|
1565
|
-
}
|
1566
|
-
|
1567
|
-
// Range to read begins with a proper subrange of the current chunk.
|
1568
|
-
assert(!current_chunk_.empty());
|
1077
|
+
// Short circuit if reading the entire data edge.
|
1569
1078
|
assert(current_leaf_ != nullptr);
|
1570
|
-
|
1571
|
-
|
1572
|
-
|
1573
|
-
|
1574
|
-
|
1575
|
-
current_chunk_.size());
|
1576
|
-
}
|
1577
|
-
n -= current_chunk_.size();
|
1578
|
-
bytes_remaining_ -= current_chunk_.size();
|
1579
|
-
|
1580
|
-
// Process the next node(s) on the stack, reading whole subtrees depending on
|
1581
|
-
// their length and how many bytes we are advancing.
|
1582
|
-
CordRep* node = nullptr;
|
1583
|
-
while (!stack_of_right_children.empty()) {
|
1584
|
-
node = stack_of_right_children.back();
|
1585
|
-
stack_of_right_children.pop_back();
|
1586
|
-
if (node->length > n) break;
|
1587
|
-
// TODO(qrczak): This might unnecessarily recreate existing concat nodes.
|
1588
|
-
// Avoiding that would need pretty complicated logic (instead of
|
1589
|
-
// current_leaf, keep current_subtree_ which points to the highest node
|
1590
|
-
// such that the current leaf can be found on the path of left children
|
1591
|
-
// starting from current_subtree_; delay creating subnode while node is
|
1592
|
-
// below current_subtree_; find the proper node along the path of left
|
1593
|
-
// children starting from current_subtree_ if this loop exits while staying
|
1594
|
-
// below current_subtree_; etc.; alternatively, push parents instead of
|
1595
|
-
// right children on the stack).
|
1596
|
-
subnode = Concat(subnode, CordRep::Ref(node));
|
1597
|
-
n -= node->length;
|
1598
|
-
bytes_remaining_ -= node->length;
|
1599
|
-
node = nullptr;
|
1600
|
-
}
|
1601
|
-
|
1602
|
-
if (node == nullptr) {
|
1603
|
-
// We have reached the end of the Cord.
|
1604
|
-
assert(bytes_remaining_ == 0);
|
1605
|
-
subcord.contents_.EmplaceTree(VerifyTree(subnode), method);
|
1079
|
+
if (n == current_leaf_->length) {
|
1080
|
+
bytes_remaining_ = 0;
|
1081
|
+
current_chunk_ = {};
|
1082
|
+
CordRep* tree = CordRep::Ref(current_leaf_);
|
1083
|
+
subcord.contents_.EmplaceTree(VerifyTree(tree), method);
|
1606
1084
|
return subcord;
|
1607
1085
|
}
|
1608
1086
|
|
1609
|
-
//
|
1610
|
-
//
|
1611
|
-
|
1612
|
-
|
1613
|
-
|
1614
|
-
|
1615
|
-
|
1616
|
-
|
1617
|
-
|
1618
|
-
subnode = Concat(subnode, CordRep::Ref(node->concat()->left));
|
1619
|
-
n -= node->concat()->left->length;
|
1620
|
-
bytes_remaining_ -= node->concat()->left->length;
|
1621
|
-
node = node->concat()->right;
|
1622
|
-
}
|
1623
|
-
}
|
1624
|
-
|
1625
|
-
// Get the child node if we encounter a SUBSTRING.
|
1626
|
-
size_t offset = 0;
|
1627
|
-
size_t length = node->length;
|
1628
|
-
if (node->IsSubstring()) {
|
1629
|
-
offset = node->substring()->start;
|
1630
|
-
node = node->substring()->child;
|
1631
|
-
}
|
1087
|
+
// From this point on, we need a partial substring node.
|
1088
|
+
// Get pointer to the underlying flat or external data payload and
|
1089
|
+
// compute data pointer and offset into current flat or external.
|
1090
|
+
CordRep* payload = current_leaf_->IsSubstring()
|
1091
|
+
? current_leaf_->substring()->child
|
1092
|
+
: current_leaf_;
|
1093
|
+
const char* data = payload->IsExternal() ? payload->external()->base
|
1094
|
+
: payload->flat()->Data();
|
1095
|
+
const size_t offset = current_chunk_.data() - data;
|
1632
1096
|
|
1633
|
-
|
1634
|
-
|
1635
|
-
assert(node->IsExternal() || node->IsFlat());
|
1636
|
-
assert(length > n);
|
1637
|
-
if (n > 0) {
|
1638
|
-
subnode = Concat(subnode, NewSubstring(CordRep::Ref(node), offset, n));
|
1639
|
-
}
|
1640
|
-
const char* data =
|
1641
|
-
node->IsExternal() ? node->external()->base : node->flat()->Data();
|
1642
|
-
current_chunk_ = absl::string_view(data + offset + n, length - n);
|
1643
|
-
current_leaf_ = node;
|
1097
|
+
auto* tree = CordRepSubstring::Substring(payload, offset, n);
|
1098
|
+
subcord.contents_.EmplaceTree(VerifyTree(tree), method);
|
1644
1099
|
bytes_remaining_ -= n;
|
1645
|
-
|
1100
|
+
current_chunk_.remove_prefix(n);
|
1646
1101
|
return subcord;
|
1647
1102
|
}
|
1648
1103
|
|
1649
|
-
void Cord::ChunkIterator::AdvanceBytesSlowPath(size_t n) {
|
1650
|
-
assert(bytes_remaining_ >= n && "Attempted to iterate past `end()`");
|
1651
|
-
assert(n >= current_chunk_.size()); // This should only be called when
|
1652
|
-
// iterating to a new node.
|
1653
|
-
|
1654
|
-
n -= current_chunk_.size();
|
1655
|
-
bytes_remaining_ -= current_chunk_.size();
|
1656
|
-
|
1657
|
-
if (stack_of_right_children_.empty()) {
|
1658
|
-
// We have reached the end of the Cord.
|
1659
|
-
assert(bytes_remaining_ == 0);
|
1660
|
-
return;
|
1661
|
-
}
|
1662
|
-
|
1663
|
-
// Process the next node(s) on the stack, skipping whole subtrees depending on
|
1664
|
-
// their length and how many bytes we are advancing.
|
1665
|
-
CordRep* node = nullptr;
|
1666
|
-
auto& stack_of_right_children = stack_of_right_children_;
|
1667
|
-
while (!stack_of_right_children.empty()) {
|
1668
|
-
node = stack_of_right_children.back();
|
1669
|
-
stack_of_right_children.pop_back();
|
1670
|
-
if (node->length > n) break;
|
1671
|
-
n -= node->length;
|
1672
|
-
bytes_remaining_ -= node->length;
|
1673
|
-
node = nullptr;
|
1674
|
-
}
|
1675
|
-
|
1676
|
-
if (node == nullptr) {
|
1677
|
-
// We have reached the end of the Cord.
|
1678
|
-
assert(bytes_remaining_ == 0);
|
1679
|
-
return;
|
1680
|
-
}
|
1681
|
-
|
1682
|
-
// Walk down the appropriate branches until we hit a non-CONCAT node. Save the
|
1683
|
-
// right children to the stack for subsequent traversal.
|
1684
|
-
while (node->IsConcat()) {
|
1685
|
-
if (node->concat()->left->length > n) {
|
1686
|
-
// Push right, descend left.
|
1687
|
-
stack_of_right_children.push_back(node->concat()->right);
|
1688
|
-
node = node->concat()->left;
|
1689
|
-
} else {
|
1690
|
-
// Skip left, descend right.
|
1691
|
-
n -= node->concat()->left->length;
|
1692
|
-
bytes_remaining_ -= node->concat()->left->length;
|
1693
|
-
node = node->concat()->right;
|
1694
|
-
}
|
1695
|
-
}
|
1696
|
-
|
1697
|
-
// Get the child node if we encounter a SUBSTRING.
|
1698
|
-
size_t offset = 0;
|
1699
|
-
size_t length = node->length;
|
1700
|
-
if (node->IsSubstring()) {
|
1701
|
-
offset = node->substring()->start;
|
1702
|
-
node = node->substring()->child;
|
1703
|
-
}
|
1704
|
-
|
1705
|
-
assert(node->IsExternal() || node->IsFlat());
|
1706
|
-
assert(length > n);
|
1707
|
-
const char* data =
|
1708
|
-
node->IsExternal() ? node->external()->base : node->flat()->Data();
|
1709
|
-
current_chunk_ = absl::string_view(data + offset + n, length - n);
|
1710
|
-
current_leaf_ = node;
|
1711
|
-
bytes_remaining_ -= n;
|
1712
|
-
}
|
1713
|
-
|
1714
1104
|
char Cord::operator[](size_t i) const {
|
1715
1105
|
ABSL_HARDENING_ASSERT(i < size());
|
1716
1106
|
size_t offset = i;
|
@@ -1718,6 +1108,7 @@ char Cord::operator[](size_t i) const {
|
|
1718
1108
|
if (rep == nullptr) {
|
1719
1109
|
return contents_.data()[i];
|
1720
1110
|
}
|
1111
|
+
rep = cord_internal::SkipCrcNode(rep);
|
1721
1112
|
while (true) {
|
1722
1113
|
assert(rep != nullptr);
|
1723
1114
|
assert(offset < rep->length);
|
@@ -1729,16 +1120,6 @@ char Cord::operator[](size_t i) const {
|
|
1729
1120
|
} else if (rep->IsExternal()) {
|
1730
1121
|
// Get the "i"th character from the external array.
|
1731
1122
|
return rep->external()->base[offset];
|
1732
|
-
} else if (rep->IsConcat()) {
|
1733
|
-
// Recursively branch to the side of the concatenation that the "i"th
|
1734
|
-
// character is on.
|
1735
|
-
size_t left_length = rep->concat()->left->length;
|
1736
|
-
if (offset < left_length) {
|
1737
|
-
rep = rep->concat()->left;
|
1738
|
-
} else {
|
1739
|
-
offset -= left_length;
|
1740
|
-
rep = rep->concat()->right;
|
1741
|
-
}
|
1742
1123
|
} else {
|
1743
1124
|
// This must be a substring a node, so bypass it to get to the child.
|
1744
1125
|
assert(rep->IsSubstring());
|
@@ -1778,6 +1159,7 @@ absl::string_view Cord::FlattenSlowPath() {
|
|
1778
1159
|
|
1779
1160
|
/* static */ bool Cord::GetFlatAux(CordRep* rep, absl::string_view* fragment) {
|
1780
1161
|
assert(rep != nullptr);
|
1162
|
+
rep = cord_internal::SkipCrcNode(rep);
|
1781
1163
|
if (rep->IsFlat()) {
|
1782
1164
|
*fragment = absl::string_view(rep->flat()->Data(), rep->length);
|
1783
1165
|
return true;
|
@@ -1807,6 +1189,9 @@ absl::string_view Cord::FlattenSlowPath() {
|
|
1807
1189
|
/* static */ void Cord::ForEachChunkAux(
|
1808
1190
|
absl::cord_internal::CordRep* rep,
|
1809
1191
|
absl::FunctionRef<void(absl::string_view)> callback) {
|
1192
|
+
assert(rep != nullptr);
|
1193
|
+
rep = cord_internal::SkipCrcNode(rep);
|
1194
|
+
|
1810
1195
|
if (rep->IsBtree()) {
|
1811
1196
|
ChunkIterator it(rep), end;
|
1812
1197
|
while (it != end) {
|
@@ -1816,44 +1201,13 @@ absl::string_view Cord::FlattenSlowPath() {
|
|
1816
1201
|
return;
|
1817
1202
|
}
|
1818
1203
|
|
1819
|
-
|
1820
|
-
|
1821
|
-
|
1822
|
-
|
1823
|
-
|
1824
|
-
|
1825
|
-
|
1826
|
-
if (current_node->IsConcat()) {
|
1827
|
-
if (stack_pos == stack_max) {
|
1828
|
-
// There's no more room on our stack array to add another right branch,
|
1829
|
-
// and the idea is to avoid allocations, so call this function
|
1830
|
-
// recursively to navigate this subtree further. (This is not something
|
1831
|
-
// we expect to happen in practice).
|
1832
|
-
ForEachChunkAux(current_node, callback);
|
1833
|
-
|
1834
|
-
// Pop the next right branch and iterate.
|
1835
|
-
current_node = stack[--stack_pos];
|
1836
|
-
continue;
|
1837
|
-
} else {
|
1838
|
-
// Save the right branch for later traversal and continue down the left
|
1839
|
-
// branch.
|
1840
|
-
stack[stack_pos++] = current_node->concat()->right;
|
1841
|
-
current_node = current_node->concat()->left;
|
1842
|
-
continue;
|
1843
|
-
}
|
1844
|
-
}
|
1845
|
-
// This is a leaf node, so invoke our callback.
|
1846
|
-
absl::string_view chunk;
|
1847
|
-
bool success = GetFlatAux(current_node, &chunk);
|
1848
|
-
assert(success);
|
1849
|
-
if (success) {
|
1850
|
-
callback(chunk);
|
1851
|
-
}
|
1852
|
-
if (stack_pos == 0) {
|
1853
|
-
// end of traversal
|
1854
|
-
return;
|
1855
|
-
}
|
1856
|
-
current_node = stack[--stack_pos];
|
1204
|
+
// This is a leaf node, so invoke our callback.
|
1205
|
+
absl::cord_internal::CordRep* current_node = cord_internal::SkipCrcNode(rep);
|
1206
|
+
absl::string_view chunk;
|
1207
|
+
bool success = GetFlatAux(current_node, &chunk);
|
1208
|
+
assert(success);
|
1209
|
+
if (success) {
|
1210
|
+
callback(chunk);
|
1857
1211
|
}
|
1858
1212
|
}
|
1859
1213
|
|
@@ -1868,14 +1222,11 @@ static void DumpNode(CordRep* rep, bool include_data, std::ostream* os,
|
|
1868
1222
|
*os << " [";
|
1869
1223
|
if (include_data) *os << static_cast<void*>(rep);
|
1870
1224
|
*os << "]";
|
1871
|
-
*os << " " << (IsRootBalanced(rep) ? 'b' : 'u');
|
1872
1225
|
*os << " " << std::setw(indent) << "";
|
1873
|
-
if (rep->
|
1874
|
-
*os << "
|
1226
|
+
if (rep->IsCrc()) {
|
1227
|
+
*os << "CRC crc=" << rep->crc()->crc << "\n";
|
1875
1228
|
indent += kIndentStep;
|
1876
|
-
|
1877
|
-
stack.push_back(rep->concat()->right);
|
1878
|
-
rep = rep->concat()->left;
|
1229
|
+
rep = rep->crc()->child;
|
1879
1230
|
} else if (rep->IsSubstring()) {
|
1880
1231
|
*os << "SUBSTRING @ " << rep->substring()->start << "\n";
|
1881
1232
|
indent += kIndentStep;
|
@@ -1912,7 +1263,7 @@ static std::string ReportError(CordRep* root, CordRep* node) {
|
|
1912
1263
|
}
|
1913
1264
|
|
1914
1265
|
static bool VerifyNode(CordRep* root, CordRep* start_node,
|
1915
|
-
bool full_validation) {
|
1266
|
+
bool /* full_validation */) {
|
1916
1267
|
absl::InlinedVector<CordRep*, 2> worklist;
|
1917
1268
|
worklist.push_back(start_node);
|
1918
1269
|
do {
|
@@ -1922,21 +1273,10 @@ static bool VerifyNode(CordRep* root, CordRep* start_node,
|
|
1922
1273
|
ABSL_INTERNAL_CHECK(node != nullptr, ReportError(root, node));
|
1923
1274
|
if (node != root) {
|
1924
1275
|
ABSL_INTERNAL_CHECK(node->length != 0, ReportError(root, node));
|
1276
|
+
ABSL_INTERNAL_CHECK(!node->IsCrc(), ReportError(root, node));
|
1925
1277
|
}
|
1926
1278
|
|
1927
|
-
if (node->
|
1928
|
-
ABSL_INTERNAL_CHECK(node->concat()->left != nullptr,
|
1929
|
-
ReportError(root, node));
|
1930
|
-
ABSL_INTERNAL_CHECK(node->concat()->right != nullptr,
|
1931
|
-
ReportError(root, node));
|
1932
|
-
ABSL_INTERNAL_CHECK((node->length == node->concat()->left->length +
|
1933
|
-
node->concat()->right->length),
|
1934
|
-
ReportError(root, node));
|
1935
|
-
if (full_validation) {
|
1936
|
-
worklist.push_back(node->concat()->right);
|
1937
|
-
worklist.push_back(node->concat()->left);
|
1938
|
-
}
|
1939
|
-
} else if (node->IsFlat()) {
|
1279
|
+
if (node->IsFlat()) {
|
1940
1280
|
ABSL_INTERNAL_CHECK(node->length <= node->flat()->Capacity(),
|
1941
1281
|
ReportError(root, node));
|
1942
1282
|
} else if (node->IsExternal()) {
|
@@ -1949,75 +1289,17 @@ static bool VerifyNode(CordRep* root, CordRep* start_node,
|
|
1949
1289
|
ABSL_INTERNAL_CHECK(node->substring()->start + node->length <=
|
1950
1290
|
node->substring()->child->length,
|
1951
1291
|
ReportError(root, node));
|
1292
|
+
} else if (node->IsCrc()) {
|
1293
|
+
ABSL_INTERNAL_CHECK(node->crc()->child != nullptr,
|
1294
|
+
ReportError(root, node));
|
1295
|
+
ABSL_INTERNAL_CHECK(node->crc()->length == node->crc()->child->length,
|
1296
|
+
ReportError(root, node));
|
1297
|
+
worklist.push_back(node->crc()->child);
|
1952
1298
|
}
|
1953
1299
|
} while (!worklist.empty());
|
1954
1300
|
return true;
|
1955
1301
|
}
|
1956
1302
|
|
1957
|
-
// Traverses the tree and computes the total memory allocated.
|
1958
|
-
/* static */ size_t Cord::MemoryUsageAux(const CordRep* rep) {
|
1959
|
-
size_t total_mem_usage = 0;
|
1960
|
-
|
1961
|
-
// Allow a quick exit for the common case that the root is a leaf.
|
1962
|
-
if (RepMemoryUsageLeaf(rep, &total_mem_usage)) {
|
1963
|
-
return total_mem_usage;
|
1964
|
-
}
|
1965
|
-
|
1966
|
-
// Iterate over the tree. cur_node is never a leaf node and leaf nodes will
|
1967
|
-
// never be appended to tree_stack. This reduces overhead from manipulating
|
1968
|
-
// tree_stack.
|
1969
|
-
absl::InlinedVector<const CordRep*, kInlinedVectorSize> tree_stack;
|
1970
|
-
const CordRep* cur_node = rep;
|
1971
|
-
while (true) {
|
1972
|
-
const CordRep* next_node = nullptr;
|
1973
|
-
|
1974
|
-
if (cur_node->IsConcat()) {
|
1975
|
-
total_mem_usage += sizeof(CordRepConcat);
|
1976
|
-
const CordRep* left = cur_node->concat()->left;
|
1977
|
-
if (!RepMemoryUsageLeaf(left, &total_mem_usage)) {
|
1978
|
-
next_node = left;
|
1979
|
-
}
|
1980
|
-
|
1981
|
-
const CordRep* right = cur_node->concat()->right;
|
1982
|
-
if (!RepMemoryUsageLeaf(right, &total_mem_usage)) {
|
1983
|
-
if (next_node) {
|
1984
|
-
tree_stack.push_back(next_node);
|
1985
|
-
}
|
1986
|
-
next_node = right;
|
1987
|
-
}
|
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
|
-
}
|
2000
|
-
} else {
|
2001
|
-
// Since cur_node is not a leaf or a concat node it must be a substring.
|
2002
|
-
assert(cur_node->IsSubstring());
|
2003
|
-
total_mem_usage += sizeof(CordRepSubstring);
|
2004
|
-
next_node = cur_node->substring()->child;
|
2005
|
-
if (RepMemoryUsageLeaf(next_node, &total_mem_usage)) {
|
2006
|
-
next_node = nullptr;
|
2007
|
-
}
|
2008
|
-
}
|
2009
|
-
|
2010
|
-
if (!next_node) {
|
2011
|
-
if (tree_stack.empty()) {
|
2012
|
-
return total_mem_usage;
|
2013
|
-
}
|
2014
|
-
next_node = tree_stack.back();
|
2015
|
-
tree_stack.pop_back();
|
2016
|
-
}
|
2017
|
-
cur_node = next_node;
|
2018
|
-
}
|
2019
|
-
}
|
2020
|
-
|
2021
1303
|
std::ostream& operator<<(std::ostream& out, const Cord& cord) {
|
2022
1304
|
for (absl::string_view chunk : cord.Chunks()) {
|
2023
1305
|
out.write(chunk.data(), chunk.size());
|
@@ -2035,7 +1317,6 @@ uint8_t CordTestAccess::LengthToTag(size_t s) {
|
|
2035
1317
|
ABSL_INTERNAL_CHECK(s <= kMaxFlatLength, absl::StrCat("Invalid length ", s));
|
2036
1318
|
return cord_internal::AllocatedSizeToTag(s + cord_internal::kFlatOverhead);
|
2037
1319
|
}
|
2038
|
-
size_t CordTestAccess::SizeofCordRepConcat() { return sizeof(CordRepConcat); }
|
2039
1320
|
size_t CordTestAccess::SizeofCordRepExternal() {
|
2040
1321
|
return sizeof(CordRepExternal);
|
2041
1322
|
}
|