Esempio n. 1
0
        public void CouldMoveAtOnNonEmpty(int count)
        {
            Assert.Fail("Need a proper MA test");
            var s = new AppendSeries <int, int>();

            for (int i = 1; i <= count; i++)
            {
                s.Append(i, i);
            }

            var searchValue = count / 2;

            // TODO all corners all directions and all inner

            var c = s.GetCursor();

            Assert.IsTrue(c.MoveAt(searchValue, Lookup.GT));
            Assert.AreEqual(searchValue + 1, c.CurrentValue);
            Assert.AreEqual(searchValue + 1, c.CurrentKey);

            Assert.IsTrue(c.MoveAt(searchValue, Lookup.GE));
            Assert.IsTrue(c.MoveAt(searchValue, Lookup.EQ));
            Assert.IsTrue(c.MoveAt(searchValue, Lookup.LE));
            Assert.IsTrue(c.MoveAt(searchValue, Lookup.LT));
            c.Dispose();
            s.Dispose();
        }
Esempio n. 2
0
        public async Task CouldCancelCursor()
        {
            var s = new AppendSeries <int, int>();

            var c = s.GetAsyncEnumerator();

            var t = Task.Run(async() =>
            {
                try
                {
                    await c.MoveNextAsync();
                    Assert.Fail();
                }
                catch (Exception ex)
                {
                    Assert.True(true);
                }
            });

            Thread.Sleep(100);

            c.TryComplete(true);

            t.Wait();

            c.Dispose();
            s.Dispose();
        }
Esempio n. 3
0
        public void NewSeries()
        {
            var s = new Series <int, int>(Array.Empty <int>(), Array.Empty <int>());

            Assert.AreEqual(s.Mutability, Mutability.ReadOnly);
            Assert.AreEqual(s.KeySorting, KeySorting.Strong);
            Assert.AreEqual(0, s.RowCount.Value);
            s.Dispose();
            Assert.IsTrue(s.IsDisposed);

            var aps = new AppendSeries <int, int>();

            Assert.AreEqual(aps.Mutability, Mutability.AppendOnly);
            Assert.AreEqual(aps.KeySorting, KeySorting.Strong);
            Assert.AreEqual(0, aps.RowCount.Value);
            aps.Dispose();
            Assert.IsTrue(aps.IsDisposed);

            var mus = new MutableSeries <int, int>();

            Assert.AreEqual(mus.Mutability, Mutability.Mutable);
            Assert.AreEqual(mus.KeySorting, KeySorting.Strong);
            Assert.AreEqual(0, mus.RowCount.Value);
            mus.MarkAppendOnly();
            mus.MarkAppendOnly(); // ignored, does not throw
            Assert.AreEqual(Mutability.AppendOnly, mus.Mutability);
            mus.MarkReadOnly();
            mus.MarkReadOnly(); // ignored, does not throw
            Assert.AreEqual(Mutability.ReadOnly, mus.Mutability);
            Assert.Throws <InvalidOperationException>(() => { mus.MarkAppendOnly(); });
            mus.Dispose();
            Assert.IsTrue(mus.IsDisposed);
        }
Esempio n. 4
0
        public void CouldNotMoveNextPreviousOnEmpty()
        {
            var s = new AppendSeries <int, int>();
            var c = s.GetCursor();

            Assert.IsFalse(c.MoveNext());
            Assert.IsFalse(c.MovePrevious());
            Assert.IsFalse(c.MoveFirst());
            Assert.IsFalse(c.MoveLast());
            s.Append(1, 1);
            Assert.IsTrue(c.MoveNext());
            Assert.IsFalse(c.MovePrevious());
            Assert.IsTrue(c.MoveFirst());
            Assert.IsTrue(c.MoveLast());

            s.Append(2, 2);
            Assert.IsTrue(c.MoveNext());
            Assert.AreEqual(2, c.CurrentKey);
            Assert.AreEqual(2, c.CurrentValue);
            Assert.IsTrue(c.MovePrevious());
            Assert.AreEqual(1, c.CurrentKey);
            Assert.AreEqual(1, c.CurrentValue);
            Assert.IsTrue(c.MoveFirst());
            Assert.IsTrue(c.MoveLast());

            c.Dispose();
            s.Dispose();
        }
