示例#1
0
        /// <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
        }
示例#2
0
        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);
        }
示例#3
0
		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);

		}