コード例 #1
0
ファイル: memSegmentManager.cs プロジェクト: luanzhu/OOD.NET
		private			FileHeader		m_fileHeader; //the only file header in the two files, it is located at page 0.
		
		public memSegmentManager(DiskFile file)
		{
			m_cache = new CacheHashtable(m_cacheSize);

			m_pageSize = 1 << m_pageBits;
			m_diskFile = file;
			m_bitmap = new PageBitmap();
			m_fileHeader = new FileHeader();
			if (file.Length < m_bitmap.Data.Length + m_pageSize*2) //page 0 for fileheader, page 33 for segTree, page 44 for spacetree
			{
				//this helper file is a new one

				for (int i=0; i<(m_bitmap.Data.Length >> (m_pageBits + 3)); i++)
					m_bitmap.Data[i] = 0xFF;
				m_bitmap.SetPageTaken(m_bitmap.GetFirstFreePageID()); //one more page taken because of the fileheader
				m_bitmap.Dirty = true;

				m_fileHeader.SetInitializeNeeded();
			}
			else 
			{
				byte[] header = file.SynRead(0, m_pageSize);
				m_fileHeader.Deserialize(header);
				file.SynRead(m_bitmap.Data, 0, m_pageSize, m_bitmap.Data.Length);
			}

			m_LRU = new BNode();
		}
コード例 #2
0
ファイル: CacheHashtable.cs プロジェクト: luanzhu/OOD.NET
		public bool Insert(Segment seg)
		{
			Debug.Assert(Exists(seg.SegmentID) == false);

			int pos = (int)(seg.SegmentID % m_size);

			CacheEntry head = m_data[pos];

			if (head == null)
				m_data[pos] = new CacheEntry(seg);
			else
			{
				while (head.Next != null &&head.Segment.SegmentID != seg.SegmentID)
				{
					head = head.Next;
				}
				if (head.Segment.SegmentID == seg.SegmentID)
					return false;
				else
				{
					head.Next = new CacheEntry(seg,null);
				}
			}

			m_count ++;
			return true;
		}
コード例 #3
0
ファイル: memSegmentManager.cs プロジェクト: luanzhu/OOD.NET
		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;
			}
 		}
コード例 #4
0
ファイル: Segment.cs プロジェクト: luanzhu/OOD.NET
		public void BreakLinks()
		{
			m_prev.m_next = m_next;
			m_next.m_prev = m_prev;

			m_next = m_prev = this;
		}
コード例 #5
0
ファイル: Segment.cs プロジェクト: luanzhu/OOD.NET
		public void BuildLinks(Segment prev, Segment next)
		{
			m_prev = prev;
			m_next = next;

			prev.m_next = this;
			next.m_prev = this;
		}
コード例 #6
0
ファイル: dbSegmentManager.cs プロジェクト: luanzhu/OOD.NET
		private			int					m_threshold = 256; //256 bytes


		public dbSegmentManager(uint nextSegmentId, SegTree segTree, SpaceTree spaceTree, DiskFile file)
		{
			m_next_segment_id = nextSegmentId;
			m_segTree = segTree;
			m_cache = new CacheHashtable(m_cacheSize);
			m_diskFile = file;
			m_spaceTree = spaceTree;
			m_LRU = new BNode();
		}
コード例 #7
0
ファイル: dbSegmentManager.cs プロジェクト: luanzhu/OOD.NET
		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;	
			}
			
		}
コード例 #8
0
ファイル: dbSegmentManager.cs プロジェクト: luanzhu/OOD.NET
		/// <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
		}
コード例 #9
0
ファイル: dbSegmentManager.cs プロジェクト: luanzhu/OOD.NET
		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
		}
コード例 #10
0
ファイル: dbSegmentManager.cs プロジェクト: luanzhu/OOD.NET
		public override void GetNewSegment(Segment seg)
		{
			seg.SegmentID = m_next_segment_id;		
			seg.Initialize(m_next_segment_id++);
 
			_put_in_cache(seg);
		}
コード例 #11
0
ファイル: dbSegmentManager.cs プロジェクト: luanzhu/OOD.NET
		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);

		}
コード例 #12
0
ファイル: SegmentManager.cs プロジェクト: luanzhu/OOD.NET
		public abstract void FreeSegment(Segment seg);
コード例 #13
0
ファイル: SegmentManager.cs プロジェクト: luanzhu/OOD.NET
		public abstract void GetNewSegment(Segment seg);
コード例 #14
0
ファイル: memSegmentManager.cs プロジェクト: luanzhu/OOD.NET
		/// <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
		}
コード例 #15
0
ファイル: memSegmentManager.cs プロジェクト: luanzhu/OOD.NET
		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();
		}
コード例 #16
0
ファイル: memSegmentManager.cs プロジェクト: luanzhu/OOD.NET
		public override void GetNewSegment(Segment seg)
		{
			uint segId = m_bitmap.GetFirstFreePageID();
			seg.Initialize(segId);
			m_bitmap.SetPageTaken(segId);

			//put the new node into cache
			//kick out one if needed

			_put_in_cache(seg);
		}
コード例 #17
0
ファイル: SegmentManager.cs プロジェクト: luanzhu/OOD.NET
		public abstract Segment GetSegment(uint segId, Segment segFactory, object helper);
コード例 #18
0
ファイル: Segment.cs プロジェクト: luanzhu/OOD.NET
		protected Segment()
		{
			m_prev = m_next = this;
		}