public void TransferBlobAndReferences(BlobStore dst, string dstbackupset, byte[] blobhash, BlobLocation.BlobType blobtype, bool includefiles) { BlobLocation rootDstBlobLocation; try { rootDstBlobLocation = dst.GetBlobLocation(blobhash); } catch (KeyNotFoundException) { byte[] blob; (rootDstBlobLocation, blob) = TransferBlobNoReferences(dst, dstbackupset, blobhash, GetBlobLocation(blobhash)); IBlobReferenceIterator blobReferences = GetAllBlobReferences(blobhash, blobtype, includefiles, false); blobReferences.SupplyData(blob); foreach (var reference in blobReferences) { BlobLocation dstBlobLocation; try { dstBlobLocation = dst.GetBlobLocation(reference); // Dont need to increment child references if this already exists blobReferences.SkipChildren(); } catch (KeyNotFoundException) { (dstBlobLocation, blob) = TransferBlobNoReferences(dst, dstbackupset, reference, GetBlobLocation(reference)); blobReferences.SupplyData(blob); } // When we finish iterating over the children, increment this blob blobReferences.PostOrderAction(() => dst.IncrementReferenceCountNoRecurse(dstbackupset, dstBlobLocation, reference, 1)); } } dst.IncrementReferenceCountNoRecurse(dstbackupset, rootDstBlobLocation, blobhash, 1); }
// TODO: If include files is false, should we require dstbackupset.EndsWith(Core.ShallowSuffix)? public void TransferBlobAndReferences(BlobStore dst, BackupSetReference dstbackupset, byte[] blobhash, BlobLocation.BlobType blobtype, bool includefiles) { bool refInDst; bool shallowInDst; BlobLocation?rootDstBlobLocation = null; try { rootDstBlobLocation = dst.GetBlobLocation(blobhash); refInDst = true; shallowInDst = rootDstBlobLocation.TotalNonShallowReferenceCount == 0; } catch (KeyNotFoundException) { refInDst = false; shallowInDst = false; // Meaningless when ref not in dst } if (!refInDst || (shallowInDst && includefiles)) { byte[]? blob; if (refInDst) { blob = RetrieveData(blobhash); } else { (rootDstBlobLocation, blob) = TransferBlobNoReferences(dst, dstbackupset, blobhash, GetBlobLocation(blobhash)); } IBlobReferenceIterator blobReferences = GetAllBlobReferences(blobhash, blobtype, includefiles, false); blobReferences.SupplyData(blob); foreach (var reference in blobReferences) { bool iterRefInDst; bool iterShallowInDst; BlobLocation?dstBlobLocation = null; try { dstBlobLocation = dst.GetBlobLocation(reference); iterRefInDst = true; iterShallowInDst = dstBlobLocation.TotalNonShallowReferenceCount == 0; } catch (KeyNotFoundException) { iterRefInDst = false; iterShallowInDst = false; // Meaningless when ref not in dst } if (!iterRefInDst || (iterShallowInDst && includefiles)) { if (iterRefInDst) { blob = RetrieveData(reference); } else { (dstBlobLocation, blob) = TransferBlobNoReferences(dst, dstbackupset, reference, GetBlobLocation(reference)); } blobReferences.SupplyData(blob); } else { // Dont need to increment child references if this already exists blobReferences.SkipChildrenOfCurrent(); } //if (!iterRefInDst) // Don't increment child reference if already present? //{ // When we finish iterating over the children, increment this blob #pragma warning disable CS8604 // Possible null reference argument. blobReferences.PostOrderAction(() => dst.IncrementReferenceCountNoRecurse(dstbackupset, dstBlobLocation, reference, 1)); #pragma warning restore CS8604 // Possible null reference argument. //} } } #pragma warning disable CS8604 // Possible null reference argument. dst.IncrementReferenceCountNoRecurse(dstbackupset, rootDstBlobLocation, blobhash, 1); #pragma warning restore CS8604 // Possible null reference argument. }