/// <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()); } }
/// <summary> /// Check whether a block is a newly added block or is in new segment or recycle store. /// </summary> /// <param name="addStore"></param> /// <param name="fileGrowthStore"></param> /// <param name="recycledCollectionStore"></param> /// <param name="key"></param> /// <param name="blockSize"></param> /// <param name="checkIfInGrowthSegments"></param> /// <returns>true if block is either new, in new segment or in recycle store, false otherwise</returns> internal static void RegisterAdd( Collections.Generic.ISortedDictionary <RecordKey, long> addStore, Collections.Generic.ISortedDictionary <RecordKey, long> fileGrowthStore, Collections.Generic.ISortedDictionary <RecordKey, long> recycledCollectionStore, RecordKey key, int blockSize, bool checkIfInGrowthSegments) { //** Check if Block is in Growth Segments if (checkIfInGrowthSegments && (RegionLogic.IsSegmentInStore(fileGrowthStore, key, blockSize) || RegionLogic.IsSegmentInStore(recycledCollectionStore, key, blockSize))) { return; } //** Add Block to AddStore for use on Rollback... if (!addStore.ContainsKey(key)) { short passCount = 0; //** Detect and merge contiguous blocks if (!addStore.MovePrevious()) { addStore.MoveFirst(); } while (!addStore.EndOfTree()) { var de = addStore.CurrentEntry; RecordKey k2 = de.Value.Key; long i = de.Value.Value; if (k2.ServerSystemFilename == key.ServerSystemFilename && k2.Filename == key.Filename && k2.CollectionName == key.CollectionName) { if (key.Address + blockSize == k2.Address) { long newSize = i + blockSize; addStore.Remove(de.Value.Key); k2.Address = key.Address; addStore.Add(k2, newSize); return; } if (k2.Address + i == key.Address) { addStore.CurrentValue = i + blockSize; return; } if (key.Address >= k2.Address && key.Address + blockSize <= k2.Address + i) { //** if block is inclusive, don't do anything... return; } } else if (++passCount >= 2) { break; } addStore.MoveNext(); } addStore.Add(key, blockSize); } }
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()); } }
/// <summary> /// Check whether a block is: /// - a newly added block /// - in new segment /// - in recycled store /// - in updated blocks /// </summary> /// <param name="addStore"></param> /// <param name="fileGrowthStore"></param> /// <param name="recycledCollectionStore"></param> /// <param name="key"></param> /// <param name="blockSize"></param> /// <param name="checkIfInGrowthSegments"></param> /// <returns>true if block is either new, in new segment or in recycle store, false otherwise</returns> internal static void RegisterAdd( Collections.Generic.ISortedDictionary <RecordKey, long> addStore, Collections.Generic.ISortedDictionary <RecordKey, long> fileGrowthStore, Collections.Generic.ISortedDictionary <RecordKey, long> recycledCollectionStore, RecordKey key, int blockSize, bool checkIfInGrowthSegments) { /* todo: complete the story for: RegisterAdd, ...Save, ...Remove, ...Recycle, ...FileGrowth * Logic table: * Add Save (Update)/Remove Recycle FileGrowth * - FileGrowth blocks can be deleted, then re-allocated for Add * - Block can be allocated for Add, Deleted(will create Updated blocks) if item is deleted, then re-Allocated for Add.*/ // Check if Block is in Growth, RecycledCollection, Recycled blocks segments... if (checkIfInGrowthSegments) { if (RegionLogic.IsSegmentInStore(fileGrowthStore, key, blockSize) || RegionLogic.IsSegmentInStore(recycledCollectionStore, key, blockSize)) { return; } } AddMerge(addStore, key, blockSize); }