/*
 * Copyright (C) 2026 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include <wtf/InlineMap.h>

#include "MoveOnly.h"
#include "RefLogger.h"
#include "Test.h"
#include <wtf/HashSet.h>
#include <wtf/PackedRefPtr.h>
#include <wtf/Ref.h>
#include <wtf/RefPtr.h>
#include <wtf/Vector.h>
#include <wtf/text/MakeString.h>
#include <wtf/text/StringHash.h>

namespace TestWebKitAPI {

TEST(WTF_InlineMap, Empty)
{
    // A freshly constructed map is empty and all queries return no results.
    InlineMap<unsigned, unsigned, 5, IntHash<unsigned>> map;

    EXPECT_TRUE(WTF::InlineMapAccessForTesting::isInline(map));
    EXPECT_TRUE(map.isEmpty());
    EXPECT_EQ(map.size(), 0u);
    EXPECT_FALSE(map.contains(1));
    EXPECT_FALSE(map.contains(2));
    EXPECT_TRUE(map.find(1) == map.end());
    EXPECT_TRUE(map.begin() == map.end());
}

TEST(WTF_InlineMap, BasicAddAndFind)
{
    // Adding a single entry makes it findable; missing keys return end().
    InlineMap<unsigned, unsigned, 5, IntHash<unsigned>> map;

    auto result = map.add(1, 100);
    EXPECT_TRUE(result.isNewEntry);
    EXPECT_EQ(result.iterator->key, 1u);
    EXPECT_EQ(result.iterator->value, 100u);

    EXPECT_FALSE(map.isEmpty());
    EXPECT_EQ(map.size(), 1u);
    EXPECT_TRUE(map.contains(1));
    EXPECT_FALSE(map.contains(2));

    auto it = map.find(1);
    EXPECT_FALSE(it == map.end());
    EXPECT_EQ(it->key, 1u);
    EXPECT_EQ(it->value, 100u);

    it = map.find(2);
    EXPECT_TRUE(it == map.end());
}

TEST(WTF_InlineMap, DuplicateAdd)
{
    // Adding a key that already exists preserves the original value.
    InlineMap<unsigned, unsigned, 5, IntHash<unsigned>> map;

    auto result1 = map.add(1, 100);
    EXPECT_TRUE(result1.isNewEntry);

    auto result2 = map.add(1, 200);
    EXPECT_FALSE(result2.isNewEntry);
    EXPECT_EQ(result2.iterator->value, 100u); // Original value preserved

    EXPECT_EQ(map.size(), 1u);
}

TEST(WTF_InlineMap, StorageModeTransitions)
{
    // Map transitions from inline to hashed storage when inline capacity is exceeded.
    // Explicitly specify InitialCapacity=3 and InitialHashedCapacity=8
    InlineMap<unsigned, unsigned, 3, IntHash<unsigned>> map;

    // New map starts empty
    EXPECT_TRUE(WTF::InlineMapAccessForTesting::isInline(map));

    // First add stays in linear mode
    map.add(1, 10);
    EXPECT_TRUE(WTF::InlineMapAccessForTesting::isInline(map));

    // Stays linear through capacity (3 entries)
    map.add(2, 20);
    EXPECT_TRUE(WTF::InlineMapAccessForTesting::isInline(map));

    map.add(3, 30);
    EXPECT_TRUE(WTF::InlineMapAccessForTesting::isInline(map));

    // Fourth entry triggers transition to hashed mode
    map.add(4, 40);
    EXPECT_FALSE(WTF::InlineMapAccessForTesting::isInline(map));

    // Stays hashed as more entries are added
    map.add(5, 50);
    EXPECT_FALSE(WTF::InlineMapAccessForTesting::isInline(map));

    // All entries should be accessible
    EXPECT_EQ(map.size(), 5u);
    for (unsigned i = 1; i <= 5; ++i) {
        auto it = map.find(i);
        ASSERT_FALSE(it == map.end());
        EXPECT_EQ(it->value, i * 10);
    }
}

TEST(WTF_InlineMap, LinearMode)
{
    // Entries within inline capacity are stored inline and are all findable.
    // Explicitly specify InitialCapacity=3 to test linear storage behavior
    InlineMap<unsigned, unsigned, 3, IntHash<unsigned>> map;

    EXPECT_TRUE(WTF::InlineMapAccessForTesting::isInline(map));

    for (unsigned i = 1; i <= 3; ++i) {
        auto result = map.add(i, i * 10);
        EXPECT_TRUE(result.isNewEntry);
        EXPECT_TRUE(WTF::InlineMapAccessForTesting::isInline(map));
    }

    EXPECT_EQ(map.size(), 3u);

    for (unsigned i = 1; i <= 3; ++i) {
        EXPECT_TRUE(map.contains(i));
        auto it = map.find(i);
        EXPECT_FALSE(it == map.end());
        EXPECT_EQ(it->value, i * 10);
    }

    EXPECT_FALSE(map.contains(4));
}

TEST(WTF_InlineMap, GrowToHashedMode)
{
    // Growing well past inline capacity preserves all entries in hashed mode.
    // Explicitly specify InitialCapacity=3 and InitialHashedCapacity=8
    InlineMap<unsigned, unsigned, 3, IntHash<unsigned>> map;

    EXPECT_TRUE(WTF::InlineMapAccessForTesting::isInline(map));

    // Fill linear capacity (3 entries)
    for (unsigned i = 1; i <= 3; ++i) {
        map.add(i, i * 10);
        EXPECT_TRUE(WTF::InlineMapAccessForTesting::isInline(map));
    }

    // Adding one more should trigger transition to hashed mode
    map.add(4, 40);
    EXPECT_FALSE(WTF::InlineMapAccessForTesting::isInline(map));

    // Fill beyond initial capacity to trigger growth
    for (unsigned i = 5; i <= 100; ++i) {
        auto result = map.add(i, i * 10);
        EXPECT_TRUE(result.isNewEntry);
        EXPECT_FALSE(WTF::InlineMapAccessForTesting::isInline(map));
    }

    EXPECT_EQ(map.size(), 100u);

    // Verify all entries are still accessible
    for (unsigned i = 1; i <= 100; ++i) {
        EXPECT_TRUE(map.contains(i));
        auto it = map.find(i);
        EXPECT_FALSE(it == map.end());
        EXPECT_EQ(it->value, i * 10);
    }

    EXPECT_FALSE(map.contains(101));
}

TEST(WTF_InlineMap, Iteration)
{
    // Range-based for visits every entry exactly once.
    InlineMap<unsigned, unsigned, 5, IntHash<unsigned>> map;

    for (unsigned i = 1; i <= 10; ++i)
        map.add(i, i * 10);

    HashSet<unsigned, IntHash<unsigned>, WTF::UnsignedWithZeroKeyHashTraits<unsigned>> seenKeys;
    unsigned count = 0;

    for (auto& entry : map) {
        seenKeys.add(entry.key);
        EXPECT_EQ(entry.value, entry.key * 10);
        ++count;
    }

    EXPECT_EQ(count, 10u);
    EXPECT_EQ(seenKeys.size(), 10u);

    for (unsigned i = 1; i <= 10; ++i)
        EXPECT_TRUE(seenKeys.contains(i));
}

TEST(WTF_InlineMap, IterationAfterGrowth)
{
    // Iteration works correctly after the map has grown to hashed mode.
    InlineMap<unsigned, unsigned, 5, IntHash<unsigned>> map;

    for (unsigned i = 1; i <= 100; ++i)
        map.add(i, i * 10);

    HashSet<unsigned, IntHash<unsigned>, WTF::UnsignedWithZeroKeyHashTraits<unsigned>> seenKeys;
    unsigned count = 0;

    for (auto& entry : map) {
        seenKeys.add(entry.key);
        EXPECT_EQ(entry.value, entry.key * 10);
        ++count;
    }

    EXPECT_EQ(count, 100u);
    EXPECT_EQ(seenKeys.size(), 100u);
}

TEST(WTF_InlineMap, MoveConstruction)
{
    // Move constructor transfers all entries and leaves the source empty.
    InlineMap<unsigned, unsigned, 5, IntHash<unsigned>> map1;

    for (unsigned i = 1; i <= 10; ++i)
        map1.add(i, i * 10);

    InlineMap<unsigned, unsigned, 5, IntHash<unsigned>> map2(WTF::move(map1));

    EXPECT_TRUE(map1.isEmpty());
    EXPECT_EQ(map2.size(), 10u);

    for (unsigned i = 1; i <= 10; ++i) {
        EXPECT_TRUE(map2.contains(i));
        EXPECT_EQ(map2.find(i)->value, i * 10);
    }
}

TEST(WTF_InlineMap, MoveAssignment)
{
    // Move assignment replaces the target's content and leaves the source empty.
    InlineMap<unsigned, unsigned, 5, IntHash<unsigned>> map1;
    InlineMap<unsigned, unsigned, 5, IntHash<unsigned>> map2;

    for (unsigned i = 1; i <= 10; ++i)
        map1.add(i, i * 10);

    map2.add(100, 1000);

    map2 = WTF::move(map1);

    EXPECT_TRUE(map1.isEmpty());
    EXPECT_EQ(map2.size(), 10u);
    EXPECT_FALSE(map2.contains(100));

    for (unsigned i = 1; i <= 10; ++i)
        EXPECT_TRUE(map2.contains(i));
}

TEST(WTF_InlineMap, CopyConstructionEmpty)
{
    // Copy-constructing from an empty map produces another empty map.
    InlineMap<unsigned, unsigned, 5, IntHash<unsigned>> map1;

    InlineMap<unsigned, unsigned, 5, IntHash<unsigned>> map2(map1);

    EXPECT_TRUE(map1.isEmpty());
    EXPECT_TRUE(map2.isEmpty());
    EXPECT_EQ(map1.size(), 0u);
    EXPECT_EQ(map2.size(), 0u);
}

TEST(WTF_InlineMap, CopyConstructionLinearMode)
{
    // Copy-constructing a map in inline mode produces an independent copy.
    InlineMap<unsigned, unsigned, 3, IntHash<unsigned>> map1;

    map1.add(1, 10);
    map1.add(2, 20);
    EXPECT_TRUE(WTF::InlineMapAccessForTesting::isInline(map1));

    InlineMap<unsigned, unsigned, 3, IntHash<unsigned>> map2(map1);

    // Original should be unchanged
    EXPECT_EQ(map1.size(), 2u);
    EXPECT_TRUE(map1.contains(1));
    EXPECT_TRUE(map1.contains(2));
    EXPECT_EQ(map1.find(1)->value, 10u);
    EXPECT_EQ(map1.find(2)->value, 20u);

    // Copy should have same content
    EXPECT_EQ(map2.size(), 2u);
    EXPECT_TRUE(map2.contains(1));
    EXPECT_TRUE(map2.contains(2));
    EXPECT_EQ(map2.find(1)->value, 10u);
    EXPECT_EQ(map2.find(2)->value, 20u);

    // Modifying copy should not affect original
    map2.add(3, 30);
    EXPECT_EQ(map1.size(), 2u);
    EXPECT_EQ(map2.size(), 3u);
    EXPECT_FALSE(map1.contains(3));
    EXPECT_TRUE(map2.contains(3));
}

TEST(WTF_InlineMap, CopyConstructionHashedMode)
{
    // Copy-constructing a map in hashed mode produces an independent copy.
    InlineMap<unsigned, unsigned, 5, IntHash<unsigned>> map1;

    for (unsigned i = 1; i <= 20; ++i)
        map1.add(i, i * 10);

    EXPECT_FALSE(WTF::InlineMapAccessForTesting::isInline(map1));

    InlineMap<unsigned, unsigned, 5, IntHash<unsigned>> map2(map1);

    // Original should be unchanged
    EXPECT_EQ(map1.size(), 20u);
    for (unsigned i = 1; i <= 20; ++i) {
        EXPECT_TRUE(map1.contains(i));
        EXPECT_EQ(map1.find(i)->value, i * 10);
    }

    // Copy should have same content
    EXPECT_EQ(map2.size(), 20u);
    for (unsigned i = 1; i <= 20; ++i) {
        EXPECT_TRUE(map2.contains(i));
        EXPECT_EQ(map2.find(i)->value, i * 10);
    }

    // Modifying copy should not affect original
    map2.add(100, 1000);
    EXPECT_EQ(map1.size(), 20u);
    EXPECT_EQ(map2.size(), 21u);
    EXPECT_FALSE(map1.contains(100));
    EXPECT_TRUE(map2.contains(100));
}

TEST(WTF_InlineMap, CopyAssignment)
{
    // Copy assignment replaces the target's content with a copy of the source.
    InlineMap<unsigned, unsigned, 5, IntHash<unsigned>> map1;
    InlineMap<unsigned, unsigned, 5, IntHash<unsigned>> map2;

    for (unsigned i = 1; i <= 10; ++i)
        map1.add(i, i * 10);

    map2.add(100, 1000);

    map2 = map1;

    // Original should be unchanged
    EXPECT_EQ(map1.size(), 10u);
    for (unsigned i = 1; i <= 10; ++i)
        EXPECT_TRUE(map1.contains(i));

    // Assigned map should have same content, old content replaced
    EXPECT_EQ(map2.size(), 10u);
    EXPECT_FALSE(map2.contains(100));
    for (unsigned i = 1; i <= 10; ++i) {
        EXPECT_TRUE(map2.contains(i));
        EXPECT_EQ(map2.find(i)->value, i * 10);
    }
}

TEST(WTF_InlineMap, CopyAssignmentToSelf)
{
    // Self-assignment is a no-op and preserves the map's content.
    InlineMap<unsigned, unsigned, 5, IntHash<unsigned>> map;

    for (unsigned i = 1; i <= 10; ++i)
        map.add(i, i * 10);

    // Use a reference to avoid -Wself-assign-overloaded warning
    auto& ref = map;
    map = ref;

    // Map should be unchanged after self-assignment
    EXPECT_EQ(map.size(), 10u);
    for (unsigned i = 1; i <= 10; ++i) {
        EXPECT_TRUE(map.contains(i));
        EXPECT_EQ(map.find(i)->value, i * 10);
    }
}

TEST(WTF_InlineMap, CopyConstructionWithStrings)
{
    // Copy construction works correctly with String key/value types.
    InlineMap<String, String, 5, StringHash> map1;

    map1.add("key1"_s, "value1"_s);
    map1.add("key2"_s, "value2"_s);
    map1.add("key3"_s, "value3"_s);

    InlineMap<String, String, 5, StringHash> map2(map1);

    EXPECT_EQ(map1.size(), 3u);
    EXPECT_EQ(map2.size(), 3u);

    EXPECT_EQ(map1.find("key1"_s)->value, "value1"_s);
    EXPECT_EQ(map2.find("key1"_s)->value, "value1"_s);
    EXPECT_EQ(map1.find("key2"_s)->value, "value2"_s);
    EXPECT_EQ(map2.find("key2"_s)->value, "value2"_s);
    EXPECT_EQ(map1.find("key3"_s)->value, "value3"_s);
    EXPECT_EQ(map2.find("key3"_s)->value, "value3"_s);
}

TEST(WTF_InlineMap, RemoveFromEmpty)
{
    // Removing from an empty map returns false.
    InlineMap<unsigned, unsigned, 5, IntHash<unsigned>> map;

    EXPECT_FALSE(map.remove(1));
    EXPECT_TRUE(map.isEmpty());
}

TEST(WTF_InlineMap, RemoveLinearMode)
{
    // Removing entries in inline mode works and the map can be emptied completely.
    InlineMap<unsigned, unsigned, 3, IntHash<unsigned>> map;

    map.add(1, 10);
    map.add(2, 20);
    map.add(3, 30);
    EXPECT_TRUE(WTF::InlineMapAccessForTesting::isInline(map));
    EXPECT_EQ(map.size(), 3u);

    // Remove middle entry
    EXPECT_TRUE(map.remove(2));
    EXPECT_EQ(map.size(), 2u);
    EXPECT_TRUE(map.contains(1));
    EXPECT_FALSE(map.contains(2));
    EXPECT_TRUE(map.contains(3));
    EXPECT_EQ(map.find(1)->value, 10u);
    EXPECT_EQ(map.find(3)->value, 30u);

    // Remove first entry
    EXPECT_TRUE(map.remove(1));
    EXPECT_EQ(map.size(), 1u);
    EXPECT_FALSE(map.contains(1));
    EXPECT_TRUE(map.contains(3));

    // Remove last entry
    EXPECT_TRUE(map.remove(3));
    EXPECT_EQ(map.size(), 0u);
    EXPECT_TRUE(map.isEmpty());
    EXPECT_FALSE(map.contains(3));

    // Remove from empty should return false
    EXPECT_FALSE(map.remove(1));
}

TEST(WTF_InlineMap, RemoveNonexistentLinearMode)
{
    // Removing a key not present in inline mode returns false and changes nothing.
    InlineMap<unsigned, unsigned, 3, IntHash<unsigned>> map;

    map.add(1, 10);
    map.add(2, 20);
    EXPECT_TRUE(WTF::InlineMapAccessForTesting::isInline(map));

    EXPECT_FALSE(map.remove(3));
    EXPECT_EQ(map.size(), 2u);
    EXPECT_TRUE(map.contains(1));
    EXPECT_TRUE(map.contains(2));
}

TEST(WTF_InlineMap, RemoveHashedMode)
{
    // Removing entries in hashed mode leaves the remaining entries intact.
    InlineMap<unsigned, unsigned, 5, IntHash<unsigned>> map;

    for (unsigned i = 1; i <= 20; ++i)
        map.add(i, i * 10);

    EXPECT_FALSE(WTF::InlineMapAccessForTesting::isInline(map));
    EXPECT_EQ(map.size(), 20u);

    // Remove several entries
    EXPECT_TRUE(map.remove(5));
    EXPECT_TRUE(map.remove(10));
    EXPECT_TRUE(map.remove(15));

    EXPECT_EQ(map.size(), 17u);
    EXPECT_FALSE(map.contains(5));
    EXPECT_FALSE(map.contains(10));
    EXPECT_FALSE(map.contains(15));

    // Other entries should still be accessible
    for (unsigned i = 1; i <= 20; ++i) {
        if (i == 5 || i == 10 || i == 15)
            continue;
        EXPECT_TRUE(map.contains(i));
        EXPECT_EQ(map.find(i)->value, i * 10);
    }

    // Remove nonexistent should return false
    EXPECT_FALSE(map.remove(5));
    EXPECT_FALSE(map.remove(100));
}

TEST(WTF_InlineMap, RemoveAndReaddHashedMode)
{
    // A removed key can be re-added with a different value.
    InlineMap<unsigned, unsigned, 5, IntHash<unsigned>> map;

    for (unsigned i = 1; i <= 10; ++i)
        map.add(i, i * 10);

    EXPECT_FALSE(WTF::InlineMapAccessForTesting::isInline(map));

    // Remove and re-add with different value
    EXPECT_TRUE(map.remove(5));
    EXPECT_FALSE(map.contains(5));

    auto result = map.add(5, 500);
    EXPECT_TRUE(result.isNewEntry);
    EXPECT_TRUE(map.contains(5));
    EXPECT_EQ(map.find(5)->value, 500u);
    EXPECT_EQ(map.size(), 10u);
}

TEST(WTF_InlineMap, RemoveAllHashedMode)
{
    // Removing all entries one by one leaves the map empty.
    InlineMap<unsigned, unsigned, 5, IntHash<unsigned>> map;

    for (unsigned i = 1; i <= 10; ++i)
        map.add(i, i * 10);

    EXPECT_FALSE(WTF::InlineMapAccessForTesting::isInline(map));

    // Remove all entries
    for (unsigned i = 1; i <= 10; ++i)
        EXPECT_TRUE(map.remove(i));

    EXPECT_EQ(map.size(), 0u);
    EXPECT_TRUE(map.isEmpty());

    // All entries should be gone
    for (unsigned i = 1; i <= 10; ++i)
        EXPECT_FALSE(map.contains(i));
}

TEST(WTF_InlineMap, IterationAfterRemove)
{
    // Iteration skips removed entries and visits only live ones.
    InlineMap<unsigned, unsigned, 5, IntHash<unsigned>> map;

    for (unsigned i = 1; i <= 10; ++i)
        map.add(i, i * 10);

    // Remove some entries
    map.remove(2);
    map.remove(5);
    map.remove(8);

    // Iteration should only visit non-removed entries
    HashSet<unsigned, IntHash<unsigned>, WTF::UnsignedWithZeroKeyHashTraits<unsigned>> seenKeys;
    unsigned count = 0;

    for (auto& entry : map) {
        seenKeys.add(entry.key);
        EXPECT_EQ(entry.value, entry.key * 10);
        ++count;
    }

    EXPECT_EQ(count, 7u);
    EXPECT_EQ(seenKeys.size(), 7u);
    EXPECT_FALSE(seenKeys.contains(2));
    EXPECT_FALSE(seenKeys.contains(5));
    EXPECT_FALSE(seenKeys.contains(8));
}

TEST(WTF_InlineMap, RemoveWithStrings)
{
    // Remove works correctly with String keys.
    InlineMap<String, unsigned, 5, StringHash> map;

    map.add("one"_s, 1);
    map.add("two"_s, 2);
    map.add("three"_s, 3);

    EXPECT_TRUE(map.remove("two"_s));
    EXPECT_EQ(map.size(), 2u);
    EXPECT_TRUE(map.contains("one"_s));
    EXPECT_FALSE(map.contains("two"_s));
    EXPECT_TRUE(map.contains("three"_s));

    EXPECT_FALSE(map.remove("four"_s));
    EXPECT_FALSE(map.remove("two"_s));
}

TEST(WTF_InlineMap, GrowAfterRemove)
{
    // The hash table can grow correctly after entries have been removed.
    InlineMap<unsigned, unsigned, 3, IntHash<unsigned>> map;

    // Fill to trigger hashed mode
    for (unsigned i = 1; i <= 4; ++i)
        map.add(i, i * 10);

    EXPECT_FALSE(WTF::InlineMapAccessForTesting::isInline(map));

    // Remove some entries
    map.remove(2);
    map.remove(3);
    EXPECT_EQ(map.size(), 2u);

    // Add more entries to trigger growth
    for (unsigned i = 5; i <= 20; ++i)
        map.add(i, i * 10);

    // Verify all expected entries are present
    EXPECT_TRUE(map.contains(1));
    EXPECT_FALSE(map.contains(2));
    EXPECT_FALSE(map.contains(3));
    EXPECT_TRUE(map.contains(4));
    for (unsigned i = 5; i <= 20; ++i)
        EXPECT_TRUE(map.contains(i));
}

TEST(WTF_InlineMap, PointerKeys)
{
    // Raw pointers work as map keys.
    InlineMap<int*, int, 5> map;

    constexpr unsigned arraySize = 50;
    int array[arraySize];

    for (unsigned i = 0; i < arraySize; ++i) {
        array[i] = i;
        int* ptr = &array[i];
        EXPECT_FALSE(map.contains(ptr));
        auto result = map.add(ptr, i * 10);
        EXPECT_TRUE(result.isNewEntry);
        EXPECT_TRUE(map.contains(ptr));
    }

    EXPECT_EQ(map.size(), arraySize);

    for (unsigned i = 0; i < arraySize; ++i) {
        int* ptr = &array[i];
        auto it = map.find(ptr);
        EXPECT_FALSE(it == map.end());
        EXPECT_EQ(it->value, static_cast<int>(i * 10));
    }
}

TEST(WTF_InlineMap, ConstIteration)
{
    // Iteration works through a const reference to the map.
    InlineMap<unsigned, unsigned, 5, IntHash<unsigned>> map;

    for (unsigned i = 1; i <= 10; ++i)
        map.add(i, i * 10);

    const auto& constMap = map;
    unsigned count = 0;

    for (const auto& entry : constMap) {
        EXPECT_EQ(entry.value, entry.key * 10);
        ++count;
    }

    EXPECT_EQ(count, 10u);
}

TEST(WTF_InlineMap, ConstFind)
{
    // find() works through a const reference to the map.
    InlineMap<unsigned, unsigned, 5, IntHash<unsigned>> map;
    map.add(1, 100);

    const auto& constMap = map;

    auto it = constMap.find(1);
    EXPECT_FALSE(it == constMap.end());
    EXPECT_EQ(it->value, 100u);

    it = constMap.find(2);
    EXPECT_TRUE(it == constMap.end());
}

TEST(WTF_InlineMap, MoveOnlyValues)
{
    // Move-only types work as map values.
    InlineMap<unsigned, MoveOnly, 5, IntHash<unsigned>> map;

    for (size_t i = 0; i < 100; ++i) {
        MoveOnly moveOnly(i + 1);
        auto result = map.add(static_cast<unsigned>(i + 1), WTF::move(moveOnly));
        EXPECT_TRUE(result.isNewEntry);
    }

    EXPECT_EQ(map.size(), 100u);

    for (size_t i = 0; i < 100; ++i) {
        auto it = map.find(static_cast<unsigned>(i + 1));
        ASSERT_FALSE(it == map.end());
        EXPECT_EQ(it->value.value(), i + 1);
    }
}

TEST(WTF_InlineMap, MoveOnlyKeys)
{
    // Move-only types work as map keys, including duplicate detection.
    InlineMap<MoveOnly, unsigned, 5, DefaultHash<MoveOnly>> map;

    for (size_t i = 0; i < 100; ++i) {
        MoveOnly moveOnly(i + 1);
        auto result = map.add(WTF::move(moveOnly), static_cast<unsigned>(i + 1));
        EXPECT_TRUE(result.isNewEntry);
    }

    EXPECT_EQ(map.size(), 100u);

    for (size_t i = 0; i < 100; ++i) {
        auto it = map.find(MoveOnly(i + 1));
        ASSERT_FALSE(it == map.end());
        EXPECT_EQ(it->value, static_cast<unsigned>(i + 1));
    }

    // Verify duplicate add doesn't insert
    for (size_t i = 0; i < 100; ++i)
        EXPECT_FALSE(map.add(MoveOnly(i + 1), static_cast<unsigned>(i + 1)).isNewEntry);
}

namespace {

template<typename T> struct ZeroHash : public IntHash<T> {
    static unsigned hash(const T&) { return 0; }
};

} // anonymous namespace

TEST(WTF_InlineMap, HashCollisions)
{
    // All entries remain accessible even when every key hashes to the same bucket.
    // Use a hash that always returns 0 to force all entries into the same bucket
    InlineMap<unsigned, unsigned, 5, ZeroHash<unsigned>> map;

    // Add enough entries to trigger hashed mode
    for (unsigned i = 1; i <= 20; ++i) {
        auto result = map.add(i, i * 10);
        EXPECT_TRUE(result.isNewEntry);
    }

    EXPECT_EQ(map.size(), 20u);

    // Verify all entries are still accessible despite hash collisions
    for (unsigned i = 1; i <= 20; ++i) {
        EXPECT_TRUE(map.contains(i));
        auto it = map.find(i);
        ASSERT_FALSE(it == map.end());
        EXPECT_EQ(it->value, i * 10);
    }

    // Verify non-existent key lookup
    EXPECT_FALSE(map.contains(100));
}

TEST(WTF_InlineMap, IteratorComparison)
{
    // Iterator == and \!= operators work correctly, including const conversions.
    InlineMap<unsigned, unsigned, 5, IntHash<unsigned>> map;
    map.add(1, 100);

    ASSERT_TRUE(map.begin() != map.end());
    ASSERT_FALSE(map.begin() == map.end());

    InlineMap<unsigned, unsigned, 5, IntHash<unsigned>>::const_iterator begin = map.begin();
    ASSERT_TRUE(begin == map.begin());
    ASSERT_TRUE(map.begin() == begin);
    ASSERT_TRUE(begin != map.end());
    ASSERT_TRUE(map.end() != begin);
    ASSERT_FALSE(begin != map.begin());
    ASSERT_FALSE(map.begin() != begin);
    ASSERT_FALSE(begin == map.end());
    ASSERT_FALSE(map.end() == begin);
}

namespace {

class DestructorCounter {
public:
    static unsigned destructorCount;

    struct TestingScope {
        TestingScope() { destructorCount = 0; }
    };

    DestructorCounter() = default;
    DestructorCounter(unsigned value)
        : m_value(value)
    { }

    DestructorCounter(DestructorCounter&& other)
        : m_value(other.m_value)
    {
        other.m_value = 0;
    }

    DestructorCounter& operator=(DestructorCounter&& other)
    {
        m_value = other.m_value;
        other.m_value = 0;
        return *this;
    }

    ~DestructorCounter()
    {
        if (m_value != emptyValue())
            ++destructorCount;
    }

    unsigned value() const { return m_value; }

    static constexpr unsigned emptyValue() { return std::numeric_limits<unsigned>::max(); }

private:
    unsigned m_value { emptyValue() };
};

unsigned DestructorCounter::destructorCount = 0;

} // anonymous namespace

TEST(WTF_InlineMap, DestructorCalledOnClear)
{
    // Value destructors are called when the map is destroyed (inline mode).
    DestructorCounter::TestingScope scope;

    {
        InlineMap<unsigned, DestructorCounter, 5, IntHash<unsigned>> map;

        for (unsigned i = 1; i <= 3; ++i)
            map.add(i, DestructorCounter(i));

        EXPECT_EQ(map.size(), 3u);
        EXPECT_EQ(DestructorCounter::destructorCount, 3u); // Moved-from temporaries
    }

    // Destructor should be called for all 3 entries when map is destroyed
    EXPECT_EQ(DestructorCounter::destructorCount, 6u);
}

TEST(WTF_InlineMap, DestructorCalledOnClearAfterGrowth)
{
    // Value destructors are called for all live entries after growth (hashed mode).
    DestructorCounter::TestingScope scope;
    unsigned countBeforeDestruction = 0;

    {
        InlineMap<unsigned, DestructorCounter, 5, IntHash<unsigned>> map;

        for (unsigned i = 1; i <= 100; ++i)
            map.add(i, DestructorCounter(i));

        EXPECT_EQ(map.size(), 100u);

        // Record the count before map destruction. This includes temporaries from add()
        // calls as well as internal temporaries created during hash table growth.
        countBeforeDestruction = DestructorCounter::destructorCount;
    }

    // Map destruction should destroy exactly 100 live entries
    EXPECT_EQ(DestructorCounter::destructorCount, countBeforeDestruction + 100u);
}

TEST(WTF_InlineMap, StringKeys)
{
    // String objects work as map keys.
    InlineMap<String, unsigned, 5, StringHash> map;

    map.add("one"_s, 1);
    map.add("two"_s, 2);
    map.add("three"_s, 3);

    EXPECT_EQ(map.size(), 3u);
    EXPECT_TRUE(map.contains("one"_s));
    EXPECT_TRUE(map.contains("two"_s));
    EXPECT_TRUE(map.contains("three"_s));
    EXPECT_FALSE(map.contains("four"_s));

    EXPECT_EQ(map.find("one"_s)->value, 1u);
    EXPECT_EQ(map.find("two"_s)->value, 2u);
    EXPECT_EQ(map.find("three"_s)->value, 3u);
}

TEST(WTF_InlineMap, StringValues)
{
    // String objects work as map values.
    InlineMap<unsigned, String, 5, IntHash<unsigned>> map;

    map.add(1, "one"_s);
    map.add(2, "two"_s);
    map.add(3, "three"_s);

    EXPECT_EQ(map.size(), 3u);
    EXPECT_EQ(map.find(1)->value, "one"_s);
    EXPECT_EQ(map.find(2)->value, "two"_s);
    EXPECT_EQ(map.find(3)->value, "three"_s);
}

TEST(WTF_InlineMap, StringKeysAndValues)
{
    // String-to-String map works, and duplicate add preserves the original value.
    InlineMap<String, String, 5, StringHash> map;

    map.add("key1"_s, "value1"_s);
    map.add("key2"_s, "value2"_s);
    map.add("key3"_s, "value3"_s);

    EXPECT_EQ(map.size(), 3u);
    EXPECT_EQ(map.find("key1"_s)->value, "value1"_s);
    EXPECT_EQ(map.find("key2"_s)->value, "value2"_s);
    EXPECT_EQ(map.find("key3"_s)->value, "value3"_s);

    // Duplicate add should not overwrite
    auto result = map.add("key1"_s, "newvalue"_s);
    EXPECT_FALSE(result.isNewEntry);
    EXPECT_EQ(map.find("key1"_s)->value, "value1"_s);
}

TEST(WTF_InlineMap, StringKeysGrowth)
{
    // String keys survive growth from inline to hashed mode.
    InlineMap<String, unsigned, 5, StringHash> map;

    // Add enough entries to trigger growth to hashed mode
    for (unsigned i = 1; i <= 100; ++i)
        map.add(makeString("key"_s, i), i);

    EXPECT_EQ(map.size(), 100u);

    // Verify all entries are still accessible
    for (unsigned i = 1; i <= 100; ++i) {
        auto key = makeString("key"_s, i);
        EXPECT_TRUE(map.contains(key));
        auto it = map.find(key);
        ASSERT_FALSE(it == map.end());
        EXPECT_EQ(it->value, i);
    }

    EXPECT_FALSE(map.contains("key101"_s));
}

TEST(WTF_InlineMap, RefPtrKeys)
{
    // RefPtr objects work as map keys, looked up by raw pointer.
    DerivedRefLogger a("a");
    DerivedRefLogger b("b");
    DerivedRefLogger c("c");

    InlineMap<RefPtr<RefLogger>, int, 5> map;

    map.add(RefPtr<RefLogger>(&a), 1);
    map.add(RefPtr<RefLogger>(&b), 2);
    map.add(RefPtr<RefLogger>(&c), 3);

    EXPECT_EQ(map.size(), 3u);
    EXPECT_TRUE(map.contains(&a));
    EXPECT_TRUE(map.contains(&b));
    EXPECT_TRUE(map.contains(&c));

    EXPECT_EQ(map.find(&a)->value, 1);
    EXPECT_EQ(map.find(&b)->value, 2);
    EXPECT_EQ(map.find(&c)->value, 3);
}

TEST(WTF_InlineMap, RefPtrValues)
{
    // RefPtr objects work as map values.
    DerivedRefLogger a("a");
    DerivedRefLogger b("b");

    InlineMap<unsigned, RefPtr<RefLogger>, 5, IntHash<unsigned>> map;

    map.add(1, RefPtr<RefLogger>(&a));
    map.add(2, RefPtr<RefLogger>(&b));

    EXPECT_EQ(map.size(), 2u);
    EXPECT_EQ(map.find(1)->value.get(), &a);
    EXPECT_EQ(map.find(2)->value.get(), &b);
}

TEST(WTF_InlineMap, RefKeys)
{
    // Ref objects work as map keys and are properly deref'd on destruction.
    RefLogger a("a");

    {
        InlineMap<Ref<RefLogger>, int, 5> map;

        Ref<RefLogger> ref(a);
        map.add(WTF::move(ref), 1);

        EXPECT_EQ(map.size(), 1u);

        // Verify through iteration since we don't have translator support
        bool found = false;
        for (auto& entry : map) {
            if (entry.key.ptr() == &a) {
                EXPECT_EQ(entry.value, 1);
                found = true;
            }
        }
        EXPECT_TRUE(found);
    }

    EXPECT_STREQ("ref(a) deref(a) ", takeLogStr().c_str());
}

TEST(WTF_InlineMap, RefValues)
{
    // Ref objects work as map values and are properly deref'd on destruction.
    RefLogger a("a");

    {
        InlineMap<unsigned, Ref<RefLogger>, 5, IntHash<unsigned>> map;

        Ref<RefLogger> ref(a);
        map.add(1, WTF::move(ref));

        EXPECT_EQ(map.size(), 1u);
        EXPECT_EQ(map.find(1)->value.ptr(), &a);
    }

    EXPECT_STREQ("ref(a) deref(a) ", takeLogStr().c_str());
}

TEST(WTF_InlineMap, RefKeysGrowth)
{
    // Ref keys work correctly through growth transitions.
    // Test that Ref keys work correctly through growth transitions
    Vector<Ref<RefLogger>> loggers;
    for (int i = 0; i < 50; ++i)
        loggers.append(adoptRef(*new RefLogger("a")));

    {
        InlineMap<Ref<RefLogger>, int, 5> map;

        for (int i = 0; i < 50; ++i) {
            Ref<RefLogger> ref = loggers[i].copyRef();
            map.add(WTF::move(ref), i + 1);
        }

        EXPECT_EQ(map.size(), 50u);

        // Verify all entries through iteration
        unsigned count = 0;
        for (auto& entry : map) {
            ++count;
            // Just verify values are in expected range
            EXPECT_GE(entry.value, 1);
            EXPECT_LE(entry.value, 50);
        }
        EXPECT_EQ(count, 50u);
    }
}

TEST(WTF_InlineMap, ClearEmpty)
{
    // Clearing an already-empty map is a no-op.
    InlineMap<unsigned, unsigned, 5, IntHash<unsigned>> map;

    map.clear();

    EXPECT_TRUE(map.isEmpty());
    EXPECT_EQ(map.size(), 0u);
}

TEST(WTF_InlineMap, ClearLinearMode)
{
    // Clearing in inline mode removes entries but preserves inline storage.
    InlineMap<unsigned, unsigned, 3, IntHash<unsigned>> map;

    map.add(1, 10);
    map.add(2, 20);
    EXPECT_TRUE(WTF::InlineMapAccessForTesting::isInline(map));
    EXPECT_EQ(map.size(), 2u);

    map.clear();

    // Storage is preserved, just cleared
    EXPECT_TRUE(WTF::InlineMapAccessForTesting::isInline(map));
    EXPECT_TRUE(map.isEmpty());
    EXPECT_EQ(map.size(), 0u);

    // Should be able to add entries again after clear
    map.add(3, 30);
    EXPECT_EQ(map.size(), 1u);
    EXPECT_TRUE(map.contains(3));
    EXPECT_FALSE(map.contains(1));
    EXPECT_FALSE(map.contains(2));
}

TEST(WTF_InlineMap, ClearHashedMode)
{
    // Clearing in hashed mode frees heap storage and transitions back to inline.
    InlineMap<unsigned, unsigned, 5, IntHash<unsigned>> map;

    for (unsigned i = 1; i <= 20; ++i)
        map.add(i, i * 10);

    EXPECT_FALSE(WTF::InlineMapAccessForTesting::isInline(map));
    EXPECT_EQ(map.size(), 20u);

    map.clear();

    // Should transition back to inline
    EXPECT_TRUE(WTF::InlineMapAccessForTesting::isInline(map));
    EXPECT_TRUE(map.isEmpty());
    EXPECT_EQ(map.size(), 0u);

    // Should be able to add entries again after clear
    for (unsigned i = 100; i <= 104; ++i)
        map.add(i, i);

    EXPECT_EQ(map.size(), 5u);
    EXPECT_TRUE(WTF::InlineMapAccessForTesting::isInline(map));
    for (unsigned i = 100; i <= 104; ++i)
        EXPECT_TRUE(map.contains(i));
    EXPECT_FALSE(map.contains(1));

    // Adding one more should transition to hashed
    map.add(105, 105);
    EXPECT_FALSE(WTF::InlineMapAccessForTesting::isInline(map));
}

TEST(WTF_InlineMap, ClearWithStrings)
{
    // Clearing works correctly with String key/value types.
    InlineMap<String, String, 5, StringHash> map;

    map.add("key1"_s, "value1"_s);
    map.add("key2"_s, "value2"_s);
    map.add("key3"_s, "value3"_s);

    EXPECT_EQ(map.size(), 3u);

    map.clear();

    EXPECT_TRUE(map.isEmpty());
    EXPECT_FALSE(map.contains("key1"_s));
}

TEST(WTF_InlineMap, ReserveInitialCapacityZero)
{
    // Reserving zero capacity keeps the map in inline mode.
    InlineMap<unsigned, unsigned, 5, IntHash<unsigned>> map;

    map.reserveInitialCapacity(0);

    EXPECT_TRUE(WTF::InlineMapAccessForTesting::isInline(map));
    EXPECT_TRUE(map.isEmpty());
}

TEST(WTF_InlineMap, ReserveInitialCapacityLinear)
{
    // Reserving within inline capacity keeps inline storage.
    InlineMap<unsigned, unsigned, 3, IntHash<unsigned>> map;

    map.reserveInitialCapacity(2);

    // Should allocate linear storage
    EXPECT_TRUE(WTF::InlineMapAccessForTesting::isInline(map));
    EXPECT_TRUE(map.isEmpty());

    // Should be able to add entries
    map.add(1, 10);
    map.add(2, 20);
    EXPECT_EQ(map.size(), 2u);
    EXPECT_TRUE(map.contains(1));
    EXPECT_TRUE(map.contains(2));
}

TEST(WTF_InlineMap, ReserveInitialCapacityHashed)
{
    // Reserving beyond inline capacity switches directly to hashed storage.
    InlineMap<unsigned, unsigned, 3, IntHash<unsigned>> map;

    map.reserveInitialCapacity(10);

    // Should allocate hashed storage directly
    EXPECT_FALSE(WTF::InlineMapAccessForTesting::isInline(map));
    EXPECT_TRUE(map.isEmpty());

    // Should be able to add entries without triggering growth
    for (unsigned i = 1; i <= 10; ++i)
        map.add(i, i * 10);

    EXPECT_EQ(map.size(), 10u);
    for (unsigned i = 1; i <= 10; ++i) {
        EXPECT_TRUE(map.contains(i));
        EXPECT_EQ(map.find(i)->value, i * 10);
    }
}

TEST(WTF_InlineMap, ReserveInitialCapacityLarge)
{
    // Reserving a large capacity pre-allocates hashed storage for many entries.
    InlineMap<unsigned, unsigned, 5, IntHash<unsigned>> map;

    map.reserveInitialCapacity(100);

    EXPECT_FALSE(WTF::InlineMapAccessForTesting::isInline(map));
    EXPECT_TRUE(map.isEmpty());

    // Add all 100 entries
    for (unsigned i = 1; i <= 100; ++i)
        map.add(i, i * 10);

    EXPECT_EQ(map.size(), 100u);
    for (unsigned i = 1; i <= 100; ++i)
        EXPECT_TRUE(map.contains(i));
}

TEST(WTF_InlineMap, ValuesIteration)
{
    // The values() range visits every value exactly once.
    InlineMap<unsigned, unsigned, 5, IntHash<unsigned>> map;

    for (unsigned i = 1; i <= 10; ++i)
        map.add(i, i * 10);

    unsigned sum = 0;
    unsigned count = 0;
    for (auto& value : map.values()) {
        sum += value;
        ++count;
    }

    EXPECT_EQ(count, 10u);
    // Sum of 10 + 20 + ... + 100 = 550
    EXPECT_EQ(sum, 550u);
}

TEST(WTF_InlineMap, ValuesIterationModify)
{
    // Values can be modified in-place through the values() iterator.
    InlineMap<unsigned, unsigned, 5, IntHash<unsigned>> map;

    for (unsigned i = 1; i <= 5; ++i)
        map.add(i, i);

    // Modify values through the values iterator
    for (auto& value : map.values())
        value *= 10;

    // Verify modifications
    for (unsigned i = 1; i <= 5; ++i)
        EXPECT_EQ(map.find(i)->value, i * 10);
}

TEST(WTF_InlineMap, ValuesIterationEmpty)
{
    // The values() range on an empty map produces zero iterations.
    InlineMap<unsigned, unsigned, 5, IntHash<unsigned>> map;

    unsigned count = 0;
    for (auto& value : map.values()) {
        UNUSED_PARAM(value);
        ++count;
    }

    EXPECT_EQ(count, 0u);
}

TEST(WTF_InlineMap, ValuesIterationConst)
{
    // The values() range works through a const reference.
    InlineMap<unsigned, unsigned, 5, IntHash<unsigned>> map;

    for (unsigned i = 1; i <= 5; ++i)
        map.add(i, i * 10);

    const auto& constMap = map;
    unsigned sum = 0;
    for (const auto& value : constMap.values())
        sum += value;

    EXPECT_EQ(sum, 150u); // 10 + 20 + 30 + 40 + 50
}

TEST(WTF_InlineMap, SwapBothEmpty)
{
    // Swapping two empty maps is a no-op.
    InlineMap<unsigned, unsigned, 5, IntHash<unsigned>> map1;
    InlineMap<unsigned, unsigned, 5, IntHash<unsigned>> map2;

    map1.swap(map2);

    EXPECT_TRUE(map1.isEmpty());
    EXPECT_TRUE(map2.isEmpty());
}

TEST(WTF_InlineMap, SwapOneEmpty)
{
    // Swapping a populated map with an empty one exchanges their contents.
    InlineMap<unsigned, unsigned, 5, IntHash<unsigned>> map1;
    InlineMap<unsigned, unsigned, 5, IntHash<unsigned>> map2;

    for (unsigned i = 1; i <= 5; ++i)
        map1.add(i, i * 10);

    EXPECT_EQ(map1.size(), 5u);
    EXPECT_TRUE(map2.isEmpty());

    map1.swap(map2);

    EXPECT_TRUE(map1.isEmpty());
    EXPECT_EQ(map2.size(), 5u);
    for (unsigned i = 1; i <= 5; ++i) {
        EXPECT_TRUE(map2.contains(i));
        EXPECT_EQ(map2.find(i)->value, i * 10);
    }
}

TEST(WTF_InlineMap, SwapBothPopulated)
{
    // Swapping two populated maps exchanges their contents.
    InlineMap<unsigned, unsigned, 5, IntHash<unsigned>> map1;
    InlineMap<unsigned, unsigned, 5, IntHash<unsigned>> map2;

    for (unsigned i = 1; i <= 5; ++i)
        map1.add(i, i * 10);

    for (unsigned i = 100; i <= 103; ++i)
        map2.add(i, i);

    EXPECT_EQ(map1.size(), 5u);
    EXPECT_EQ(map2.size(), 4u);

    map1.swap(map2);

    EXPECT_EQ(map1.size(), 4u);
    EXPECT_EQ(map2.size(), 5u);

    // Verify map1 now has map2's original content
    for (unsigned i = 100; i <= 103; ++i) {
        EXPECT_TRUE(map1.contains(i));
        EXPECT_EQ(map1.find(i)->value, i);
    }
    EXPECT_FALSE(map1.contains(1));

    // Verify map2 now has map1's original content
    for (unsigned i = 1; i <= 5; ++i) {
        EXPECT_TRUE(map2.contains(i));
        EXPECT_EQ(map2.find(i)->value, i * 10);
    }
    EXPECT_FALSE(map2.contains(100));
}

TEST(WTF_InlineMap, SwapWithStrings)
{
    // Swap works correctly with String key/value types.
    InlineMap<String, String, 5, StringHash> map1;
    InlineMap<String, String, 5, StringHash> map2;

    map1.add("key1"_s, "value1"_s);
    map1.add("key2"_s, "value2"_s);

    map2.add("other"_s, "data"_s);

    map1.swap(map2);

    EXPECT_EQ(map1.size(), 1u);
    EXPECT_EQ(map2.size(), 2u);

    EXPECT_TRUE(map1.contains("other"_s));
    EXPECT_EQ(map1.find("other"_s)->value, "data"_s);

    EXPECT_TRUE(map2.contains("key1"_s));
    EXPECT_TRUE(map2.contains("key2"_s));
}

// --- PackedRefPtr key tests (matching production use in VariableEnvironment) ---

TEST(WTF_InlineMap, PackedRefPtrKeysBasic)
{
    // PackedRefPtr<StringImpl> keys work for basic add/find/contains.
    Vector<String> strings;
    strings.append("alpha"_s);
    strings.append("beta"_s);
    strings.append("gamma"_s);

    InlineMap<PackedRefPtr<StringImpl>, unsigned, 5> map;

    for (unsigned i = 0; i < strings.size(); ++i) {
        auto result = map.add(strings[i].impl(), i + 1);
        EXPECT_TRUE(result.isNewEntry);
    }

    EXPECT_TRUE(WTF::InlineMapAccessForTesting::isInline(map));
    EXPECT_EQ(map.size(), 3u);

    for (unsigned i = 0; i < strings.size(); ++i) {
        EXPECT_TRUE(map.contains(strings[i].impl()));
        auto it = map.find(strings[i].impl());
        ASSERT_FALSE(it == map.end());
        EXPECT_EQ(it->value, i + 1);
    }

    EXPECT_FALSE(map.contains(String("delta"_s).impl()));
}

TEST(WTF_InlineMap, PackedRefPtrKeysGrowth)
{
    // PackedRefPtr keys survive growth from inline to hashed mode.
    constexpr unsigned count = 50;
    Vector<String> strings;
    for (unsigned i = 0; i < count; ++i)
        strings.append(makeString("key_"_s, i));

    InlineMap<PackedRefPtr<StringImpl>, unsigned, 5> map;

    for (unsigned i = 0; i < count; ++i) {
        auto result = map.add(strings[i].impl(), i * 10);
        EXPECT_TRUE(result.isNewEntry);
    }

    EXPECT_FALSE(WTF::InlineMapAccessForTesting::isInline(map));
    EXPECT_EQ(map.size(), count);

    for (unsigned i = 0; i < count; ++i) {
        EXPECT_TRUE(map.contains(strings[i].impl()));
        auto it = map.find(strings[i].impl());
        ASSERT_FALSE(it == map.end());
        EXPECT_EQ(it->value, i * 10);
    }

    EXPECT_FALSE(map.contains(String("nonexistent"_s).impl()));
}

TEST(WTF_InlineMap, PackedRefPtrKeysRemoveAndReinsert)
{
    // PackedRefPtr keys can be removed and re-inserted with new values.
    constexpr unsigned count = 20;
    Vector<String> strings;
    for (unsigned i = 0; i < count; ++i)
        strings.append(makeString("var_"_s, i));

    InlineMap<PackedRefPtr<StringImpl>, unsigned, 5> map;

    for (unsigned i = 0; i < count; ++i)
        map.add(strings[i].impl(), i);

    EXPECT_FALSE(WTF::InlineMapAccessForTesting::isInline(map));

    // Remove even-indexed entries
    for (unsigned i = 0; i < count; i += 2)
        EXPECT_TRUE(map.remove(strings[i].impl()));

    EXPECT_EQ(map.size(), count / 2);

    // Verify odd-indexed entries are still present
    for (unsigned i = 1; i < count; i += 2) {
        EXPECT_TRUE(map.contains(strings[i].impl()));
        EXPECT_EQ(map.find(strings[i].impl())->value, i);
    }

    // Re-add even-indexed entries with new values
    for (unsigned i = 0; i < count; i += 2) {
        auto result = map.add(strings[i].impl(), i + 1000);
        EXPECT_TRUE(result.isNewEntry);
    }

    EXPECT_EQ(map.size(), count);

    // Verify all entries
    for (unsigned i = 0; i < count; ++i) {
        EXPECT_TRUE(map.contains(strings[i].impl()));
        unsigned expectedValue = (i % 2) ? i : i + 1000;
        EXPECT_EQ(map.find(strings[i].impl())->value, expectedValue);
    }
}

TEST(WTF_InlineMap, PackedRefPtrKeysCopy)
{
    // Copying a map with PackedRefPtr keys produces an independent copy.
    constexpr unsigned count = 20;
    Vector<String> strings;
    for (unsigned i = 0; i < count; ++i)
        strings.append(makeString("name_"_s, i));

    InlineMap<PackedRefPtr<StringImpl>, unsigned, 5> map1;

    for (unsigned i = 0; i < count; ++i)
        map1.add(strings[i].impl(), i);

    EXPECT_FALSE(WTF::InlineMapAccessForTesting::isInline(map1));

    InlineMap<PackedRefPtr<StringImpl>, unsigned, 5> map2(map1);

    EXPECT_EQ(map1.size(), count);
    EXPECT_EQ(map2.size(), count);

    for (unsigned i = 0; i < count; ++i) {
        EXPECT_TRUE(map1.contains(strings[i].impl()));
        EXPECT_TRUE(map2.contains(strings[i].impl()));
        EXPECT_EQ(map1.find(strings[i].impl())->value, i);
        EXPECT_EQ(map2.find(strings[i].impl())->value, i);
    }

    // Modifying copy should not affect original
    map2.add(String("extra"_s).impl(), 999);
    EXPECT_EQ(map1.size(), count);
    EXPECT_EQ(map2.size(), count + 1);
}

// --- Stress tests ---

TEST(WTF_InlineMap, StressInsertions)
{
    // Inserting 1000 entries works and all are retrievable.
    InlineMap<unsigned, unsigned, 5, IntHash<unsigned>> map;

    for (unsigned i = 1; i <= 1000; ++i) {
        auto result = map.add(i, i * 10);
        EXPECT_TRUE(result.isNewEntry);
    }

    EXPECT_FALSE(WTF::InlineMapAccessForTesting::isInline(map));
    EXPECT_EQ(map.size(), 1000u);

    for (unsigned i = 1; i <= 1000; ++i) {
        EXPECT_TRUE(map.contains(i));
        auto it = map.find(i);
        ASSERT_FALSE(it == map.end());
        EXPECT_EQ(it->value, i * 10);
    }

    EXPECT_FALSE(map.contains(1001));
}

TEST(WTF_InlineMap, StressInsertRemoveReinsert)
{
    // Bulk remove of odd keys and re-insert with new values preserves integrity.
    InlineMap<unsigned, unsigned, 5, IntHash<unsigned>> map;

    // Add 200 entries
    for (unsigned i = 1; i <= 200; ++i)
        map.add(i, i);

    EXPECT_EQ(map.size(), 200u);

    // Remove odd-keyed entries
    for (unsigned i = 1; i <= 200; i += 2)
        EXPECT_TRUE(map.remove(i));

    EXPECT_EQ(map.size(), 100u);

    // Verify even entries remain, odd entries gone
    for (unsigned i = 1; i <= 200; ++i) {
        if (!(i % 2)) {
            EXPECT_TRUE(map.contains(i));
            EXPECT_EQ(map.find(i)->value, i);
        } else
            EXPECT_FALSE(map.contains(i));
    }

    // Re-add odd entries with new values
    for (unsigned i = 1; i <= 200; i += 2) {
        auto result = map.add(i, i + 1000);
        EXPECT_TRUE(result.isNewEntry);
    }

    EXPECT_EQ(map.size(), 200u);

    // Verify all entries
    for (unsigned i = 1; i <= 200; ++i) {
        EXPECT_TRUE(map.contains(i));
        unsigned expectedValue = (i % 2) ? i + 1000 : i;
        EXPECT_EQ(map.find(i)->value, expectedValue);
    }
}

TEST(WTF_InlineMap, StressRemoveAll)
{
    // Removing all 500 entries then re-adding them works correctly.
    InlineMap<unsigned, unsigned, 5, IntHash<unsigned>> map;

    // Add 500 entries
    for (unsigned i = 1; i <= 500; ++i)
        map.add(i, i * 10);

    EXPECT_EQ(map.size(), 500u);

    // Remove all one by one
    for (unsigned i = 1; i <= 500; ++i)
        EXPECT_TRUE(map.remove(i));

    EXPECT_EQ(map.size(), 0u);
    EXPECT_TRUE(map.isEmpty());

    for (unsigned i = 1; i <= 500; ++i)
        EXPECT_FALSE(map.contains(i));

    // Re-add 500 entries with different values
    for (unsigned i = 1; i <= 500; ++i) {
        auto result = map.add(i, i + 5000);
        EXPECT_TRUE(result.isNewEntry);
    }

    EXPECT_EQ(map.size(), 500u);

    for (unsigned i = 1; i <= 500; ++i) {
        EXPECT_TRUE(map.contains(i));
        EXPECT_EQ(map.find(i)->value, i + 5000);
    }
}

TEST(WTF_InlineMap, DuplicateAddHashedMode)
{
    // Duplicate adds in hashed mode preserve original values.
    InlineMap<unsigned, unsigned, 5, IntHash<unsigned>> map;

    for (unsigned i = 1; i <= 20; ++i)
        map.add(i, i * 10);

    EXPECT_FALSE(WTF::InlineMapAccessForTesting::isInline(map));
    EXPECT_EQ(map.size(), 20u);

    // Attempt duplicate adds
    for (unsigned i = 1; i <= 20; ++i) {
        auto result = map.add(i, i * 100);
        EXPECT_FALSE(result.isNewEntry);
        EXPECT_EQ(result.iterator->value, i * 10); // Original value preserved
    }

    EXPECT_EQ(map.size(), 20u);
}

TEST(WTF_InlineMap, IterationInlineMode)
{
    // Iteration visits all entries while still in inline mode.
    InlineMap<unsigned, unsigned, 5, IntHash<unsigned>> map;

    for (unsigned i = 1; i <= 3; ++i)
        map.add(i, i * 10);

    EXPECT_TRUE(WTF::InlineMapAccessForTesting::isInline(map));

    HashSet<unsigned, IntHash<unsigned>, WTF::UnsignedWithZeroKeyHashTraits<unsigned>> seenKeys;
    unsigned count = 0;

    for (auto& entry : map) {
        seenKeys.add(entry.key);
        EXPECT_EQ(entry.value, entry.key * 10);
        ++count;
    }

    EXPECT_EQ(count, 3u);
    EXPECT_EQ(seenKeys.size(), 3u);
    for (unsigned i = 1; i <= 3; ++i)
        EXPECT_TRUE(seenKeys.contains(i));
}

TEST(WTF_InlineMap, MoveConstructionInlineMode)
{
    // Move construction in inline mode transfers entries and preserves inline storage.
    InlineMap<unsigned, unsigned, 5, IntHash<unsigned>> map1;

    for (unsigned i = 1; i <= 3; ++i)
        map1.add(i, i * 10);

    EXPECT_TRUE(WTF::InlineMapAccessForTesting::isInline(map1));

    InlineMap<unsigned, unsigned, 5, IntHash<unsigned>> map2(WTF::move(map1));

    EXPECT_TRUE(map1.isEmpty());
    EXPECT_TRUE(WTF::InlineMapAccessForTesting::isInline(map1));
    EXPECT_EQ(map2.size(), 3u);
    EXPECT_TRUE(WTF::InlineMapAccessForTesting::isInline(map2));

    for (unsigned i = 1; i <= 3; ++i) {
        EXPECT_TRUE(map2.contains(i));
        EXPECT_EQ(map2.find(i)->value, i * 10);
    }
}

TEST(WTF_InlineMap, MoveConstructionHashedMode)
{
    // Move construction in hashed mode steals the heap pointer.
    InlineMap<unsigned, unsigned, 5, IntHash<unsigned>> map1;

    for (unsigned i = 1; i <= 20; ++i)
        map1.add(i, i * 10);

    EXPECT_FALSE(WTF::InlineMapAccessForTesting::isInline(map1));

    InlineMap<unsigned, unsigned, 5, IntHash<unsigned>> map2(WTF::move(map1));

    EXPECT_TRUE(map1.isEmpty());
    EXPECT_TRUE(WTF::InlineMapAccessForTesting::isInline(map1)); // Reset to inline after move
    EXPECT_EQ(map2.size(), 20u);
    EXPECT_FALSE(WTF::InlineMapAccessForTesting::isInline(map2)); // Stole heap pointer

    for (unsigned i = 1; i <= 20; ++i) {
        EXPECT_TRUE(map2.contains(i));
        EXPECT_EQ(map2.find(i)->value, i * 10);
    }
}

TEST(WTF_InlineMap, MoveAssignmentInlineToInline)
{
    // Move assignment between two inline maps works correctly.
    InlineMap<unsigned, unsigned, 5, IntHash<unsigned>> map1;
    InlineMap<unsigned, unsigned, 5, IntHash<unsigned>> map2;

    for (unsigned i = 1; i <= 3; ++i)
        map1.add(i, i * 10);

    map2.add(100, 1000);

    EXPECT_TRUE(WTF::InlineMapAccessForTesting::isInline(map1));
    EXPECT_TRUE(WTF::InlineMapAccessForTesting::isInline(map2));

    map2 = WTF::move(map1);

    EXPECT_TRUE(map1.isEmpty());
    EXPECT_EQ(map2.size(), 3u);
    EXPECT_FALSE(map2.contains(100));

    for (unsigned i = 1; i <= 3; ++i) {
        EXPECT_TRUE(map2.contains(i));
        EXPECT_EQ(map2.find(i)->value, i * 10);
    }
}

TEST(WTF_InlineMap, SwapInlineAndHashed)
{
    // Swapping an inline map with a hashed map exchanges both content and storage mode.
    InlineMap<unsigned, unsigned, 5, IntHash<unsigned>> inlineMap;
    InlineMap<unsigned, unsigned, 5, IntHash<unsigned>> hashedMap;

    for (unsigned i = 1; i <= 3; ++i)
        inlineMap.add(i, i * 10);

    for (unsigned i = 100; i <= 120; ++i)
        hashedMap.add(i, i);

    EXPECT_TRUE(WTF::InlineMapAccessForTesting::isInline(inlineMap));
    EXPECT_FALSE(WTF::InlineMapAccessForTesting::isInline(hashedMap));

    inlineMap.swap(hashedMap);

    // inlineMap now has hashed content
    EXPECT_EQ(inlineMap.size(), 21u);
    EXPECT_FALSE(WTF::InlineMapAccessForTesting::isInline(inlineMap));
    for (unsigned i = 100; i <= 120; ++i) {
        EXPECT_TRUE(inlineMap.contains(i));
        EXPECT_EQ(inlineMap.find(i)->value, i);
    }
    EXPECT_FALSE(inlineMap.contains(1));

    // hashedMap now has inline content
    EXPECT_EQ(hashedMap.size(), 3u);
    EXPECT_TRUE(WTF::InlineMapAccessForTesting::isInline(hashedMap));
    for (unsigned i = 1; i <= 3; ++i) {
        EXPECT_TRUE(hashedMap.contains(i));
        EXPECT_EQ(hashedMap.find(i)->value, i * 10);
    }
    EXPECT_FALSE(hashedMap.contains(100));
}

TEST(WTF_InlineMap, ClearThenGrow)
{
    // A cleared map transitions to inline and can grow back to hashed.
    InlineMap<unsigned, unsigned, 5, IntHash<unsigned>> map;

    for (unsigned i = 1; i <= 20; ++i)
        map.add(i, i * 10);

    EXPECT_FALSE(WTF::InlineMapAccessForTesting::isInline(map));

    map.clear();

    EXPECT_TRUE(map.isEmpty());
    EXPECT_TRUE(WTF::InlineMapAccessForTesting::isInline(map));

    // Add enough entries to trigger growth back to hashed
    for (unsigned i = 1; i <= 100; ++i)
        map.add(i, i + 100);

    EXPECT_EQ(map.size(), 100u);
    EXPECT_FALSE(WTF::InlineMapAccessForTesting::isInline(map));

    for (unsigned i = 1; i <= 100; ++i) {
        EXPECT_TRUE(map.contains(i));
        EXPECT_EQ(map.find(i)->value, i + 100);
    }
}

TEST(WTF_InlineMap, CopyWithDeletedEntries)
{
    // Copying a map with deleted tombstones preserves them in the copy.
    InlineMap<unsigned, unsigned, 5, IntHash<unsigned>> map1;

    for (unsigned i = 1; i <= 20; ++i)
        map1.add(i, i * 10);

    EXPECT_FALSE(WTF::InlineMapAccessForTesting::isInline(map1));

    // Remove some entries to create deleted tombstones
    map1.remove(3);
    map1.remove(7);
    map1.remove(11);
    map1.remove(15);
    map1.remove(19);

    EXPECT_EQ(map1.size(), 15u);

    InlineMap<unsigned, unsigned, 5, IntHash<unsigned>> map2(map1);

    EXPECT_EQ(map2.size(), 15u);

    // Verify copy has exactly the right entries
    for (unsigned i = 1; i <= 20; ++i) {
        if (i == 3 || i == 7 || i == 11 || i == 15 || i == 19)
            EXPECT_FALSE(map2.contains(i));
        else {
            EXPECT_TRUE(map2.contains(i));
            EXPECT_EQ(map2.find(i)->value, i * 10);
        }
    }

    // Adding to copy should not affect original
    map2.add(3, 999);
    EXPECT_TRUE(map2.contains(3));
    EXPECT_FALSE(map1.contains(3));
}

TEST(WTF_InlineMap, RemoveLastInlineEntry)
{
    // Removing the sole inline entry leaves the map empty and still usable.
    InlineMap<unsigned, unsigned, 5, IntHash<unsigned>> map;

    map.add(42, 420);
    EXPECT_TRUE(WTF::InlineMapAccessForTesting::isInline(map));
    EXPECT_EQ(map.size(), 1u);

    EXPECT_TRUE(map.remove(42));
    EXPECT_EQ(map.size(), 0u);
    EXPECT_TRUE(map.isEmpty());
    EXPECT_FALSE(map.contains(42));

    // Map should still be usable
    map.add(99, 990);
    EXPECT_EQ(map.size(), 1u);
    EXPECT_TRUE(map.contains(99));
    EXPECT_EQ(map.find(99)->value, 990u);
}

// --- Shrink / deleted-count / transition-back-to-inline tests ---

TEST(WTF_InlineMap, ShrinkAfterRemovalTransitionsToInline)
{
    // Removing enough entries from hashed mode triggers shrink back to inline.
    // With InlineCapacity=5, adding 20 entries gives capacity=32.
    // Shrink triggers when m_size * 6 < capacity. At capacity=32, that's m_size < 5.33.
    // Since m_size=5 <= InlineCapacity=5, we transition to inline.
    InlineMap<unsigned, unsigned, 5, IntHash<unsigned>> map;

    for (unsigned i = 1; i <= 20; ++i)
        map.add(i, i * 10);

    EXPECT_FALSE(WTF::InlineMapAccessForTesting::isInline(map));
    EXPECT_EQ(map.size(), 20u);

    // Remove entries 6 through 20, leaving keys 1-5
    for (unsigned i = 6; i <= 20; ++i)
        EXPECT_TRUE(map.remove(i));

    EXPECT_EQ(map.size(), 5u);
    EXPECT_TRUE(WTF::InlineMapAccessForTesting::isInline(map));

    // All remaining entries should be accessible
    for (unsigned i = 1; i <= 5; ++i) {
        EXPECT_TRUE(map.contains(i));
        EXPECT_EQ(map.find(i)->value, i * 10);
    }
    for (unsigned i = 6; i <= 20; ++i)
        EXPECT_FALSE(map.contains(i));
}

TEST(WTF_InlineMap, ShrinkAfterRemovalReducesCapacity)
{
    // Removing entries reduces capacity but stays hashed when size > InlineCapacity.
    // With InlineCapacity=3, adding 100 entries gives capacity=256.
    // Remove down to 10 entries: should shrink but remain hashed since 10 > 3.
    InlineMap<unsigned, unsigned, 3, IntHash<unsigned>> map;

    for (unsigned i = 1; i <= 100; ++i)
        map.add(i, i * 10);

    EXPECT_FALSE(WTF::InlineMapAccessForTesting::isInline(map));
    unsigned originalCapacity = WTF::InlineMapAccessForTesting::capacity(map);

    // Remove entries, keeping 1-10
    for (unsigned i = 11; i <= 100; ++i)
        EXPECT_TRUE(map.remove(i));

    EXPECT_EQ(map.size(), 10u);
    EXPECT_FALSE(WTF::InlineMapAccessForTesting::isInline(map));
    EXPECT_LT(WTF::InlineMapAccessForTesting::capacity(map), originalCapacity);

    for (unsigned i = 1; i <= 10; ++i) {
        EXPECT_TRUE(map.contains(i));
        EXPECT_EQ(map.find(i)->value, i * 10);
    }
}

TEST(WTF_InlineMap, DeletedCountTracking)
{
    // Deleted count is incremented on remove and decremented when a deleted slot is reused.
    InlineMap<unsigned, unsigned, 3, IntHash<unsigned>> map;

    // Go to hashed mode
    for (unsigned i = 1; i <= 10; ++i)
        map.add(i, i * 10);

    EXPECT_FALSE(WTF::InlineMapAccessForTesting::isInline(map));
    EXPECT_EQ(WTF::InlineMapAccessForTesting::deletedCount(map), 0u);

    // Remove 2 entries (these won't trigger shrink since 8*6=48 is not < 16)
    EXPECT_TRUE(map.remove(1));
    EXPECT_TRUE(map.remove(2));
    EXPECT_EQ(map.size(), 8u);
    EXPECT_EQ(WTF::InlineMapAccessForTesting::deletedCount(map), 2u);

    // Re-add one of the removed keys — should reuse a deleted slot
    auto result = map.add(1, 100);
    EXPECT_TRUE(result.isNewEntry);
    EXPECT_EQ(WTF::InlineMapAccessForTesting::deletedCount(map), 1u);
    EXPECT_EQ(map.size(), 9u);
}

TEST(WTF_InlineMap, DeletedCountResetAfterRehash)
{
    // Deleted count resets to 0 after a rehash triggered by expansion.
    InlineMap<unsigned, unsigned, 3, IntHash<unsigned>> map;

    for (unsigned i = 1; i <= 10; ++i)
        map.add(i, i * 10);

    EXPECT_FALSE(WTF::InlineMapAccessForTesting::isInline(map));

    // Remove a couple entries to build up deleted count
    map.remove(1);
    map.remove(2);
    EXPECT_EQ(WTF::InlineMapAccessForTesting::deletedCount(map), 2u);

    // Add enough new entries to trigger expansion
    // Current: m_size=8, deletedCount=2, capacity=16
    // Expansion triggers when (8+2)*4 >= 16*3 -> 40 >= 48 -> false
    // After adding 4 more: m_size=12, deletedCount=2 -> (12+2)*4 = 56 >= 48 -> true
    for (unsigned i = 11; i <= 14; ++i)
        map.add(i, i * 10);

    // After expansion, deleted count should be 0
    EXPECT_EQ(WTF::InlineMapAccessForTesting::deletedCount(map), 0u);

    // All live entries should be accessible
    EXPECT_FALSE(map.contains(1));
    EXPECT_FALSE(map.contains(2));
    for (unsigned i = 3; i <= 14; ++i) {
        EXPECT_TRUE(map.contains(i));
        EXPECT_EQ(map.find(i)->value, i * 10);
    }
}

TEST(WTF_InlineMap, CompactOnlyWhenManyDeleted)
{
    // When many entries are deleted and new (non-reusable) keys are added,
    // the expansion check triggers. If shouldCompactOnly is true, the table
    // rehashes at the same capacity rather than doubling.
    InlineMap<unsigned, unsigned, 3, IntHash<unsigned>> map;

    // Build a larger table: add 24 entries to get capacity=32
    // (transitions: 4→cap8, 6→cap16, 12→cap32)
    for (unsigned i = 1; i <= 24; ++i)
        map.add(i, i * 10);

    EXPECT_FALSE(WTF::InlineMapAccessForTesting::isInline(map));
    EXPECT_EQ(WTF::InlineMapAccessForTesting::capacity(map), 32u);

    // Remove 20 entries, keeping only 4 live entries (keys 21-24).
    // shouldShrink: 4*6=24 < 32? Yes — but shrink happens one removal at a time.
    // At m_size=5: 5*6=30 < 32 → shrink to 16. deletedCount resets to 0.
    // Then at m_size=4 in cap=16: 4*6=24 not < 16 → no further shrink.
    for (unsigned i = 1; i <= 20; ++i)
        map.remove(i);

    // After shrinks, we should be at capacity=16 with 4 live entries.
    EXPECT_EQ(map.size(), 4u);

    // Now create deleted entries without triggering shrink.
    // Add 8 more entries (keys 25-32) to get m_size=12 at some capacity,
    // then remove 6 of them.
    for (unsigned i = 25; i <= 32; ++i)
        map.add(i, i * 10);

    // Remove 6 entries without hitting shrink threshold
    for (unsigned i = 25; i <= 30; ++i)
        map.remove(i);

    // Now we have 6 live entries and 6 deleted entries.
    EXPECT_EQ(map.size(), 6u);
    unsigned currentCapacity = WTF::InlineMapAccessForTesting::capacity(map);

    // Add new keys (that won't match any deleted slot's key) until expansion triggers.
    // Expansion triggers when (m_size + deletedCount) * 4 >= capacity * 3.
    // Each add of a new key into an empty slot: m_size++, deletedCount unchanged, sum increases.
    // Each add into a deleted slot: m_size++, deletedCount--, sum unchanged.
    // We keep adding until expansion happens.
    unsigned nextKey = 100;
    while (WTF::InlineMapAccessForTesting::capacity(map) == currentCapacity) {
        map.add(nextKey, nextKey * 10);
        ++nextKey;
    }

    // After expansion, deletedCount should be 0
    EXPECT_EQ(WTF::InlineMapAccessForTesting::deletedCount(map), 0u);

    // All live entries should be accessible
    for (unsigned i = 21; i <= 24; ++i)
        EXPECT_TRUE(map.contains(i));
    for (unsigned i = 31; i <= 32; ++i)
        EXPECT_TRUE(map.contains(i));
}

TEST(WTF_InlineMap, ClearTransitionsToInline)
{
    // Clearing a hashed-mode map transitions back to inline mode.
    InlineMap<unsigned, unsigned, 5, IntHash<unsigned>> map;

    for (unsigned i = 1; i <= 20; ++i)
        map.add(i, i * 10);

    EXPECT_FALSE(WTF::InlineMapAccessForTesting::isInline(map));

    map.clear();

    EXPECT_TRUE(WTF::InlineMapAccessForTesting::isInline(map));
    EXPECT_TRUE(map.isEmpty());
    EXPECT_EQ(map.size(), 0u);

    // Re-adding entries should work with normal inline→hashed lifecycle
    for (unsigned i = 1; i <= 5; ++i) {
        map.add(i, i);
        EXPECT_TRUE(WTF::InlineMapAccessForTesting::isInline(map));
    }

    map.add(6, 6);
    EXPECT_FALSE(WTF::InlineMapAccessForTesting::isInline(map));
}

TEST(WTF_InlineMap, ClearEmptyHashedTransitionsToInline)
{
    // Clearing an empty hashed-mode map (from reserveInitialCapacity) transitions to inline.
    InlineMap<unsigned, unsigned, 5, IntHash<unsigned>> map;

    map.reserveInitialCapacity(20);
    EXPECT_FALSE(WTF::InlineMapAccessForTesting::isInline(map));
    EXPECT_TRUE(map.isEmpty());

    map.clear();

    EXPECT_TRUE(WTF::InlineMapAccessForTesting::isInline(map));
    EXPECT_TRUE(map.isEmpty());

    // Should be usable as a fresh map
    map.add(1, 10);
    EXPECT_EQ(map.size(), 1u);
    EXPECT_TRUE(map.contains(1));
}

TEST(WTF_InlineMap, ShrinkToInlineWithStrings)
{
    // Shrink-to-inline transition works with String keys.
    InlineMap<String, unsigned, 5, StringHash> map;

    for (unsigned i = 1; i <= 20; ++i)
        map.add(makeString("key"_s, i), i);

    EXPECT_FALSE(WTF::InlineMapAccessForTesting::isInline(map));

    // Remove entries, keeping only 5
    for (unsigned i = 6; i <= 20; ++i)
        EXPECT_TRUE(map.remove(makeString("key"_s, i)));

    EXPECT_EQ(map.size(), 5u);
    EXPECT_TRUE(WTF::InlineMapAccessForTesting::isInline(map));

    // Verify remaining entries
    for (unsigned i = 1; i <= 5; ++i) {
        auto key = makeString("key"_s, i);
        EXPECT_TRUE(map.contains(key));
        EXPECT_EQ(map.find(key)->value, i);
    }
}

TEST(WTF_InlineMap, ShrinkPreservesDataIntegrity)
{
    // Exact key-value pairs survive the hashed→inline transition, and the map
    // can grow back to hashed afterwards.
    InlineMap<unsigned, unsigned, 5, IntHash<unsigned>> map;

    for (unsigned i = 1; i <= 50; ++i)
        map.add(i, i * 100);

    EXPECT_FALSE(WTF::InlineMapAccessForTesting::isInline(map));

    // Remove all but keys 10, 20, 30, 40, 50
    for (unsigned i = 1; i <= 50; ++i) {
        if (i % 10)
            map.remove(i);
    }

    EXPECT_EQ(map.size(), 5u);
    EXPECT_TRUE(WTF::InlineMapAccessForTesting::isInline(map));

    // Verify exact key-value pairs
    EXPECT_EQ(map.find(10)->value, 1000u);
    EXPECT_EQ(map.find(20)->value, 2000u);
    EXPECT_EQ(map.find(30)->value, 3000u);
    EXPECT_EQ(map.find(40)->value, 4000u);
    EXPECT_EQ(map.find(50)->value, 5000u);

    // Grow back to hashed
    for (unsigned i = 51; i <= 60; ++i)
        map.add(i, i * 100);

    EXPECT_FALSE(WTF::InlineMapAccessForTesting::isInline(map));
    EXPECT_EQ(map.size(), 15u);

    // Original entries still accessible
    EXPECT_EQ(map.find(10)->value, 1000u);
    EXPECT_EQ(map.find(50)->value, 5000u);
}

TEST(WTF_InlineMap, RepeatedGrowShrinkCycles)
{
    // Multiple cycles of grow-to-hashed then shrink-to-inline work correctly.
    InlineMap<unsigned, unsigned, 5, IntHash<unsigned>> map;
    unsigned nextKey = 1;

    for (int cycle = 0; cycle < 3; ++cycle) {
        // Add 20 entries to go hashed
        unsigned firstKey = nextKey;
        for (unsigned i = 0; i < 20; ++i) {
            map.add(nextKey, nextKey * 10);
            ++nextKey;
        }

        EXPECT_FALSE(WTF::InlineMapAccessForTesting::isInline(map));

        // Remove all but 2 entries from this batch
        for (unsigned i = firstKey; i < firstKey + 18; ++i)
            map.remove(i);

        // Verify the map is inline if small enough, and the remaining entries are correct
        if (map.size() <= 5)
            EXPECT_TRUE(WTF::InlineMapAccessForTesting::isInline(map));
        unsigned remaining1 = firstKey + 18;
        unsigned remaining2 = firstKey + 19;
        EXPECT_TRUE(map.contains(remaining1));
        EXPECT_TRUE(map.contains(remaining2));
    }

    // After 3 cycles, we have 6 entries (2 per cycle)
    EXPECT_EQ(map.size(), 6u);
}

TEST(WTF_InlineMap, RemoveAllOneByOneTriggersShrink)
{
    // Removing all entries one by one eventually transitions back to inline.
    InlineMap<unsigned, unsigned, 5, IntHash<unsigned>> map;

    for (unsigned i = 1; i <= 20; ++i)
        map.add(i, i * 10);

    EXPECT_FALSE(WTF::InlineMapAccessForTesting::isInline(map));

    bool becameInline = false;
    for (unsigned i = 1; i <= 20; ++i) {
        EXPECT_TRUE(map.remove(i));
        if (!becameInline && WTF::InlineMapAccessForTesting::isInline(map))
            becameInline = true;
    }

    EXPECT_TRUE(becameInline);
    EXPECT_TRUE(map.isEmpty());
    EXPECT_TRUE(WTF::InlineMapAccessForTesting::isInline(map));
}

TEST(WTF_InlineMap, DeletedCountWithCollisions)
{
    // Deleted count tracking works correctly under hash collisions.
    InlineMap<unsigned, unsigned, 5, ZeroHash<unsigned>> map;

    // All entries hash to bucket 0
    for (unsigned i = 1; i <= 10; ++i)
        map.add(i, i * 10);

    EXPECT_FALSE(WTF::InlineMapAccessForTesting::isInline(map));
    EXPECT_EQ(WTF::InlineMapAccessForTesting::deletedCount(map), 0u);

    // Remove 3 entries
    map.remove(3);
    map.remove(5);
    map.remove(7);
    EXPECT_EQ(WTF::InlineMapAccessForTesting::deletedCount(map), 3u);
    EXPECT_EQ(map.size(), 7u);

    // Re-add one of them — should reuse a deleted slot and decrement deletedCount
    map.add(3, 300);
    EXPECT_EQ(WTF::InlineMapAccessForTesting::deletedCount(map), 2u);
    EXPECT_EQ(map.size(), 8u);
    EXPECT_EQ(map.find(3)->value, 300u);

    // All remaining entries accessible
    for (unsigned i = 1; i <= 10; ++i) {
        if (i == 5 || i == 7)
            EXPECT_FALSE(map.contains(i));
        else
            EXPECT_TRUE(map.contains(i));
    }
}

TEST(WTF_InlineMap, ExpandWithDeletedEntriesPreservesData)
{
    // Expansion triggered by deleted entries filling the table preserves all live data.
    // We add entries until expansion triggers, then verify everything is intact.
    InlineMap<unsigned, unsigned, 3, IntHash<unsigned>> map;

    // Build up a table then create deleted entries
    for (unsigned i = 1; i <= 10; ++i)
        map.add(i, i * 10);

    EXPECT_FALSE(WTF::InlineMapAccessForTesting::isInline(map));

    // Remove entries but stay above shrink threshold
    map.remove(1);
    map.remove(2);
    map.remove(3);
    map.remove(4);
    // m_size=6, some deletedCount, some capacity
    EXPECT_EQ(map.size(), 6u);

    unsigned capacityBefore = WTF::InlineMapAccessForTesting::capacity(map);

    // Add new keys until expansion triggers (capacity changes)
    unsigned nextKey = 100;
    while (WTF::InlineMapAccessForTesting::capacity(map) == capacityBefore) {
        map.add(nextKey, nextKey * 10);
        ++nextKey;
    }

    // After expansion, deleted count should be 0
    EXPECT_EQ(WTF::InlineMapAccessForTesting::deletedCount(map), 0u);

    // All live entries preserved
    for (unsigned i = 5; i <= 10; ++i) {
        EXPECT_TRUE(map.contains(i));
        EXPECT_EQ(map.find(i)->value, i * 10);
    }
    for (unsigned i = 100; i < nextKey; ++i) {
        EXPECT_TRUE(map.contains(i));
        EXPECT_EQ(map.find(i)->value, i * 10);
    }
    for (unsigned i = 1; i <= 4; ++i)
        EXPECT_FALSE(map.contains(i));
}

TEST(WTF_InlineMap, MoveConstructionPreservesDeletedCount)
{
    // Move-constructing from a hashed map with deleted entries transfers deletedCount.
    InlineMap<unsigned, unsigned, 3, IntHash<unsigned>> map1;

    for (unsigned i = 1; i <= 10; ++i)
        map1.add(i, i * 10);

    EXPECT_FALSE(WTF::InlineMapAccessForTesting::isInline(map1));

    // Remove entries without triggering shrink
    map1.remove(1);
    map1.remove(2);
    EXPECT_EQ(WTF::InlineMapAccessForTesting::deletedCount(map1), 2u);

    InlineMap<unsigned, unsigned, 3, IntHash<unsigned>> map2(WTF::move(map1));

    EXPECT_TRUE(map1.isEmpty());
    EXPECT_TRUE(WTF::InlineMapAccessForTesting::isInline(map1));

    EXPECT_EQ(map2.size(), 8u);
    EXPECT_FALSE(WTF::InlineMapAccessForTesting::isInline(map2));
    EXPECT_EQ(WTF::InlineMapAccessForTesting::deletedCount(map2), 2u);

    for (unsigned i = 3; i <= 10; ++i) {
        EXPECT_TRUE(map2.contains(i));
        EXPECT_EQ(map2.find(i)->value, i * 10);
    }
}

TEST(WTF_InlineMap, CopyConstructionPreservesDeletedCount)
{
    // Copy-constructing from a hashed map with deleted entries preserves deletedCount.
    InlineMap<unsigned, unsigned, 3, IntHash<unsigned>> map1;

    for (unsigned i = 1; i <= 10; ++i)
        map1.add(i, i * 10);

    map1.remove(1);
    map1.remove(2);
    EXPECT_EQ(WTF::InlineMapAccessForTesting::deletedCount(map1), 2u);

    InlineMap<unsigned, unsigned, 3, IntHash<unsigned>> map2(map1);

    // Both maps should have same state
    EXPECT_EQ(map1.size(), 8u);
    EXPECT_EQ(map2.size(), 8u);
    EXPECT_EQ(WTF::InlineMapAccessForTesting::deletedCount(map1), 2u);
    EXPECT_EQ(WTF::InlineMapAccessForTesting::deletedCount(map2), 2u);

    // Both maps should have the same entries
    for (unsigned i = 3; i <= 10; ++i) {
        EXPECT_TRUE(map1.contains(i));
        EXPECT_TRUE(map2.contains(i));
        EXPECT_EQ(map1.find(i)->value, i * 10);
        EXPECT_EQ(map2.find(i)->value, i * 10);
    }
    EXPECT_FALSE(map1.contains(1));
    EXPECT_FALSE(map2.contains(1));
}

TEST(WTF_InlineMap, ShrinkWithMoveOnlyValues)
{
    // Move-only values survive the hashed→inline transition.
    InlineMap<unsigned, MoveOnly, 5, IntHash<unsigned>> map;

    for (unsigned i = 1; i <= 20; ++i)
        map.add(i, MoveOnly(i));

    EXPECT_FALSE(WTF::InlineMapAccessForTesting::isInline(map));

    // Remove entries, keeping 1-4
    for (unsigned i = 5; i <= 20; ++i)
        map.remove(i);

    EXPECT_EQ(map.size(), 4u);
    EXPECT_TRUE(WTF::InlineMapAccessForTesting::isInline(map));

    for (unsigned i = 1; i <= 4; ++i) {
        auto it = map.find(i);
        ASSERT_FALSE(it == map.end());
        EXPECT_EQ(it->value.value(), i);
    }
}

TEST(WTF_InlineMap, ShrinkDoesNotHappenAboveThreshold)
{
    // Removing entries that keep the load above 1/6 does not trigger shrink.
    InlineMap<unsigned, unsigned, 5, IntHash<unsigned>> map;

    for (unsigned i = 1; i <= 20; ++i)
        map.add(i, i * 10);

    EXPECT_FALSE(WTF::InlineMapAccessForTesting::isInline(map));
    unsigned capacityBefore = WTF::InlineMapAccessForTesting::capacity(map);

    // With capacity=32, shrink triggers when m_size * 6 < 32, i.e., m_size < 5.33
    // Removing down to m_size=6 should NOT trigger shrink (6*6=36 >= 32)
    for (unsigned i = 7; i <= 20; ++i)
        EXPECT_TRUE(map.remove(i));

    EXPECT_EQ(map.size(), 6u);
    EXPECT_FALSE(WTF::InlineMapAccessForTesting::isInline(map));
    EXPECT_EQ(WTF::InlineMapAccessForTesting::capacity(map), capacityBefore);
    EXPECT_EQ(WTF::InlineMapAccessForTesting::deletedCount(map), 14u);

    // All remaining entries accessible
    for (unsigned i = 1; i <= 6; ++i) {
        EXPECT_TRUE(map.contains(i));
        EXPECT_EQ(map.find(i)->value, i * 10);
    }
}

TEST(WTF_InlineMap, ClearHashedMapWithDeletedEntries)
{
    // clear() on a hashed map with nonzero deletedCount transitions to inline.
    InlineMap<unsigned, unsigned, 5, IntHash<unsigned>> map;

    for (unsigned i = 1; i <= 20; ++i)
        map.add(i, i * 10);

    EXPECT_FALSE(WTF::InlineMapAccessForTesting::isInline(map));

    // Remove some entries to build up deletedCount
    map.remove(3);
    map.remove(7);
    map.remove(11);
    EXPECT_EQ(WTF::InlineMapAccessForTesting::deletedCount(map), 3u);
    EXPECT_EQ(map.size(), 17u);

    map.clear();
    EXPECT_TRUE(map.isEmpty());
    EXPECT_TRUE(WTF::InlineMapAccessForTesting::isInline(map));

    // Re-adding entries works normally
    for (unsigned i = 1; i <= 10; ++i)
        map.add(i, i * 100);

    EXPECT_FALSE(WTF::InlineMapAccessForTesting::isInline(map));
    EXPECT_EQ(map.size(), 10u);
    for (unsigned i = 1; i <= 10; ++i)
        EXPECT_EQ(map.find(i)->value, i * 100);
}

TEST(WTF_InlineMap, CopyAfterShrinkToInline)
{
    // Copy and move construction work correctly after a hashed→inline shrink.
    InlineMap<unsigned, unsigned, 5, IntHash<unsigned>> map;

    for (unsigned i = 1; i <= 20; ++i)
        map.add(i, i * 10);

    EXPECT_FALSE(WTF::InlineMapAccessForTesting::isInline(map));

    // Remove down to 5 entries, triggering shrink to inline
    for (unsigned i = 6; i <= 20; ++i)
        map.remove(i);

    EXPECT_EQ(map.size(), 5u);
    EXPECT_TRUE(WTF::InlineMapAccessForTesting::isInline(map));

    // Copy-construct from the shrunk inline map
    InlineMap<unsigned, unsigned, 5, IntHash<unsigned>> mapCopy(map);
    EXPECT_TRUE(WTF::InlineMapAccessForTesting::isInline(mapCopy));
    EXPECT_EQ(mapCopy.size(), 5u);
    for (unsigned i = 1; i <= 5; ++i) {
        EXPECT_TRUE(mapCopy.contains(i));
        EXPECT_EQ(mapCopy.find(i)->value, i * 10);
    }

    // Original still intact
    for (unsigned i = 1; i <= 5; ++i) {
        EXPECT_TRUE(map.contains(i));
        EXPECT_EQ(map.find(i)->value, i * 10);
    }

    // Move-construct from the shrunk inline map
    InlineMap<unsigned, unsigned, 5, IntHash<unsigned>> mapMoved(WTF::move(map));
    EXPECT_TRUE(WTF::InlineMapAccessForTesting::isInline(mapMoved));
    EXPECT_EQ(mapMoved.size(), 5u);
    for (unsigned i = 1; i <= 5; ++i) {
        EXPECT_TRUE(mapMoved.contains(i));
        EXPECT_EQ(mapMoved.find(i)->value, i * 10);
    }

    EXPECT_TRUE(map.isEmpty());
}

TEST(WTF_InlineMap, IterationAfterShrinkToInline)
{
    // Range-for iteration works correctly after hashed→inline shrink.
    InlineMap<unsigned, unsigned, 5, IntHash<unsigned>> map;

    for (unsigned i = 1; i <= 20; ++i)
        map.add(i, i * 10);

    EXPECT_FALSE(WTF::InlineMapAccessForTesting::isInline(map));

    // Remove down to 4 entries (keys 1-4 survive)
    for (unsigned i = 5; i <= 20; ++i)
        map.remove(i);

    EXPECT_EQ(map.size(), 4u);
    EXPECT_TRUE(WTF::InlineMapAccessForTesting::isInline(map));

    // Iterate and collect all entries
    HashSet<unsigned> seenKeys;
    unsigned total = 0;
    for (auto& entry : map) {
        EXPECT_TRUE(entry.key >= 1 && entry.key <= 4);
        EXPECT_EQ(entry.value, entry.key * 10);
        seenKeys.add(entry.key);
        ++total;
    }

    EXPECT_EQ(total, 4u);
    for (unsigned i = 1; i <= 4; ++i)
        EXPECT_TRUE(seenKeys.contains(i));
}

TEST(WTF_InlineMap, MustRehashInPlacePathDirect)
{
    // Directly tests the mustRehashInPlace() path: many deleted entries cause
    // expand() to rehash in place (same capacity) rather than doubling.
    InlineMap<unsigned, unsigned, 3, IntHash<unsigned>> map;

    // Add enough entries to get a known capacity
    for (unsigned i = 1; i <= 20; ++i)
        map.add(i, i * 10);

    EXPECT_FALSE(WTF::InlineMapAccessForTesting::isInline(map));
    unsigned initialCapacity = WTF::InlineMapAccessForTesting::capacity(map);

    // Remove entries to create many deleted slots.
    // Keep enough live entries that shouldShrink() is false but mustRehashInPlace() is true.
    // shouldShrink: m_size * 6 < capacity  => false when m_size >= capacity/6
    // mustRehashInPlace: m_size * 6 < capacity * 2  => true when m_size < capacity/3
    // So we need capacity/6 <= m_size < capacity/3.
    // With capacity=32: we need 6 <= m_size < 11.
    unsigned targetSize = initialCapacity / 4; // safely between capacity/6 and capacity/3
    if (targetSize < initialCapacity / 6 + 1)
        targetSize = initialCapacity / 6 + 1;

    for (unsigned i = targetSize + 1; i <= 20; ++i)
        map.remove(i);

    EXPECT_EQ(map.size(), targetSize);
    unsigned capacityAfterRemoves = WTF::InlineMapAccessForTesting::capacity(map);
    unsigned deletedAfterRemoves = WTF::InlineMapAccessForTesting::deletedCount(map);
    EXPECT_GT(deletedAfterRemoves, 0u);

    // Now add new unique keys until expansion triggers.
    // Because (m_size + deletedCount) * 4 >= capacity * 3, the expansion check fires.
    // Since mustRehashInPlace() is true, it should rehash to the same capacity.
    unsigned nextKey = 1000;
    while (WTF::InlineMapAccessForTesting::capacity(map) == capacityAfterRemoves
        && WTF::InlineMapAccessForTesting::deletedCount(map) > 0) {
        map.add(nextKey, nextKey * 10);
        ++nextKey;
    }

    // Either capacity stayed the same (rehash in place reclaimed deleted slots)
    // or if all deleted slots were reused before expansion, deletedCount hit 0.
    // In either case, deletedCount should be 0 after rehash.
    EXPECT_EQ(WTF::InlineMapAccessForTesting::deletedCount(map), 0u);

    // Verify all live entries are accessible
    for (unsigned i = 1; i <= targetSize; ++i) {
        EXPECT_TRUE(map.contains(i));
        EXPECT_EQ(map.find(i)->value, i * 10);
    }
    for (unsigned i = 1000; i < nextKey; ++i) {
        EXPECT_TRUE(map.contains(i));
        EXPECT_EQ(map.find(i)->value, i * 10);
    }
}

} // namespace TestWebKitAPI
