public void Test_StringPool_GetOrAdd_ReadOnlySpan_Misc()
        {
            var pool = new StringPool();

            string
                hello      = pool.GetOrAdd(nameof(hello).AsSpan()),
                helloworld = pool.GetOrAdd(nameof(helloworld).AsSpan()),
                windowsCommunityToolkit = pool.GetOrAdd(nameof(windowsCommunityToolkit).AsSpan());

            Assert.AreEqual(nameof(hello), hello);
            Assert.AreEqual(nameof(helloworld), helloworld);
            Assert.AreEqual(nameof(windowsCommunityToolkit), windowsCommunityToolkit);

            Assert.AreSame(hello, pool.GetOrAdd(hello.AsSpan()));
            Assert.AreSame(helloworld, pool.GetOrAdd(helloworld.AsSpan()));
            Assert.AreSame(windowsCommunityToolkit, pool.GetOrAdd(windowsCommunityToolkit.AsSpan()));

            pool.Reset();

            Assert.AreEqual(nameof(hello), hello);
            Assert.AreEqual(nameof(helloworld), helloworld);
            Assert.AreEqual(nameof(windowsCommunityToolkit), windowsCommunityToolkit);

            Assert.AreNotSame(hello, pool.GetOrAdd(hello.AsSpan()));
            Assert.AreNotSame(helloworld, pool.GetOrAdd(helloworld.AsSpan()));
            Assert.AreNotSame(windowsCommunityToolkit, pool.GetOrAdd(windowsCommunityToolkit.AsSpan()));
        }
        public void Test_StringPool_GetOrAdd_Overflow()
        {
            var pool = new StringPool(32);

            // Fill the pool
            for (int i = 0; i < 4096; i++)
            {
                _ = pool.GetOrAdd(i.ToString());
            }

            // Get the buckets
            Array maps = (Array)typeof(StringPool).GetField("maps", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(pool);

            Type      bucketType    = Type.GetType("Microsoft.Toolkit.HighPerformance.Buffers.StringPool+FixedSizePriorityMap, Microsoft.Toolkit.HighPerformance");
            FieldInfo timestampInfo = bucketType.GetField("timestamp", BindingFlags.Instance | BindingFlags.NonPublic);

            // Force the timestamp to be the maximum value, or the test would take too long
            for (int i = 0; i < maps.LongLength; i++)
            {
                object map = maps.GetValue(i);

                timestampInfo.SetValue(map, uint.MaxValue);

                maps.SetValue(map, i);
            }

            // Force an overflow
            string text = "Hello world";

            _ = pool.GetOrAdd(text);

            Type heapEntryType = Type.GetType("Microsoft.Toolkit.HighPerformance.Buffers.StringPool+FixedSizePriorityMap+HeapEntry, Microsoft.Toolkit.HighPerformance");

            foreach (var map in maps)
            {
                // Get the heap for each bucket
                Array     heapEntries = (Array)bucketType.GetField("heapEntries", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(map);
                FieldInfo fieldInfo   = heapEntryType.GetField("Timestamp");

                // Extract the array with the timestamps in the heap nodes
                uint[] array = heapEntries.Cast <object>().Select(entry => (uint)fieldInfo.GetValue(entry)).ToArray();
        public void Test_StringPool_GetOrAdd_Encoding_Misc()
        {
            var pool = new StringPool();

            string helloworld = nameof(helloworld);

            pool.Add(helloworld);

            Span <byte> span = Encoding.UTF8.GetBytes(nameof(helloworld));

            string helloworld2 = pool.GetOrAdd(span, Encoding.UTF8);

            Assert.AreSame(helloworld, helloworld2);

            string windowsCommunityToolkit = nameof(windowsCommunityToolkit);

            Span <byte> span2 = Encoding.ASCII.GetBytes(windowsCommunityToolkit);

            string
                windowsCommunityToolkit2 = pool.GetOrAdd(span2, Encoding.ASCII),
                windowsCommunityToolkit3 = pool.GetOrAdd(windowsCommunityToolkit);

            Assert.AreSame(windowsCommunityToolkit2, windowsCommunityToolkit3);
        }
        public void Test_StringPool_GetOrAdd_String_Misc()
        {
            var pool = new StringPool();

            string helloworld = nameof(helloworld);

            string cached = pool.GetOrAdd(helloworld);

            Assert.AreSame(helloworld, cached);

            Span <char> span = stackalloc char[helloworld.Length];

            helloworld.AsSpan().CopyTo(span);

            string helloworld2 = span.ToString();

            cached = pool.GetOrAdd(helloworld2);

            Assert.AreSame(helloworld, cached);

            cached = pool.GetOrAdd(new string(helloworld.ToCharArray()));

            Assert.AreSame(helloworld, cached);
        }