Esempio n. 1
0
        /// <summary>
        /// 分配Page
        /// </summary>
        /// <param name="buf"></param>
        /// <param name="elemSize">Page页的元素尺寸</param>
        /// <param name="size">实际申请的字节数</param>
        /// <returns></returns>
        public PoolPage AllocPage(IByteBuf buf, int elemSize, int size)
        {
            if (!this.CanAlloc)
            {
                return(null);
            }

            //如果可用的字节数不足则返回null
            if (this.Availables < size)
            {
                return(null);
            }

            PoolPage page = AllocPage(elemSize, size);

            if (page == null)
            {
                return(null);
            }

            //分配一个句柄
            long handle = page.Alloc(elemSize);

            //计算偏移
            int offset = HandleToOffset(handle, elemSize);

            //初始化ByteBuf
            BytebufInit(this.memory, buf, handle, offset, size);

            return(page);
        }
Esempio n. 2
0
        /// <summary>
        /// 申请一个Page
        /// </summary>
        /// <param name="elemSize">page元素的尺寸</param>
        /// <param name="size">实际申请的内存尺寸</param>
        /// <returns></returns>
        public PoolPage AllocPage(int elemSize, int size)
        {
            //如果可用的字节数不足则返回null
            if (this.Availables < size)
            {
                return(null);
            }

            //计算申请内存尺寸在memoryMap中的深度
            AllocInfo alloc = CalcAllocDepth(size);

            //通过深度获得节点编号
            int id = AllocHandle(alloc.Depth);

            int tableId = PageIdx(id);

            PoolPage page = subpages[tableId];

            if (page == null)
            {
                page = new PoolPage(this, id, alloc.PageCapacity, elemSize);
                subpages[tableId] = page;
            }
            else if (!page.Allocated)
            {
                //找到一个被重置过的Page则重新进行分配
                page.ReAlloc(alloc.PageCapacity, elemSize);
            }

            usedables += pageSize;

            return(page);
        }
Esempio n. 3
0
        public bool TryAllocPage(IByteBuf buf, int newSize, int size, out PoolPage page)
        {
            page = null;

            if (Head == Tail && Head == null)
            {
                return(false);
            }

            PoolChunk chunk = Head;

            page = chunk.AllocPage(buf, newSize, size);

            while (page == null)
            {
                chunk = chunk.Next;
                if (chunk == null)
                {
                    return(false);
                }

                page = chunk.AllocPage(buf, newSize, size);
            }

            //转移chunk
            TryTransfer(chunk);

            return(true);
        }
Esempio n. 4
0
        private void ValidHandle(int handle)
        {
            try
            {
                PoolPage page = subpages[PageIdx(handle)];

                if (page == null)
                {
                    throw new IndexOutOfRangeException();
                }
            }
            catch (IndexOutOfRangeException)
            {
                throw new IndexOutOfRangeException("handle的值不合法");
            }
        }
Esempio n. 5
0
        /// <summary>
        /// 释放handle,当length=PageSize则表示释放整个Page的长度
        /// 否则只释放length长度
        ///
        /// 异常:
        ///     IndexOutOfRangeException:如果handle不合法抛出异常
        ///     IndexOutOfRangeException
        ///
        /// </summary>
        /// <param name="handle">需要释放的句柄</param>
        /// <param name="length">需要释放的长度</param>
        public void Return(int handle)
        {
            ValidHandle(handle);

            //将当前节点的值还原
            SetValue(handle, ValueDefaut(handle));

            //更新父节点
            UpdateParentNodeAllocation(handle);

            PoolPage page = subpages[PageIdx(handle)];

            page.Clear();

            usedables -= pageSize;

            //如果chunk空了。
            if (usedables == 0)
            {
                Return();
                arena.Return(this);
            }
        }