Esempio n. 5
0
        public void DeadCursorDoesNotCauseEndlessLoopInNotifyUpdate()
        {
            var s = new AppendSeries <int, int>();

            s.Append(1, 1);

            var cursor = s.GetAsyncEnumerator();

            Assert.True(cursor.MoveNext());
            Assert.False(cursor.MoveNext());

            cursor.MoveNextAsync();
            cursor.Dispose();
            cursor = default;

            GC.Collect(2, GCCollectionMode.Forced, true);
            GC.Collect(2, GCCollectionMode.Forced, true);

            //var t = Task.Run(() => cursor.MoveNextAsync(cts.Token));

            s.Append(2, 2);
            s.Append(3, 3);

            Assert.True(s.RowCount == 3);

            s.Dispose();
        }
Esempio n. 6
0
        public void CouldMoveAtOnSingle()
        {
            Assert.Fail("Proper MA tests");
            var s = new AppendSeries <int, int>();

            s.Append(1, 1);
            var c = s.GetCursor();

            Assert.IsFalse(c.MoveAt(1, Lookup.GT));
            Assert.IsTrue(c.MoveAt(1, Lookup.GE));
            Assert.IsTrue(c.MoveAt(1, Lookup.EQ));
            Assert.IsTrue(c.MoveAt(1, Lookup.LE));
            Assert.IsFalse(c.MoveAt(1, Lookup.LT));
            c.Dispose();
            s.Dispose();
        }
Esempio n. 7
0
        [Test, Ignore("broken")] // TODO
        public void CouldAppendSeries()
        {
            var sa = new AppendSeries <int, int>(DataBlock.Create());

            Assert.IsTrue(sa.TryAddLast(1, 1).Result);
            Assert.IsFalse(sa.TryAddLast(1, 1).Result);

            Assert.IsTrue(sa.TryAddLast(2, 2).Result);

            Assert.Throws <KeyNotFoundException>(() =>
            {
                var _ = sa[0];
            });

            Assert.AreEqual(1, sa[1]);
            Assert.AreEqual(2, sa[2]);

            Assert.AreEqual(2, sa.Count());

            for (int i = 3; i < 42000; i++)
            {
                Assert.IsTrue(sa.TryAddLast(i, i).Result);
                Assert.AreEqual(i, sa.Last.Present.Value);
            }

            //// TODO remove when implemented
            //Assert.Throws<NotImplementedException>(() =>
            //{
            //    for (int i = 32000; i < 33000; i++)
            //    {
            //        Assert.IsTrue(sa.TryAddLast(i, i).Result);
            //    }
            //});

            GC.Collect(2, GCCollectionMode.Forced, true, true);
            GC.WaitForPendingFinalizers();
            GC.Collect(2, GCCollectionMode.Forced, true, true);
            GC.WaitForPendingFinalizers();

            sa.Dispose();

            GC.Collect(2, GCCollectionMode.Forced, true, true);
            GC.WaitForPendingFinalizers();
            GC.Collect(2, GCCollectionMode.Forced, true, true);
            GC.WaitForPendingFinalizers();
        }
Esempio n. 8
0
        public void CouldMovePreviousFromInitialized(int count)
        {
            var s = new AppendSeries <int, int>();

            for (int i = 1; i <= count; i++)
            {
                s.Append(i, i);
            }

            var c = s.GetCursor();

            Assert.IsTrue(c.MovePrevious());
            Assert.AreEqual(count, c.CurrentKey);
            Assert.AreEqual(count, c.CurrentValue);

            c.Dispose();
            s.Dispose();
        }
Esempio n. 9
0
        public async Task CouldEnumerateSMUsingCursor()
        {
            var s     = new AppendSeries <int, int>();
            var count = (int)TestUtils.GetBenchCount();

            for (int i = 0; i < count; i++)
            {
                s.Append(i, i);
            }

#pragma warning disable HAA0401 // Possible allocation of reference type enumerator
            var ae = s.GetAsyncEnumerator();
#pragma warning restore HAA0401 // Possible allocation of reference type enumerator

            var t = Task.Run(async() =>
            {
                using (Benchmark.Run("SCM.AsyncEnumerator", count))
                {
                    var cnt = 0;
                    while (await ae.MoveNextAsync())
                    {
                        cnt++;
                    }

                    await ae.DisposeAsync();
                    Assert.AreEqual(count * 2, cnt);
                }

                Benchmark.Dump();
            });

            for (int i = count; i < count * 2; i++)
            {
                s.Append(i, i);
            }

            s.MarkReadOnly();

            t.Wait();

            s.Dispose();
        }
