internal void SetHolderForNewRecord(Core.RecordHolder value) { System.Diagnostics.Debug.Assert(mmHolder == null, "mHolder can only be set once"); #if DUMP_FINALIZE System.Diagnostics.Trace.WriteLine(this.GetType().Name + " #" + value.mRecordNo); #endif mmHolder = value; }
/// <summary> /// Note that this method is called from flush and from the record destructor in the garbage collector thread. /// </summary> /// <param name="recordHolder"></param> internal void InternalFillWriteBuffer(RecordHolder recordHolder, Record record) { Debug.Assert(record != null, "InternalFillWriteBuffer : record must be not null."); var newBuffer = new Byte[mRecordWidth]; if (OnFillWriteBuffer(record, newBuffer)) { recordHolder.SetNewBuffer(newBuffer); } }
private void SetLastUsed(LinkedListNode <RecordHolder> linkListNode) { if (linkListNode.List == mRecordsByLastUsed) { if (linkListNode != mRecordsByLastUsed.Last) { mRecordsByLastUsed.Remove(linkListNode); mRecordsByLastUsed.AddLast(linkListNode); } } else { mRecordsByLastUsed.AddLast(linkListNode); } // for every table we use PERCENT_CACHED_RECORDS int limit = (int)(PERCENT_CACHED_RECORDS * mRecordCount); if (limit < MIN_CACHED_RECORDS) { limit = MIN_CACHED_RECORDS; } else if (limit > MAX_CACHED_RECORDS) { limit = MAX_CACHED_RECORDS; } var node = mRecordsByLastUsed.First; while (node != null && mRecordsByLastUsed.Count > limit) { RecordHolder recordHolder = node.Value; var nextNode = node.Next; node.Value.Hold = false; mRecordsByLastUsed.Remove(node); #if DUMP_FINALIZE System.Diagnostics.Trace.WriteLine(this.mOriginalFile + " Remove last used Record #" + recordHolder.mRecordNo); #endif node = nextNode; } }
internal void EmptyTable() { var node = mRecordsByLastUsed.First; while (node != null && mRecordsByLastUsed.Count > 0) { RecordHolder recordHolder = node.Value; var nextNode = node.Next; recordHolder.Save(); node = nextNode; } #if DUMP_FINALIZE System.Diagnostics.Trace.WriteLine(this.mOriginalFile + " Clear Records"); #endif mRecordsByRecordNo.Clear(); mRecordsByLastUsed.Clear(); mRecordCount = 0; mStream.SetLength(mHeaderWidth); }
public virtual object NewRecord() { var recordNo = mRecordCount; mRecordCount += 1; var result = OnCreateNewRecord(/*isnew*/ true, recordNo); var holder = new RecordHolder(this, recordNo, result); var linkedListNode = new LinkedListNode <RecordHolder>(holder); result.SetHolderForNewRecord(holder); mRecordsByRecordNo[recordNo] = linkedListNode; SetLastUsed(linkedListNode); #if DUMP_FINALIZE System.Diagnostics.Trace.WriteLine(this.mOriginalFile + " Add Record #" + recordNo); #endif return(result); }
internal virtual protected Record InternalGetRecord(UInt32 recordNo, bool returnNullIfNotInCache) { Debug.Assert(recordNo < UInt32.MaxValue, "Invalid RecordNo"); LinkedListNode <RecordHolder> linkListNode = null; RecordHolder holder = null; Record record = null; if (mRecordsByRecordNo.TryGetValue(recordNo, out linkListNode)) { holder = linkListNode.Value; record = holder.Record; if (record != null) { SetLastUsed(linkListNode); return(record); } else { // we're going to add a new one in one sec RemoveLastUsed(linkListNode); } } if (returnNullIfNotInCache) { return(null); } // we're here because the record was disposed or never created var newRecord = OnCreateNewRecord(/*isnew*/ false, recordNo); if (holder == null) { holder = new RecordHolder(this, recordNo, newRecord); linkListNode = new LinkedListNode <RecordHolder>(holder); SetLastUsed(linkListNode); mRecordsByRecordNo[recordNo] = linkListNode; #if DUMP_FINALIZE System.Diagnostics.Trace.WriteLine(this.mOriginalFile + " Save Record #" + recordNo); #endif } else { // holder exist but object doesn't we expect that a finalized happened if (holder.RecordFinalized.WaitOne(10000)) { // we (re)connect the recordHolder to the new Record holder.RecordFinalized.Reset(); holder.Record = newRecord; } else { throw new Exception("Something very wrong happened."); } } newRecord.SetHolderForNewRecord(holder); Byte[] sourceBuffer = holder.GetCurrentBuffer(/*readIfNeeded*/ true); OnReadRecordBuffer(sourceBuffer, newRecord); return(newRecord); }