/// <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); }
/// <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); } } } }