Example #1
0
        private void AllocPage(IByteBuf buf, int newSize, int size)
        {
            int          idx;
            PoolPageList pageList;

            if (IsTiny(newSize))
            {
                idx      = (newSize >> 4) - 1;
                pageList = tinyPoolPages[idx];
            }
            else
            {
                idx      = IntEx.Log2(newSize >> 10);
                pageList = smallPoolPages[idx];
            }

            var page = pageList.GetNextAvailPage();

            if (page != null)
            {
                long handle = page.Alloc(newSize);
                if (handle > -1)
                {
                    page.Chunk.BytebufInit(buf, handle, newSize, size);
                    useables += newSize;
                }
                return;
            }

            //1,如果缓存中没有elemsize=size的page
            //2,如果从缓冲中分配失败
            //1和2都满足,那么会重新分配一个新的page
            page = AllocNewPage(buf, newSize, size);

            if (page == null)
            {
                return;
            }

            pageList.AddLast(page);
        }
Example #2
0
        /// <summary>
        /// 更新bitmap,并返回当前的
        /// </summary>
        /// <returns></returns>
        private int GetHandleAndUpdateBitMap()
        {
            //
            //方法1:先遍历数组,再遍历位
            //优点:思路简单
            //缺点:极端条件下最高可能遍历512次
            //
            //for (int i = 0; i < bitmap.Length; i++)
            //{
            //    for (int j = 0; j < 64; j++)
            //    {
            //        //注意是1L不是1
            //        long mask = 1L << j;
            //        if ((bitmap[i] & mask) == 0)
            //        {
            //            bitmap[i] |= mask;
            //            return (i << 6) + j;  //i*64+j
            //        }
            //    }
            //}
            //return -1;

            //
            //方法2:采用位运算
            //优点:最多只需要遍历8次就能获得结果
            //缺点:不易理解
            //
            int result = -1;

            for (int i = 0; i < bitmap.Length; i++)
            {
                long b = bitmap[i];
                if (b != 0)
                {
                    /*
                     * 获得当前long的第一个1开始的值
                     * 比如:
                     *     10010001,计算得到1
                     *     10010010,计算得到10
                     *     10010100,计算得到100
                     */
                    long mask = b & ~(b - 1);

                    /*
                     * 关闭位
                     * 比如:bitmap[i]=10010100,mask=00000100
                     *     10010100 ^ 00000100 = 10010000 将第2号位的1置0
                     */
                    bitmap[i] ^= mask;

                    /*
                     * 为了方便传值,我们使用一个long类型来携带分配的信息
                     * (更清晰简单的办法是直接返回mask和索引i),这里我们将
                     * mask和i浓缩到一个long类型中来传递
                     *
                     * 根据掩码mask和索引i计算出具体的位数,因为long型的
                     * mask只有一个1,所以我们只需要得到值为1的序号就OK了
                     */

                    int h32 = (int)(mask >> 32);        //高32位的值
                    int l32 = (int)mask;                //低32位的值

                    //如果1在高位
                    if (h32 > 0)
                    {
                        //在高位时需要+32
                        //i<<6 = i*64 表示在第几号long中
                        return(IntEx.Log2(h32) + 32 + (i << 6));
                    }
                    //如果1在低位
                    else
                    {
                        return(IntEx.Log2(l32) + (i << 6));
                    }
                }
            }

            return(result);
        }