internal void _write_back(Segment seg) { //write it out to the disk byte[] content = seg.Serialize(); //get its offset and length for the segment uint offset = 0; int length = -1; if (m_segTree.GetAddr(seg.SegmentID, ref offset, ref length)) { Debug.Assert(length != -1); if (content.Length > length) { //original space is too small //0. put original one fre m_spaceTree.SetSegmentFree(offset, length); //1. request a new segment with size = cotent.length + m_threshold; if (m_spaceTree.RequireSegment(content.Length + m_threshold, ref offset) == false) { throw new OOD.Exception.ProgramLogicError( this, "Error happed while requesting free space."); } //3. update the new addressing in m_segTree. if (m_segTree.UpdateAddr(seg.SegmentID, offset, content.Length + m_threshold) == false) { throw new OOD.Exception.ProgramLogicError( this, "Erro happened while updating addressing."); } } else if (content.Length < length - m_threshold) { //original space is too big, shrink it to length + 256; //1. update the addressing information in seqTree // int newLength = content.Length + m_threshold; // m_segTree.UpdateAddr(seg.SegmentID, offset, newLength); // // //2. insert the left empty space into the spaceTree // uint leftOffset = (uint)(offset + newLength); // newLength = length - newLength; // m_spaceTree.SetSegmentFree(leftOffset, newLength); } } else { Debug.Assert(length == -1); //this is a new segment, it is never assigned adress before //1. Request a free space if (m_spaceTree.RequireSegment(content.Length + m_threshold, ref offset) == false) { throw new OOD.Exception.ProgramLogicError( this, "Request space failed."); } //2.put this into the m_segTree if (m_segTree.InsertAddr(seg.SegmentID, offset, content.Length + m_threshold) == false) { throw new OOD.Exception.ProgramLogicError( this, "put segment addressing info failed in SegTree."); } } m_diskFile.SynWrite(content, 0, offset, content.Length); }