/// <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_back(victim); } 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 an existing key into CacheHashtable"); } seg.BuildLinks(m_LRU, m_LRU.Next); //move it the front of the LRU list }
/// <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 }
public override Segment GetSegment(uint segId, Segment segFactory, object helper) { Debug.Assert(segId >= (m_bitmap.Data.Length >> m_pageBits)); Debug.Assert(m_bitmap.PageFree(segId) == false); if (m_cache.Exists(segId)) { //requested page is in the cache Segment seg = m_cache.Retrive(segId); //update recently used page list, move this one to the front of the list, most recently used. seg.BreakLinks(); seg.BuildLinks(m_LRU, m_LRU.Next); return(seg); } else { //the requested page is not in the cache, read it from disk byte[] content = m_diskFile.SynRead(segId * m_pageSize, m_pageSize); Segment seg = segFactory.Deserialize(segId, helper, content); _put_in_cache(seg); return(seg); } }
public override void FreeSegment(Segment seg) { m_bitmap.SetPageFree(seg.SegmentID); //remove that one from cache m_cache.Delete(seg.SegmentID); //remove it from the LRU list also seg.BreakLinks(); }
public override Segment GetSegment(uint segId, Segment segFactory, object helper) { Segment result = null; //check if this segment is already in cache if (m_cache.Exists(segId)) { result = m_cache.Retrive(segId); //update the least recently used list result.BreakLinks(); result.BuildLinks(m_LRU, m_LRU.Next); return(result); } else { //if not, read that from disk uint offset = 0; int length = 0; if (m_segTree.GetAddr(segId, ref offset, ref length)) { // put this segment into cache byte[] content = m_diskFile.SynRead(offset, length); result = segFactory.Deserialize(segId, helper, content); _put_in_cache(result); } else { throw new OOD.Exception.ProgramLogicError( this, "Trying to access a non-existing segment."); } return(result); } }
public override void FreeSegment(Segment seg) { //remove it from cache this.m_cache.Delete(seg.SegmentID); //remove it from LRU list seg.BreakLinks(); uint offset = 0; int length = -1; if (m_segTree.GetAddr(seg.SegmentID, ref offset, ref length)) { Debug.Assert(length != -1); //this segment's addressing info is in the system. //put this segment into the free tree m_spaceTree.SetSegmentFree(offset, length); //remove its addressing information from segTree m_segTree.DeleteSegment(seg.SegmentID); } //if this segment is never written back to disk, just delete it from memory is enough }