public virtual void TestAllocateAndFree()
        {
            RecyclingByteBlockAllocator allocator = NewAllocator();
            var allocated        = new HashSet <byte[]>();
            int freeButAllocated = 0;
            var block            = allocator.ByteBlock;

            allocated.Add(block);
            Assert.IsNotNull(block);
            int size = block.Length;

            int numIters = AtLeast(97);

            for (int i = 0; i < numIters; i++)
            {
                int num = 1 + Random().Next(39);
                for (int j = 0; j < num; j++)
                {
                    block            = allocator.ByteBlock;
                    freeButAllocated = Math.Max(0, freeButAllocated - 1);
                    Assert.IsNotNull(block);
                    Assert.AreEqual(size, block.Length);
                    Assert.IsTrue(allocated.Add(block), "block is returned twice");
                    Assert.AreEqual(size * (allocated.Count + allocator.NumBufferedBlocks()), allocator.BytesUsed());
                }

                var array = allocated.ToArray();
                int begin = Random().Next(array.Length);
                int end   = begin + Random().Next(array.Length - begin);
                for (int j = begin; j < end; j++)
                {
                    var b = array[j];
                    Assert.IsTrue(allocated.Remove(b));
                }
                allocator.RecycleByteBlocks(array, begin, end);
                for (int j = begin; j < end; j++)
                {
                    Assert.IsNull(array[j]);
                }
                // randomly free blocks
                int numFreeBlocks = allocator.NumBufferedBlocks();
                int freeBlocks    = allocator.FreeBlocks(Random().Next(7 + allocator.MaxBufferedBlocks()));
                Assert.AreEqual(allocator.NumBufferedBlocks(), numFreeBlocks - freeBlocks);
            }
        }
        public virtual void TestAllocateAndRecycle()
        {
            RecyclingByteBlockAllocator allocator = NewAllocator();
            var allocated = new HashSet <byte[]>();

            var block = allocator.ByteBlock;

            allocated.Add(block);
            Assert.IsNotNull(block);
            int size = block.Length;

            int numIters = AtLeast(97);

            for (int i = 0; i < numIters; i++)
            {
                int num = 1 + Random().Next(39);
                for (int j = 0; j < num; j++)
                {
                    block = allocator.ByteBlock;
                    Assert.IsNotNull(block);
                    Assert.AreEqual(size, block.Length);
                    Assert.IsTrue(allocated.Add(block), "block is returned twice");
                    Assert.AreEqual(size * (allocated.Count + allocator.NumBufferedBlocks()), allocator.BytesUsed());
                }
                var array    = allocated.ToArray();
                int begin    = Random().Next(array.Length);
                int end      = begin + Random().Next(array.Length - begin);
                var selected = new List <byte[]>();
                for (int j = begin; j < end; j++)
                {
                    selected.Add(array[j]);
                }
                allocator.RecycleByteBlocks(array, begin, end);
                for (int j = begin; j < end; j++)
                {
                    Assert.IsNull(array[j]);
                    var b = selected[0];
                    selected.RemoveAt(0);
                    Assert.IsTrue(allocated.Remove(b));
                }
            }
        }
        public virtual void TestAllocate()
        {
            RecyclingByteBlockAllocator allocator = NewAllocator();
            var set   = new HashSet <byte[]>();
            var block = allocator.ByteBlock;

            set.Add(block);
            Assert.IsNotNull(block);
            int size = block.Length;

            int num = AtLeast(97);

            for (int i = 0; i < num; i++)
            {
                block = allocator.ByteBlock;
                Assert.IsNotNull(block);
                Assert.AreEqual(size, block.Length);
                Assert.IsTrue(set.Add(block), "block is returned twice");
                Assert.AreEqual(size * (i + 2), allocator.BytesUsed()); // zero based + 1
                Assert.AreEqual(0, allocator.NumBufferedBlocks());
            }
        }