예제 #1
0
        /// <summary>
        /// Loads a lagern index.
        /// </summary>
        /// <returns></returns>
        private (BlobStore blobs, BackupStore backups) LoadIndex()
        {
            BlobStoreDependencies   blobStoreDependencies = new BlobStoreDependencies(DstFSInterop);
            BlobStore               blobs = BlobStore.deserialize(DstFSInterop.LoadIndexFileAsync(null, IndexFileType.BlobIndex).Result, blobStoreDependencies);
            BackupStoreDependencies backupStoreDependencies = new BackupStoreDependencies(DstFSInterop, blobs);
            BackupStore             backups = new BackupStore(backupStoreDependencies);

            return(blobs, backups);
        }
예제 #2
0
        /// <summary>
        /// Syncs a cache with this backup store for the given bsname.
        /// Moves blobs only present in cache to the blobstore tied to this BackupStore
        /// Does not trigger a save of either cache or this backup set
        /// </summary>
        /// <param name="cache"></param>
        /// <param name="bsname"></param>
        /// <param name="dstbset"></param>
        /// <param name="cachebset"></param>
        public (BackupSet dstbset, BackupSet cachebset) SyncCache(BackupStore cache, string bsname, BackupSet?dstbset = null, BackupSet?cachebset = null)
        {
            int          cacheindex = 0;
            int          dstindex   = 0;
            BackupRecord?cachebr    = null;
            BackupRecord?dstbr      = null;

            BackupSetReference cachebsname = new(bsname, false, true, false);

            if (dstbset == null)
            {
                dstbset = LoadBackupSet(new BackupSetReference(bsname, false, false, false));
            }
            if (cachebset == null)
            {
                cachebset = cache.LoadBackupSet(new BackupSetReference(bsname, false, false, false));
            }
            if (cachebset.Backups.Count > 0 && dstbset.Backups.Count > 0)
            {
                while (cachebset.Backups.Count > cacheindex && dstbset.Backups.Count > dstindex)
                {
                    if (!cachebset.Backups[cacheindex].hash.SequenceEqual(dstbset.Backups[dstindex].hash))
                    {
                        if (cachebr == null)
                        {
                            cachebr = cache.GetBackupRecord(cachebsname, cachebset.Backups[cacheindex].hash);
                        }
                        if (dstbr == null)
                        {
                            dstbr = GetBackupRecord(new BackupSetReference(bsname, false, false, false), dstbset.Backups[dstindex].hash);
                        }
                        if (cachebr.BackupTime < dstbr.BackupTime)
                        {
                            if (cachebset.Backups[cacheindex].shallow)
                            {
                                // Remove shallow backups from cache not present in dst
                                cache.Dependencies.Blobs.DecrementReferenceCount(cachebsname, cachebset.Backups[cacheindex].hash,
                                                                                 BlobLocation.BlobType.BackupRecord, false);
                                cachebset.Backups.RemoveAt(cacheindex);
                            }
                            else
                            {
                                // Add non shallow backups from cache not present in dst
                                dstbset.Backups.Insert(dstindex, (cachebset.Backups[cacheindex].hash, false));
                                cache.Dependencies.Blobs.TransferBackup(Dependencies.Blobs, new BackupSetReference(bsname, false, false, false), cachebset.Backups[cacheindex].hash, true);

                                // After transfer, make the cache backup shallow
                                // Since no clean way to only get file references and not "parent" references,
                                // we delete the entire backup data from cache, then add it back shallow
                                // TODO: Means to iterate through blobs only including files
                                cache.Dependencies.Blobs.DecrementReferenceCount(cachebsname, cachebset.Backups[cacheindex].hash,
                                                                                 BlobLocation.BlobType.BackupRecord, true);
                                Dependencies.Blobs.TransferBackup(cache.Dependencies.Blobs, cachebsname, dstbset.Backups[dstindex].hash, false);
                                dstindex += 1;
                                // After insert and increment j still referes to the same backup (dstbr)
                                cacheindex += 1;
                            }
                            cachebr = null;
                        }
                        else // (srcbr.BackupTime > dstbr.BackupTime)
                        {
                            // Add (as shallow) backups in dst not present in cache
                            cachebset.Backups.Insert(cacheindex, (dstbset.Backups[dstindex].hash, true));
                            Dependencies.Blobs.TransferBackup(cache.Dependencies.Blobs, cachebsname, dstbset.Backups[dstindex].hash, false);
                            cacheindex += 1;
                            dstindex   += 1;
                            dstbr       = null;
                        }
                    }
                    else
                    {
                        cacheindex += 1;
                        cachebr     = null;
                        dstindex   += 1;
                        dstbr       = null;
                    }
                }
            }
            // Handle backups "dangling" after merge
            while (cacheindex < cachebset.Backups.Count)
            {
                if (cachebset.Backups[cacheindex].shallow)
                {
                    // Remove shallow backups from cache not present in dst
                    cache.Dependencies.Blobs.DecrementReferenceCount(cachebsname, cachebset.Backups[cacheindex].hash,
                                                                     BlobLocation.BlobType.BackupRecord, false);
                    cachebset.Backups.RemoveAt(cacheindex);
                }
                else
                {
                    // Add non shallow backups from cache not present in dst
                    dstbset.Backups.Add((cachebset.Backups[cacheindex].hash, false));
                    cache.Dependencies.Blobs.TransferBackup(Dependencies.Blobs, new BackupSetReference(bsname, false, false, false), cachebset.Backups[cacheindex].hash, true);
                    dstindex += 1;
                    // After insert and increment j still referes to the same backup (dstbr)
                    cacheindex += 1;
                }
            }
            while (dstindex < dstbset.Backups.Count)
            {
                // Add (as shallow) backups in dst not present in cache
                cachebset.Backups.Add((dstbset.Backups[dstindex].hash, true));
                Dependencies.Blobs.TransferBackup(cache.Dependencies.Blobs, cachebsname, dstbset.Backups[dstindex].hash, false);
                cacheindex += 1;
                dstindex   += 1;
            }
            Dependencies.Blobs.CacheBlobList(bsname, cache.Dependencies.Blobs);
            return(dstbset, cachebset);
        }