/// <summary> /// Checks whether a certain area on disk (segment) /// is inclusive on any of segment entries of the store. /// </summary> /// <param name="fileGrowthStore"></param> /// <param name="key"></param> /// <param name="blockSize"></param> /// <returns></returns> public bool IsSegmentInStore( Collections.Generic.ISortedDictionary <Transaction.Transaction.RecordKey, long> fileGrowthStore, Transaction.Transaction.RecordKey key, int blockSize) { fileGrowthStore.Locker.Lock(); try { if (fileGrowthStore.ContainsKey(key)) { return(true); } KeyValuePair <Transaction.Transaction.RecordKey, long>?de; Transaction.Transaction.RecordKey k2; short passCount = 0; if (!fileGrowthStore.MovePrevious()) { fileGrowthStore.MoveFirst(); } while (!fileGrowthStore.EndOfTree()) { de = fileGrowthStore.CurrentEntry; if (de == null) { break; } k2 = de.Value.Key; if (k2.ServerSystemFilename == key.ServerSystemFilename && k2.Filename == key.Filename) { long i = (long)de.Value.Value; if (key.Address >= k2.Address && key.Address + blockSize <= k2.Address + i) { return(true); } } else if (++passCount >= 2) { break; } fileGrowthStore.MoveNext(); } return(false); } finally { fileGrowthStore.Locker.Unlock(); } }
//public Region RemoveIntersections(Collections.Generic.ISortedDictionary<Transaction.Transaction.RecordKey, long> addStore, // Transaction.Transaction.RecordKey key, Region region) //{ // Region target = new List<KeyValuePair<RecordKey, Region>>(); // foreach(var area in region) // { // } //} /// <summary> /// RemoveIntersections will check whether an area on disk was already /// inclusive in any of the segment areas stored as entries in a store (addStore). /// If input area is fully inclusive, this function returns null, otherwise /// it will return a region equivalent to the input area minus any intersecting /// area(s) of segment(s) in the store. /// </summary> /// <param name="addStore"></param> /// <param name="key"></param> /// <param name="blockAddress"></param> /// <param name="segmentSize"></param> /// <returns></returns> public Region RemoveIntersections( Collections.Generic.ISortedDictionary <Transaction.Transaction.RecordKey, long> addStore, Transaction.Transaction.RecordKey key, long blockAddress, int segmentSize) { addStore.Locker.Lock(); try { long size; if (addStore.TryGetValue(key, out size)) { if (size >= segmentSize) { return(null); } } else if (!addStore.MovePrevious()) { addStore.MoveFirst(); } //** Step 1 //** Starting from current block until block whose address is > BlockAddress + SegmentSize... //** long[0] = Address //** long[1] = Size var region = new Region(blockAddress, segmentSize); Transaction.Transaction.RecordKey k2; short passCount = 0; while (!addStore.EndOfTree()) { var de = addStore.CurrentEntry; k2 = de.Value.Key; if (k2.ServerSystemFilename == key.ServerSystemFilename && k2.Filename == key.Filename) // && k2.CollectionName == key.CollectionName) { size = de.Value.Value; if (k2.Address >= blockAddress + segmentSize) { break; } if (size > int.MaxValue) { throw new InvalidOperationException( string.Format( "Updated segment Size({0} reached > int.MaxValue which isn't supported in a transaction. Keep your transaction smaller by Committing more often", size)); } if (Intersect(k2.Address, (int)size, blockAddress, segmentSize)) { region.Subtract(k2.Address, (int)size); if (region.Count == 0) { return(null); } } else if (++passCount >= 2) { break; } } else if (++passCount >= 2) { break; } if (!addStore.MoveNext()) { break; } } return(region); } finally { addStore.Locker.Unlock(); } }