#include "universal_container/adaptive_sequence.hpp" #include "universal_container/ring_block.hpp" #include #include #include #include #include #include #include #include #include #include namespace { int failures = 0; void expect(bool condition, const char* expression, int line) { if (!condition) { std::cerr << "FAIL line " << line << ": " << expression << '\n'; ++failures; } } #define EXPECT(expression) expect(static_cast(expression), #expression, __LINE__) struct DeferredTransitionPolicy { uc::TieredConfig target{8, 4, 2}; bool ready = false; std::size_t decisions = 0; std::size_t transitions = 0; uc::StorageMode last_from = uc::StorageMode::vector; uc::StorageMode last_to = uc::StorageMode::vector; void observe(const uc::OperationSample& sample) noexcept { if (sample.kind == uc::OperationKind::insert) { ready = true; } } [[nodiscard]] bool decision_ready() const noexcept { return ready; } [[nodiscard]] std::optional recommended_decision(uc::StorageMode current, std::size_t, uc::TieredConfig) noexcept { if (!ready) { return std::nullopt; } ready = false; ++decisions; if (current == uc::StorageMode::vector) { return uc::AdaptationDecision{uc::StorageMode::tiered, target, 1.0}; } return std::nullopt; } void on_transition(uc::StorageMode from, uc::StorageMode to, uc::TieredConfig active) noexcept { ++transitions; last_from = from; last_to = to; target = active; ready = false; } void reset() noexcept { ready = false; decisions = 0; transitions = 0; } }; struct WraparoundHash { [[nodiscard]] std::size_t operator()(std::uint32_t) const noexcept { return std::numeric_limits::max(); } }; template void expect_equal(const Sequence& sequence, const Reference& reference) { EXPECT(sequence.size() == reference.size()); for (std::size_t i = 0; i < reference.size() && i < sequence.size(); ++i) { EXPECT(sequence[i] == reference[i]); } } void ring_block_offsets() { uc::detail::RingBlock block(8); block.push_back(2); block.push_back(3); block.insert(0, 1); block.insert(0, 0); block.insert(2, 9); EXPECT(block.offset() != 0); const std::vector expected{0, 1, 9, 2, 3}; for (std::size_t i = 0; i < expected.size(); ++i) { EXPECT(block[i] == expected[i]); } EXPECT(block.erase(2) == 9); EXPECT(block.erase(0) == 0); EXPECT(block.size() == 3); EXPECT(block[0] == 1 && block[1] == 2 && block[2] == 3); } void randomized_differential() { uc::TieredConfig config{16, 4, 4}; uc::AdaptiveSequence actual(config); actual.force_tiered_mode(); std::vector expected; std::mt19937_64 random(0xC0FFEEULL); for (std::size_t step = 0; step < 30'000; ++step) { const auto operation = static_cast(random() % 5); if (expected.empty() || operation == 0) { const auto value = static_cast(random()); const auto index = expected.empty() ? 0 : static_cast(random() % (expected.size() + 1)); expected.insert(expected.begin() + static_cast(index), value); actual.insert(index, value); } else if (operation == 1) { const auto index = static_cast(random() % expected.size()); expected.erase(expected.begin() + static_cast(index)); actual.erase(index); } else if (operation == 2) { const auto value = static_cast(random()); expected.push_back(value); actual.push_back(value); } else if (operation == 3) { const auto index = static_cast(random() % expected.size()); const auto value = static_cast(random()); expected[index] = value; actual.set(index, value); } else { const auto index = static_cast(random() % expected.size()); EXPECT(actual[index] == expected[index]); } if (step % 251 == 0) { expect_equal(actual, expected); actual.force_vector_mode(); expect_equal(actual, expected); actual.force_tiered_mode(); } } expect_equal(actual, expected); } void indexed_duplicates_and_ids() { uc::AdaptiveSequence values({8, 4, 3}); values.push_back(5); values.push_back(8); values.push_back(5); values.push_back(3); values.push_back(5); const auto middle_id = values.id_at(2); EXPECT(values.contains(5)); EXPECT(values.find_all(5) == std::vector({0, 2, 4})); values.force_tiered_mode(); values.insert(1, 5); EXPECT(values.find_all(5) == std::vector({0, 1, 3, 5})); EXPECT(values.id_alive(middle_id)); values.force_tiered_mode({16, 4, 3}); EXPECT(values.find_all(5) == std::vector({0, 1, 3, 5})); EXPECT(values.id_alive(middle_id)); values[3] = 42; EXPECT(values.find_all(5) == std::vector({0, 1, 5})); EXPECT(values.contains(42)); values.erase_by_id(middle_id); EXPECT(!values.id_alive(middle_id)); EXPECT(!values.contains(42)); EXPECT(values.erase_all(5) == 3); EXPECT(!values.contains(5)); EXPECT(values.size() == 2); } void indexed_ids_reuse_slots_without_reviving_stale_handles() { uc::AdaptiveSequence values; for (std::uint32_t value = 0; value < 64; ++value) { values.push_back(value); } const auto first_id = values.id_at(0); const auto fixed_allocation = values.allocated_bytes(); for (std::uint32_t step = 0; step < 2'048; ++step) { const auto retired = values.id_at(0); values.erase_by_id(retired); EXPECT(!values.id_alive(retired)); values.push_back(10'000 + step); const auto replacement = values.id_at(values.size() - 1); EXPECT(replacement != retired); EXPECT(values.id_alive(replacement)); EXPECT(!values.id_alive(retired)); EXPECT(!values.id_alive(first_id)); EXPECT(values.find_one(10'000 + step) == values.size() - 1); EXPECT(values.find_all_ids(10'000 + step) == std::vector({replacement})); bool stale_rejected = false; try { values.erase_by_id(retired); } catch (const std::out_of_range&) { stale_rejected = true; } EXPECT(stale_rejected); } // Churn at a fixed live size must recycle the 64 metadata slots instead // of growing the ID vector outside a logical-capacity boundary. EXPECT(values.size() == 64); EXPECT(values.capacity() == 64); EXPECT(values.allocated_bytes() == fixed_allocation); values.set(0, 0xf00d); values.set(1, 0xf00d); const auto duplicate_ids = values.find_all_ids(0xf00d); EXPECT(duplicate_ids.size() == 2); EXPECT(values.erase_all(0xf00d) == 2); for (const auto id : duplicate_ids) { EXPECT(!values.id_alive(id)); } std::vector ids_before_clear; ids_before_clear.reserve(values.size()); for (std::size_t index = 0; index < values.size(); ++index) { ids_before_clear.push_back(values.id_at(index)); } values.clear(); for (const auto id : ids_before_clear) { EXPECT(!values.id_alive(id)); } EXPECT(!values.id_alive(decltype(values)::invalid_id)); values.push_back(77); const auto after_clear = values.id_at(0); EXPECT(values.id_alive(after_clear)); EXPECT(std::find(ids_before_clear.begin(), ids_before_clear.end(), after_clear) == ids_before_clear.end()); } void moved_from_sequences_are_reusable_and_assignment_invalidates_proxies() { using Sequence = uc::AdaptiveSequence; Sequence source({8, 4, 3}); for (std::uint32_t value = 0; value < 64; ++value) { source.push_back(value); } source.force_tiered_mode(); const auto transferred_id = source.id_at(17); Sequence moved(std::move(source)); EXPECT(moved.size() == 64); EXPECT(moved.id_alive(transferred_id)); EXPECT(source.empty()); EXPECT(source.capacity() == 0); EXPECT(source.mode() == uc::StorageMode::vector); EXPECT(!source.id_alive(transferred_id)); for (std::uint32_t value = 0; value < 40; ++value) { source.push_back(1'000 + value); } EXPECT(source.size() == 40); EXPECT(source.contains(1'039)); Sequence destination; destination.push_back(7); auto stale_after_move_assignment = destination[0]; destination = std::move(moved); bool move_assignment_invalidated = false; try { stale_after_move_assignment = 8; } catch (const std::logic_error&) { move_assignment_invalidated = true; } EXPECT(move_assignment_invalidated); EXPECT(destination.id_alive(transferred_id)); EXPECT(moved.empty()); moved.push_back(2'000); EXPECT(moved.contains(2'000)); Sequence copy_source; copy_source.push_back(99); auto stale_after_copy_assignment = destination[0]; destination = copy_source; bool copy_assignment_invalidated = false; try { stale_after_copy_assignment = 9; } catch (const std::logic_error&) { copy_assignment_invalidated = true; } EXPECT(copy_assignment_invalidated); EXPECT(destination.size() == 1); EXPECT(destination.contains(99)); } void hash_backward_shift_handles_wraparound_and_duplicates() { using Sequence = uc::AdaptiveSequence; Sequence values; std::vector ids; for (std::uint32_t value = 0; value < 12; ++value) { values.push_back(value); ids.push_back(values.id_at(values.size() - 1)); } values.push_back(5); const auto duplicate_id = values.id_at(values.size() - 1); const auto buckets = values.hash_bucket_count(); // Every distinct key starts in the final bucket, so the probe chain wraps // through bucket zero. Removing a middle key must compact that chain // without losing later keys or the duplicate list. values.erase_by_id(ids[3]); EXPECT(!values.id_alive(ids[3])); for (std::uint32_t value = 0; value < 12; ++value) { EXPECT(values.contains(value) == (value != 3)); } EXPECT(values.find_all(5).size() == 2); EXPECT(values.id_alive(ids[5])); EXPECT(values.id_alive(duplicate_id)); values.erase_by_id(ids[5]); EXPECT(values.contains(5)); EXPECT(values.find_all_ids(5) == std::vector({duplicate_id})); EXPECT(values.hash_bucket_count() == buckets); } void indexed_proxy_detects_structural_invalidation() { uc::AdaptiveSequence values({8, 4, 2}); values.push_back(10); values.push_back(20); auto stale = values[1]; values.insert(0, 5); bool invalidation_detected = false; try { stale = 99; } catch (const std::logic_error&) { invalidation_detected = true; } EXPECT(invalidation_detected); const auto& read_only = values; EXPECT(read_only[0] == 5); EXPECT(read_only[1] == 10); EXPECT(read_only[2] == 20); } void iterator_and_contiguous_contract() { uc::AdaptiveSequence values({8, 4, 3}); for (int i = 0; i < 100; ++i) { values.push_back(i); } values.force_tiered_mode(); EXPECT(values.data() == nullptr); std::int64_t sum = 0; values.for_each([&](int value) { sum += value; }); EXPECT(sum == 4'950); const auto contiguous = values.make_contiguous(); EXPECT(values.mode() == uc::StorageMode::vector); EXPECT(contiguous.size() == 100); EXPECT(contiguous[37] == 37); auto iterator = values.begin(); EXPECT(*iterator == 0); values.push_back(100); bool invalidation_detected = false; try { (void)*iterator; } catch (const std::logic_error&) { invalidation_detected = true; } EXPECT(invalidation_detected); } struct NonTrivial { std::string text; std::uint64_t marker = 0; NonTrivial(std::string value, std::uint64_t number) : text(std::move(value)), marker(number) {} NonTrivial(const NonTrivial&) = default; NonTrivial(NonTrivial&&) noexcept = default; NonTrivial& operator=(const NonTrivial&) = default; NonTrivial& operator=(NonTrivial&&) noexcept = default; ~NonTrivial() { marker ^= 0; } friend bool operator==(const NonTrivial&, const NonTrivial&) = default; }; void non_trivial_values() { uc::AdaptiveSequence values({4, 4, 2}); values.push_back(NonTrivial{"alpha", 1}); values.push_back(NonTrivial{"gamma", 3}); values.force_tiered_mode(); values.insert(1, NonTrivial{"beta", 2}); EXPECT(values[0].text == "alpha"); EXPECT(values[1].text == "beta"); EXPECT(values[2].text == "gamma"); values.erase(0); EXPECT(values[0].marker == 2); } void tiered_shape_rebuild_preserves_order() { uc::AdaptiveSequence values({8, 4, 2}); std::vector expected; for (std::uint32_t i = 0; i < 257; ++i) { values.push_back(i * 3 + 1); expected.push_back(i * 3 + 1); } values.force_tiered_mode(); values.force_tiered_mode({64, 8, 3}); EXPECT(values.mode() == uc::StorageMode::tiered); EXPECT(values.tiered_config() == (uc::TieredConfig{64, 8, 3})); expect_equal(values, expected); values.insert(129, 0xfeedu); expected.insert(expected.begin() + 129, 0xfeedu); values.force_tiered_mode({16, 4, 4}); EXPECT(values.tiered_config() == (uc::TieredConfig{16, 4, 4})); expect_equal(values, expected); values.force_tiered_mode({16, 4, 1}); values.force_tiered_mode({16, 4, 4}); expect_equal(values, expected); EXPECT(values.policy().telemetry().tiered_rebuilds == 4); EXPECT(values.policy().telemetry().tiered_leaf_rebuilds == 2); EXPECT(values.policy().telemetry().tiered_directory_rebuilds == 2); } void capacity_boundaries_control_mode_and_geometry() { uc::ResizePolicyConfig policy_config; policy_config.minimum_tiered_size = 8; uc::ResizePolicy policy(policy_config, {4, 4, 3}); uc::AdaptiveSequence values({4, 4, 3}, policy); for (std::uint32_t value = 0; value < 8; ++value) { values.push_back(value); } EXPECT(values.capacity() == 8); EXPECT(values.mode() == uc::StorageMode::vector); // The ninth element is the next x2 capacity boundary. The representation // and sqrt(N) leaf are selected as part of that single rebuild. values.push_back(8); EXPECT(values.capacity() == 16); EXPECT(values.mode() == uc::StorageMode::tiered); EXPECT(values.tiered_config().leaf_capacity == 4); const auto leaf_at_16 = values.tiered_config().leaf_capacity; for (std::uint32_t value = 9; value < 16; ++value) { values.push_back(value); EXPECT(values.tiered_config().leaf_capacity == leaf_at_16); } values.push_back(16); EXPECT(values.capacity() == 32); EXPECT(values.mode() == uc::StorageMode::tiered); EXPECT(values.tiered_config().leaf_capacity == 5); // Shrink is exactly one /2 step at 12.5% occupancy. At N=4 the same // rebuild crosses the cutoff in the opposite direction. while (values.size() > 4) { values.erase(values.size() - 1); } EXPECT(values.capacity() == 16); EXPECT(values.mode() == uc::StorageMode::vector); expect_equal(values, std::vector({0, 1, 2, 3})); EXPECT(!values.adapt_now()); EXPECT(values.mode() == uc::StorageMode::vector); } void calibrated_default_cutoff_is_applied_at_resize() { uc::AdaptiveSequence values; for (std::uint32_t value = 0; value < 4'096; ++value) { values.push_back(value); } EXPECT(values.capacity() == 4'096); EXPECT(values.mode() == uc::StorageMode::vector); values.push_back(4'096); EXPECT(values.capacity() == 8'192); EXPECT(values.mode() == uc::StorageMode::tiered); EXPECT(values.tiered_config().leaf_capacity == 65); while (values.size() > 1'024) { values.erase(values.size() - 1); } EXPECT(values.capacity() == 4'096); EXPECT(values.mode() == uc::StorageMode::vector); } std::optional shape_decision( std::size_t n, uc::TieredConfig current, bool localized) { uc::AdaptationConfig config; config.evaluation_interval = 64; config.minimum_observations = 64; config.minimum_edit_observations = 64; config.minimum_residency_operations = 0; config.minimum_shape_residency_operations = 0; config.minimum_shape_edit_fraction = 0.0; config.required_confirmation_windows = 1; config.minimum_tiered_size = 1; config.forecast_operations = 1'000'000; config.tiered_rebuild_safety = 0.0; config.minimum_shape_improvement = 0.0; config.vector_move_unit = 1.0; uc::CostModelPolicy policy(config, current); policy.on_transition(uc::StorageMode::vector, uc::StorageMode::tiered, current); for (std::size_t i = 0; i < 64; ++i) { const auto position = localized ? n / 2 + i % 17 : (i * 104'729 + 17) % n; policy.observe({uc::OperationKind::insert, n, position, 1, sizeof(std::uint32_t)}); } return policy.recommended_decision(uc::StorageMode::tiered, n, current); } void forecast_horizon_is_bounded_by_observed_evidence() { uc::AdaptationConfig config; config.evaluation_interval = 64; config.minimum_observations = 64; config.minimum_residency_operations = 0; config.required_confirmation_windows = 1; config.forecast_operations = 10'000; config.minimum_forecast_operations = 1; config.forecast_growth_factor = 8.0; const uc::TieredConfig tiered{64, 64, 4}; uc::CostModelPolicy policy(config, tiered); for (std::size_t i = 0; i < 64; ++i) { policy.observe({uc::OperationKind::insert, 10'000, i, 1, sizeof(std::uint32_t)}); } (void)policy.recommended_decision(uc::StorageMode::vector, 10'000, tiered); EXPECT(policy.telemetry().last_forecast_operations == 512); } void confirmation_requires_consecutive_supporting_windows() { uc::AdaptationConfig config; config.evaluation_interval = 16; config.edit_evaluation_interval = 8; config.minimum_observations = 16; config.minimum_edit_observations = 8; config.minimum_residency_operations = 0; config.minimum_tiered_size = 1; config.required_confirmation_windows = 2; config.forecast_operations = 1'000'000; config.minimum_forecast_operations = 1; config.vector_to_tiered_safety = 0.0; config.vector_move_unit = 1.0; config.tiered_move_unit = 0.01; config.tiered_directory_unit = 0.0; config.tiered_read_base = 2.0; config.ewma_alpha = 1.0; config.tiered_entry_edit_fraction = 0.50; const uc::TieredConfig tiered{64, 64, 4}; uc::CostModelPolicy policy(config, tiered); constexpr std::size_t n = 10'000; auto edit_window = [&] { for (std::size_t i = 0; i < 8; ++i) { policy.observe({uc::OperationKind::insert, n, n / 2 + i, 1, sizeof(std::uint32_t)}); } }; edit_window(); for (std::size_t i = 0; i < 16; ++i) { policy.observe({uc::OperationKind::random_read, n, i, 1, sizeof(std::uint32_t)}); } edit_window(); // Three windows accumulated, but the middle one contradicted the tiered // proposal, so the final edit window starts a new streak of one. EXPECT(!policy.recommended_decision( uc::StorageMode::vector, n, tiered).has_value()); edit_window(); const auto confirmed = policy.recommended_decision( uc::StorageMode::vector, n, tiered); EXPECT(confirmed.has_value()); if (confirmed) { EXPECT(confirmed->target == uc::StorageMode::tiered); } } void stationary_phases_do_not_thrash() { constexpr std::size_t operations = 30'000; { // This is the v12 failure shape: a stationary uniform edit phase at // N=10k used to alternate vector/tiered dozens of times. uc::AdaptationConfig config; const uc::TieredConfig initial{512, 64, 4}; uc::CostModelPolicy policy(config, initial); uc::StorageMode mode = uc::StorageMode::vector; auto active = initial; std::mt19937_64 random(0x7c4a'9e13'51d2'08b7ULL); for (std::size_t observed = 0; observed < operations; observed += 4) { const auto position = static_cast(random() % 10'000); policy.observe({uc::OperationKind::insert, 10'000, position, 4, sizeof(std::uint64_t)}); if (!policy.decision_ready()) { continue; } const auto decision = policy.recommended_decision(mode, 10'000, active); if (!decision) { continue; } const auto previous = mode; mode = decision->target; if (mode == uc::StorageMode::tiered) { active = decision->tiered_config; } policy.on_transition(previous, mode, active); } const auto& telemetry = policy.telemetry(); EXPECT(telemetry.vector_to_tiered + telemetry.tiered_to_vector <= 1); } { // Starting tiered isolates shape selection. A stationary uniform // phase may select a better leaf once, but must not bounce thereafter. uc::AdaptationConfig config; const uc::TieredConfig initial{512, 64, 4}; uc::CostModelPolicy policy(config, initial); uc::StorageMode mode = uc::StorageMode::tiered; auto active = initial; policy.on_transition(uc::StorageMode::vector, mode, active); std::mt19937_64 random(0xd1b5'4a32'09fc'77e1ULL); for (std::size_t observed = 0; observed < operations; observed += 4) { const auto position = static_cast(random() % 100'000); policy.observe({uc::OperationKind::insert, 100'000, position, 4, sizeof(std::uint64_t)}); if (!policy.decision_ready()) { continue; } const auto decision = policy.recommended_decision(mode, 100'000, active); if (!decision) { continue; } const auto previous = mode; mode = decision->target; if (mode == uc::StorageMode::tiered) { active = decision->tiered_config; } policy.on_transition(previous, mode, active); } const auto& telemetry = policy.telemetry(); EXPECT(telemetry.tiered_to_vector == 0); EXPECT(telemetry.tiered_leaf_rebuilds <= 1); } } void policy_changes_shape_with_scale_and_locality() { const auto small_uniform = shape_decision(10'000, {512, 64, 4}, false); EXPECT(small_uniform.has_value()); EXPECT(small_uniform->target == uc::StorageMode::tiered); EXPECT(small_uniform->tiered_config.leaf_capacity <= 128); const auto large_uniform = shape_decision(1'000'000, {64, 64, 4}, false); EXPECT(large_uniform.has_value()); EXPECT(large_uniform->target == uc::StorageMode::tiered); EXPECT(large_uniform->tiered_config.leaf_capacity >= 512); const auto large_local = shape_decision(1'000'000, {1024, 64, 4}, true); EXPECT(large_local.has_value()); EXPECT(large_local->target == uc::StorageMode::tiered); EXPECT(large_local->tiered_config.leaf_capacity < large_uniform->tiered_config.leaf_capacity); uc::AdaptationConfig depth_config; depth_config.evaluation_interval = 64; depth_config.minimum_observations = 64; depth_config.minimum_residency_operations = 0; depth_config.minimum_shape_residency_operations = 0; depth_config.minimum_shape_edit_fraction = 0.0; depth_config.required_confirmation_windows = 1; depth_config.forecast_operations = 1'000'000; depth_config.tiered_rebuild_safety = 0.0; depth_config.minimum_shape_improvement = 0.0; depth_config.vector_read = 100.0; depth_config.tiered_leaf_candidates.fill(64); uc::CostModelPolicy depth_policy(depth_config, {64, 64, 2}); depth_policy.on_transition(uc::StorageMode::vector, uc::StorageMode::tiered, {64, 64, 2}); for (std::size_t i = 0; i < 64; ++i) { depth_policy.observe({uc::OperationKind::random_read, 1'000'000, i, 1, sizeof(std::uint32_t)}); } const auto depth = depth_policy.recommended_decision( uc::StorageMode::tiered, 1'000'000, {64, 64, 2}); EXPECT(depth.has_value()); EXPECT(depth->target == uc::StorageMode::tiered); EXPECT(depth->tiered_config.leaf_capacity == 64); EXPECT(depth->tiered_config.directory_levels == 3); } void indexed_hash_capacity_tracks_container_capacity() { uc::ResizePolicyConfig policy_config; policy_config.minimum_tiered_size = 32; uc::AdaptiveSequence values( {8, 8, 3}, uc::ResizePolicy(policy_config, {8, 8, 3})); auto previous_capacity = values.capacity(); auto previous_buckets = values.hash_bucket_count(); for (std::uint32_t value = 0; value < 257; ++value) { values.push_back(value * 16); EXPECT(values.contains(value * 16)); if (values.capacity() == previous_capacity) { EXPECT(values.hash_bucket_count() == previous_buckets); } else { EXPECT(values.capacity() == 1 || values.capacity() == previous_capacity * 2); EXPECT(values.hash_bucket_count() >= previous_buckets); previous_capacity = values.capacity(); previous_buckets = values.hash_bucket_count(); } } // These keys share low hash bits and exercise backward-shift deletion in // the linear-probing table without an intermediate rehash. for (std::uint32_t value = 0; value < 257; value += 2) { EXPECT(values.erase_one(value * 16)); } for (std::uint32_t value = 0; value < 257; ++value) { EXPECT(values.contains(value * 16) == (value % 2 != 0)); } const auto buckets_before_shrink = values.hash_bucket_count(); while (values.size() > values.capacity() / 8) { values.erase(values.size() - 1); } EXPECT(values.hash_bucket_count() <= buckets_before_shrink); } } // namespace int main() { ring_block_offsets(); randomized_differential(); indexed_duplicates_and_ids(); indexed_ids_reuse_slots_without_reviving_stale_handles(); moved_from_sequences_are_reusable_and_assignment_invalidates_proxies(); hash_backward_shift_handles_wraparound_and_duplicates(); indexed_proxy_detects_structural_invalidation(); iterator_and_contiguous_contract(); non_trivial_values(); tiered_shape_rebuild_preserves_order(); capacity_boundaries_control_mode_and_geometry(); calibrated_default_cutoff_is_applied_at_resize(); forecast_horizon_is_bounded_by_observed_evidence(); confirmation_requires_consecutive_supporting_windows(); stationary_phases_do_not_thrash(); policy_changes_shape_with_scale_and_locality(); indexed_hash_capacity_tracks_container_capacity(); if (failures != 0) { std::cerr << failures << " test assertion(s) failed\n"; return EXIT_FAILURE; } std::cout << "All AdaptiveSequence tests passed\n"; return EXIT_SUCCESS; }