public void DecrementReferenceCount(BackupSetReference backupsetname, byte[] blobhash, BlobLocation.BlobType blobtype, bool includefiles) { BlobLocation rootBlobLocation = GetBlobLocation(blobhash); if (rootBlobLocation.GetBSetReferenceCount(backupsetname) == 1) // To be deleted? { IBlobReferenceIterator blobReferences = GetAllBlobReferences(blobhash, blobtype, includefiles, false); foreach (var reference in blobReferences) { BlobLocation blocation = GetBlobLocation(reference); // When we finish iterating over the children, decrement this blob blobReferences.PostOrderAction(() => IncrementReferenceCountNoRecurse(backupsetname, blocation, reference, -1)); try { if (blocation.GetBSetReferenceCount(backupsetname) != 1) // Not to be deleted? { // Dont need to decrement child references if this wont be deleted blobReferences.SkipChildrenOfCurrent(); } } catch (KeyNotFoundException) { throw; } } } IncrementReferenceCountNoRecurse(backupsetname, rootBlobLocation, blobhash, -1); // must delete parent last so parent can be loaded/used in GetAllBlobReferences() }
public void FinalizeBlobAddition(BackupSetReference bsname, byte[] blobhash, BlobLocation.BlobType blobType) { // Handle root blob BlobLocation rootblocation = GetBlobLocation(blobhash); if (rootblocation.TotalReferenceCount == 0) { IBlobReferenceIterator blobReferences = GetAllBlobReferences(blobhash, blobType, true, false); // Loop through children foreach (byte[] reference in blobReferences) { BlobLocation blocation = GetBlobLocation(reference); if (blocation.TotalReferenceCount > 0) // This was already stored { blobReferences.SkipChildrenOfCurrent(); } IncrementReferenceCountNoRecurse(bsname, blocation, blobhash, 1); } } // Increment root blob IncrementReferenceCountNoRecurse(bsname, rootblocation, 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. }