public AggregateCopyOperationsDecorator(IDeltaWriter decorated)
 {
     this.decorated = decorated;
 }
Ejemplo n.º 2
0
        public void BuildDelta(Stream newFileStream, ISignatureReader signatureReader, IDeltaWriter deltaWriter)
        {
            var signature = signatureReader.ReadSignature();
            var chunks = signature.Chunks;

            var hash = signature.HashAlgorithm.ComputeHash(newFileStream);
            newFileStream.Seek(0, SeekOrigin.Begin);

            deltaWriter.WriteMetadata(signature.HashAlgorithm, hash);

            chunks = OrderChunksByChecksum(chunks);

            int minChunkSize;
            int maxChunkSize;
            var chunkMap = CreateChunkMap(chunks, out maxChunkSize, out minChunkSize);

            var buffer = new byte[ReadBufferSize];
            long lastMatchPosition = 0;

            var fileSize = newFileStream.Length;
            ProgressReporter.ReportProgress("Building delta", 0, fileSize);

            while (true)
            {
                var startPosition = newFileStream.Position;
                var read = newFileStream.Read(buffer, 0, buffer.Length);
                if (read < 0)
                    break;

                var checksumAlgorithm = signature.RollingChecksumAlgorithm;
                uint checksum = 0;

                var remainingPossibleChunkSize = maxChunkSize;

                for (var i = 0; i < read - minChunkSize + 1; i++)
                {
                    var readSoFar = startPosition + i;

                    var remainingBytes = read - i;
                    if (remainingBytes < maxChunkSize)
                    {
                        remainingPossibleChunkSize = minChunkSize;
                    }

                    if (i == 0 || remainingBytes < maxChunkSize)
                    {
                        checksum = checksumAlgorithm.Calculate(buffer, i, remainingPossibleChunkSize);
                    }
                    else
                    {
                        var remove = buffer[i- 1];
                        var add = buffer[i + remainingPossibleChunkSize - 1];
                        checksum = checksumAlgorithm.Rotate(checksum, remove, add, remainingPossibleChunkSize);
                    }

                    ProgressReporter.ReportProgress("Building delta", readSoFar, fileSize);

                    if (readSoFar - (lastMatchPosition - remainingPossibleChunkSize) < remainingPossibleChunkSize)
                        continue;

                    if (!chunkMap.ContainsKey(checksum)) 
                        continue;

                    var startIndex = chunkMap[checksum];

                    for (var j = startIndex; j < chunks.Count && chunks[j].RollingChecksum == checksum; j++)
                    {
                        var chunk = chunks[j];

                        var sha = signature.HashAlgorithm.ComputeHash(buffer, i, remainingPossibleChunkSize);

                        if (StructuralComparisons.StructuralEqualityComparer.Equals(sha, chunks[j].Hash))
                        {
                            readSoFar = readSoFar + remainingPossibleChunkSize;

                            var missing = readSoFar - lastMatchPosition;
                            if (missing > remainingPossibleChunkSize)
                            {
                                deltaWriter.WriteDataCommand(newFileStream, lastMatchPosition, missing - remainingPossibleChunkSize);
                            }

                            deltaWriter.WriteCopyCommand(new DataRange(chunk.StartOffset, chunk.Length));
                            lastMatchPosition = readSoFar;
                            break;
                        }
                    }
                }

                if (read < buffer.Length)
                {
                    break;
                }

                newFileStream.Position = newFileStream.Position - maxChunkSize + 1;
            }

            if (newFileStream.Length != lastMatchPosition)
            {
                deltaWriter.WriteDataCommand(newFileStream, lastMatchPosition, newFileStream.Length - lastMatchPosition);
            }

            deltaWriter.Finish();
        }
 public AggregateCopyOperationsDecorator(IDeltaWriter decorated)
 {
     this.decorated = decorated;
 }
