Пример #1
0
        /// <summary>读取内存块,自动识别是否空闲</summary>
        /// <param name="view"></param>
        public Boolean Read(MemoryView view)
        {
            var p = Position;

            if (p < 0)
            {
                throw new ArgumentNullException(nameof(Position));
            }

            if (p + 8 >= view.Capacity)
            {
                return(false);
            }

            // 不管是否空闲块,都是长度开头
            var len  = view.ReadInt64(p);
            var flag = len & 0b0000_0111;

            len -= flag;

            Size     = len;
            Free     = (flag & 0b0000_00001) > 0;
            PrevFree = (flag & 0b0000_00010) > 0;

            // 如果是空闲块,还要读取前后空闲指针,最后8字节则可以不用读取
            if (Free)
            {
                Next = view.ReadInt64(p + 8);
            }
            else
            {
                Next = 0;
            }

#if DEBUG
            XTrace.WriteLine("Read  " + this);
#endif

            return(true);
        }
Пример #2
0
        /// <summary>写入内存块</summary>
        /// <param name="view"></param>
        public void Write(MemoryView view)
        {
            var p = Position;

            if (p < 0)
            {
                throw new ArgumentNullException(nameof(Position));
            }

#if DEBUG
            //XTrace.WriteLine("Write " + this);
#endif

            // 8字节对齐
            var len = Align(Size);

            var len2 = len;
            if (Free)
            {
                len2 |= 0b0000_00001;
            }
            if (PrevFree)
            {
                len2 |= 0b0000_00010;
            }

            view.Write(p, len2);
            // 空闲块有下一块指针,尾部也有长度标记
            if (Free)
            {
                view.Write(p + 8, Next);
                if (Next > 0)
                {
                    view.Write(p + len - 8, len2);
                }

                // 修改下一个相邻块的PrevFree
                p += len;
                if (p + 8 < view.Capacity)
                {
                    len = view.ReadInt64(p);
                    // 标记下一相邻块的PrevFree为1
                    if ((len & 0b0000_00010) == 0)
                    {
                        len |= 0b0000_00010;
                        view.Write(p, len);
                    }
                }
            }
        }