public virtual void TestAllocateAndFree()
        {
            RecyclingInt32BlockAllocator allocator = NewAllocator();
            ISet <int[]> allocated        = new JCG.HashSet <int[]>();
            int          freeButAllocated = 0;

            int[] block = allocator.GetInt32Block();
            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.GetInt32Block();
                    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(4 * size * (allocated.Count + allocator.NumBufferedBlocks), allocator.BytesUsed, "" + (4 * size * (allocated.Count + allocator.NumBufferedBlocks) - allocator.BytesUsed));
                }

                int[][] array = allocated.ToArray(/*new int[0][]*/);
                int     begin = Random.Next(array.Length);
                int     end   = begin + Random.Next(array.Length - begin);
                for (int j = begin; j < end; j++)
                {
                    int[] b = array[j];
                    Assert.IsTrue(allocated.Remove(b));
                }
                allocator.RecycleInt32Blocks(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()
        {
            RecyclingInt32BlockAllocator allocator = NewAllocator();
            ISet <int[]> allocated = new JCG.HashSet <int[]>();

            int[] block = allocator.GetInt32Block();
            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.GetInt32Block();
                    Assert.IsNotNull(block);
                    Assert.AreEqual(size, block.Length);
                    Assert.IsTrue(allocated.Add(block), "block is returned twice");
                    Assert.AreEqual(4 * size * (allocated.Count + allocator.NumBufferedBlocks), allocator.BytesUsed);
                }
                int[][]       array    = allocated.ToArray(/*new int[0][]*/);
                int           begin    = Random.Next(array.Length);
                int           end      = begin + Random.Next(array.Length - begin);
                IList <int[]> selected = new List <int[]>();
                for (int j = begin; j < end; j++)
                {
                    selected.Add(array[j]);
                }
                allocator.RecycleInt32Blocks(array, begin, end);
                for (int j = begin; j < end; j++)
                {
                    Assert.IsNull(array[j]);
                    int[] b = selected[0];
                    selected.RemoveAt(0);
                    Assert.IsTrue(allocated.Remove(b));
                }
            }
        }
        public virtual void TestAllocate()
        {
            RecyclingInt32BlockAllocator allocator = NewAllocator();
            ISet <int[]> set = new JCG.HashSet <int[]>();

            int[] block = allocator.GetInt32Block();
            set.Add(block);
            Assert.IsNotNull(block);
            int size = block.Length;

            int num = AtLeast(97);

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