internal static bool GetIntersectingLogs(BackupDataLogKey logKey, int logKeySize, out IEnumerable <KeyValuePair <BackupDataLogKey, BackupDataLogValue> > target, out long startMergedBlockAddress, out long mergedBlockSize) { target = null; startMergedBlockAddress = mergedBlockSize = 0; var l = new List <KeyValuePair <BackupDataLogKey, BackupDataLogValue> >(); if (!LogCollection.Search(logKey)) { if (!LogCollection.MovePrevious()) { if (!LogCollection.MoveFirst()) { return(false); } } } long address1 = logKey.SourceDataAddress; int size1 = logKeySize; startMergedBlockAddress = address1; mergedBlockSize = size1; bool intersected = false; for (int i = 0; i < 3; i++) { var key = LogCollection.CurrentKey; var value = LogCollection.CurrentValue; if (logKey.SourceFilename == key.SourceFilename) { long address2 = key.SourceDataAddress; int size2 = value.DataSize; if (RegionLogic.FirstWithinSecond(address1, size1, address2, size2)) { return(true); } if (RegionLogic.Intersect(address1, size1, address2, size2)) { l.Add(new KeyValuePair <BackupDataLogKey, BackupDataLogValue>(key, value)); i = 0; intersected = true; if (address2 < startMergedBlockAddress) { startMergedBlockAddress = address2; } if (startMergedBlockAddress + mergedBlockSize < address2 + size2) { long l2 = address2 + size2 - startMergedBlockAddress; if (l2 >= int.MaxValue) { break; } mergedBlockSize = l2; } } else if (intersected) { break; } } else { break; } if (!LogCollection.MoveNext()) { break; } } if (l.Count > 0) { target = l; return(true); } return(false); }
internal static bool DetectAndMerge(Collections.Generic.ISortedDictionary <long, long> store, long dataAddress, long dataSize, int segmentSize = DataBlock.DataBlockDriver.MaxSegmentSize, RegionLogic region = null) { if (store.Count == 0) { if (dataSize > segmentSize) { return(false); } store.Add(dataAddress, dataSize); return(true); } if (store.Search(dataAddress)) { long currSize = store.CurrentValue; if (currSize < dataSize) { store.CurrentValue = dataSize; } return(true); } //** Detect and merge contiguous deleted blocks short passCount = 0; if (!store.MovePrevious()) { store.MoveFirst(); } while (true) { KeyValuePair <long, long>?item = store.CurrentEntry; long k2 = item.Value.Key; long i = 0; long cv = store.CurrentValue; i = cv; if (region != null) { if (region.Equals(dataAddress, dataSize, k2, i) || region.FirstWithinSecond(dataAddress, dataSize, k2, i)) { return(true); } if (region.FirstWithinSecond(k2, i, dataAddress, dataSize)) { store.Remove(k2); store.Add(dataAddress, dataSize); return(true); } } if (dataAddress + dataSize == k2) { long newSize = i + dataSize; if (newSize <= segmentSize) { store.Remove(item.Value.Key); store.Add(dataAddress, newSize); return(true); } return(false); } if (k2 + i == dataAddress) { if (i + dataSize <= segmentSize) { store.CurrentValue = i + dataSize; return(true); } return(false); } if (++passCount >= 2) { break; } if (!store.MoveNext()) { break; } } return(false); }