private void PackSlotFillers(BTreeAlgorithm parent, System.IO.BinaryWriter writer, object simpleKey, ref int keySizeOnDisk, ref byte[] keyOfEmptySlots) { // write filler space same size as VersionNumber CollectionOnDisk.WritePersistentData(parent, 0L, writer); // write filler space same size as Key if (keySizeOnDisk > 0 || simpleKey == null) { if (keySizeOnDisk == 0) { keySizeOnDisk = 20; keySizeOnDisk += (sizeof(long) * 2); } if (keyOfEmptySlots == null) { keyOfEmptySlots = new byte[keySizeOnDisk]; } CollectionOnDisk.WritePersistentData(parent, keyOfEmptySlots, writer, ItemType.Key); } else { CollectionOnDisk.WritePersistentData(parent, simpleKey, writer, ItemType.Key); } // write filler space same size as Value's Address on disk //CollectionOnDisk.WritePersistentData(parent, -1L, writer); }
//** todo: 1/7/09: Copy On Write(COW) each Register block to a backup file that //** gets overwritten over and over as only last activity detail data is logged/rolled back //** NOTE: older activities are deemed successful if there is a newer activity(ie - the last activity) //** idea: // 1. track new Add/Growth segments, don't track Save on said segments as, //** they can be stashed away without harm as only added on transaction that will be rolled //** back if failed/program crash // 2. track updated segments not in Add/Growth to allow rollback of said segments. // 3. last action entry will be rolled back on restart... protected internal override void RegisterAdd(CollectionOnDisk collection, long blockAddress, int blockSize) { //** all transaction collections reside in TransactionFile which will be rolled back and //** truncated during restart after program crash... Transaction.RegisterAdd(_addStore, _fileGrowthStore, _recycledCollectionStore, collection, blockAddress, blockSize, true); }
private void AllocateOnNextSegment(CollectionOnDisk parent, HeaderData hd, Sop.DataBlock block) { long g; long segmentSize = parent.Grow(out g); if (segmentSize > 0) { Transaction.ITransactionLogger trans = parent.Transaction; if (trans != null) { ((Transaction.TransactionBase)trans).RegisterFileGrowth(parent, g, segmentSize); } } else { string s = string.Format("File '{0}' failed to grow.", parent.File.Filename); //_logger.LogLine(s); throw new InvalidOperationException(s); } hd.OnDiskLeftoverSegmentSize = (int)(hd.EndAllocatableAddress - hd.NextAllocatableAddress); hd.StartAllocatableAddress = g; hd.EndAllocatableAddress = hd.StartAllocatableAddress + segmentSize; hd.NextAllocatableAddress = hd.StartAllocatableAddress; block.DataAddress = hd.NextAllocatableAddress; hd.NextAllocatableAddress += block.Length; hd.DiskBuffer.IsDirty = true; hd.IsModifiedInTransaction = true; }
protected internal override void RegisterFileGrowth(CollectionOnDisk collection, long segmentAddress, long segmentSize) { //** all transaction collections reside in TransactionFile which will be rolled back and //** truncated during restart after program crash... Transaction.RegisterFileGrowth(_fileGrowthStore, collection, segmentAddress, segmentSize, false); }
/// <summary> /// RegisterAdd will be called whenever a "new" block is allocated. /// Don't save block at this point as changes not saved yet. /// </summary> /// <param name="collection"></param> /// <param name="blockAddress"></param> /// <param name="blockSize"></param> protected internal override void RegisterAdd(CollectionOnDisk collection, long blockAddress, int blockSize) { if (IsTransactionStore(collection)) { ((TransactionBase)collection.ParentTransactionLogger).RegisterAdd(collection, blockAddress, blockSize); return; } if (LogCollection == null) { return; } RecordKey key = CreateKey(collection, blockAddress); //** Check if Block is in Growth Segments if (RegionLogic.IsSegmentInStore(_fileGrowthStore, key, blockSize) || RegionLogic.IsSegmentInStore(_recycledSegmentsStore, key, blockSize)) { if (_inCommit == 0) { TrackModification(collection.GetTopParent()); } return; } RegisterAdd(_addBlocksStore, _fileGrowthStore, _recycledSegmentsStore, collection, blockAddress, blockSize, false); if (_inCommit == 0) { TrackModification(collection.GetTopParent()); } }
private void RegisterRemovedBlock(CollectionOnDisk container, long blockAddress, int blockSize) { // register removed block if (container.Transaction != null) { ((Transaction.TransactionBase)container.Transaction).Register( Sop.Transaction.ActionType.Remove, (CollectionOnDisk)container, blockAddress, blockSize); } }
private void PackSlotItem(BTreeAlgorithm parent, System.IO.BinaryWriter writer, BTreeItemOnDisk slot, ref int keySizeOnDisk, bool?isKeySimpleType) { if (slot != null) { IO.OnDiskBinaryWriter _writer = (IO.OnDiskBinaryWriter)writer; long streamPos = _writer.LogicalPosition; if (slot.Value.IsDirty) { slot.VersionNumber++; } CollectionOnDisk.WritePersistentData(parent, slot.VersionNumber, writer); CollectionOnDisk.WritePersistentData(parent, slot.Key, writer, ItemType.Key); if (parent.IsDataInKeySegment) { if (parent.IsDataLongInt) { writer.Write((long)slot.Value.Data); } else { if (parent.PersistenceType == PersistenceType.Unknown) { parent.PersistenceType = CollectionOnDisk.GetPersistenceType(parent, slot.Value.Data, ItemType.Value); parent.IsDirty = true; } //** write the value and keep track of its data size and location in the disk buffer. //slot.ValueBlockIndex = DiskBuffer.GetIndexOf(((OnDiskBinaryWriter)writer).DataBlock); //slot.ValueIndexInBlock = ((OnDiskBinaryWriter) writer).DataBlockPosition; long startPos = _writer.LogicalPosition; //parent.PersistenceType CollectionOnDisk.WritePersistentData(parent, slot.Value.Data, writer, ItemType.Value); slot.HintSizeOnDisk = (int)(_writer.LogicalPosition - startPos); //** } slot.Value.IsDirty = false; } else { if (slot.Value.diskBuffer == null) { slot.Value.DiskBuffer = parent.CreateBlock(); //new Sop.DataBlock(parent.DataBlockSize); } writer.Write(parent.GetId(slot.Value.DiskBuffer)); } if (keySizeOnDisk == 0) { int keyDataSize = (int)(_writer.LogicalPosition - streamPos); keySizeOnDisk = keyDataSize; parent.HintKeySizeOnDisk = keyDataSize; } } }
protected internal override void RegisterRecycleCollection(CollectionOnDisk collection, long blockAddress, int blockSize) { RecordKey key = CreateKey(collection, blockAddress); if (!_recycledCollectionStore.ContainsKey(key)) { RegisterFileGrowth(_recycledCollectionStore, collection, blockAddress, blockSize, true); } }
internal static void RegisterAdd( Collections.Generic.ISortedDictionary <RecordKey, long> addStore, Collections.Generic.ISortedDictionary <RecordKey, long> fileGrowthStore, Collections.Generic.ISortedDictionary <RecordKey, long> recycledCollectionStore, CollectionOnDisk collection, long blockAddress, int blockSize, bool checkIfInGrowthSegments) { RecordKey key = CreateKey(collection, blockAddress); RegisterAdd(addStore, fileGrowthStore, recycledCollectionStore, key, blockSize, checkIfInGrowthSegments); }
override internal protected void TrackModification(CollectionOnDisk collection, bool untrack = false) { CollectionOnDisk p = collection; // Collection.GetTopParent(); RecordKey key = CreateKey(p); if (!untrack) { ModifiedCollections[key] = p; return; } ModifiedCollections.Remove(key); }
private bool IsInUpdatedBlocks(CollectionOnDisk collection, long blockAddress, int blockSize) { BackupDataLogKey logKey = new BackupDataLogKey(); logKey.SourceFilename = collection.File.Filename; logKey.SourceDataAddress = blockAddress; IEnumerable <KeyValuePair <BackupDataLogKey, BackupDataLogValue> > intersectingLogs; long mergedBlockStartAddress, mergedBlockSize; return(GetIntersectingLogs(logKey, blockSize, out intersectingLogs, out mergedBlockStartAddress, out mergedBlockSize) && intersectingLogs == null); }
/// <summary> /// Register file growth /// </summary> /// <param name="collection"></param> /// <param name="segmentAddress"></param> /// <param name="segmentSize"></param> protected internal override void RegisterFileGrowth(CollectionOnDisk collection, long segmentAddress, long segmentSize) { if (IsTransactionStore(collection)) { ((TransactionBase)collection.ParentTransactionLogger).RegisterFileGrowth(collection, segmentAddress, segmentSize); return; } if (LogCollection != null) { RegisterFileGrowth(_fileGrowthStore, collection, segmentAddress, segmentSize, false); } }
/// <summary> /// Pack this Item for serialization to disk /// </summary> /// <param name="parent"></param> /// <param name="writer"></param> public virtual void Pack(IInternalPersistent parent, System.IO.BinaryWriter writer) { bool isReference = Value.DiskBuffer.DataAddress > -1; writer.Write(isReference); if (isReference) { writer.Write(Value.DiskBuffer.DataAddress); } else { CollectionOnDisk.WritePersistentData(parent, Value, writer); } }
/// <summary> /// Unpack or read the contents of this object from a Binary Reader. /// </summary> /// <param name="parent"></param> /// <param name="reader"></param> public override void Unpack(IInternalPersistent parent, System.IO.BinaryReader reader) { DataIsUserDefined = false; bool?r = CollectionOnDisk.ReadPersistentData(parent, reader, ref Data); if (r == null) { DataIsUserDefined = true; } else if (!r.Value) { Data = null; } }
private void AllocateAvailableBlock(CollectionOnDisk parent, HeaderData hd, Sop.DataBlock block) { //** Allocate block from the "available" segment block.DataAddress = hd.NextAllocatableAddress; hd.NextAllocatableAddress += block.Length; hd.DiskBuffer.IsDirty = true; hd.IsModifiedInTransaction = true; //** register the add of new block to transaction log Transaction.ITransactionLogger trans = parent.Transaction; if (trans == null) { return; } ((Transaction.TransactionBase)trans).RegisterAdd(parent, block.DataAddress, block.Length); }
protected internal override bool RegisterRecycle(CollectionOnDisk collection, long blockAddress, int blockSize) { if (!Transaction.RegisterRecycle(_addBlocksStore, _recycledBlocksStore, collection, blockAddress, blockSize)) { using (var writePool = new ConcurrentIOPoolManager()) { using (var readPool = new ConcurrentIOPoolManager()) { RegisterSave(collection, blockAddress, blockSize, readPool, writePool); } } } return(true); }
internal static bool RegisterRecycle( Collections.Generic.ISortedDictionary <RecordKey, long> addStore, Collections.Generic.ISortedDictionary <RecordKey, long> recycleStore, CollectionOnDisk collection, long blockAddress, int blockSize) { var key = CreateKey(collection, blockAddress); //if (InStore(key, blockSize, recycleStore)) // return false; BackupDataLogKey logKey = new BackupDataLogKey(); logKey.SourceFilename = collection.File.Filename; logKey.SourceDataAddress = blockAddress; IEnumerable <KeyValuePair <BackupDataLogKey, BackupDataLogValue> > intersectingLogs; long mergedBlockStartAddress, mergedBlockSize; if (GetIntersectingLogs(logKey, blockSize, out intersectingLogs, out mergedBlockStartAddress, out mergedBlockSize)) { if (intersectingLogs == null) { RegisterAdd(addStore, null, null, collection, blockAddress, blockSize, false); return(true); } // get area(s) outside each intersecting segment and back it up... Region newRegion = new Region(blockAddress, blockSize); bool wasIntersected = false; foreach (KeyValuePair <BackupDataLogKey, BackupDataLogValue> entry in intersectingLogs) { if (newRegion.Subtract(entry.Key.SourceDataAddress, entry.Value.DataSize)) { wasIntersected = true; } } if (wasIntersected) { foreach (KeyValuePair <long, int> newArea in newRegion) { RegisterAdd(addStore, null, null, collection, newArea.Key, newArea.Value, false); } return(true); } } RegisterAdd(addStore, null, null, collection, blockAddress, blockSize, false); return(true); }
protected internal override void RegisterRemove(CollectionOnDisk collection) { if (IsTransactionStore(collection)) { ((TransactionBase)collection.ParentTransactionLogger).RegisterRemove(collection); return; } if (LogCollection == null) { return; } if (_inCommit == 0) { TrackModification(collection.GetTopParent()); } }
/// <summary> /// Recycle DataSet, KeySet and DeletedBlocks' Segments /// </summary> public override void Delete() { if (DataBlockDriver != null) { RemoveDeletedDataBlocks(); CollectionOnDisk cod = GetTopParent(); IDataBlockRecycler db = cod.deletedBlocks; cod.deletedBlocks = null; if (DataSet != null) { DataSet.Delete(); } cod.deletedBlocks = db; } base.Delete(); }
public void Register(ActionType action, CollectionOnDisk collection, long blockAddress, long blockSize) { switch (action) { case ActionType.Add: if (blockSize > (long)DataBlockSize.Maximum) { throw new ArgumentOutOfRangeException("blockSize"); } RegisterAdd(collection, blockAddress, (int)blockSize); break; case ActionType.Remove: if (blockSize > int.MaxValue) { throw new ArgumentOutOfRangeException("Register: ActionType.Remove blockSize is bigger than int.MaxValue."); } RegisterRemove(collection, blockAddress, (int)blockSize); break; case ActionType.Grow: RegisterFileGrowth(collection, blockAddress, blockSize); break; case ActionType.Recycle: if (blockSize > int.MaxValue) { throw new ArgumentOutOfRangeException("Register: ActionType.Recycle blockSize is bigger than int.MaxValue."); } RegisterRecycle(collection, blockAddress, (int)blockSize); break; case ActionType.RecycleCollection: if (blockSize > int.MaxValue) { throw new ArgumentOutOfRangeException("blockSize"); } RegisterRecycleCollection(collection, blockAddress, (int)blockSize); break; default: throw new SopException(string.Format("Unsupported Transaction Action {0}", action)); } }
internal bool ResurfaceDeletedBlockNextSegment(CollectionOnDisk parent, DeletedBlockInfo dbi, long segmentEnd) { //** read next segment of deleted collection Sop.DataBlock db = CreateBlock(parent.DataBlockSize); long address = segmentEnd - (int)parent.DataBlockSize; db = ReadBlockFromDisk(parent, address, true, true, db); if (db.InternalNextBlockAddress >= 0) { dbi.StartBlockAddress = db.InternalNextBlockAddress; if (parent.File.DeletedCollections != null) { parent.File.DeletedCollections.SetTop(dbi); } return(true); } return(false); }
/// <summary> /// Create/Get Data Store for IPersistent typed Key and "Simple typed" Value. /// NOTE: Simple type means one of the integer, numeric(decimals,...), char data types, byte array /// or a string /// </summary> /// <typeparam name="TKey"></typeparam> /// <typeparam name="TValue"></typeparam> /// <param name="createIfNotExist"></param> /// <param name="container"></param> /// <param name="comparer"></param> /// <param name="name"></param> /// <param name="isDataInKeySegment"> </param> /// <param name="mruManaged"> </param> /// <returns></returns> public ISortedDictionary <TKey, TValue> GetPersistentKey <TKey, TValue>(object container, string name, System.Collections.Generic.IComparer <TKey> comparer = null, bool createIfNotExist = true, bool isDataInKeySegment = true, bool mruManaged = true) where TKey : IPersistent, new() { if (!CollectionOnDisk.IsSimpleType(typeof(TValue))) { throw new ArgumentException(string.Format("Type of TValue ({0}) isn't an SOP simple type.", typeof(TValue))); } BTreeAlgorithm.CurrentOnValueUnpack = PersistentTypeKeySimpleValue <TKey, TValue> .Collection_OnKeyUnpack; var r2 = CreateDictionary <PersistentTypeKeySimpleValue <TKey, TValue>, TKey, TValue>(createIfNotExist, container, name, containerDod => { var r = new PersistentTypeKeySimpleValue <TKey, TValue >( container, comparer, name, DataStoreType . SopOndisk, null, isDataInKeySegment); containerDod. SetCurrentValueInMemoryData (r); return(r); }, mruManaged); return(r2); }
protected internal override void RegisterRemove(CollectionOnDisk collection, long blockAddress, int blockSize) { if (IsTransactionStore(collection)) { ((TransactionBase)collection.ParentTransactionLogger).RegisterRemove(collection, blockAddress, blockSize); return; } if (LogCollection == null) { return; } if (_inCommit == 0) { TrackModification(collection.GetTopParent()); } // object o = 90; // todo: remove return when ready... return; // Check if Block is in Growth, RecycledCollection, Add, Recycled blocks segments... RecordKey key = CreateKey(collection, blockAddress); if (RegionLogic.IsSegmentInStore(_fileGrowthStore, key, blockSize) || RegionLogic.IsSegmentInStore(_recycledSegmentsStore, key, blockSize) || RegionLogic.IsSegmentInStore(_addBlocksStore, key, blockSize)) { return; } // check if block is in updated blocks... if (IsInUpdatedBlocks(collection, blockAddress, blockSize)) { return; } AddMerge(_recycledBlocksStore, key, blockSize); if (_inCommit == 0) { TrackModification(collection.GetTopParent()); } }
private void RemoveInMemory(CollectionOnDisk coll, long address) { bool reload = false; CollectionOnDisk p = coll; while (p != null) { if (p.RemoveInMemory(address, this) && !reload) { reload = true; } if (p.Parent is CollectionOnDisk) { p = (CollectionOnDisk)p.Parent; } else { return; } } }
private void BackupData(CollectionOnDisk collection, long blockAddress, int segmentSize) { if (_loggerTransDetailsFileStream == null) { int bufferSize; //** open with 1 MB custom buffering string s = _loggerTransDetailsLogFilename; if (Server != null) { s = Server.NormalizePath(s); } _loggerTransDetailsFileStream = File.UnbufferedOpen(s, out bufferSize).RealStream; _loggerTransDetailsBuffer = new byte[bufferSize]; } long sourceOffset = collection.FileStream.Position; collection.FileStream.Seek(blockAddress, System.IO.SeekOrigin.Begin); //** copy asynchronously from source to target log file IAsyncResult iar = collection.FileStream.BeginRead(_loggerTransDetailsBuffer, 0, segmentSize, null, null); if (!iar.IsCompleted) { iar.AsyncWaitHandle.WaitOne(); } collection.FileStream.EndRead(iar); _loggerTransDetailsFileStream.Seek(0, System.IO.SeekOrigin.Begin); iar = _loggerTransDetailsFileStream.BeginWrite(_loggerTransDetailsBuffer, 0, segmentSize, null, null); if (!iar.IsCompleted) { iar.AsyncWaitHandle.WaitOne(); } _loggerTransDetailsFileStream.EndWrite(iar); _loggerTransDetailsFileStream.Flush(); if (_loggerTransDetailsFileStream.Length > segmentSize) { _loggerTransDetailsFileStream.SetLength(segmentSize); } collection.FileStream.Seek(sourceOffset, System.IO.SeekOrigin.Begin); }
/// <summary> /// Unpack this item for DeSerialization from Stream /// </summary> /// <param name="parent"></param> /// <param name="reader"></param> public virtual void Unpack(IInternalPersistent parent, System.IO.BinaryReader reader) { bool?r = CollectionOnDisk.ReadPersistentData(parent, reader, ref Key); if (r == null) { if (((BTreeAlgorithm)parent).onKeyUnpack != null) { Key = ((BTreeAlgorithm)parent).onKeyUnpack(reader); } else { throw new SopException("Can't Deserialize Custom persisted 'Key'."); } } if (Value == null) { var f = (File.File)InternalPersistent.GetParent(parent, typeof(File.File)); Value = new ItemOnDisk(f.DataBlockSize); } bool valueIsReference = reader.ReadBoolean(); if (valueIsReference) { Value.DiskBuffer.DataAddress = reader.ReadInt64(); } else { object o = Value; CollectionOnDisk.ReadPersistentData(parent, reader, ref o); Value = (ItemOnDisk)o; if (Value.DataIsUserDefined && ((BTreeAlgorithm)parent).onValueUnpack != null) { Value.Data = ((BTreeAlgorithm)parent).onValueUnpack(reader); } } IsDirty = false; }
/// <summary> /// Commit a transaction /// </summary> /// <param name="phase"> /// FirstPhase will make changes permanent but keep transaction log so rollback /// is still possible. /// /// SecondPhase will: /// 1. call FirstPhase commit if this transaction is in UnCommitted phase /// 2. clear the transaction log to complete Commit /// NOTE: Rollback is no longer allowed after completion of SecondPhase /// </param> ///<returns>true if successful otherwise false</returns> public override bool InternalCommit(CommitPhase phase) { if (CurrentCommitPhase == CommitPhase.Committed) { throw new InvalidOperationException(string.Format("Transaction '{0}' is already committed.", Id)); } _inCommit++; try { switch (phase) { case CommitPhase.FirstPhase: if (CurrentCommitPhase == CommitPhase.UnCommitted) { RollbackConflicts(); //** save all cached data of each collection var parents = new Dictionary <CollectionOnDisk, object>(ModifiedCollections.Count); var closeColls = new List <RecordKey>(); foreach (KeyValuePair <RecordKey, CollectionOnDisk> kvp in ModifiedCollections) { CollectionOnDisk collection = kvp.Value; CollectionOnDisk ct = collection.GetTopParent(); if (ct.IsOpen) { parents[ct] = null; } else { closeColls.Add(kvp.Key); } } foreach (CollectionOnDisk collection in parents.Keys) { if (!collection.IsOpen) { continue; } collection.Flush(); collection.OnCommit(); } foreach (RecordKey k in closeColls) { ModifiedCollections.Remove(k); } //File.DeletedCollections.Flush(); CurrentCommitPhase = CommitPhase.FirstPhase; //** don't clear transaction log so rollback is still possible return(true); } break; case CommitPhase.SecondPhase: if (CurrentCommitPhase == CommitPhase.UnCommitted) { if (!Commit(CommitPhase.FirstPhase)) { break; } } if (CurrentCommitPhase == CommitPhase.FirstPhase) { //** mark second phase completed as when it starts, no turning back... CurrentCommitPhase = CommitPhase.SecondPhase; //** preserve the recycled segment so on rollback it can be restored... foreach (CollectionOnDisk collection in ModifiedCollections.Values) { if (!collection.IsOpen) { continue; } collection.HeaderData.RecycledSegmentBeforeTransaction = collection.HeaderData.RecycledSegment; if (collection.HeaderData.RecycledSegmentBeforeTransaction != null) { collection.HeaderData.RecycledSegmentBeforeTransaction = (DeletedBlockInfo) collection.HeaderData.RecycledSegmentBeforeTransaction.Clone(); } } //** delete new (AddStore), updated (LogCollection) and //** file growth segments (FileGrowthStore) "log entries" ClearStores(true); //** todo: Record on Trans Log the FileSet Remove action + info needed for //** commit resume "on crash and restart" 11/9/08 File.Delete(Server.Path + DataBackupFilename); //** todo: remove from trans Log the FileSet Remove action... 11/09/08 return(true); } break; } //** auto roll back this transaction if commit failed above if (CurrentCommitPhase != CommitPhase.Rolledback && CurrentCommitPhase != CommitPhase.SecondPhase) { Rollback(); } return(false); } finally { _inCommit--; if (Parent == null) { CollectionOnDisk.transaction = null; } else { Parent.Children.Remove(this); } } }
/// <summary> /// Create Instance /// </summary> /// <param name="transaction"> </param> /// <param name="typeId"></param> /// <param name="parameters"></param> /// <returns></returns> public object CreateInstance(Transaction.ITransactionLogger transaction, byte typeId, params KeyValuePair <string, object>[] parameters) { if (typeId >= (byte)BuiltinTypes.MinType && typeId <= (byte)BuiltinTypes.MaxType) { File.File f; switch ((BuiltinTypes)typeId) { case BuiltinTypes.SortedDictionaryOnDisk: f = (File.File)CollectionOnDisk.GetParamValue(parameters, "File"); if (f != null) { if (transaction is Sop.Transaction.TransactionBase) { return(((Sop.Transaction.TransactionBase)transaction).CreateCollection(f)); } else { return(new SortedDictionaryOnDisk(f)); } } return(transaction is Sop.Transaction.TransactionBase ? ((Sop.Transaction.TransactionBase)transaction).CreateCollection(f) : new SortedDictionaryOnDisk()); case BuiltinTypes.SharedBlockOnDiskList: f = (File.File)CollectionOnDisk.GetParamValue(parameters, "File"); if (f != null) { return(new SharedBlockOnDiskList(f)); } return(new SharedBlockOnDiskList()); case BuiltinTypes.BTreeAlgorithm: return(new BTreeAlgorithm()); case BuiltinTypes.File: return(transaction is Sop.Transaction.TransactionBase ? ((Sop.Transaction.TransactionBase)transaction).CreateFile() : new File.File()); case BuiltinTypes.FileSet: return(transaction is Sop.Transaction.TransactionBase ? ((Sop.Transaction.TransactionBase)transaction).CreateFileSet() : new FileSet()); case BuiltinTypes.LinkedListOnDisk: return(new LinkedListOnDisk()); case BuiltinTypes.LinkedListOnDiskItemOnDisk: return(new LinkedListOnDisk.LinkedItemOnDisk()); case BuiltinTypes.BTreeOnDiskTreeNode: return(new BTreeNodeOnDisk()); case BuiltinTypes.BTreeItemOnDisk: return(new ItemOnDisk()); case BuiltinTypes.DeletedBlockInfo: return(new DeletedBlockInfo()); case BuiltinTypes.DataReference: return(new DataReference()); case BuiltinTypes.BackupDataLogKey: return(new Transaction.Transaction.BackupDataLogKey()); case BuiltinTypes.BackupDataLogValue: return(new Transaction.Transaction.BackupDataLogValue()); case BuiltinTypes.UserDefined: return(null); default: throw new ArgumentOutOfRangeException("typeId", typeId, "Not supported Type ID."); } } //** TypeID should be a User type... throw new InvalidOperationException( string.Format("Built-in TypeStore doesn't support this Type ID '{0}'.", typeId) ); }
protected internal virtual void TrackModification(CollectionOnDisk collection, bool untrack = false) { }
protected internal abstract void RegisterRecycleCollection(CollectionOnDisk collection, long blockAddress, int blockSize);