Ignore:
Timestamp:
27/08/2010 10:18:57 (21 months ago)
Author:
chris
Message:

Change the store info file format to include an account name and the
number of blocks in current (not old or deleted) files, an
often-requested feature since this number is difficult to calculate
otherwise, because files may be both old and deleted, thus counted
twice.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • box/trunk/lib/backupstore/BackupStoreInfo.cpp

    r2415 r2702  
    1212#include <algorithm> 
    1313 
     14#include "Archive.h" 
    1415#include "BackupStoreInfo.h" 
    1516#include "BackupStoreException.h" 
     
    2930// make sure the defaults in CreateNew are modified! 
    3031// ****************** 
     32// Old version, grandfathered, do not change! 
    3133typedef struct 
    3234{ 
     
    4547        int64_t mNumberDeletedDirectories; 
    4648        // Then loads of int64_t IDs for the deleted directories 
    47 } info_StreamFormat; 
    48  
    49 #define INFO_MAGIC_VALUE        0x34832476 
     49} info_StreamFormat_1; 
     50 
     51#define INFO_MAGIC_VALUE_1      0x34832476 
     52#define INFO_MAGIC_VALUE_2      0x494e4632 /* INF2 */ 
    5053 
    5154// Use default packing 
     
    8083          mLastObjectIDUsed(-1), 
    8184          mBlocksUsed(0), 
     85          mBlocksInCurrentFiles(0), 
    8286          mBlocksInOldFiles(0), 
    83           mBlocksInDeletedFiles(0) 
     87          mBlocksInDeletedFiles(0), 
     88          mBlocksInDirectories(0), 
     89          mNumFiles(0), 
     90          mNumOldFiles(0), 
     91          mNumDeletedFiles(0), 
     92          mNumDirectories(0) 
    8493{ 
    8594} 
     
    107116void BackupStoreInfo::CreateNew(int32_t AccountID, const std::string &rRootDir, int DiscSet, int64_t BlockSoftLimit, int64_t BlockHardLimit) 
    108117{ 
    109         // Initial header (is entire file) 
    110         info_StreamFormat hdr = { 
    111                 htonl(INFO_MAGIC_VALUE), // mMagicValue 
    112                 htonl(AccountID), // mAccountID 
    113                 0, // mClientStoreMarker 
    114                 box_hton64(1), // mLastObjectIDUsed (which is the root directory) 
    115                 0, // mBlocksUsed 
    116                 0, // mBlocksInOldFiles 
    117                 0, // mBlocksInDeletedFiles 
    118                 0, // mBlocksInDirectories 
    119                 box_hton64(BlockSoftLimit), // mBlocksSoftLimit 
    120                 box_hton64(BlockHardLimit), // mBlocksHardLimit 
    121                 0, // mCurrentMarkNumber 
    122                 0, // mOptionsPresent 
    123                 0 // mNumberDeletedDirectories 
    124         }; 
    125          
     118        BackupStoreInfo info; 
     119        info.mAccountID = AccountID; 
     120        info.mDiscSet = DiscSet; 
     121        info.mReadOnly = false; 
     122        info.mLastObjectIDUsed = 1; 
     123        info.mBlocksSoftLimit = BlockSoftLimit; 
     124        info.mBlocksHardLimit = BlockHardLimit; 
     125 
    126126        // Generate the filename 
    127127        ASSERT(rRootDir[rRootDir.size() - 1] == '/' || 
    128128                rRootDir[rRootDir.size() - 1] == DIRECTORY_SEPARATOR_ASCHAR); 
    129         std::string fn(rRootDir + INFO_FILENAME); 
    130          
    131         // Open the file for writing 
    132         RaidFileWrite rf(DiscSet, fn); 
    133         rf.Open(false);         // no overwriting, as this is a new file 
    134          
    135         // Write header 
    136         rf.Write(&hdr, sizeof(hdr)); 
    137          
    138         // Commit it to disc, converting it to RAID now 
    139         rf.Commit(true); 
    140          
    141         // Done. 
    142 } 
    143  
    144 // -------------------------------------------------------------------------- 
    145 // 
    146 // Function 
    147 //              Name:    BackupStoreInfo::Load(int32_t, const std::string &, int, bool) 
    148 //              Purpose: Loads the info from disc, given the root information. Can be marked as read only. 
     129        info.mFilename = rRootDir + INFO_FILENAME; 
     130 
     131        info.Save(false); 
     132} 
     133 
     134// -------------------------------------------------------------------------- 
     135// 
     136// Function 
     137//              Name:    BackupStoreInfo::Load(int32_t, const std::string &, 
     138//                       int, bool) 
     139//              Purpose: Loads the info from disc, given the root 
     140//                       information. Can be marked as read only. 
    149141//              Created: 2003/08/28 
    150142// 
     
    157149        // Open the file for reading (passing on optional request for revision ID) 
    158150        std::auto_ptr<RaidFileRead> rf(RaidFileRead::Open(DiscSet, fn, pRevisionID)); 
    159          
    160         // Read in a header 
    161         info_StreamFormat hdr; 
    162         if(!rf->ReadFullBuffer(&hdr, sizeof(hdr), 0 /* not interested in bytes read if this fails */)) 
    163         { 
    164                 THROW_EXCEPTION(BackupStoreException, CouldNotLoadStoreInfo) 
    165         } 
    166          
    167         // Check it 
    168         if(ntohl(hdr.mMagicValue) != INFO_MAGIC_VALUE || (int32_t)ntohl(hdr.mAccountID) != AccountID) 
     151 
     152        // Read in format and version 
     153        int32_t magic; 
     154        if(!rf->ReadFullBuffer(&magic, sizeof(magic), 0)) 
     155        { 
     156                THROW_EXCEPTION(BackupStoreException, CouldNotLoadStoreInfo); 
     157        } 
     158 
     159        bool v1 = false, v2 = false; 
     160 
     161        if(ntohl(magic) == INFO_MAGIC_VALUE_1) 
     162        { 
     163                v1 = true; 
     164        } 
     165        else if(ntohl(magic) == INFO_MAGIC_VALUE_2) 
     166        { 
     167                v2 = true; 
     168        } 
     169        else 
    169170        { 
    170171                THROW_EXCEPTION(BackupStoreException, BadStoreInfoOnLoad) 
    171172        } 
    172          
     173 
    173174        // Make new object 
    174175        std::auto_ptr<BackupStoreInfo> info(new BackupStoreInfo); 
     
    180181        info->mReadOnly = ReadOnly; 
    181182         
    182         // Insert info from file 
    183         info->mClientStoreMarker        = box_ntoh64(hdr.mClientStoreMarker); 
    184         info->mLastObjectIDUsed         = box_ntoh64(hdr.mLastObjectIDUsed); 
    185         info->mBlocksUsed               = box_ntoh64(hdr.mBlocksUsed); 
    186         info->mBlocksInOldFiles         = box_ntoh64(hdr.mBlocksInOldFiles); 
    187         info->mBlocksInDeletedFiles     = box_ntoh64(hdr.mBlocksInDeletedFiles); 
    188         info->mBlocksInDirectories      = box_ntoh64(hdr.mBlocksInDirectories); 
    189         info->mBlocksSoftLimit          = box_ntoh64(hdr.mBlocksSoftLimit); 
    190         info->mBlocksHardLimit          = box_ntoh64(hdr.mBlocksHardLimit); 
    191          
    192         // Load up array of deleted objects 
    193         int64_t numDelObj = box_ntoh64(hdr.mNumberDeletedDirectories); 
    194          
     183        int64_t numDelObj; 
     184 
     185        if (v1) 
     186        { 
     187                // Read in a header 
     188                info_StreamFormat_1 hdr; 
     189 
     190                if(!rf->ReadFullBuffer(&hdr, sizeof(hdr), 
     191                        0 /* not interested in bytes read if this fails */)) 
     192                { 
     193                        THROW_EXCEPTION(BackupStoreException, 
     194                                CouldNotLoadStoreInfo) 
     195                } 
     196                 
     197                // Check it 
     198                if((int32_t)ntohl(hdr.mAccountID) != AccountID) 
     199                { 
     200                        THROW_EXCEPTION(BackupStoreException, 
     201                                BadStoreInfoOnLoad) 
     202                } 
     203                 
     204                // Insert info from file 
     205                info->mClientStoreMarker        = box_ntoh64(hdr.mClientStoreMarker); 
     206                info->mLastObjectIDUsed         = box_ntoh64(hdr.mLastObjectIDUsed); 
     207                info->mBlocksUsed               = box_ntoh64(hdr.mBlocksUsed); 
     208                info->mBlocksInOldFiles         = box_ntoh64(hdr.mBlocksInOldFiles); 
     209                info->mBlocksInDeletedFiles     = box_ntoh64(hdr.mBlocksInDeletedFiles); 
     210                info->mBlocksInDirectories      = box_ntoh64(hdr.mBlocksInDirectories); 
     211                info->mBlocksSoftLimit          = box_ntoh64(hdr.mBlocksSoftLimit); 
     212                info->mBlocksHardLimit          = box_ntoh64(hdr.mBlocksHardLimit); 
     213                 
     214                // Load up array of deleted objects 
     215                numDelObj = box_ntoh64(hdr.mNumberDeletedDirectories); 
     216        } 
     217        else if(v2) 
     218        { 
     219                Archive archive(*rf, IOStream::TimeOutInfinite); 
     220 
     221                // Check it 
     222                int32_t FileAccountID; 
     223                archive.Read(FileAccountID); 
     224                if (FileAccountID != AccountID) 
     225                { 
     226                        THROW_EXCEPTION(BackupStoreException, 
     227                                BadStoreInfoOnLoad) 
     228                } 
     229 
     230                archive.Read(info->mAccountName); 
     231                archive.Read(info->mClientStoreMarker); 
     232                archive.Read(info->mLastObjectIDUsed); 
     233                archive.Read(info->mBlocksUsed); 
     234                archive.Read(info->mBlocksInCurrentFiles); 
     235                archive.Read(info->mBlocksInOldFiles); 
     236                archive.Read(info->mBlocksInDeletedFiles); 
     237                archive.Read(info->mBlocksInDirectories); 
     238                archive.Read(info->mBlocksSoftLimit); 
     239                archive.Read(info->mBlocksHardLimit); 
     240                archive.Read(info->mNumFiles); 
     241                archive.Read(info->mNumOldFiles); 
     242                archive.Read(info->mNumDeletedFiles); 
     243                archive.Read(info->mNumDirectories); 
     244                archive.Read(numDelObj); 
     245        } 
     246 
    195247        // Then load them in 
    196248        if(numDelObj > 0) 
     
    239291// 
    240292// -------------------------------------------------------------------------- 
    241 std::auto_ptr<BackupStoreInfo> BackupStoreInfo::CreateForRegeneration(int32_t AccountID, const std::string &rRootDir, 
    242         int DiscSet, int64_t LastObjectID, int64_t BlocksUsed, int64_t BlocksInOldFiles, 
    243         int64_t BlocksInDeletedFiles, int64_t BlocksInDirectories, int64_t BlockSoftLimit, int64_t BlockHardLimit) 
     293std::auto_ptr<BackupStoreInfo> BackupStoreInfo::CreateForRegeneration( 
     294        int32_t AccountID, const std::string& rAccountName, 
     295        const std::string &rRootDir, int DiscSet, 
     296        int64_t LastObjectID, int64_t BlocksUsed, 
     297        int64_t BlocksInCurrentFiles, int64_t BlocksInOldFiles, 
     298        int64_t BlocksInDeletedFiles, int64_t BlocksInDirectories, 
     299        int64_t BlockSoftLimit, int64_t BlockHardLimit) 
    244300{ 
    245301        // Generate the filename 
     
    251307        // Put in basic info 
    252308        info->mAccountID = AccountID; 
     309        info->mAccountName = rAccountName; 
    253310        info->mDiscSet = DiscSet; 
    254311        info->mFilename = fn; 
     
    258315        info->mClientStoreMarker        = 0; 
    259316        info->mLastObjectIDUsed         = LastObjectID; 
    260         info->mBlocksUsed                       = BlocksUsed; 
     317        info->mBlocksUsed               = BlocksUsed; 
     318        info->mBlocksInCurrentFiles     = BlocksInCurrentFiles; 
    261319        info->mBlocksInOldFiles         = BlocksInOldFiles; 
    262320        info->mBlocksInDeletedFiles     = BlocksInDeletedFiles; 
     
    273331// 
    274332// Function 
    275 //              Name:    BackupStoreInfo::Save() 
     333//              Name:    BackupStoreInfo::Save(bool allowOverwrite) 
    276334//              Purpose: Save modified info back to disc 
    277335//              Created: 2003/08/28 
    278336// 
    279337// -------------------------------------------------------------------------- 
    280 void BackupStoreInfo::Save() 
     338void BackupStoreInfo::Save(bool allowOverwrite) 
    281339{ 
    282340        // Make sure we're initialised (although should never come to this) 
     
    294352        // Then... open a write file 
    295353        RaidFileWrite rf(mDiscSet, mFilename); 
    296         rf.Open(true);          // allow overwriting 
     354        rf.Open(allowOverwrite); 
    297355         
    298356        // Make header 
    299         info_StreamFormat hdr; 
    300         hdr.mMagicValue                                 = htonl(INFO_MAGIC_VALUE); 
    301         hdr.mAccountID                                  = htonl(mAccountID); 
    302         hdr.mClientStoreMarker                  = box_hton64(mClientStoreMarker); 
    303         hdr.mLastObjectIDUsed                   = box_hton64(mLastObjectIDUsed); 
    304         hdr.mBlocksUsed                                 = box_hton64(mBlocksUsed); 
    305         hdr.mBlocksInOldFiles                   = box_hton64(mBlocksInOldFiles); 
    306         hdr.mBlocksInDeletedFiles               = box_hton64(mBlocksInDeletedFiles); 
    307         hdr.mBlocksInDirectories                = box_hton64(mBlocksInDirectories); 
    308         hdr.mBlocksSoftLimit                    = box_hton64(mBlocksSoftLimit); 
    309         hdr.mBlocksHardLimit                    = box_hton64(mBlocksHardLimit); 
    310         hdr.mCurrentMarkNumber                  = 0; 
    311         hdr.mOptionsPresent                             = 0; 
    312         hdr.mNumberDeletedDirectories   = box_hton64(mDeletedDirectories.size()); 
    313          
    314         // Write header 
    315         rf.Write(&hdr, sizeof(hdr)); 
    316          
     357        int32_t magic = htonl(INFO_MAGIC_VALUE_2); 
     358        rf.Write(&magic, sizeof(magic)); 
     359        Archive archive(rf, IOStream::TimeOutInfinite); 
     360 
     361        archive.Write(mAccountID); 
     362        archive.Write(mAccountName); 
     363        archive.Write(mClientStoreMarker); 
     364        archive.Write(mLastObjectIDUsed); 
     365        archive.Write(mBlocksUsed); 
     366        archive.Write(mBlocksInCurrentFiles); 
     367        archive.Write(mBlocksInOldFiles); 
     368        archive.Write(mBlocksInDeletedFiles); 
     369        archive.Write(mBlocksInDirectories); 
     370        archive.Write(mBlocksSoftLimit); 
     371        archive.Write(mBlocksHardLimit); 
     372        archive.Write(mNumFiles); 
     373        archive.Write(mNumOldFiles); 
     374        archive.Write(mNumDeletedFiles); 
     375        archive.Write(mNumDirectories); 
     376 
     377        int64_t numDelObj = mDeletedDirectories.size(); 
     378        archive.Write(numDelObj); 
     379 
    317380        // Write the deleted object list 
    318381        if(mDeletedDirectories.size() > 0) 
     
    350413} 
    351414 
    352  
     415int BackupStoreInfo::ReportChangesTo(BackupStoreInfo& rOldInfo) 
     416{ 
     417        int numChanges = 0; 
     418 
     419        #define COMPARE(attribute) \ 
     420        if (rOldInfo.Get ## attribute () != Get ## attribute ()) \ 
     421        { \ 
     422                BOX_WARNING(#attribute " changed from " << \ 
     423                        rOldInfo.Get ## attribute () << " to " << \ 
     424                        Get ## attribute ()); \ 
     425                numChanges++; \ 
     426        } 
     427 
     428        COMPARE(AccountID); 
     429        COMPARE(AccountName); 
     430        COMPARE(LastObjectIDUsed); 
     431        COMPARE(BlocksUsed); 
     432        COMPARE(BlocksInCurrentFiles); 
     433        COMPARE(BlocksInOldFiles); 
     434        COMPARE(BlocksInDeletedFiles); 
     435        COMPARE(BlocksInDirectories); 
     436        COMPARE(BlocksSoftLimit); 
     437        COMPARE(BlocksHardLimit); 
     438        COMPARE(NumFiles); 
     439        COMPARE(NumOldFiles); 
     440        COMPARE(NumDeletedFiles); 
     441        COMPARE(NumDirectories); 
     442 
     443        #undef COMPARE 
     444 
     445        return numChanges; 
     446} 
    353447 
    354448// -------------------------------------------------------------------------- 
     
    379473// 
    380474// Function 
     475//              Name:    BackupStoreInfo::ChangeBlocksInCurrentFiles(int32_t) 
     476//              Purpose: Change number of blocks in current files, by a delta 
     477//                       amount 
     478//              Created: 2010/08/26 
     479// 
     480// -------------------------------------------------------------------------- 
     481void BackupStoreInfo::ChangeBlocksInCurrentFiles(int64_t Delta) 
     482{ 
     483        if(mReadOnly) 
     484        { 
     485                THROW_EXCEPTION(BackupStoreException, StoreInfoIsReadOnly) 
     486        } 
     487 
     488        if((mBlocksInCurrentFiles + Delta) < 0) 
     489        { 
     490                THROW_EXCEPTION(BackupStoreException, 
     491                        StoreInfoBlockDeltaMakesValueNegative) 
     492        } 
     493         
     494        mBlocksInCurrentFiles += Delta; 
     495        mIsModified = true; 
     496} 
     497 
     498// -------------------------------------------------------------------------- 
     499// 
     500// Function 
    381501//              Name:    BackupStoreInfo::ChangeBlocksInOldFiles(int32_t) 
    382502//              Purpose: Change number of blocks in old files, by a delta amount 
     
    448568} 
    449569 
     570void BackupStoreInfo::AdjustNumFiles(int64_t increase) 
     571{ 
     572        if(mReadOnly) 
     573        { 
     574                THROW_EXCEPTION(BackupStoreException, StoreInfoIsReadOnly) 
     575        } 
     576 
     577        if((mNumFiles + increase) < 0) 
     578        { 
     579                THROW_EXCEPTION(BackupStoreException, StoreInfoBlockDeltaMakesValueNegative) 
     580        } 
     581         
     582        mNumFiles += increase; 
     583        mIsModified = true; 
     584 
     585} 
     586 
     587void BackupStoreInfo::AdjustNumOldFiles(int64_t increase) 
     588{ 
     589        if(mReadOnly) 
     590        { 
     591                THROW_EXCEPTION(BackupStoreException, StoreInfoIsReadOnly) 
     592        } 
     593 
     594        if((mNumOldFiles + increase) < 0) 
     595        { 
     596                THROW_EXCEPTION(BackupStoreException, StoreInfoBlockDeltaMakesValueNegative) 
     597        } 
     598         
     599        mNumOldFiles += increase; 
     600        mIsModified = true; 
     601} 
     602 
     603void BackupStoreInfo::AdjustNumDeletedFiles(int64_t increase) 
     604{ 
     605        if(mReadOnly) 
     606        { 
     607                THROW_EXCEPTION(BackupStoreException, StoreInfoIsReadOnly) 
     608        } 
     609 
     610        if((mNumDeletedFiles + increase) < 0) 
     611        { 
     612                THROW_EXCEPTION(BackupStoreException, StoreInfoBlockDeltaMakesValueNegative) 
     613        } 
     614         
     615        mNumDeletedFiles += increase; 
     616        mIsModified = true; 
     617} 
     618 
     619void BackupStoreInfo::AdjustNumDirectories(int64_t increase) 
     620{ 
     621        if(mReadOnly) 
     622        { 
     623                THROW_EXCEPTION(BackupStoreException, StoreInfoIsReadOnly) 
     624        } 
     625 
     626        if((mNumDirectories + increase) < 0) 
     627        { 
     628                THROW_EXCEPTION(BackupStoreException, StoreInfoBlockDeltaMakesValueNegative) 
     629        } 
     630         
     631        mNumDirectories += increase; 
     632        mIsModified = true; 
     633} 
    450634 
    451635// -------------------------------------------------------------------------- 
     
    591775 
    592776 
    593  
     777// -------------------------------------------------------------------------- 
     778// 
     779// Function 
     780//              Name:    BackupStoreInfo::SetAccountName(const std::string&) 
     781//              Purpose: Sets the account name 
     782//              Created: 2008/08/22 
     783// 
     784// -------------------------------------------------------------------------- 
     785void BackupStoreInfo::SetAccountName(const std::string& rName) 
     786{ 
     787        if(mReadOnly) 
     788        { 
     789                THROW_EXCEPTION(BackupStoreException, StoreInfoIsReadOnly) 
     790        } 
     791         
     792        mAccountName = rName; 
     793         
     794        mIsModified = true; 
     795} 
     796 
     797 
Note: See TracChangeset for help on using the changeset viewer.