示例#1
0
 public BlobReferenceIterator(BlobStore blobs, byte[] blobhash, BlobLocation.BlobType blobtype,
                              bool includefiles, bool bottomup)
 {
     Blobs        = blobs;
     ParentHash   = blobhash;
     BottomUp     = bottomup;
     IncludeFiles = includefiles;
     BlobType     = blobtype;
 }
示例#2
0
        /// <summary>
        /// Calculates the size of the blobs and child blobs referenced by the given hash.
        /// </summary>
        /// <param name="blobhash"></param>
        /// <returns>(Size of all referenced blobs, size of blobs referenced only by the given hash and its children)</returns>
        public (int allreferences, int uniquereferences) GetSizes(byte[] blobhash, BlobLocation.BlobType blobtype)
        {
            Dictionary <string, (int frequency, BlobLocation blocation)> hashfreqsize = new Dictionary <string, (int, BlobLocation)>();

            GetBlobReferenceFrequencies(blobhash, blobtype, hashfreqsize);
            int allreferences    = 0;
            int uniquereferences = 0;

            foreach (var(frequency, blocation) in hashfreqsize.Values)
            {
                allreferences += blocation.ByteLength * frequency;
                if (blocation.TotalReferenceCount == frequency)
                {
                    uniquereferences += blocation.ByteLength; // TODO: unique referenes
                }
            }
            return(allreferences, uniquereferences);
        }
示例#3
0
        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);
        }
示例#4
0
        public void DecrementReferenceCount(string backupsetname, byte[] blobhash, BlobLocation.BlobType blobtype,
                                            bool includefiles)
        {
            BlobLocation rootBlobLocation = GetBlobLocation(blobhash);

            if (rootBlobLocation.BSetReferenceCounts[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));
                    if (rootBlobLocation.BSetReferenceCounts[backupsetname] != 1) // Not to be deleted?
                    {
                        // Dont need to decrement child references if this wont be deleted
                        blobReferences.SkipChildren();
                    }
                }
            }
            IncrementReferenceCountNoRecurse(backupsetname, rootBlobLocation, blobhash, -1); // must delete parent last so parent can be loaded/used in GetAllBlobReferences()
        }
示例#5
0
        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);
        }
示例#6
0
 public IBlobReferenceIterator GetAllBlobReferences(byte[] blobhash, BlobLocation.BlobType blobtype,
                                                    bool includefiles, bool bottomup = true)
 {
     return(new BlobReferenceIterator(this, blobhash, blobtype, includefiles, bottomup));
 }
示例#7
0
        // 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.
        }
示例#8
0
 private void GetBlobReferenceFrequencies(byte[] blobhash, BlobLocation.BlobType blobtype,
                                          Dictionary <string, (int frequency, BlobLocation blocation)> hashfreqsize)