Ejemplo n.º 4
0
        public void BuildDelta(Stream newFileStream, ISignatureReader signatureReader, IDeltaWriter deltaWriter)
        {
            var signature = signatureReader.ReadSignature();
            var chunks    = signature.Chunks;

            var hash = signature.HashAlgorithm.ComputeHash(newFileStream);

            newFileStream.Seek(0, SeekOrigin.Begin);

            deltaWriter.WriteMetadata(signature.HashAlgorithm, hash);

            chunks = OrderChunksByChecksum(chunks);

            int minChunkSize;
            int maxChunkSize;
            var chunkMap = CreateChunkMap(chunks, out maxChunkSize, out minChunkSize);

            var  buffer            = new byte[ReadBufferSize];
            long lastMatchPosition = 0;

            var fileSize = newFileStream.Length;

            ProgressReporter.ReportProgress("Building delta", 0, fileSize);

            while (true)
            {
                var startPosition = newFileStream.Position;
                var read          = newFileStream.Read(buffer, 0, buffer.Length);
                if (read < 0)
                {
                    break;
                }

                var  checksumAlgorithm = signature.RollingChecksumAlgorithm;
                uint checksum          = 0;

                var remainingPossibleChunkSize = maxChunkSize;

                for (var i = 0; i < read - minChunkSize + 1; i++)
                {
                    var readSoFar = startPosition + i;

                    var remainingBytes = read - i;
                    if (remainingBytes < maxChunkSize)
                    {
                        remainingPossibleChunkSize = minChunkSize;
                    }

                    if (i == 0 || remainingBytes < maxChunkSize)
                    {
                        checksum = checksumAlgorithm.Calculate(buffer, i, remainingPossibleChunkSize);
                    }
                    else
                    {
                        var remove = buffer[i - 1];
                        var add    = buffer[i + remainingPossibleChunkSize - 1];
                        checksum = checksumAlgorithm.Rotate(checksum, remove, add, remainingPossibleChunkSize);
                    }

                    ProgressReporter.ReportProgress("Building delta", readSoFar, fileSize);

                    if (readSoFar - (lastMatchPosition - remainingPossibleChunkSize) < remainingPossibleChunkSize)
                    {
                        continue;
                    }

                    if (!chunkMap.ContainsKey(checksum))
                    {
                        continue;
                    }

                    var startIndex = chunkMap[checksum];

                    for (var j = startIndex; j < chunks.Count && chunks[j].RollingChecksum == checksum; j++)
                    {
                        var chunk = chunks[j];

                        var sha = signature.HashAlgorithm.ComputeHash(buffer, i, remainingPossibleChunkSize);

                        if (StructuralComparisons.StructuralEqualityComparer.Equals(sha, chunks[j].Hash))
                        {
                            readSoFar = readSoFar + remainingPossibleChunkSize;

                            var missing = readSoFar - lastMatchPosition;
                            if (missing > remainingPossibleChunkSize)
                            {
                                deltaWriter.WriteDataCommand(newFileStream, lastMatchPosition, missing - remainingPossibleChunkSize);
                            }

                            deltaWriter.WriteCopyCommand(new DataRange(chunk.StartOffset, chunk.Length));
                            lastMatchPosition = readSoFar;
                            break;
                        }
                    }
                }

                if (read < buffer.Length)
                {
                    break;
                }

                newFileStream.Position = newFileStream.Position - maxChunkSize + 1;
            }

            if (newFileStream.Length != lastMatchPosition)
            {
                deltaWriter.WriteDataCommand(newFileStream, lastMatchPosition, newFileStream.Length - lastMatchPosition);
            }

            deltaWriter.Finish();
        }
