Esempio n. 1
0
        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);
        }
Esempio n. 2
0
        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);
        }