예제 #1
0
 public BackupRecord GetBackupRecord(string bsname, byte[] hash)
 {
     if (hash == null)
     {
         return(GetBackupRecord(bsname));
     }
     return(BackupRecord.deserialize(Dependencies.Blobs.RetrieveData(hash)));
 }
예제 #2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="bsname"></param>
        /// <param name="message"></param>
        /// <param name="metadatatreehash"></param>
        /// <param name="shallow"></param>
        /// <returns>The hash of the new backup</returns>
        public byte[] AddBackup(string bsname, string message, byte[] metadatatreehash, bool shallow, DateTime backupTime, BackupSet bset = null)
        {
            if (bset == null)
            {
                bset = LoadBackupSet(bsname);
            }
            BackupRecord newbackup = new BackupRecord(message, metadatatreehash, backupTime);

            byte[] brbytes    = newbackup.serialize();
            byte[] backuphash = BlobStore.StoreData(new List <BlobStore>(1)
            {
                Dependencies.Blobs
            }, bsname, brbytes);
            bset.Backups.Add((backuphash, shallow));
            return(backuphash);
        }
예제 #3
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;

            string cachebsname = bsname + Core.CacheSuffix;

            if (dstbset == null)
            {
                dstbset = LoadBackupSet(bsname);
            }
            if (cachebset == null)
            {
                cachebset = cache.LoadBackupSet(cachebsname);
            }
            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(bsname, 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, bsname, 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, bsname, cachebset.Backups[cacheindex].hash, true);
                    dstindex += 1;
                    // After insert and increment j still referes to the same backup (dstbr)
                    cacheindex += 1;
                }
                cachebr = null;
            }
            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;
                dstbr       = null;
            }
            Dependencies.Blobs.CacheBlobList(bsname, cache.Dependencies.Blobs);
            return(dstbset, cachebset);
        }