Пример #1
0
        /// <summary>
        /// Initializes a new ByteBufPool instance with a given segment size and chunk order.
        /// If isUnsafe is true, all memory will be allocated from process's heap by using
        /// native HeapAlloc API.
        /// </summary>
        /// <param name="segmentSize">The size of a segment</param>
        /// <param name="chunkOrder">Used to caculate chunk size and ensures it is a multiple of a segment size</param>
        /// <param name="isUnsafe">Indicates whether allocates memory from process's heap</param>
        public ByteBufPool(int segmentSize, int chunkOrder, bool isUnsafe)
        {
            SegmentSize = segmentSize;
            ChunkSize = ValidateAndCalculateChunkSize(segmentSize, chunkOrder);
            this.isUnsafe = isUnsafe;

            q100 = new ByteBufChunkList(null, 100, int.MaxValue); // No maxUsage for this list. All 100% usage of chunks will be in here.
            q075 = new ByteBufChunkList(q100, 75, 100);
            q050 = new ByteBufChunkList(q075, 50, 100);
            q025 = new ByteBufChunkList(q050, 25, 75);
            q000 = new ByteBufChunkList(q025, 1, 50);
            qInit = new ByteBufChunkList(q000, int.MinValue, 25); // No minUsage for this list. All new chunks will be inserted to here.

            q100.PrevList = q075;
            q075.PrevList = q050;
            q050.PrevList = q025;
            q025.PrevList = q000;
            q000.PrevList = null;
            qInit.PrevList = qInit;
        }
Пример #2
0
        public const int DefaultChunkOrder = 7; // 65536 << 8 = 16 MBytes per chunk

        /// <summary>
        /// Initializes a new ByteBufPool instance with a given segment size and chunk order.
        /// If isUnsafe is true, all memory will be allocated from process's heap by using
        /// native HeapAlloc API.
        /// </summary>
        /// <param name="segmentSize">The size of a segment</param>
        /// <param name="chunkOrder">Used to caculate chunk size and ensures it is a multiple of a segment size</param>
        /// <param name="isUnsafe">Indicates whether allocates memory from process's heap</param>
        public ByteBufPool(int segmentSize, int chunkOrder, bool isUnsafe)
        {
            SegmentSize   = segmentSize;
            ChunkSize     = ValidateAndCalculateChunkSize(segmentSize, chunkOrder);
            this.isUnsafe = isUnsafe;

            q100  = new ByteBufChunkList(null, 100, int.MaxValue); // No maxUsage for this list. All 100% usage of chunks will be in here.
            q075  = new ByteBufChunkList(q100, 75, 100);
            q050  = new ByteBufChunkList(q075, 50, 100);
            q025  = new ByteBufChunkList(q050, 25, 75);
            q000  = new ByteBufChunkList(q025, 1, 50);
            qInit = new ByteBufChunkList(q000, int.MinValue, 25); // No minUsage for this list. All new chunks will be inserted to here.

            q100.PrevList  = q075;
            q075.PrevList  = q050;
            q050.PrevList  = q025;
            q025.PrevList  = q000;
            q000.PrevList  = null;
            qInit.PrevList = qInit;
        }
Пример #3
0
 /// <summary>
 /// Initializes a ByteBufChunkList instance with the next ByteBufChunkList and minUsage and maxUsage
 /// </summary>
 /// <param name="nextList">The next item of this ByteBufChunkList</param>
 /// <param name="minUsage">The definition of minimum usage to contain ByteBufChunk</param>
 /// <param name="maxUsage">The definition of maximum usage to contain ByteBufChunk</param>
 public ByteBufChunkList(ByteBufChunkList nextList, int minUsage, int maxUsage)
 {
     NextList      = nextList;
     this.minUsage = minUsage;
     this.maxUsage = maxUsage;
 }
Пример #4
0
        public void TestAllocateAndFree()
        {
            var q50 = new ByteBufChunkList(null, 50, 200);
            var q00 = new ByteBufChunkList(q50, 1, 50);
            q00.PrevList = null;
            q50.PrevList = q00;

            // This chunk can only allocate 4 ByteBufs totally
            var chunk1 = ByteBufChunk.NewChunk(bufPool, bufPool.SegmentSize, bufPool.ChunkSize, false);
            var chunk2 = ByteBufChunk.NewChunk(bufPool, bufPool.SegmentSize, bufPool.ChunkSize, false);
            var chunk3 = ByteBufChunk.NewChunk(bufPool, bufPool.SegmentSize, bufPool.ChunkSize, false);

            //
            // Verify Allocate()
            //
            q00.Add(chunk1);
            // Verify the chunk is hosted in q50.
            Assert.AreEqual(chunk1.ToString(), q00.ToString());
            // Verify allocation success
            ByteBuf byteBuf1;
            Assert.IsTrue(q00.Allocate(out byteBuf1));
            // Verify the chunk be moved to next list.
            ByteBuf byteBuf2;
            Assert.IsTrue(q00.Allocate(out byteBuf2));
            Assert.AreEqual(chunk1.ToString(), q50.ToString()); // chunk1 is in q50 now

            // Allocates from q50
            ByteBuf byteBuf3;
            Assert.IsTrue(q50.Allocate(out byteBuf3));
            ByteBuf byteBuf4;
            Assert.IsTrue(q50.Allocate(out byteBuf4));
            // Verify failed allocation due to chunk 100% usage
            ByteBuf byteBuf5;
            Assert.AreEqual(100, chunk1.Usage);
            Assert.IsFalse(q50.Allocate(out byteBuf5));
            // Verify allocation success from chunk2
            q50.Add(chunk2);
            Assert.IsTrue(q50.Allocate(out byteBuf5));
            Assert.AreEqual(chunk2, byteBuf5.ByteBufChunk);

            //
            // Verify Free()
            //

            // Build chunk1's chain for Free()
            chunk1.Next = chunk3;
            chunk3.Prev = chunk1;

            // Verify Free() returns false due to chunk2's usage is 0
            // that means the chunk need to be destroyed.
            Assert.IsFalse(q50.Free(chunk2, byteBuf5));
            q50.Add(chunk2);

            // Free chunk1 from q50 now.
            Assert.IsTrue(q50.Free(chunk1, byteBuf4));
            Assert.IsTrue(q50.Free(chunk1, byteBuf3));
            Assert.IsTrue(q50.Free(chunk1, byteBuf2));
            Assert.AreEqual(chunk1.ToString(), q00.ToString()); // chunk1 is in q00 now
            Assert.AreSame(q00, chunk1.Parent);
            Assert.AreSame(chunk3, chunk2.Next);

            // Free chunk1 from q00 now.
            Assert.IsFalse(q00.Free(chunk1, byteBuf1));
            Assert.AreEqual("none", q00.ToString()); // q00 is empty now
        }
Пример #5
0
 /// <summary>
 /// Initializes a ByteBufChunkList instance with the next ByteBufChunkList and minUsage and maxUsage
 /// </summary>
 /// <param name="nextList">The next item of this ByteBufChunkList</param>
 /// <param name="minUsage">The definition of minimum usage to contain ByteBufChunk</param>
 /// <param name="maxUsage">The definition of maximum usage to contain ByteBufChunk</param>
 public ByteBufChunkList(ByteBufChunkList nextList, int minUsage, int maxUsage)
 {
     NextList = nextList;
     this.minUsage = minUsage;
     this.maxUsage = maxUsage;
 }