/// <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); }
/// <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); }
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); }
private void ValidHandle(int handle) { try { PoolPage page = subpages[PageIdx(handle)]; if (page == null) { throw new IndexOutOfRangeException(); } } catch (IndexOutOfRangeException) { throw new IndexOutOfRangeException("handle的值不合法"); } }
/// <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); } }