grpc 1.84.0 → 1.85.0.pre1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Makefile +40 -27
- data/include/grpc/event_engine/memory_allocator.h +1 -0
- data/include/grpc/grpc.h +3 -0
- data/include/grpc/grpc_security_constants.h +2 -0
- data/include/grpc/impl/channel_arg_names.h +4 -0
- data/src/core/call/call_filters.h +10 -10
- data/src/core/{lib/security/authorization → call}/evaluate_args.cc +22 -1
- data/src/core/{lib/security/authorization → call}/evaluate_args.h +19 -5
- data/src/core/call/filter_fusion.h +15 -15
- data/src/core/call/interception_chain.h +3 -3
- data/src/core/call/metadata_batch.cc +1 -0
- data/src/core/call/metadata_batch.h +45 -33
- data/src/core/call/parsed_metadata.h +3 -3
- data/src/core/call/request_buffer.cc +6 -6
- data/src/core/call/request_buffer.h +1 -1
- data/src/core/channelz/channel_trace.cc +5 -5
- data/src/core/channelz/channel_trace.h +1 -1
- data/src/core/channelz/channelz.cc +9 -9
- data/src/core/channelz/channelz.h +12 -12
- data/src/core/channelz/channelz_registry.cc +10 -10
- data/src/core/channelz/ztrace_collector.h +5 -5
- data/src/core/client_channel/client_channel.cc +4 -4
- data/src/core/client_channel/client_channel_filter.cc +14 -14
- data/src/core/client_channel/global_subchannel_pool.cc +4 -4
- data/src/core/client_channel/subchannel.cc +24 -23
- data/src/core/client_channel/subchannel_stream_client.cc +5 -5
- data/src/core/credentials/call/external/aws_external_account_credentials.cc +7 -7
- data/src/core/credentials/call/external/aws_request_signer.cc +16 -0
- data/src/core/credentials/call/external/external_account_credentials.cc +4 -4
- data/src/core/credentials/call/regional_access_boundary_fetcher.cc +9 -9
- data/src/core/credentials/call/token_fetcher/token_fetcher_credentials.cc +4 -4
- data/src/core/credentials/transport/google_default/google_default_credentials.cc +3 -3
- data/src/core/credentials/transport/ssl/ssl_security_connector.cc +1 -1
- data/src/core/credentials/transport/tls/grpc_tls_certificate_distributor.cc +9 -9
- data/src/core/credentials/transport/tls/grpc_tls_certificate_distributor.h +1 -1
- data/src/core/credentials/transport/tls/grpc_tls_certificate_provider.cc +6 -6
- data/src/core/credentials/transport/tls/grpc_tls_certificate_verifier.cc +3 -3
- data/src/core/credentials/transport/tls/grpc_tls_crl_provider.cc +4 -4
- data/src/core/credentials/transport/tls/ssl_utils.cc +10 -0
- data/src/core/credentials/transport/tls/tls_security_connector.cc +10 -10
- data/src/core/credentials/transport/tls/tls_security_connector.h +6 -6
- data/src/core/credentials/transport/tls/tls_utils.h +9 -0
- data/src/core/ext/filters/channel_idle/legacy_channel_idle_filter.cc +1 -1
- data/src/core/ext/filters/fault_injection/fault_injection_filter.cc +1 -1
- data/src/core/ext/filters/gcp_authentication/gcp_authentication_filter.cc +2 -2
- data/src/core/ext/filters/gcp_authentication/gcp_authentication_filter.h +1 -1
- data/src/core/ext/filters/http/message_compress/compression_filter.cc +15 -0
- data/src/core/ext/filters/rbac/rbac_filter.h +1 -1
- data/src/core/ext/transport/chttp2/client/chttp2_connector.cc +5 -5
- data/src/core/ext/transport/chttp2/server/chttp2_server.cc +30 -21
- data/src/core/ext/transport/chttp2/server/chttp2_server.h +5 -11
- data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +14 -11
- data/src/core/ext/transport/chttp2/transport/flow_control.cc +1 -0
- data/src/core/ext/transport/chttp2/transport/flow_control.h +0 -4
- data/src/core/ext/transport/chttp2/transport/frame.h +9 -0
- data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +12 -9
- data/src/core/ext/transport/chttp2/transport/hpack_parser.h +4 -2
- data/src/core/ext/transport/chttp2/transport/http2_client_transport.cc +16 -18
- data/src/core/ext/transport/chttp2/transport/http2_client_transport.h +2 -1
- data/src/core/ext/transport/chttp2/transport/http2_server_transport.cc +277 -189
- data/src/core/ext/transport/chttp2/transport/http2_server_transport.h +40 -17
- data/src/core/ext/transport/chttp2/transport/http2_transport.cc +12 -24
- data/src/core/ext/transport/chttp2/transport/http2_transport.h +3 -29
- data/src/core/ext/transport/chttp2/transport/internal.h +2 -2
- data/src/core/ext/transport/chttp2/transport/parsing.cc +3 -2
- data/src/core/ext/transport/chttp2/transport/read_context.h +96 -3
- data/src/core/ext/transport/chttp2/transport/reclaimer.cc +32 -0
- data/src/core/ext/transport/chttp2/transport/reclaimer.h +64 -0
- data/src/core/ext/transport/chttp2/transport/security_frame.h +8 -8
- data/src/core/ext/transport/chttp2/transport/stream_data_queue.h +17 -9
- data/src/core/ext/transport/chttp2/transport/write_cycle.h +23 -3
- data/src/core/ext/transport/inproc/inproc_transport.cc +5 -5
- data/src/core/ext/upb-gen/grpc/channelz/v1/channelz.upb.h +137 -73
- data/src/core/ext/upb-gen/grpc/channelz/v1/channelz.upb_minitable.c +45 -25
- data/src/core/ext/upb-gen/{src/proto/grpc → grpc}/gcp/altscontext.upb.h +6 -6
- data/src/core/ext/upb-gen/{src/proto/grpc → grpc}/gcp/altscontext.upb_minitable.c +4 -4
- data/src/core/ext/upb-gen/{src/proto/grpc → grpc}/gcp/altscontext.upb_minitable.h +5 -5
- data/src/core/ext/upb-gen/{src/proto/grpc → grpc}/gcp/handshaker.upb.h +46 -26
- data/src/core/ext/upb-gen/{src/proto/grpc → grpc}/gcp/handshaker.upb_minitable.c +17 -14
- data/src/core/ext/upb-gen/{src/proto/grpc → grpc}/gcp/handshaker.upb_minitable.h +5 -5
- data/src/core/ext/upb-gen/{src/proto/grpc → grpc}/gcp/transport_security_common.upb.h +5 -5
- data/src/core/ext/upb-gen/{src/proto/grpc → grpc}/gcp/transport_security_common.upb_minitable.c +3 -3
- data/src/core/ext/upb-gen/{src/proto/grpc → grpc}/gcp/transport_security_common.upb_minitable.h +5 -5
- data/src/core/ext/upb-gen/grpc/health/v1/health.upb.h +329 -0
- data/src/core/ext/upb-gen/grpc/health/v1/health.upb_minitable.c +128 -0
- data/src/core/ext/upb-gen/{src/proto/grpc → grpc}/health/v1/health.upb_minitable.h +8 -5
- data/src/core/ext/upb-gen/{src/proto/grpc → grpc}/lb/v1/load_balancer.upb.h +5 -5
- data/src/core/ext/upb-gen/{src/proto/grpc → grpc}/lb/v1/load_balancer.upb_minitable.c +3 -3
- data/src/core/ext/upb-gen/{src/proto/grpc → grpc}/lb/v1/load_balancer.upb_minitable.h +5 -5
- data/src/core/ext/upb-gen/{src/proto/grpc → grpc}/lookup/v1/rls.upb.h +185 -23
- data/src/core/ext/upb-gen/{src/proto/grpc → grpc}/lookup/v1/rls.upb_minitable.c +20 -12
- data/src/core/ext/upb-gen/{src/proto/grpc → grpc}/lookup/v1/rls.upb_minitable.h +5 -5
- data/src/core/ext/upb-gen/{src/proto/grpc → grpc}/lookup/v1/rls_config.upb.h +58 -42
- data/src/core/ext/upb-gen/{src/proto/grpc → grpc}/lookup/v1/rls_config.upb_minitable.c +17 -12
- data/src/core/ext/upb-gen/{src/proto/grpc → grpc}/lookup/v1/rls_config.upb_minitable.h +5 -5
- data/src/core/ext/upbdefs-gen/grpc/channelz/v1/channelz.upbdefs.c +567 -549
- data/src/core/ext/upbdefs-gen/grpc/lookup/v1/rls_config.upbdefs.c +182 -0
- data/src/core/ext/upbdefs-gen/{src/proto/grpc → grpc}/lookup/v1/rls_config.upbdefs.h +14 -14
- data/src/core/filter/ext_proc/ext_proc_filter.cc +1603 -46
- data/src/core/filter/ext_proc/ext_proc_filter.h +55 -22
- data/src/core/filter/ext_proc/ext_proc_messages.cc +106 -51
- data/src/core/filter/ext_proc/ext_proc_messages.h +36 -9
- data/src/core/handshaker/handshaker.cc +4 -4
- data/src/core/handshaker/http_connect/http_connect_client_handshaker.cc +3 -3
- data/src/core/handshaker/security/pipelined_secure_endpoint.cc +10 -10
- data/src/core/handshaker/security/secure_endpoint.cc +13 -13
- data/src/core/handshaker/security/security_handshaker.cc +6 -6
- data/src/core/handshaker/tcp_connect/tcp_connect_handshaker.cc +4 -4
- data/src/core/lib/channel/channel_args.cc +20 -0
- data/src/core/lib/channel/channel_args.h +17 -17
- data/src/core/lib/channel/promise_based_filter.cc +2 -2
- data/src/core/lib/channel/promise_based_filter.h +66 -27
- data/src/core/lib/debug/trace_flags.cc +2 -0
- data/src/core/lib/debug/trace_flags.h +1 -0
- data/src/core/lib/event_engine/ares_resolver.cc +14 -14
- data/src/core/lib/event_engine/cf_engine/cf_engine.cc +7 -7
- data/src/core/lib/event_engine/cf_engine/cfsocket_listener.cc +4 -4
- data/src/core/lib/event_engine/default_event_engine.cc +5 -5
- data/src/core/lib/event_engine/posix_engine/ev_epoll1_linux.cc +9 -9
- data/src/core/lib/event_engine/posix_engine/ev_poll_posix.cc +16 -14
- data/src/core/lib/event_engine/posix_engine/file_descriptor_collection.cc +6 -6
- data/src/core/lib/event_engine/posix_engine/grpc_polled_fd_posix.h +3 -3
- data/src/core/lib/event_engine/posix_engine/posix_endpoint.cc +1 -1
- data/src/core/lib/event_engine/posix_engine/posix_endpoint.h +7 -7
- data/src/core/lib/event_engine/posix_engine/posix_engine.cc +17 -17
- data/src/core/lib/event_engine/posix_engine/posix_engine_listener.cc +3 -3
- data/src/core/lib/event_engine/posix_engine/timer.cc +5 -5
- data/src/core/lib/event_engine/posix_engine/timer_manager.cc +5 -5
- data/src/core/lib/event_engine/posix_engine/traced_buffer_list.cc +3 -3
- data/src/core/lib/event_engine/posix_engine/traced_buffer_list.h +1 -1
- data/src/core/lib/event_engine/thread_pool/thread_count.cc +1 -1
- data/src/core/lib/event_engine/thread_pool/thread_count.h +3 -3
- data/src/core/lib/event_engine/thread_pool/work_stealing_thread_pool.cc +50 -21
- data/src/core/lib/event_engine/thready_event_engine/thready_event_engine.cc +3 -3
- data/src/core/lib/event_engine/windows/grpc_polled_fd_windows.cc +3 -3
- data/src/core/lib/event_engine/windows/windows_engine.cc +15 -15
- data/src/core/lib/event_engine/windows/windows_listener.cc +6 -6
- data/src/core/lib/event_engine/work_queue/basic_work_queue.cc +6 -6
- data/src/core/lib/experiments/experiments.cc +48 -0
- data/src/core/lib/experiments/experiments.h +24 -0
- data/src/core/lib/iomgr/buffer_list.cc +3 -3
- data/src/core/lib/iomgr/buffer_list.h +1 -1
- data/src/core/lib/iomgr/combiner.cc +0 -1
- data/src/core/lib/iomgr/ev_apple.cc +4 -4
- data/src/core/lib/iomgr/event_engine_shims/endpoint.cc +2 -2
- data/src/core/lib/iomgr/tcp_client_posix.cc +3 -3
- data/src/core/lib/iomgr/tcp_posix.cc +7 -7
- data/src/core/lib/promise/activity.cc +1 -1
- data/src/core/lib/promise/activity.h +1 -1
- data/src/core/lib/promise/arena_promise.h +7 -7
- data/src/core/lib/promise/detail/promise_factory.h +8 -8
- data/src/core/lib/promise/detail/promise_like.h +4 -4
- data/src/core/lib/promise/inter_activity_latch.h +6 -6
- data/src/core/lib/promise/inter_activity_pipe.h +1 -1
- data/src/core/lib/promise/observable.h +3 -3
- data/src/core/lib/promise/party.cc +1 -1
- data/src/core/lib/promise/try_seq.h +2 -2
- data/src/core/lib/resource_quota/arena.h +3 -3
- data/src/core/lib/resource_quota/memory_quota.cc +16 -16
- data/src/core/lib/resource_quota/memory_quota.h +1 -1
- data/src/core/lib/resource_quota/thread_quota.cc +3 -3
- data/src/core/lib/security/authorization/audit_logging.cc +5 -5
- data/src/core/lib/security/authorization/authorization_engine.h +1 -1
- data/src/core/lib/security/authorization/grpc_authorization_engine.h +1 -1
- data/src/core/lib/security/authorization/grpc_server_authz_filter.cc +1 -1
- data/src/core/lib/security/authorization/grpc_server_authz_filter.h +1 -1
- data/src/core/lib/security/authorization/matchers.h +1 -1
- data/src/core/lib/surface/call.cc +8 -7
- data/src/core/lib/surface/call.h +3 -3
- data/src/core/lib/surface/call_utils.h +4 -0
- data/src/core/lib/surface/channel.cc +1 -1
- data/src/core/lib/surface/channel.h +1 -1
- data/src/core/lib/surface/channel_init.cc +1 -1
- data/src/core/lib/surface/init.cc +7 -7
- data/src/core/lib/surface/lame_client.cc +1 -1
- data/src/core/lib/surface/legacy_channel.cc +2 -2
- data/src/core/lib/surface/version.cc +1 -1
- data/src/core/lib/transport/transport_framing_endpoint_extension.h +3 -3
- data/src/core/load_balancing/autosharding/autosharding.cc +931 -0
- data/src/core/load_balancing/autosharding/autosharding.h +78 -0
- data/src/core/load_balancing/grpclb/grpclb_client_stats.cc +2 -2
- data/src/core/load_balancing/grpclb/load_balancer_api.cc +1 -1
- data/src/core/load_balancing/grpclb/load_balancer_api.h +3 -1
- data/src/core/load_balancing/health_check_client.cc +7 -7
- data/src/core/load_balancing/lb_policy.cc +1 -1
- data/src/core/load_balancing/oob_backend_metric.cc +5 -5
- data/src/core/load_balancing/outlier_detection/outlier_detection.cc +2 -2
- data/src/core/load_balancing/ring_hash/ring_hash.cc +109 -37
- data/src/core/load_balancing/rls/rls.cc +23 -17
- data/src/core/load_balancing/weighted_round_robin/weighted_round_robin.cc +10 -10
- data/src/core/load_balancing/xds/cds.cc +6 -5
- data/src/core/load_balancing/xds/xds_cluster_impl.cc +2 -2
- data/src/core/load_balancing/xds/xds_override_host.cc +10 -10
- data/src/core/mitigation_engine/mitigation_engine.h +28 -4
- data/src/core/plugin_registry/grpc_plugin_registry.cc +2 -0
- data/src/core/resolver/dns/dns_resolver.cc +7 -7
- data/src/core/resolver/fake/fake_resolver.cc +5 -5
- data/src/core/resolver/google_c2p/google_c2p_resolver.cc +38 -30
- data/src/core/server/server.cc +30 -30
- data/src/core/server/server.h +4 -3
- data/src/core/server/server_config_selector_filter.cc +3 -3
- data/src/core/server/xds_server_config_fetcher_legacy.cc +15 -15
- data/src/core/telemetry/default_tcp_tracer.cc +1 -1
- data/src/core/telemetry/instrument.cc +30 -16
- data/src/core/telemetry/instrument.h +3 -3
- data/src/core/tsi/alts/handshaker/alts_handshaker_client.cc +3 -3
- data/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc +4 -4
- data/src/core/tsi/alts/handshaker/alts_tsi_handshaker.h +2 -2
- data/src/core/tsi/alts/handshaker/alts_tsi_utils.h +1 -1
- data/src/core/tsi/alts/handshaker/transport_security_common_api.h +1 -1
- data/src/core/tsi/ssl/key_logging/ssl_key_logging.cc +5 -5
- data/src/core/tsi/ssl/session_cache/ssl_session_cache.cc +3 -3
- data/src/core/tsi/ssl_transport_security.cc +46 -13
- data/src/core/tsi/ssl_transport_security.h +7 -0
- data/src/core/tsi/ssl_transport_security_utils.cc +16 -6
- data/src/core/util/event_log.cc +3 -3
- data/src/core/util/http_client/httpcli.cc +5 -5
- data/src/core/util/http_client/httpcli.h +1 -1
- data/src/core/util/json/json_object_loader.cc +7 -0
- data/src/core/util/json/json_object_loader.h +17 -2
- data/src/core/util/latent_see.cc +123 -36
- data/src/core/util/latent_see.h +14 -1
- data/src/core/util/mpscq.cc +1 -1
- data/src/core/util/notification.h +4 -4
- data/src/core/util/sync.h +20 -6
- data/src/core/util/table.h +20 -22
- data/src/core/util/work_serializer.cc +2 -2
- data/src/core/xds/grpc/blackboard.cc +4 -3
- data/src/core/xds/grpc/certificate_provider_store.cc +2 -2
- data/src/core/xds/grpc/streaming_call_promise_wrapper.cc +181 -0
- data/src/core/xds/grpc/streaming_call_promise_wrapper.h +213 -0
- data/src/core/xds/grpc/xds_bootstrap_grpc_builder.cc +2 -2
- data/src/core/xds/grpc/xds_client_grpc.cc +8 -8
- data/src/core/xds/grpc/xds_cluster_specifier_plugin.cc +2 -2
- data/src/core/xds/grpc/xds_endpoint.cc +1 -1
- data/src/core/xds/grpc/xds_endpoint_parser.cc +11 -0
- data/src/core/xds/grpc/xds_grpc_service_parser.cc +12 -10
- data/src/core/xds/grpc/xds_http_ext_proc_filter.cc +17 -14
- data/src/core/xds/grpc/xds_matcher.h +2 -2
- data/src/core/xds/grpc/xds_transport_grpc.cc +125 -85
- data/src/core/xds/grpc/xds_transport_grpc.h +19 -4
- data/src/core/xds/xds_client/lrs_client.cc +22 -19
- data/src/core/xds/xds_client/xds_client.cc +19 -16
- data/src/core/xds/xds_client/xds_transport.h +49 -3
- data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +2 -0
- data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +3 -0
- data/src/ruby/lib/grpc/version.rb +1 -1
- data/src/ruby/pb/README.md +1 -1
- data/src/ruby/pb/generate_proto_ruby.sh +1 -1
- data/third_party/abseil-cpp/absl/algorithm/algorithm.h +34 -2
- data/third_party/abseil-cpp/absl/algorithm/container.h +345 -147
- data/third_party/abseil-cpp/absl/base/attributes.h +67 -44
- data/third_party/abseil-cpp/absl/base/call_once.h +1 -0
- data/third_party/abseil-cpp/absl/base/casts.cc +61 -0
- data/third_party/abseil-cpp/absl/base/casts.h +135 -2
- data/third_party/abseil-cpp/absl/base/config.h +63 -41
- data/third_party/abseil-cpp/absl/base/fast_type_id.h +30 -2
- data/third_party/abseil-cpp/absl/base/internal/dynamic_annotations.h +1 -1
- data/third_party/abseil-cpp/absl/base/internal/hardening.h +136 -0
- data/third_party/abseil-cpp/absl/base/internal/iterator_traits.h +6 -2
- data/third_party/abseil-cpp/absl/base/internal/low_level_alloc.cc +39 -4
- data/third_party/abseil-cpp/absl/base/internal/low_level_alloc.h +6 -0
- data/third_party/abseil-cpp/absl/base/internal/low_level_scheduling.h +77 -15
- data/third_party/abseil-cpp/absl/base/internal/raw_logging.cc +3 -4
- data/third_party/abseil-cpp/absl/base/internal/spinlock.cc +26 -24
- data/third_party/abseil-cpp/absl/base/internal/spinlock.h +74 -29
- data/third_party/abseil-cpp/absl/base/internal/sysinfo.cc +1 -11
- data/third_party/abseil-cpp/absl/base/internal/thread_identity.h +52 -0
- data/third_party/abseil-cpp/absl/base/internal/unscaledcycleclock.cc +5 -1
- data/third_party/abseil-cpp/absl/base/internal/unscaledcycleclock.h +5 -0
- data/third_party/abseil-cpp/absl/base/internal/unscaledcycleclock_config.h +1 -1
- data/third_party/abseil-cpp/absl/base/macros.h +76 -37
- data/third_party/abseil-cpp/absl/base/nullability.h +5 -5
- data/third_party/abseil-cpp/absl/base/optimization.h +4 -5
- data/third_party/abseil-cpp/absl/base/options.h +46 -18
- data/third_party/abseil-cpp/absl/base/policy_checks.h +5 -5
- data/third_party/abseil-cpp/absl/base/{internal/throw_delegate.cc → throw_delegate.cc} +9 -7
- data/third_party/abseil-cpp/absl/base/{internal/throw_delegate.h → throw_delegate.h} +4 -14
- data/third_party/abseil-cpp/absl/cleanup/cleanup.h +7 -2
- data/third_party/abseil-cpp/absl/cleanup/internal/cleanup.h +3 -2
- data/third_party/abseil-cpp/absl/container/btree_map.h +60 -10
- data/third_party/abseil-cpp/absl/container/btree_set.h +61 -15
- data/third_party/abseil-cpp/absl/container/fixed_array.h +19 -21
- data/third_party/abseil-cpp/absl/container/flat_hash_map.h +49 -27
- data/third_party/abseil-cpp/absl/container/flat_hash_set.h +50 -26
- data/third_party/abseil-cpp/absl/container/inlined_vector.h +42 -36
- data/third_party/abseil-cpp/absl/container/internal/btree.h +32 -24
- data/third_party/abseil-cpp/absl/container/internal/btree_container.h +30 -22
- data/third_party/abseil-cpp/absl/container/internal/common.h +57 -5
- data/third_party/abseil-cpp/absl/container/internal/common_policy_traits.h +1 -1
- data/third_party/abseil-cpp/absl/container/internal/compressed_tuple.h +40 -36
- data/third_party/abseil-cpp/absl/container/internal/container_memory.h +119 -39
- data/third_party/abseil-cpp/absl/container/internal/hash_function_defaults.h +14 -2
- data/third_party/abseil-cpp/absl/container/internal/hash_policy_traits.h +14 -22
- data/third_party/abseil-cpp/absl/container/internal/hashtable_control_bytes.h +52 -52
- data/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler.cc +7 -7
- data/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler.h +7 -7
- data/third_party/abseil-cpp/absl/container/internal/inlined_vector.h +32 -40
- data/third_party/abseil-cpp/absl/container/internal/layout.h +13 -13
- data/third_party/abseil-cpp/absl/container/internal/raw_hash_map.h +95 -72
- data/third_party/abseil-cpp/absl/container/internal/raw_hash_set.cc +633 -365
- data/third_party/abseil-cpp/absl/container/internal/raw_hash_set.h +1016 -749
- data/third_party/abseil-cpp/absl/container/internal/raw_hash_set_resize_impl.h +0 -1
- data/third_party/abseil-cpp/absl/container/node_hash_map.h +58 -35
- data/third_party/abseil-cpp/absl/crc/internal/cpu_detect.cc +23 -6
- data/third_party/abseil-cpp/absl/crc/internal/cpu_detect.h +7 -1
- data/third_party/abseil-cpp/absl/crc/internal/crc.cc +4 -6
- data/third_party/abseil-cpp/absl/crc/internal/crc32_x86_arm_combined_simd.h +41 -0
- data/third_party/abseil-cpp/absl/crc/internal/crc_internal.h +0 -16
- data/third_party/abseil-cpp/absl/crc/internal/crc_memcpy_x86_arm_combined.cc +5 -0
- data/third_party/abseil-cpp/absl/crc/internal/crc_x86_arm_combined.cc +304 -188
- data/third_party/abseil-cpp/absl/crc/internal/non_temporal_arm_intrinsics.h +4 -2
- data/third_party/abseil-cpp/absl/debugging/internal/demangle.cc +2 -2
- data/third_party/abseil-cpp/absl/debugging/internal/demangle_rust.h +8 -0
- data/third_party/abseil-cpp/absl/debugging/internal/elf_mem_image.h +4 -4
- data/third_party/abseil-cpp/absl/debugging/internal/examine_stack.cc +15 -1
- data/third_party/abseil-cpp/absl/debugging/internal/examine_stack.h +7 -1
- data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_aarch64-inl.inc +12 -1
- data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_config.h +6 -5
- data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_emscripten-inl.inc +13 -11
- data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_generic-inl.inc +14 -7
- data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_powerpc-inl.inc +3 -2
- data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_riscv-inl.inc +6 -1
- data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_x86-inl.inc +14 -8
- data/third_party/abseil-cpp/absl/debugging/internal/symbolize.h +48 -38
- data/third_party/abseil-cpp/absl/debugging/internal/vdso_support.cc +4 -0
- data/third_party/abseil-cpp/absl/debugging/stacktrace.cc +63 -118
- data/third_party/abseil-cpp/absl/debugging/stacktrace.h +7 -47
- data/third_party/abseil-cpp/absl/debugging/symbolize.cc +20 -2
- data/third_party/abseil-cpp/absl/debugging/symbolize_elf.inc +83 -149
- data/third_party/abseil-cpp/absl/debugging/symbolize_emscripten.inc +4 -17
- data/third_party/abseil-cpp/absl/debugging/symbolize_unimplemented.inc +4 -4
- data/third_party/abseil-cpp/absl/debugging/symbolize_win32.inc +2 -4
- data/third_party/abseil-cpp/absl/flags/commandlineflag.h +8 -6
- data/third_party/abseil-cpp/absl/flags/declare.h +9 -0
- data/third_party/abseil-cpp/absl/flags/flag.h +2 -1
- data/third_party/abseil-cpp/absl/flags/internal/commandlineflag.h +1 -1
- data/third_party/abseil-cpp/absl/flags/internal/flag.cc +19 -18
- data/third_party/abseil-cpp/absl/flags/internal/flag.h +33 -34
- data/third_party/abseil-cpp/absl/flags/internal/program_name.cc +2 -2
- data/third_party/abseil-cpp/absl/flags/marshalling.cc +1 -16
- data/third_party/abseil-cpp/absl/flags/marshalling.h +2 -28
- data/third_party/abseil-cpp/absl/flags/reflection.cc +11 -7
- data/third_party/abseil-cpp/absl/flags/usage_config.cc +2 -2
- data/third_party/abseil-cpp/absl/functional/any_invocable.h +22 -19
- data/third_party/abseil-cpp/absl/functional/bind_front.h +7 -1
- data/third_party/abseil-cpp/absl/functional/function_ref.h +125 -20
- data/third_party/abseil-cpp/absl/functional/internal/any_invocable.h +43 -31
- data/third_party/abseil-cpp/absl/functional/internal/front_binder.h +4 -4
- data/third_party/abseil-cpp/absl/functional/internal/function_ref.h +44 -6
- data/third_party/abseil-cpp/absl/hash/hash.h +1 -1
- data/third_party/abseil-cpp/absl/hash/internal/city.cc +39 -51
- data/third_party/abseil-cpp/absl/hash/internal/hash.cc +379 -14
- data/third_party/abseil-cpp/absl/hash/internal/hash.h +457 -353
- data/third_party/abseil-cpp/absl/log/absl_vlog_is_on.h +0 -2
- data/third_party/abseil-cpp/absl/log/internal/check_impl.h +2 -1
- data/third_party/abseil-cpp/absl/log/internal/check_op.cc +4 -0
- data/third_party/abseil-cpp/absl/log/internal/check_op.h +128 -50
- data/third_party/abseil-cpp/absl/log/internal/conditions.h +38 -35
- data/third_party/abseil-cpp/absl/log/internal/log_impl.h +108 -110
- data/third_party/abseil-cpp/absl/log/internal/log_message.cc +10 -6
- data/third_party/abseil-cpp/absl/log/internal/log_message.h +19 -1
- data/third_party/abseil-cpp/absl/log/internal/log_sink_set.cc +4 -4
- data/third_party/abseil-cpp/absl/log/internal/nullstream.h +1 -1
- data/third_party/abseil-cpp/absl/log/internal/proto.cc +13 -0
- data/third_party/abseil-cpp/absl/log/internal/strip.h +30 -31
- data/third_party/abseil-cpp/absl/log/internal/structured_proto.cc +5 -5
- data/third_party/abseil-cpp/absl/log/internal/structured_proto.h +6 -5
- data/third_party/abseil-cpp/absl/log/internal/vlog_config.cc +30 -30
- data/third_party/abseil-cpp/absl/log/internal/vlog_config.h +0 -1
- data/third_party/abseil-cpp/absl/log/log.h +2 -2
- data/third_party/abseil-cpp/absl/log/log_entry.cc +263 -0
- data/third_party/abseil-cpp/absl/log/log_entry.h +2 -0
- data/third_party/abseil-cpp/absl/log/vlog_is_on.h +0 -2
- data/third_party/abseil-cpp/absl/memory/memory.h +55 -5
- data/third_party/abseil-cpp/absl/meta/type_traits.h +161 -56
- data/third_party/abseil-cpp/absl/numeric/int128.h +41 -21
- data/third_party/abseil-cpp/absl/numeric/int128_have_intrinsic.inc +16 -22
- data/third_party/abseil-cpp/absl/numeric/int128_no_intrinsic.inc +5 -7
- data/third_party/abseil-cpp/absl/numeric/internal/bits.h +32 -4
- data/third_party/abseil-cpp/absl/profiling/internal/sample_recorder.h +9 -9
- data/third_party/abseil-cpp/absl/random/beta_distribution.h +2 -2
- data/third_party/abseil-cpp/absl/random/bit_gen_ref.h +26 -53
- data/third_party/abseil-cpp/absl/random/discrete_distribution.h +1 -1
- data/third_party/abseil-cpp/absl/random/distributions.h +17 -17
- data/third_party/abseil-cpp/absl/random/exponential_distribution.h +1 -1
- data/third_party/abseil-cpp/absl/random/internal/distribution_caller.h +8 -21
- data/third_party/abseil-cpp/absl/random/internal/entropy_pool.cc +2 -2
- data/third_party/abseil-cpp/absl/random/internal/fast_uniform_bits.h +1 -1
- data/third_party/abseil-cpp/absl/random/internal/generate_real.h +1 -1
- data/third_party/abseil-cpp/absl/random/internal/iostream_state_saver.h +2 -2
- data/third_party/abseil-cpp/absl/random/internal/nonsecure_base.h +2 -2
- data/third_party/abseil-cpp/absl/random/internal/pcg_engine.h +6 -6
- data/third_party/abseil-cpp/absl/random/internal/platform.h +0 -13
- data/third_party/abseil-cpp/absl/random/internal/randen_detect.cc +6 -6
- data/third_party/abseil-cpp/absl/random/internal/randen_engine.h +2 -2
- data/third_party/abseil-cpp/absl/random/internal/salted_seed_seq.h +6 -5
- data/third_party/abseil-cpp/absl/random/internal/seed_material.cc +5 -31
- data/third_party/abseil-cpp/absl/random/internal/seed_material.h +2 -1
- data/third_party/abseil-cpp/absl/random/internal/traits.h +21 -0
- data/third_party/abseil-cpp/absl/random/internal/uniform_helper.h +23 -23
- data/third_party/abseil-cpp/absl/random/mocking_access.h +74 -0
- data/third_party/abseil-cpp/absl/random/uniform_real_distribution.h +1 -1
- data/third_party/abseil-cpp/absl/status/internal/status_internal.cc +63 -18
- data/third_party/abseil-cpp/absl/status/internal/status_internal.h +30 -4
- data/third_party/abseil-cpp/absl/status/internal/statusor_internal.h +225 -63
- data/third_party/abseil-cpp/absl/status/status.cc +66 -70
- data/third_party/abseil-cpp/absl/status/status.h +254 -23
- data/third_party/abseil-cpp/absl/status/status_payload_printer.h +3 -2
- data/third_party/abseil-cpp/absl/status/statusor.h +117 -137
- data/third_party/abseil-cpp/absl/strings/ascii.h +10 -6
- data/third_party/abseil-cpp/absl/strings/cord.cc +41 -17
- data/third_party/abseil-cpp/absl/strings/cord.h +26 -17
- data/third_party/abseil-cpp/absl/strings/cord_buffer.h +4 -2
- data/third_party/abseil-cpp/absl/strings/escaping.cc +305 -125
- data/third_party/abseil-cpp/absl/strings/escaping.h +12 -2
- data/third_party/abseil-cpp/absl/strings/internal/append_and_overwrite.h +93 -0
- data/third_party/abseil-cpp/absl/strings/internal/cord_internal.h +2 -2
- data/third_party/abseil-cpp/absl/strings/internal/cordz_handle.cc +6 -6
- data/third_party/abseil-cpp/absl/strings/internal/cordz_info.cc +27 -21
- data/third_party/abseil-cpp/absl/strings/internal/cordz_info.h +11 -19
- data/third_party/abseil-cpp/absl/strings/internal/damerau_levenshtein_distance.cc +6 -0
- data/third_party/abseil-cpp/absl/strings/internal/damerau_levenshtein_distance.h +1 -0
- data/third_party/abseil-cpp/absl/strings/internal/escaping.cc +0 -141
- data/third_party/abseil-cpp/absl/strings/internal/escaping.h +2 -24
- data/third_party/abseil-cpp/absl/strings/internal/resize_uninitialized.h +31 -36
- data/third_party/abseil-cpp/absl/strings/internal/stl_type_traits.h +39 -39
- data/third_party/abseil-cpp/absl/strings/internal/str_format/arg.h +14 -22
- data/third_party/abseil-cpp/absl/strings/internal/str_format/bind.h +2 -2
- data/third_party/abseil-cpp/absl/strings/internal/str_format/checker.h +2 -4
- data/third_party/abseil-cpp/absl/strings/internal/str_format/float_conversion.cc +921 -231
- data/third_party/abseil-cpp/absl/strings/internal/str_join_internal.h +18 -16
- data/third_party/abseil-cpp/absl/strings/internal/str_split_internal.h +16 -12
- data/third_party/abseil-cpp/absl/strings/internal/stringify_sink.h +12 -0
- data/third_party/abseil-cpp/absl/strings/numbers.cc +477 -8
- data/third_party/abseil-cpp/absl/strings/numbers.h +29 -12
- data/third_party/abseil-cpp/absl/strings/resize_and_overwrite.h +198 -0
- data/third_party/abseil-cpp/absl/strings/str_cat.cc +96 -91
- data/third_party/abseil-cpp/absl/strings/str_cat.h +53 -13
- data/third_party/abseil-cpp/absl/strings/str_split.h +14 -9
- data/third_party/abseil-cpp/absl/strings/string_view.h +10 -716
- data/third_party/abseil-cpp/absl/strings/substitute.cc +24 -24
- data/third_party/abseil-cpp/absl/strings/substitute.h +2 -2
- data/third_party/abseil-cpp/absl/synchronization/barrier.cc +1 -1
- data/third_party/abseil-cpp/absl/synchronization/blocking_counter.cc +2 -2
- data/third_party/abseil-cpp/absl/synchronization/internal/create_thread_identity.cc +24 -3
- data/third_party/abseil-cpp/absl/synchronization/internal/graphcycles.cc +30 -33
- data/third_party/abseil-cpp/absl/synchronization/internal/kernel_timeout.h +2 -2
- data/third_party/abseil-cpp/absl/synchronization/internal/per_thread_sem.h +5 -0
- data/third_party/abseil-cpp/absl/synchronization/mutex.cc +41 -29
- data/third_party/abseil-cpp/absl/synchronization/mutex.h +199 -94
- data/third_party/abseil-cpp/absl/synchronization/notification.cc +5 -5
- data/third_party/abseil-cpp/absl/synchronization/notification.h +1 -1
- data/third_party/abseil-cpp/absl/time/clock.cc +29 -30
- data/third_party/abseil-cpp/absl/time/clock.h +3 -0
- data/third_party/abseil-cpp/absl/time/duration.cc +2 -2
- data/third_party/abseil-cpp/absl/time/format.cc +3 -10
- data/third_party/abseil-cpp/absl/time/internal/cctz/include/cctz/civil_time_detail.h +12 -0
- data/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_format.cc +131 -91
- data/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_lookup.cc +6 -103
- data/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_name_win.cc +185 -0
- data/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_name_win.h +37 -0
- data/third_party/abseil-cpp/absl/time/internal/cctz/src/tzfile.h +10 -15
- data/third_party/abseil-cpp/absl/time/time.cc +4 -4
- data/third_party/abseil-cpp/absl/time/time.h +14 -13
- data/third_party/abseil-cpp/absl/types/compare.h +64 -63
- data/third_party/abseil-cpp/absl/types/internal/span.h +6 -6
- data/third_party/abseil-cpp/absl/types/optional.h +31 -4
- data/third_party/abseil-cpp/absl/types/optional_ref.h +295 -0
- data/third_party/{boringssl-with-bazel/crypto/x509/x_val.cc → abseil-cpp/absl/types/source_location.cc} +4 -14
- data/third_party/abseil-cpp/absl/types/source_location.h +172 -0
- data/third_party/abseil-cpp/absl/types/span.h +67 -38
- data/third_party/abseil-cpp/absl/types/variant.h +75 -18
- data/third_party/abseil-cpp/absl/utility/utility.h +112 -16
- data/third_party/boringssl-with-bazel/crypto/aes/aes.cc +3 -0
- data/third_party/boringssl-with-bazel/crypto/armv8_feature_parsing.h +67 -0
- data/third_party/boringssl-with-bazel/crypto/asn1/a_bitstr.cc +143 -105
- data/third_party/boringssl-with-bazel/crypto/asn1/a_bool.cc +5 -8
- data/third_party/boringssl-with-bazel/crypto/asn1/a_d2i_fp.cc +3 -3
- data/third_party/boringssl-with-bazel/crypto/asn1/a_dup.cc +6 -6
- data/third_party/boringssl-with-bazel/crypto/asn1/a_gentm.cc +33 -12
- data/third_party/boringssl-with-bazel/crypto/asn1/a_i2d_fp.cc +7 -6
- data/third_party/boringssl-with-bazel/crypto/asn1/a_int.cc +80 -52
- data/third_party/boringssl-with-bazel/crypto/asn1/a_mbstr.cc +7 -4
- data/third_party/boringssl-with-bazel/crypto/asn1/a_object.cc +70 -72
- data/third_party/boringssl-with-bazel/crypto/asn1/a_strex.cc +38 -42
- data/third_party/boringssl-with-bazel/crypto/asn1/a_strnid.cc +41 -39
- data/third_party/boringssl-with-bazel/crypto/asn1/a_time.cc +59 -35
- data/third_party/boringssl-with-bazel/crypto/asn1/a_type.cc +275 -15
- data/third_party/boringssl-with-bazel/crypto/asn1/a_utctm.cc +32 -13
- data/third_party/boringssl-with-bazel/crypto/asn1/asn1_lib.cc +128 -30
- data/third_party/boringssl-with-bazel/crypto/asn1/asn_pack.cc +10 -10
- data/third_party/boringssl-with-bazel/crypto/asn1/f_int.cc +1 -1
- data/third_party/boringssl-with-bazel/crypto/asn1/f_string.cc +1 -1
- data/third_party/boringssl-with-bazel/crypto/asn1/internal.h +261 -115
- data/third_party/boringssl-with-bazel/crypto/asn1/posix_time.cc +8 -5
- data/third_party/boringssl-with-bazel/crypto/asn1/tasn_dec.cc +373 -725
- data/third_party/boringssl-with-bazel/crypto/asn1/tasn_enc.cc +211 -526
- data/third_party/boringssl-with-bazel/crypto/asn1/tasn_fre.cc +22 -19
- data/third_party/boringssl-with-bazel/crypto/asn1/tasn_new.cc +26 -24
- data/third_party/boringssl-with-bazel/crypto/asn1/tasn_typ.cc +19 -5
- data/third_party/boringssl-with-bazel/crypto/asn1/tasn_utl.cc +47 -51
- data/third_party/boringssl-with-bazel/crypto/base64/base64.cc +14 -15
- data/third_party/boringssl-with-bazel/crypto/bcm_support.h +7 -29
- data/third_party/boringssl-with-bazel/crypto/bio/bio.cc +234 -176
- data/third_party/boringssl-with-bazel/crypto/bio/bio_mem.cc +72 -86
- data/third_party/boringssl-with-bazel/crypto/bio/connect.cc +153 -199
- data/third_party/boringssl-with-bazel/crypto/bio/errno.cc +3 -1
- data/third_party/boringssl-with-bazel/crypto/bio/fd.cc +56 -55
- data/third_party/boringssl-with-bazel/crypto/bio/file.cc +70 -78
- data/third_party/boringssl-with-bazel/crypto/bio/hexdump.cc +6 -4
- data/third_party/boringssl-with-bazel/crypto/bio/internal.h +69 -17
- data/third_party/boringssl-with-bazel/crypto/bio/pair.cc +117 -136
- data/third_party/boringssl-with-bazel/crypto/bio/printf.cc +1 -1
- data/third_party/boringssl-with-bazel/crypto/bio/socket.cc +116 -50
- data/third_party/boringssl-with-bazel/crypto/bio/socket_helper.cc +53 -5
- data/third_party/boringssl-with-bazel/crypto/blake2/blake2.cc +9 -5
- data/third_party/boringssl-with-bazel/crypto/bn/bn_asn1.cc +2 -2
- data/third_party/boringssl-with-bazel/crypto/bn/convert.cc +56 -70
- data/third_party/boringssl-with-bazel/crypto/bn/div.cc +102 -0
- data/third_party/boringssl-with-bazel/crypto/bn/exponentiation.cc +26 -42
- data/third_party/boringssl-with-bazel/crypto/bn/sqrt.cc +93 -0
- data/third_party/boringssl-with-bazel/crypto/buf/buf.cc +6 -5
- data/third_party/boringssl-with-bazel/crypto/bytestring/asn1_compat.cc +6 -5
- data/third_party/boringssl-with-bazel/crypto/bytestring/ber.cc +22 -20
- data/third_party/boringssl-with-bazel/crypto/bytestring/cbb.cc +119 -59
- data/third_party/boringssl-with-bazel/crypto/bytestring/cbs.cc +115 -31
- data/third_party/boringssl-with-bazel/crypto/bytestring/internal.h +79 -24
- data/third_party/boringssl-with-bazel/crypto/bytestring/unicode.cc +2 -2
- data/third_party/boringssl-with-bazel/crypto/chacha/chacha.cc +5 -3
- data/third_party/boringssl-with-bazel/crypto/chacha/internal.h +23 -22
- data/third_party/boringssl-with-bazel/crypto/cipher/derive_key.cc +14 -18
- data/third_party/boringssl-with-bazel/crypto/cipher/e_aesctrhmac.cc +73 -58
- data/third_party/boringssl-with-bazel/crypto/cipher/e_aeseax.cc +132 -70
- data/third_party/boringssl-with-bazel/crypto/cipher/e_aesgcmsiv.cc +390 -249
- data/third_party/boringssl-with-bazel/crypto/cipher/e_chacha20poly1305.cc +200 -137
- data/third_party/boringssl-with-bazel/crypto/cipher/e_des.cc +45 -29
- data/third_party/boringssl-with-bazel/crypto/cipher/e_null.cc +9 -5
- data/third_party/boringssl-with-bazel/crypto/cipher/e_rc2.cc +43 -28
- data/third_party/boringssl-with-bazel/crypto/cipher/e_rc4.cc +7 -5
- data/third_party/boringssl-with-bazel/crypto/cipher/e_tls.cc +250 -237
- data/third_party/boringssl-with-bazel/crypto/cipher/get_cipher.cc +12 -12
- data/third_party/boringssl-with-bazel/crypto/cipher/internal.h +59 -59
- data/third_party/boringssl-with-bazel/crypto/cipher/tls_cbc.cc +111 -111
- data/third_party/boringssl-with-bazel/crypto/cms/cms.cc +48 -42
- data/third_party/boringssl-with-bazel/crypto/conf/conf.cc +69 -63
- data/third_party/boringssl-with-bazel/crypto/conf/internal.h +11 -12
- data/third_party/boringssl-with-bazel/crypto/cpu_aarch64_apple.cc +8 -5
- data/third_party/boringssl-with-bazel/crypto/cpu_aarch64_fuchsia.cc +6 -1
- data/third_party/boringssl-with-bazel/crypto/cpu_aarch64_linux.cc +7 -1
- data/third_party/boringssl-with-bazel/crypto/cpu_aarch64_openbsd.cc +7 -21
- data/third_party/boringssl-with-bazel/crypto/cpu_aarch64_sysreg.cc +15 -41
- data/third_party/boringssl-with-bazel/crypto/cpu_aarch64_win.cc +16 -3
- data/third_party/boringssl-with-bazel/crypto/cpu_arm_freebsd.cc +4 -2
- data/third_party/boringssl-with-bazel/crypto/cpu_arm_linux.cc +54 -31
- data/third_party/boringssl-with-bazel/crypto/cpu_arm_linux.h +79 -101
- data/third_party/boringssl-with-bazel/crypto/cpu_intel.cc +51 -45
- data/third_party/boringssl-with-bazel/crypto/crypto.cc +26 -55
- data/third_party/boringssl-with-bazel/crypto/curve25519/curve25519.cc +28 -25
- data/third_party/boringssl-with-bazel/crypto/curve25519/curve25519_tables.h +6 -6
- data/third_party/boringssl-with-bazel/crypto/curve25519/internal.h +14 -15
- data/third_party/boringssl-with-bazel/crypto/curve25519/spake25519.cc +23 -20
- data/third_party/boringssl-with-bazel/crypto/des/des.cc +27 -19
- data/third_party/boringssl-with-bazel/crypto/des/internal.h +4 -9
- data/third_party/boringssl-with-bazel/crypto/dh/dh_asn1.cc +34 -49
- data/third_party/boringssl-with-bazel/crypto/dh/params.cc +44 -41
- data/third_party/boringssl-with-bazel/crypto/digest/digest_extra.cc +87 -40
- data/third_party/boringssl-with-bazel/crypto/dsa/dsa.cc +237 -260
- data/third_party/boringssl-with-bazel/crypto/dsa/dsa_asn1.cc +100 -173
- data/third_party/boringssl-with-bazel/crypto/dsa/internal.h +23 -21
- data/third_party/boringssl-with-bazel/crypto/ec/ec_asn1.cc +181 -209
- data/third_party/boringssl-with-bazel/crypto/ec/ec_derive.cc +26 -28
- data/third_party/boringssl-with-bazel/crypto/ec/hash_to_curve.cc +265 -174
- data/third_party/boringssl-with-bazel/crypto/ec/internal.h +54 -18
- data/third_party/boringssl-with-bazel/crypto/ecdh/ecdh.cc +7 -5
- data/third_party/boringssl-with-bazel/crypto/ecdsa/ecdsa_asn1.cc +50 -70
- data/third_party/boringssl-with-bazel/crypto/ecdsa/ecdsa_p1363.cc +54 -0
- data/third_party/boringssl-with-bazel/crypto/engine/engine.cc +7 -7
- data/third_party/boringssl-with-bazel/crypto/err/err.cc +116 -105
- data/third_party/boringssl-with-bazel/crypto/err/internal.h +8 -21
- data/third_party/boringssl-with-bazel/crypto/evp/evp.cc +238 -166
- data/third_party/boringssl-with-bazel/crypto/evp/evp_asn1.cc +202 -234
- data/third_party/boringssl-with-bazel/crypto/evp/evp_ctx.cc +260 -159
- data/third_party/boringssl-with-bazel/crypto/evp/evp_kem.cc +82 -0
- data/third_party/boringssl-with-bazel/crypto/evp/internal.h +292 -137
- data/third_party/boringssl-with-bazel/crypto/evp/p_dh.cc +198 -25
- data/third_party/boringssl-with-bazel/crypto/evp/p_dsa.cc +333 -0
- data/third_party/boringssl-with-bazel/crypto/evp/p_ec.cc +427 -42
- data/third_party/boringssl-with-bazel/crypto/evp/p_ed25519.cc +270 -14
- data/third_party/boringssl-with-bazel/crypto/evp/p_hkdf.cc +70 -102
- data/third_party/boringssl-with-bazel/crypto/evp/p_mldsa.cc +549 -0
- data/third_party/boringssl-with-bazel/crypto/evp/p_mlkem.cc +485 -0
- data/third_party/boringssl-with-bazel/crypto/evp/p_rsa.cc +666 -158
- data/third_party/boringssl-with-bazel/crypto/evp/p_x25519.cc +290 -28
- data/third_party/boringssl-with-bazel/crypto/evp/p_xwing.cc +273 -0
- data/third_party/boringssl-with-bazel/crypto/evp/pbkdf.cc +14 -7
- data/third_party/boringssl-with-bazel/crypto/evp/print.cc +34 -89
- data/third_party/boringssl-with-bazel/crypto/evp/scrypt.cc +23 -21
- data/third_party/boringssl-with-bazel/crypto/evp/sign.cc +23 -42
- data/third_party/boringssl-with-bazel/crypto/ex_data.cc +40 -41
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/aes/aes.cc.inc +34 -28
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/aes/aes_nohw.cc.inc +119 -121
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/aes/cbc.cc.inc +16 -14
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/aes/cfb.cc.inc +12 -10
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/aes/ctr.cc.inc +7 -5
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/aes/gcm.cc.inc +39 -29
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/aes/gcm_nohw.cc.inc +15 -13
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/aes/internal.h +193 -177
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/aes/key_wrap.cc.inc +5 -3
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/aes/mode_wrappers.cc.inc +7 -3
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/aes/ofb.cc.inc +7 -5
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/bcm.cc +24 -19
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/bcm_interface.h +512 -384
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/bn/add.cc.inc +7 -5
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/bn/asm/x86_64-gcc.cc.inc +63 -44
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/bn/bn.cc.inc +40 -37
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/bn/bytes.cc.inc +27 -22
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/bn/cmp.cc.inc +9 -7
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/bn/ctx.cc.inc +62 -126
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/bn/div.cc.inc +92 -167
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/bn/div_extra.cc.inc +15 -12
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/bn/exponentiation.cc.inc +96 -93
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/bn/gcd.cc.inc +73 -92
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/bn/gcd_extra.cc.inc +59 -71
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/bn/generic.cc.inc +54 -57
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/bn/internal.h +333 -255
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/bn/jacobi.cc.inc +12 -19
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/bn/montgomery.cc.inc +80 -95
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/bn/montgomery_inv.cc.inc +53 -96
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/bn/mul.cc.inc +58 -419
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/bn/prime.cc.inc +164 -213
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/bn/random.cc.inc +27 -26
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/bn/rsaz_exp.cc.inc +12 -10
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/bn/rsaz_exp.h +47 -49
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/bn/shift.cc.inc +14 -17
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/bn/sqrt.cc.inc +19 -108
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/cipher/aead.cc.inc +427 -105
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/cipher/cipher.cc.inc +412 -212
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/cipher/e_aes.cc.inc +230 -225
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/cipher/e_aesccm.cc.inc +115 -84
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/cipher/internal.h +374 -27
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/cmac/cmac.cc.inc +28 -23
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/delocate.h +36 -40
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/dh/check.cc.inc +68 -78
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/dh/dh.cc.inc +154 -196
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/dh/internal.h +24 -24
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/digest/digest.cc.inc +40 -69
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/digest/digests.cc.inc +13 -7
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/digest/internal.h +13 -11
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/digest/md32_common.h +86 -81
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/digestsign/digestsign.cc.inc +38 -34
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/ec/ec.cc.inc +187 -196
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/ec/ec_key.cc.inc +196 -154
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/ec/ec_montgomery.cc.inc +65 -125
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/ec/felem.cc.inc +85 -22
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/ec/internal.h +281 -287
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/ec/oct.cc.inc +23 -22
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/ec/p256.cc.inc +514 -573
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/ec/p256_internal.h +193 -0
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/ec/scalar.cc.inc +44 -39
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/ec/simple.cc.inc +58 -90
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/ec/simple_mul.cc.inc +39 -34
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/ec/util.cc.inc +6 -3
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/ec/wnaf.cc.inc +23 -20
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/ecdh/ecdh.cc.inc +6 -3
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/ecdsa/ecdsa.cc.inc +47 -37
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/ecdsa/internal.h +5 -10
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/entropy/internal.h +38 -0
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/entropy/jitter.cc.inc +463 -0
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/entropy/sha512.cc.inc +329 -0
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/hkdf/hkdf.cc.inc +8 -6
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/hmac/hmac.cc.inc +19 -16
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/keccak/internal.h +41 -15
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/keccak/keccak.cc.inc +172 -44
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/mldsa/fips_known_values.inc +5 -5
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/mldsa/mldsa.cc.inc +1632 -766
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/mlkem/fips_known_values.inc +5 -5
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/mlkem/mlkem.cc.inc +740 -436
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/rand/android_entropy_client.cc.inc +82 -0
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/rand/ctrdrbg.cc.inc +240 -53
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/rand/internal.h +41 -26
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/rand/rand.cc.inc +221 -218
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/rsa/internal.h +64 -67
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/rsa/padding.cc.inc +49 -57
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/rsa/rsa.cc.inc +247 -234
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/rsa/rsa_impl.cc.inc +392 -692
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/self_check/fips.cc.inc +10 -10
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/self_check/self_check.cc.inc +479 -449
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/service_indicator/internal.h +34 -11
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/service_indicator/service_indicator.cc.inc +46 -43
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/sha/internal.h +61 -70
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/sha/sha1.cc.inc +27 -13
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/sha/sha256.cc.inc +46 -30
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/sha/sha512.cc.inc +47 -47
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/slhdsa/address.h +98 -73
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/slhdsa/fors.cc.inc +108 -98
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/slhdsa/fors.h +14 -24
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/slhdsa/merkle.cc.inc +94 -91
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/slhdsa/merkle.h +19 -31
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/slhdsa/params.h +156 -56
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/slhdsa/slhdsa.cc.inc +318 -132
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/slhdsa/thash.cc.inc +234 -81
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/slhdsa/thash.h +20 -34
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/slhdsa/wots.cc.inc +97 -96
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/slhdsa/wots.h +10 -20
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/tls/internal.h +2 -16
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/tls/kdf.cc.inc +26 -26
- data/third_party/boringssl-with-bazel/crypto/fuzzer_mode.cc +5 -5
- data/third_party/boringssl-with-bazel/crypto/hpke/hpke.cc +461 -97
- data/third_party/boringssl-with-bazel/crypto/hrss/hrss.cc +153 -149
- data/third_party/boringssl-with-bazel/crypto/hrss/internal.h +9 -13
- data/third_party/boringssl-with-bazel/crypto/internal.h +531 -394
- data/third_party/boringssl-with-bazel/crypto/kyber/internal.h +117 -12
- data/third_party/boringssl-with-bazel/crypto/kyber/kyber.cc +59 -58
- data/third_party/boringssl-with-bazel/crypto/lhash/internal.h +38 -37
- data/third_party/boringssl-with-bazel/crypto/lhash/lhash.cc +68 -65
- data/third_party/boringssl-with-bazel/crypto/md4/md4.cc +19 -6
- data/third_party/boringssl-with-bazel/crypto/md5/internal.h +6 -9
- data/third_party/boringssl-with-bazel/crypto/md5/md5.cc +18 -6
- data/third_party/boringssl-with-bazel/crypto/mem.cc +61 -65
- data/third_party/boringssl-with-bazel/crypto/mem_internal.h +671 -0
- data/third_party/boringssl-with-bazel/crypto/mldsa/mldsa.cc +238 -32
- data/third_party/boringssl-with-bazel/crypto/mlkem/mlkem.cc +21 -65
- data/third_party/boringssl-with-bazel/crypto/obj/obj.cc +132 -157
- data/third_party/boringssl-with-bazel/crypto/obj/obj_dat.h +79 -1
- data/third_party/boringssl-with-bazel/crypto/obj/obj_xref.cc +14 -11
- data/third_party/boringssl-with-bazel/crypto/params_internal.h +30 -0
- data/third_party/boringssl-with-bazel/crypto/pem/internal.h +20 -15
- data/third_party/boringssl-with-bazel/crypto/pem/pem_all.cc +20 -19
- data/third_party/boringssl-with-bazel/crypto/pem/pem_info.cc +72 -76
- data/third_party/boringssl-with-bazel/crypto/pem/pem_lib.cc +215 -217
- data/third_party/boringssl-with-bazel/crypto/pem/pem_oth.cc +6 -6
- data/third_party/boringssl-with-bazel/crypto/pem/pem_pk8.cc +13 -13
- data/third_party/boringssl-with-bazel/crypto/pem/pem_pkey.cc +11 -11
- data/third_party/boringssl-with-bazel/crypto/pkcs7/internal.h +12 -17
- data/third_party/boringssl-with-bazel/crypto/pkcs7/pkcs7.cc +29 -27
- data/third_party/boringssl-with-bazel/crypto/pkcs7/pkcs7_x509.cc +55 -49
- data/third_party/boringssl-with-bazel/crypto/pkcs8/internal.h +21 -26
- data/third_party/boringssl-with-bazel/crypto/pkcs8/p5_pbev2.cc +33 -31
- data/third_party/boringssl-with-bazel/crypto/pkcs8/pkcs8.cc +73 -81
- data/third_party/boringssl-with-bazel/crypto/pkcs8/pkcs8_x509.cc +139 -138
- data/third_party/boringssl-with-bazel/crypto/poly1305/internal.h +3 -7
- data/third_party/boringssl-with-bazel/crypto/poly1305/poly1305.cc +5 -4
- data/third_party/boringssl-with-bazel/crypto/poly1305/poly1305_arm.cc +43 -47
- data/third_party/boringssl-with-bazel/crypto/poly1305/poly1305_vec.cc +29 -26
- data/third_party/boringssl-with-bazel/crypto/pool/internal.h +64 -20
- data/third_party/boringssl-with-bazel/crypto/pool/pool.cc +177 -157
- data/third_party/boringssl-with-bazel/crypto/rand/deterministic.cc +9 -16
- data/third_party/boringssl-with-bazel/crypto/rand/fork_detect.cc +70 -42
- data/third_party/boringssl-with-bazel/crypto/rand/forkunsafe.cc +7 -7
- data/third_party/boringssl-with-bazel/crypto/rand/getentropy.cc +6 -13
- data/third_party/boringssl-with-bazel/crypto/rand/internal.h +16 -4
- data/third_party/boringssl-with-bazel/crypto/rand/ios.cc +4 -11
- data/third_party/boringssl-with-bazel/crypto/rand/rand.cc +11 -9
- data/third_party/boringssl-with-bazel/crypto/rand/trusty.cc +4 -11
- data/third_party/boringssl-with-bazel/crypto/rand/urandom.cc +16 -195
- data/third_party/boringssl-with-bazel/crypto/rand/windows.cc +12 -19
- data/third_party/boringssl-with-bazel/crypto/refcount.cc +7 -17
- data/third_party/boringssl-with-bazel/crypto/rsa/internal.h +22 -7
- data/third_party/boringssl-with-bazel/crypto/rsa/rsa_asn1.cc +199 -78
- data/third_party/boringssl-with-bazel/crypto/rsa/rsa_crypt.cc +49 -50
- data/third_party/boringssl-with-bazel/crypto/rsa/rsa_extra.cc +11 -0
- data/third_party/boringssl-with-bazel/crypto/rsa/rsa_print.cc +4 -6
- data/third_party/boringssl-with-bazel/crypto/sha/sha1.cc +3 -0
- data/third_party/boringssl-with-bazel/crypto/sha/sha256.cc +3 -1
- data/third_party/boringssl-with-bazel/crypto/sha/sha512.cc +6 -4
- data/third_party/boringssl-with-bazel/crypto/siphash/siphash.cc +2 -0
- data/third_party/boringssl-with-bazel/crypto/slhdsa/slhdsa.cc +43 -6
- data/third_party/boringssl-with-bazel/crypto/spake2plus/internal.h +31 -31
- data/third_party/boringssl-with-bazel/crypto/spake2plus/spake2plus.cc +1 -1
- data/third_party/boringssl-with-bazel/crypto/stack/stack.cc +89 -130
- data/third_party/boringssl-with-bazel/crypto/thread.cc +14 -14
- data/third_party/boringssl-with-bazel/crypto/thread_none.cc +10 -13
- data/third_party/boringssl-with-bazel/crypto/thread_pthread.cc +22 -35
- data/third_party/boringssl-with-bazel/crypto/thread_win.cc +29 -40
- data/third_party/boringssl-with-bazel/crypto/trust_token/internal.h +81 -88
- data/third_party/boringssl-with-bazel/crypto/trust_token/pmbtoken.cc +160 -144
- data/third_party/boringssl-with-bazel/crypto/trust_token/trust_token.cc +96 -80
- data/third_party/boringssl-with-bazel/crypto/trust_token/voprf.cc +90 -87
- data/third_party/boringssl-with-bazel/crypto/x509/a_digest.cc +5 -5
- data/third_party/boringssl-with-bazel/crypto/x509/a_sign.cc +51 -48
- data/third_party/boringssl-with-bazel/crypto/x509/a_verify.cc +30 -34
- data/third_party/boringssl-with-bazel/crypto/x509/algorithm.cc +47 -16
- data/third_party/boringssl-with-bazel/crypto/x509/asn1_gen.cc +41 -43
- data/third_party/boringssl-with-bazel/crypto/x509/by_dir.cc +183 -237
- data/third_party/boringssl-with-bazel/crypto/x509/by_file.cc +29 -30
- data/third_party/boringssl-with-bazel/crypto/x509/internal.h +276 -180
- data/third_party/boringssl-with-bazel/crypto/x509/name_print.cc +15 -13
- data/third_party/boringssl-with-bazel/crypto/x509/policy.cc +415 -525
- data/third_party/boringssl-with-bazel/crypto/x509/rsa_pss.cc +94 -271
- data/third_party/boringssl-with-bazel/crypto/x509/t_crl.cc +11 -8
- data/third_party/boringssl-with-bazel/crypto/x509/t_req.cc +26 -23
- data/third_party/boringssl-with-bazel/crypto/x509/t_x509.cc +26 -22
- data/third_party/boringssl-with-bazel/crypto/x509/t_x509a.cc +3 -1
- data/third_party/boringssl-with-bazel/crypto/x509/v3_akey.cc +69 -76
- data/third_party/boringssl-with-bazel/crypto/x509/v3_akeya.cc +2 -2
- data/third_party/boringssl-with-bazel/crypto/x509/v3_alt.cc +112 -69
- data/third_party/boringssl-with-bazel/crypto/x509/v3_bcons.cc +15 -14
- data/third_party/boringssl-with-bazel/crypto/x509/v3_bitst.cc +16 -18
- data/third_party/boringssl-with-bazel/crypto/x509/v3_conf.cc +62 -67
- data/third_party/boringssl-with-bazel/crypto/x509/v3_cpols.cc +143 -170
- data/third_party/boringssl-with-bazel/crypto/x509/v3_crld.cc +121 -165
- data/third_party/boringssl-with-bazel/crypto/x509/v3_enum.cc +13 -12
- data/third_party/boringssl-with-bazel/crypto/x509/v3_extku.cc +17 -34
- data/third_party/boringssl-with-bazel/crypto/x509/v3_genn.cc +20 -10
- data/third_party/boringssl-with-bazel/crypto/x509/v3_ia5.cc +22 -18
- data/third_party/boringssl-with-bazel/crypto/x509/v3_info.cc +45 -47
- data/third_party/boringssl-with-bazel/crypto/x509/v3_int.cc +35 -33
- data/third_party/boringssl-with-bazel/crypto/x509/v3_lib.cc +106 -61
- data/third_party/boringssl-with-bazel/crypto/x509/v3_ncons.cc +642 -358
- data/third_party/boringssl-with-bazel/crypto/x509/v3_ocsp.cc +25 -22
- data/third_party/boringssl-with-bazel/crypto/x509/v3_pcons.cc +15 -14
- data/third_party/boringssl-with-bazel/crypto/x509/v3_pmaps.cc +16 -15
- data/third_party/boringssl-with-bazel/crypto/x509/v3_prn.cc +6 -6
- data/third_party/boringssl-with-bazel/crypto/x509/v3_purp.cc +150 -137
- data/third_party/boringssl-with-bazel/crypto/x509/v3_skey.cc +23 -26
- data/third_party/boringssl-with-bazel/crypto/x509/v3_utl.cc +151 -178
- data/third_party/boringssl-with-bazel/crypto/x509/x509.cc +1 -1
- data/third_party/boringssl-with-bazel/crypto/x509/x509_att.cc +32 -30
- data/third_party/boringssl-with-bazel/crypto/x509/x509_cmp.cc +95 -88
- data/third_party/boringssl-with-bazel/crypto/x509/x509_d2.cc +9 -9
- data/third_party/boringssl-with-bazel/crypto/x509/x509_def.cc +6 -8
- data/third_party/boringssl-with-bazel/crypto/x509/x509_ext.cc +46 -24
- data/third_party/boringssl-with-bazel/crypto/x509/x509_lu.cc +211 -195
- data/third_party/boringssl-with-bazel/crypto/x509/x509_obj.cc +20 -16
- data/third_party/boringssl-with-bazel/crypto/x509/x509_req.cc +37 -46
- data/third_party/boringssl-with-bazel/crypto/x509/x509_set.cc +62 -90
- data/third_party/boringssl-with-bazel/crypto/x509/x509_trs.cc +18 -13
- data/third_party/boringssl-with-bazel/crypto/x509/x509_v3.cc +33 -33
- data/third_party/boringssl-with-bazel/crypto/x509/x509_vfy.cc +109 -110
- data/third_party/boringssl-with-bazel/crypto/x509/x509_vpm.cc +56 -47
- data/third_party/boringssl-with-bazel/crypto/x509/x509cset.cc +27 -40
- data/third_party/boringssl-with-bazel/crypto/x509/x509name.cc +77 -67
- data/third_party/boringssl-with-bazel/crypto/x509/x509rset.cc +5 -17
- data/third_party/boringssl-with-bazel/crypto/x509/x509spki.cc +13 -13
- data/third_party/boringssl-with-bazel/crypto/x509/x_algor.cc +131 -24
- data/third_party/boringssl-with-bazel/crypto/x509/x_all.cc +72 -39
- data/third_party/boringssl-with-bazel/crypto/x509/x_attrib.cc +10 -4
- data/third_party/boringssl-with-bazel/crypto/x509/x_crl.cc +77 -44
- data/third_party/boringssl-with-bazel/crypto/x509/x_exten.cc +6 -0
- data/third_party/boringssl-with-bazel/crypto/x509/x_name.cc +311 -383
- data/third_party/boringssl-with-bazel/crypto/x509/x_pubkey.cc +129 -82
- data/third_party/boringssl-with-bazel/crypto/x509/x_req.cc +11 -6
- data/third_party/boringssl-with-bazel/crypto/x509/x_sig.cc +4 -4
- data/third_party/boringssl-with-bazel/crypto/x509/x_spki.cc +11 -1
- data/third_party/boringssl-with-bazel/crypto/x509/x_x509.cc +285 -280
- data/third_party/boringssl-with-bazel/crypto/x509/x_x509a.cc +60 -60
- data/third_party/boringssl-with-bazel/crypto/xwing/xwing.cc +257 -0
- data/third_party/boringssl-with-bazel/gen/boringssl_prefix_symbols_internal_x86_64_win_asm.inc +301 -0
- data/third_party/boringssl-with-bazel/gen/boringssl_prefix_symbols_internal_x86_win_asm.inc +301 -0
- data/third_party/boringssl-with-bazel/gen/crypto/err_data.cc +526 -500
- data/third_party/boringssl-with-bazel/include/openssl/aead.h +286 -114
- data/third_party/boringssl-with-bazel/include/openssl/aes.h +43 -43
- data/third_party/boringssl-with-bazel/include/openssl/asm_base.h +29 -16
- data/third_party/boringssl-with-bazel/include/openssl/asn1.h +641 -631
- data/third_party/boringssl-with-bazel/include/openssl/asn1t.h +7 -9
- data/third_party/boringssl-with-bazel/include/openssl/base.h +34 -54
- data/third_party/boringssl-with-bazel/include/openssl/base64.h +30 -30
- data/third_party/boringssl-with-bazel/include/openssl/bio.h +373 -316
- data/third_party/boringssl-with-bazel/include/openssl/blake2.h +15 -11
- data/third_party/boringssl-with-bazel/include/openssl/blowfish.h +10 -3
- data/third_party/boringssl-with-bazel/include/openssl/bn.h +298 -306
- data/third_party/boringssl-with-bazel/include/openssl/buf.h +14 -14
- data/third_party/boringssl-with-bazel/include/openssl/bytestring.h +272 -207
- data/third_party/boringssl-with-bazel/include/openssl/cast.h +45 -8
- data/third_party/boringssl-with-bazel/include/openssl/chacha.h +3 -3
- data/third_party/boringssl-with-bazel/include/openssl/cipher.h +334 -152
- data/third_party/boringssl-with-bazel/include/openssl/cmac.h +13 -13
- data/third_party/boringssl-with-bazel/include/openssl/cms.h +35 -34
- data/third_party/boringssl-with-bazel/include/openssl/conf.h +15 -14
- data/third_party/boringssl-with-bazel/include/openssl/crypto.h +15 -13
- data/third_party/boringssl-with-bazel/include/openssl/ctrdrbg.h +49 -15
- data/third_party/boringssl-with-bazel/include/openssl/curve25519.h +24 -24
- data/third_party/boringssl-with-bazel/include/openssl/des.h +22 -16
- data/third_party/boringssl-with-bazel/include/openssl/dh.h +95 -95
- data/third_party/boringssl-with-bazel/include/openssl/digest.h +140 -71
- data/third_party/boringssl-with-bazel/include/openssl/dsa.h +101 -101
- data/third_party/boringssl-with-bazel/include/openssl/ec.h +143 -119
- data/third_party/boringssl-with-bazel/include/openssl/ec_key.h +97 -97
- data/third_party/boringssl-with-bazel/include/openssl/ecdh.h +9 -9
- data/third_party/boringssl-with-bazel/include/openssl/ecdsa.h +89 -46
- data/third_party/boringssl-with-bazel/include/openssl/engine.h +5 -5
- data/third_party/boringssl-with-bazel/include/openssl/err.h +73 -71
- data/third_party/boringssl-with-bazel/include/openssl/evp.h +824 -344
- data/third_party/boringssl-with-bazel/include/openssl/evp_errors.h +9 -2
- data/third_party/boringssl-with-bazel/include/openssl/ex_data.h +27 -32
- data/third_party/boringssl-with-bazel/include/openssl/hkdf.h +6 -6
- data/third_party/boringssl-with-bazel/include/openssl/hmac.h +31 -31
- data/third_party/boringssl-with-bazel/include/openssl/hpke.h +133 -117
- data/third_party/boringssl-with-bazel/include/openssl/hrss.h +14 -8
- data/third_party/boringssl-with-bazel/include/openssl/kdf.h +20 -19
- data/third_party/boringssl-with-bazel/include/openssl/lhash.h +4 -25
- data/third_party/boringssl-with-bazel/include/openssl/md4.h +14 -7
- data/third_party/boringssl-with-bazel/include/openssl/md5.h +7 -7
- data/third_party/boringssl-with-bazel/include/openssl/mem.h +38 -38
- data/third_party/boringssl-with-bazel/include/openssl/mldsa.h +380 -24
- data/third_party/boringssl-with-bazel/include/openssl/mlkem.h +43 -43
- data/third_party/boringssl-with-bazel/include/openssl/nid.h +1297 -2
- data/third_party/boringssl-with-bazel/include/openssl/obj.h +49 -49
- data/third_party/boringssl-with-bazel/include/openssl/opensslconf.h +30 -0
- data/third_party/boringssl-with-bazel/include/openssl/params.h +42 -0
- data/third_party/boringssl-with-bazel/include/openssl/pem.h +39 -30
- data/third_party/boringssl-with-bazel/include/openssl/pkcs7.h +40 -40
- data/third_party/boringssl-with-bazel/include/openssl/pkcs8.h +69 -63
- data/third_party/boringssl-with-bazel/include/openssl/poly1305.h +8 -5
- data/third_party/boringssl-with-bazel/include/openssl/pool.h +54 -25
- data/third_party/boringssl-with-bazel/include/openssl/posix_time.h +6 -6
- data/third_party/boringssl-with-bazel/include/openssl/prefix_symbols.h +7866 -0
- data/third_party/boringssl-with-bazel/include/openssl/prefix_symbols_internal_S.h +585 -0
- data/third_party/boringssl-with-bazel/include/openssl/prefix_symbols_internal_c.h +305 -0
- data/third_party/boringssl-with-bazel/include/openssl/rand.h +18 -18
- data/third_party/boringssl-with-bazel/include/openssl/rc4.h +4 -4
- data/third_party/boringssl-with-bazel/include/openssl/ripemd.h +15 -10
- data/third_party/boringssl-with-bazel/include/openssl/rsa.h +272 -235
- data/third_party/boringssl-with-bazel/include/openssl/service_indicator.h +4 -81
- data/third_party/boringssl-with-bazel/include/openssl/sha.h +43 -166
- data/third_party/boringssl-with-bazel/include/openssl/sha2.h +201 -0
- data/third_party/boringssl-with-bazel/include/openssl/slhdsa.h +100 -48
- data/third_party/boringssl-with-bazel/include/openssl/span.h +190 -75
- data/third_party/boringssl-with-bazel/include/openssl/ssl.h +2168 -1567
- data/third_party/boringssl-with-bazel/include/openssl/ssl3.h +11 -69
- data/third_party/boringssl-with-bazel/include/openssl/stack.h +135 -80
- data/third_party/boringssl-with-bazel/include/openssl/target.h +13 -1
- data/third_party/boringssl-with-bazel/include/openssl/thread.h +0 -10
- data/third_party/boringssl-with-bazel/include/openssl/tls1.h +31 -310
- data/third_party/boringssl-with-bazel/include/openssl/tls_prf.h +47 -0
- data/third_party/boringssl-with-bazel/include/openssl/trust_token.h +97 -92
- data/third_party/boringssl-with-bazel/include/openssl/type_check.h +1 -1
- data/third_party/boringssl-with-bazel/include/openssl/x509.h +1805 -1857
- data/third_party/boringssl-with-bazel/include/openssl/x509v3.h +1 -1
- data/third_party/boringssl-with-bazel/include/openssl/xwing.h +115 -0
- data/third_party/boringssl-with-bazel/ssl/bio_ssl.cc +24 -19
- data/third_party/boringssl-with-bazel/ssl/d1_both.cc +59 -57
- data/third_party/boringssl-with-bazel/ssl/d1_lib.cc +53 -42
- data/third_party/boringssl-with-bazel/ssl/d1_pkt.cc +4 -4
- data/third_party/boringssl-with-bazel/ssl/d1_srtp.cc +2 -2
- data/third_party/boringssl-with-bazel/ssl/dtls_method.cc +10 -10
- data/third_party/boringssl-with-bazel/ssl/dtls_record.cc +6 -6
- data/third_party/boringssl-with-bazel/ssl/encrypted_client_hello.cc +61 -71
- data/third_party/boringssl-with-bazel/ssl/extensions.cc +967 -366
- data/third_party/boringssl-with-bazel/ssl/handoff.cc +77 -38
- data/third_party/boringssl-with-bazel/ssl/handshake.cc +63 -30
- data/third_party/boringssl-with-bazel/ssl/handshake_client.cc +129 -85
- data/third_party/boringssl-with-bazel/ssl/handshake_server.cc +116 -68
- data/third_party/boringssl-with-bazel/ssl/internal.h +983 -1207
- data/third_party/boringssl-with-bazel/ssl/s3_both.cc +34 -29
- data/third_party/boringssl-with-bazel/ssl/s3_lib.cc +4 -3
- data/third_party/boringssl-with-bazel/ssl/s3_pkt.cc +12 -12
- data/third_party/boringssl-with-bazel/ssl/ssl_aead_ctx.cc +5 -5
- data/third_party/boringssl-with-bazel/ssl/ssl_asn1.cc +114 -59
- data/third_party/boringssl-with-bazel/ssl/ssl_buffer.cc +17 -18
- data/third_party/boringssl-with-bazel/ssl/ssl_cert.cc +99 -61
- data/third_party/boringssl-with-bazel/ssl/ssl_cipher.cc +143 -134
- data/third_party/boringssl-with-bazel/ssl/ssl_credential.cc +188 -90
- data/third_party/boringssl-with-bazel/ssl/ssl_file.cc +132 -225
- data/third_party/boringssl-with-bazel/ssl/ssl_key_share.cc +79 -7
- data/third_party/boringssl-with-bazel/ssl/ssl_lib.cc +698 -302
- data/third_party/boringssl-with-bazel/ssl/ssl_privkey.cc +102 -45
- data/third_party/boringssl-with-bazel/ssl/ssl_session.cc +117 -102
- data/third_party/boringssl-with-bazel/ssl/ssl_transcript.cc +3 -3
- data/third_party/boringssl-with-bazel/ssl/ssl_versions.cc +24 -24
- data/third_party/boringssl-with-bazel/ssl/ssl_x509.cc +184 -170
- data/third_party/boringssl-with-bazel/ssl/t1_enc.cc +12 -10
- data/third_party/boringssl-with-bazel/ssl/tls13_both.cc +86 -54
- data/third_party/boringssl-with-bazel/ssl/tls13_client.cc +176 -90
- data/third_party/boringssl-with-bazel/ssl/tls13_enc.cc +166 -112
- data/third_party/boringssl-with-bazel/ssl/tls13_server.cc +188 -97
- data/third_party/boringssl-with-bazel/ssl/tls_method.cc +23 -23
- data/third_party/boringssl-with-bazel/ssl/tls_record.cc +17 -14
- data/third_party/boringssl-with-bazel/third_party/fiat/bedrock_unverified_bareminimum.c.inc +47 -0
- data/third_party/boringssl-with-bazel/third_party/fiat/bedrock_unverified_platform.c.inc +137 -0
- data/third_party/boringssl-with-bazel/third_party/fiat/curve25519_64_adx.h +37 -33
- data/third_party/boringssl-with-bazel/third_party/fiat/p256_64.h +4 -93
- data/third_party/boringssl-with-bazel/third_party/fiat/p256_64_msvc.h +4 -69
- data/third_party/boringssl-with-bazel/third_party/fiat/p256_field_32.br.c.inc +71 -0
- data/third_party/boringssl-with-bazel/third_party/fiat/p256_field_64.br.c.inc +84 -0
- data/third_party/boringssl-with-bazel/third_party/fiat/p256_point.br.c.inc +166 -0
- metadata +77 -52
- data/src/core/ext/transport/chttp2/transport/bin_decoder.cc +0 -240
- data/src/core/ext/transport/chttp2/transport/bin_decoder.h +0 -56
- data/src/core/ext/upb-gen/src/proto/grpc/health/v1/health.upb.h +0 -157
- data/src/core/ext/upb-gen/src/proto/grpc/health/v1/health.upb_minitable.c +0 -72
- data/src/core/ext/upbdefs-gen/src/proto/grpc/lookup/v1/rls_config.upbdefs.c +0 -181
- data/third_party/abseil-cpp/absl/base/internal/identity.h +0 -39
- data/third_party/abseil-cpp/absl/base/internal/nullability_deprecated.h +0 -106
- data/third_party/abseil-cpp/absl/hash/internal/low_level_hash.cc +0 -105
- data/third_party/abseil-cpp/absl/hash/internal/low_level_hash.h +0 -50
- data/third_party/abseil-cpp/absl/strings/string_view.cc +0 -257
- data/third_party/boringssl-with-bazel/crypto/evp/p_dh_asn1.cc +0 -142
- data/third_party/boringssl-with-bazel/crypto/evp/p_dsa_asn1.cc +0 -279
- data/third_party/boringssl-with-bazel/crypto/evp/p_ec_asn1.cc +0 -286
- data/third_party/boringssl-with-bazel/crypto/evp/p_ed25519_asn1.cc +0 -225
- data/third_party/boringssl-with-bazel/crypto/evp/p_rsa_asn1.cc +0 -198
- data/third_party/boringssl-with-bazel/crypto/evp/p_x25519_asn1.cc +0 -237
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/ec/p224-64.cc.inc +0 -1163
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/ec/p256-nistz.cc.inc +0 -741
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/ec/p256-nistz.h +0 -207
- data/third_party/boringssl-with-bazel/crypto/fipsmodule/rsa/blinding.cc.inc +0 -147
- data/third_party/boringssl-with-bazel/crypto/rand/getrandom_fillin.h +0 -64
- data/third_party/boringssl-with-bazel/crypto/rand/passive.cc +0 -178
- data/third_party/boringssl-with-bazel/crypto/x509/ext_dat.h +0 -92
- data/third_party/boringssl-with-bazel/include/openssl/bcm_public.h +0 -82
- data/third_party/boringssl-with-bazel/include/openssl/experimental/kyber.h +0 -146
|
@@ -150,11 +150,11 @@
|
|
|
150
150
|
// To `insert`, we compose `unchecked_insert` with `find`. We compute `h(x)` and
|
|
151
151
|
// perform a `find` to see if it's already present; if it is, we're done. If
|
|
152
152
|
// it's not, we may decide the table is getting overcrowded (i.e. the load
|
|
153
|
-
// factor is greater than 7/8 for big tables;
|
|
154
|
-
// factor of 1); in this case, we allocate a bigger array,
|
|
155
|
-
// each element of the table into the new array (we know that
|
|
156
|
-
// will insert an already-present value), and discard the old
|
|
157
|
-
// this point, we may `unchecked_insert` the value `x`.
|
|
153
|
+
// factor is greater than 7/8 for big tables; tables smaller than one probing
|
|
154
|
+
// group use a max load factor of 1); in this case, we allocate a bigger array,
|
|
155
|
+
// `unchecked_insert` each element of the table into the new array (we know that
|
|
156
|
+
// no insertion here will insert an already-present value), and discard the old
|
|
157
|
+
// backing array. At this point, we may `unchecked_insert` the value `x`.
|
|
158
158
|
//
|
|
159
159
|
// Below, `unchecked_insert` is partly implemented by `prepare_insert`, which
|
|
160
160
|
// presents a viable, initialized slot pointee to the caller.
|
|
@@ -194,6 +194,7 @@
|
|
|
194
194
|
#include <utility>
|
|
195
195
|
|
|
196
196
|
#include "absl/base/attributes.h"
|
|
197
|
+
#include "absl/base/casts.h"
|
|
197
198
|
#include "absl/base/config.h"
|
|
198
199
|
#include "absl/base/internal/endian.h"
|
|
199
200
|
#include "absl/base/internal/iterator_traits.h"
|
|
@@ -220,6 +221,14 @@
|
|
|
220
221
|
#include "absl/numeric/bits.h"
|
|
221
222
|
#include "absl/utility/utility.h"
|
|
222
223
|
|
|
224
|
+
#if ABSL_INTERNAL_CPLUSPLUS_LANG >= 202002L
|
|
225
|
+
#include <ranges> // NOLINT(build/c++20)
|
|
226
|
+
#endif
|
|
227
|
+
|
|
228
|
+
#ifdef __BMI2__
|
|
229
|
+
#include <bmi2intrin.h>
|
|
230
|
+
#endif // __BMI2__
|
|
231
|
+
|
|
223
232
|
namespace absl {
|
|
224
233
|
ABSL_NAMESPACE_BEGIN
|
|
225
234
|
namespace container_internal {
|
|
@@ -282,10 +291,8 @@ void SwapAlloc(AllocType& lhs, AllocType& rhs,
|
|
|
282
291
|
swap(lhs, rhs);
|
|
283
292
|
}
|
|
284
293
|
template <typename AllocType>
|
|
285
|
-
void SwapAlloc(AllocType& lhs, AllocType& rhs,
|
|
294
|
+
void SwapAlloc([[maybe_unused]] AllocType& lhs, [[maybe_unused]] AllocType& rhs,
|
|
286
295
|
std::false_type /* propagate_on_container_swap */) {
|
|
287
|
-
(void)lhs;
|
|
288
|
-
(void)rhs;
|
|
289
296
|
assert(lhs == rhs &&
|
|
290
297
|
"It's UB to call swap with unequal non-propagating allocators.");
|
|
291
298
|
}
|
|
@@ -298,57 +305,6 @@ void CopyAlloc(AllocType& lhs, AllocType& rhs,
|
|
|
298
305
|
template <typename AllocType>
|
|
299
306
|
void CopyAlloc(AllocType&, AllocType&, std::false_type /* propagate_alloc */) {}
|
|
300
307
|
|
|
301
|
-
// The state for a probe sequence.
|
|
302
|
-
//
|
|
303
|
-
// Currently, the sequence is a triangular progression of the form
|
|
304
|
-
//
|
|
305
|
-
// p(i) := Width * (i^2 + i)/2 + hash (mod mask + 1)
|
|
306
|
-
//
|
|
307
|
-
// The use of `Width` ensures that each probe step does not overlap groups;
|
|
308
|
-
// the sequence effectively outputs the addresses of *groups* (although not
|
|
309
|
-
// necessarily aligned to any boundary). The `Group` machinery allows us
|
|
310
|
-
// to check an entire group with minimal branching.
|
|
311
|
-
//
|
|
312
|
-
// Wrapping around at `mask + 1` is important, but not for the obvious reason.
|
|
313
|
-
// As described above, the first few entries of the control byte array
|
|
314
|
-
// are mirrored at the end of the array, which `Group` will find and use
|
|
315
|
-
// for selecting candidates. However, when those candidates' slots are
|
|
316
|
-
// actually inspected, there are no corresponding slots for the cloned bytes,
|
|
317
|
-
// so we need to make sure we've treated those offsets as "wrapping around".
|
|
318
|
-
//
|
|
319
|
-
// It turns out that this probe sequence visits every group exactly once if the
|
|
320
|
-
// number of groups is a power of two, since (i^2+i)/2 is a bijection in
|
|
321
|
-
// Z/(2^m). See https://en.wikipedia.org/wiki/Quadratic_probing
|
|
322
|
-
template <size_t Width>
|
|
323
|
-
class probe_seq {
|
|
324
|
-
public:
|
|
325
|
-
// Creates a new probe sequence using `hash` as the initial value of the
|
|
326
|
-
// sequence and `mask` (usually the capacity of the table) as the mask to
|
|
327
|
-
// apply to each value in the progression.
|
|
328
|
-
probe_seq(size_t hash, size_t mask) {
|
|
329
|
-
ABSL_SWISSTABLE_ASSERT(((mask + 1) & mask) == 0 && "not a mask");
|
|
330
|
-
mask_ = mask;
|
|
331
|
-
offset_ = hash & mask_;
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
// The offset within the table, i.e., the value `p(i)` above.
|
|
335
|
-
size_t offset() const { return offset_; }
|
|
336
|
-
size_t offset(size_t i) const { return (offset_ + i) & mask_; }
|
|
337
|
-
|
|
338
|
-
void next() {
|
|
339
|
-
index_ += Width;
|
|
340
|
-
offset_ += index_;
|
|
341
|
-
offset_ &= mask_;
|
|
342
|
-
}
|
|
343
|
-
// 0-based probe index, a multiple of `Width`.
|
|
344
|
-
size_t index() const { return index_; }
|
|
345
|
-
|
|
346
|
-
private:
|
|
347
|
-
size_t mask_;
|
|
348
|
-
size_t offset_;
|
|
349
|
-
size_t index_ = 0;
|
|
350
|
-
};
|
|
351
|
-
|
|
352
308
|
template <class ContainerKey, class Hash, class Eq>
|
|
353
309
|
struct RequireUsableKey {
|
|
354
310
|
template <class PassedKey, class... Args>
|
|
@@ -364,48 +320,21 @@ struct IsDecomposable : std::false_type {};
|
|
|
364
320
|
|
|
365
321
|
template <class Policy, class Hash, class Eq, class... Ts>
|
|
366
322
|
struct IsDecomposable<
|
|
367
|
-
|
|
323
|
+
std::void_t<decltype(Policy::apply(
|
|
368
324
|
RequireUsableKey<typename Policy::key_type, Hash, Eq>(),
|
|
369
325
|
std::declval<Ts>()...))>,
|
|
370
326
|
Policy, Hash, Eq, Ts...> : std::true_type {};
|
|
371
327
|
|
|
372
|
-
|
|
373
|
-
template <class T>
|
|
374
|
-
constexpr bool IsNoThrowSwappable(std::true_type = {} /* is_swappable */) {
|
|
375
|
-
using std::swap;
|
|
376
|
-
return noexcept(swap(std::declval<T&>(), std::declval<T&>()));
|
|
377
|
-
}
|
|
378
|
-
template <class T>
|
|
379
|
-
constexpr bool IsNoThrowSwappable(std::false_type /* is_swappable */) {
|
|
380
|
-
return false;
|
|
381
|
-
}
|
|
328
|
+
ABSL_DLL extern ctrl_t kDefaultIterControl;
|
|
382
329
|
|
|
383
|
-
//
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
// We use these sentinel capacity values in debug mode to indicate different
|
|
387
|
-
// classes of bugs.
|
|
388
|
-
enum InvalidCapacity : size_t {
|
|
389
|
-
kAboveMaxValidCapacity = ~size_t{} - 100,
|
|
390
|
-
kReentrance,
|
|
391
|
-
kDestroyed,
|
|
392
|
-
|
|
393
|
-
// These two must be last because we use `>= kMovedFrom` to mean moved-from.
|
|
394
|
-
kMovedFrom,
|
|
395
|
-
kSelfMovedFrom,
|
|
396
|
-
};
|
|
397
|
-
|
|
398
|
-
// Returns a pointer to a control byte group that can be used by empty tables.
|
|
399
|
-
inline ctrl_t* EmptyGroup() {
|
|
400
|
-
// Const must be cast away here; no uses of this function will actually write
|
|
401
|
-
// to it because it is only used for empty tables.
|
|
402
|
-
return const_cast<ctrl_t*>(kEmptyGroup + 16);
|
|
403
|
-
}
|
|
330
|
+
// Returns a pointer to a control byte that can be used by default-constructed
|
|
331
|
+
// iterators. We don't expect this pointer to be dereferenced.
|
|
332
|
+
inline ctrl_t* DefaultIterControl() { return &kDefaultIterControl; }
|
|
404
333
|
|
|
405
334
|
// For use in SOO iterators.
|
|
406
335
|
// TODO(b/289225379): we could potentially get rid of this by adding an is_soo
|
|
407
336
|
// bit in iterators. This would add branches but reduce cache misses.
|
|
408
|
-
ABSL_DLL extern const ctrl_t kSooControl[
|
|
337
|
+
ABSL_DLL extern const ctrl_t kSooControl[2];
|
|
409
338
|
|
|
410
339
|
// Returns a pointer to a full byte followed by a sentinel byte.
|
|
411
340
|
inline ctrl_t* SooControl() {
|
|
@@ -433,6 +362,8 @@ inline bool IsEmptyGeneration(const GenerationType* generation) {
|
|
|
433
362
|
// - In order to prevent user code from depending on iteration order for small
|
|
434
363
|
// tables, we would need to randomize the iteration order somehow.
|
|
435
364
|
constexpr size_t SooCapacity() { return 1; }
|
|
365
|
+
// Maximum capacity of a table where we don't need to hash any keys.
|
|
366
|
+
constexpr size_t MaxSmallCapacity() { return 1; }
|
|
436
367
|
// Sentinel type to indicate SOO CommonFields construction.
|
|
437
368
|
struct soo_tag_t {};
|
|
438
369
|
// Sentinel type to indicate SOO CommonFields construction with full size.
|
|
@@ -444,66 +375,308 @@ struct uninitialized_tag_t {};
|
|
|
444
375
|
// Sentinel value to indicate creation of an empty table without a seed.
|
|
445
376
|
struct no_seed_empty_tag_t {};
|
|
446
377
|
|
|
378
|
+
// Returns whether `n` is a valid capacity (i.e., number of slots).
|
|
379
|
+
//
|
|
380
|
+
// A valid capacity is a non-zero integer `2^m - 1`.
|
|
381
|
+
constexpr bool IsValidCapacity(size_t n) { return ((n + 1) & n) == 0 && n > 0; }
|
|
382
|
+
|
|
383
|
+
// Whether a table is small enough that we don't need to hash any keys.
|
|
384
|
+
constexpr bool IsSmallCapacity(size_t capacity) {
|
|
385
|
+
return capacity <= MaxSmallCapacity();
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
// Converts `n` into the next valid capacity, per `IsValidCapacity`.
|
|
389
|
+
constexpr size_t NormalizeCapacity(size_t n) {
|
|
390
|
+
return n ? ~size_t{} >> countl_zero(n) : 1;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
// Returns the next valid capacity after `n`.
|
|
394
|
+
constexpr size_t NextCapacity(size_t n) {
|
|
395
|
+
ABSL_SWISSTABLE_ASSERT(IsValidCapacity(n) || n == 0);
|
|
396
|
+
return n * 2 + 1;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
// Returns the previous valid capacity before `n`.
|
|
400
|
+
constexpr size_t PreviousCapacity(size_t n) {
|
|
401
|
+
ABSL_SWISSTABLE_ASSERT(IsValidCapacity(n));
|
|
402
|
+
return n / 2;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
// General notes on capacity/growth methods below:
|
|
406
|
+
// - We use 7/8th as maximum load factor. For 16-wide groups, that gives an
|
|
407
|
+
// average of two empty slots per group.
|
|
408
|
+
// - For (capacity+1) >= Group::kWidth, growth is 7/8*capacity.
|
|
409
|
+
// - For (capacity+1) < Group::kWidth, growth == capacity. In this case, we
|
|
410
|
+
// never need to probe (the whole table fits in one group) so we don't need a
|
|
411
|
+
// load factor less than 1.
|
|
412
|
+
|
|
413
|
+
// Given `capacity`, applies the load factor; i.e., it returns the maximum
|
|
414
|
+
// number of values we should put into the table before a resizing rehash.
|
|
415
|
+
constexpr size_t CapacityToGrowth(size_t capacity) {
|
|
416
|
+
ABSL_SWISSTABLE_ASSERT(IsValidCapacity(capacity));
|
|
417
|
+
// `capacity*7/8`
|
|
418
|
+
if (Group::kWidth == 8 && capacity == 7) {
|
|
419
|
+
// x-x/8 does not work when x==7.
|
|
420
|
+
return 6;
|
|
421
|
+
}
|
|
422
|
+
return capacity - capacity / 8;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
// Given `size`, "unapplies" the load factor to find how large the capacity
|
|
426
|
+
// should be to stay within the load factor.
|
|
427
|
+
//
|
|
428
|
+
// For size == 0, returns 0.
|
|
429
|
+
// For other values, returns the same as `NormalizeCapacity(size*8/7)`.
|
|
430
|
+
constexpr size_t SizeToCapacity(size_t size) {
|
|
431
|
+
if (size == 0) {
|
|
432
|
+
return 0;
|
|
433
|
+
}
|
|
434
|
+
// The minimum possible capacity is NormalizeCapacity(size).
|
|
435
|
+
// Shifting right `~size_t{}` by `leading_zeros` yields
|
|
436
|
+
// NormalizeCapacity(size).
|
|
437
|
+
int leading_zeros = absl::countl_zero(size);
|
|
438
|
+
constexpr size_t kLast3Bits = size_t{7} << (sizeof(size_t) * 8 - 3);
|
|
439
|
+
// max_size_for_next_capacity = max_load_factor * next_capacity
|
|
440
|
+
// = (7/8) * (~size_t{} >> leading_zeros)
|
|
441
|
+
// = (7/8*~size_t{}) >> leading_zeros
|
|
442
|
+
// = kLast3Bits >> leading_zeros
|
|
443
|
+
size_t max_size_for_next_capacity = kLast3Bits >> leading_zeros;
|
|
444
|
+
// Decrease shift if size is too big for the minimum capacity.
|
|
445
|
+
leading_zeros -= static_cast<int>(size > max_size_for_next_capacity);
|
|
446
|
+
if constexpr (Group::kWidth == 8) {
|
|
447
|
+
// Formula doesn't work when size==7 for 8-wide groups.
|
|
448
|
+
leading_zeros -= (size == 7);
|
|
449
|
+
}
|
|
450
|
+
return (~size_t{}) >> leading_zeros;
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
// The mode we store capacity in the table.
|
|
454
|
+
enum HashtableCapacityStorageMode {
|
|
455
|
+
// Capacity stored as size_t as a full number.
|
|
456
|
+
kCapacityByValue,
|
|
457
|
+
// Capacity stored as uint8_t as log2, i.e. capacity = 2^capacity_ - 1.
|
|
458
|
+
kCapacityByLog,
|
|
459
|
+
};
|
|
460
|
+
|
|
461
|
+
// The number of slots in the backing array. This is always 2^N-1 for an
|
|
462
|
+
// integer N.
|
|
463
|
+
// NOTE: this class exists to simplify experiments with different ways to store
|
|
464
|
+
// capacity within size.
|
|
465
|
+
// NOTE: we tried experimenting with compressing the capacity and storing it
|
|
466
|
+
// together with size_: (a) using 6 bits to store the corresponding power (N in
|
|
467
|
+
// 2^N-1), and (b) storing 2^N as the most significant bit of size_ and storing
|
|
468
|
+
// size in the low bits. Both of these experiments were regressions, presumably
|
|
469
|
+
// because we need capacity to do find operations.
|
|
470
|
+
template <HashtableCapacityStorageMode StorageMode>
|
|
471
|
+
class HashtableCapacityImpl {
|
|
472
|
+
using IntType =
|
|
473
|
+
std::conditional_t<StorageMode == kCapacityByValue, size_t, uint8_t>;
|
|
474
|
+
|
|
475
|
+
public:
|
|
476
|
+
static constexpr HashtableCapacityImpl CreateDestroyed() {
|
|
477
|
+
return HashtableCapacityImpl(kDestroyed);
|
|
478
|
+
}
|
|
479
|
+
static constexpr HashtableCapacityImpl CreateReentrance() {
|
|
480
|
+
return HashtableCapacityImpl(kReentrance);
|
|
481
|
+
}
|
|
482
|
+
static constexpr HashtableCapacityImpl CreateMovedFrom() {
|
|
483
|
+
return HashtableCapacityImpl(kMovedFrom);
|
|
484
|
+
}
|
|
485
|
+
static constexpr HashtableCapacityImpl CreateSelfMovedFrom() {
|
|
486
|
+
return HashtableCapacityImpl(kSelfMovedFrom);
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
explicit HashtableCapacityImpl(uninitialized_tag_t) {}
|
|
490
|
+
explicit constexpr HashtableCapacityImpl(size_t capacity)
|
|
491
|
+
: capacity_data_(static_cast<IntType>(
|
|
492
|
+
StorageMode == kCapacityByValue ? capacity
|
|
493
|
+
: TrailingZeros(capacity + 1))) {
|
|
494
|
+
ABSL_SWISSTABLE_ASSERT(capacity == 0 || IsValidCapacity(capacity));
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
// Creates capacity from the value that was returned by `ToRawData()`.
|
|
498
|
+
// This is needed to use bitfield for capacity.
|
|
499
|
+
// At least on Windows combination uint8_t and uint64_t bitfield in one struct
|
|
500
|
+
// is not optimized by compiler.
|
|
501
|
+
static HashtableCapacityImpl FromRawData(uint64_t capacity) {
|
|
502
|
+
auto cap = HashtableCapacityImpl(uninitialized_tag_t{});
|
|
503
|
+
cap.capacity_data_ = static_cast<IntType>(capacity);
|
|
504
|
+
return cap;
|
|
505
|
+
}
|
|
506
|
+
IntType ToRawData() const { return capacity_data_; }
|
|
507
|
+
|
|
508
|
+
constexpr bool IsValid() const {
|
|
509
|
+
return capacity_data_ <= kAboveMaxValidCapacity;
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
constexpr bool IsDestroyed() const { return capacity_data_ == kDestroyed; }
|
|
513
|
+
constexpr bool IsReentrance() const { return capacity_data_ == kReentrance; }
|
|
514
|
+
// Returns true if the table is moved-from including self moved-from.
|
|
515
|
+
constexpr bool IsMovedFrom() const { return capacity_data_ >= kMovedFrom; }
|
|
516
|
+
constexpr bool IsSelfMovedFrom() const {
|
|
517
|
+
return capacity_data_ == kSelfMovedFrom;
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
constexpr size_t capacity() const {
|
|
521
|
+
ABSL_SWISSTABLE_ASSERT(IsValid());
|
|
522
|
+
return StorageMode == kCapacityByValue ? capacity_data_
|
|
523
|
+
: (size_t{1} << capacity_data_) - 1;
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
constexpr bool is_small() const {
|
|
527
|
+
// Small tables have capacity 0 or 1. This expression is valid for both
|
|
528
|
+
// capacity storage modes.
|
|
529
|
+
// Comparing capacity_data_ directly leads to a better generated code.
|
|
530
|
+
// One byte comparison is used before computing the capacity in order to
|
|
531
|
+
// detect small tables faster for critical path.
|
|
532
|
+
static_assert(MaxSmallCapacity() == 1);
|
|
533
|
+
return capacity_data_ <= 1;
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
constexpr size_t mask(size_t value) const {
|
|
537
|
+
#ifdef __BMI2__
|
|
538
|
+
if constexpr (StorageMode == kCapacityByLog) {
|
|
539
|
+
if constexpr (sizeof(size_t) == 8) {
|
|
540
|
+
return _bzhi_u64(value, capacity_data_);
|
|
541
|
+
} else {
|
|
542
|
+
return _bzhi_u32(value, capacity_data_);
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
#endif // __BMI2__
|
|
546
|
+
return value & capacity();
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
private:
|
|
550
|
+
// We use these sentinel capacity values in debug mode to indicate different
|
|
551
|
+
// classes of bugs.
|
|
552
|
+
enum InvalidCapacity : IntType {
|
|
553
|
+
kAboveMaxValidCapacity = (std::numeric_limits<IntType>::max)() - 100,
|
|
554
|
+
kReentrance,
|
|
555
|
+
kDestroyed,
|
|
556
|
+
|
|
557
|
+
// These two must be last because we use `>= kMovedFrom` to mean moved-from.
|
|
558
|
+
kMovedFrom,
|
|
559
|
+
kSelfMovedFrom,
|
|
560
|
+
};
|
|
561
|
+
|
|
562
|
+
explicit constexpr HashtableCapacityImpl(InvalidCapacity capacity)
|
|
563
|
+
: capacity_data_(capacity) {
|
|
564
|
+
ABSL_SWISSTABLE_ASSERT(capacity_data_ > kAboveMaxValidCapacity);
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
// Capacity is stored as a value or as a log2 depending on `StorageMode`.
|
|
568
|
+
IntType capacity_data_;
|
|
569
|
+
};
|
|
570
|
+
|
|
571
|
+
template <HashtableCapacityStorageMode StorageMode>
|
|
572
|
+
class HashtableInlineDataImpl;
|
|
573
|
+
|
|
574
|
+
// Returns next per-table seed.
|
|
575
|
+
uint16_t NextHashTableSeed();
|
|
576
|
+
|
|
447
577
|
// Per table hash salt. This gets mixed into H1 to randomize iteration order
|
|
448
578
|
// per-table.
|
|
449
579
|
// The seed is needed to ensure non-determinism of iteration order.
|
|
450
|
-
|
|
580
|
+
template <typename StorageType>
|
|
581
|
+
class PerTableSeedImpl {
|
|
451
582
|
public:
|
|
583
|
+
using IntType = StorageType;
|
|
584
|
+
|
|
452
585
|
// The number of bits in the seed.
|
|
453
586
|
// It is big enough to ensure non-determinism of iteration order.
|
|
454
587
|
// We store the seed inside a uint64_t together with size and other metadata.
|
|
455
|
-
// Using 16 bits allows us to save one `and` instruction in H1 (we use
|
|
456
|
-
// instead of
|
|
457
|
-
|
|
588
|
+
// Using 8 or 16 bits allows us to save one `and` instruction in H1 (we use
|
|
589
|
+
// zero-extended move instead of mov+and). When absl::Hash is inlined, it can
|
|
590
|
+
// also have lower latency knowing that the high bits of the seed are zero.
|
|
591
|
+
static constexpr size_t kBitCount = sizeof(IntType) * 8;
|
|
458
592
|
|
|
459
|
-
//
|
|
593
|
+
// We need to use a constant seed when the table is sampled so that sampled
|
|
594
|
+
// hashes use the same seed and can e.g. identify stuck bits accurately.
|
|
595
|
+
static constexpr IntType kSampledSeed = static_cast<IntType>(~IntType{0});
|
|
596
|
+
|
|
597
|
+
// Returns the seed for the table.
|
|
460
598
|
size_t seed() const { return seed_; }
|
|
461
599
|
|
|
462
600
|
private:
|
|
463
|
-
|
|
464
|
-
|
|
601
|
+
template <HashtableCapacityStorageMode StorageMode>
|
|
602
|
+
friend class HashtableInlineDataImpl;
|
|
465
603
|
|
|
466
|
-
|
|
467
|
-
}
|
|
604
|
+
explicit PerTableSeedImpl(uint64_t seed)
|
|
605
|
+
: seed_(static_cast<IntType>(seed)) {}
|
|
468
606
|
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
static_assert(PerTableSeed::kBitCount == 16);
|
|
472
|
-
thread_local uint16_t seed =
|
|
473
|
-
static_cast<uint16_t>(reinterpret_cast<uintptr_t>(&seed));
|
|
474
|
-
seed += uint16_t{0xad53};
|
|
475
|
-
return seed;
|
|
476
|
-
}
|
|
607
|
+
const IntType seed_;
|
|
608
|
+
};
|
|
477
609
|
|
|
478
|
-
//
|
|
610
|
+
// Capacity, size and also has additionally
|
|
479
611
|
// 1) one bit that stores whether we have infoz.
|
|
480
|
-
// 2) PerTableSeed::kBitCount bits for the seed.
|
|
481
|
-
|
|
612
|
+
// 2) PerTableSeed::kBitCount bits for the seed. (For SOO tables, the lowest
|
|
613
|
+
// bit of the seed is repurposed to track if sampling has been tried).
|
|
614
|
+
template <HashtableCapacityStorageMode StorageMode>
|
|
615
|
+
class HashtableInlineDataImpl {
|
|
482
616
|
public:
|
|
483
|
-
static constexpr
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
617
|
+
static constexpr HashtableCapacityStorageMode kStorageMode = StorageMode;
|
|
618
|
+
using PerTableSeed = PerTableSeedImpl<
|
|
619
|
+
std::conditional_t<StorageMode == kCapacityByValue, uint16_t, uint8_t>>;
|
|
620
|
+
using HashtableCapacity = HashtableCapacityImpl<StorageMode>;
|
|
621
|
+
static constexpr size_t kSizeBitCount =
|
|
622
|
+
StorageMode == kCapacityByValue
|
|
623
|
+
? 64 - PerTableSeed::kBitCount - 1
|
|
624
|
+
: 64 - PerTableSeed::kBitCount - sizeof(HashtableCapacity) * 8 - 1;
|
|
625
|
+
|
|
626
|
+
explicit HashtableInlineDataImpl(uninitialized_tag_t) {}
|
|
627
|
+
explicit HashtableInlineDataImpl(HashtableCapacity capacity,
|
|
628
|
+
no_seed_empty_tag_t)
|
|
629
|
+
: capacity_internal_(capacity.ToRawData()), data_(0) {}
|
|
630
|
+
HashtableInlineDataImpl(HashtableCapacity capacity, full_soo_tag_t,
|
|
631
|
+
bool has_tried_sampling)
|
|
632
|
+
: capacity_internal_(capacity.ToRawData()),
|
|
633
|
+
data_(kSizeOneNoMetadata |
|
|
634
|
+
(has_tried_sampling ? kSooHasTriedSamplingMask : 0)) {}
|
|
635
|
+
|
|
636
|
+
HashtableCapacity capacity() const {
|
|
637
|
+
return HashtableCapacity::FromRawData(capacity_internal_);
|
|
638
|
+
}
|
|
639
|
+
bool is_small() const { return capacity().is_small(); }
|
|
640
|
+
|
|
641
|
+
void set_capacity(HashtableCapacity c) { capacity_internal_ = c.ToRawData(); }
|
|
642
|
+
void set_capacity(size_t c) { set_capacity(HashtableCapacity(c)); }
|
|
488
643
|
|
|
489
644
|
// Returns actual size of the table.
|
|
490
645
|
size_t size() const { return static_cast<size_t>(data_ >> kSizeShift); }
|
|
491
646
|
void increment_size() { data_ += kSizeOneNoMetadata; }
|
|
492
647
|
void increment_size(size_t size) {
|
|
493
|
-
data_ += static_cast<uint64_t>(size)
|
|
648
|
+
data_ += static_cast<uint64_t>(size) << kSizeShift;
|
|
494
649
|
}
|
|
495
650
|
void decrement_size() { data_ -= kSizeOneNoMetadata; }
|
|
496
651
|
// Returns true if the table is empty.
|
|
497
652
|
bool empty() const { return data_ < kSizeOneNoMetadata; }
|
|
498
|
-
// Sets the size to zero, but keeps all the metadata bits.
|
|
499
|
-
void set_size_to_zero_keep_metadata() { data_ = data_ & kMetadataMask; }
|
|
500
653
|
|
|
501
|
-
|
|
502
|
-
|
|
654
|
+
// Returns true if an empty SOO table has already queried should_sample_soo().
|
|
655
|
+
bool soo_has_tried_sampling() const {
|
|
656
|
+
return (data_ & kSooHasTriedSamplingMask) != 0;
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
// Records that an empty SOO table has tried sampling.
|
|
660
|
+
void set_soo_has_tried_sampling() { data_ |= kSooHasTriedSamplingMask; }
|
|
661
|
+
|
|
662
|
+
// Sets the size, but keeps all the metadata bits.
|
|
663
|
+
void set_size(size_t size) {
|
|
664
|
+
data_ =
|
|
665
|
+
(data_ & kMetadataMask) | (static_cast<uint64_t>(size) << kSizeShift);
|
|
503
666
|
}
|
|
504
667
|
|
|
668
|
+
PerTableSeed seed() const { return PerTableSeed(data_ & kSeedMask); }
|
|
669
|
+
|
|
505
670
|
void generate_new_seed() {
|
|
506
|
-
|
|
671
|
+
set_seed(static_cast<typename PerTableSeed::IntType>(NextHashTableSeed()));
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
// We need to use a constant seed when the table is sampled so that sampled
|
|
675
|
+
// hashes use the same seed and can e.g. identify stuck bits accurately.
|
|
676
|
+
void set_sampled_seed() { set_seed(PerTableSeed::kSampledSeed); }
|
|
677
|
+
|
|
678
|
+
bool is_sampled_seed() const {
|
|
679
|
+
return seed().seed() == PerTableSeed::kSampledSeed;
|
|
507
680
|
}
|
|
508
681
|
|
|
509
682
|
// Returns true if the table has infoz.
|
|
@@ -517,25 +690,59 @@ class HashtableSize {
|
|
|
517
690
|
void set_no_seed_for_testing() { data_ &= ~kSeedMask; }
|
|
518
691
|
|
|
519
692
|
private:
|
|
520
|
-
|
|
693
|
+
// Bit layout of `data_` from MSB to LSB:
|
|
694
|
+
// (47 bits) : size
|
|
695
|
+
// (1 bit) : has_infoz
|
|
696
|
+
// (16 or 8 bits) : seed
|
|
697
|
+
// We don't split these components of `data_` into separate bit field elements
|
|
698
|
+
// because we get worse generated code that way.
|
|
699
|
+
static constexpr size_t kDataBitCount =
|
|
700
|
+
PerTableSeed::kBitCount + 1 + kSizeBitCount;
|
|
701
|
+
static constexpr size_t kSizeShift = kDataBitCount - kSizeBitCount;
|
|
521
702
|
static constexpr uint64_t kSizeOneNoMetadata = uint64_t{1} << kSizeShift;
|
|
522
703
|
static constexpr uint64_t kMetadataMask = kSizeOneNoMetadata - 1;
|
|
523
704
|
static constexpr uint64_t kSeedMask =
|
|
524
705
|
(uint64_t{1} << PerTableSeed::kBitCount) - 1;
|
|
525
706
|
// The next bit after the seed.
|
|
526
707
|
static constexpr uint64_t kHasInfozMask = kSeedMask + 1;
|
|
527
|
-
|
|
708
|
+
// For SOO tables, the seed is unused, and bit 0 is repurposed to track
|
|
709
|
+
// whether the table has already queried should_sample_soo().
|
|
710
|
+
static constexpr uint64_t kSooHasTriedSamplingMask = 1;
|
|
711
|
+
|
|
712
|
+
void set_seed(typename PerTableSeed::IntType seed) {
|
|
713
|
+
data_ = (data_ & ~kSeedMask) | seed;
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
uint64_t capacity_internal_ : sizeof(HashtableCapacity) * 8;
|
|
717
|
+
uint64_t data_ : kDataBitCount;
|
|
528
718
|
};
|
|
529
719
|
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
720
|
+
static_assert(
|
|
721
|
+
sizeof(HashtableInlineDataImpl<kCapacityByValue>::HashtableCapacity) ==
|
|
722
|
+
sizeof(size_t));
|
|
723
|
+
// NOTE: some platforms have this size to be equal to 12 for two reasons:
|
|
724
|
+
// 1) alignof(uint64_t) == 4.
|
|
725
|
+
// 2) sizeof(size_t) == sizeof(HashtableCapacityImpl<kCapacityByValue>) == 4.
|
|
726
|
+
static_assert(sizeof(HashtableInlineDataImpl<kCapacityByValue>) <= 16);
|
|
727
|
+
static_assert(
|
|
728
|
+
sizeof(HashtableInlineDataImpl<kCapacityByLog>::HashtableCapacity) == 1);
|
|
729
|
+
static_assert(sizeof(HashtableInlineDataImpl<kCapacityByLog>) == 8);
|
|
730
|
+
|
|
731
|
+
#ifndef ABSL_SWISSTABLE_INTERNAL_ENABLE_CAPACITY_BY_VALUE
|
|
732
|
+
using HashtableInlineData = HashtableInlineDataImpl<kCapacityByLog>;
|
|
733
|
+
#else
|
|
734
|
+
using HashtableInlineData = HashtableInlineDataImpl<kCapacityByValue>;
|
|
735
|
+
#endif // ABSL_SWISSTABLE_INTERNAL_ENABLE_CAPACITY_BY_VALUE
|
|
736
|
+
using PerTableSeed = HashtableInlineData::PerTableSeed;
|
|
737
|
+
using HashtableCapacity = HashtableInlineData::HashtableCapacity;
|
|
738
|
+
|
|
739
|
+
// H1 is just the low bits of the hash.
|
|
740
|
+
inline size_t H1(size_t hash) { return hash; }
|
|
534
741
|
|
|
535
|
-
// Extracts the H2 portion of a hash: the 7
|
|
742
|
+
// Extracts the H2 portion of a hash: the 7 most significant bits.
|
|
536
743
|
//
|
|
537
744
|
// These are used as an occupied control byte.
|
|
538
|
-
inline h2_t H2(size_t hash) { return hash
|
|
745
|
+
inline h2_t H2(size_t hash) { return hash >> (sizeof(size_t) * 8 - 7); }
|
|
539
746
|
|
|
540
747
|
// When there is an insertion with no reserved growth, we rehash with
|
|
541
748
|
// probability `min(1, RehashProbabilityConstant() / capacity())`. Using a
|
|
@@ -571,11 +778,9 @@ class CommonFieldsGenerationInfoEnabled {
|
|
|
571
778
|
// references. We rehash on the first insertion after reserved_growth_ reaches
|
|
572
779
|
// 0 after a call to reserve. We also do a rehash with low probability
|
|
573
780
|
// whenever reserved_growth_ is zero.
|
|
574
|
-
bool should_rehash_for_bug_detection_on_insert(
|
|
575
|
-
size_t capacity) const;
|
|
781
|
+
bool should_rehash_for_bug_detection_on_insert(size_t capacity) const;
|
|
576
782
|
// Similar to above, except that we don't depend on reserved_growth_.
|
|
577
|
-
bool should_rehash_for_bug_detection_on_move(
|
|
578
|
-
size_t capacity) const;
|
|
783
|
+
bool should_rehash_for_bug_detection_on_move(size_t capacity) const;
|
|
579
784
|
void maybe_increment_generation_on_insert() {
|
|
580
785
|
if (reserved_growth_ == kReservedGrowthJustRanOut) reserved_growth_ = 0;
|
|
581
786
|
|
|
@@ -628,12 +833,8 @@ class CommonFieldsGenerationInfoDisabled {
|
|
|
628
833
|
CommonFieldsGenerationInfoDisabled& operator=(
|
|
629
834
|
CommonFieldsGenerationInfoDisabled&&) = default;
|
|
630
835
|
|
|
631
|
-
bool should_rehash_for_bug_detection_on_insert(
|
|
632
|
-
|
|
633
|
-
}
|
|
634
|
-
bool should_rehash_for_bug_detection_on_move(PerTableSeed, size_t) const {
|
|
635
|
-
return false;
|
|
636
|
-
}
|
|
836
|
+
bool should_rehash_for_bug_detection_on_insert(size_t) const { return false; }
|
|
837
|
+
bool should_rehash_for_bug_detection_on_move(size_t) const { return false; }
|
|
637
838
|
void maybe_increment_generation_on_insert() {}
|
|
638
839
|
void increment_generation() {}
|
|
639
840
|
void reset_reserved_growth(size_t, size_t) {}
|
|
@@ -776,11 +977,6 @@ class GrowthInfo {
|
|
|
776
977
|
static_assert(sizeof(GrowthInfo) == sizeof(size_t), "");
|
|
777
978
|
static_assert(alignof(GrowthInfo) == alignof(size_t), "");
|
|
778
979
|
|
|
779
|
-
// Returns whether `n` is a valid capacity (i.e., number of slots).
|
|
780
|
-
//
|
|
781
|
-
// A valid capacity is a non-zero integer `2^m - 1`.
|
|
782
|
-
constexpr bool IsValidCapacity(size_t n) { return ((n + 1) & n) == 0 && n > 0; }
|
|
783
|
-
|
|
784
980
|
// Returns the number of "cloned control bytes".
|
|
785
981
|
//
|
|
786
982
|
// This is the number of control bytes that are present both at the beginning
|
|
@@ -790,13 +986,23 @@ constexpr size_t NumClonedBytes() { return Group::kWidth - 1; }
|
|
|
790
986
|
|
|
791
987
|
// Returns the number of control bytes including cloned.
|
|
792
988
|
constexpr size_t NumControlBytes(size_t capacity) {
|
|
793
|
-
return capacity + 1 + NumClonedBytes();
|
|
989
|
+
return IsSmallCapacity(capacity) ? 0 : capacity + 1 + NumClonedBytes();
|
|
990
|
+
}
|
|
991
|
+
|
|
992
|
+
// Returns whether table with the given capacity has a GrowthInfo.
|
|
993
|
+
constexpr bool HasGrowthInfoForCapacity(size_t capacity) {
|
|
994
|
+
return !IsSmallCapacity(capacity);
|
|
794
995
|
}
|
|
795
996
|
|
|
796
997
|
// Computes the offset from the start of the backing allocation of control.
|
|
797
998
|
// infoz and growth_info are stored at the beginning of the backing array.
|
|
798
|
-
constexpr size_t ControlOffset(bool has_infoz) {
|
|
799
|
-
|
|
999
|
+
constexpr size_t ControlOffset(bool has_infoz, bool has_growth_info) {
|
|
1000
|
+
if (ABSL_PREDICT_FALSE(has_infoz)) {
|
|
1001
|
+
// We always allocate GrowthInfo for sampled tables to allow branchless
|
|
1002
|
+
// access to infoz pointer.
|
|
1003
|
+
return sizeof(HashtablezInfoHandle) + sizeof(GrowthInfo);
|
|
1004
|
+
}
|
|
1005
|
+
return has_growth_info ? sizeof(GrowthInfo) : 0;
|
|
800
1006
|
}
|
|
801
1007
|
|
|
802
1008
|
// Returns the offset of the next item after `offset` that is aligned to `align`
|
|
@@ -810,7 +1016,8 @@ class RawHashSetLayout {
|
|
|
810
1016
|
public:
|
|
811
1017
|
explicit RawHashSetLayout(size_t capacity, size_t slot_size,
|
|
812
1018
|
size_t slot_align, bool has_infoz)
|
|
813
|
-
: control_offset_(
|
|
1019
|
+
: control_offset_(
|
|
1020
|
+
ControlOffset(has_infoz, HasGrowthInfoForCapacity(capacity))),
|
|
814
1021
|
generation_offset_(control_offset_ + NumControlBytes(capacity)),
|
|
815
1022
|
slot_offset_(
|
|
816
1023
|
AlignUpTo(generation_offset_ + NumGenerationBytes(), slot_align)),
|
|
@@ -846,50 +1053,30 @@ class RawHashSetLayout {
|
|
|
846
1053
|
|
|
847
1054
|
struct HashtableFreeFunctionsAccess;
|
|
848
1055
|
|
|
849
|
-
// Suppress erroneous uninitialized memory errors on GCC. For example, GCC
|
|
850
|
-
// thinks that the call to slot_array() in find_or_prepare_insert() is reading
|
|
851
|
-
// uninitialized memory, but slot_array is only called there when the table is
|
|
852
|
-
// non-empty and this memory is initialized when the table is non-empty.
|
|
853
|
-
#if !defined(__clang__) && defined(__GNUC__)
|
|
854
|
-
#define ABSL_SWISSTABLE_IGNORE_UNINITIALIZED(x) \
|
|
855
|
-
_Pragma("GCC diagnostic push") \
|
|
856
|
-
_Pragma("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") \
|
|
857
|
-
_Pragma("GCC diagnostic ignored \"-Wuninitialized\"") x; \
|
|
858
|
-
_Pragma("GCC diagnostic pop")
|
|
859
|
-
#define ABSL_SWISSTABLE_IGNORE_UNINITIALIZED_RETURN(x) \
|
|
860
|
-
ABSL_SWISSTABLE_IGNORE_UNINITIALIZED(return x)
|
|
861
|
-
#else
|
|
862
|
-
#define ABSL_SWISSTABLE_IGNORE_UNINITIALIZED(x) x
|
|
863
|
-
#define ABSL_SWISSTABLE_IGNORE_UNINITIALIZED_RETURN(x) return x
|
|
864
|
-
#endif
|
|
865
|
-
|
|
866
1056
|
// This allows us to work around an uninitialized memory warning when
|
|
867
1057
|
// constructing begin() iterators in empty hashtables.
|
|
1058
|
+
template <typename T>
|
|
868
1059
|
union MaybeInitializedPtr {
|
|
869
|
-
|
|
870
|
-
void set(
|
|
1060
|
+
T* get() const { ABSL_SWISSTABLE_IGNORE_UNINITIALIZED_RETURN(p); }
|
|
1061
|
+
void set(T* ptr) { p = ptr; }
|
|
871
1062
|
|
|
872
|
-
|
|
1063
|
+
T* p;
|
|
873
1064
|
};
|
|
874
1065
|
|
|
875
1066
|
struct HeapPtrs {
|
|
876
|
-
explicit HeapPtrs(uninitialized_tag_t) {}
|
|
877
|
-
explicit HeapPtrs(ctrl_t* c) : control(c) {}
|
|
878
|
-
|
|
879
1067
|
// The control bytes (and, also, a pointer near to the base of the backing
|
|
880
1068
|
// array).
|
|
881
1069
|
//
|
|
882
|
-
// This contains `capacity + 1 + NumClonedBytes()` entries
|
|
883
|
-
// when the table is empty (hence EmptyGroup).
|
|
1070
|
+
// This contains `capacity + 1 + NumClonedBytes()` entries.
|
|
884
1071
|
//
|
|
885
1072
|
// Note that growth_info is stored immediately before this pointer.
|
|
886
|
-
// May be uninitialized for
|
|
887
|
-
ctrl_t
|
|
1073
|
+
// May be uninitialized for small tables.
|
|
1074
|
+
MaybeInitializedPtr<ctrl_t> control;
|
|
888
1075
|
|
|
889
1076
|
// The beginning of the slots, located at `SlotOffset()` bytes after
|
|
890
1077
|
// `control`. May be uninitialized for empty tables.
|
|
891
1078
|
// Note: we can't use `slots` because Qt defines "slots" as a macro.
|
|
892
|
-
MaybeInitializedPtr slot_array;
|
|
1079
|
+
MaybeInitializedPtr<void> slot_array;
|
|
893
1080
|
};
|
|
894
1081
|
|
|
895
1082
|
// Returns the maximum size of the SOO slot.
|
|
@@ -898,19 +1085,16 @@ constexpr size_t MaxSooSlotSize() { return sizeof(HeapPtrs); }
|
|
|
898
1085
|
// Manages the backing array pointers or the SOO slot. When raw_hash_set::is_soo
|
|
899
1086
|
// is true, the SOO slot is stored in `soo_data`. Otherwise, we use `heap`.
|
|
900
1087
|
union HeapOrSoo {
|
|
901
|
-
|
|
902
|
-
explicit HeapOrSoo(ctrl_t* c) : heap(c) {}
|
|
903
|
-
|
|
904
|
-
ctrl_t*& control() {
|
|
1088
|
+
MaybeInitializedPtr<ctrl_t>& control() {
|
|
905
1089
|
ABSL_SWISSTABLE_IGNORE_UNINITIALIZED_RETURN(heap.control);
|
|
906
1090
|
}
|
|
907
|
-
ctrl_t
|
|
1091
|
+
MaybeInitializedPtr<ctrl_t> control() const {
|
|
908
1092
|
ABSL_SWISSTABLE_IGNORE_UNINITIALIZED_RETURN(heap.control);
|
|
909
1093
|
}
|
|
910
|
-
MaybeInitializedPtr
|
|
1094
|
+
MaybeInitializedPtr<void>& slot_array() {
|
|
911
1095
|
ABSL_SWISSTABLE_IGNORE_UNINITIALIZED_RETURN(heap.slot_array);
|
|
912
1096
|
}
|
|
913
|
-
MaybeInitializedPtr slot_array() const {
|
|
1097
|
+
MaybeInitializedPtr<void> slot_array() const {
|
|
914
1098
|
ABSL_SWISSTABLE_IGNORE_UNINITIALIZED_RETURN(heap.slot_array);
|
|
915
1099
|
}
|
|
916
1100
|
void* get_soo_data() {
|
|
@@ -939,20 +1123,15 @@ inline GrowthInfo& GetGrowthInfoFromControl(ctrl_t* control) {
|
|
|
939
1123
|
class CommonFields : public CommonFieldsGenerationInfo {
|
|
940
1124
|
public:
|
|
941
1125
|
explicit CommonFields(soo_tag_t)
|
|
942
|
-
:
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
: capacity_(SooCapacity()),
|
|
947
|
-
size_(full_soo_tag_t{}),
|
|
948
|
-
heap_or_soo_(uninitialized_tag_t{}) {}
|
|
1126
|
+
: inline_data_(HashtableCapacity(SooCapacity()), no_seed_empty_tag_t{}) {}
|
|
1127
|
+
explicit CommonFields(full_soo_tag_t, bool has_tried_sampling)
|
|
1128
|
+
: inline_data_(HashtableCapacity(SooCapacity()), full_soo_tag_t{},
|
|
1129
|
+
has_tried_sampling) {}
|
|
949
1130
|
explicit CommonFields(non_soo_tag_t)
|
|
950
|
-
:
|
|
951
|
-
size_(no_seed_empty_tag_t{}),
|
|
952
|
-
heap_or_soo_(EmptyGroup()) {}
|
|
1131
|
+
: inline_data_(HashtableCapacity(0), no_seed_empty_tag_t{}) {}
|
|
953
1132
|
// For use in swapping.
|
|
954
1133
|
explicit CommonFields(uninitialized_tag_t)
|
|
955
|
-
:
|
|
1134
|
+
: inline_data_(uninitialized_tag_t{}) {}
|
|
956
1135
|
|
|
957
1136
|
// Not copyable
|
|
958
1137
|
CommonFields(const CommonFields&) = delete;
|
|
@@ -960,10 +1139,7 @@ class CommonFields : public CommonFieldsGenerationInfo {
|
|
|
960
1139
|
|
|
961
1140
|
// Copy with guarantee that it is not SOO.
|
|
962
1141
|
CommonFields(non_soo_tag_t, const CommonFields& that)
|
|
963
|
-
:
|
|
964
|
-
size_(that.size_),
|
|
965
|
-
heap_or_soo_(that.heap_or_soo_) {
|
|
966
|
-
}
|
|
1142
|
+
: inline_data_(that.inline_data_), heap_or_soo_(that.heap_or_soo_) {}
|
|
967
1143
|
|
|
968
1144
|
// Movable
|
|
969
1145
|
CommonFields(CommonFields&& that) = default;
|
|
@@ -979,76 +1155,91 @@ class CommonFields : public CommonFieldsGenerationInfo {
|
|
|
979
1155
|
const void* soo_data() const { return heap_or_soo_.get_soo_data(); }
|
|
980
1156
|
void* soo_data() { return heap_or_soo_.get_soo_data(); }
|
|
981
1157
|
|
|
982
|
-
ctrl_t* control() const {
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
heap_or_soo_.control() = c;
|
|
993
|
-
if constexpr (kGenerateSeed) {
|
|
994
|
-
generate_new_seed();
|
|
995
|
-
}
|
|
996
|
-
}
|
|
997
|
-
void* backing_array_start() const {
|
|
998
|
-
// growth_info (and maybe infoz) is stored before control bytes.
|
|
999
|
-
ABSL_SWISSTABLE_ASSERT(
|
|
1000
|
-
reinterpret_cast<uintptr_t>(control()) % alignof(size_t) == 0);
|
|
1001
|
-
return control() - ControlOffset(has_infoz());
|
|
1158
|
+
ctrl_t* control() const {
|
|
1159
|
+
ABSL_SWISSTABLE_ASSERT(capacity() > 0);
|
|
1160
|
+
// Assume that the control bytes don't alias `this`.
|
|
1161
|
+
ctrl_t* ctrl = heap_or_soo_.control().get();
|
|
1162
|
+
[[maybe_unused]] size_t num_control_bytes = NumControlBytes(capacity());
|
|
1163
|
+
ABSL_ASSUME(reinterpret_cast<uintptr_t>(ctrl + num_control_bytes) <=
|
|
1164
|
+
reinterpret_cast<uintptr_t>(this) ||
|
|
1165
|
+
reinterpret_cast<uintptr_t>(this + 1) <=
|
|
1166
|
+
reinterpret_cast<uintptr_t>(ctrl));
|
|
1167
|
+
ABSL_SWISSTABLE_IGNORE_UNINITIALIZED_RETURN(ctrl);
|
|
1002
1168
|
}
|
|
1003
1169
|
|
|
1170
|
+
void set_control(ctrl_t* c) { heap_or_soo_.control().set(c); }
|
|
1171
|
+
|
|
1004
1172
|
// Note: we can't use slots() because Qt defines "slots" as a macro.
|
|
1005
1173
|
void* slot_array() const { return heap_or_soo_.slot_array().get(); }
|
|
1006
|
-
MaybeInitializedPtr slots_union() const {
|
|
1174
|
+
MaybeInitializedPtr<void> slots_union() const {
|
|
1175
|
+
return heap_or_soo_.slot_array();
|
|
1176
|
+
}
|
|
1007
1177
|
void set_slots(void* s) { heap_or_soo_.slot_array().set(s); }
|
|
1008
1178
|
|
|
1009
1179
|
// The number of filled slots.
|
|
1010
|
-
size_t size() const { return
|
|
1180
|
+
size_t size() const { return inline_data_.size(); }
|
|
1011
1181
|
// Sets the size to zero, but keeps hashinfoz bit and seed.
|
|
1012
|
-
void set_size_to_zero() {
|
|
1182
|
+
void set_size_to_zero() { inline_data_.set_size(0); }
|
|
1013
1183
|
void set_empty_soo() {
|
|
1014
1184
|
AssertInSooMode();
|
|
1015
|
-
|
|
1185
|
+
inline_data_.set_size(0);
|
|
1016
1186
|
}
|
|
1017
1187
|
void set_full_soo() {
|
|
1018
1188
|
AssertInSooMode();
|
|
1019
|
-
|
|
1189
|
+
inline_data_.set_size(1);
|
|
1020
1190
|
}
|
|
1021
1191
|
void increment_size() {
|
|
1022
1192
|
ABSL_SWISSTABLE_ASSERT(size() < capacity());
|
|
1023
|
-
|
|
1193
|
+
inline_data_.increment_size();
|
|
1024
1194
|
}
|
|
1025
1195
|
void increment_size(size_t n) {
|
|
1026
1196
|
ABSL_SWISSTABLE_ASSERT(size() + n <= capacity());
|
|
1027
|
-
|
|
1197
|
+
inline_data_.increment_size(n);
|
|
1028
1198
|
}
|
|
1029
1199
|
void decrement_size() {
|
|
1030
1200
|
ABSL_SWISSTABLE_ASSERT(!empty());
|
|
1031
|
-
|
|
1201
|
+
inline_data_.decrement_size();
|
|
1202
|
+
}
|
|
1203
|
+
bool empty() const { return inline_data_.empty(); }
|
|
1204
|
+
void set_soo_has_tried_sampling() {
|
|
1205
|
+
inline_data_.set_soo_has_tried_sampling();
|
|
1206
|
+
}
|
|
1207
|
+
bool soo_has_tried_sampling() const {
|
|
1208
|
+
return inline_data_.soo_has_tried_sampling();
|
|
1209
|
+
}
|
|
1210
|
+
|
|
1211
|
+
// The seed used for the hash function.
|
|
1212
|
+
PerTableSeed seed() const { return inline_data_.seed(); }
|
|
1213
|
+
// Generates a new seed the hash function.
|
|
1214
|
+
// The table will be invalidated if `!empty()` because hash is being changed.
|
|
1215
|
+
// In such cases, we will need to rehash the table.
|
|
1216
|
+
void generate_new_seed(bool has_infoz) {
|
|
1217
|
+
// Note: we can't use has_infoz() here because we set has_infoz later than
|
|
1218
|
+
// we generate the seed.
|
|
1219
|
+
if (ABSL_PREDICT_FALSE(has_infoz)) {
|
|
1220
|
+
inline_data_.set_sampled_seed();
|
|
1221
|
+
return;
|
|
1222
|
+
}
|
|
1223
|
+
inline_data_.generate_new_seed();
|
|
1032
1224
|
}
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
// The seed used for the H1 part of the hash function.
|
|
1036
|
-
PerTableSeed seed() const { return size_.seed(); }
|
|
1037
|
-
// Generates a new seed for the H1 part of the hash function.
|
|
1038
|
-
// The table will be invalidated if
|
|
1039
|
-
// `kGenerateSeed && !empty() && !is_single_group(capacity())` because H1 is
|
|
1040
|
-
// being changed. In such cases, we will need to rehash the table.
|
|
1041
|
-
void generate_new_seed() { size_.generate_new_seed(); }
|
|
1042
|
-
void set_no_seed_for_testing() { size_.set_no_seed_for_testing(); }
|
|
1225
|
+
void set_no_seed_for_testing() { inline_data_.set_no_seed_for_testing(); }
|
|
1043
1226
|
|
|
1044
|
-
|
|
1045
|
-
|
|
1227
|
+
HashtableCapacity capacity_impl() const {
|
|
1228
|
+
HashtableCapacity cap = inline_data_.capacity();
|
|
1229
|
+
ABSL_SWISSTABLE_ASSERT(cap.IsValid());
|
|
1230
|
+
return cap;
|
|
1231
|
+
}
|
|
1232
|
+
size_t capacity() const { return capacity_impl().capacity(); }
|
|
1233
|
+
// We have a separate alias for callsites in which the capacity may be
|
|
1234
|
+
// invalid.
|
|
1235
|
+
HashtableCapacity maybe_invalid_capacity() const {
|
|
1236
|
+
return inline_data_.capacity();
|
|
1237
|
+
}
|
|
1238
|
+
void set_capacity(HashtableCapacity c) { inline_data_.set_capacity(c); }
|
|
1046
1239
|
void set_capacity(size_t c) {
|
|
1047
|
-
|
|
1048
|
-
ABSL_SWISSTABLE_ASSERT(c == 0 || IsValidCapacity(c) ||
|
|
1049
|
-
c > kAboveMaxValidCapacity);
|
|
1050
|
-
capacity_ = c;
|
|
1240
|
+
set_capacity(HashtableCapacity(c));
|
|
1051
1241
|
}
|
|
1242
|
+
bool is_small() const { return inline_data_.is_small(); }
|
|
1052
1243
|
|
|
1053
1244
|
// The number of slots we can still fill without needing to rehash.
|
|
1054
1245
|
// This is stored in the heap allocation before the control bytes.
|
|
@@ -1057,23 +1248,35 @@ class CommonFields : public CommonFieldsGenerationInfo {
|
|
|
1057
1248
|
size_t growth_left() const { return growth_info().GetGrowthLeft(); }
|
|
1058
1249
|
|
|
1059
1250
|
GrowthInfo& growth_info() {
|
|
1251
|
+
ABSL_SWISSTABLE_ASSERT(HasGrowthInfoForCapacity(capacity()));
|
|
1060
1252
|
return GetGrowthInfoFromControl(control());
|
|
1061
1253
|
}
|
|
1062
1254
|
GrowthInfo growth_info() const {
|
|
1063
1255
|
return const_cast<CommonFields*>(this)->growth_info();
|
|
1064
1256
|
}
|
|
1065
1257
|
|
|
1066
|
-
bool has_infoz() const { return
|
|
1067
|
-
void set_has_infoz() {
|
|
1258
|
+
bool has_infoz() const { return inline_data_.has_infoz(); }
|
|
1259
|
+
void set_has_infoz() {
|
|
1260
|
+
ABSL_SWISSTABLE_ASSERT(inline_data_.is_sampled_seed());
|
|
1261
|
+
inline_data_.set_has_infoz();
|
|
1262
|
+
}
|
|
1263
|
+
|
|
1264
|
+
HashtablezInfoHandle* infoz_ptr() const {
|
|
1265
|
+
// growth_info is stored before control bytes.
|
|
1266
|
+
ABSL_SWISSTABLE_ASSERT(
|
|
1267
|
+
reinterpret_cast<uintptr_t>(control()) % alignof(size_t) == 0);
|
|
1268
|
+
ABSL_SWISSTABLE_ASSERT(has_infoz());
|
|
1269
|
+
return reinterpret_cast<HashtablezInfoHandle*>(
|
|
1270
|
+
control() - ControlOffset(/*has_infoz=*/true,
|
|
1271
|
+
HasGrowthInfoForCapacity(capacity())));
|
|
1272
|
+
}
|
|
1068
1273
|
|
|
1069
1274
|
HashtablezInfoHandle infoz() {
|
|
1070
|
-
return has_infoz()
|
|
1071
|
-
? *reinterpret_cast<HashtablezInfoHandle*>(backing_array_start())
|
|
1072
|
-
: HashtablezInfoHandle();
|
|
1275
|
+
return has_infoz() ? *infoz_ptr() : HashtablezInfoHandle();
|
|
1073
1276
|
}
|
|
1074
1277
|
void set_infoz(HashtablezInfoHandle infoz) {
|
|
1075
1278
|
ABSL_SWISSTABLE_ASSERT(has_infoz());
|
|
1076
|
-
*
|
|
1279
|
+
*infoz_ptr() = infoz;
|
|
1077
1280
|
}
|
|
1078
1281
|
|
|
1079
1282
|
bool should_rehash_for_bug_detection_on_insert() const {
|
|
@@ -1084,11 +1287,11 @@ class CommonFields : public CommonFieldsGenerationInfo {
|
|
|
1084
1287
|
// will end up rehashing anyways.
|
|
1085
1288
|
if (growth_left() == 0) return false;
|
|
1086
1289
|
return CommonFieldsGenerationInfo::
|
|
1087
|
-
should_rehash_for_bug_detection_on_insert(
|
|
1290
|
+
should_rehash_for_bug_detection_on_insert(capacity());
|
|
1088
1291
|
}
|
|
1089
1292
|
bool should_rehash_for_bug_detection_on_move() const {
|
|
1090
1293
|
return CommonFieldsGenerationInfo::should_rehash_for_bug_detection_on_move(
|
|
1091
|
-
|
|
1294
|
+
capacity());
|
|
1092
1295
|
}
|
|
1093
1296
|
void reset_reserved_growth(size_t reservation) {
|
|
1094
1297
|
CommonFieldsGenerationInfo::reset_reserved_growth(reservation, size());
|
|
@@ -1104,8 +1307,7 @@ class CommonFields : public CommonFieldsGenerationInfo {
|
|
|
1104
1307
|
void move_non_heap_or_soo_fields(CommonFields& that) {
|
|
1105
1308
|
static_cast<CommonFieldsGenerationInfo&>(*this) =
|
|
1106
1309
|
std::move(static_cast<CommonFieldsGenerationInfo&>(that));
|
|
1107
|
-
|
|
1108
|
-
size_ = that.size_;
|
|
1310
|
+
inline_data_ = that.inline_data_;
|
|
1109
1311
|
}
|
|
1110
1312
|
|
|
1111
1313
|
// Returns the number of control bytes set to kDeleted. For testing only.
|
|
@@ -1122,8 +1324,8 @@ class CommonFields : public CommonFieldsGenerationInfo {
|
|
|
1122
1324
|
f();
|
|
1123
1325
|
return;
|
|
1124
1326
|
#endif
|
|
1125
|
-
const
|
|
1126
|
-
set_capacity(
|
|
1327
|
+
const HashtableCapacity cap = maybe_invalid_capacity();
|
|
1328
|
+
set_capacity(HashtableCapacity::CreateReentrance());
|
|
1127
1329
|
f();
|
|
1128
1330
|
set_capacity(cap);
|
|
1129
1331
|
}
|
|
@@ -1142,38 +1344,18 @@ class CommonFields : public CommonFieldsGenerationInfo {
|
|
|
1142
1344
|
ABSL_SWISSTABLE_ASSERT(!has_infoz());
|
|
1143
1345
|
}
|
|
1144
1346
|
|
|
1145
|
-
// The number of slots in the backing array. This is always 2^N-1 for an
|
|
1146
|
-
// integer N. NOTE: we tried experimenting with compressing the capacity and
|
|
1147
|
-
// storing it together with size_: (a) using 6 bits to store the corresponding
|
|
1148
|
-
// power (N in 2^N-1), and (b) storing 2^N as the most significant bit of
|
|
1149
|
-
// size_ and storing size in the low bits. Both of these experiments were
|
|
1150
|
-
// regressions, presumably because we need capacity to do find operations.
|
|
1151
|
-
size_t capacity_;
|
|
1152
|
-
|
|
1153
1347
|
// TODO(b/289225379): we could put size_ into HeapOrSoo and make capacity_
|
|
1154
1348
|
// encode the size in SOO case. We would be making size()/capacity() more
|
|
1155
1349
|
// expensive in order to have more SOO space.
|
|
1156
|
-
|
|
1350
|
+
HashtableInlineData inline_data_;
|
|
1157
1351
|
|
|
1158
1352
|
// Either the control/slots pointers or the SOO slot.
|
|
1159
1353
|
HeapOrSoo heap_or_soo_;
|
|
1160
1354
|
};
|
|
1161
1355
|
|
|
1162
|
-
template <class Policy, class
|
|
1356
|
+
template <class Policy, class... Params>
|
|
1163
1357
|
class raw_hash_set;
|
|
1164
1358
|
|
|
1165
|
-
// Returns the next valid capacity after `n`.
|
|
1166
|
-
constexpr size_t NextCapacity(size_t n) {
|
|
1167
|
-
ABSL_SWISSTABLE_ASSERT(IsValidCapacity(n) || n == 0);
|
|
1168
|
-
return n * 2 + 1;
|
|
1169
|
-
}
|
|
1170
|
-
|
|
1171
|
-
// Returns the previous valid capacity before `n`.
|
|
1172
|
-
constexpr size_t PreviousCapacity(size_t n) {
|
|
1173
|
-
ABSL_SWISSTABLE_ASSERT(IsValidCapacity(n));
|
|
1174
|
-
return n / 2;
|
|
1175
|
-
}
|
|
1176
|
-
|
|
1177
1359
|
// Applies the following mapping to every byte in the control array:
|
|
1178
1360
|
// * kDeleted -> kEmpty
|
|
1179
1361
|
// * kEmpty -> kEmpty
|
|
@@ -1184,55 +1366,6 @@ constexpr size_t PreviousCapacity(size_t n) {
|
|
|
1184
1366
|
// ctrl[i] != ctrl_t::kSentinel for all i < capacity
|
|
1185
1367
|
void ConvertDeletedToEmptyAndFullToDeleted(ctrl_t* ctrl, size_t capacity);
|
|
1186
1368
|
|
|
1187
|
-
// Converts `n` into the next valid capacity, per `IsValidCapacity`.
|
|
1188
|
-
constexpr size_t NormalizeCapacity(size_t n) {
|
|
1189
|
-
return n ? ~size_t{} >> countl_zero(n) : 1;
|
|
1190
|
-
}
|
|
1191
|
-
|
|
1192
|
-
// General notes on capacity/growth methods below:
|
|
1193
|
-
// - We use 7/8th as maximum load factor. For 16-wide groups, that gives an
|
|
1194
|
-
// average of two empty slots per group.
|
|
1195
|
-
// - For (capacity+1) >= Group::kWidth, growth is 7/8*capacity.
|
|
1196
|
-
// - For (capacity+1) < Group::kWidth, growth == capacity. In this case, we
|
|
1197
|
-
// never need to probe (the whole table fits in one group) so we don't need a
|
|
1198
|
-
// load factor less than 1.
|
|
1199
|
-
|
|
1200
|
-
// Given `capacity`, applies the load factor; i.e., it returns the maximum
|
|
1201
|
-
// number of values we should put into the table before a resizing rehash.
|
|
1202
|
-
constexpr size_t CapacityToGrowth(size_t capacity) {
|
|
1203
|
-
ABSL_SWISSTABLE_ASSERT(IsValidCapacity(capacity));
|
|
1204
|
-
// `capacity*7/8`
|
|
1205
|
-
if (Group::kWidth == 8 && capacity == 7) {
|
|
1206
|
-
// x-x/8 does not work when x==7.
|
|
1207
|
-
return 6;
|
|
1208
|
-
}
|
|
1209
|
-
return capacity - capacity / 8;
|
|
1210
|
-
}
|
|
1211
|
-
|
|
1212
|
-
// Given `size`, "unapplies" the load factor to find how large the capacity
|
|
1213
|
-
// should be to stay within the load factor.
|
|
1214
|
-
//
|
|
1215
|
-
// For size == 0, returns 0.
|
|
1216
|
-
// For other values, returns the same as `NormalizeCapacity(size*8/7)`.
|
|
1217
|
-
constexpr size_t SizeToCapacity(size_t size) {
|
|
1218
|
-
if (size == 0) {
|
|
1219
|
-
return 0;
|
|
1220
|
-
}
|
|
1221
|
-
// The minimum possible capacity is NormalizeCapacity(size).
|
|
1222
|
-
// Shifting right `~size_t{}` by `leading_zeros` yields
|
|
1223
|
-
// NormalizeCapacity(size).
|
|
1224
|
-
int leading_zeros = absl::countl_zero(size);
|
|
1225
|
-
constexpr size_t kLast3Bits = size_t{7} << (sizeof(size_t) * 8 - 3);
|
|
1226
|
-
size_t max_size_for_next_capacity = kLast3Bits >> leading_zeros;
|
|
1227
|
-
// Decrease shift if size is too big for the minimum capacity.
|
|
1228
|
-
leading_zeros -= static_cast<int>(size > max_size_for_next_capacity);
|
|
1229
|
-
if constexpr (Group::kWidth == 8) {
|
|
1230
|
-
// Formula doesn't work when size==7 for 8-wide groups.
|
|
1231
|
-
leading_zeros -= (size == 7);
|
|
1232
|
-
}
|
|
1233
|
-
return (~size_t{}) >> leading_zeros;
|
|
1234
|
-
}
|
|
1235
|
-
|
|
1236
1369
|
template <class InputIter>
|
|
1237
1370
|
size_t SelectBucketCountForIterRange(InputIter first, InputIter last,
|
|
1238
1371
|
size_t bucket_count) {
|
|
@@ -1255,6 +1388,26 @@ constexpr bool SwisstableDebugEnabled() {
|
|
|
1255
1388
|
#endif
|
|
1256
1389
|
}
|
|
1257
1390
|
|
|
1391
|
+
// Dereferences `ptr`. The function is named in order to provide a helpful error
|
|
1392
|
+
// message when users see crashing stack traces. Note that this function is not
|
|
1393
|
+
// guaranteed to crash when `ptr` is invalid if sanitizer mode is not enabled.
|
|
1394
|
+
template <typename T>
|
|
1395
|
+
T CrashIfIteratorIsInvalid(const T* ptr) {
|
|
1396
|
+
// If the following line(s) crash, then it's likely that `ptr` is from a
|
|
1397
|
+
// backing array that has been deallocated. If you see a crash here, it likely
|
|
1398
|
+
// means that you are comparing an invalid iterator from a table that has
|
|
1399
|
+
// rehashed, moved, or been destroyed. In such cases, it is often helpful to
|
|
1400
|
+
// reproduce the issue with --config=asan and (assuming there's a crash here)
|
|
1401
|
+
// examine the corresponding deallocation stack trace.
|
|
1402
|
+
T ret = *ptr;
|
|
1403
|
+
// Force a read with inline asm to make sure that a crash happens here, rather
|
|
1404
|
+
// than later when the value is used.
|
|
1405
|
+
#ifdef __clang__
|
|
1406
|
+
asm("" : "+r"(ret));
|
|
1407
|
+
#endif
|
|
1408
|
+
return ret;
|
|
1409
|
+
}
|
|
1410
|
+
|
|
1258
1411
|
inline void AssertIsFull(const ctrl_t* ctrl, GenerationType generation,
|
|
1259
1412
|
const GenerationType* generation_ptr,
|
|
1260
1413
|
const char* operation) {
|
|
@@ -1267,25 +1420,26 @@ inline void AssertIsFull(const ctrl_t* ctrl, GenerationType generation,
|
|
|
1267
1420
|
if (ABSL_PREDICT_FALSE(ctrl == nullptr)) {
|
|
1268
1421
|
ABSL_RAW_LOG(FATAL, "%s called on end() iterator.", operation);
|
|
1269
1422
|
}
|
|
1270
|
-
if (ABSL_PREDICT_FALSE(ctrl ==
|
|
1423
|
+
if (ABSL_PREDICT_FALSE(ctrl == DefaultIterControl())) {
|
|
1271
1424
|
ABSL_RAW_LOG(FATAL, "%s called on default-constructed iterator.",
|
|
1272
1425
|
operation);
|
|
1273
1426
|
}
|
|
1274
1427
|
if (SwisstableGenerationsEnabled()) {
|
|
1275
|
-
if (ABSL_PREDICT_FALSE(generation !=
|
|
1428
|
+
if (ABSL_PREDICT_FALSE(generation !=
|
|
1429
|
+
CrashIfIteratorIsInvalid(generation_ptr))) {
|
|
1276
1430
|
ABSL_RAW_LOG(FATAL,
|
|
1277
1431
|
"%s called on invalid iterator. The table could have "
|
|
1278
1432
|
"rehashed or moved since this iterator was initialized.",
|
|
1279
1433
|
operation);
|
|
1280
1434
|
}
|
|
1281
|
-
if (ABSL_PREDICT_FALSE(!IsFull(
|
|
1435
|
+
if (ABSL_PREDICT_FALSE(!IsFull(CrashIfIteratorIsInvalid(ctrl)))) {
|
|
1282
1436
|
ABSL_RAW_LOG(
|
|
1283
1437
|
FATAL,
|
|
1284
1438
|
"%s called on invalid iterator. The element was likely erased.",
|
|
1285
1439
|
operation);
|
|
1286
1440
|
}
|
|
1287
1441
|
} else {
|
|
1288
|
-
if (ABSL_PREDICT_FALSE(!IsFull(
|
|
1442
|
+
if (ABSL_PREDICT_FALSE(!IsFull(CrashIfIteratorIsInvalid(ctrl)))) {
|
|
1289
1443
|
ABSL_RAW_LOG(
|
|
1290
1444
|
FATAL,
|
|
1291
1445
|
"%s called on invalid iterator. The element might have been erased "
|
|
@@ -1302,12 +1456,19 @@ inline void AssertIsValidForComparison(const ctrl_t* ctrl,
|
|
|
1302
1456
|
const GenerationType* generation_ptr) {
|
|
1303
1457
|
if (!SwisstableDebugEnabled()) return;
|
|
1304
1458
|
const bool ctrl_is_valid_for_comparison =
|
|
1305
|
-
ctrl == nullptr || ctrl ==
|
|
1459
|
+
ctrl == nullptr || ctrl == DefaultIterControl() ||
|
|
1460
|
+
IsFull(CrashIfIteratorIsInvalid(ctrl));
|
|
1306
1461
|
if (SwisstableGenerationsEnabled()) {
|
|
1307
|
-
if (ABSL_PREDICT_FALSE(generation !=
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1462
|
+
if (ABSL_PREDICT_FALSE(generation !=
|
|
1463
|
+
CrashIfIteratorIsInvalid(generation_ptr))) {
|
|
1464
|
+
// Note: in the case of a rehash, we would expect to see a sanitizer crash
|
|
1465
|
+
// in CrashIfIteratorIsInvalid so this assertion will only catch moved
|
|
1466
|
+
// table cases, unless we're using a custom allocator that does not
|
|
1467
|
+
// deallocate the old backing array (e.g. an arena allocator).
|
|
1468
|
+
ABSL_RAW_LOG(
|
|
1469
|
+
FATAL,
|
|
1470
|
+
"Invalid iterator comparison. The table was likely moved (or "
|
|
1471
|
+
"possibly rehashed) since this iterator was initialized.");
|
|
1311
1472
|
}
|
|
1312
1473
|
if (ABSL_PREDICT_FALSE(!ctrl_is_valid_for_comparison)) {
|
|
1313
1474
|
ABSL_RAW_LOG(
|
|
@@ -1368,8 +1529,8 @@ inline void AssertSameContainer(const ctrl_t* ctrl_a, const ctrl_t* ctrl_b,
|
|
|
1368
1529
|
}
|
|
1369
1530
|
};
|
|
1370
1531
|
|
|
1371
|
-
const bool a_is_default = ctrl_a ==
|
|
1372
|
-
const bool b_is_default = ctrl_b ==
|
|
1532
|
+
const bool a_is_default = ctrl_a == DefaultIterControl();
|
|
1533
|
+
const bool b_is_default = ctrl_b == DefaultIterControl();
|
|
1373
1534
|
if (a_is_default && b_is_default) return;
|
|
1374
1535
|
fail_if(a_is_default != b_is_default,
|
|
1375
1536
|
"Comparing default-constructed hashtable iterator with a "
|
|
@@ -1377,13 +1538,6 @@ inline void AssertSameContainer(const ctrl_t* ctrl_a, const ctrl_t* ctrl_b,
|
|
|
1377
1538
|
|
|
1378
1539
|
if (SwisstableGenerationsEnabled()) {
|
|
1379
1540
|
if (ABSL_PREDICT_TRUE(generation_ptr_a == generation_ptr_b)) return;
|
|
1380
|
-
// Users don't need to know whether the tables are SOO so don't mention SOO
|
|
1381
|
-
// in the debug message.
|
|
1382
|
-
const bool a_is_soo = IsSooControl(ctrl_a);
|
|
1383
|
-
const bool b_is_soo = IsSooControl(ctrl_b);
|
|
1384
|
-
fail_if(a_is_soo != b_is_soo || (a_is_soo && b_is_soo),
|
|
1385
|
-
"Comparing iterators from different hashtables.");
|
|
1386
|
-
|
|
1387
1541
|
const bool a_is_empty = IsEmptyGeneration(generation_ptr_a);
|
|
1388
1542
|
const bool b_is_empty = IsEmptyGeneration(generation_ptr_b);
|
|
1389
1543
|
fail_if(a_is_empty != b_is_empty,
|
|
@@ -1418,27 +1572,66 @@ constexpr bool is_single_group(size_t capacity) {
|
|
|
1418
1572
|
return capacity <= Group::kWidth;
|
|
1419
1573
|
}
|
|
1420
1574
|
|
|
1575
|
+
// The state for a probe sequence.
|
|
1576
|
+
//
|
|
1577
|
+
// Currently, the sequence is a triangular progression of the form
|
|
1578
|
+
//
|
|
1579
|
+
// p(i) := Width * (i^2 + i)/2 + hash (mod mask + 1)
|
|
1580
|
+
//
|
|
1581
|
+
// The use of `Width` ensures that each probe step does not overlap groups;
|
|
1582
|
+
// the sequence effectively outputs the addresses of *groups* (although not
|
|
1583
|
+
// necessarily aligned to any boundary). The `Group` machinery allows us
|
|
1584
|
+
// to check an entire group with minimal branching.
|
|
1585
|
+
//
|
|
1586
|
+
// Wrapping around at `mask + 1` is important, but not for the obvious reason.
|
|
1587
|
+
// As described above, the first few entries of the control byte array
|
|
1588
|
+
// are mirrored at the end of the array, which `Group` will find and use
|
|
1589
|
+
// for selecting candidates. However, when those candidates' slots are
|
|
1590
|
+
// actually inspected, there are no corresponding slots for the cloned bytes,
|
|
1591
|
+
// so we need to make sure we've treated those offsets as "wrapping around".
|
|
1592
|
+
//
|
|
1593
|
+
// It turns out that this probe sequence visits every group exactly once if the
|
|
1594
|
+
// number of groups is a power of two, since (i^2+i)/2 is a bijection in
|
|
1595
|
+
// Z/(2^m). See https://en.wikipedia.org/wiki/Quadratic_probing
|
|
1596
|
+
template <size_t Width>
|
|
1597
|
+
class probe_seq {
|
|
1598
|
+
public:
|
|
1599
|
+
// Creates a new probe sequence using `hash` as the initial value of the
|
|
1600
|
+
// sequence and `capacity` as the mask to apply to each value in the
|
|
1601
|
+
// progression.
|
|
1602
|
+
probe_seq(HashtableCapacity capacity, size_t hash)
|
|
1603
|
+
: capacity_(capacity), offset_(capacity.mask(hash)) {}
|
|
1604
|
+
|
|
1605
|
+
// The offset within the table, i.e., the value `p(i)` above.
|
|
1606
|
+
size_t offset() const { return offset_; }
|
|
1607
|
+
size_t offset(size_t i) const { return capacity_.mask(offset_ + i); }
|
|
1608
|
+
|
|
1609
|
+
void next() {
|
|
1610
|
+
index_ += Width;
|
|
1611
|
+
offset_ += index_;
|
|
1612
|
+
offset_ = capacity_.mask(offset_);
|
|
1613
|
+
}
|
|
1614
|
+
// 0-based probe index, a multiple of `Width`.
|
|
1615
|
+
size_t index() const { return index_; }
|
|
1616
|
+
|
|
1617
|
+
private:
|
|
1618
|
+
HashtableCapacity capacity_;
|
|
1619
|
+
size_t offset_;
|
|
1620
|
+
size_t index_ = 0;
|
|
1621
|
+
};
|
|
1622
|
+
|
|
1421
1623
|
// Begins a probing operation on `common.control`, using `hash`.
|
|
1422
|
-
inline probe_seq<Group::kWidth>
|
|
1423
|
-
|
|
1624
|
+
inline probe_seq<Group::kWidth> probe_h1(HashtableCapacity capacity,
|
|
1625
|
+
size_t h1) {
|
|
1626
|
+
return probe_seq<Group::kWidth>(capacity, h1);
|
|
1424
1627
|
}
|
|
1425
|
-
inline probe_seq<Group::kWidth> probe(
|
|
1426
|
-
|
|
1427
|
-
return probe(H1(hash, seed), capacity);
|
|
1628
|
+
inline probe_seq<Group::kWidth> probe(HashtableCapacity capacity, size_t hash) {
|
|
1629
|
+
return probe_h1(capacity, H1(hash));
|
|
1428
1630
|
}
|
|
1429
1631
|
inline probe_seq<Group::kWidth> probe(const CommonFields& common, size_t hash) {
|
|
1430
|
-
return probe(common.
|
|
1632
|
+
return probe(common.capacity_impl(), hash);
|
|
1431
1633
|
}
|
|
1432
1634
|
|
|
1433
|
-
// Probes an array of control bits using a probe sequence derived from `hash`,
|
|
1434
|
-
// and returns the offset corresponding to the first deleted or empty slot.
|
|
1435
|
-
//
|
|
1436
|
-
// Behavior when the entire table is full is undefined.
|
|
1437
|
-
//
|
|
1438
|
-
// NOTE: this function must work with tables having both empty and deleted
|
|
1439
|
-
// slots in the same group. Such tables appear during `erase()`.
|
|
1440
|
-
FindInfo find_first_non_full(const CommonFields& common, size_t hash);
|
|
1441
|
-
|
|
1442
1635
|
constexpr size_t kProbedElementIndexSentinel = ~size_t{};
|
|
1443
1636
|
|
|
1444
1637
|
// Implementation detail of transfer_unprobed_elements_to_next_capacity_fn.
|
|
@@ -1502,79 +1695,11 @@ extern template size_t TryFindNewIndexWithoutProbing(size_t h1,
|
|
|
1502
1695
|
ctrl_t* new_ctrl,
|
|
1503
1696
|
size_t new_capacity);
|
|
1504
1697
|
|
|
1505
|
-
// Sets sanitizer poisoning for slot corresponding to control byte being set.
|
|
1506
|
-
inline void DoSanitizeOnSetCtrl(const CommonFields& c, size_t i, ctrl_t h,
|
|
1507
|
-
size_t slot_size) {
|
|
1508
|
-
ABSL_SWISSTABLE_ASSERT(i < c.capacity());
|
|
1509
|
-
auto* slot_i = static_cast<const char*>(c.slot_array()) + i * slot_size;
|
|
1510
|
-
if (IsFull(h)) {
|
|
1511
|
-
SanitizerUnpoisonMemoryRegion(slot_i, slot_size);
|
|
1512
|
-
} else {
|
|
1513
|
-
SanitizerPoisonMemoryRegion(slot_i, slot_size);
|
|
1514
|
-
}
|
|
1515
|
-
}
|
|
1516
|
-
|
|
1517
|
-
// Sets `ctrl[i]` to `h`.
|
|
1518
|
-
//
|
|
1519
|
-
// Unlike setting it directly, this function will perform bounds checks and
|
|
1520
|
-
// mirror the value to the cloned tail if necessary.
|
|
1521
|
-
inline void SetCtrl(const CommonFields& c, size_t i, ctrl_t h,
|
|
1522
|
-
size_t slot_size) {
|
|
1523
|
-
DoSanitizeOnSetCtrl(c, i, h, slot_size);
|
|
1524
|
-
ctrl_t* ctrl = c.control();
|
|
1525
|
-
ctrl[i] = h;
|
|
1526
|
-
ctrl[((i - NumClonedBytes()) & c.capacity()) +
|
|
1527
|
-
(NumClonedBytes() & c.capacity())] = h;
|
|
1528
|
-
}
|
|
1529
|
-
// Overload for setting to an occupied `h2_t` rather than a special `ctrl_t`.
|
|
1530
|
-
inline void SetCtrl(const CommonFields& c, size_t i, h2_t h, size_t slot_size) {
|
|
1531
|
-
SetCtrl(c, i, static_cast<ctrl_t>(h), slot_size);
|
|
1532
|
-
}
|
|
1533
|
-
|
|
1534
|
-
// Like SetCtrl, but in a single group table, we can save some operations when
|
|
1535
|
-
// setting the cloned control byte.
|
|
1536
|
-
inline void SetCtrlInSingleGroupTable(const CommonFields& c, size_t i, ctrl_t h,
|
|
1537
|
-
size_t slot_size) {
|
|
1538
|
-
ABSL_SWISSTABLE_ASSERT(is_single_group(c.capacity()));
|
|
1539
|
-
DoSanitizeOnSetCtrl(c, i, h, slot_size);
|
|
1540
|
-
ctrl_t* ctrl = c.control();
|
|
1541
|
-
ctrl[i] = h;
|
|
1542
|
-
ctrl[i + c.capacity() + 1] = h;
|
|
1543
|
-
}
|
|
1544
|
-
// Overload for setting to an occupied `h2_t` rather than a special `ctrl_t`.
|
|
1545
|
-
inline void SetCtrlInSingleGroupTable(const CommonFields& c, size_t i, h2_t h,
|
|
1546
|
-
size_t slot_size) {
|
|
1547
|
-
SetCtrlInSingleGroupTable(c, i, static_cast<ctrl_t>(h), slot_size);
|
|
1548
|
-
}
|
|
1549
|
-
|
|
1550
|
-
// Like SetCtrl, but in a table with capacity >= Group::kWidth - 1,
|
|
1551
|
-
// we can save some operations when setting the cloned control byte.
|
|
1552
|
-
inline void SetCtrlInLargeTable(const CommonFields& c, size_t i, ctrl_t h,
|
|
1553
|
-
size_t slot_size) {
|
|
1554
|
-
ABSL_SWISSTABLE_ASSERT(c.capacity() >= Group::kWidth - 1);
|
|
1555
|
-
DoSanitizeOnSetCtrl(c, i, h, slot_size);
|
|
1556
|
-
ctrl_t* ctrl = c.control();
|
|
1557
|
-
ctrl[i] = h;
|
|
1558
|
-
ctrl[((i - NumClonedBytes()) & c.capacity()) + NumClonedBytes()] = h;
|
|
1559
|
-
}
|
|
1560
|
-
// Overload for setting to an occupied `h2_t` rather than a special `ctrl_t`.
|
|
1561
|
-
inline void SetCtrlInLargeTable(const CommonFields& c, size_t i, h2_t h,
|
|
1562
|
-
size_t slot_size) {
|
|
1563
|
-
SetCtrlInLargeTable(c, i, static_cast<ctrl_t>(h), slot_size);
|
|
1564
|
-
}
|
|
1565
|
-
|
|
1566
1698
|
// growth_info (which is a size_t) is stored with the backing array.
|
|
1567
1699
|
constexpr size_t BackingArrayAlignment(size_t align_of_slot) {
|
|
1568
1700
|
return (std::max)(align_of_slot, alignof(GrowthInfo));
|
|
1569
1701
|
}
|
|
1570
1702
|
|
|
1571
|
-
// Returns the address of the ith slot in slots where each slot occupies
|
|
1572
|
-
// slot_size.
|
|
1573
|
-
inline void* SlotAddress(void* slot_array, size_t slot, size_t slot_size) {
|
|
1574
|
-
return static_cast<void*>(static_cast<char*>(slot_array) +
|
|
1575
|
-
(slot * slot_size));
|
|
1576
|
-
}
|
|
1577
|
-
|
|
1578
1703
|
// Iterates over all full slots and calls `cb(const ctrl_t*, void*)`.
|
|
1579
1704
|
// No insertion to the table is allowed during `cb` call.
|
|
1580
1705
|
// Erasure is allowed only for the element passed to the callback.
|
|
@@ -1592,33 +1717,14 @@ constexpr bool ShouldSampleHashtablezInfoForAlloc() {
|
|
|
1592
1717
|
return std::is_same_v<CharAlloc, std::allocator<char>>;
|
|
1593
1718
|
}
|
|
1594
1719
|
|
|
1595
|
-
template <bool kSooEnabled>
|
|
1596
|
-
bool ShouldSampleHashtablezInfoOnResize(bool force_sampling,
|
|
1597
|
-
bool is_hashtablez_eligible,
|
|
1598
|
-
size_t old_capacity, CommonFields& c) {
|
|
1599
|
-
if (!is_hashtablez_eligible) return false;
|
|
1600
|
-
// Force sampling is only allowed for SOO tables.
|
|
1601
|
-
ABSL_SWISSTABLE_ASSERT(kSooEnabled || !force_sampling);
|
|
1602
|
-
if (kSooEnabled && force_sampling) {
|
|
1603
|
-
return true;
|
|
1604
|
-
}
|
|
1605
|
-
// In SOO, we sample on the first insertion so if this is an empty SOO case
|
|
1606
|
-
// (e.g. when reserve is called), then we still need to sample.
|
|
1607
|
-
if (kSooEnabled && old_capacity == SooCapacity() && c.empty()) {
|
|
1608
|
-
return ShouldSampleNextTable();
|
|
1609
|
-
}
|
|
1610
|
-
if (!kSooEnabled && old_capacity == 0) {
|
|
1611
|
-
return ShouldSampleNextTable();
|
|
1612
|
-
}
|
|
1613
|
-
return false;
|
|
1614
|
-
}
|
|
1615
|
-
|
|
1616
1720
|
// Allocates `n` bytes for a backing array.
|
|
1617
1721
|
template <size_t AlignOfBackingArray, typename Alloc>
|
|
1618
|
-
|
|
1722
|
+
void* AllocateBackingArray(void* alloc, size_t n) {
|
|
1619
1723
|
return Allocate<AlignOfBackingArray>(static_cast<Alloc*>(alloc), n);
|
|
1620
1724
|
}
|
|
1621
1725
|
|
|
1726
|
+
// Note: we mark this function as ABSL_ATTRIBUTE_NOINLINE because we don't want
|
|
1727
|
+
// it to be inlined into e.g. the destructor to save code size.
|
|
1622
1728
|
template <size_t AlignOfBackingArray, typename Alloc>
|
|
1623
1729
|
ABSL_ATTRIBUTE_NOINLINE void DeallocateBackingArray(
|
|
1624
1730
|
void* alloc, size_t capacity, ctrl_t* ctrl, size_t slot_size,
|
|
@@ -1647,7 +1753,7 @@ struct PolicyFunctions {
|
|
|
1647
1753
|
void* (*hash_fn)(CommonFields& common);
|
|
1648
1754
|
|
|
1649
1755
|
// Returns the hash of the pointed-to slot.
|
|
1650
|
-
|
|
1756
|
+
HashSlotFn hash_slot;
|
|
1651
1757
|
|
|
1652
1758
|
// Transfers the contents of `count` slots from src_slot to dst_slot.
|
|
1653
1759
|
// We use ability to transfer several slots in single group table growth.
|
|
@@ -1684,51 +1790,54 @@ struct PolicyFunctions {
|
|
|
1684
1790
|
}
|
|
1685
1791
|
};
|
|
1686
1792
|
|
|
1687
|
-
//
|
|
1688
|
-
// This
|
|
1689
|
-
//
|
|
1793
|
+
// The following functions are used for calculating the max valid size of the
|
|
1794
|
+
// table. This is important for security to avoid overflowing size_t when
|
|
1795
|
+
// calculating the allocation size of the backing array
|
|
1796
|
+
// (https://nvd.nist.gov/vuln/detail/CVE-2025-0838). We also limit the max valid
|
|
1797
|
+
// size based on the size of the key_type, and this is an optimization because
|
|
1798
|
+
// we ABSL_ASSUME that the size is less than MaxValidSize, which can enable
|
|
1799
|
+
// other optimizations for tables with small keys.
|
|
1800
|
+
|
|
1690
1801
|
template <size_t kSizeOfSizeT = sizeof(size_t)>
|
|
1691
|
-
constexpr size_t
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1802
|
+
constexpr size_t MaxSizeAtMaxValidCapacity(size_t slot_size) {
|
|
1803
|
+
using SizeT = std::conditional_t<kSizeOfSizeT == 4, uint32_t, uint64_t>;
|
|
1804
|
+
// We shift right by 2 for a safe margin against overflow.
|
|
1805
|
+
constexpr SizeT kMaxValidCapacity = ~SizeT{} >> 2;
|
|
1806
|
+
return CapacityToGrowth(kMaxValidCapacity) / slot_size;
|
|
1807
|
+
}
|
|
1808
|
+
|
|
1809
|
+
constexpr size_t MaxStorableSize() {
|
|
1810
|
+
return static_cast<size_t>(uint64_t{1}
|
|
1811
|
+
<< HashtableInlineData::kSizeBitCount) -
|
|
1812
|
+
1;
|
|
1813
|
+
}
|
|
1814
|
+
|
|
1815
|
+
// There are no more than 2^sizeof(key_type) unique key_types (and hashtable
|
|
1816
|
+
// keys must be unique) so we can't have a hashtable with more than
|
|
1817
|
+
// 2^sizeof(key_type) elements.
|
|
1818
|
+
template <size_t kSizeOfSizeT = sizeof(size_t)>
|
|
1819
|
+
constexpr size_t MaxValidSizeForKeySize(size_t key_size) {
|
|
1820
|
+
if (key_size < kSizeOfSizeT) return size_t{1} << 8 * key_size;
|
|
1821
|
+
return (std::numeric_limits<size_t>::max)();
|
|
1699
1822
|
}
|
|
1700
1823
|
|
|
1701
|
-
// Returns the maximum valid size for a table with provided slot size.
|
|
1702
|
-
// Template parameter is only used to enable testing.
|
|
1703
1824
|
template <size_t kSizeOfSizeT = sizeof(size_t)>
|
|
1704
|
-
constexpr size_t
|
|
1825
|
+
constexpr size_t MaxValidSizeForSlotSize(size_t slot_size) {
|
|
1705
1826
|
if constexpr (kSizeOfSizeT == 8) {
|
|
1706
|
-
// For small slot sizes we are limited by
|
|
1707
|
-
if (slot_size < size_t{1} << (64 -
|
|
1708
|
-
return
|
|
1827
|
+
// For small slot sizes we are limited by HashtableStackData::kSizeBitCount.
|
|
1828
|
+
if (slot_size < size_t{1} << (64 - HashtableInlineData::kSizeBitCount)) {
|
|
1829
|
+
return MaxStorableSize();
|
|
1709
1830
|
}
|
|
1710
|
-
return (size_t{1} << (kSizeOfSizeT * 8 - 2)) / slot_size;
|
|
1711
|
-
} else {
|
|
1712
|
-
return MaxValidSizeFor1ByteSlot<kSizeOfSizeT>() / slot_size;
|
|
1713
1831
|
}
|
|
1832
|
+
return MaxSizeAtMaxValidCapacity<kSizeOfSizeT>(slot_size);
|
|
1714
1833
|
}
|
|
1715
1834
|
|
|
1716
|
-
// Returns
|
|
1717
|
-
// It is an optimization to avoid the division operation in the common case.
|
|
1835
|
+
// Returns the maximum valid size for a table, given the key size and slot size.
|
|
1718
1836
|
// Template parameter is only used to enable testing.
|
|
1719
1837
|
template <size_t kSizeOfSizeT = sizeof(size_t)>
|
|
1720
|
-
constexpr
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
if (ABSL_PREDICT_TRUE(slot_size <
|
|
1724
|
-
(size_t{1} << (64 - HashtableSize::kSizeBitCount)))) {
|
|
1725
|
-
return size > MaxValidSizeFor1ByteSlot<kSizeOfSizeT>();
|
|
1726
|
-
}
|
|
1727
|
-
return size > MaxValidSize<kSizeOfSizeT>(slot_size);
|
|
1728
|
-
} else {
|
|
1729
|
-
return uint64_t{size} * slot_size >
|
|
1730
|
-
MaxValidSizeFor1ByteSlot<kSizeOfSizeT>();
|
|
1731
|
-
}
|
|
1838
|
+
constexpr size_t MaxValidSize(size_t key_size, size_t slot_size) {
|
|
1839
|
+
return (std::min)(MaxValidSizeForKeySize<kSizeOfSizeT>(key_size),
|
|
1840
|
+
MaxValidSizeForSlotSize<kSizeOfSizeT>(slot_size));
|
|
1732
1841
|
}
|
|
1733
1842
|
|
|
1734
1843
|
// Returns the index of the SOO slot when growing from SOO to non-SOO in a
|
|
@@ -1743,8 +1852,9 @@ constexpr size_t SooSlotIndex() { return 1; }
|
|
|
1743
1852
|
// Allowing till 16 would require additional store that can be avoided.
|
|
1744
1853
|
constexpr size_t MaxSmallAfterSooCapacity() { return 7; }
|
|
1745
1854
|
|
|
1746
|
-
// Type erased version of raw_hash_set::reserve.
|
|
1747
|
-
//
|
|
1855
|
+
// Type erased version of raw_hash_set::reserve. Requires:
|
|
1856
|
+
// 1. `new_size > policy.soo_capacity`.
|
|
1857
|
+
// 2. `new_size <= kMaxValidSize`.
|
|
1748
1858
|
void ReserveTableToFitNewSize(CommonFields& common,
|
|
1749
1859
|
const PolicyFunctions& policy, size_t new_size);
|
|
1750
1860
|
|
|
@@ -1753,11 +1863,13 @@ void ReserveTableToFitNewSize(CommonFields& common,
|
|
|
1753
1863
|
// 1. `c.capacity() == policy.soo_capacity`.
|
|
1754
1864
|
// 2. `c.empty()`.
|
|
1755
1865
|
// 3. `new_size > policy.soo_capacity`.
|
|
1866
|
+
// 4. `bucket_count <= MaxValidCapacity()`.
|
|
1756
1867
|
// The table will be attempted to be sampled.
|
|
1757
1868
|
void ReserveEmptyNonAllocatedTableToFitBucketCount(
|
|
1758
1869
|
CommonFields& common, const PolicyFunctions& policy, size_t bucket_count);
|
|
1759
1870
|
|
|
1760
1871
|
// Type erased version of raw_hash_set::rehash.
|
|
1872
|
+
// Requires: `n <= MaxValidCapacity()`.
|
|
1761
1873
|
void Rehash(CommonFields& common, const PolicyFunctions& policy, size_t n);
|
|
1762
1874
|
|
|
1763
1875
|
// Type erased version of copy constructor.
|
|
@@ -1802,23 +1914,20 @@ constexpr size_t OptimalMemcpySizeForSooSlotTransfer(
|
|
|
1802
1914
|
|
|
1803
1915
|
// Resizes SOO table to the NextCapacity(SooCapacity()) and prepares insert for
|
|
1804
1916
|
// the given new_hash. Returns the offset of the new element.
|
|
1805
|
-
// `soo_slot_ctrl` is the control byte of the SOO slot.
|
|
1806
|
-
// If soo_slot_ctrl is kEmpty
|
|
1807
|
-
// 1. The table must be empty.
|
|
1808
|
-
// 2. Table will be forced to be sampled.
|
|
1809
1917
|
// All possible template combinations are defined in cc file to improve
|
|
1810
1918
|
// compilation time.
|
|
1811
1919
|
template <size_t SooSlotMemcpySize, bool TransferUsesMemcpy>
|
|
1812
|
-
size_t GrowSooTableToNextCapacityAndPrepareInsert(
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
//
|
|
1818
|
-
//
|
|
1819
|
-
//
|
|
1820
|
-
void
|
|
1821
|
-
|
|
1920
|
+
size_t GrowSooTableToNextCapacityAndPrepareInsert(
|
|
1921
|
+
CommonFields& common, const PolicyFunctions& policy,
|
|
1922
|
+
absl::FunctionRef<size_t(size_t)> get_hash, bool force_sampling);
|
|
1923
|
+
|
|
1924
|
+
// PrepareInsert for small tables (is_small()==true).
|
|
1925
|
+
// Returns the new control and the new slot.
|
|
1926
|
+
// Hash is only computed if the table is sampled or grew to large size
|
|
1927
|
+
// (is_small()==false).
|
|
1928
|
+
std::pair<ctrl_t*, void*> PrepareInsertSmallNonSoo(
|
|
1929
|
+
CommonFields& common, const PolicyFunctions& policy,
|
|
1930
|
+
absl::FunctionRef<size_t(size_t)> get_hash);
|
|
1822
1931
|
|
|
1823
1932
|
// Resizes table with allocated slots and change the table seed.
|
|
1824
1933
|
// Tables with SOO enabled must have capacity > policy.soo_capacity.
|
|
@@ -1829,12 +1938,13 @@ void ResizeAllocatedTableWithSeedChange(CommonFields& common,
|
|
|
1829
1938
|
|
|
1830
1939
|
// ClearBackingArray clears the backing array, either modifying it in place,
|
|
1831
1940
|
// or creating a new one based on the value of "reuse".
|
|
1832
|
-
// REQUIRES: c.capacity >
|
|
1941
|
+
// REQUIRES: c.capacity > MaxSmallCapacity().
|
|
1833
1942
|
void ClearBackingArray(CommonFields& c, const PolicyFunctions& policy,
|
|
1834
|
-
void* alloc, bool reuse
|
|
1943
|
+
void* alloc, bool reuse);
|
|
1835
1944
|
|
|
1836
|
-
// Type-erased
|
|
1837
|
-
void
|
|
1945
|
+
// Type-erased versions of raw_hash_set::erase_meta_only_{small,large}.
|
|
1946
|
+
void EraseMetaOnlySmall(CommonFields& c, bool soo_enabled, size_t slot_size);
|
|
1947
|
+
void EraseMetaOnlyLarge(CommonFields& c, const ctrl_t* ctrl, size_t slot_size);
|
|
1838
1948
|
|
|
1839
1949
|
// For trivially relocatable types we use memcpy directly. This allows us to
|
|
1840
1950
|
// share the same function body for raw_hash_set instantiations that have the
|
|
@@ -1853,23 +1963,44 @@ ABSL_ATTRIBUTE_NOINLINE void TransferNRelocatable(void*, void* dst, void* src,
|
|
|
1853
1963
|
// empty class cases.
|
|
1854
1964
|
void* GetRefForEmptyClass(CommonFields& common);
|
|
1855
1965
|
|
|
1856
|
-
// Given the hash of a value not currently in the table and the first
|
|
1857
|
-
// slot in the probe sequence, finds a viable slot index to insert it
|
|
1966
|
+
// Given the hash of a value not currently in the table and the first group with
|
|
1967
|
+
// an empty slot in the probe sequence, finds a viable slot index to insert it
|
|
1968
|
+
// at.
|
|
1858
1969
|
//
|
|
1859
1970
|
// In case there's no space left, the table can be resized or rehashed
|
|
1860
1971
|
// (for tables with deleted slots, see FindInsertPositionWithGrowthOrRehash).
|
|
1861
1972
|
//
|
|
1862
1973
|
// In the case of absence of deleted slots and positive growth_left, the element
|
|
1863
|
-
// can be inserted in the provided `
|
|
1974
|
+
// can be inserted in one of the empty slots in the provided `target_group`.
|
|
1864
1975
|
//
|
|
1865
1976
|
// When the table has deleted slots (according to GrowthInfo), the target
|
|
1866
1977
|
// position will be searched one more time using `find_first_non_full`.
|
|
1867
1978
|
//
|
|
1868
|
-
// REQUIRES:
|
|
1979
|
+
// REQUIRES: `!common.is_small()`.
|
|
1869
1980
|
// REQUIRES: At least one non-full slot available.
|
|
1870
|
-
// REQUIRES: `
|
|
1871
|
-
|
|
1872
|
-
|
|
1981
|
+
// REQUIRES: `mask_empty` is a mask containing empty slots for the
|
|
1982
|
+
// `target_group`.
|
|
1983
|
+
// REQUIRES: `target_group` is a starting position for the group that has
|
|
1984
|
+
// at least one empty slot.
|
|
1985
|
+
size_t PrepareInsertLarge(CommonFields& common, const PolicyFunctions& policy,
|
|
1986
|
+
size_t hash, Group::NonIterableBitMaskType mask_empty,
|
|
1987
|
+
FindInfo target_group);
|
|
1988
|
+
|
|
1989
|
+
// Same as above, but with generations enabled, we may end up changing the seed,
|
|
1990
|
+
// which means we need to be able to recompute the hash.
|
|
1991
|
+
size_t PrepareInsertLargeGenerationsEnabled(
|
|
1992
|
+
CommonFields& common, const PolicyFunctions& policy, size_t hash,
|
|
1993
|
+
Group::NonIterableBitMaskType mask_empty, FindInfo target_group,
|
|
1994
|
+
absl::FunctionRef<size_t(size_t)> recompute_hash);
|
|
1995
|
+
|
|
1996
|
+
template <typename Policy, typename Hash, typename Eq, typename Alloc>
|
|
1997
|
+
struct InstantiateRawHashSet {
|
|
1998
|
+
using type = typename ApplyWithoutDefaultSuffix<
|
|
1999
|
+
raw_hash_set,
|
|
2000
|
+
TypeList<void, typename Policy::DefaultHash, typename Policy::DefaultEq,
|
|
2001
|
+
typename Policy::DefaultAlloc>,
|
|
2002
|
+
TypeList<Policy, Hash, Eq, Alloc>>::type;
|
|
2003
|
+
};
|
|
1873
2004
|
|
|
1874
2005
|
// A SwissTable.
|
|
1875
2006
|
//
|
|
@@ -1877,26 +2008,47 @@ size_t PrepareInsertNonSoo(CommonFields& common, const PolicyFunctions& policy,
|
|
|
1877
2008
|
// the slots of the hashtable (see hash_policy_traits.h for the full interface
|
|
1878
2009
|
// of policy).
|
|
1879
2010
|
//
|
|
2011
|
+
// Params...: a variadic list of parameters that allows us to omit default
|
|
2012
|
+
// types. This reduces the mangled name of the class and the size of
|
|
2013
|
+
// debug strings like __PRETTY_FUNCTION__. Default types do not give
|
|
2014
|
+
// any new information.
|
|
2015
|
+
//
|
|
1880
2016
|
// Hash: a (possibly polymorphic) functor that hashes keys of the hashtable. The
|
|
1881
2017
|
// functor should accept a key and return size_t as hash. For best performance
|
|
1882
2018
|
// it is important that the hash function provides high entropy across all bits
|
|
1883
2019
|
// of the hash.
|
|
2020
|
+
// This is the first element in `Params...` if it exists, or Policy::DefaultHash
|
|
2021
|
+
// otherwise.
|
|
1884
2022
|
//
|
|
1885
2023
|
// Eq: a (possibly polymorphic) functor that compares two keys for equality. It
|
|
1886
2024
|
// should accept two (of possibly different type) keys and return a bool: true
|
|
1887
2025
|
// if they are equal, false if they are not. If two keys compare equal, then
|
|
1888
2026
|
// their hash values as defined by Hash MUST be equal.
|
|
2027
|
+
// This is the second element in `Params...` if it exists, or Policy::DefaultEq
|
|
2028
|
+
// otherwise.
|
|
1889
2029
|
//
|
|
1890
2030
|
// Allocator: an Allocator
|
|
1891
2031
|
// [https://en.cppreference.com/w/cpp/named_req/Allocator] with which
|
|
1892
2032
|
// the storage of the hashtable will be allocated and the elements will be
|
|
1893
2033
|
// constructed and destroyed.
|
|
1894
|
-
|
|
2034
|
+
// This is the third element in `Params...` if it exists, or
|
|
2035
|
+
// Policy::DefaultAlloc otherwise.
|
|
2036
|
+
template <class Policy, class... Params>
|
|
1895
2037
|
class raw_hash_set {
|
|
1896
2038
|
using PolicyTraits = hash_policy_traits<Policy>;
|
|
2039
|
+
using Hash = GetFromListOr<typename Policy::DefaultHash, 0, Params...>;
|
|
2040
|
+
using Eq = GetFromListOr<typename Policy::DefaultEq, 1, Params...>;
|
|
2041
|
+
using Alloc = GetFromListOr<typename Policy::DefaultAlloc, 2, Params...>;
|
|
1897
2042
|
using KeyArgImpl =
|
|
1898
2043
|
KeyArg<IsTransparent<Eq>::value && IsTransparent<Hash>::value>;
|
|
1899
2044
|
|
|
2045
|
+
static_assert(
|
|
2046
|
+
std::is_same_v<
|
|
2047
|
+
typename InstantiateRawHashSet<Policy, Hash, Eq, Alloc>::type,
|
|
2048
|
+
raw_hash_set>,
|
|
2049
|
+
"Redundant template parameters were passed. Use InstantiateRawHashSet<> "
|
|
2050
|
+
"instead");
|
|
2051
|
+
|
|
1900
2052
|
public:
|
|
1901
2053
|
using init_type = typename PolicyTraits::init_type;
|
|
1902
2054
|
using key_type = typename PolicyTraits::key_type;
|
|
@@ -1909,9 +2061,9 @@ class raw_hash_set {
|
|
|
1909
2061
|
using value_type = typename PolicyTraits::value_type;
|
|
1910
2062
|
using reference = value_type&;
|
|
1911
2063
|
using const_reference = const value_type&;
|
|
1912
|
-
using pointer = typename
|
|
2064
|
+
using pointer = typename std::allocator_traits<
|
|
1913
2065
|
allocator_type>::template rebind_traits<value_type>::pointer;
|
|
1914
|
-
using const_pointer = typename
|
|
2066
|
+
using const_pointer = typename std::allocator_traits<
|
|
1915
2067
|
allocator_type>::template rebind_traits<value_type>::const_pointer;
|
|
1916
2068
|
|
|
1917
2069
|
private:
|
|
@@ -1924,6 +2076,10 @@ class raw_hash_set {
|
|
|
1924
2076
|
|
|
1925
2077
|
using slot_type = typename PolicyTraits::slot_type;
|
|
1926
2078
|
|
|
2079
|
+
constexpr static bool kIsDefaultHash =
|
|
2080
|
+
std::is_same_v<hasher, absl::Hash<key_type>> ||
|
|
2081
|
+
std::is_same_v<hasher, absl::container_internal::StringHash>;
|
|
2082
|
+
|
|
1927
2083
|
// TODO(b/289225379): we could add extra SOO space inside raw_hash_set
|
|
1928
2084
|
// after CommonFields to allow inlining larger slot_types (e.g. std::string),
|
|
1929
2085
|
// but it's a bit complicated if we want to support incomplete mapped_type in
|
|
@@ -1939,28 +2095,47 @@ class raw_hash_set {
|
|
|
1939
2095
|
constexpr static size_t DefaultCapacity() {
|
|
1940
2096
|
return SooEnabled() ? SooCapacity() : 0;
|
|
1941
2097
|
}
|
|
2098
|
+
constexpr static size_t MaxValidSize() {
|
|
2099
|
+
return container_internal::MaxValidSize(sizeof(key_type),
|
|
2100
|
+
sizeof(slot_type));
|
|
2101
|
+
}
|
|
2102
|
+
constexpr static size_t MaxValidCapacity() {
|
|
2103
|
+
return SizeToCapacity(MaxValidSize());
|
|
2104
|
+
}
|
|
1942
2105
|
|
|
1943
2106
|
// Whether `size` fits in the SOO capacity of this table.
|
|
1944
2107
|
bool fits_in_soo(size_t size) const {
|
|
1945
2108
|
return SooEnabled() && size <= SooCapacity();
|
|
1946
2109
|
}
|
|
1947
2110
|
// Whether this table is in SOO mode or non-SOO mode.
|
|
1948
|
-
bool is_soo() const {
|
|
2111
|
+
bool is_soo() const {
|
|
2112
|
+
HashtableCapacity cap = maybe_invalid_capacity();
|
|
2113
|
+
return cap.IsValid() && fits_in_soo(cap.capacity());
|
|
2114
|
+
}
|
|
1949
2115
|
bool is_full_soo() const { return is_soo() && !empty(); }
|
|
1950
2116
|
|
|
2117
|
+
bool is_small() const { return common().is_small(); }
|
|
2118
|
+
|
|
1951
2119
|
// Give an early error when key_type is not hashable/eq.
|
|
1952
2120
|
auto KeyTypeCanBeHashed(const Hash& h, const key_type& k) -> decltype(h(k));
|
|
1953
2121
|
auto KeyTypeCanBeEq(const Eq& eq, const key_type& k) -> decltype(eq(k, k));
|
|
1954
2122
|
|
|
1955
|
-
|
|
1956
|
-
using
|
|
2123
|
+
// Try to be helpful when the hasher returns an unreasonable type.
|
|
2124
|
+
using key_hash_result =
|
|
2125
|
+
absl::remove_cvref_t<decltype(std::declval<const Hash&>()(
|
|
2126
|
+
std::declval<const key_type&>()))>;
|
|
2127
|
+
static_assert(sizeof(key_hash_result) >= sizeof(size_t),
|
|
2128
|
+
"`Hash::operator()` should return a `size_t`");
|
|
2129
|
+
|
|
2130
|
+
using AllocTraits = std::allocator_traits<allocator_type>;
|
|
2131
|
+
using SlotAlloc = typename std::allocator_traits<
|
|
1957
2132
|
allocator_type>::template rebind_alloc<slot_type>;
|
|
1958
2133
|
// People are often sloppy with the exact type of their allocator (sometimes
|
|
1959
2134
|
// it has an extra const or is missing the pair, but rebinds made it work
|
|
1960
2135
|
// anyway).
|
|
1961
2136
|
using CharAlloc =
|
|
1962
|
-
typename
|
|
1963
|
-
using SlotAllocTraits = typename
|
|
2137
|
+
typename std::allocator_traits<Alloc>::template rebind_alloc<char>;
|
|
2138
|
+
using SlotAllocTraits = typename std::allocator_traits<
|
|
1964
2139
|
allocator_type>::template rebind_traits<slot_type>;
|
|
1965
2140
|
|
|
1966
2141
|
static_assert(std::is_lvalue_reference<reference>::value,
|
|
@@ -1969,7 +2144,7 @@ class raw_hash_set {
|
|
|
1969
2144
|
// An enabler for insert(T&&): T must be convertible to init_type or be the
|
|
1970
2145
|
// same as [cv] value_type [ref].
|
|
1971
2146
|
template <class T>
|
|
1972
|
-
using Insertable =
|
|
2147
|
+
using Insertable = std::disjunction<
|
|
1973
2148
|
std::is_same<absl::remove_cvref_t<reference>, absl::remove_cvref_t<T>>,
|
|
1974
2149
|
std::is_convertible<T, init_type>>;
|
|
1975
2150
|
template <class T>
|
|
@@ -2009,28 +2184,28 @@ class raw_hash_set {
|
|
|
2009
2184
|
using iterator_category = std::forward_iterator_tag;
|
|
2010
2185
|
using value_type = typename raw_hash_set::value_type;
|
|
2011
2186
|
using reference =
|
|
2012
|
-
|
|
2187
|
+
std::conditional_t<PolicyTraits::constant_iterators::value,
|
|
2013
2188
|
const value_type&, value_type&>;
|
|
2014
|
-
using pointer =
|
|
2189
|
+
using pointer = std::remove_reference_t<reference>*;
|
|
2015
2190
|
using difference_type = typename raw_hash_set::difference_type;
|
|
2016
2191
|
|
|
2017
2192
|
iterator() {}
|
|
2018
2193
|
|
|
2019
2194
|
// PRECONDITION: not an end() iterator.
|
|
2020
2195
|
reference operator*() const {
|
|
2021
|
-
|
|
2196
|
+
assert_is_full("operator*()");
|
|
2022
2197
|
return unchecked_deref();
|
|
2023
2198
|
}
|
|
2024
2199
|
|
|
2025
2200
|
// PRECONDITION: not an end() iterator.
|
|
2026
2201
|
pointer operator->() const {
|
|
2027
|
-
|
|
2202
|
+
assert_is_full("operator->");
|
|
2028
2203
|
return &operator*();
|
|
2029
2204
|
}
|
|
2030
2205
|
|
|
2031
2206
|
// PRECONDITION: not an end() iterator.
|
|
2032
2207
|
iterator& operator++() {
|
|
2033
|
-
|
|
2208
|
+
assert_is_full("operator++");
|
|
2034
2209
|
++ctrl_;
|
|
2035
2210
|
++slot_;
|
|
2036
2211
|
skip_empty_or_deleted();
|
|
@@ -2068,7 +2243,7 @@ class raw_hash_set {
|
|
|
2068
2243
|
// This constructor is used in begin() to avoid an MSan
|
|
2069
2244
|
// use-of-uninitialized-value error. Delegating from this constructor to
|
|
2070
2245
|
// the previous one doesn't avoid the error.
|
|
2071
|
-
iterator(ctrl_t* ctrl, MaybeInitializedPtr slot,
|
|
2246
|
+
iterator(ctrl_t* ctrl, MaybeInitializedPtr<void> slot,
|
|
2072
2247
|
const GenerationType* generation_ptr)
|
|
2073
2248
|
: HashSetIteratorGenerationInfo(generation_ptr),
|
|
2074
2249
|
ctrl_(ctrl),
|
|
@@ -2081,38 +2256,42 @@ class raw_hash_set {
|
|
|
2081
2256
|
explicit iterator(const GenerationType* generation_ptr)
|
|
2082
2257
|
: HashSetIteratorGenerationInfo(generation_ptr), ctrl_(nullptr) {}
|
|
2083
2258
|
|
|
2259
|
+
void assert_is_full(const char* operation) const {
|
|
2260
|
+
AssertIsFull(ctrl_, generation(), generation_ptr(), operation);
|
|
2261
|
+
}
|
|
2262
|
+
|
|
2084
2263
|
// Fixes up `ctrl_` to point to a full or sentinel by advancing `ctrl_` and
|
|
2085
2264
|
// `slot_` until they reach one.
|
|
2086
2265
|
void skip_empty_or_deleted() {
|
|
2087
2266
|
while (IsEmptyOrDeleted(*ctrl_)) {
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
ctrl_ += shift;
|
|
2091
|
-
slot_ += shift;
|
|
2267
|
+
++ctrl_;
|
|
2268
|
+
++slot_;
|
|
2092
2269
|
}
|
|
2093
2270
|
}
|
|
2094
2271
|
|
|
2095
|
-
ctrl_t* control() const { return ctrl_; }
|
|
2096
|
-
slot_type* slot() const { return slot_; }
|
|
2097
|
-
|
|
2098
|
-
// We use EmptyGroup() for default-constructed iterators so that they can
|
|
2099
|
-
// be distinguished from end iterators, which have nullptr ctrl_.
|
|
2100
|
-
ctrl_t* ctrl_ = EmptyGroup();
|
|
2101
|
-
// To avoid uninitialized member warnings, put slot_ in an anonymous union.
|
|
2102
|
-
// The member is not initialized on singleton and end iterators.
|
|
2103
|
-
union {
|
|
2104
|
-
slot_type* slot_;
|
|
2105
|
-
};
|
|
2106
|
-
|
|
2107
2272
|
// An equality check which skips ABSL Hardening iterator invalidation
|
|
2108
2273
|
// checks.
|
|
2109
2274
|
// Should be used when the lifetimes of the iterators are well-enough
|
|
2110
2275
|
// understood to prove that they cannot be invalid.
|
|
2111
|
-
bool unchecked_equals(const iterator& b) {
|
|
2276
|
+
bool unchecked_equals(const iterator& b) const {
|
|
2277
|
+
return ctrl_ == b.control();
|
|
2278
|
+
}
|
|
2112
2279
|
|
|
2113
2280
|
// Dereferences the iterator without ABSL Hardening iterator invalidation
|
|
2114
2281
|
// checks.
|
|
2115
2282
|
reference unchecked_deref() const { return PolicyTraits::element(slot_); }
|
|
2283
|
+
|
|
2284
|
+
ctrl_t* control() const { return ctrl_; }
|
|
2285
|
+
slot_type* slot() const { return slot_; }
|
|
2286
|
+
|
|
2287
|
+
// We use DefaultIterControl() for default-constructed iterators so that
|
|
2288
|
+
// they can be distinguished from end iterators, which have nullptr ctrl_.
|
|
2289
|
+
ctrl_t* ctrl_ = DefaultIterControl();
|
|
2290
|
+
// To avoid uninitialized member warnings, put slot_ in an anonymous union.
|
|
2291
|
+
// The member is not initialized on singleton and end iterators.
|
|
2292
|
+
union {
|
|
2293
|
+
slot_type* slot_;
|
|
2294
|
+
};
|
|
2116
2295
|
};
|
|
2117
2296
|
|
|
2118
2297
|
class const_iterator {
|
|
@@ -2153,14 +2332,13 @@ class raw_hash_set {
|
|
|
2153
2332
|
const GenerationType* gen)
|
|
2154
2333
|
: inner_(const_cast<ctrl_t*>(ctrl), const_cast<slot_type*>(slot), gen) {
|
|
2155
2334
|
}
|
|
2335
|
+
bool unchecked_equals(const const_iterator& b) const {
|
|
2336
|
+
return inner_.unchecked_equals(b.inner_);
|
|
2337
|
+
}
|
|
2156
2338
|
ctrl_t* control() const { return inner_.control(); }
|
|
2157
2339
|
slot_type* slot() const { return inner_.slot(); }
|
|
2158
2340
|
|
|
2159
2341
|
iterator inner_;
|
|
2160
|
-
|
|
2161
|
-
bool unchecked_equals(const const_iterator& b) {
|
|
2162
|
-
return inner_.unchecked_equals(b.inner_);
|
|
2163
|
-
}
|
|
2164
2342
|
};
|
|
2165
2343
|
|
|
2166
2344
|
using node_type = node_handle<Policy, hash_policy_traits<Policy>, Alloc>;
|
|
@@ -2181,7 +2359,8 @@ class raw_hash_set {
|
|
|
2181
2359
|
alloc) {
|
|
2182
2360
|
if (bucket_count > DefaultCapacity()) {
|
|
2183
2361
|
ReserveEmptyNonAllocatedTableToFitBucketCount(
|
|
2184
|
-
common(), GetPolicyFunctions(),
|
|
2362
|
+
common(), GetPolicyFunctions(),
|
|
2363
|
+
(std::min)(bucket_count, MaxValidCapacity()));
|
|
2185
2364
|
}
|
|
2186
2365
|
}
|
|
2187
2366
|
|
|
@@ -2214,6 +2393,28 @@ class raw_hash_set {
|
|
|
2214
2393
|
const allocator_type& alloc)
|
|
2215
2394
|
: raw_hash_set(first, last, bucket_count, hasher(), key_equal(), alloc) {}
|
|
2216
2395
|
|
|
2396
|
+
#if defined(__cpp_lib_containers_ranges) && \
|
|
2397
|
+
__cpp_lib_containers_ranges >= 202202L
|
|
2398
|
+
template <typename R>
|
|
2399
|
+
raw_hash_set(std::from_range_t, R&& rg, size_type bucket_count = 0,
|
|
2400
|
+
const hasher& hash = hasher(), const key_equal& eq = key_equal(),
|
|
2401
|
+
const allocator_type& alloc = allocator_type())
|
|
2402
|
+
: raw_hash_set(std::begin(rg), std::end(rg), bucket_count, hash, eq,
|
|
2403
|
+
alloc) {}
|
|
2404
|
+
|
|
2405
|
+
template <typename R>
|
|
2406
|
+
raw_hash_set(std::from_range_t, R&& rg, size_type bucket_count,
|
|
2407
|
+
const allocator_type& alloc)
|
|
2408
|
+
: raw_hash_set(std::from_range, std::forward<R>(rg), bucket_count,
|
|
2409
|
+
hasher(), key_equal(), alloc) {}
|
|
2410
|
+
|
|
2411
|
+
template <typename R>
|
|
2412
|
+
raw_hash_set(std::from_range_t, R&& rg, size_type bucket_count,
|
|
2413
|
+
const hasher& hash, const allocator_type& alloc)
|
|
2414
|
+
: raw_hash_set(std::from_range, std::forward<R>(rg), bucket_count, hash,
|
|
2415
|
+
key_equal(), alloc) {}
|
|
2416
|
+
#endif
|
|
2417
|
+
|
|
2217
2418
|
template <class InputIter>
|
|
2218
2419
|
raw_hash_set(InputIter first, InputIter last, const allocator_type& alloc)
|
|
2219
2420
|
: raw_hash_set(first, last, 0, hasher(), key_equal(), alloc) {}
|
|
@@ -2308,7 +2509,8 @@ class raw_hash_set {
|
|
|
2308
2509
|
// Note: we avoid using exchange for better generated code.
|
|
2309
2510
|
settings_(PolicyTraits::transfer_uses_memcpy() || !that.is_full_soo()
|
|
2310
2511
|
? std::move(that.common())
|
|
2311
|
-
: CommonFields{full_soo_tag_t{}
|
|
2512
|
+
: CommonFields{full_soo_tag_t{},
|
|
2513
|
+
that.common().soo_has_tried_sampling()},
|
|
2312
2514
|
that.hash_ref(), that.eq_ref(), that.char_alloc_ref()) {
|
|
2313
2515
|
if (!PolicyTraits::transfer_uses_memcpy() && that.is_full_soo()) {
|
|
2314
2516
|
transfer(soo_slot(), that.soo_slot());
|
|
@@ -2345,7 +2547,7 @@ class raw_hash_set {
|
|
|
2345
2547
|
}
|
|
2346
2548
|
|
|
2347
2549
|
raw_hash_set& operator=(raw_hash_set&& that) noexcept(
|
|
2348
|
-
|
|
2550
|
+
AllocTraits::is_always_equal::value &&
|
|
2349
2551
|
std::is_nothrow_move_assignable<hasher>::value &&
|
|
2350
2552
|
std::is_nothrow_move_assignable<key_equal>::value) {
|
|
2351
2553
|
// TODO(sbenza): We should only use the operations from the noexcept clause
|
|
@@ -2359,13 +2561,13 @@ class raw_hash_set {
|
|
|
2359
2561
|
~raw_hash_set() {
|
|
2360
2562
|
destructor_impl();
|
|
2361
2563
|
if constexpr (SwisstableAssertAccessToDestroyedTable()) {
|
|
2362
|
-
common().set_capacity(
|
|
2564
|
+
common().set_capacity(HashtableCapacity::CreateDestroyed());
|
|
2363
2565
|
}
|
|
2364
2566
|
}
|
|
2365
2567
|
|
|
2366
2568
|
iterator begin() ABSL_ATTRIBUTE_LIFETIME_BOUND {
|
|
2367
2569
|
if (ABSL_PREDICT_FALSE(empty())) return end();
|
|
2368
|
-
if (
|
|
2570
|
+
if (is_small()) return single_iterator();
|
|
2369
2571
|
iterator it = {control(), common().slots_union(),
|
|
2370
2572
|
common().generation_ptr()};
|
|
2371
2573
|
it.skip_empty_or_deleted();
|
|
@@ -2391,21 +2593,27 @@ class raw_hash_set {
|
|
|
2391
2593
|
bool empty() const { return !size(); }
|
|
2392
2594
|
size_t size() const {
|
|
2393
2595
|
AssertNotDebugCapacity();
|
|
2394
|
-
|
|
2596
|
+
const size_t size = common().size();
|
|
2597
|
+
[[maybe_unused]] const size_t kMaxValidSize = MaxValidSize();
|
|
2598
|
+
ABSL_ASSUME(size <= kMaxValidSize);
|
|
2599
|
+
return size;
|
|
2395
2600
|
}
|
|
2396
2601
|
size_t capacity() const {
|
|
2397
2602
|
const size_t cap = common().capacity();
|
|
2398
|
-
// Compiler complains when using functions in ASSUME so use local
|
|
2399
|
-
|
|
2400
|
-
|
|
2603
|
+
// Compiler complains when using functions in ASSUME so use local variables.
|
|
2604
|
+
[[maybe_unused]] const bool kIsValid = IsValidCapacity(cap);
|
|
2605
|
+
[[maybe_unused]] const size_t kDefaultCapacity = DefaultCapacity();
|
|
2606
|
+
[[maybe_unused]] const size_t kMaxValidCapacity = MaxValidCapacity();
|
|
2607
|
+
ABSL_ASSUME(kIsValid || cap == 0);
|
|
2401
2608
|
ABSL_ASSUME(cap >= kDefaultCapacity);
|
|
2609
|
+
ABSL_ASSUME(cap <= kMaxValidCapacity);
|
|
2402
2610
|
return cap;
|
|
2403
2611
|
}
|
|
2404
|
-
size_t max_size() const { return MaxValidSize(
|
|
2612
|
+
size_t max_size() const { return MaxValidSize(); }
|
|
2405
2613
|
|
|
2406
2614
|
ABSL_ATTRIBUTE_REINITIALIZES void clear() {
|
|
2407
2615
|
if (SwisstableGenerationsEnabled() &&
|
|
2408
|
-
|
|
2616
|
+
maybe_invalid_capacity().IsMovedFrom()) {
|
|
2409
2617
|
common().set_capacity(DefaultCapacity());
|
|
2410
2618
|
}
|
|
2411
2619
|
AssertNotDebugCapacity();
|
|
@@ -2419,9 +2627,11 @@ class raw_hash_set {
|
|
|
2419
2627
|
const size_t cap = capacity();
|
|
2420
2628
|
if (cap == 0) {
|
|
2421
2629
|
// Already guaranteed to be empty; so nothing to do.
|
|
2422
|
-
} else if (
|
|
2423
|
-
if (!empty())
|
|
2424
|
-
|
|
2630
|
+
} else if (is_small()) {
|
|
2631
|
+
if (!empty()) {
|
|
2632
|
+
destroy(single_slot());
|
|
2633
|
+
decrement_small_size();
|
|
2634
|
+
}
|
|
2425
2635
|
} else {
|
|
2426
2636
|
destroy_slots();
|
|
2427
2637
|
clear_backing_array(/*reuse=*/cap < 128);
|
|
@@ -2491,13 +2701,13 @@ class raw_hash_set {
|
|
|
2491
2701
|
// s.insert({"abc", 42});
|
|
2492
2702
|
std::pair<iterator, bool> insert(init_type&& value)
|
|
2493
2703
|
ABSL_ATTRIBUTE_LIFETIME_BOUND
|
|
2494
|
-
#if
|
|
2704
|
+
#if ABSL_INTERNAL_CPLUSPLUS_LANG >= 202002L
|
|
2495
2705
|
requires(!IsLifetimeBoundAssignmentFrom<init_type>::value)
|
|
2496
2706
|
#endif
|
|
2497
2707
|
{
|
|
2498
2708
|
return emplace(std::move(value));
|
|
2499
2709
|
}
|
|
2500
|
-
#if
|
|
2710
|
+
#if ABSL_INTERNAL_CPLUSPLUS_LANG >= 202002L
|
|
2501
2711
|
std::pair<iterator, bool> insert(
|
|
2502
2712
|
init_type&& value ABSL_INTERNAL_ATTRIBUTE_CAPTURED_BY(this))
|
|
2503
2713
|
ABSL_ATTRIBUTE_LIFETIME_BOUND
|
|
@@ -2540,17 +2750,17 @@ class raw_hash_set {
|
|
|
2540
2750
|
|
|
2541
2751
|
template <class InputIt>
|
|
2542
2752
|
void insert(InputIt first, InputIt last) {
|
|
2543
|
-
|
|
2753
|
+
insert_range(first, last);
|
|
2544
2754
|
}
|
|
2545
2755
|
|
|
2546
2756
|
template <class T, RequiresNotInit<T> = 0,
|
|
2547
2757
|
std::enable_if_t<Insertable<const T&>::value, int> = 0>
|
|
2548
2758
|
void insert(std::initializer_list<T> ilist) {
|
|
2549
|
-
|
|
2759
|
+
insert_range(ilist.begin(), ilist.end());
|
|
2550
2760
|
}
|
|
2551
2761
|
|
|
2552
2762
|
void insert(std::initializer_list<init_type> ilist) {
|
|
2553
|
-
|
|
2763
|
+
insert_range(ilist.begin(), ilist.end());
|
|
2554
2764
|
}
|
|
2555
2765
|
|
|
2556
2766
|
insert_return_type insert(node_type&& node) ABSL_ATTRIBUTE_LIFETIME_BOUND {
|
|
@@ -2697,26 +2907,23 @@ class raw_hash_set {
|
|
|
2697
2907
|
// This overload is necessary because otherwise erase<K>(const K&) would be
|
|
2698
2908
|
// a better match if non-const iterator is passed as an argument.
|
|
2699
2909
|
void erase(iterator it) {
|
|
2910
|
+
ABSL_SWISSTABLE_ASSERT(capacity() > 0);
|
|
2700
2911
|
AssertNotDebugCapacity();
|
|
2701
|
-
|
|
2912
|
+
it.assert_is_full("erase()");
|
|
2702
2913
|
destroy(it.slot());
|
|
2703
|
-
|
|
2704
|
-
common().set_empty_soo();
|
|
2705
|
-
} else {
|
|
2706
|
-
erase_meta_only(it);
|
|
2707
|
-
}
|
|
2914
|
+
erase_meta_only(it);
|
|
2708
2915
|
}
|
|
2709
2916
|
|
|
2710
2917
|
iterator erase(const_iterator first,
|
|
2711
2918
|
const_iterator last) ABSL_ATTRIBUTE_LIFETIME_BOUND {
|
|
2712
2919
|
AssertNotDebugCapacity();
|
|
2713
|
-
// We check for empty
|
|
2714
|
-
// capacity() >
|
|
2920
|
+
// We check for empty and for is_small because clear_backing_array requires
|
|
2921
|
+
// that capacity() > MaxSmallCapacity() as a precondition.
|
|
2715
2922
|
if (empty()) return end();
|
|
2716
2923
|
if (first == last) return last.inner_;
|
|
2717
|
-
if (
|
|
2718
|
-
destroy(
|
|
2719
|
-
|
|
2924
|
+
if (is_small()) {
|
|
2925
|
+
destroy(single_slot());
|
|
2926
|
+
erase_meta_only_small();
|
|
2720
2927
|
return end();
|
|
2721
2928
|
}
|
|
2722
2929
|
if (first == begin() && last == end()) {
|
|
@@ -2736,8 +2943,11 @@ class raw_hash_set {
|
|
|
2736
2943
|
|
|
2737
2944
|
// Moves elements from `src` into `this`.
|
|
2738
2945
|
// If the element already exists in `this`, it is left unmodified in `src`.
|
|
2739
|
-
template <
|
|
2740
|
-
|
|
2946
|
+
template <
|
|
2947
|
+
typename... Params2,
|
|
2948
|
+
typename = std::enable_if_t<std::is_same_v<
|
|
2949
|
+
Alloc, typename raw_hash_set<Policy, Params2...>::allocator_type>>>
|
|
2950
|
+
void merge(raw_hash_set<Policy, Params2...>& src) { // NOLINT
|
|
2741
2951
|
AssertNotDebugCapacity();
|
|
2742
2952
|
src.AssertNotDebugCapacity();
|
|
2743
2953
|
assert(this != &src);
|
|
@@ -2748,34 +2958,33 @@ class raw_hash_set {
|
|
|
2748
2958
|
.second;
|
|
2749
2959
|
};
|
|
2750
2960
|
|
|
2751
|
-
if (src.
|
|
2961
|
+
if (src.is_small()) {
|
|
2752
2962
|
if (src.empty()) return;
|
|
2753
|
-
if (insert_slot(src.
|
|
2963
|
+
if (insert_slot(src.single_slot()))
|
|
2964
|
+
src.erase_meta_only_small();
|
|
2754
2965
|
return;
|
|
2755
2966
|
}
|
|
2756
2967
|
for (auto it = src.begin(), e = src.end(); it != e;) {
|
|
2757
2968
|
auto next = std::next(it);
|
|
2758
|
-
if (insert_slot(it.slot())) src.
|
|
2969
|
+
if (insert_slot(it.slot())) src.erase_meta_only_large(it);
|
|
2759
2970
|
it = next;
|
|
2760
2971
|
}
|
|
2761
2972
|
}
|
|
2762
2973
|
|
|
2763
|
-
template <
|
|
2764
|
-
|
|
2974
|
+
template <
|
|
2975
|
+
typename... Params2,
|
|
2976
|
+
typename = std::enable_if_t<std::is_same_v<
|
|
2977
|
+
Alloc, typename raw_hash_set<Policy, Params2...>::allocator_type>>>
|
|
2978
|
+
void merge(raw_hash_set<Policy, Params2...>&& src) { // NOLINT
|
|
2765
2979
|
merge(src);
|
|
2766
2980
|
}
|
|
2767
2981
|
|
|
2768
2982
|
node_type extract(const_iterator position) {
|
|
2769
2983
|
AssertNotDebugCapacity();
|
|
2770
|
-
|
|
2771
|
-
position.inner_.generation_ptr(), "extract()");
|
|
2984
|
+
position.inner_.assert_is_full("extract()");
|
|
2772
2985
|
allocator_type alloc(char_alloc_ref());
|
|
2773
2986
|
auto node = CommonAccess::Transfer<node_type>(alloc, position.slot());
|
|
2774
|
-
|
|
2775
|
-
common().set_empty_soo();
|
|
2776
|
-
} else {
|
|
2777
|
-
erase_meta_only(position);
|
|
2778
|
-
}
|
|
2987
|
+
erase_meta_only(position);
|
|
2779
2988
|
return node;
|
|
2780
2989
|
}
|
|
2781
2990
|
|
|
@@ -2787,9 +2996,9 @@ class raw_hash_set {
|
|
|
2787
2996
|
}
|
|
2788
2997
|
|
|
2789
2998
|
void swap(raw_hash_set& that) noexcept(
|
|
2790
|
-
|
|
2791
|
-
|
|
2792
|
-
|
|
2999
|
+
AllocTraits::is_always_equal::value &&
|
|
3000
|
+
std::is_nothrow_swappable<hasher>::value &&
|
|
3001
|
+
std::is_nothrow_swappable<key_equal>::value) {
|
|
2793
3002
|
AssertNotDebugCapacity();
|
|
2794
3003
|
that.AssertNotDebugCapacity();
|
|
2795
3004
|
using std::swap;
|
|
@@ -2800,11 +3009,14 @@ class raw_hash_set {
|
|
|
2800
3009
|
typename AllocTraits::propagate_on_container_swap{});
|
|
2801
3010
|
}
|
|
2802
3011
|
|
|
2803
|
-
void rehash(size_t n) {
|
|
3012
|
+
void rehash(size_t n) {
|
|
3013
|
+
Rehash(common(), GetPolicyFunctions(), (std::min)(n, MaxValidCapacity()));
|
|
3014
|
+
}
|
|
2804
3015
|
|
|
2805
3016
|
void reserve(size_t n) {
|
|
2806
3017
|
if (ABSL_PREDICT_TRUE(n > DefaultCapacity())) {
|
|
2807
|
-
ReserveTableToFitNewSize(common(), GetPolicyFunctions(),
|
|
3018
|
+
ReserveTableToFitNewSize(common(), GetPolicyFunctions(),
|
|
3019
|
+
(std::min)(n, MaxValidSize()));
|
|
2808
3020
|
}
|
|
2809
3021
|
}
|
|
2810
3022
|
|
|
@@ -2828,12 +3040,12 @@ class raw_hash_set {
|
|
|
2828
3040
|
// NOTE: This is a very low level operation and should not be used without
|
|
2829
3041
|
// specific benchmarks indicating its importance.
|
|
2830
3042
|
template <class K = key_type>
|
|
2831
|
-
void prefetch(const key_arg<K>& key) const {
|
|
3043
|
+
void prefetch([[maybe_unused]] const key_arg<K>& key) const {
|
|
2832
3044
|
if (capacity() == DefaultCapacity()) return;
|
|
2833
|
-
(void)key;
|
|
2834
3045
|
// Avoid probing if we won't be able to prefetch the addresses received.
|
|
2835
3046
|
#ifdef ABSL_HAVE_PREFETCH
|
|
2836
3047
|
prefetch_heap_block();
|
|
3048
|
+
if (is_small()) return;
|
|
2837
3049
|
auto seq = probe(common(), hash_of(key));
|
|
2838
3050
|
PrefetchToLocalCache(control() + seq.offset());
|
|
2839
3051
|
PrefetchToLocalCache(slot_array() + seq.offset());
|
|
@@ -2851,7 +3063,7 @@ class raw_hash_set {
|
|
|
2851
3063
|
template <class K = key_type>
|
|
2852
3064
|
iterator find(const key_arg<K>& key) ABSL_ATTRIBUTE_LIFETIME_BOUND {
|
|
2853
3065
|
AssertOnFind(key);
|
|
2854
|
-
if (
|
|
3066
|
+
if (is_small()) return find_small(key);
|
|
2855
3067
|
prefetch_heap_block();
|
|
2856
3068
|
return find_large(key, hash_of(key));
|
|
2857
3069
|
}
|
|
@@ -2960,24 +3172,6 @@ class raw_hash_set {
|
|
|
2960
3172
|
const raw_hash_set& s;
|
|
2961
3173
|
};
|
|
2962
3174
|
|
|
2963
|
-
struct HashElement {
|
|
2964
|
-
template <class K, class... Args>
|
|
2965
|
-
size_t operator()(const K& key, Args&&...) const {
|
|
2966
|
-
return h(key);
|
|
2967
|
-
}
|
|
2968
|
-
const hasher& h;
|
|
2969
|
-
};
|
|
2970
|
-
|
|
2971
|
-
template <class K1>
|
|
2972
|
-
struct EqualElement {
|
|
2973
|
-
template <class K2, class... Args>
|
|
2974
|
-
bool operator()(const K2& lhs, Args&&...) const {
|
|
2975
|
-
ABSL_SWISSTABLE_IGNORE_UNINITIALIZED_RETURN(eq(lhs, rhs));
|
|
2976
|
-
}
|
|
2977
|
-
const K1& rhs;
|
|
2978
|
-
const key_equal& eq;
|
|
2979
|
-
};
|
|
2980
|
-
|
|
2981
3175
|
struct EmplaceDecomposable {
|
|
2982
3176
|
template <class K, class... Args>
|
|
2983
3177
|
std::pair<iterator, bool> operator()(const K& key, Args&&... args) const {
|
|
@@ -3031,18 +3225,13 @@ class raw_hash_set {
|
|
|
3031
3225
|
// SOO functionality.
|
|
3032
3226
|
template <class K = key_type>
|
|
3033
3227
|
iterator find_small(const key_arg<K>& key) {
|
|
3034
|
-
ABSL_SWISSTABLE_ASSERT(
|
|
3035
|
-
return empty() || !
|
|
3036
|
-
EqualElement<K>{key, eq_ref()},
|
|
3037
|
-
PolicyTraits::element(single_slot()))
|
|
3038
|
-
? end()
|
|
3039
|
-
: single_iterator();
|
|
3228
|
+
ABSL_SWISSTABLE_ASSERT(is_small());
|
|
3229
|
+
return empty() || !equal_to(key, single_slot()) ? end() : single_iterator();
|
|
3040
3230
|
}
|
|
3041
3231
|
|
|
3042
3232
|
template <class K = key_type>
|
|
3043
3233
|
iterator find_large(const key_arg<K>& key, size_t hash) {
|
|
3044
|
-
ABSL_SWISSTABLE_ASSERT(
|
|
3045
|
-
ABSL_SWISSTABLE_ASSERT(!is_soo());
|
|
3234
|
+
ABSL_SWISSTABLE_ASSERT(!is_small());
|
|
3046
3235
|
auto seq = probe(common(), hash);
|
|
3047
3236
|
const h2_t h2 = H2(hash);
|
|
3048
3237
|
const ctrl_t* ctrl = control();
|
|
@@ -3052,9 +3241,7 @@ class raw_hash_set {
|
|
|
3052
3241
|
#endif
|
|
3053
3242
|
Group g{ctrl + seq.offset()};
|
|
3054
3243
|
for (uint32_t i : g.Match(h2)) {
|
|
3055
|
-
if (ABSL_PREDICT_TRUE(
|
|
3056
|
-
EqualElement<K>{key, eq_ref()},
|
|
3057
|
-
PolicyTraits::element(slot_array() + seq.offset(i)))))
|
|
3244
|
+
if (ABSL_PREDICT_TRUE(equal_to(key, slot_array() + seq.offset(i))))
|
|
3058
3245
|
return iterator_at(seq.offset(i));
|
|
3059
3246
|
}
|
|
3060
3247
|
if (ABSL_PREDICT_TRUE(g.MaskEmpty())) return end();
|
|
@@ -3063,30 +3250,42 @@ class raw_hash_set {
|
|
|
3063
3250
|
}
|
|
3064
3251
|
}
|
|
3065
3252
|
|
|
3066
|
-
// Returns true if the table needs to be sampled.
|
|
3253
|
+
// Returns true if the table needs to be sampled. This keeps track of whether
|
|
3254
|
+
// sampling has already been evaluated and ensures that it can only return
|
|
3255
|
+
// true on its first evaluation. All subsequent calls will return false.
|
|
3256
|
+
//
|
|
3067
3257
|
// This should be called on insertion into an empty SOO table and in copy
|
|
3068
3258
|
// construction when the size can fit in SOO capacity.
|
|
3069
|
-
bool should_sample_soo()
|
|
3259
|
+
bool should_sample_soo() {
|
|
3070
3260
|
ABSL_SWISSTABLE_ASSERT(is_soo());
|
|
3071
|
-
if (!ShouldSampleHashtablezInfoForAlloc<CharAlloc>())
|
|
3261
|
+
if constexpr (!ShouldSampleHashtablezInfoForAlloc<CharAlloc>()) {
|
|
3262
|
+
return false;
|
|
3263
|
+
}
|
|
3264
|
+
if (common().soo_has_tried_sampling()) {
|
|
3265
|
+
// Already evaluated sampling on this SOO table; do not re-evaluate
|
|
3266
|
+
// sampling each time it transitions from empty to full SOO state.
|
|
3267
|
+
return false;
|
|
3268
|
+
}
|
|
3269
|
+
// TODO: b/396049910 -- consider managing this flag on the 1->0 size
|
|
3270
|
+
// transition of SOO tables rather than the 0->1 transition.
|
|
3271
|
+
common().set_soo_has_tried_sampling();
|
|
3072
3272
|
return ABSL_PREDICT_FALSE(ShouldSampleNextTable());
|
|
3073
3273
|
}
|
|
3074
3274
|
|
|
3075
3275
|
void clear_backing_array(bool reuse) {
|
|
3076
|
-
ABSL_SWISSTABLE_ASSERT(capacity() >
|
|
3077
|
-
ClearBackingArray(common(), GetPolicyFunctions(), &char_alloc_ref(), reuse
|
|
3078
|
-
SooEnabled());
|
|
3276
|
+
ABSL_SWISSTABLE_ASSERT(capacity() > MaxSmallCapacity());
|
|
3277
|
+
ClearBackingArray(common(), GetPolicyFunctions(), &char_alloc_ref(), reuse);
|
|
3079
3278
|
}
|
|
3080
3279
|
|
|
3081
3280
|
void destroy_slots() {
|
|
3082
|
-
ABSL_SWISSTABLE_ASSERT(!
|
|
3281
|
+
ABSL_SWISSTABLE_ASSERT(!is_small());
|
|
3083
3282
|
if (PolicyTraits::template destroy_is_trivial<Alloc>()) return;
|
|
3084
3283
|
auto destroy_slot = [&](const ctrl_t*, void* slot) {
|
|
3085
3284
|
this->destroy(static_cast<slot_type*>(slot));
|
|
3086
3285
|
};
|
|
3087
3286
|
if constexpr (SwisstableAssertAccessToDestroyedTable()) {
|
|
3088
3287
|
CommonFields common_copy(non_soo_tag_t{}, this->common());
|
|
3089
|
-
common().set_capacity(
|
|
3288
|
+
common().set_capacity(HashtableCapacity::CreateDestroyed());
|
|
3090
3289
|
IterateOverFullSlots(common_copy, sizeof(slot_type), destroy_slot);
|
|
3091
3290
|
common().set_capacity(common_copy.capacity());
|
|
3092
3291
|
} else {
|
|
@@ -3107,17 +3306,18 @@ class raw_hash_set {
|
|
|
3107
3306
|
|
|
3108
3307
|
void destructor_impl() {
|
|
3109
3308
|
if (SwisstableGenerationsEnabled() &&
|
|
3110
|
-
|
|
3309
|
+
maybe_invalid_capacity().IsMovedFrom()) {
|
|
3111
3310
|
return;
|
|
3112
3311
|
}
|
|
3113
3312
|
if (capacity() == 0) return;
|
|
3114
|
-
if (
|
|
3313
|
+
if (is_small()) {
|
|
3115
3314
|
if (!empty()) {
|
|
3116
|
-
ABSL_SWISSTABLE_IGNORE_UNINITIALIZED(destroy(
|
|
3315
|
+
ABSL_SWISSTABLE_IGNORE_UNINITIALIZED(destroy(single_slot()));
|
|
3117
3316
|
}
|
|
3118
|
-
return;
|
|
3317
|
+
if constexpr (SooEnabled()) return;
|
|
3318
|
+
} else {
|
|
3319
|
+
destroy_slots();
|
|
3119
3320
|
}
|
|
3120
|
-
destroy_slots();
|
|
3121
3321
|
dealloc();
|
|
3122
3322
|
}
|
|
3123
3323
|
|
|
@@ -3126,23 +3326,41 @@ class raw_hash_set {
|
|
|
3126
3326
|
// This merely updates the pertinent control byte. This can be used in
|
|
3127
3327
|
// conjunction with Policy::transfer to move the object to another place.
|
|
3128
3328
|
void erase_meta_only(const_iterator it) {
|
|
3129
|
-
|
|
3130
|
-
|
|
3131
|
-
|
|
3329
|
+
if (is_small()) {
|
|
3330
|
+
erase_meta_only_small();
|
|
3331
|
+
return;
|
|
3332
|
+
}
|
|
3333
|
+
erase_meta_only_large(it);
|
|
3334
|
+
}
|
|
3335
|
+
void erase_meta_only_small() {
|
|
3336
|
+
EraseMetaOnlySmall(common(), SooEnabled(), sizeof(slot_type));
|
|
3337
|
+
}
|
|
3338
|
+
void erase_meta_only_large(const_iterator it) {
|
|
3339
|
+
EraseMetaOnlyLarge(common(), it.control(), sizeof(slot_type));
|
|
3132
3340
|
}
|
|
3133
3341
|
|
|
3134
3342
|
template <class K>
|
|
3135
|
-
|
|
3136
|
-
|
|
3137
|
-
|
|
3138
|
-
size_t hash_of(slot_type* slot) const {
|
|
3139
|
-
return PolicyTraits::apply(HashElement{hash_ref()},
|
|
3343
|
+
ABSL_ATTRIBUTE_ALWAYS_INLINE bool equal_to(const K& key,
|
|
3344
|
+
slot_type* slot) const {
|
|
3345
|
+
return PolicyTraits::apply(EqualElement<K, key_equal>{key, eq_ref()},
|
|
3140
3346
|
PolicyTraits::element(slot));
|
|
3141
3347
|
}
|
|
3348
|
+
template <class K>
|
|
3349
|
+
ABSL_ATTRIBUTE_ALWAYS_INLINE size_t hash_of(const K& key) const {
|
|
3350
|
+
return HashElement<hasher, kIsDefaultHash>{hash_ref(),
|
|
3351
|
+
common().seed().seed()}(key);
|
|
3352
|
+
}
|
|
3353
|
+
ABSL_ATTRIBUTE_ALWAYS_INLINE size_t hash_of(slot_type* slot) const {
|
|
3354
|
+
return PolicyTraits::apply(
|
|
3355
|
+
HashElement<hasher, kIsDefaultHash>{hash_ref(), common().seed().seed()},
|
|
3356
|
+
PolicyTraits::element(slot));
|
|
3357
|
+
}
|
|
3142
3358
|
|
|
3143
3359
|
// Casting directly from e.g. char* to slot_type* can cause compilation errors
|
|
3144
3360
|
// on objective-C. This function converts to void* first, avoiding the issue.
|
|
3145
|
-
static slot_type* to_slot(void* buf) {
|
|
3361
|
+
static ABSL_ATTRIBUTE_ALWAYS_INLINE slot_type* to_slot(void* buf) {
|
|
3362
|
+
return static_cast<slot_type*>(buf);
|
|
3363
|
+
}
|
|
3146
3364
|
|
|
3147
3365
|
// Requires that lhs does not have a full SOO slot.
|
|
3148
3366
|
static void move_common(bool rhs_is_full_soo, CharAlloc& rhs_alloc,
|
|
@@ -3178,17 +3396,18 @@ class raw_hash_set {
|
|
|
3178
3396
|
std::move(tmp));
|
|
3179
3397
|
}
|
|
3180
3398
|
|
|
3181
|
-
void annotate_for_bug_detection_on_move(
|
|
3182
|
-
ABSL_ATTRIBUTE_UNUSED raw_hash_set& that) {
|
|
3399
|
+
void annotate_for_bug_detection_on_move([[maybe_unused]] raw_hash_set& that) {
|
|
3183
3400
|
// We only enable moved-from validation when generations are enabled (rather
|
|
3184
3401
|
// than using NDEBUG) to avoid issues in which NDEBUG is enabled in some
|
|
3185
3402
|
// translation units but not in others.
|
|
3186
3403
|
if (SwisstableGenerationsEnabled()) {
|
|
3187
|
-
that.common().set_capacity(this == &that
|
|
3188
|
-
|
|
3404
|
+
that.common().set_capacity(this == &that
|
|
3405
|
+
? HashtableCapacity::CreateSelfMovedFrom()
|
|
3406
|
+
: HashtableCapacity::CreateMovedFrom());
|
|
3189
3407
|
}
|
|
3190
|
-
if (!SwisstableGenerationsEnabled() ||
|
|
3191
|
-
|
|
3408
|
+
if (!SwisstableGenerationsEnabled() ||
|
|
3409
|
+
!maybe_invalid_capacity().IsValid() ||
|
|
3410
|
+
capacity() == DefaultCapacity()) {
|
|
3192
3411
|
return;
|
|
3193
3412
|
}
|
|
3194
3413
|
common().increment_generation();
|
|
@@ -3250,64 +3469,102 @@ class raw_hash_set {
|
|
|
3250
3469
|
|
|
3251
3470
|
template <class K>
|
|
3252
3471
|
std::pair<iterator, bool> find_or_prepare_insert_soo(const K& key) {
|
|
3253
|
-
|
|
3472
|
+
ABSL_SWISSTABLE_ASSERT(is_soo());
|
|
3473
|
+
bool force_sampling;
|
|
3254
3474
|
if (empty()) {
|
|
3255
3475
|
if (!should_sample_soo()) {
|
|
3256
3476
|
common().set_full_soo();
|
|
3257
|
-
return {
|
|
3477
|
+
return {single_iterator(), true};
|
|
3258
3478
|
}
|
|
3259
|
-
|
|
3260
|
-
} else if (
|
|
3261
|
-
|
|
3262
|
-
return {soo_iterator(), false};
|
|
3479
|
+
force_sampling = true;
|
|
3480
|
+
} else if (equal_to(key, single_slot())) {
|
|
3481
|
+
return {single_iterator(), false};
|
|
3263
3482
|
} else {
|
|
3264
|
-
|
|
3483
|
+
force_sampling = false;
|
|
3265
3484
|
}
|
|
3485
|
+
ABSL_SWISSTABLE_ASSERT(capacity() == 1);
|
|
3266
3486
|
constexpr bool kUseMemcpy =
|
|
3267
3487
|
PolicyTraits::transfer_uses_memcpy() && SooEnabled();
|
|
3268
3488
|
size_t index = GrowSooTableToNextCapacityAndPrepareInsert<
|
|
3269
3489
|
kUseMemcpy ? OptimalMemcpySizeForSooSlotTransfer(sizeof(slot_type)) : 0,
|
|
3270
|
-
kUseMemcpy>(common(), GetPolicyFunctions(),
|
|
3271
|
-
|
|
3490
|
+
kUseMemcpy>(common(), GetPolicyFunctions(),
|
|
3491
|
+
HashKey<hasher, K, kIsDefaultHash>{hash_ref(), key},
|
|
3492
|
+
force_sampling);
|
|
3272
3493
|
return {iterator_at(index), true};
|
|
3273
3494
|
}
|
|
3274
3495
|
|
|
3275
3496
|
template <class K>
|
|
3276
|
-
std::pair<iterator, bool>
|
|
3497
|
+
std::pair<iterator, bool> find_or_prepare_insert_small(const K& key) {
|
|
3498
|
+
ABSL_SWISSTABLE_ASSERT(is_small());
|
|
3499
|
+
if constexpr (SooEnabled()) {
|
|
3500
|
+
return find_or_prepare_insert_soo(key);
|
|
3501
|
+
}
|
|
3502
|
+
if (!empty()) {
|
|
3503
|
+
if (equal_to(key, single_slot())) {
|
|
3504
|
+
return {single_iterator(), false};
|
|
3505
|
+
}
|
|
3506
|
+
}
|
|
3507
|
+
return {iterator_at_ptr(PrepareInsertSmallNonSoo(
|
|
3508
|
+
common(), GetPolicyFunctions(),
|
|
3509
|
+
HashKey<hasher, K, kIsDefaultHash>{hash_ref(), key})),
|
|
3510
|
+
true};
|
|
3511
|
+
}
|
|
3512
|
+
|
|
3513
|
+
template <class K>
|
|
3514
|
+
std::pair<iterator, bool> find_or_prepare_insert_large(const K& key) {
|
|
3277
3515
|
ABSL_SWISSTABLE_ASSERT(!is_soo());
|
|
3278
3516
|
prefetch_heap_block();
|
|
3279
3517
|
const size_t hash = hash_of(key);
|
|
3280
3518
|
auto seq = probe(common(), hash);
|
|
3281
3519
|
const h2_t h2 = H2(hash);
|
|
3282
3520
|
const ctrl_t* ctrl = control();
|
|
3283
|
-
|
|
3521
|
+
size_t index;
|
|
3522
|
+
bool inserted;
|
|
3523
|
+
// We use a lambda function to be able to exit from the nested loop without
|
|
3524
|
+
// duplicating generated code for the return statement (e.g. iterator_at).
|
|
3525
|
+
[&]() ABSL_ATTRIBUTE_ALWAYS_INLINE {
|
|
3526
|
+
while (true) {
|
|
3284
3527
|
#ifndef ABSL_HAVE_MEMORY_SANITIZER
|
|
3285
|
-
|
|
3528
|
+
absl::PrefetchToLocalCache(slot_array() + seq.offset());
|
|
3286
3529
|
#endif
|
|
3287
|
-
|
|
3288
|
-
|
|
3289
|
-
|
|
3290
|
-
|
|
3291
|
-
|
|
3292
|
-
|
|
3293
|
-
|
|
3294
|
-
|
|
3295
|
-
|
|
3296
|
-
|
|
3297
|
-
|
|
3298
|
-
|
|
3299
|
-
|
|
3300
|
-
|
|
3530
|
+
Group g{ctrl + seq.offset()};
|
|
3531
|
+
for (uint32_t i : g.Match(h2)) {
|
|
3532
|
+
if (ABSL_PREDICT_TRUE(equal_to(key, slot_array() + seq.offset(i)))) {
|
|
3533
|
+
index = seq.offset(i);
|
|
3534
|
+
inserted = false;
|
|
3535
|
+
return;
|
|
3536
|
+
}
|
|
3537
|
+
}
|
|
3538
|
+
auto mask_empty = g.MaskEmpty();
|
|
3539
|
+
if (ABSL_PREDICT_TRUE(mask_empty)) {
|
|
3540
|
+
size_t target_group_offset = seq.offset();
|
|
3541
|
+
index = SwisstableGenerationsEnabled()
|
|
3542
|
+
? PrepareInsertLargeGenerationsEnabled(
|
|
3543
|
+
common(), GetPolicyFunctions(), hash, mask_empty,
|
|
3544
|
+
FindInfo{target_group_offset, seq.index()},
|
|
3545
|
+
HashKey<hasher, K, kIsDefaultHash>{hash_ref(), key})
|
|
3546
|
+
: PrepareInsertLarge(
|
|
3547
|
+
common(), GetPolicyFunctions(), hash, mask_empty,
|
|
3548
|
+
FindInfo{target_group_offset, seq.index()});
|
|
3549
|
+
inserted = true;
|
|
3550
|
+
return;
|
|
3551
|
+
}
|
|
3552
|
+
seq.next();
|
|
3553
|
+
ABSL_SWISSTABLE_ASSERT(seq.index() <= capacity() && "full table!");
|
|
3301
3554
|
}
|
|
3302
|
-
|
|
3303
|
-
|
|
3304
|
-
|
|
3555
|
+
}();
|
|
3556
|
+
return {iterator_at(index), inserted};
|
|
3557
|
+
}
|
|
3558
|
+
|
|
3559
|
+
template <class InputIt>
|
|
3560
|
+
void insert_range(InputIt first, InputIt last) {
|
|
3561
|
+
for (; first != last; ++first) emplace(*first);
|
|
3305
3562
|
}
|
|
3306
3563
|
|
|
3307
3564
|
protected:
|
|
3308
3565
|
// Asserts for correctness that we run on find/find_or_prepare_insert.
|
|
3309
3566
|
template <class K>
|
|
3310
|
-
void AssertOnFind(
|
|
3567
|
+
void AssertOnFind([[maybe_unused]] const K& key) {
|
|
3311
3568
|
AssertHashEqConsistent(key);
|
|
3312
3569
|
AssertNotDebugCapacity();
|
|
3313
3570
|
}
|
|
@@ -3319,21 +3576,21 @@ class raw_hash_set {
|
|
|
3319
3576
|
return;
|
|
3320
3577
|
}
|
|
3321
3578
|
#endif
|
|
3322
|
-
|
|
3323
|
-
|
|
3579
|
+
const HashtableCapacity cap = maybe_invalid_capacity();
|
|
3580
|
+
if (ABSL_PREDICT_TRUE(cap.IsValid())) {
|
|
3324
3581
|
return;
|
|
3325
3582
|
}
|
|
3326
|
-
assert(
|
|
3583
|
+
assert(!cap.IsReentrance() &&
|
|
3327
3584
|
"Reentrant container access during element construction/destruction "
|
|
3328
3585
|
"is not allowed.");
|
|
3329
3586
|
if constexpr (SwisstableAssertAccessToDestroyedTable()) {
|
|
3330
|
-
if (
|
|
3587
|
+
if (cap.IsDestroyed()) {
|
|
3331
3588
|
ABSL_RAW_LOG(FATAL, "Use of destroyed hash table.");
|
|
3332
3589
|
}
|
|
3333
3590
|
}
|
|
3334
3591
|
if (SwisstableGenerationsEnabled() &&
|
|
3335
|
-
ABSL_PREDICT_FALSE(
|
|
3336
|
-
if (
|
|
3592
|
+
ABSL_PREDICT_FALSE(cap.IsMovedFrom())) {
|
|
3593
|
+
if (cap.IsSelfMovedFrom()) {
|
|
3337
3594
|
// If this log triggers, then a hash table was move-assigned to itself
|
|
3338
3595
|
// and then used again later without being reinitialized.
|
|
3339
3596
|
ABSL_RAW_LOG(FATAL, "Use of self-move-assigned hash table.");
|
|
@@ -3363,23 +3620,18 @@ class raw_hash_set {
|
|
|
3363
3620
|
|
|
3364
3621
|
const size_t hash_of_arg = hash_of(key);
|
|
3365
3622
|
const auto assert_consistent = [&](const ctrl_t*, void* slot) {
|
|
3366
|
-
const
|
|
3367
|
-
PolicyTraits::element(static_cast<slot_type*>(slot));
|
|
3368
|
-
const bool is_key_equal =
|
|
3369
|
-
PolicyTraits::apply(EqualElement<K>{key, eq_ref()}, element);
|
|
3623
|
+
const bool is_key_equal = equal_to(key, to_slot(slot));
|
|
3370
3624
|
if (!is_key_equal) return;
|
|
3371
3625
|
|
|
3372
|
-
const
|
|
3373
|
-
|
|
3374
|
-
ABSL_ATTRIBUTE_UNUSED const bool is_hash_equal =
|
|
3375
|
-
hash_of_arg == hash_of_slot;
|
|
3626
|
+
[[maybe_unused]] const bool is_hash_equal =
|
|
3627
|
+
hash_of_arg == hash_of(to_slot(slot));
|
|
3376
3628
|
assert((!is_key_equal || is_hash_equal) &&
|
|
3377
3629
|
"eq(k1, k2) must imply that hash(k1) == hash(k2). "
|
|
3378
3630
|
"hash/eq functors are inconsistent.");
|
|
3379
3631
|
};
|
|
3380
3632
|
|
|
3381
|
-
if (
|
|
3382
|
-
assert_consistent(/*unused*/ nullptr,
|
|
3633
|
+
if (is_small()) {
|
|
3634
|
+
assert_consistent(/*unused*/ nullptr, single_slot());
|
|
3383
3635
|
return;
|
|
3384
3636
|
}
|
|
3385
3637
|
// We only do validation for small tables so that it's constant time.
|
|
@@ -3393,8 +3645,8 @@ class raw_hash_set {
|
|
|
3393
3645
|
template <class K>
|
|
3394
3646
|
std::pair<iterator, bool> find_or_prepare_insert(const K& key) {
|
|
3395
3647
|
AssertOnFind(key);
|
|
3396
|
-
if (
|
|
3397
|
-
return
|
|
3648
|
+
if (is_small()) return find_or_prepare_insert_small(key);
|
|
3649
|
+
return find_or_prepare_insert_large(key);
|
|
3398
3650
|
}
|
|
3399
3651
|
|
|
3400
3652
|
// Constructs the value in the space pointed by the iterator. This only works
|
|
@@ -3409,9 +3661,9 @@ class raw_hash_set {
|
|
|
3409
3661
|
void emplace_at(iterator iter, Args&&... args) {
|
|
3410
3662
|
construct(iter.slot(), std::forward<Args>(args)...);
|
|
3411
3663
|
|
|
3412
|
-
// When
|
|
3664
|
+
// When is_small, find calls find_small and if size is 0, then it will
|
|
3413
3665
|
// return an end iterator. This can happen in the raw_hash_set copy ctor.
|
|
3414
|
-
assert((
|
|
3666
|
+
assert((is_small() ||
|
|
3415
3667
|
PolicyTraits::apply(FindElement{*this}, *iter) == iter) &&
|
|
3416
3668
|
"constructed value does not match the lookup key");
|
|
3417
3669
|
}
|
|
@@ -3422,6 +3674,10 @@ class raw_hash_set {
|
|
|
3422
3674
|
const_iterator iterator_at(size_t i) const ABSL_ATTRIBUTE_LIFETIME_BOUND {
|
|
3423
3675
|
return const_cast<raw_hash_set*>(this)->iterator_at(i);
|
|
3424
3676
|
}
|
|
3677
|
+
iterator iterator_at_ptr(std::pair<ctrl_t*, void*> ptrs)
|
|
3678
|
+
ABSL_ATTRIBUTE_LIFETIME_BOUND {
|
|
3679
|
+
return {ptrs.first, to_slot(ptrs.second), common().generation_ptr()};
|
|
3680
|
+
}
|
|
3425
3681
|
|
|
3426
3682
|
reference unchecked_deref(iterator it) { return it.unchecked_deref(); }
|
|
3427
3683
|
|
|
@@ -3439,16 +3695,13 @@ class raw_hash_set {
|
|
|
3439
3695
|
//
|
|
3440
3696
|
// See `CapacityToGrowth()`.
|
|
3441
3697
|
size_t growth_left() const {
|
|
3442
|
-
ABSL_SWISSTABLE_ASSERT(!is_soo());
|
|
3443
3698
|
return common().growth_left();
|
|
3444
3699
|
}
|
|
3445
3700
|
|
|
3446
3701
|
GrowthInfo& growth_info() {
|
|
3447
|
-
ABSL_SWISSTABLE_ASSERT(!is_soo());
|
|
3448
3702
|
return common().growth_info();
|
|
3449
3703
|
}
|
|
3450
3704
|
GrowthInfo growth_info() const {
|
|
3451
|
-
ABSL_SWISSTABLE_ASSERT(!is_soo());
|
|
3452
3705
|
return common().growth_info();
|
|
3453
3706
|
}
|
|
3454
3707
|
|
|
@@ -3465,6 +3718,11 @@ class raw_hash_set {
|
|
|
3465
3718
|
CommonFields& common() { return settings_.template get<0>(); }
|
|
3466
3719
|
const CommonFields& common() const { return settings_.template get<0>(); }
|
|
3467
3720
|
|
|
3721
|
+
// For use when the capacity is potentially invalid we return
|
|
3722
|
+
// HashtableCapacity directly.
|
|
3723
|
+
HashtableCapacity maybe_invalid_capacity() const {
|
|
3724
|
+
return common().maybe_invalid_capacity();
|
|
3725
|
+
}
|
|
3468
3726
|
ctrl_t* control() const {
|
|
3469
3727
|
ABSL_SWISSTABLE_ASSERT(!is_soo());
|
|
3470
3728
|
return common().control();
|
|
@@ -3482,22 +3740,22 @@ class raw_hash_set {
|
|
|
3482
3740
|
ABSL_SWISSTABLE_IGNORE_UNINITIALIZED_RETURN(
|
|
3483
3741
|
const_cast<raw_hash_set*>(this)->soo_slot());
|
|
3484
3742
|
}
|
|
3485
|
-
iterator soo_iterator() {
|
|
3486
|
-
return {SooControl(), soo_slot(), common().generation_ptr()};
|
|
3487
|
-
}
|
|
3488
|
-
const_iterator soo_iterator() const {
|
|
3489
|
-
return const_cast<raw_hash_set*>(this)->soo_iterator();
|
|
3490
|
-
}
|
|
3491
3743
|
slot_type* single_slot() {
|
|
3492
|
-
ABSL_SWISSTABLE_ASSERT(
|
|
3744
|
+
ABSL_SWISSTABLE_ASSERT(is_small());
|
|
3493
3745
|
return SooEnabled() ? soo_slot() : slot_array();
|
|
3494
3746
|
}
|
|
3495
3747
|
const slot_type* single_slot() const {
|
|
3496
3748
|
return const_cast<raw_hash_set*>(this)->single_slot();
|
|
3497
3749
|
}
|
|
3750
|
+
void decrement_small_size() {
|
|
3751
|
+
ABSL_SWISSTABLE_ASSERT(is_small());
|
|
3752
|
+
SooEnabled() ? common().set_empty_soo() : common().decrement_size();
|
|
3753
|
+
if (!SooEnabled()) {
|
|
3754
|
+
SanitizerPoisonObject(single_slot());
|
|
3755
|
+
}
|
|
3756
|
+
}
|
|
3498
3757
|
iterator single_iterator() {
|
|
3499
|
-
return {
|
|
3500
|
-
common().generation_ptr()};
|
|
3758
|
+
return {SooControl(), single_slot(), common().generation_ptr()};
|
|
3501
3759
|
}
|
|
3502
3760
|
const_iterator single_iterator() const {
|
|
3503
3761
|
return const_cast<raw_hash_set*>(this)->single_iterator();
|
|
@@ -3554,8 +3812,6 @@ class raw_hash_set {
|
|
|
3554
3812
|
ctrl_t* new_ctrl = common.control();
|
|
3555
3813
|
slot_type* new_slots = set->slot_array();
|
|
3556
3814
|
|
|
3557
|
-
const PerTableSeed seed = common.seed();
|
|
3558
|
-
|
|
3559
3815
|
for (size_t group_index = 0; group_index < old_capacity;
|
|
3560
3816
|
group_index += Group::kWidth) {
|
|
3561
3817
|
GroupFullEmptyOrDeleted old_g(old_ctrl + group_index);
|
|
@@ -3571,7 +3827,7 @@ class raw_hash_set {
|
|
|
3571
3827
|
// TODO(b/382423690): try to avoid entire hash calculation since we need
|
|
3572
3828
|
// only one new bit of h1.
|
|
3573
3829
|
size_t hash = set->hash_of(old_slot);
|
|
3574
|
-
size_t h1 = H1(hash
|
|
3830
|
+
size_t h1 = H1(hash);
|
|
3575
3831
|
h2_t h2 = H2(hash);
|
|
3576
3832
|
size_t new_index = TryFindNewIndexWithoutProbing(
|
|
3577
3833
|
h1, old_index, old_capacity, new_ctrl, new_capacity);
|
|
@@ -3614,7 +3870,7 @@ class raw_hash_set {
|
|
|
3614
3870
|
// for standard layout and alignof(Hash) <= alignof(CommonFields).
|
|
3615
3871
|
std::is_empty_v<hasher> ? &GetRefForEmptyClass
|
|
3616
3872
|
: &raw_hash_set::get_hash_ref_fn,
|
|
3617
|
-
PolicyTraits::template get_hash_slot_fn<hasher>(),
|
|
3873
|
+
PolicyTraits::template get_hash_slot_fn<hasher, kIsDefaultHash>(),
|
|
3618
3874
|
PolicyTraits::transfer_uses_memcpy()
|
|
3619
3875
|
? TransferNRelocatable<sizeof(slot_type)>
|
|
3620
3876
|
: &raw_hash_set::transfer_n_slots_fn,
|
|
@@ -3642,18 +3898,18 @@ struct HashtableFreeFunctionsAccess {
|
|
|
3642
3898
|
if (c->empty()) {
|
|
3643
3899
|
return 0;
|
|
3644
3900
|
}
|
|
3645
|
-
if (c->
|
|
3646
|
-
auto it = c->
|
|
3901
|
+
if (c->is_small()) {
|
|
3902
|
+
auto it = c->single_iterator();
|
|
3647
3903
|
if (!pred(*it)) {
|
|
3648
3904
|
ABSL_SWISSTABLE_ASSERT(c->size() == 1 &&
|
|
3649
3905
|
"hash table was modified unexpectedly");
|
|
3650
3906
|
return 0;
|
|
3651
3907
|
}
|
|
3652
3908
|
c->destroy(it.slot());
|
|
3653
|
-
c->
|
|
3909
|
+
c->erase_meta_only_small();
|
|
3654
3910
|
return 1;
|
|
3655
3911
|
}
|
|
3656
|
-
|
|
3912
|
+
[[maybe_unused]] const size_t original_size_for_assert = c->size();
|
|
3657
3913
|
size_t num_deleted = 0;
|
|
3658
3914
|
using SlotType = typename Set::slot_type;
|
|
3659
3915
|
IterateOverFullSlots(
|
|
@@ -3662,8 +3918,7 @@ struct HashtableFreeFunctionsAccess {
|
|
|
3662
3918
|
auto* slot = static_cast<SlotType*>(slot_void);
|
|
3663
3919
|
if (pred(Set::PolicyTraits::element(slot))) {
|
|
3664
3920
|
c->destroy(slot);
|
|
3665
|
-
|
|
3666
|
-
sizeof(*slot));
|
|
3921
|
+
EraseMetaOnlyLarge(c->common(), ctrl, sizeof(*slot));
|
|
3667
3922
|
++num_deleted;
|
|
3668
3923
|
}
|
|
3669
3924
|
});
|
|
@@ -3680,8 +3935,8 @@ struct HashtableFreeFunctionsAccess {
|
|
|
3680
3935
|
if (c->empty()) {
|
|
3681
3936
|
return;
|
|
3682
3937
|
}
|
|
3683
|
-
if (c->
|
|
3684
|
-
cb(*c->
|
|
3938
|
+
if (c->is_small()) {
|
|
3939
|
+
cb(*c->single_iterator());
|
|
3685
3940
|
return;
|
|
3686
3941
|
}
|
|
3687
3942
|
using SlotType = typename Set::slot_type;
|
|
@@ -3696,31 +3951,33 @@ struct HashtableFreeFunctionsAccess {
|
|
|
3696
3951
|
};
|
|
3697
3952
|
|
|
3698
3953
|
// Erases all elements that satisfy the predicate `pred` from the container `c`.
|
|
3699
|
-
template <typename P, typename
|
|
3700
|
-
typename raw_hash_set<P,
|
|
3701
|
-
Predicate& pred, raw_hash_set<P,
|
|
3954
|
+
template <typename P, typename... Params, typename Predicate>
|
|
3955
|
+
typename raw_hash_set<P, Params...>::size_type EraseIf(
|
|
3956
|
+
Predicate& pred, raw_hash_set<P, Params...>* c) {
|
|
3702
3957
|
return HashtableFreeFunctionsAccess::EraseIf(pred, c);
|
|
3703
3958
|
}
|
|
3704
3959
|
|
|
3705
3960
|
// Calls `cb` for all elements in the container `c`.
|
|
3706
|
-
template <typename P, typename
|
|
3707
|
-
void ForEach(Callback& cb, raw_hash_set<P,
|
|
3961
|
+
template <typename P, typename... Params, typename Callback>
|
|
3962
|
+
void ForEach(Callback& cb, raw_hash_set<P, Params...>* c) {
|
|
3708
3963
|
return HashtableFreeFunctionsAccess::ForEach(cb, c);
|
|
3709
3964
|
}
|
|
3710
|
-
template <typename P, typename
|
|
3711
|
-
void ForEach(Callback& cb, const raw_hash_set<P,
|
|
3965
|
+
template <typename P, typename... Params, typename Callback>
|
|
3966
|
+
void ForEach(Callback& cb, const raw_hash_set<P, Params...>* c) {
|
|
3712
3967
|
return HashtableFreeFunctionsAccess::ForEach(cb, c);
|
|
3713
3968
|
}
|
|
3714
3969
|
|
|
3715
3970
|
namespace hashtable_debug_internal {
|
|
3716
3971
|
template <typename Set>
|
|
3717
|
-
struct HashtableDebugAccess<Set,
|
|
3972
|
+
struct HashtableDebugAccess<Set, std::void_t<typename Set::raw_hash_set>> {
|
|
3718
3973
|
using Traits = typename Set::PolicyTraits;
|
|
3719
3974
|
using Slot = typename Traits::slot_type;
|
|
3720
3975
|
|
|
3976
|
+
constexpr static bool kIsDefaultHash = Set::kIsDefaultHash;
|
|
3977
|
+
|
|
3721
3978
|
static size_t GetNumProbes(const Set& set,
|
|
3722
3979
|
const typename Set::key_type& key) {
|
|
3723
|
-
if (set.
|
|
3980
|
+
if (set.is_small()) return 0;
|
|
3724
3981
|
size_t num_probes = 0;
|
|
3725
3982
|
const size_t hash = set.hash_of(key);
|
|
3726
3983
|
auto seq = probe(set.common(), hash);
|
|
@@ -3729,10 +3986,7 @@ struct HashtableDebugAccess<Set, absl::void_t<typename Set::raw_hash_set>> {
|
|
|
3729
3986
|
while (true) {
|
|
3730
3987
|
container_internal::Group g{ctrl + seq.offset()};
|
|
3731
3988
|
for (uint32_t i : g.Match(h2)) {
|
|
3732
|
-
if (
|
|
3733
|
-
typename Set::template EqualElement<typename Set::key_type>{
|
|
3734
|
-
key, set.eq_ref()},
|
|
3735
|
-
Traits::element(set.slot_array() + seq.offset(i))))
|
|
3989
|
+
if (set.equal_to(key, set.slot_array() + seq.offset(i)))
|
|
3736
3990
|
return num_probes;
|
|
3737
3991
|
++num_probes;
|
|
3738
3992
|
}
|
|
@@ -3765,18 +4019,31 @@ struct HashtableDebugAccess<Set, absl::void_t<typename Set::raw_hash_set>> {
|
|
|
3765
4019
|
// Extern template instantiations reduce binary size and linker input size.
|
|
3766
4020
|
// Function definition is in raw_hash_set.cc.
|
|
3767
4021
|
extern template size_t GrowSooTableToNextCapacityAndPrepareInsert<0, false>(
|
|
3768
|
-
CommonFields&, const PolicyFunctions&, size_t
|
|
4022
|
+
CommonFields&, const PolicyFunctions&, absl::FunctionRef<size_t(size_t)>,
|
|
4023
|
+
bool);
|
|
3769
4024
|
extern template size_t GrowSooTableToNextCapacityAndPrepareInsert<1, true>(
|
|
3770
|
-
CommonFields&, const PolicyFunctions&, size_t
|
|
4025
|
+
CommonFields&, const PolicyFunctions&, absl::FunctionRef<size_t(size_t)>,
|
|
4026
|
+
bool);
|
|
3771
4027
|
extern template size_t GrowSooTableToNextCapacityAndPrepareInsert<4, true>(
|
|
3772
|
-
CommonFields&, const PolicyFunctions&, size_t
|
|
4028
|
+
CommonFields&, const PolicyFunctions&, absl::FunctionRef<size_t(size_t)>,
|
|
4029
|
+
bool);
|
|
3773
4030
|
extern template size_t GrowSooTableToNextCapacityAndPrepareInsert<8, true>(
|
|
3774
|
-
CommonFields&, const PolicyFunctions&, size_t
|
|
4031
|
+
CommonFields&, const PolicyFunctions&, absl::FunctionRef<size_t(size_t)>,
|
|
4032
|
+
bool);
|
|
3775
4033
|
#if UINTPTR_MAX == UINT64_MAX
|
|
3776
4034
|
extern template size_t GrowSooTableToNextCapacityAndPrepareInsert<16, true>(
|
|
3777
|
-
CommonFields&, const PolicyFunctions&, size_t
|
|
4035
|
+
CommonFields&, const PolicyFunctions&, absl::FunctionRef<size_t(size_t)>,
|
|
4036
|
+
bool);
|
|
3778
4037
|
#endif
|
|
3779
4038
|
|
|
4039
|
+
extern template void* AllocateBackingArray<
|
|
4040
|
+
BackingArrayAlignment(alignof(size_t)), std::allocator<char>>(void* alloc,
|
|
4041
|
+
size_t n);
|
|
4042
|
+
extern template void DeallocateBackingArray<
|
|
4043
|
+
BackingArrayAlignment(alignof(size_t)), std::allocator<char>>(
|
|
4044
|
+
void* alloc, size_t capacity, ctrl_t* ctrl, size_t slot_size,
|
|
4045
|
+
size_t slot_align, bool had_infoz);
|
|
4046
|
+
|
|
3780
4047
|
} // namespace container_internal
|
|
3781
4048
|
ABSL_NAMESPACE_END
|
|
3782
4049
|
} // namespace absl
|