Esempio n. 10
0
        public void CancelledCursorDoesntCauseEndlessLoopInNotifyUpdate()
        {
            var s = new AppendSeries <int, int>();

            s.Append(1, 1);

            var c = s.GetAsyncEnumerator();

            Assert.True(c.MoveNext());
            Assert.False(c.MoveNext());

            c.MoveNextAsync();

            s.Append(2, 2);
            s.Append(3, 3);

            Assert.True(s.RowCount == 3);

            c.Dispose();
            s.Dispose();
        }
Esempio n. 11
0
        public void CouldMoveFirstLast(int count)
        {
            var s = new AppendSeries <int, int>();

            for (int i = 1; i <= count; i++)
            {
                s.Append(i, i);
            }
            SCursor <int, int> c;

            c = s.GetCursor();
            Assert.IsTrue(c.MoveFirst());
            Assert.IsTrue(c.MoveLast());
            c.Dispose();

            c = s.GetCursor();
            Assert.IsTrue(c.MoveLast());
            Assert.IsTrue(c.MoveFirst());
            c.Dispose();

            s.Dispose();
        }
Esempio n. 12
0
        public async Task NotificationWorksWhenCursorIsNotWating()
        {
            var s = new AppendSeries <int, int>();

            s.Append(1, 1);
            s.Append(2, 2);

            var c = s.GetAsyncEnumerator();

            Assert.True(await c.MoveNextAsync());
            Assert.True(await c.MoveNextAsync());

            Assert.IsTrue(c.MovePrevious());

            s.Append(3, 3);

            await Task.Delay(250);

            Assert.AreEqual(1, c.CurrentKey);
            Assert.AreEqual(1, c.CurrentValue);
            c.Dispose();
            s.Dispose();
        }
Esempio n. 13
0
        public async Task CouldAsyncEnumerate()
        {
            var s     = new AppendSeries <int, int>();
            var count = (int)TestUtils.GetBenchCount(10_000_000, 5);

            for (int i = 0; i < count; i++)
            {
                s.Append(i, i);
            }

            var t = Task.Run(async() =>
            {
                using (Benchmark.Run("SCM.AsyncEnumerator", count))
                {
                    var cnt = 0;
                    await foreach (var _ in s)
                    {
                        cnt++;
                    }

                    Assert.AreEqual(count * 2, cnt);
                }

                Benchmark.Dump();
            });

            for (int i = count; i < count * 2; i++)
            {
                s.Append(i, i);
            }

            s.MarkReadOnly();

            t.Wait();

            s.Dispose();
        }
Esempio n. 14
0
        public void CouldAppendSeriesBench()
        {
            if (AdditionalCorrectnessChecks.Enabled)
            {
                Console.WriteLine("AdditionalCorrectnessChecks.Enabled");
            }

            int count  = 10_000_000;
            int rounds = 100;

            var sa = new AppendSeries <int, int>(DataBlock.Create());
            var sm = new SortedMap <int, int>();

            //for (int r = 0; r < rounds; r++)
            //{
            //    using (Benchmark.Run("SM.TryAddLast", count))
            //    {
            //        for (int i = r * count; i < (r + 1) * count; i++)
            //        {
            //            if (i == r * count + 3)
            //            {
            //                continue;
            //            }
            //            if (!sm.TryAddLast(i, i).Result)
            //            {
            //                Assert.Fail("Cannot add " + i);
            //            }
            //        }
            //    }
            //    Console.WriteLine($"Added {((r + 1) * count / 1000000).ToString("N")}");
            //}

            for (int r = 0; r < rounds; r++)
            {
                using (Benchmark.Run("Append", count))
                {
                    for (int i = r * count; i < (r + 1) * count; i++)
                    {
                        if (i == r * count + 3)
                        {
                            continue;
                        }
                        if (!sa.TryAddLast(i, i).Result)
                        {
                            Console.WriteLine("Cannot add " + i);
                            return;
                        }
                    }
                }

                Console.WriteLine($"Added {((r + 1) * count / 1000000).ToString("N")}");
            }



            Benchmark.Dump();

            Console.WriteLine("Finished, press enter");
            Console.ReadLine();

            sa.Dispose();
        }
