re2 1.24.0 → 1.25.0
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.
- package/LICENSE +15 -20
- package/README.md +63 -4
- package/binding.gyp +1 -2
- package/lib/addon.cc +9 -5
- package/lib/exec.cc +4 -4
- package/lib/match.cc +4 -4
- package/lib/new.cc +6 -6
- package/lib/pattern.cc +148 -1
- package/lib/replace.cc +5 -4
- package/lib/search.cc +1 -1
- package/lib/set.cc +85 -10
- package/lib/test.cc +1 -1
- package/lib/unicode_properties.h +15840 -0
- package/lib/wrapped_re2.h +40 -4
- package/lib/wrapped_re2_set.h +3 -1
- package/llms-full.txt +497 -0
- package/llms.txt +135 -0
- package/package.json +19 -11
- package/re2.d.ts +2 -0
- package/re2.js +1 -0
- package/vendor/abseil-cpp/CMake/AbseilDll.cmake +87 -74
- package/vendor/abseil-cpp/CMakeLists.txt +3 -3
- package/vendor/abseil-cpp/FAQ.md +130 -79
- package/vendor/abseil-cpp/MODULE.bazel +6 -7
- package/vendor/abseil-cpp/absl/BUILD.bazel +6 -0
- package/vendor/abseil-cpp/absl/algorithm/BUILD.bazel +4 -0
- package/vendor/abseil-cpp/absl/algorithm/CMakeLists.txt +4 -0
- package/vendor/abseil-cpp/absl/algorithm/algorithm.h +34 -2
- package/vendor/abseil-cpp/absl/algorithm/container.h +164 -17
- package/vendor/abseil-cpp/absl/algorithm/container_test.cc +390 -13
- package/vendor/abseil-cpp/absl/base/BUILD.bazel +53 -6
- package/vendor/abseil-cpp/absl/base/CMakeLists.txt +28 -4
- package/vendor/abseil-cpp/absl/base/attributes.h +61 -42
- package/vendor/abseil-cpp/absl/base/call_once.h +1 -0
- package/vendor/abseil-cpp/absl/base/casts.h +8 -1
- package/vendor/abseil-cpp/absl/base/casts_test.cc +3 -6
- package/vendor/abseil-cpp/absl/base/config.h +53 -9
- package/vendor/abseil-cpp/absl/base/exception_safety_testing_test.cc +9 -9
- package/vendor/abseil-cpp/absl/base/fast_type_id.h +30 -2
- package/vendor/abseil-cpp/absl/base/fast_type_id_test.cc +3 -0
- package/vendor/abseil-cpp/absl/base/internal/exception_safety_testing.h +15 -12
- package/vendor/abseil-cpp/absl/base/internal/hardening.h +136 -0
- package/vendor/abseil-cpp/absl/base/internal/hardening_test.cc +168 -0
- package/vendor/abseil-cpp/absl/base/internal/iterator_traits.h +2 -2
- package/vendor/abseil-cpp/absl/base/internal/low_level_alloc.cc +6 -0
- package/vendor/abseil-cpp/absl/base/internal/low_level_scheduling.h +77 -15
- package/vendor/abseil-cpp/absl/base/internal/sysinfo.cc +1 -2
- package/vendor/abseil-cpp/absl/base/internal/thread_identity.h +52 -0
- package/vendor/abseil-cpp/absl/base/internal/unscaledcycleclock.h +5 -0
- package/vendor/abseil-cpp/absl/base/macros.h +36 -20
- package/vendor/abseil-cpp/absl/base/nullability.h +4 -3
- package/vendor/abseil-cpp/absl/base/optimization.h +3 -2
- package/vendor/abseil-cpp/absl/base/optimization_test.cc +4 -3
- package/vendor/abseil-cpp/absl/base/options.h +55 -1
- package/vendor/abseil-cpp/absl/base/policy_checks.h +5 -5
- package/vendor/abseil-cpp/absl/base/{internal/throw_delegate.cc → throw_delegate.cc} +9 -7
- package/vendor/abseil-cpp/absl/base/{internal/throw_delegate.h → throw_delegate.h} +4 -14
- package/vendor/abseil-cpp/absl/base/throw_delegate_test.cc +19 -28
- package/vendor/abseil-cpp/absl/cleanup/BUILD.bazel +2 -0
- package/vendor/abseil-cpp/absl/cleanup/CMakeLists.txt +2 -0
- package/vendor/abseil-cpp/absl/cleanup/cleanup.h +3 -2
- package/vendor/abseil-cpp/absl/cleanup/internal/cleanup.h +3 -2
- package/vendor/abseil-cpp/absl/container/BUILD.bazel +19 -7
- package/vendor/abseil-cpp/absl/container/CMakeLists.txt +6 -5
- package/vendor/abseil-cpp/absl/container/btree_benchmark.cc +3 -5
- package/vendor/abseil-cpp/absl/container/btree_set.h +5 -5
- package/vendor/abseil-cpp/absl/container/btree_test.cc +11 -14
- package/vendor/abseil-cpp/absl/container/chunked_queue.h +8 -6
- package/vendor/abseil-cpp/absl/container/chunked_queue_test.cc +5 -5
- package/vendor/abseil-cpp/absl/container/fixed_array.h +14 -13
- package/vendor/abseil-cpp/absl/container/fixed_array_test.cc +3 -3
- package/vendor/abseil-cpp/absl/container/flat_hash_map.h +18 -6
- package/vendor/abseil-cpp/absl/container/flat_hash_map_test.cc +34 -1
- package/vendor/abseil-cpp/absl/container/flat_hash_set.h +21 -7
- package/vendor/abseil-cpp/absl/container/flat_hash_set_test.cc +39 -7
- package/vendor/abseil-cpp/absl/container/inlined_vector.h +29 -29
- package/vendor/abseil-cpp/absl/container/inlined_vector_test.cc +2 -2
- package/vendor/abseil-cpp/absl/container/internal/btree.h +32 -24
- package/vendor/abseil-cpp/absl/container/internal/btree_container.h +16 -17
- package/vendor/abseil-cpp/absl/container/internal/common.h +6 -5
- package/vendor/abseil-cpp/absl/container/internal/common_policy_traits.h +1 -1
- package/vendor/abseil-cpp/absl/container/internal/compressed_tuple.h +16 -16
- package/vendor/abseil-cpp/absl/container/internal/compressed_tuple_test.cc +13 -13
- package/vendor/abseil-cpp/absl/container/internal/container_memory.h +41 -31
- package/vendor/abseil-cpp/absl/container/internal/hash_function_defaults.h +2 -2
- package/vendor/abseil-cpp/absl/container/internal/hash_generator_testing.h +4 -4
- package/vendor/abseil-cpp/absl/container/internal/hash_policy_traits.h +3 -3
- package/vendor/abseil-cpp/absl/container/internal/hashtable_control_bytes.h +27 -19
- package/vendor/abseil-cpp/absl/container/internal/hashtablez_sampler.cc +2 -2
- package/vendor/abseil-cpp/absl/container/internal/hashtablez_sampler.h +0 -17
- package/vendor/abseil-cpp/absl/container/internal/hashtablez_sampler_test.cc +12 -30
- package/vendor/abseil-cpp/absl/container/internal/inlined_vector.h +28 -28
- package/vendor/abseil-cpp/absl/container/internal/layout.h +13 -13
- package/vendor/abseil-cpp/absl/container/internal/layout_test.cc +3 -2
- package/vendor/abseil-cpp/absl/container/internal/raw_hash_map.h +60 -62
- package/vendor/abseil-cpp/absl/container/internal/raw_hash_set.cc +59 -39
- package/vendor/abseil-cpp/absl/container/internal/raw_hash_set.h +619 -326
- package/vendor/abseil-cpp/absl/container/internal/raw_hash_set_benchmark.cc +25 -2
- package/vendor/abseil-cpp/absl/container/internal/raw_hash_set_probe_benchmark.cc +4 -4
- package/vendor/abseil-cpp/absl/container/internal/raw_hash_set_test.cc +575 -159
- package/vendor/abseil-cpp/absl/container/linked_hash_map.h +2 -2
- package/vendor/abseil-cpp/absl/container/node_hash_map.h +27 -15
- package/vendor/abseil-cpp/absl/container/node_hash_map_test.cc +34 -0
- package/vendor/abseil-cpp/absl/container/node_hash_set.h +25 -11
- package/vendor/abseil-cpp/absl/container/node_hash_set_test.cc +39 -7
- package/vendor/abseil-cpp/absl/container/sample_element_size_test.cc +7 -4
- package/vendor/abseil-cpp/absl/crc/BUILD.bazel +0 -1
- package/vendor/abseil-cpp/absl/crc/CMakeLists.txt +2 -3
- package/vendor/abseil-cpp/absl/crc/crc32c_benchmark.cc +2 -1
- package/vendor/abseil-cpp/absl/crc/internal/cpu_detect.cc +6 -6
- package/vendor/abseil-cpp/absl/crc/internal/crc.cc +4 -6
- package/vendor/abseil-cpp/absl/crc/internal/crc32_x86_arm_combined_simd.h +41 -0
- package/vendor/abseil-cpp/absl/crc/internal/crc_internal.h +0 -16
- package/vendor/abseil-cpp/absl/crc/internal/crc_x86_arm_combined.cc +143 -81
- package/vendor/abseil-cpp/absl/debugging/BUILD.bazel +9 -31
- package/vendor/abseil-cpp/absl/debugging/CMakeLists.txt +3 -33
- package/vendor/abseil-cpp/absl/debugging/internal/demangle_rust.h +8 -0
- package/vendor/abseil-cpp/absl/debugging/internal/demangle_test.cc +2 -1
- package/vendor/abseil-cpp/absl/debugging/internal/examine_stack.cc +12 -2
- package/vendor/abseil-cpp/absl/debugging/internal/examine_stack.h +2 -3
- package/vendor/abseil-cpp/absl/debugging/internal/stacktrace_aarch64-inl.inc +11 -0
- package/vendor/abseil-cpp/absl/debugging/internal/stacktrace_emscripten-inl.inc +13 -4
- package/vendor/abseil-cpp/absl/debugging/internal/stacktrace_generic-inl.inc +14 -7
- package/vendor/abseil-cpp/absl/debugging/internal/stacktrace_riscv-inl.inc +4 -0
- package/vendor/abseil-cpp/absl/debugging/internal/symbolize.h +46 -36
- package/vendor/abseil-cpp/absl/debugging/stacktrace.cc +18 -58
- package/vendor/abseil-cpp/absl/debugging/stacktrace.h +5 -48
- package/vendor/abseil-cpp/absl/debugging/stacktrace_test.cc +10 -124
- package/vendor/abseil-cpp/absl/debugging/symbolize.cc +20 -2
- package/vendor/abseil-cpp/absl/debugging/symbolize_elf.inc +58 -106
- package/vendor/abseil-cpp/absl/debugging/symbolize_test.cc +37 -36
- package/vendor/abseil-cpp/absl/debugging/symbolize_unimplemented.inc +4 -4
- package/vendor/abseil-cpp/absl/flags/BUILD.bazel +6 -3
- package/vendor/abseil-cpp/absl/flags/CMakeLists.txt +1 -1
- package/vendor/abseil-cpp/absl/flags/commandlineflag.h +8 -6
- package/vendor/abseil-cpp/absl/flags/commandlineflag_test.cc +1 -1
- package/vendor/abseil-cpp/absl/flags/flag_benchmark.cc +5 -5
- package/vendor/abseil-cpp/absl/flags/flag_test.cc +30 -30
- package/vendor/abseil-cpp/absl/flags/internal/flag.cc +4 -4
- package/vendor/abseil-cpp/absl/flags/internal/flag.h +6 -6
- package/vendor/abseil-cpp/absl/flags/marshalling.h +2 -28
- package/vendor/abseil-cpp/absl/flags/marshalling_test.cc +12 -11
- package/vendor/abseil-cpp/absl/flags/reflection_test.cc +1 -1
- package/vendor/abseil-cpp/absl/functional/BUILD.bazel +26 -1
- package/vendor/abseil-cpp/absl/functional/CMakeLists.txt +29 -1
- package/vendor/abseil-cpp/absl/functional/any_invocable.h +13 -14
- package/vendor/abseil-cpp/absl/functional/any_invocable_test.cc +46 -47
- package/vendor/abseil-cpp/absl/functional/bind_back.h +79 -0
- package/vendor/abseil-cpp/absl/functional/bind_back_test.cc +237 -0
- package/vendor/abseil-cpp/absl/functional/bind_front.h +7 -1
- package/vendor/abseil-cpp/absl/functional/bind_front_test.cc +4 -4
- package/vendor/abseil-cpp/absl/functional/function_ref_test.cc +2 -2
- package/vendor/abseil-cpp/absl/functional/internal/any_invocable.h +28 -28
- package/vendor/abseil-cpp/absl/functional/internal/back_binder.h +95 -0
- package/vendor/abseil-cpp/absl/functional/internal/front_binder.h +4 -4
- package/vendor/abseil-cpp/absl/functional/internal/function_ref.h +2 -2
- package/vendor/abseil-cpp/absl/functional/overload_test.cc +13 -13
- package/vendor/abseil-cpp/absl/hash/BUILD.bazel +1 -2
- package/vendor/abseil-cpp/absl/hash/CMakeLists.txt +1 -2
- package/vendor/abseil-cpp/absl/hash/hash.h +1 -1
- package/vendor/abseil-cpp/absl/hash/hash_test.cc +14 -20
- package/vendor/abseil-cpp/absl/hash/hash_testing.h +11 -9
- package/vendor/abseil-cpp/absl/hash/internal/city.cc +39 -51
- package/vendor/abseil-cpp/absl/hash/internal/hash.cc +165 -47
- package/vendor/abseil-cpp/absl/hash/internal/hash.h +86 -27
- package/vendor/abseil-cpp/absl/hash/internal/low_level_hash_test.cc +36 -1
- package/vendor/abseil-cpp/absl/hash/internal/spy_hash_state.h +8 -5
- package/vendor/abseil-cpp/absl/log/BUILD.bazel +5 -2
- package/vendor/abseil-cpp/absl/log/CMakeLists.txt +5 -3
- package/vendor/abseil-cpp/absl/log/absl_vlog_is_on.h +0 -2
- package/vendor/abseil-cpp/absl/log/internal/BUILD.bazel +15 -1
- package/vendor/abseil-cpp/absl/log/internal/log_message.cc +5 -4
- package/vendor/abseil-cpp/absl/log/internal/log_message.h +14 -0
- package/vendor/abseil-cpp/absl/log/internal/nullstream.h +1 -1
- package/vendor/abseil-cpp/absl/log/internal/proto.cc +13 -0
- package/vendor/abseil-cpp/absl/log/internal/structured_proto.cc +5 -5
- package/vendor/abseil-cpp/absl/log/internal/structured_proto.h +6 -5
- package/vendor/abseil-cpp/absl/log/internal/structured_proto_test.cc +3 -3
- package/vendor/abseil-cpp/absl/log/internal/vlog_config.cc +2 -2
- package/vendor/abseil-cpp/absl/log/internal/vlog_config_benchmark.cc +3 -3
- package/vendor/abseil-cpp/absl/log/log_format_test.cc +19 -2
- package/vendor/abseil-cpp/absl/log/log_modifier_methods_test.cc +18 -0
- package/vendor/abseil-cpp/absl/log/log_streamer.h +29 -2
- package/vendor/abseil-cpp/absl/log/log_streamer_test.cc +18 -0
- package/vendor/abseil-cpp/absl/log/scoped_mock_log_test.cc +1 -1
- package/vendor/abseil-cpp/absl/log/vlog_is_on.h +0 -2
- package/vendor/abseil-cpp/absl/log/vlog_is_on_test.cc +6 -5
- package/vendor/abseil-cpp/absl/memory/memory.h +55 -5
- package/vendor/abseil-cpp/absl/memory/memory_test.cc +55 -1
- package/vendor/abseil-cpp/absl/meta/BUILD.bazel +2 -0
- package/vendor/abseil-cpp/absl/meta/internal/requires.h +1 -1
- package/vendor/abseil-cpp/absl/meta/type_traits.h +119 -55
- package/vendor/abseil-cpp/absl/meta/type_traits_test.cc +7 -7
- package/vendor/abseil-cpp/absl/numeric/int128_test.cc +6 -6
- package/vendor/abseil-cpp/absl/profiling/BUILD.bazel +3 -1
- package/vendor/abseil-cpp/absl/profiling/hashtable.cc +0 -4
- package/vendor/abseil-cpp/absl/profiling/internal/profile_builder.cc +32 -33
- package/vendor/abseil-cpp/absl/profiling/internal/profile_builder.h +25 -2
- package/vendor/abseil-cpp/absl/profiling/internal/sample_recorder_test.cc +8 -5
- package/vendor/abseil-cpp/absl/random/BUILD.bazel +13 -1
- package/vendor/abseil-cpp/absl/random/CMakeLists.txt +23 -2
- package/vendor/abseil-cpp/absl/random/benchmarks.cc +1 -1
- package/vendor/abseil-cpp/absl/random/beta_distribution.h +2 -2
- package/vendor/abseil-cpp/absl/random/bit_gen_ref.h +26 -53
- package/vendor/abseil-cpp/absl/random/bit_gen_ref_test.cc +43 -0
- package/vendor/abseil-cpp/absl/random/discrete_distribution.h +1 -1
- package/vendor/abseil-cpp/absl/random/distributions.h +17 -17
- package/vendor/abseil-cpp/absl/random/distributions_test.cc +4 -4
- package/vendor/abseil-cpp/absl/random/exponential_distribution.h +1 -1
- package/vendor/abseil-cpp/absl/random/internal/BUILD.bazel +4 -2
- package/vendor/abseil-cpp/absl/random/internal/distribution_caller.h +8 -21
- package/vendor/abseil-cpp/absl/random/internal/fast_uniform_bits.h +1 -1
- package/vendor/abseil-cpp/absl/random/internal/generate_real.h +1 -1
- package/vendor/abseil-cpp/absl/random/internal/iostream_state_saver.h +2 -2
- package/vendor/abseil-cpp/absl/random/internal/iostream_state_saver_test.cc +3 -2
- package/vendor/abseil-cpp/absl/random/internal/mock_helpers.h +14 -40
- package/vendor/abseil-cpp/absl/random/internal/nonsecure_base.h +2 -2
- package/vendor/abseil-cpp/absl/random/internal/nonsecure_base_test.cc +2 -2
- package/vendor/abseil-cpp/absl/random/internal/pcg_engine.h +6 -6
- package/vendor/abseil-cpp/absl/random/internal/pcg_engine_test.cc +3 -2
- package/vendor/abseil-cpp/absl/random/internal/randen_detect.cc +6 -6
- package/vendor/abseil-cpp/absl/random/internal/randen_engine.h +2 -2
- package/vendor/abseil-cpp/absl/random/internal/randen_engine_test.cc +3 -2
- package/vendor/abseil-cpp/absl/random/internal/randen_test.cc +3 -2
- package/vendor/abseil-cpp/absl/random/internal/salted_seed_seq.h +6 -5
- package/vendor/abseil-cpp/absl/random/internal/seed_material.cc +4 -4
- package/vendor/abseil-cpp/absl/random/internal/seed_material.h +2 -1
- package/vendor/abseil-cpp/absl/random/internal/traits.h +21 -0
- package/vendor/abseil-cpp/absl/random/internal/traits_test.cc +5 -0
- package/vendor/abseil-cpp/absl/random/internal/uniform_helper.h +23 -23
- package/vendor/abseil-cpp/absl/random/internal/uniform_helper_test.cc +2 -1
- package/vendor/abseil-cpp/absl/random/mocking_access.h +74 -0
- package/vendor/abseil-cpp/absl/random/mocking_bit_gen.h +9 -19
- package/vendor/abseil-cpp/absl/random/uniform_real_distribution.h +1 -1
- package/vendor/abseil-cpp/absl/status/BUILD.bazel +81 -0
- package/vendor/abseil-cpp/absl/status/CMakeLists.txt +91 -0
- package/vendor/abseil-cpp/absl/status/internal/status_internal.cc +63 -18
- package/vendor/abseil-cpp/absl/status/internal/status_internal.h +26 -2
- package/vendor/abseil-cpp/absl/status/internal/status_matchers.h +22 -8
- package/vendor/abseil-cpp/absl/status/internal/statusor_internal.h +43 -43
- package/vendor/abseil-cpp/absl/status/status.cc +62 -70
- package/vendor/abseil-cpp/absl/status/status.h +249 -23
- package/vendor/abseil-cpp/absl/status/status_benchmark.cc +12 -0
- package/vendor/abseil-cpp/absl/status/status_builder.cc +196 -0
- package/vendor/abseil-cpp/absl/status/status_builder.h +978 -0
- package/vendor/abseil-cpp/absl/status/status_builder_test.cc +380 -0
- package/vendor/abseil-cpp/absl/status/status_macros.h +484 -0
- package/vendor/abseil-cpp/absl/status/status_macros_test.cc +634 -0
- package/vendor/abseil-cpp/absl/status/status_matchers.h +2 -1
- package/vendor/abseil-cpp/absl/status/status_matchers_test.cc +3 -4
- package/vendor/abseil-cpp/absl/status/status_payload_printer.h +3 -2
- package/vendor/abseil-cpp/absl/status/status_test.cc +443 -13
- package/vendor/abseil-cpp/absl/status/statusor.h +69 -36
- package/vendor/abseil-cpp/absl/status/statusor_test.cc +132 -35
- package/vendor/abseil-cpp/absl/strings/BUILD.bazel +42 -7
- package/vendor/abseil-cpp/absl/strings/CMakeLists.txt +33 -4
- package/vendor/abseil-cpp/absl/strings/ascii.h +1 -2
- package/vendor/abseil-cpp/absl/strings/atod_manual_test.cc +5 -5
- package/vendor/abseil-cpp/absl/strings/cord.cc +26 -7
- package/vendor/abseil-cpp/absl/strings/cord.h +23 -13
- package/vendor/abseil-cpp/absl/strings/cord_buffer.h +4 -2
- package/vendor/abseil-cpp/absl/strings/cord_test.cc +85 -9
- package/vendor/abseil-cpp/absl/strings/escaping.cc +183 -35
- package/vendor/abseil-cpp/absl/strings/escaping.h +12 -2
- package/vendor/abseil-cpp/absl/strings/escaping_benchmark.cc +1 -3
- package/vendor/abseil-cpp/absl/strings/escaping_test.cc +22 -18
- package/vendor/abseil-cpp/absl/strings/has_absl_stringify_test.cc +2 -2
- package/vendor/abseil-cpp/absl/strings/has_ostream_operator_test.cc +2 -2
- package/vendor/abseil-cpp/absl/strings/internal/append_and_overwrite.h +10 -10
- package/vendor/abseil-cpp/absl/strings/internal/cordz_sample_token_test.cc +1 -1
- package/vendor/abseil-cpp/absl/strings/internal/damerau_levenshtein_distance.cc +6 -0
- package/vendor/abseil-cpp/absl/strings/internal/damerau_levenshtein_distance.h +1 -0
- package/vendor/abseil-cpp/absl/strings/internal/escaping.cc +0 -141
- package/vendor/abseil-cpp/absl/strings/internal/escaping.h +2 -26
- package/vendor/abseil-cpp/absl/strings/internal/generic_printer_internal.h +23 -2
- package/vendor/abseil-cpp/absl/strings/internal/generic_printer_test.cc +6 -2
- package/vendor/abseil-cpp/absl/strings/internal/resize_uninitialized.h +31 -24
- package/vendor/abseil-cpp/absl/strings/internal/resize_uninitialized_test.cc +16 -41
- package/vendor/abseil-cpp/absl/strings/internal/stl_type_traits.h +39 -39
- package/vendor/abseil-cpp/absl/strings/internal/str_format/arg.h +14 -22
- package/vendor/abseil-cpp/absl/strings/internal/str_format/bind.h +2 -2
- package/vendor/abseil-cpp/absl/strings/internal/str_format/convert_test.cc +12 -20
- package/vendor/abseil-cpp/absl/strings/internal/str_format/float_conversion.cc +510 -307
- package/vendor/abseil-cpp/absl/strings/internal/str_join_internal.h +0 -1
- package/vendor/abseil-cpp/absl/strings/internal/str_split_internal.h +9 -10
- package/vendor/abseil-cpp/absl/strings/internal/string_constant_test.cc +6 -5
- package/vendor/abseil-cpp/absl/strings/internal/stringify_sink.h +12 -0
- package/vendor/abseil-cpp/absl/strings/internal/stringify_stream.h +119 -0
- package/vendor/abseil-cpp/absl/strings/internal/stringify_stream_test.cc +111 -0
- package/vendor/abseil-cpp/absl/strings/numbers.cc +406 -0
- package/vendor/abseil-cpp/absl/strings/numbers.h +4 -0
- package/vendor/abseil-cpp/absl/strings/numbers_test.cc +33 -0
- package/vendor/abseil-cpp/absl/strings/resize_and_overwrite.h +10 -6
- package/vendor/abseil-cpp/absl/strings/str_cat.h +36 -1
- package/vendor/abseil-cpp/absl/strings/str_cat_benchmark.cc +1 -2
- package/vendor/abseil-cpp/absl/strings/str_cat_test.cc +28 -0
- package/vendor/abseil-cpp/absl/strings/str_join_test.cc +4 -4
- package/vendor/abseil-cpp/absl/strings/str_split.h +11 -6
- package/vendor/abseil-cpp/absl/strings/str_split_test.cc +13 -0
- package/vendor/abseil-cpp/absl/strings/substitute.h +2 -2
- package/vendor/abseil-cpp/absl/synchronization/BUILD.bazel +3 -0
- package/vendor/abseil-cpp/absl/synchronization/internal/create_thread_identity.cc +21 -0
- package/vendor/abseil-cpp/absl/synchronization/internal/per_thread_sem.h +5 -0
- package/vendor/abseil-cpp/absl/synchronization/mutex.cc +13 -0
- package/vendor/abseil-cpp/absl/synchronization/mutex.h +32 -2
- package/vendor/abseil-cpp/absl/synchronization/mutex_test.cc +17 -3
- package/vendor/abseil-cpp/absl/time/BUILD.bazel +80 -0
- package/vendor/abseil-cpp/absl/time/CMakeLists.txt +73 -0
- package/vendor/abseil-cpp/absl/time/clock.h +3 -0
- package/vendor/abseil-cpp/absl/time/clock_interface.cc +71 -0
- package/vendor/abseil-cpp/absl/time/clock_interface.h +93 -0
- package/vendor/abseil-cpp/absl/time/clock_interface_test.cc +128 -0
- package/vendor/abseil-cpp/absl/time/format.cc +3 -10
- package/vendor/abseil-cpp/absl/time/format_test.cc +12 -0
- package/vendor/abseil-cpp/absl/time/internal/cctz/src/time_zone_format.cc +90 -89
- package/vendor/abseil-cpp/absl/time/internal/cctz/src/time_zone_format_test.cc +80 -5
- package/vendor/abseil-cpp/absl/time/internal/cctz/src/time_zone_name_win.cc +1 -2
- package/vendor/abseil-cpp/absl/time/internal/cctz/src/tzfile.h +10 -15
- package/vendor/abseil-cpp/absl/time/internal/cctz/testdata/version +1 -1
- package/vendor/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Vancouver +0 -0
- package/vendor/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ho_Chi_Minh +0 -0
- package/vendor/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Phnom_Penh +0 -0
- package/vendor/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Saigon +0 -0
- package/vendor/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tbilisi +0 -0
- package/vendor/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Asia/Vientiane +0 -0
- package/vendor/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Canada/Pacific +0 -0
- package/vendor/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Chisinau +0 -0
- package/vendor/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Europe/Tiraspol +0 -0
- package/vendor/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/zone1970.tab +1 -1
- package/vendor/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/zonenow.tab +3 -3
- package/vendor/abseil-cpp/absl/time/simulated_clock.cc +225 -0
- package/vendor/abseil-cpp/absl/time/simulated_clock.h +109 -0
- package/vendor/abseil-cpp/absl/time/simulated_clock_test.cc +614 -0
- package/vendor/abseil-cpp/absl/types/BUILD.bazel +116 -0
- package/vendor/abseil-cpp/absl/types/CMakeLists.txt +100 -0
- package/vendor/abseil-cpp/absl/types/any.h +26 -4
- package/vendor/abseil-cpp/absl/types/any_span.h +1067 -0
- package/vendor/abseil-cpp/absl/types/any_span_benchmark.cc +258 -0
- package/vendor/abseil-cpp/absl/types/any_span_test.cc +1210 -0
- package/vendor/abseil-cpp/absl/types/compare.h +4 -4
- package/vendor/abseil-cpp/absl/types/internal/any_span.h +477 -0
- package/vendor/abseil-cpp/absl/types/internal/span.h +5 -6
- package/vendor/abseil-cpp/absl/types/optional.h +30 -3
- package/vendor/abseil-cpp/absl/types/optional_ref.h +295 -0
- package/vendor/abseil-cpp/absl/types/optional_ref_test.cc +370 -0
- package/vendor/abseil-cpp/absl/types/source_location.cc +18 -0
- package/vendor/abseil-cpp/absl/types/source_location.h +172 -0
- package/vendor/abseil-cpp/absl/types/source_location_test.cc +139 -0
- package/vendor/abseil-cpp/absl/types/span.h +19 -23
- package/vendor/abseil-cpp/absl/types/variant.h +75 -18
- package/vendor/abseil-cpp/absl/types/variant_test.cc +23 -23
- package/vendor/abseil-cpp/absl/utility/BUILD.bazel +1 -0
- package/vendor/abseil-cpp/absl/utility/CMakeLists.txt +1 -0
- package/vendor/abseil-cpp/absl/utility/utility.h +99 -16
- package/vendor/abseil-cpp/ci/absl_alternate_options.h +2 -0
- package/vendor/abseil-cpp/ci/linux_arm_clang-latest_libcxx_bazel.sh +10 -4
- package/vendor/abseil-cpp/ci/linux_clang-latest_libcxx_asan_bazel.sh +13 -6
- package/vendor/abseil-cpp/ci/linux_clang-latest_libcxx_bazel.sh +10 -4
- package/vendor/abseil-cpp/ci/linux_clang-latest_libcxx_tsan_bazel.sh +12 -5
- package/vendor/abseil-cpp/ci/linux_clang-latest_libstdcxx_bazel.sh +9 -2
- package/vendor/abseil-cpp/ci/linux_docker_containers.sh +4 -4
- package/vendor/abseil-cpp/ci/linux_gcc-floor_libstdcxx_bazel.sh +10 -3
- package/vendor/abseil-cpp/ci/linux_gcc-latest_libstdcxx_bazel.sh +8 -2
- package/vendor/abseil-cpp/ci/macos_xcode_bazel.sh +4 -3
- package/vendor/abseil-cpp/ci/macos_xcode_cmake.sh +2 -2
- package/vendor/abseil-cpp/ci/windows_clangcl_bazel.bat +1 -1
- package/vendor/abseil-cpp/ci/windows_msvc_bazel.bat +1 -1
- package/vendor/abseil-cpp/absl/debugging/internal/borrowed_fixup_buffer.cc +0 -118
- package/vendor/abseil-cpp/absl/debugging/internal/borrowed_fixup_buffer.h +0 -71
- package/vendor/abseil-cpp/absl/debugging/internal/borrowed_fixup_buffer_test.cc +0 -97
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
#include <map>
|
|
32
32
|
#include <memory>
|
|
33
33
|
#include <numeric>
|
|
34
|
+
#include <optional>
|
|
34
35
|
#include <ostream>
|
|
35
36
|
#include <random>
|
|
36
37
|
#include <set>
|
|
@@ -53,7 +54,6 @@
|
|
|
53
54
|
#include "absl/container/internal/container_memory.h"
|
|
54
55
|
#include "absl/container/internal/hash_function_defaults.h"
|
|
55
56
|
#include "absl/container/internal/hash_policy_testing.h"
|
|
56
|
-
#include "absl/random/random.h"
|
|
57
57
|
#include "absl/container/internal/hashtable_control_bytes.h"
|
|
58
58
|
#include "absl/container/internal/hashtable_debug.h"
|
|
59
59
|
#include "absl/container/internal/hashtablez_sampler.h"
|
|
@@ -68,9 +68,9 @@
|
|
|
68
68
|
#include "absl/memory/memory.h"
|
|
69
69
|
#include "absl/meta/type_traits.h"
|
|
70
70
|
#include "absl/numeric/int128.h"
|
|
71
|
+
#include "absl/random/random.h"
|
|
71
72
|
#include "absl/strings/str_cat.h"
|
|
72
73
|
#include "absl/strings/string_view.h"
|
|
73
|
-
#include "absl/types/optional.h"
|
|
74
74
|
|
|
75
75
|
namespace absl {
|
|
76
76
|
ABSL_NAMESPACE_BEGIN
|
|
@@ -96,6 +96,7 @@ namespace {
|
|
|
96
96
|
using ::testing::ElementsAre;
|
|
97
97
|
using ::testing::Eq;
|
|
98
98
|
using ::testing::Ge;
|
|
99
|
+
using ::testing::HasSubstr;
|
|
99
100
|
using ::testing::Lt;
|
|
100
101
|
using ::testing::Pair;
|
|
101
102
|
using ::testing::UnorderedElementsAre;
|
|
@@ -337,7 +338,8 @@ TEST(Util, GrowthAndCapacity) {
|
|
|
337
338
|
}
|
|
338
339
|
|
|
339
340
|
TEST(Util, probe_seq) {
|
|
340
|
-
|
|
341
|
+
HashtableCapacity capacity(127);
|
|
342
|
+
probe_seq<16> seq(capacity, /*hash=*/0);
|
|
341
343
|
auto gen = [&]() {
|
|
342
344
|
size_t res = seq.offset();
|
|
343
345
|
seq.next();
|
|
@@ -346,11 +348,191 @@ TEST(Util, probe_seq) {
|
|
|
346
348
|
std::vector<size_t> offsets(8);
|
|
347
349
|
std::generate_n(offsets.begin(), 8, gen);
|
|
348
350
|
EXPECT_THAT(offsets, ElementsAre(0, 16, 48, 96, 32, 112, 80, 64));
|
|
349
|
-
seq = probe_seq<16>(
|
|
351
|
+
seq = probe_seq<16>(capacity, /*hash=*/128);
|
|
350
352
|
std::generate_n(offsets.begin(), 8, gen);
|
|
351
353
|
EXPECT_THAT(offsets, ElementsAre(0, 16, 48, 96, 32, 112, 80, 64));
|
|
352
354
|
}
|
|
353
355
|
|
|
356
|
+
template <typename T>
|
|
357
|
+
class HashtableDataTest : public ::testing::Test {};
|
|
358
|
+
|
|
359
|
+
using StorageModes = ::testing::Types<
|
|
360
|
+
std::integral_constant<HashtableCapacityStorageMode,
|
|
361
|
+
HashtableCapacityStorageMode::kCapacityByValue>,
|
|
362
|
+
std::integral_constant<HashtableCapacityStorageMode,
|
|
363
|
+
HashtableCapacityStorageMode::kCapacityByLog>>;
|
|
364
|
+
|
|
365
|
+
TYPED_TEST_SUITE(HashtableDataTest, StorageModes);
|
|
366
|
+
|
|
367
|
+
TYPED_TEST(HashtableDataTest, HashtableCapacity) {
|
|
368
|
+
constexpr HashtableCapacityStorageMode kMode = TypeParam::value;
|
|
369
|
+
using Capacity = HashtableCapacityImpl<kMode>;
|
|
370
|
+
|
|
371
|
+
Capacity cap0(0);
|
|
372
|
+
EXPECT_TRUE(cap0.IsValid());
|
|
373
|
+
EXPECT_EQ(cap0.capacity(), 0);
|
|
374
|
+
EXPECT_FALSE(cap0.IsDestroyed());
|
|
375
|
+
EXPECT_FALSE(cap0.IsReentrance());
|
|
376
|
+
EXPECT_FALSE(cap0.IsMovedFrom());
|
|
377
|
+
EXPECT_FALSE(cap0.IsSelfMovedFrom());
|
|
378
|
+
|
|
379
|
+
for (size_t i = 0, cap = 0; i < 20; ++i, cap = NextCapacity(cap)) {
|
|
380
|
+
Capacity capacity(cap);
|
|
381
|
+
ASSERT_TRUE(capacity.IsValid());
|
|
382
|
+
ASSERT_EQ(capacity.capacity(), cap);
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
auto destroyed = Capacity::CreateDestroyed();
|
|
386
|
+
EXPECT_FALSE(destroyed.IsValid());
|
|
387
|
+
EXPECT_TRUE(destroyed.IsDestroyed());
|
|
388
|
+
|
|
389
|
+
auto reentrance = Capacity::CreateReentrance();
|
|
390
|
+
EXPECT_FALSE(reentrance.IsValid());
|
|
391
|
+
EXPECT_TRUE(reentrance.IsReentrance());
|
|
392
|
+
|
|
393
|
+
auto moved_from = Capacity::CreateMovedFrom();
|
|
394
|
+
EXPECT_FALSE(moved_from.IsValid());
|
|
395
|
+
EXPECT_TRUE(moved_from.IsMovedFrom());
|
|
396
|
+
EXPECT_FALSE(moved_from.IsSelfMovedFrom());
|
|
397
|
+
|
|
398
|
+
auto self_moved_from = Capacity::CreateSelfMovedFrom();
|
|
399
|
+
EXPECT_FALSE(self_moved_from.IsValid());
|
|
400
|
+
EXPECT_TRUE(self_moved_from.IsSelfMovedFrom());
|
|
401
|
+
EXPECT_TRUE(self_moved_from.IsMovedFrom());
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
TYPED_TEST(HashtableDataTest, RawData) {
|
|
405
|
+
constexpr HashtableCapacityStorageMode kMode = TypeParam::value;
|
|
406
|
+
using Capacity = HashtableCapacityImpl<kMode>;
|
|
407
|
+
|
|
408
|
+
for (size_t i = 0, cap = 0; i < 20; ++i, cap = NextCapacity(cap)) {
|
|
409
|
+
Capacity orig_capacity(cap);
|
|
410
|
+
Capacity capacity = Capacity::FromRawData(orig_capacity.ToRawData());
|
|
411
|
+
ASSERT_TRUE(capacity.IsValid());
|
|
412
|
+
ASSERT_EQ(capacity.capacity(), cap);
|
|
413
|
+
}
|
|
414
|
+
auto orig_reentrance = Capacity::CreateReentrance();
|
|
415
|
+
Capacity reentrance = Capacity::FromRawData(orig_reentrance.ToRawData());
|
|
416
|
+
EXPECT_TRUE(reentrance.IsReentrance());
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
TYPED_TEST(HashtableDataTest, HashtableInlineDataCapacity) {
|
|
420
|
+
constexpr HashtableCapacityStorageMode kMode = TypeParam::value;
|
|
421
|
+
using InlineData = HashtableInlineDataImpl<kMode>;
|
|
422
|
+
using Capacity = HashtableCapacityImpl<kMode>;
|
|
423
|
+
|
|
424
|
+
InlineData data(Capacity(0), no_seed_empty_tag_t{});
|
|
425
|
+
EXPECT_EQ(data.capacity().capacity(), 0);
|
|
426
|
+
EXPECT_EQ(data.size(), 0);
|
|
427
|
+
EXPECT_TRUE(data.empty());
|
|
428
|
+
|
|
429
|
+
for (size_t i = 0, cap = 0; i < 20; ++i, cap = NextCapacity(cap)) {
|
|
430
|
+
data.set_capacity(cap);
|
|
431
|
+
ASSERT_EQ(data.capacity().capacity(), cap);
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
// Test overload from `Capacity` object.
|
|
435
|
+
for (size_t i = 0, cap = 0; i < 20; ++i, cap = NextCapacity(cap)) {
|
|
436
|
+
data.set_capacity(Capacity(cap));
|
|
437
|
+
ASSERT_EQ(data.capacity().capacity(), cap);
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
auto reentrance = Capacity::CreateReentrance();
|
|
441
|
+
data.set_capacity(reentrance);
|
|
442
|
+
EXPECT_TRUE(data.capacity().IsReentrance());
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
TYPED_TEST(HashtableDataTest, HashtableInlineDataSize) {
|
|
446
|
+
constexpr HashtableCapacityStorageMode kMode = TypeParam::value;
|
|
447
|
+
using InlineData = HashtableInlineDataImpl<kMode>;
|
|
448
|
+
using Capacity = HashtableCapacityImpl<kMode>;
|
|
449
|
+
|
|
450
|
+
InlineData data(Capacity(0), no_seed_empty_tag_t{});
|
|
451
|
+
EXPECT_EQ(data.size(), 0);
|
|
452
|
+
data.increment_size();
|
|
453
|
+
EXPECT_EQ(data.size(), 1);
|
|
454
|
+
EXPECT_FALSE(data.empty());
|
|
455
|
+
|
|
456
|
+
data.increment_size(5);
|
|
457
|
+
EXPECT_EQ(data.size(), 6);
|
|
458
|
+
|
|
459
|
+
data.decrement_size();
|
|
460
|
+
EXPECT_EQ(data.size(), 5);
|
|
461
|
+
|
|
462
|
+
constexpr size_t kHugeIncrement =
|
|
463
|
+
(size_t(1) << (sizeof(size_t) == 4 ? 31 : 42));
|
|
464
|
+
data.increment_size(kHugeIncrement);
|
|
465
|
+
EXPECT_EQ(data.size(), kHugeIncrement + 5);
|
|
466
|
+
|
|
467
|
+
EXPECT_FALSE(data.has_infoz());
|
|
468
|
+
data.set_has_infoz();
|
|
469
|
+
data.set_size(10);
|
|
470
|
+
EXPECT_EQ(data.size(), 10);
|
|
471
|
+
EXPECT_TRUE(data.has_infoz());
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
TYPED_TEST(HashtableDataTest, HashtableInlineDataMetadata) {
|
|
475
|
+
constexpr HashtableCapacityStorageMode kMode = TypeParam::value;
|
|
476
|
+
using InlineData = HashtableInlineDataImpl<kMode>;
|
|
477
|
+
using Capacity = HashtableCapacityImpl<kMode>;
|
|
478
|
+
|
|
479
|
+
InlineData data(Capacity(0), no_seed_empty_tag_t{});
|
|
480
|
+
|
|
481
|
+
// SOO sampling (test this first before seed messes with bit 0)
|
|
482
|
+
EXPECT_FALSE(data.soo_has_tried_sampling());
|
|
483
|
+
data.set_soo_has_tried_sampling();
|
|
484
|
+
EXPECT_TRUE(data.soo_has_tried_sampling());
|
|
485
|
+
|
|
486
|
+
data.set_no_seed_for_testing();
|
|
487
|
+
EXPECT_EQ(data.seed().seed(), 0);
|
|
488
|
+
|
|
489
|
+
data.set_sampled_seed();
|
|
490
|
+
EXPECT_TRUE(data.is_sampled_seed());
|
|
491
|
+
|
|
492
|
+
// Infoz
|
|
493
|
+
EXPECT_FALSE(data.has_infoz());
|
|
494
|
+
data.set_has_infoz();
|
|
495
|
+
EXPECT_TRUE(data.has_infoz());
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
TYPED_TEST(HashtableDataTest, HashtableInlineDataFullSooConstructor) {
|
|
499
|
+
constexpr HashtableCapacityStorageMode kMode = TypeParam::value;
|
|
500
|
+
using InlineData = HashtableInlineDataImpl<kMode>;
|
|
501
|
+
using Capacity = HashtableCapacityImpl<kMode>;
|
|
502
|
+
|
|
503
|
+
{
|
|
504
|
+
InlineData data_soo(Capacity(1), full_soo_tag_t{},
|
|
505
|
+
/*has_tried_sampling=*/true);
|
|
506
|
+
EXPECT_EQ(data_soo.capacity().capacity(), 1);
|
|
507
|
+
EXPECT_EQ(data_soo.size(), 1);
|
|
508
|
+
EXPECT_TRUE(data_soo.soo_has_tried_sampling());
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
{
|
|
512
|
+
InlineData data_soo(Capacity(1), full_soo_tag_t{},
|
|
513
|
+
/*has_tried_sampling=*/false);
|
|
514
|
+
EXPECT_EQ(data_soo.capacity().capacity(), 1);
|
|
515
|
+
EXPECT_EQ(data_soo.size(), 1);
|
|
516
|
+
EXPECT_FALSE(data_soo.soo_has_tried_sampling());
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
TYPED_TEST(HashtableDataTest, GenerateNewSeedDoesntChangeSize) {
|
|
521
|
+
constexpr HashtableCapacityStorageMode kMode = TypeParam::value;
|
|
522
|
+
using InlineData = HashtableInlineDataImpl<kMode>;
|
|
523
|
+
using Capacity = HashtableCapacityImpl<kMode>;
|
|
524
|
+
size_t size = 1;
|
|
525
|
+
do {
|
|
526
|
+
InlineData inline_data(Capacity(15), no_seed_empty_tag_t{});
|
|
527
|
+
inline_data.increment_size(size);
|
|
528
|
+
EXPECT_EQ(inline_data.size(), size);
|
|
529
|
+
inline_data.generate_new_seed();
|
|
530
|
+
EXPECT_EQ(inline_data.size(), size);
|
|
531
|
+
size = size * 2 + 1;
|
|
532
|
+
} while (size < std::min(MaxStorableSize(),
|
|
533
|
+
MaxSizeAtMaxValidCapacity(/*slot_size=*/1)));
|
|
534
|
+
}
|
|
535
|
+
|
|
354
536
|
TEST(Batch, DropDeletes) {
|
|
355
537
|
constexpr size_t kCapacity = 63;
|
|
356
538
|
constexpr size_t kGroupWidth = container_internal::Group::kWidth;
|
|
@@ -388,13 +570,13 @@ struct ValuePolicy {
|
|
|
388
570
|
|
|
389
571
|
template <class Allocator, class... Args>
|
|
390
572
|
static void construct(Allocator* alloc, slot_type* slot, Args&&... args) {
|
|
391
|
-
|
|
392
|
-
|
|
573
|
+
std::allocator_traits<Allocator>::construct(*alloc, slot,
|
|
574
|
+
std::forward<Args>(args)...);
|
|
393
575
|
}
|
|
394
576
|
|
|
395
577
|
template <class Allocator>
|
|
396
578
|
static void destroy(Allocator* alloc, slot_type* slot) {
|
|
397
|
-
|
|
579
|
+
std::allocator_traits<Allocator>::destroy(*alloc, slot);
|
|
398
580
|
}
|
|
399
581
|
|
|
400
582
|
template <class Allocator>
|
|
@@ -745,12 +927,20 @@ TEST(Table, EmptyFunctorOptimization) {
|
|
|
745
927
|
static_assert(std::is_empty<std::equal_to<absl::string_view>>::value, "");
|
|
746
928
|
static_assert(std::is_empty<std::allocator<int>>::value, "");
|
|
747
929
|
|
|
748
|
-
struct
|
|
930
|
+
struct MockTableByValue {
|
|
749
931
|
size_t capacity;
|
|
750
932
|
uint64_t size;
|
|
751
933
|
void* ctrl;
|
|
752
934
|
void* slots;
|
|
753
935
|
};
|
|
936
|
+
struct MockTableByLog {
|
|
937
|
+
uint64_t size;
|
|
938
|
+
void* ctrl;
|
|
939
|
+
void* slots;
|
|
940
|
+
};
|
|
941
|
+
using MockTable =
|
|
942
|
+
std::conditional_t<HashtableInlineData::kStorageMode == kCapacityByValue,
|
|
943
|
+
MockTableByValue, MockTableByLog>;
|
|
754
944
|
struct StatelessHash {
|
|
755
945
|
size_t operator()(absl::string_view) const { return 0; }
|
|
756
946
|
};
|
|
@@ -975,6 +1165,101 @@ TYPED_TEST(SooTest, InsertWithinCapacity) {
|
|
|
975
1165
|
EXPECT_THAT(addr(0), original_addr_0);
|
|
976
1166
|
}
|
|
977
1167
|
|
|
1168
|
+
TYPED_TEST(SooTest, ClearDifferentSizes) {
|
|
1169
|
+
for (size_t size = 0; size < 32; ++size) {
|
|
1170
|
+
for (bool reserve : {false, true}) {
|
|
1171
|
+
for (bool clear_via_erase : {false, true}) {
|
|
1172
|
+
SCOPED_TRACE(absl::StrCat("size: ", size, ", reserve: ", reserve,
|
|
1173
|
+
", clear_via_erase: ", clear_via_erase));
|
|
1174
|
+
TypeParam t;
|
|
1175
|
+
if (reserve) {
|
|
1176
|
+
t.reserve(size);
|
|
1177
|
+
}
|
|
1178
|
+
for (size_t i = 0; i < size; ++i) {
|
|
1179
|
+
ASSERT_TRUE(t.insert(static_cast<int>(i)).second) << i;
|
|
1180
|
+
}
|
|
1181
|
+
if (clear_via_erase) {
|
|
1182
|
+
t.erase(t.begin(), t.end());
|
|
1183
|
+
} else {
|
|
1184
|
+
t.clear();
|
|
1185
|
+
}
|
|
1186
|
+
ASSERT_EQ(t.size(), 0);
|
|
1187
|
+
for (size_t i = 0; i < size; ++i) {
|
|
1188
|
+
ASSERT_TRUE(t.insert(static_cast<int>(i)).second) << i;
|
|
1189
|
+
}
|
|
1190
|
+
}
|
|
1191
|
+
}
|
|
1192
|
+
}
|
|
1193
|
+
}
|
|
1194
|
+
|
|
1195
|
+
TYPED_TEST(SooTest, ReserveTwice) {
|
|
1196
|
+
for (size_t reserve_size = 0; reserve_size < 32; ++reserve_size) {
|
|
1197
|
+
for (size_t reserve_size2 = reserve_size; reserve_size2 < 32;
|
|
1198
|
+
++reserve_size2) {
|
|
1199
|
+
SCOPED_TRACE(absl::StrCat("reserve_size: ", reserve_size,
|
|
1200
|
+
", reserve_size2: ", reserve_size2));
|
|
1201
|
+
TypeParam t;
|
|
1202
|
+
t.reserve(reserve_size);
|
|
1203
|
+
{ // Insert first batch of elements.
|
|
1204
|
+
size_t cap = t.capacity();
|
|
1205
|
+
for (size_t i = 0; i < reserve_size; ++i) {
|
|
1206
|
+
ASSERT_TRUE(t.insert(static_cast<int>(i)).second) << i;
|
|
1207
|
+
}
|
|
1208
|
+
ASSERT_EQ(t.capacity(), cap);
|
|
1209
|
+
}
|
|
1210
|
+
t.reserve(reserve_size2);
|
|
1211
|
+
{ // Insert second batch of elements.
|
|
1212
|
+
size_t cap = t.capacity();
|
|
1213
|
+
for (size_t i = reserve_size; i < reserve_size2; ++i) {
|
|
1214
|
+
ASSERT_TRUE(t.insert(static_cast<int>(i)).second) << i;
|
|
1215
|
+
}
|
|
1216
|
+
ASSERT_EQ(t.capacity(), cap);
|
|
1217
|
+
}
|
|
1218
|
+
for (size_t i = 0; i < reserve_size2; ++i) {
|
|
1219
|
+
ASSERT_TRUE(t.contains(static_cast<int>(i))) << i;
|
|
1220
|
+
}
|
|
1221
|
+
}
|
|
1222
|
+
}
|
|
1223
|
+
}
|
|
1224
|
+
|
|
1225
|
+
TYPED_TEST(SooTest, GrowAfterReserve) {
|
|
1226
|
+
for (size_t reserve_size = 1; reserve_size <= 150; ++reserve_size) {
|
|
1227
|
+
size_t size = reserve_size + 1;
|
|
1228
|
+
TypeParam s;
|
|
1229
|
+
s.reserve(reserve_size);
|
|
1230
|
+
for (size_t i = 0; i < size; ++i) {
|
|
1231
|
+
ASSERT_TRUE(s.insert(static_cast<int>(i)).second) << i;
|
|
1232
|
+
}
|
|
1233
|
+
EXPECT_EQ(s.size(), size);
|
|
1234
|
+
for (size_t i = 0; i < size; ++i) {
|
|
1235
|
+
ASSERT_TRUE(s.contains(static_cast<int>(i))) << i;
|
|
1236
|
+
}
|
|
1237
|
+
}
|
|
1238
|
+
}
|
|
1239
|
+
|
|
1240
|
+
TYPED_TEST(SooTest, ClearAfterReserve) {
|
|
1241
|
+
for (size_t reserve_size :
|
|
1242
|
+
std::vector<size_t>{1, 3, 4, 6, 7, 8, 13, 14, 15, 128, 150}) {
|
|
1243
|
+
TypeParam s;
|
|
1244
|
+
s.reserve(reserve_size);
|
|
1245
|
+
for (size_t i = 0; i < reserve_size; ++i) {
|
|
1246
|
+
ASSERT_TRUE(s.insert(static_cast<int>(i)).second);
|
|
1247
|
+
}
|
|
1248
|
+
EXPECT_EQ(s.size(), reserve_size);
|
|
1249
|
+
s.clear();
|
|
1250
|
+
EXPECT_EQ(s.size(), 0);
|
|
1251
|
+
for (size_t i = 0; i < reserve_size; ++i) {
|
|
1252
|
+
ASSERT_FALSE(s.contains(static_cast<int>(i))) << i;
|
|
1253
|
+
}
|
|
1254
|
+
for (size_t i = 0; i < reserve_size; ++i) {
|
|
1255
|
+
ASSERT_TRUE(s.insert(static_cast<int>(i)).second) << i;
|
|
1256
|
+
}
|
|
1257
|
+
for (size_t i = 0; i < reserve_size; ++i) {
|
|
1258
|
+
ASSERT_TRUE(s.contains(static_cast<int>(i))) << i;
|
|
1259
|
+
}
|
|
1260
|
+
}
|
|
1261
|
+
}
|
|
1262
|
+
|
|
978
1263
|
template <class TableType>
|
|
979
1264
|
class SmallTableResizeTest : public testing::Test {};
|
|
980
1265
|
|
|
@@ -2307,7 +2592,7 @@ TEST(Table, NoThrowMoveAssign) {
|
|
|
2307
2592
|
std::is_nothrow_move_assignable<std::equal_to<absl::string_view>>::value);
|
|
2308
2593
|
ASSERT_TRUE(std::is_nothrow_move_assignable<std::allocator<int>>::value);
|
|
2309
2594
|
ASSERT_TRUE(
|
|
2310
|
-
|
|
2595
|
+
std::allocator_traits<std::allocator<int>>::is_always_equal::value);
|
|
2311
2596
|
EXPECT_TRUE(std::is_nothrow_move_assignable<StringTable>::value);
|
|
2312
2597
|
}
|
|
2313
2598
|
|
|
@@ -2383,7 +2668,7 @@ template <template <typename> class C, class Table, class = void>
|
|
|
2383
2668
|
struct VerifyResultOf : std::false_type {};
|
|
2384
2669
|
|
|
2385
2670
|
template <template <typename> class C, class Table>
|
|
2386
|
-
struct VerifyResultOf<C, Table,
|
|
2671
|
+
struct VerifyResultOf<C, Table, std::void_t<C<Table>>> : std::true_type {};
|
|
2387
2672
|
|
|
2388
2673
|
TEST(Table, HeterogeneousLookupOverloads) {
|
|
2389
2674
|
using NonTransparentTable =
|
|
@@ -2582,6 +2867,18 @@ TYPED_TEST(SooTest, HintInsert) {
|
|
|
2582
2867
|
EXPECT_TRUE(node); // NOLINT(bugprone-use-after-move)
|
|
2583
2868
|
}
|
|
2584
2869
|
|
|
2870
|
+
TYPED_TEST(SooTest, RehashZeroForSmallTable) {
|
|
2871
|
+
TypeParam t{0};
|
|
2872
|
+
EXPECT_EQ(t.capacity(), 1);
|
|
2873
|
+
t.rehash(0);
|
|
2874
|
+
EXPECT_EQ(t.capacity(), 1);
|
|
2875
|
+
EXPECT_TRUE(t.contains(0));
|
|
2876
|
+
t.insert(1);
|
|
2877
|
+
EXPECT_EQ(t.capacity(), NextCapacity(1));
|
|
2878
|
+
EXPECT_TRUE(t.contains(0));
|
|
2879
|
+
EXPECT_TRUE(t.contains(1));
|
|
2880
|
+
}
|
|
2881
|
+
|
|
2585
2882
|
template <typename T>
|
|
2586
2883
|
T MakeSimpleTable(size_t size, bool do_reserve) {
|
|
2587
2884
|
T t;
|
|
@@ -2601,7 +2898,7 @@ std::vector<int> OrderOfIteration(const T& t) {
|
|
|
2601
2898
|
// in seed.
|
|
2602
2899
|
void GenerateIrrelevantSeeds(int cnt) {
|
|
2603
2900
|
for (int i = cnt % 17; i > 0; --i) {
|
|
2604
|
-
|
|
2901
|
+
NextHashTableSeed();
|
|
2605
2902
|
}
|
|
2606
2903
|
}
|
|
2607
2904
|
|
|
@@ -2639,8 +2936,8 @@ TYPED_TEST(SooTest, IterationOrderChangesOnRehash) {
|
|
|
2639
2936
|
for (bool do_reserve : {false, true}) {
|
|
2640
2937
|
for (size_t size : {2u, 3u, 6u, 7u, 12u, 15u, 20u, 50u}) {
|
|
2641
2938
|
for (size_t rehash_size : {
|
|
2642
|
-
size_t{0},
|
|
2643
|
-
size * 10
|
|
2939
|
+
size_t{0}, // Force rehash is guaranteed.
|
|
2940
|
+
size * 10 // Rehash to the larger capacity is guaranteed.
|
|
2644
2941
|
}) {
|
|
2645
2942
|
SCOPED_TRACE(absl::StrCat("size: ", size, " rehash_size: ", rehash_size,
|
|
2646
2943
|
" do_reserve: ", do_reserve));
|
|
@@ -2732,18 +3029,12 @@ TEST(TableDeathTest, InvalidIteratorAssertsSoo) {
|
|
|
2732
3029
|
// the control is static constant.
|
|
2733
3030
|
}
|
|
2734
3031
|
|
|
2735
|
-
// Invalid iterator use can trigger
|
|
2736
|
-
|
|
2737
|
-
|
|
2738
|
-
|
|
2739
|
-
|
|
2740
|
-
|
|
2741
|
-
// MSVC doesn't support | in regex.
|
|
2742
|
-
#if defined(_MSC_VER)
|
|
2743
|
-
constexpr bool kMsvc = true;
|
|
2744
|
-
#else
|
|
2745
|
-
constexpr bool kMsvc = false;
|
|
2746
|
-
#endif
|
|
3032
|
+
// Invalid iterator use can trigger crashes or invalidated iterator assertions.
|
|
3033
|
+
testing::Matcher<const std::string&> InvalidIteratorMatcher() {
|
|
3034
|
+
return AnyOf(HasSubstr("invalidated iterator"), HasSubstr("Invalid iterator"),
|
|
3035
|
+
HasSubstr("invalid iterator"),
|
|
3036
|
+
HasSubstr("CrashIfIteratorIsInvalid"));
|
|
3037
|
+
}
|
|
2747
3038
|
|
|
2748
3039
|
TYPED_TEST(SooTest, IteratorInvalidAssertsEqualityOperator) {
|
|
2749
3040
|
if (!IsAssertEnabled() && !SwisstableGenerationsEnabled())
|
|
@@ -2785,7 +3076,6 @@ TYPED_TEST(SooTest, IteratorInvalidAssertsEqualityOperator) {
|
|
|
2785
3076
|
TYPED_TEST(SooTest, IteratorInvalidAssertsEqualityOperatorRehash) {
|
|
2786
3077
|
if (!IsAssertEnabled() && !SwisstableGenerationsEnabled())
|
|
2787
3078
|
GTEST_SKIP() << "Assertions not enabled.";
|
|
2788
|
-
if (kMsvc) GTEST_SKIP() << "MSVC doesn't support | in regex.";
|
|
2789
3079
|
#ifdef ABSL_HAVE_THREAD_SANITIZER
|
|
2790
3080
|
GTEST_SKIP() << "ThreadSanitizer test runs fail on use-after-free even in "
|
|
2791
3081
|
"EXPECT_DEATH.";
|
|
@@ -2798,11 +3088,20 @@ TYPED_TEST(SooTest, IteratorInvalidAssertsEqualityOperatorRehash) {
|
|
|
2798
3088
|
// Trigger a rehash in t.
|
|
2799
3089
|
for (int i = 0; i < 10; ++i) t.insert(i);
|
|
2800
3090
|
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
|
|
3091
|
+
EXPECT_DEATH_IF_SUPPORTED(void(iter == t.begin()), InvalidIteratorMatcher());
|
|
3092
|
+
}
|
|
3093
|
+
|
|
3094
|
+
TYPED_TEST(SooTest, IteratorInvalidAssertsEqualityOperatorMovedFrom) {
|
|
3095
|
+
if (!SwisstableGenerationsEnabled())
|
|
3096
|
+
GTEST_SKIP() << "Generations not enabled.";
|
|
3097
|
+
|
|
3098
|
+
TypeParam t;
|
|
3099
|
+
for (int i = 0; i < 10; ++i) t.insert(i);
|
|
3100
|
+
auto iter = t.begin();
|
|
3101
|
+
|
|
3102
|
+
TypeParam t2 = std::move(t);
|
|
3103
|
+
|
|
3104
|
+
EXPECT_DEATH_IF_SUPPORTED(void(iter == t2.begin()), InvalidIteratorMatcher());
|
|
2806
3105
|
}
|
|
2807
3106
|
|
|
2808
3107
|
#if defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE)
|
|
@@ -2812,8 +3111,7 @@ class RawHashSamplerTest : public testing::Test {};
|
|
|
2812
3111
|
using RawHashSamplerTestTypes = ::testing::Types<
|
|
2813
3112
|
// 32 bits to make sure that table is Soo for 32 bits platform as well.
|
|
2814
3113
|
// 64 bits table is not SOO due to alignment.
|
|
2815
|
-
SooInt32Table,
|
|
2816
|
-
NonSooIntTable>;
|
|
3114
|
+
SooInt32Table, NonSooIntTable>;
|
|
2817
3115
|
TYPED_TEST_SUITE(RawHashSamplerTest, RawHashSamplerTestTypes);
|
|
2818
3116
|
|
|
2819
3117
|
TYPED_TEST(RawHashSamplerTest, Sample) {
|
|
@@ -2831,7 +3129,6 @@ TYPED_TEST(RawHashSamplerTest, Sample) {
|
|
|
2831
3129
|
absl::flat_hash_set<const HashtablezInfo*> preexisting_info(10);
|
|
2832
3130
|
absl::flat_hash_map<size_t, int> observed_checksums(10);
|
|
2833
3131
|
absl::flat_hash_map<ssize_t, int> reservations(10);
|
|
2834
|
-
absl::flat_hash_map<std::pair<size_t, size_t>, int> hit_misses(10);
|
|
2835
3132
|
|
|
2836
3133
|
start_size += sampler.Iterate([&](const HashtablezInfo& info) {
|
|
2837
3134
|
preexisting_info.insert(&info);
|
|
@@ -2844,8 +3141,6 @@ TYPED_TEST(RawHashSamplerTest, Sample) {
|
|
|
2844
3141
|
|
|
2845
3142
|
const bool do_reserve = (i % 10 > 5);
|
|
2846
3143
|
const bool do_rehash = !do_reserve && (i % 10 > 0);
|
|
2847
|
-
const bool do_first_insert_hit = i % 2 == 0;
|
|
2848
|
-
const bool do_second_insert_hit = i % 4 == 0;
|
|
2849
3144
|
|
|
2850
3145
|
if (do_reserve) {
|
|
2851
3146
|
// Don't reserve on all tables.
|
|
@@ -2853,14 +3148,7 @@ TYPED_TEST(RawHashSamplerTest, Sample) {
|
|
|
2853
3148
|
}
|
|
2854
3149
|
|
|
2855
3150
|
tables.back().insert(1);
|
|
2856
|
-
if (do_first_insert_hit) {
|
|
2857
|
-
tables.back().insert(1);
|
|
2858
|
-
tables.back().insert(1);
|
|
2859
|
-
}
|
|
2860
3151
|
tables.back().insert(i % 5);
|
|
2861
|
-
if (do_second_insert_hit) {
|
|
2862
|
-
tables.back().insert(i % 5);
|
|
2863
|
-
}
|
|
2864
3152
|
|
|
2865
3153
|
if (do_rehash) {
|
|
2866
3154
|
// Rehash some other tables.
|
|
@@ -2872,10 +3160,6 @@ TYPED_TEST(RawHashSamplerTest, Sample) {
|
|
|
2872
3160
|
++end_size;
|
|
2873
3161
|
if (preexisting_info.contains(&info)) return;
|
|
2874
3162
|
reservations[info.max_reserve.load(std::memory_order_relaxed)]++;
|
|
2875
|
-
hit_misses[std::make_pair(
|
|
2876
|
-
info.num_insert_hits.load(std::memory_order_relaxed),
|
|
2877
|
-
info.size.load(std::memory_order_relaxed))]++;
|
|
2878
|
-
|
|
2879
3163
|
EXPECT_EQ(info.inline_element_size, sizeof(typename TypeParam::value_type));
|
|
2880
3164
|
EXPECT_EQ(info.key_size, sizeof(typename TypeParam::key_type));
|
|
2881
3165
|
EXPECT_EQ(info.value_size, sizeof(typename TypeParam::value_type));
|
|
@@ -2899,25 +3183,11 @@ TYPED_TEST(RawHashSamplerTest, Sample) {
|
|
|
2899
3183
|
EXPECT_NEAR((100 * count) / static_cast<double>(tables.size()), 0.1, 0.05)
|
|
2900
3184
|
<< reservation;
|
|
2901
3185
|
}
|
|
2902
|
-
|
|
2903
|
-
EXPECT_THAT(hit_misses, testing::SizeIs(6));
|
|
2904
|
-
const double sampled_tables = end_size - start_size;
|
|
2905
|
-
// i % 20: { 1, 11 }
|
|
2906
|
-
EXPECT_NEAR((hit_misses[{1, 1}] / sampled_tables), 0.10, 0.02);
|
|
2907
|
-
// i % 20: { 6 }
|
|
2908
|
-
EXPECT_NEAR((hit_misses[{3, 1}] / sampled_tables), 0.05, 0.02);
|
|
2909
|
-
// i % 20: { 0, 4, 8, 12 }
|
|
2910
|
-
EXPECT_NEAR((hit_misses[{3, 2}] / sampled_tables), 0.20, 0.02);
|
|
2911
|
-
// i % 20: { 2, 10, 14, 18 }
|
|
2912
|
-
EXPECT_NEAR((hit_misses[{2, 2}] / sampled_tables), 0.20, 0.02);
|
|
2913
|
-
// i % 20: { 16 }
|
|
2914
|
-
EXPECT_NEAR((hit_misses[{4, 1}] / sampled_tables), 0.05, 0.02);
|
|
2915
|
-
// i % 20: { 3, 5, 7, 9, 13, 15, 17, 19 }
|
|
2916
|
-
EXPECT_NEAR((hit_misses[{0, 2}] / sampled_tables), 0.40, 0.02);
|
|
2917
3186
|
}
|
|
2918
3187
|
|
|
2919
|
-
|
|
2920
|
-
|
|
3188
|
+
template <typename IntTableType>
|
|
3189
|
+
std::vector<const HashtablezInfo*> SampleTableMutation(
|
|
3190
|
+
absl::FunctionRef<void(IntTableType&)> mutate_table) {
|
|
2921
3191
|
// Enable the feature even if the prod default is off.
|
|
2922
3192
|
SetSamplingRateTo1Percent();
|
|
2923
3193
|
|
|
@@ -2930,7 +3200,7 @@ std::vector<const HashtablezInfo*> SampleSooMutation(
|
|
|
2930
3200
|
++start_size;
|
|
2931
3201
|
});
|
|
2932
3202
|
|
|
2933
|
-
std::vector<
|
|
3203
|
+
std::vector<IntTableType> tables;
|
|
2934
3204
|
for (int i = 0; i < 1000000; ++i) {
|
|
2935
3205
|
tables.emplace_back();
|
|
2936
3206
|
mutate_table(tables.back());
|
|
@@ -2949,6 +3219,16 @@ std::vector<const HashtablezInfo*> SampleSooMutation(
|
|
|
2949
3219
|
return infos;
|
|
2950
3220
|
}
|
|
2951
3221
|
|
|
3222
|
+
std::vector<const HashtablezInfo*> SampleSooMutation(
|
|
3223
|
+
absl::FunctionRef<void(SooInt32Table&)> mutate_table) {
|
|
3224
|
+
return SampleTableMutation<SooInt32Table>(mutate_table);
|
|
3225
|
+
}
|
|
3226
|
+
|
|
3227
|
+
std::vector<const HashtablezInfo*> SampleNonSooMutation(
|
|
3228
|
+
absl::FunctionRef<void(NonSooIntTable&)> mutate_table) {
|
|
3229
|
+
return SampleTableMutation<NonSooIntTable>(mutate_table);
|
|
3230
|
+
}
|
|
3231
|
+
|
|
2952
3232
|
TEST(RawHashSamplerTest, SooTableInsertToEmpty) {
|
|
2953
3233
|
if (SooInt32Table().capacity() != SooCapacity()) {
|
|
2954
3234
|
CHECK_LT(sizeof(void*), 8) << "missing SOO coverage";
|
|
@@ -2970,6 +3250,86 @@ TEST(RawHashSamplerTest, SooTableInsertToEmpty) {
|
|
|
2970
3250
|
}
|
|
2971
3251
|
}
|
|
2972
3252
|
|
|
3253
|
+
// Verifies that repeated insertions and erasures on an SOO table do not cause
|
|
3254
|
+
// the sampling decision to be evaluated multiple times, preventing
|
|
3255
|
+
// oversampling.
|
|
3256
|
+
TEST(RawHashSamplerTest, SooTableRepeatedInsertEraseDoesNotOversample) {
|
|
3257
|
+
if (SooInt32Table().capacity() != SooCapacity()) {
|
|
3258
|
+
CHECK_LT(sizeof(void*), 8) << "missing SOO coverage";
|
|
3259
|
+
GTEST_SKIP() << "not SOO on this platform";
|
|
3260
|
+
}
|
|
3261
|
+
std::vector<const HashtablezInfo*> infos =
|
|
3262
|
+
SampleSooMutation([](SooInt32Table& t) {
|
|
3263
|
+
for (int i = 0; i < 10; ++i) {
|
|
3264
|
+
t.insert(1);
|
|
3265
|
+
t.erase(1);
|
|
3266
|
+
}
|
|
3267
|
+
});
|
|
3268
|
+
|
|
3269
|
+
// SampleSooMutation checks EXPECT_NEAR(sampled/total, 1%, 0.5%).
|
|
3270
|
+
// If the sampling logic is incorrectly evaluated on every 0->1 element
|
|
3271
|
+
// transition, the chance of being sampled per table approaches 10% (1 -
|
|
3272
|
+
// 0.99^10), which is enough to cause this test to fail. By passing, this test
|
|
3273
|
+
// verifies that the sampling decision is evaluated exactly once per SOO table
|
|
3274
|
+
// instance.
|
|
3275
|
+
}
|
|
3276
|
+
|
|
3277
|
+
TEST(RawHashSamplerTest, NonSooTableRepeatedInsertEraseCountSizeRight) {
|
|
3278
|
+
ASSERT_EQ(NonSooIntTable().capacity(), 0);
|
|
3279
|
+
std::vector<const HashtablezInfo*> infos =
|
|
3280
|
+
SampleNonSooMutation([](NonSooIntTable& t) {
|
|
3281
|
+
for (int i = 0; i < 10; ++i) {
|
|
3282
|
+
t.insert(1);
|
|
3283
|
+
t.erase(1);
|
|
3284
|
+
}
|
|
3285
|
+
});
|
|
3286
|
+
for (const HashtablezInfo* info : infos) {
|
|
3287
|
+
EXPECT_EQ(info->soo_capacity, 0);
|
|
3288
|
+
ASSERT_EQ(info->capacity, 1);
|
|
3289
|
+
ASSERT_EQ(info->size, 0);
|
|
3290
|
+
}
|
|
3291
|
+
}
|
|
3292
|
+
|
|
3293
|
+
// Verifies that copy-constructing or copy-assigning an SOO table does not
|
|
3294
|
+
// incorrectly trigger new sampling evaluations.
|
|
3295
|
+
TEST(RawHashSamplerTest, SooTableCopyDoesNotOversample) {
|
|
3296
|
+
if (SooInt32Table().capacity() != SooCapacity()) {
|
|
3297
|
+
CHECK_LT(sizeof(void*), 8) << "missing SOO coverage";
|
|
3298
|
+
GTEST_SKIP() << "not SOO on this platform";
|
|
3299
|
+
}
|
|
3300
|
+
std::vector<const HashtablezInfo*> infos =
|
|
3301
|
+
SampleSooMutation([](SooInt32Table& t) {
|
|
3302
|
+
t.insert(1);
|
|
3303
|
+
t.erase(1);
|
|
3304
|
+
SooInt32Table t_copy(t);
|
|
3305
|
+
for (int i = 0; i < 10; ++i) {
|
|
3306
|
+
t_copy.insert(1);
|
|
3307
|
+
t_copy.erase(1);
|
|
3308
|
+
}
|
|
3309
|
+
t = std::move(t_copy);
|
|
3310
|
+
});
|
|
3311
|
+
}
|
|
3312
|
+
|
|
3313
|
+
// Verifies that move-constructing or move-assigning an SOO table correctly
|
|
3314
|
+
// transfers the sampling state and does not trigger oversampling.
|
|
3315
|
+
TEST(RawHashSamplerTest, SooTableMoveDoesNotOversample) {
|
|
3316
|
+
if (SooInt32Table().capacity() != SooCapacity()) {
|
|
3317
|
+
CHECK_LT(sizeof(void*), 8) << "missing SOO coverage";
|
|
3318
|
+
GTEST_SKIP() << "not SOO on this platform";
|
|
3319
|
+
}
|
|
3320
|
+
std::vector<const HashtablezInfo*> infos =
|
|
3321
|
+
SampleSooMutation([](SooInt32Table& t) {
|
|
3322
|
+
t.insert(1);
|
|
3323
|
+
t.erase(1);
|
|
3324
|
+
SooInt32Table t_moved(std::move(t));
|
|
3325
|
+
for (int i = 0; i < 10; ++i) {
|
|
3326
|
+
t_moved.insert(1);
|
|
3327
|
+
t_moved.erase(1);
|
|
3328
|
+
}
|
|
3329
|
+
t = std::move(t_moved);
|
|
3330
|
+
});
|
|
3331
|
+
}
|
|
3332
|
+
|
|
2973
3333
|
TEST(RawHashSamplerTest, SooTableReserveToEmpty) {
|
|
2974
3334
|
if (SooInt32Table().capacity() != SooCapacity()) {
|
|
2975
3335
|
CHECK_LT(sizeof(void*), 8) << "missing SOO coverage";
|
|
@@ -3027,9 +3387,7 @@ TEST(RawHashSamplerTest, SooTableSampleOnCopy) {
|
|
|
3027
3387
|
t_orig.insert(1);
|
|
3028
3388
|
|
|
3029
3389
|
std::vector<const HashtablezInfo*> infos =
|
|
3030
|
-
SampleSooMutation([&t_orig](SooInt32Table& t) {
|
|
3031
|
-
t = t_orig;
|
|
3032
|
-
});
|
|
3390
|
+
SampleSooMutation([&t_orig](SooInt32Table& t) { t = t_orig; });
|
|
3033
3391
|
|
|
3034
3392
|
for (const HashtablezInfo* info : infos) {
|
|
3035
3393
|
ASSERT_EQ(info->inline_element_size,
|
|
@@ -3067,6 +3425,63 @@ TEST(RawHashSamplerTest, SooTableRehashShrinkWhenSizeFitsInSoo) {
|
|
|
3067
3425
|
ASSERT_EQ(info->total_probe_length, 0);
|
|
3068
3426
|
}
|
|
3069
3427
|
}
|
|
3428
|
+
|
|
3429
|
+
// Verifies that a moved-from table does not retain the sampled state of the
|
|
3430
|
+
// original table, allowing it to be used without incorrectly updating global
|
|
3431
|
+
// sampling stats.
|
|
3432
|
+
TEST(RawHashSamplerTest, MovedFromTableIsNotSampled) {
|
|
3433
|
+
if (SooInt32Table().capacity() != SooCapacity()) {
|
|
3434
|
+
CHECK_LT(sizeof(void*), 8) << "missing SOO coverage";
|
|
3435
|
+
GTEST_SKIP() << "not SOO on this platform";
|
|
3436
|
+
}
|
|
3437
|
+
|
|
3438
|
+
SetSamplingRateTo1Percent();
|
|
3439
|
+
auto& sampler = GlobalHashtablezSampler();
|
|
3440
|
+
size_t start_size = 0;
|
|
3441
|
+
absl::flat_hash_set<const HashtablezInfo*> preexisting_info;
|
|
3442
|
+
sampler.Iterate([&](const HashtablezInfo& info) {
|
|
3443
|
+
preexisting_info.insert(&info);
|
|
3444
|
+
++start_size;
|
|
3445
|
+
});
|
|
3446
|
+
|
|
3447
|
+
SooInt32Table t1;
|
|
3448
|
+
// Loop until t1 is sampled
|
|
3449
|
+
while (true) {
|
|
3450
|
+
t1 = SooInt32Table();
|
|
3451
|
+
t1.insert(1);
|
|
3452
|
+
size_t new_size = 0;
|
|
3453
|
+
sampler.Iterate([&](const HashtablezInfo&) { ++new_size; });
|
|
3454
|
+
if (new_size > start_size) break;
|
|
3455
|
+
}
|
|
3456
|
+
|
|
3457
|
+
// Move the table
|
|
3458
|
+
SooInt32Table t2 = std::move(t1);
|
|
3459
|
+
|
|
3460
|
+
// Disable sampling to ensure any new sampling is a bug.
|
|
3461
|
+
SetHashtablezEnabled(false);
|
|
3462
|
+
|
|
3463
|
+
// t2 is now the sampled table. t1 is moved-from.
|
|
3464
|
+
// We want to verify that t2 is still sampled, and that t1 isn't sampled
|
|
3465
|
+
// anymore, even if we insert a new entry into it.
|
|
3466
|
+
t1.clear(); // Must clear before using a moved-from table.
|
|
3467
|
+
t1.insert(2);
|
|
3468
|
+
t2.insert(2);
|
|
3469
|
+
|
|
3470
|
+
// Verify no new sample was generated, and t2's sample size is now 2.
|
|
3471
|
+
size_t final_size = 0;
|
|
3472
|
+
const HashtablezInfo* latest_info = nullptr;
|
|
3473
|
+
size_t dropped = sampler.Iterate([&](const HashtablezInfo& info) {
|
|
3474
|
+
++final_size;
|
|
3475
|
+
if (!preexisting_info.contains(&info)) {
|
|
3476
|
+
latest_info = &info;
|
|
3477
|
+
}
|
|
3478
|
+
});
|
|
3479
|
+
EXPECT_EQ(0, dropped);
|
|
3480
|
+
EXPECT_EQ(final_size, start_size + 1);
|
|
3481
|
+
ASSERT_NE(latest_info, nullptr);
|
|
3482
|
+
EXPECT_EQ(latest_info->size.load(std::memory_order_relaxed), 2);
|
|
3483
|
+
}
|
|
3484
|
+
|
|
3070
3485
|
#endif // ABSL_INTERNAL_HASHTABLEZ_SAMPLE
|
|
3071
3486
|
|
|
3072
3487
|
TEST(RawHashSamplerTest, DoNotSampleCustomAllocators) {
|
|
@@ -3177,7 +3592,6 @@ TYPED_TEST(AlignOneTest, AlignOne) {
|
|
|
3177
3592
|
|
|
3178
3593
|
TEST(Iterator, InvalidUseCrashesWithSanitizers) {
|
|
3179
3594
|
if (!SwisstableGenerationsEnabled()) GTEST_SKIP() << "Generations disabled.";
|
|
3180
|
-
if (kMsvc) GTEST_SKIP() << "MSVC doesn't support | in regexp.";
|
|
3181
3595
|
|
|
3182
3596
|
NonSooIntTable t;
|
|
3183
3597
|
// Start with 1 element so that `it` is never an end iterator.
|
|
@@ -3185,15 +3599,13 @@ TEST(Iterator, InvalidUseCrashesWithSanitizers) {
|
|
|
3185
3599
|
for (int i = 0; i < 10; ++i) {
|
|
3186
3600
|
auto it = t.begin();
|
|
3187
3601
|
t.insert(i);
|
|
3188
|
-
EXPECT_DEATH_IF_SUPPORTED(*it,
|
|
3189
|
-
EXPECT_DEATH_IF_SUPPORTED(void(it == t.begin()),
|
|
3190
|
-
kInvalidIteratorDeathMessage);
|
|
3602
|
+
EXPECT_DEATH_IF_SUPPORTED(*it, InvalidIteratorMatcher());
|
|
3603
|
+
EXPECT_DEATH_IF_SUPPORTED(void(it == t.begin()), InvalidIteratorMatcher());
|
|
3191
3604
|
}
|
|
3192
3605
|
}
|
|
3193
3606
|
|
|
3194
3607
|
TEST(Iterator, InvalidUseWithReserveCrashesWithSanitizers) {
|
|
3195
3608
|
if (!SwisstableGenerationsEnabled()) GTEST_SKIP() << "Generations disabled.";
|
|
3196
|
-
if (kMsvc) GTEST_SKIP() << "MSVC doesn't support | in regexp.";
|
|
3197
3609
|
|
|
3198
3610
|
IntTable t;
|
|
3199
3611
|
t.reserve(10);
|
|
@@ -3214,9 +3626,8 @@ TEST(Iterator, InvalidUseWithReserveCrashesWithSanitizers) {
|
|
|
3214
3626
|
// The first insert after reserved growth is 0 is guaranteed to rehash when
|
|
3215
3627
|
// generations are enabled.
|
|
3216
3628
|
t.insert(10);
|
|
3217
|
-
EXPECT_DEATH_IF_SUPPORTED(*it,
|
|
3218
|
-
EXPECT_DEATH_IF_SUPPORTED(void(it == t.begin()),
|
|
3219
|
-
kInvalidIteratorDeathMessage);
|
|
3629
|
+
EXPECT_DEATH_IF_SUPPORTED(*it, InvalidIteratorMatcher());
|
|
3630
|
+
EXPECT_DEATH_IF_SUPPORTED(void(it == t.begin()), InvalidIteratorMatcher());
|
|
3220
3631
|
#ifdef ABSL_HAVE_ADDRESS_SANITIZER
|
|
3221
3632
|
EXPECT_DEATH_IF_SUPPORTED(std::cout << *ptr, "heap-use-after-free");
|
|
3222
3633
|
#endif
|
|
@@ -3224,7 +3635,6 @@ TEST(Iterator, InvalidUseWithReserveCrashesWithSanitizers) {
|
|
|
3224
3635
|
|
|
3225
3636
|
TEST(Iterator, InvalidUseWithMoveCrashesWithSanitizers) {
|
|
3226
3637
|
if (!SwisstableGenerationsEnabled()) GTEST_SKIP() << "Generations disabled.";
|
|
3227
|
-
if (kMsvc) GTEST_SKIP() << "MSVC doesn't support | in regexp.";
|
|
3228
3638
|
|
|
3229
3639
|
NonSooIntTable t1, t2;
|
|
3230
3640
|
t1.insert(1);
|
|
@@ -3234,9 +3644,8 @@ TEST(Iterator, InvalidUseWithMoveCrashesWithSanitizers) {
|
|
|
3234
3644
|
(void)ptr;
|
|
3235
3645
|
|
|
3236
3646
|
t2 = std::move(t1);
|
|
3237
|
-
EXPECT_DEATH_IF_SUPPORTED(*it,
|
|
3238
|
-
EXPECT_DEATH_IF_SUPPORTED(void(it == t2.begin()),
|
|
3239
|
-
kInvalidIteratorDeathMessage);
|
|
3647
|
+
EXPECT_DEATH_IF_SUPPORTED(*it, InvalidIteratorMatcher());
|
|
3648
|
+
EXPECT_DEATH_IF_SUPPORTED(void(it == t2.begin()), InvalidIteratorMatcher());
|
|
3240
3649
|
#ifdef ABSL_HAVE_ADDRESS_SANITIZER
|
|
3241
3650
|
EXPECT_DEATH_IF_SUPPORTED(std::cout << **ptr, "heap-use-after-free");
|
|
3242
3651
|
#endif
|
|
@@ -3491,7 +3900,6 @@ TEST(Table, EraseBeginEndResetsReservedGrowth) {
|
|
|
3491
3900
|
|
|
3492
3901
|
TEST(Table, GenerationInfoResetsOnClear) {
|
|
3493
3902
|
if (!SwisstableGenerationsEnabled()) GTEST_SKIP() << "Generations disabled.";
|
|
3494
|
-
if (kMsvc) GTEST_SKIP() << "MSVC doesn't support | in regexp.";
|
|
3495
3903
|
|
|
3496
3904
|
NonSooIntTable t;
|
|
3497
3905
|
for (int i = 0; i < 1000; ++i) t.insert(i);
|
|
@@ -3502,7 +3910,7 @@ TEST(Table, GenerationInfoResetsOnClear) {
|
|
|
3502
3910
|
t.insert(0);
|
|
3503
3911
|
auto it = t.begin();
|
|
3504
3912
|
t.insert(1);
|
|
3505
|
-
EXPECT_DEATH_IF_SUPPORTED(*it,
|
|
3913
|
+
EXPECT_DEATH_IF_SUPPORTED(*it, InvalidIteratorMatcher());
|
|
3506
3914
|
}
|
|
3507
3915
|
|
|
3508
3916
|
TEST(Table, InvalidReferenceUseCrashesWithSanitizers) {
|
|
@@ -3869,7 +4277,7 @@ struct DestroyCaller {
|
|
|
3869
4277
|
~DestroyCaller() {
|
|
3870
4278
|
if (destroy_func) (*destroy_func)();
|
|
3871
4279
|
}
|
|
3872
|
-
void Deactivate() { destroy_func =
|
|
4280
|
+
void Deactivate() { destroy_func = std::nullopt; }
|
|
3873
4281
|
|
|
3874
4282
|
template <typename H>
|
|
3875
4283
|
friend H AbslHashValue(H h, const DestroyCaller& d) {
|
|
@@ -3878,7 +4286,7 @@ struct DestroyCaller {
|
|
|
3878
4286
|
bool operator==(const DestroyCaller& d) const { return val == d.val; }
|
|
3879
4287
|
|
|
3880
4288
|
int val;
|
|
3881
|
-
|
|
4289
|
+
std::optional<absl::FunctionRef<void()>> destroy_func;
|
|
3882
4290
|
};
|
|
3883
4291
|
|
|
3884
4292
|
TEST(Table, ReentrantCallsFail) {
|
|
@@ -3912,7 +4320,6 @@ TEST(Table, ReentrantCallsFail) {
|
|
|
3912
4320
|
#endif
|
|
3913
4321
|
}
|
|
3914
4322
|
|
|
3915
|
-
// TODO(b/328794765): this check is very useful to run with ASAN in opt mode.
|
|
3916
4323
|
TEST(Table, DestroyedCallsFail) {
|
|
3917
4324
|
#ifdef NDEBUG
|
|
3918
4325
|
ASSERT_EQ(SwisstableAssertAccessToDestroyedTable(),
|
|
@@ -3925,19 +4332,21 @@ TEST(Table, DestroyedCallsFail) {
|
|
|
3925
4332
|
}
|
|
3926
4333
|
#if !defined(__clang__) && defined(__GNUC__)
|
|
3927
4334
|
GTEST_SKIP() << "Flaky on GCC.";
|
|
3928
|
-
#
|
|
3929
|
-
|
|
4335
|
+
#elif defined(ABSL_HAVE_THREAD_SANITIZER)
|
|
4336
|
+
GTEST_SKIP() << "Fails on TSan.";
|
|
4337
|
+
// Note: we use else rather than endif here to avoid unreachable code errors.
|
|
4338
|
+
#else
|
|
4339
|
+
std::optional<IntTable> t;
|
|
3930
4340
|
t.emplace({1});
|
|
3931
4341
|
IntTable* t_ptr = &*t;
|
|
3932
4342
|
EXPECT_TRUE(t_ptr->contains(1));
|
|
3933
4343
|
t.reset();
|
|
3934
|
-
|
|
3935
|
-
|
|
3936
|
-
"use-
|
|
3937
|
-
|
|
3938
|
-
|
|
3939
|
-
#endif
|
|
3940
|
-
EXPECT_DEATH_IF_SUPPORTED(t_ptr->contains(1), expected_death_message);
|
|
4344
|
+
EXPECT_DEATH_IF_SUPPORTED(
|
|
4345
|
+
t_ptr->contains(1),
|
|
4346
|
+
AnyOf(HasSubstr("destroyed hash table"), HasSubstr("use-after-free"),
|
|
4347
|
+
HasSubstr("use-of-uninitialized-value")));
|
|
4348
|
+
|
|
4349
|
+
#endif // ABSL_HAVE_THREAD_SANITIZER
|
|
3941
4350
|
}
|
|
3942
4351
|
|
|
3943
4352
|
TEST(Table, DestroyedCallsFailDuringDestruction) {
|
|
@@ -3946,6 +4355,10 @@ TEST(Table, DestroyedCallsFailDuringDestruction) {
|
|
|
3946
4355
|
}
|
|
3947
4356
|
#if !defined(__clang__) && defined(__GNUC__)
|
|
3948
4357
|
GTEST_SKIP() << "Flaky on GCC.";
|
|
4358
|
+
#endif
|
|
4359
|
+
#if defined(ABSL_HAVE_ADDRESS_SANITIZER) && defined(NDEBUG)
|
|
4360
|
+
// TODO(b/487002780): see if we can re-enable this test in opt-ASan mode.
|
|
4361
|
+
GTEST_SKIP() << "Fails to die in opt ASAN.";
|
|
3949
4362
|
#endif
|
|
3950
4363
|
// When EXPECT_DEATH_IF_SUPPORTED is not executed, the code after it is not
|
|
3951
4364
|
// executed as well.
|
|
@@ -3954,7 +4367,7 @@ TEST(Table, DestroyedCallsFailDuringDestruction) {
|
|
|
3954
4367
|
bool do_lookup = false;
|
|
3955
4368
|
|
|
3956
4369
|
using Table = absl::flat_hash_map<int, std::shared_ptr<int>>;
|
|
3957
|
-
|
|
4370
|
+
std::optional<Table> t = Table();
|
|
3958
4371
|
Table* t_ptr = &*t;
|
|
3959
4372
|
auto destroy = [&](int* ptr) {
|
|
3960
4373
|
if (do_lookup) {
|
|
@@ -3967,13 +4380,9 @@ TEST(Table, DestroyedCallsFailDuringDestruction) {
|
|
|
3967
4380
|
do_lookup = true;
|
|
3968
4381
|
t.reset();
|
|
3969
4382
|
};
|
|
3970
|
-
|
|
3971
|
-
|
|
3972
|
-
|
|
3973
|
-
#else
|
|
3974
|
-
"Reentrant container access";
|
|
3975
|
-
#endif
|
|
3976
|
-
EXPECT_DEATH_IF_SUPPORTED(destroy_with_lookup(), expected_death_message);
|
|
4383
|
+
EXPECT_DEATH_IF_SUPPORTED(destroy_with_lookup(),
|
|
4384
|
+
AnyOf(HasSubstr("destroyed hash table"),
|
|
4385
|
+
HasSubstr("Reentrant container access")));
|
|
3977
4386
|
}
|
|
3978
4387
|
|
|
3979
4388
|
TEST(Table, MovedFromCallsFail) {
|
|
@@ -4021,73 +4430,87 @@ TEST(Table, MovedFromCallsFail) {
|
|
|
4021
4430
|
}
|
|
4022
4431
|
}
|
|
4023
4432
|
|
|
4024
|
-
TEST(HashtableSize, GenerateNewSeedDoesntChangeSize) {
|
|
4025
|
-
size_t size = 1;
|
|
4026
|
-
do {
|
|
4027
|
-
HashtableSize hs(no_seed_empty_tag_t{});
|
|
4028
|
-
hs.increment_size(size);
|
|
4029
|
-
EXPECT_EQ(hs.size(), size);
|
|
4030
|
-
hs.generate_new_seed();
|
|
4031
|
-
EXPECT_EQ(hs.size(), size);
|
|
4032
|
-
size = size * 2 + 1;
|
|
4033
|
-
} while (size < MaxValidSizeFor1ByteSlot());
|
|
4034
|
-
}
|
|
4035
|
-
|
|
4036
4433
|
TEST(Table, MaxValidSize) {
|
|
4037
4434
|
IntTable t;
|
|
4038
|
-
EXPECT_EQ(
|
|
4435
|
+
EXPECT_EQ(
|
|
4436
|
+
MaxValidSize(sizeof(IntTable::key_type), sizeof(IntTable::value_type)),
|
|
4437
|
+
t.max_size());
|
|
4039
4438
|
if constexpr (sizeof(size_t) == 8) {
|
|
4040
4439
|
for (size_t i = 0; i < 35; ++i) {
|
|
4041
4440
|
SCOPED_TRACE(i);
|
|
4042
4441
|
size_t slot_size = size_t{1} << i;
|
|
4043
|
-
size_t
|
|
4044
|
-
|
|
4045
|
-
ASSERT_TRUE(IsAboveValidSize(max_size + 1, slot_size));
|
|
4442
|
+
size_t key_size = slot_size;
|
|
4443
|
+
size_t max_size = MaxValidSize(key_size, slot_size);
|
|
4046
4444
|
ASSERT_LT(max_size, uint64_t{1} << 60);
|
|
4047
|
-
|
|
4048
|
-
|
|
4049
|
-
|
|
4445
|
+
if (key_size <= 4) {
|
|
4446
|
+
ASSERT_EQ(max_size, uint64_t{1} << 8 * key_size);
|
|
4447
|
+
} else if (i <= 21) {
|
|
4050
4448
|
ASSERT_GE(max_size, uint64_t{1} << 40);
|
|
4051
4449
|
}
|
|
4052
|
-
|
|
4053
|
-
uint64_t{1} << HashtableSize::kSizeBitCount);
|
|
4450
|
+
ASSERT_LE(max_size, uint64_t{1} << HashtableInlineData::kSizeBitCount);
|
|
4054
4451
|
ASSERT_LT(absl::uint128(max_size) * slot_size, uint64_t{1} << 63);
|
|
4055
4452
|
}
|
|
4056
4453
|
}
|
|
4057
|
-
EXPECT_LT(MaxValidSize</*kSizeOfSizeT=*/4>(1), 1 << 30);
|
|
4058
|
-
EXPECT_LT(MaxValidSize</*kSizeOfSizeT=*/4>(2), 1 << 29);
|
|
4454
|
+
EXPECT_LT(MaxValidSize</*kSizeOfSizeT=*/4>(1, 1), 1 << 30);
|
|
4455
|
+
EXPECT_LT(MaxValidSize</*kSizeOfSizeT=*/4>(2, 2), 1 << 29);
|
|
4059
4456
|
for (size_t i = 0; i < 29; ++i) {
|
|
4457
|
+
SCOPED_TRACE(i);
|
|
4060
4458
|
size_t slot_size = size_t{1} << i;
|
|
4061
|
-
size_t
|
|
4062
|
-
|
|
4063
|
-
ASSERT_TRUE(IsAboveValidSize</*kSizeOfSizeT=*/4>(max_size + 1, slot_size));
|
|
4459
|
+
size_t key_size = slot_size;
|
|
4460
|
+
size_t max_size = MaxValidSize</*kSizeOfSizeT=*/4>(key_size, slot_size);
|
|
4064
4461
|
ASSERT_LT(max_size, 1 << 30);
|
|
4065
4462
|
size_t max_capacity = SizeToCapacity(max_size);
|
|
4066
|
-
ASSERT_LT(max_capacity,
|
|
4067
|
-
|
|
4463
|
+
ASSERT_LT(uint64_t{max_capacity} * slot_size, size_t{1} << 31);
|
|
4464
|
+
if (key_size < 4) {
|
|
4465
|
+
ASSERT_EQ(max_size, uint64_t{1} << 8 * key_size);
|
|
4466
|
+
} else {
|
|
4467
|
+
ASSERT_GT(max_capacity, (1 << 29) / slot_size);
|
|
4468
|
+
}
|
|
4068
4469
|
ASSERT_LT(max_capacity * slot_size, size_t{1} << 31);
|
|
4069
4470
|
}
|
|
4070
4471
|
}
|
|
4071
4472
|
|
|
4072
4473
|
TEST(Table, MaxSizeOverflow) {
|
|
4474
|
+
#ifdef ABSL_HAVE_EXCEPTIONS
|
|
4475
|
+
GTEST_SKIP() << "Skipping test because exceptions are enabled. EXPECT_DEATH "
|
|
4476
|
+
"doesn't work with exceptions.";
|
|
4477
|
+
#elif defined(ABSL_HAVE_THREAD_SANITIZER)
|
|
4478
|
+
GTEST_SKIP() << "ThreadSanitizer test runs fail on OOM even in EXPECT_DEATH.";
|
|
4479
|
+
#else
|
|
4480
|
+
const std::string expected_death_message =
|
|
4481
|
+
"new failed|failed to allocate|bad_alloc|exceeds maximum supported size";
|
|
4073
4482
|
size_t overflow = (std::numeric_limits<size_t>::max)();
|
|
4074
|
-
EXPECT_DEATH_IF_SUPPORTED(IntTable t(overflow),
|
|
4483
|
+
EXPECT_DEATH_IF_SUPPORTED(IntTable t(overflow), expected_death_message);
|
|
4075
4484
|
IntTable t;
|
|
4076
|
-
EXPECT_DEATH_IF_SUPPORTED(t.reserve(overflow),
|
|
4077
|
-
EXPECT_DEATH_IF_SUPPORTED(t.rehash(overflow),
|
|
4078
|
-
size_t slightly_overflow =
|
|
4485
|
+
EXPECT_DEATH_IF_SUPPORTED(t.reserve(overflow), expected_death_message);
|
|
4486
|
+
EXPECT_DEATH_IF_SUPPORTED(t.rehash(overflow), expected_death_message);
|
|
4487
|
+
size_t slightly_overflow =
|
|
4488
|
+
MaxValidSize(sizeof(IntTable::key_type), sizeof(IntTable::value_type)) +
|
|
4489
|
+
1;
|
|
4079
4490
|
size_t slightly_overflow_capacity =
|
|
4080
4491
|
NextCapacity(NormalizeCapacity(slightly_overflow));
|
|
4081
4492
|
EXPECT_DEATH_IF_SUPPORTED(IntTable t2(slightly_overflow_capacity - 10),
|
|
4082
|
-
|
|
4493
|
+
expected_death_message);
|
|
4083
4494
|
EXPECT_DEATH_IF_SUPPORTED(t.reserve(slightly_overflow),
|
|
4084
|
-
|
|
4495
|
+
expected_death_message);
|
|
4085
4496
|
EXPECT_DEATH_IF_SUPPORTED(t.rehash(slightly_overflow),
|
|
4086
|
-
|
|
4497
|
+
expected_death_message);
|
|
4087
4498
|
IntTable non_empty_table;
|
|
4088
4499
|
non_empty_table.insert(0);
|
|
4089
4500
|
EXPECT_DEATH_IF_SUPPORTED(non_empty_table.reserve(slightly_overflow),
|
|
4090
|
-
|
|
4501
|
+
expected_death_message);
|
|
4502
|
+
#endif // defined(ABSL_HAVE_THREAD_SANITIZER)
|
|
4503
|
+
}
|
|
4504
|
+
|
|
4505
|
+
// Tests that reserving enough space for more than the max number of unique keys
|
|
4506
|
+
// doesn't crash and we end up with kMaxValidCapacity.
|
|
4507
|
+
TEST(Table, MaxSizeOverflowUniqueKeys) {
|
|
4508
|
+
absl::flat_hash_set<uint8_t> t8;
|
|
4509
|
+
t8.reserve(1 << 9);
|
|
4510
|
+
EXPECT_EQ(t8.capacity(), SizeToCapacity(t8.max_size()));
|
|
4511
|
+
absl::flat_hash_set<uint16_t> t16;
|
|
4512
|
+
t16.reserve(1 << 17);
|
|
4513
|
+
EXPECT_EQ(t16.capacity(), SizeToCapacity(t16.max_size()));
|
|
4091
4514
|
}
|
|
4092
4515
|
|
|
4093
4516
|
// TODO(b/397453582): Remove support for const hasher and remove this test.
|
|
@@ -4111,9 +4534,11 @@ TEST(Table, ConstLambdaHash) {
|
|
|
4111
4534
|
EXPECT_EQ(t.find(3), t.end());
|
|
4112
4535
|
}
|
|
4113
4536
|
|
|
4114
|
-
struct
|
|
4115
|
-
|
|
4116
|
-
size_t
|
|
4537
|
+
struct ZeroHash {
|
|
4538
|
+
template <typename T>
|
|
4539
|
+
size_t operator()(T) const {
|
|
4540
|
+
return 0;
|
|
4541
|
+
}
|
|
4117
4542
|
};
|
|
4118
4543
|
|
|
4119
4544
|
// This test is imitating growth of a very big table and triggers all buffer
|
|
@@ -4129,18 +4554,18 @@ struct ConstUint8Hash {
|
|
|
4129
4554
|
// 4. Then a few times we will extend control buffer end.
|
|
4130
4555
|
// 5. Finally we will catch up and go to overflow codepath.
|
|
4131
4556
|
TEST(Table, GrowExtremelyLargeTable) {
|
|
4557
|
+
// ProbedItem8Bytes causes OOMs on some platforms so we use ProbedItem4Bytes.
|
|
4132
4558
|
constexpr size_t kTargetCapacity =
|
|
4133
|
-
#if defined(__wasm__) || defined(__asmjs__) || defined(__i386__)
|
|
4134
|
-
|
|
4559
|
+
#if defined(__wasm__) || defined(__asmjs__) || defined(__i386__) || \
|
|
4560
|
+
defined(_MSC_VER) || defined(ABSL_HAVE_THREAD_SANITIZER) || \
|
|
4561
|
+
defined(ABSL_HAVE_MEMORY_SANITIZER) || \
|
|
4562
|
+
(!defined(__clang__) && defined(__GNUC__))
|
|
4563
|
+
NextCapacity(ProbedItem4Bytes::kMaxNewCapacity);
|
|
4135
4564
|
#else
|
|
4136
4565
|
NextCapacity(ProbedItem8Bytes::kMaxNewCapacity);
|
|
4137
4566
|
#endif
|
|
4138
4567
|
|
|
4139
|
-
|
|
4140
|
-
// In order to save memory we use 1 byte slot.
|
|
4141
|
-
// There are not enough different values to achieve big capacity, so we
|
|
4142
|
-
// artificially update growth info to force resize.
|
|
4143
|
-
absl::flat_hash_set<uint8_t, ConstUint8Hash> t(63, ConstUint8Hash{&hash});
|
|
4568
|
+
absl::flat_hash_set<uint32_t, ZeroHash> t(63);
|
|
4144
4569
|
CommonFields& common = RawHashSetTestOnlyAccess::GetCommon(t);
|
|
4145
4570
|
// Set 0 seed so that H1 is always 0.
|
|
4146
4571
|
common.set_no_seed_for_testing();
|
|
@@ -4156,7 +4581,8 @@ TEST(Table, GrowExtremelyLargeTable) {
|
|
|
4156
4581
|
for (size_t cap = t.capacity(); cap < kTargetCapacity;
|
|
4157
4582
|
cap = NextCapacity(cap)) {
|
|
4158
4583
|
ASSERT_EQ(t.capacity(), cap);
|
|
4159
|
-
// Update growth info to force resize on the next insert.
|
|
4584
|
+
// Update growth info to force resize on the next insert. This way we avoid
|
|
4585
|
+
// having to insert many elements.
|
|
4160
4586
|
common.growth_info().OverwriteManyEmptyAsFull(CapacityToGrowth(cap) -
|
|
4161
4587
|
t.size());
|
|
4162
4588
|
t.insert(inserted_till++);
|
|
@@ -4168,16 +4594,6 @@ TEST(Table, GrowExtremelyLargeTable) {
|
|
|
4168
4594
|
EXPECT_EQ(t.capacity(), kTargetCapacity);
|
|
4169
4595
|
}
|
|
4170
4596
|
|
|
4171
|
-
// Test that after calling generate_new_seed(), the high bits of the returned
|
|
4172
|
-
// seed are non-zero.
|
|
4173
|
-
TEST(PerTableSeed, HighBitsAreNonZero) {
|
|
4174
|
-
HashtableSize hs(no_seed_empty_tag_t{});
|
|
4175
|
-
for (int i = 0; i < 100; ++i) {
|
|
4176
|
-
hs.generate_new_seed();
|
|
4177
|
-
ASSERT_GT(hs.seed().seed() >> 16, 0);
|
|
4178
|
-
}
|
|
4179
|
-
}
|
|
4180
|
-
|
|
4181
4597
|
} // namespace
|
|
4182
4598
|
} // namespace container_internal
|
|
4183
4599
|
ABSL_NAMESPACE_END
|