Ejemplo n.º 5
0
        public void BuildDelta(Stream newFileStream, ISignatureReader signatureReader, IDeltaWriter deltaWriter)
        {
            var newFileVerificationHashAlgorithm = SupportedAlgorithms.Hashing.Md5();

            newFileStream.Seek(0, SeekOrigin.Begin);
            var newFileHash = newFileVerificationHashAlgorithm.ComputeHash(newFileStream);

            newFileStream.Seek(0, SeekOrigin.Begin);

            var signature = signatureReader.ReadSignature();
            var chunks    = OrderChunksByChecksum(signature.Chunks);
            var chunkMap  = CreateChunkMap(chunks, out int maxChunkSize, out int minChunkSize);

            deltaWriter.WriteMetadata(new DeltaMetadata {
                HashAlgorithm             = signature.HashAlgorithm.Name,
                ExpectedFileHashAlgorithm = newFileVerificationHashAlgorithm.Name,
                ExpectedFileHash          = Convert.ToBase64String(newFileHash),
                BaseFileHash          = signature.Metadata.BaseFileHash,
                BaseFileHashAlgorithm = signature.Metadata.BaseFileHashAlgorithm
            });

            var checksumAlgorithm = signature.RollingChecksumAlgorithm;

            var  buffer            = new byte[readBufferSize];
            long lastMatchPosition = 0;

            var fileSize = newFileStream.Length;

            ProgressReport?.Report(new ProgressReport {
                Operation       = ProgressOperationType.BuildingDelta,
                CurrentPosition = 0,
                Total           = fileSize
            });

            while (true)
            {
                var startPosition = newFileStream.Position;
                var read          = newFileStream.Read(buffer, 0, buffer.Length);
                if (read < 0)
                {
                    break;
                }

                uint checksum = 0;
                long progressIterationCount = 0;

                var remainingPossibleChunkSize = maxChunkSize;

                for (var i = 0; i < read - minChunkSize + 1; i++)
                {
                    var readSoFar = startPosition + i;

                    var remainingBytes = read - i;
                    if (remainingBytes < maxChunkSize)
                    {
                        remainingPossibleChunkSize = minChunkSize;
                    }

                    if (i == 0 || remainingBytes < maxChunkSize)
                    {
                        checksum = checksumAlgorithm.Calculate(buffer, i, remainingPossibleChunkSize);
                    }
                    else
                    {
                        var remove = buffer[i - 1];
                        var add    = buffer[i + remainingPossibleChunkSize - 1];
                        checksum = checksumAlgorithm.Rotate(checksum, remove, add, remainingPossibleChunkSize);
                    }

                    progressIterationCount += 1;
                    if (ProgressReportEvery == -1 || ProgressReportEvery <= progressIterationCount)
                    {
                        ProgressReport?.Report(new ProgressReport {
                            Operation       = ProgressOperationType.BuildingDelta,
                            CurrentPosition = readSoFar,
                            Total           = fileSize
                        });
                        progressIterationCount = 0;
                    }


                    if (readSoFar - (lastMatchPosition - remainingPossibleChunkSize) < remainingPossibleChunkSize)
                    {
                        continue;
                    }

                    if (!chunkMap.ContainsKey(checksum))
                    {
                        continue;
                    }

                    var startIndex = chunkMap[checksum];

                    for (var j = startIndex; j < chunks.Count && chunks[j].RollingChecksum == checksum; j++)
                    {
                        var chunk = chunks[j];
                        var hash  = signature.HashAlgorithm.ComputeHash(buffer, i, remainingPossibleChunkSize);

                        if (StructuralComparisons.StructuralEqualityComparer.Equals(hash, chunks[j].Hash))
                        {
                            readSoFar = readSoFar + remainingPossibleChunkSize;

                            var missing = readSoFar - lastMatchPosition;
                            if (missing > remainingPossibleChunkSize)
                            {
                                deltaWriter.WriteDataCommand(newFileStream, lastMatchPosition, missing - remainingPossibleChunkSize);
                            }

                            deltaWriter.WriteCopyCommand(new DataRange(chunk.StartOffset, chunk.Length));
                            lastMatchPosition = readSoFar;
                            break;
                        }
                    }
                }

                if (read < buffer.Length)
                {
                    break;
                }

                newFileStream.Position = newFileStream.Position - maxChunkSize + 1;
            }

            if (newFileStream.Length != lastMatchPosition)
            {
                deltaWriter.WriteDataCommand(newFileStream, lastMatchPosition, newFileStream.Length - lastMatchPosition);
            }

            deltaWriter.Finish();
        }