Esempio n. 15
0
        public async Task CouldReadDataStreamWhileWritingFromManyThreads()
        {
            var map = new AppendSeries <int, int>();

            var writeCount = 0L;

            var count  = 1000_000_000;
            var rounds = 1;

            var writeTask = Task.Run(async() =>
            {
                using (Benchmark.Run("Write", count * rounds, true))
                {
                    for (int j = 0; j < rounds; j++)
                    {
                        var t1 = Task.Run(() =>
                        {
                            try
                            {
                                for (int i = j * count; i < (j + 1) * count; i++)
                                {
                                    map.DangerousTryAppend(i, i);
                                    // Thread.SpinWait(10);
                                    // Thread.Yield();
                                    Interlocked.Increment(ref writeCount);
                                }
                            }
                            catch (Exception e)
                            {
                                Console.WriteLine(e);
                                throw;
                            }
                        });
                        await t1;
                    }
                }
            });

            AsyncCursor <int, int, SCursor <int, int> > cursor = null;
            var cnt      = 0L;
            var readTask = Task.Run(async() =>
            {
                for (int r = 0; r < 1; r++)
                {
                    using (cursor = new AsyncCursor <int, int, SCursor <int, int> >(map.GetCursor()))
                    {
                        using (Benchmark.Run("Read", count * rounds, true))
                        {
                            try
                            {
                                while (await cursor.MoveNextAsync())
                                {
                                    Interlocked.Increment(ref cnt);
                                    // Thread.Sleep(1);
                                }
                            }
                            catch (Exception e)
                            {
                                Console.WriteLine(e);
                                throw;
                            }


                            // Left from coreclr 19161 tests, TODO remove when everything works OK
                            // here is a strong reference to cursor with side effects of printing to console
                            // Console.WriteLine("Last value: " + cursor.Current.Key);
                            // another strong reference after while loop, we dereference it's value and return from task
                            // lastKey1 = cursor.CurrentKey;
                        }
                    }
                }
            });


            var monitor     = true;
            var monitorTask = Task.Run(async() =>
            {
                try
                {
                    var previousR = cursor?.CurrentKey;
                    var previousW = Volatile.Read(ref writeCount);
                    while (monitor)
                    {
                        await Task.Delay(1000);
                        var r = cursor.CurrentKey;
                        var w = Volatile.Read(ref writeCount);
                        Console.WriteLine($"R: {r:N0} - {((r - previousR) / 1000000.0):N2} Mops \t | W: {w:N0}- {((w - previousW) / 1000000.0):N2} Mops");

                        if (r == previousR)
                        {
                            Console.WriteLine($"IsAwaiting {cursor.IsTaskAwating} IsCompl {cursor.IsCompleted} Counter {cursor._counter}");
                        }

                        previousR = r;
                        previousW = w;
                        // cursor.TryComplete(false);
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                    throw;
                }
            });

            await writeTask;

            Console.WriteLine("COMPLETE");
            map.MarkReadOnly();
            map.NotifyUpdate();
            Console.WriteLine("Read after map complete:" + Interlocked.Read(ref cnt));
            await readTask;

            Console.WriteLine("Read after finish:" + Interlocked.Read(ref cnt));
            // Console.WriteLine("Last key: " + lastKey);

            Benchmark.Dump();
            GC.KeepAlive(cursor);
            map.Dispose();
            monitor = false;
        }
Esempio n. 16
0
        public async Task CouldEnumerateSCMUsingCursor()
        {
            var s     = new AppendSeries <int, int>();
            var count = 1_000_000; // Settings.SCMDefaultChunkLength - 1;

            for (int i = 0; i < count; i++)
            {
                s.Append(i, i);
            }

            Console.WriteLine("Added first half");

#pragma warning disable HAA0401 // Possible allocation of reference type enumerator
            var ae = s.GetAsyncEnumerator();
#pragma warning restore HAA0401 // Possible allocation of reference type enumerator

            var t = Task.Run(async() =>
            {
                using (Benchmark.Run("SCM.AsyncEnumerator", count))
                {
                    try
                    {
                        var cnt = 0;
                        while (await ae.MoveNextAsync())
                        {
                            if (cnt != ae.Current.Key)
                            {
                                ThrowHelper.ThrowInvalidOperationException();
                            }

                            cnt++;
                        }

                        await ae.DisposeAsync();
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("EXCEPTION: " + ex.ToString());
                        throw;
                    }

                    // Assert.AreEqual(scm.Count, cnt);
                }

                Benchmark.Dump();
            });

            // Thread.Sleep(1000);

            for (int i = count; i < count * 2; i++)
            {
                s.Append(i, i);
                //Thread.SpinWait(50);
            }

            // Thread.Sleep(2000);

            s.MarkReadOnly();

            t.Wait();

            s.Dispose();
        }
Esempio n. 17
0
        public void CouldMovePartialFromMoving(int count)
        {
            var s = new AppendSeries <int, int>();

            for (int i = 1; i <= count; i++)
            {
                s.Append(i, i);
            }

            SCursor <int, int> c;

            c = s.GetCursor();
            c.MoveNext();
            Assert.AreEqual(count - 1, c.Move(count * 2, true));
            Assert.AreEqual(count, c.CurrentKey);
            Assert.AreEqual(count, c.CurrentValue);
            c.Dispose();

            c = s.GetCursor();
            c.MoveNext();
            Assert.AreEqual(count - 1, c.Move(count * 200, true));
            Assert.AreEqual(count, c.CurrentKey);
            Assert.AreEqual(count, c.CurrentValue);
            c.Dispose();

            c = s.GetCursor();
            c.MoveNext();
            Assert.AreEqual(count - 1, c.Move(count + 1, true));
            Assert.AreEqual(count, c.CurrentKey);
            Assert.AreEqual(count, c.CurrentValue);
            c.Dispose();

            c = s.GetCursor();
            c.MoveNext();
            Assert.AreEqual(count - 1, c.Move(count, true));
            Assert.AreEqual(count, c.CurrentKey);
            Assert.AreEqual(count, c.CurrentValue);
            c.Dispose();

            // ---------

            c = s.GetCursor();
            c.MovePrevious();
            Assert.AreEqual(-count + 1, c.Move(-count * 2, true));
            Assert.AreEqual(1, c.CurrentKey);
            Assert.AreEqual(1, c.CurrentValue);
            c.Dispose();

            c = s.GetCursor();
            c.MovePrevious();
            Assert.AreEqual(-count + 1, c.Move(-count * 200, true));
            Assert.AreEqual(1, c.CurrentKey);
            Assert.AreEqual(1, c.CurrentValue);
            c.Dispose();

            c = s.GetCursor();
            c.MovePrevious();
            Assert.AreEqual(-count + 1, c.Move(-(count + 1), true));
            Assert.AreEqual(1, c.CurrentKey);
            Assert.AreEqual(1, c.CurrentValue);
            c.Dispose();

            c = s.GetCursor();
            c.MovePrevious();
            Assert.AreEqual(-count + 1, c.Move(-count, true));
            Assert.AreEqual(1, c.CurrentKey);
            Assert.AreEqual(1, c.CurrentValue);
            c.Dispose();

            s.Dispose();
        }
Esempio n. 18
0
        public void CouldAppendSeries(int count)
        {
            //var counts = new[] { 50, 50000 };
            //foreach (var count in counts)
            {
                var sa = new AppendSeries <int, int>();

                Assert.IsTrue(sa.TryAppend(1, 1));
                Assert.AreEqual(1, sa.RowCount, "Row count == 1");
                Assert.IsFalse(sa.TryAppend(1, 1));

                Assert.IsTrue(sa.TryAppend(2, 2));

                Assert.Throws <KeyNotFoundException>(() =>
                {
                    var _ = sa[0];
                });

                Assert.AreEqual(1, sa[1]);
                Assert.AreEqual(2, sa[2]);

                Assert.AreEqual(2, sa.Count());

                for (int i = 3; i < count; i++)
                {
                    Assert.IsTrue(sa.TryAppend(i, i));
                    Assert.AreEqual(i, sa.Last.Present.Value);
                }

                GC.Collect(2, GCCollectionMode.Forced, true, true);
                GC.WaitForPendingFinalizers();
                GC.Collect(2, GCCollectionMode.Forced, true, true);
                GC.WaitForPendingFinalizers();

                //using (var cursor = sa.GetEnumerator())
                //{
                //    for (int i = 1; i < count; i++)
                //    {
                //        Assert.IsTrue(cursor.MoveNext(), $"could MN {i}");
                //        Assert.AreEqual(i, cursor.CurrentKey);
                //        Assert.AreEqual(i, cursor.CurrentValue);
                //    }
                //}

                //using (var cursor = sa.GetEnumerator())
                //{
                //    for (int i = count - 1; i >= 1; i--)
                //    {
                //        Assert.IsTrue(cursor.MovePrevious(), $"could MP {i}");
                //        Assert.AreEqual(i, cursor.CurrentKey);
                //        Assert.AreEqual(i, cursor.CurrentValue);
                //    }
                //}

                using (var cursor = sa.GetEnumerator())
                {
                    Assert.IsTrue(cursor.Move(count + 1, false) == 0);
                    Assert.IsTrue(cursor.State == CursorState.Initialized);
                }

                using (var cursor = sa.GetEnumerator())
                {
                    Assert.AreEqual(count - 1, cursor.Move(count + 1, true));
                    Assert.IsTrue(cursor.State == CursorState.Moving);
                    Assert.AreEqual(sa.Last.Present.Key, cursor.CurrentKey);
                    Assert.AreEqual(sa.Last.Present.Value, cursor.CurrentValue);
                }

                using (var cursor = sa.GetEnumerator())
                {
                    Assert.AreEqual(-(count - 1), cursor.Move(-count - 1, true));
                    Assert.IsTrue(cursor.State == CursorState.Moving);
                    Assert.AreEqual(sa.First.Present.Key, cursor.CurrentKey);
                    Assert.AreEqual(sa.First.Present.Value, cursor.CurrentValue);
                }

                sa.Dispose();

                GC.Collect(2, GCCollectionMode.Forced, true, true);
                GC.WaitForPendingFinalizers();
                GC.Collect(2, GCCollectionMode.Forced, true, true);
                GC.WaitForPendingFinalizers();
            }
        }
Esempio n. 19
0
        public void CouldAppendSeriesBench()
        {
            if (AdditionalCorrectnessChecks.Enabled)
            {
                Console.WriteLine("AdditionalCorrectnessChecks.Enabled");
            }

            int count  = (int)TestUtils.GetBenchCount(10_000_000, 100_000);
            int rounds = (int)TestUtils.GetBenchCount(100, 10);

            var sl = new SortedList <int, int>();

            //var cursor = sa.GetAsyncCursor();
            //cursor.MoveNextAsync();
            var di = new Dictionary <int, int>();

            //for (int r = 0; r < rounds; r++)
            //{
            //    using (Benchmark.Run("SL.Add", count))
            //    {
            //        for (int i = r * count; i < (r + 1) * count; i++)
            //        {
            //            if (i == r * count + 3)
            //            {
            //                continue;
            //            }

            //            sl.Add(i, i);
            //        }
            //    }
            //    Console.WriteLine($"Added {((r + 1) * count / 1000000):N}");
            //}

            //for (int r = 0; r < rounds; r++)
            //{
            //    using (Benchmark.Run("DI.Add", count))
            //    {
            //        for (int i = r * count; i < (r + 1) * count; i++)
            //        {
            //            if (i == r * count + 3)
            //            {
            //                continue;
            //            }

            //            di.Add(i, i);
            //        }
            //    }
            //    Console.WriteLine($"Added {((r + 1) * count / 1000000):N}");
            //}

            BufferPool <int> .MemoryPool.PrintStats();

            for (int _ = 0; _ < 2; _++)
            {
                var sa = new AppendSeries <int, int>();

                for (int r = 0; r < rounds; r++)
                {
                    using (Benchmark.Run("Append", count))
                    {
                        for (int i = r * count; i < (r + 1) * count; i++)
                        {
                            if (i == r * count + 3)
                            {
                                continue;
                            }

                            if (!sa.DangerousTryAppend(i, i))
                            {
                                Console.WriteLine("Cannot add " + i);
                                return;
                            }
                        }
                    }

                    Console.WriteLine($"Added {((r + 1) * count / 1_000_000):N}");
                }

                Benchmark.Dump();

                BufferPool <int> .MemoryPool.PrintStats();

                sa.Dispose();

                BufferPool <int> .MemoryPool.PrintStats();
            }
        }