/// <summary> /// insert this segment into cache, kick out other if needed /// </summary> /// <param name="seg"></param> /// <precondition>seg is a new page brought in memory</precondition> /// <postcondition>seg is insert into the cache, and the front of the LRU list, kick out one page if needed.</postcondition> internal void _put_in_cache(Segment seg) { //if the cache is full, kick least recently used one out if (m_cache.Count > m_cacheLimit) { //pick least recently used one Segment victim = m_LRU.Prev; Debug.Assert(victim != m_LRU); if (victim.Dirty) { //write it out to the disk byte[] content = victim.Serialize(); Debug.Assert(content.Length <= m_pageSize); m_diskFile.SynWrite(content, 0, victim.SegmentID * m_pageSize, content.Length); } victim.BreakLinks(); bool t = m_cache.Delete(victim.SegmentID); //removed this one out of the cache Debug.Assert(t); } if (m_cache.Insert(seg) == false) { throw new OOD.Exception.ProgramLogicError( this, "Trying to insert a existing key into CacheHashtable."); } seg.BuildLinks(m_LRU, m_LRU.Next); //move it the front of the LRU list }
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); }
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); }