Пример #1
0
        public void FinalizeBackupAddition(BackupSetReference bsname, byte[] backuphash, byte[] mtreehash, HashTreeNode mtreereferences)
        {
            BlobLocation backupblocation = GetBlobLocation(backuphash);
            int?         backupRefCount  = backupblocation.GetBSetReferenceCount(bsname);

            if (!backupRefCount.HasValue || backupRefCount == 0)
            {
                BlobLocation mtreeblocation = GetBlobLocation(mtreehash);
                int?         mtreeRefCount  = mtreeblocation.GetBSetReferenceCount(bsname);
                if (!mtreeRefCount.HasValue || mtreeRefCount == 0)
                {
                    ISkippableChildrenIterator <byte[]> childReferences = mtreereferences.GetChildIterator();
                    foreach (var blobhash in childReferences)
                    {
                        BlobLocation blocation = GetBlobLocation(blobhash);
                        int?         refCount  = blocation.GetBSetReferenceCount(bsname);
                        if (refCount.HasValue && refCount > 0) // This was already stored
                        {
                            childReferences.SkipChildrenOfCurrent();
                        }
                        else if (blocation.BlockHashes != null)
                        {
                            foreach (var mbref in blocation.BlockHashes)
                            {
                                IncrementReferenceCountNoRecurse(bsname, mbref, 1);
                            }
                        }
                        IncrementReferenceCountNoRecurse(bsname, blocation, blobhash, 1);
                    }

                    IncrementReferenceCountNoRecurse(bsname, mtreeblocation, mtreehash, 1);
                }
                IncrementReferenceCountNoRecurse(bsname, backupblocation, backuphash, 1);
            }
        }
Пример #2
0
        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()
        }
Пример #3
0
        private void IncrementReferenceCountNoRecurse(BackupSetReference backupset, BlobLocation blocation, byte[] blobhash, int amount)
        {
            bool originallyshallow = blocation.TotalNonShallowReferenceCount == 0;
            int? refCount          = blocation.GetBSetReferenceCount(backupset);
            int  newRefCount       = refCount.GetValueOrDefault(0) + amount;

            blocation.SetBSetReferenceCount(backupset, newRefCount);
            if (newRefCount == 0)
            {
                blocation.RemoveBSetReference(backupset);
            }
            else if (newRefCount < 0)
            {
                throw new Exception("Negative reference count in blobstore");
            }
            if (blocation.BlockHashes == null) // Can't delete from disk if this is a multiblock reference (does not directly store data on disk)
            {
                if (blocation.TotalNonShallowReferenceCount == 0)
                {
                    if (!originallyshallow)
                    {
                        try
                        {
                            if (blocation.EncryptedHash == null)
                            {
                                throw new Exception("Hash should not be null");
                            }
                            Dependencies.DeleteBlob(blocation.EncryptedHash, blocation.RelativeFilePath);
                        }
                        catch (Exception e)
                        {
                            throw new Exception("Error deleting unreferenced file.", e);
                        }
                    }
                }
            }
            if (blocation.TotalReferenceCount == 0)
            {
                IndexStore.Remove(blobhash);
            }
        }