Ejemplo n.º 1
0
        /// <summary>
        /// Add the ByteBufChunk to this ByteBufChunkList linked-list based on ByteBufChunk's usage.
        /// So it will be moved to the right ByteBufChunkList that has the correct minUsage/maxUsage.
        /// </summary>
        /// <param name="chunk">The ByteBufChunk to be added</param>
        public void Add(ByteBufChunk chunk)
        {
            if (chunk.Usage >= maxUsage)
            {
                NextList.Add(chunk);
                return;
            }

            AddInternal(chunk);
        }
Ejemplo n.º 2
0
        public ByteBuf Allocate()
        {
            ByteBuf byteBuf;

            if (q050.Allocate(out byteBuf) || q025.Allocate(out byteBuf) ||
                q000.Allocate(out byteBuf) || qInit.Allocate(out byteBuf) ||
                q075.Allocate(out byteBuf))
            {
                return(byteBuf);
            }

            // Add a new chunk and allocate a segment from it.
            try
            {
                var chunk = ByteBufChunk.NewChunk(this, SegmentSize, ChunkSize, isUnsafe);
                if (!chunk.Allocate(out byteBuf))
                {
                    logger.LogError("Failed to allocate a ByteBuf from a new ByteBufChunk - isUnsafe [{0}].", isUnsafe);
                    return(null);
                }
                qInit.Add(chunk);
                return(byteBuf);
            }
            catch (Exception e)
            {
                logger.LogException(e);
                return(null);
            }
        }
Ejemplo n.º 3
0
        public ByteBuf Allocate()
        {
            var     trial = 0;
            ByteBuf byteBuf;

            do
            {
                if (q050.Allocate(out byteBuf) || q025.Allocate(out byteBuf) ||
                    q000.Allocate(out byteBuf) || qInit.Allocate(out byteBuf) ||
                    q075.Allocate(out byteBuf))
                {
                    return(byteBuf);
                }

                // Issues a pause instruction on each loop iteration,
                // and not fall back to a more expensive wait on.
                Thread.Sleep(0);
                trial++;
            } while (trial < TrialsCount);

            // Add a new chunk and allocate a segment from it.
            try
            {
                var chunk = ByteBufChunk.NewChunk(this, SegmentSize, ChunkSize, isUnsafe);
                if (!chunk.Allocate(out byteBuf))
                {
                    logger.LogError("Failed to allocate a ByteBuf from a new ByteBufChunk - isUnsafe [{0}].",
                                    isUnsafe);
                    return(null);
                }

                qInit.Add(chunk);
                return(byteBuf);
            }
            catch (Exception e)
            {
                logger.LogException(e);
                return(null);
            }
        }
Ejemplo n.º 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
        }