Exemplo n.º 1
0
        // Uploads differences between existing blob and updated local file.
        // Have local file to reference, the search results (indicating which parts need to be uploaded)
        // container and blob name.
        private List<UploadedBlock> UploadDelta(string localFilePath, SignatureSearchResult searchResults, string containerName, string blobName, bool testMode = false, int parallelFactor=2)
        {
            var allUploadedBlocks = new List<UploadedBlock>();

            // loop through each section of the search results.
            // create blob from each RemainingBytes instances.
            // reuse the blocks already in use.
            foreach (var remainingBytes in searchResults.ByteRangesToUpload)
            {
                var uploadedBlockList = UploadBytesParallel(remainingBytes, localFilePath, containerName, blobName, testMode, parallelFactor);
                allUploadedBlocks.AddRange(uploadedBlockList);
            }

            // once we're here we should have uploaded ALL new data to Azure Blob Storage.
            // We then need to send the "construct" blob message.
            // loop through existing blocks and get offset + blockId's.
            foreach (var sig in searchResults.SignaturesToReuse)
            {
                if (sig.MD5Signature != null)
                {
                    var blockId = Convert.ToBase64String(sig.MD5Signature);
                    allUploadedBlocks.Add(new UploadedBlock() { BlockId = blockId, Offset = sig.Offset, Size = sig.Size, Sig = sig, IsNew = false });
                }
            }

            if (!testMode)
            {
                // needs to be sorted by offset so the final blob constructed is in correct order.
                var res = (from b in allUploadedBlocks orderby b.Offset ascending select b.BlockId);
                PutBlockList(res.ToArray(), containerName, blobName);
            }

            return allUploadedBlocks;
        }
Exemplo n.º 2
0
        public static SignatureSearchResult SearchLocalFileForSignatures(string localFilePath, SizeBasedCompleteSignature sig)
        {
            var result = new SignatureSearchResult();

            // length of file.
            var tempFile = File.Open(localFilePath, FileMode.Open);
            var fileLength = tempFile.Length;

            tempFile.Close();

            var offset = 0;
            var windowSize = ConfigHelper.SignatureSize;
            var windowBuffer = new byte[windowSize];

            // signatures we can reuse.
            var signaturesToReuse = new List<BlockSignature>();

            // get sizes of signatures (block sizes) from existing sig.
            // then loop through all sizes looking for matches in local file.
            // important to search from largest to smallest.
            var signatureSizes = sig.Signatures.Keys.ToList();
            signatureSizes.Sort();
            signatureSizes.Reverse();

            // byte ranges that have not been matched to existing blocks yet.
            var remainingByteList = new List<RemainingBytes>();
            remainingByteList.Add(new RemainingBytes {BeginOffset = 0, EndOffset = fileLength - 1});

            // Create the memory-mapped file.
            using (var mmf = MemoryMappedFile.CreateFromFile(localFilePath, FileMode.Open))
            {
                using (var accessor = mmf.CreateViewAccessor())
                {
                    // Any sigs smaller than 100 bytes? skip?
                    // Valid?
                    // Really want to avoid searching for single bytes everywhere.
                    foreach (var sigSize in signatureSizes)
                    {
                        var sigs = sig.Signatures[sigSize];
                        var newRemainingByteList = SearchLocalFileForSignaturesBasedOnSize(sigs, accessor, remainingByteList, sigSize, fileLength, signaturesToReuse);
                        remainingByteList = newRemainingByteList;
                    }
                }
            }

            result.ByteRangesToUpload = remainingByteList;
            result.SignaturesToReuse = signaturesToReuse;
            return result;
        }