Changeset 2534
- Timestamp:
- 27/06/2009 12:38:52 (3 years ago)
- Location:
- box/trunk/lib/backupstore
- Files:
-
- 2 edited
- 2 copied
-
BackupStoreAccounts.cpp (modified) (4 diffs)
-
BackupStoreAccounts.h (modified) (2 diffs)
-
BackupStoreRefCountDatabase.cpp (copied) (copied from box/trunk/lib/backupstore/BackupStoreInfo.cpp) (6 diffs)
-
BackupStoreRefCountDatabase.h (copied) (copied from box/trunk/lib/backupstore/BackupStoreInfo.h) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
box/trunk/lib/backupstore/BackupStoreAccounts.cpp
r881 r2534 15 15 #include "BackupStoreAccounts.h" 16 16 #include "BackupStoreAccountDatabase.h" 17 #include "BackupStoreRefCountDatabase.h" 17 18 #include "RaidFileWrite.h" 18 19 #include "BackupStoreInfo.h" … … 62 63 void BackupStoreAccounts::Create(int32_t ID, int DiscSet, int64_t SizeSoftLimit, int64_t SizeHardLimit, const std::string &rAsUsername) 63 64 { 65 // Create the entry in the database 66 BackupStoreAccountDatabase::Entry Entry(mrDatabase.AddEntry(ID, 67 DiscSet)); 68 64 69 { 65 70 // Become the user specified in the config file? … … 101 106 // Save it back 102 107 info->Save(); 108 109 // Create the refcount database 110 BackupStoreRefCountDatabase::CreateNew(Entry); 111 std::auto_ptr<BackupStoreRefCountDatabase> refcount( 112 BackupStoreRefCountDatabase::Load(Entry, false)); 113 refcount->AddReference(BACKUPSTORE_ROOT_DIRECTORY_ID); 103 114 } 104 115 105 116 // As the original user... 106 107 // Create the entry in the database108 mrDatabase.AddEntry(ID, DiscSet);109 110 117 // Write the database back 111 mrDatabase.Write(); 118 mrDatabase.Write(); 112 119 } 113 120 … … 139 146 // 140 147 // -------------------------------------------------------------------------- 141 std::string BackupStoreAccounts::MakeAccountRootDir(int32_t ID, int DiscSet) const148 std::string BackupStoreAccounts::MakeAccountRootDir(int32_t ID, int DiscSet) 142 149 { 143 150 char accid[64]; // big enough! -
box/trunk/lib/backupstore/BackupStoreAccounts.h
r217 r2534 13 13 #include <string> 14 14 15 class BackupStoreAccountDatabase; 15 #include "BackupStoreAccountDatabase.h" 16 16 17 17 // -------------------------------------------------------------------------- … … 36 36 bool AccountExists(int32_t ID); 37 37 void GetAccountRoot(int32_t ID, std::string &rRootDirOut, int &rDiscSetOut) const; 38 static std::string GetAccountRoot(const 39 BackupStoreAccountDatabase::Entry &rEntry) 40 { 41 return MakeAccountRootDir(rEntry.GetID(), rEntry.GetDiscSet()); 42 } 38 43 39 44 private: 40 st d::string MakeAccountRootDir(int32_t ID, int DiscSet) const;45 static std::string MakeAccountRootDir(int32_t ID, int DiscSet); 41 46 42 47 private: -
box/trunk/lib/backupstore/BackupStoreRefCountDatabase.cpp
r2415 r2534 2 2 // 3 3 // File 4 // Name: BackupStore Info.cpp5 // Purpose: Main backup store informationstorage6 // Created: 200 3/08/284 // Name: BackupStoreRefCountDatabase.cpp 5 // Purpose: Backup store object reference count database storage 6 // Created: 2009/06/01 7 7 // 8 8 // -------------------------------------------------------------------------- … … 12 12 #include <algorithm> 13 13 14 #include "BackupStore Info.h"14 #include "BackupStoreRefCountDatabase.h" 15 15 #include "BackupStoreException.h" 16 #include "RaidFileWrite.h" 17 #include "RaidFileRead.h" 16 #include "BackupStoreAccountDatabase.h" 17 #include "BackupStoreAccounts.h" 18 #include "RaidFileController.h" 19 #include "RaidFileUtil.h" 20 #include "RaidFileException.h" 18 21 19 22 #include "MemLeakFindOn.h" 20 23 21 // set packing to one byte 22 #ifdef STRUCTURE_PACKING_FOR_WIRE_USE_HEADERS 23 #include "BeginStructPackForWire.h" 24 #else 25 BEGIN_STRUCTURE_PACKING_FOR_WIRE 26 #endif 27 28 // ****************** 29 // make sure the defaults in CreateNew are modified! 30 // ****************** 31 typedef struct 32 { 33 int32_t mMagicValue; // also the version number 34 int32_t mAccountID; 35 int64_t mClientStoreMarker; 36 int64_t mLastObjectIDUsed; 37 int64_t mBlocksUsed; 38 int64_t mBlocksInOldFiles; 39 int64_t mBlocksInDeletedFiles; 40 int64_t mBlocksInDirectories; 41 int64_t mBlocksSoftLimit; 42 int64_t mBlocksHardLimit; 43 uint32_t mCurrentMarkNumber; 44 uint32_t mOptionsPresent; // bit mask of optional elements present 45 int64_t mNumberDeletedDirectories; 46 // Then loads of int64_t IDs for the deleted directories 47 } info_StreamFormat; 48 49 #define INFO_MAGIC_VALUE 0x34832476 50 51 // Use default packing 52 #ifdef STRUCTURE_PACKING_FOR_WIRE_USE_HEADERS 53 #include "EndStructPackForWire.h" 54 #else 55 END_STRUCTURE_PACKING_FOR_WIRE 56 #endif 57 58 #ifdef BOX_RELEASE_BUILD 59 #define NUM_DELETED_DIRS_BLOCK 256 60 #else 61 #define NUM_DELETED_DIRS_BLOCK 2 62 #endif 63 64 #define INFO_FILENAME "info" 65 66 // -------------------------------------------------------------------------- 67 // 68 // Function 69 // Name: BackupStoreInfo::BackupStoreInfo() 24 #define REFCOUNT_MAGIC_VALUE 0x52656643 // RefC 25 #define REFCOUNT_FILENAME "refcount" 26 27 // -------------------------------------------------------------------------- 28 // 29 // Function 30 // Name: BackupStoreRefCountDatabase::BackupStoreRefCountDatabase() 70 31 // Purpose: Default constructor 71 32 // Created: 2003/08/28 72 33 // 73 34 // -------------------------------------------------------------------------- 74 BackupStoreInfo::BackupStoreInfo() 75 : mAccountID(-1), 76 mDiscSet(-1), 77 mReadOnly(true), 78 mIsModified(false), 79 mClientStoreMarker(0), 80 mLastObjectIDUsed(-1), 81 mBlocksUsed(0), 82 mBlocksInOldFiles(0), 83 mBlocksInDeletedFiles(0) 84 { 85 } 86 87 // -------------------------------------------------------------------------- 88 // 89 // Function 90 // Name: BackupStoreInfo::~BackupStoreInfo 35 BackupStoreRefCountDatabase::BackupStoreRefCountDatabase(const 36 BackupStoreAccountDatabase::Entry& rAccount) 37 : mAccount(rAccount), 38 mFilename(GetFilename(rAccount)), 39 mReadOnly(true), 40 mIsModified(false) 41 { 42 } 43 44 // -------------------------------------------------------------------------- 45 // 46 // Function 47 // Name: BackupStoreRefCountDatabase::~BackupStoreRefCountDatabase 91 48 // Purpose: Destructor 92 49 // Created: 2003/08/28 93 50 // 94 51 // -------------------------------------------------------------------------- 95 BackupStoreInfo::~BackupStoreInfo() 96 { 97 } 98 99 // -------------------------------------------------------------------------- 100 // 101 // Function 102 // Name: BackupStoreInfo::CreateNew(int32_t, const std::string &, int) 103 // Purpose: Create a new info file on disc 104 // Created: 2003/08/28 105 // 106 // -------------------------------------------------------------------------- 107 void BackupStoreInfo::CreateNew(int32_t AccountID, const std::string &rRootDir, int DiscSet, int64_t BlockSoftLimit, int64_t BlockHardLimit) 108 { 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 }; 52 BackupStoreRefCountDatabase::~BackupStoreRefCountDatabase() 53 { 54 } 55 56 std::string BackupStoreRefCountDatabase::GetFilename(const 57 BackupStoreAccountDatabase::Entry& rAccount) 58 { 59 std::string RootDir = BackupStoreAccounts::GetAccountRoot(rAccount); 60 ASSERT(RootDir[RootDir.size() - 1] == '/' || 61 RootDir[RootDir.size() - 1] == DIRECTORY_SEPARATOR_ASCHAR); 62 63 std::string fn(RootDir + "refcount.db"); 64 RaidFileController &rcontroller(RaidFileController::GetController()); 65 RaidFileDiscSet rdiscSet(rcontroller.GetDiscSet(rAccount.GetDiscSet())); 66 return RaidFileUtil::MakeWriteFileName(rdiscSet, fn); 67 } 68 69 // -------------------------------------------------------------------------- 70 // 71 // Function 72 // Name: BackupStoreRefCountDatabase::Create(int32_t, 73 // const std::string &, int, bool) 74 // Purpose: Create a new database, overwriting an existing 75 // one only if AllowOverwrite is true. 76 // Created: 2003/08/28 77 // 78 // -------------------------------------------------------------------------- 79 void BackupStoreRefCountDatabase::Create(const 80 BackupStoreAccountDatabase::Entry& rAccount, bool AllowOverwrite) 81 { 82 // Initial header 83 refcount_StreamFormat hdr; 84 hdr.mMagicValue = htonl(REFCOUNT_MAGIC_VALUE); 85 hdr.mAccountID = htonl(rAccount.GetID()); 125 86 126 87 // Generate the filename 127 ASSERT(rRootDir[rRootDir.size() - 1] == '/' || 128 rRootDir[rRootDir.size() - 1] == DIRECTORY_SEPARATOR_ASCHAR); 129 std::string fn(rRootDir + INFO_FILENAME); 130 88 std::string Filename = GetFilename(rAccount); 89 131 90 // Open the file for writing 132 RaidFileWrite rf(DiscSet, fn); 133 rf.Open(false); // no overwriting, as this is a new file 91 if (FileExists(Filename) && !AllowOverwrite) 92 { 93 BOX_ERROR("Attempted to overwrite refcount database file: " << 94 Filename); 95 THROW_EXCEPTION(RaidFileException, CannotOverwriteExistingFile); 96 } 97 98 int flags = O_CREAT | O_BINARY | O_RDWR; 99 if (!AllowOverwrite) 100 { 101 flags |= O_EXCL; 102 } 103 104 std::auto_ptr<FileStream> DatabaseFile(new FileStream(Filename, flags)); 134 105 135 106 // 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. 149 // Created: 2003/08/28 150 // 151 // -------------------------------------------------------------------------- 152 std::auto_ptr<BackupStoreInfo> BackupStoreInfo::Load(int32_t AccountID, const std::string &rRootDir, int DiscSet, bool ReadOnly, int64_t *pRevisionID) 107 DatabaseFile->Write(&hdr, sizeof(hdr)); 108 } 109 110 // -------------------------------------------------------------------------- 111 // 112 // Function 113 // Name: BackupStoreRefCountDatabase::Load(int32_t AccountID, 114 // BackupStoreAccountDatabase& rAccountDatabase, 115 // bool ReadOnly); 116 // Purpose: Loads the info from disc, given the root 117 // information. Can be marked as read only. 118 // Created: 2003/08/28 119 // 120 // -------------------------------------------------------------------------- 121 std::auto_ptr<BackupStoreRefCountDatabase> BackupStoreRefCountDatabase::Load( 122 const BackupStoreAccountDatabase::Entry& rAccount, bool ReadOnly) 153 123 { 154 124 // Generate the filename 155 std::string fn(rRootDir + DIRECTORY_SEPARATOR INFO_FILENAME); 156 157 // Open the file for reading (passing on optional request for revision ID) 158 std::auto_ptr<RaidFileRead> rf(RaidFileRead::Open(DiscSet, fn, pRevisionID)); 125 std::string filename = GetFilename(rAccount); 126 int flags = ReadOnly ? O_RDONLY : O_RDWR; 127 128 // Open the file for read/write 129 std::auto_ptr<FileStream> dbfile(new FileStream(filename, 130 flags | O_BINARY)); 159 131 160 132 // Read in a header 161 info_StreamFormat hdr;162 if(! rf->ReadFullBuffer(&hdr, sizeof(hdr), 0 /* not interested in bytes read if this fails */))133 refcount_StreamFormat hdr; 134 if(!dbfile->ReadFullBuffer(&hdr, sizeof(hdr), 0 /* not interested in bytes read if this fails */)) 163 135 { 164 136 THROW_EXCEPTION(BackupStoreException, CouldNotLoadStoreInfo) … … 166 138 167 139 // Check it 168 if(ntohl(hdr.mMagicValue) != INFO_MAGIC_VALUE || (int32_t)ntohl(hdr.mAccountID) != AccountID) 140 if(ntohl(hdr.mMagicValue) != REFCOUNT_MAGIC_VALUE || 141 (int32_t)ntohl(hdr.mAccountID) != rAccount.GetID()) 169 142 { 170 143 THROW_EXCEPTION(BackupStoreException, BadStoreInfoOnLoad) … … 172 145 173 146 // Make new object 174 std::auto_ptr<BackupStore Info> info(new BackupStoreInfo);147 std::auto_ptr<BackupStoreRefCountDatabase> refcount(new BackupStoreRefCountDatabase(rAccount)); 175 148 176 149 // Put in basic location info 177 info->mAccountID = AccountID; 178 info->mDiscSet = DiscSet; 179 info->mFilename = fn; 180 info->mReadOnly = ReadOnly; 181 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 195 // Then load them in 196 if(numDelObj > 0) 197 { 198 int64_t objs[NUM_DELETED_DIRS_BLOCK]; 199 200 int64_t toload = numDelObj; 201 while(toload > 0) 202 { 203 // How many in this one? 204 int b = (toload > NUM_DELETED_DIRS_BLOCK)?NUM_DELETED_DIRS_BLOCK:((int)(toload)); 205 206 if(!rf->ReadFullBuffer(objs, b * sizeof(int64_t), 0 /* not interested in bytes read if this fails */)) 207 { 208 THROW_EXCEPTION(BackupStoreException, CouldNotLoadStoreInfo) 209 } 210 211 // Add them 212 for(int t = 0; t < b; ++t) 213 { 214 info->mDeletedDirectories.push_back(box_ntoh64(objs[t])); 215 } 216 217 // Number loaded 218 toload -= b; 219 } 220 } 221 222 // Final check 223 if(static_cast<int64_t>(info->mDeletedDirectories.size()) != numDelObj) 224 { 225 THROW_EXCEPTION(BackupStoreException, BadStoreInfoOnLoad) 226 } 150 refcount->mReadOnly = ReadOnly; 151 refcount->mapDatabaseFile = dbfile; 227 152 228 153 // return it to caller 229 return info; 230 } 231 232 233 // -------------------------------------------------------------------------- 234 // 235 // Function 236 // Name: BackupStoreInfo::CreateForRegeneration(...) 237 // Purpose: Return an object which can be used to save for regeneration. 238 // Created: 23/4/04 239 // 240 // -------------------------------------------------------------------------- 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) 244 { 245 // Generate the filename 246 std::string fn(rRootDir + DIRECTORY_SEPARATOR INFO_FILENAME); 247 248 // Make new object 249 std::auto_ptr<BackupStoreInfo> info(new BackupStoreInfo); 250 251 // Put in basic info 252 info->mAccountID = AccountID; 253 info->mDiscSet = DiscSet; 254 info->mFilename = fn; 255 info->mReadOnly = false; 256 257 // Insert info starting info 258 info->mClientStoreMarker = 0; 259 info->mLastObjectIDUsed = LastObjectID; 260 info->mBlocksUsed = BlocksUsed; 261 info->mBlocksInOldFiles = BlocksInOldFiles; 262 info->mBlocksInDeletedFiles = BlocksInDeletedFiles; 263 info->mBlocksInDirectories = BlocksInDirectories; 264 info->mBlocksSoftLimit = BlockSoftLimit; 265 info->mBlocksHardLimit = BlockHardLimit; 266 267 // return it to caller 268 return info; 269 } 270 271 272 // -------------------------------------------------------------------------- 273 // 274 // Function 275 // Name: BackupStoreInfo::Save() 154 return refcount; 155 } 156 157 // -------------------------------------------------------------------------- 158 // 159 // Function 160 // Name: BackupStoreRefCountDatabase::Save() 276 161 // Purpose: Save modified info back to disc 277 162 // Created: 2003/08/28 278 163 // 279 164 // -------------------------------------------------------------------------- 280 void BackupStoreInfo::Save() 165 /* 166 void BackupStoreRefCountDatabase::Save() 281 167 { 282 168 // Make sure we're initialised (although should never come to this) 283 if(mFilename.empty() || mAccount ID == -1 || mDiscSet == -1)169 if(mFilename.empty() || mAccount.GetID() == 0) 284 170 { 285 171 THROW_EXCEPTION(BackupStoreException, Internal) … … 293 179 294 180 // Then... open a write file 295 RaidFileWrite rf(m DiscSet, mFilename);181 RaidFileWrite rf(mAccount.GetDiscSet(), mFilename); 296 182 rf.Open(true); // allow overwriting 297 183 298 184 // Make header 299 185 info_StreamFormat hdr; 300 hdr.mMagicValue = htonl(INFO_MAGIC_VALUE);301 hdr.mAccountID = htonl(mAccountID);186 hdr.mMagicValue = htonl(INFO_MAGIC_VALUE); 187 hdr.mAccountID = htonl(mAccountID); 302 188 hdr.mClientStoreMarker = box_hton64(mClientStoreMarker); 303 189 hdr.mLastObjectIDUsed = box_hton64(mLastObjectIDUsed); … … 349 235 mIsModified = false; 350 236 } 351 352 353 354 // -------------------------------------------------------------------------- 355 // 356 // Function 357 // Name: BackupStoreInfo::ChangeBlocksUsed(int32_t) 358 // Purpose: Change number of blocks used, by a delta amount 359 // Created: 2003/08/28 360 // 361 // -------------------------------------------------------------------------- 362 void BackupStoreInfo::ChangeBlocksUsed(int64_t Delta) 363 { 364 if(mReadOnly) 365 { 366 THROW_EXCEPTION(BackupStoreException, StoreInfoIsReadOnly) 367 } 368 if((mBlocksUsed + Delta) < 0) 369 { 370 THROW_EXCEPTION(BackupStoreException, StoreInfoBlockDeltaMakesValueNegative) 371 } 372 373 mBlocksUsed += Delta; 374 375 mIsModified = true; 376 } 377 378 // -------------------------------------------------------------------------- 379 // 380 // Function 381 // Name: BackupStoreInfo::ChangeBlocksInOldFiles(int32_t) 382 // Purpose: Change number of blocks in old files, by a delta amount 383 // Created: 2003/08/28 384 // 385 // -------------------------------------------------------------------------- 386 void BackupStoreInfo::ChangeBlocksInOldFiles(int64_t Delta) 387 { 388 if(mReadOnly) 389 { 390 THROW_EXCEPTION(BackupStoreException, StoreInfoIsReadOnly) 391 } 392 if((mBlocksInOldFiles + Delta) < 0) 393 { 394 THROW_EXCEPTION(BackupStoreException, StoreInfoBlockDeltaMakesValueNegative) 395 } 396 397 mBlocksInOldFiles += Delta; 398 399 mIsModified = true; 400 } 401 402 // -------------------------------------------------------------------------- 403 // 404 // Function 405 // Name: BackupStoreInfo::ChangeBlocksInDeletedFiles(int32_t) 406 // Purpose: Change number of blocks in deleted files, by a delta amount 407 // Created: 2003/08/28 408 // 409 // -------------------------------------------------------------------------- 410 void BackupStoreInfo::ChangeBlocksInDeletedFiles(int64_t Delta) 411 { 412 if(mReadOnly) 413 { 414 THROW_EXCEPTION(BackupStoreException, StoreInfoIsReadOnly) 415 } 416 if((mBlocksInDeletedFiles + Delta) < 0) 417 { 418 THROW_EXCEPTION(BackupStoreException, StoreInfoBlockDeltaMakesValueNegative) 419 } 420 421 mBlocksInDeletedFiles += Delta; 422 423 mIsModified = true; 424 } 425 426 // -------------------------------------------------------------------------- 427 // 428 // Function 429 // Name: BackupStoreInfo::ChangeBlocksInDirectories(int32_t) 430 // Purpose: Change number of blocks in directories, by a delta amount 431 // Created: 2003/08/28 432 // 433 // -------------------------------------------------------------------------- 434 void BackupStoreInfo::ChangeBlocksInDirectories(int64_t Delta) 435 { 436 if(mReadOnly) 437 { 438 THROW_EXCEPTION(BackupStoreException, StoreInfoIsReadOnly) 439 } 440 if((mBlocksInDirectories + Delta) < 0) 441 { 442 THROW_EXCEPTION(BackupStoreException, StoreInfoBlockDeltaMakesValueNegative) 443 } 444 445 mBlocksInDirectories += Delta; 446 447 mIsModified = true; 448 } 449 450 451 // -------------------------------------------------------------------------- 452 // 453 // Function 454 // Name: BackupStoreInfo::CorrectAllUsedValues(int64_t, int64_t, int64_t, int64_t) 455 // Purpose: Set all the usage counts to specific values -- use for correcting in housekeeping 456 // if something when wrong during the backup connection, and the store info wasn't 457 // saved back to disc. 458 // Created: 15/12/03 459 // 460 // -------------------------------------------------------------------------- 461 void BackupStoreInfo::CorrectAllUsedValues(int64_t Used, int64_t InOldFiles, int64_t InDeletedFiles, int64_t InDirectories) 462 { 463 if(mReadOnly) 464 { 465 THROW_EXCEPTION(BackupStoreException, StoreInfoIsReadOnly) 466 } 467 468 // Set the values 469 mBlocksUsed = Used; 470 mBlocksInOldFiles = InOldFiles; 471 mBlocksInDeletedFiles = InDeletedFiles; 472 mBlocksInDirectories = InDirectories; 473 474 mIsModified = true; 475 } 476 477 478 // -------------------------------------------------------------------------- 479 // 480 // Function 481 // Name: BackupStoreInfo::AddDeletedDirectory(int64_t) 482 // Purpose: Add a directory ID to the deleted list 483 // Created: 2003/08/28 484 // 485 // -------------------------------------------------------------------------- 486 void BackupStoreInfo::AddDeletedDirectory(int64_t DirID) 487 { 488 if(mReadOnly) 489 { 490 THROW_EXCEPTION(BackupStoreException, StoreInfoIsReadOnly) 491 } 492 493 mDeletedDirectories.push_back(DirID); 494 495 mIsModified = true; 496 } 497 498 // -------------------------------------------------------------------------- 499 // 500 // Function 501 // Name: BackupStoreInfo::RemovedDeletedDirectory(int64_t) 502 // Purpose: Remove a directory from the deleted list 503 // Created: 2003/08/28 504 // 505 // -------------------------------------------------------------------------- 506 void BackupStoreInfo::RemovedDeletedDirectory(int64_t DirID) 507 { 508 if(mReadOnly) 509 { 510 THROW_EXCEPTION(BackupStoreException, StoreInfoIsReadOnly) 511 } 512 513 std::vector<int64_t>::iterator i(std::find(mDeletedDirectories.begin(), mDeletedDirectories.end(), DirID)); 514 if(i == mDeletedDirectories.end()) 515 { 516 THROW_EXCEPTION(BackupStoreException, StoreInfoDirNotInList) 517 } 518 mDeletedDirectories.erase(i); 519 520 mIsModified = true; 521 } 522 523 // -------------------------------------------------------------------------- 524 // 525 // Function 526 // Name: BackupStoreInfo::ChangeLimits(int64_t, int64_t) 527 // Purpose: Change the soft and hard limits 528 // Created: 15/12/03 529 // 530 // -------------------------------------------------------------------------- 531 void BackupStoreInfo::ChangeLimits(int64_t BlockSoftLimit, int64_t BlockHardLimit) 532 { 533 if(mReadOnly) 534 { 535 THROW_EXCEPTION(BackupStoreException, StoreInfoIsReadOnly) 536 } 537 538 mBlocksSoftLimit = BlockSoftLimit; 539 mBlocksHardLimit = BlockHardLimit; 540 541 mIsModified = true; 542 } 543 544 545 // -------------------------------------------------------------------------- 546 // 547 // Function 548 // Name: BackupStoreInfo::AllocateObjectID() 549 // Purpose: Allocate an ID for a new object in the store. 550 // Created: 2003/09/03 551 // 552 // -------------------------------------------------------------------------- 553 int64_t BackupStoreInfo::AllocateObjectID() 554 { 555 if(mReadOnly) 556 { 557 THROW_EXCEPTION(BackupStoreException, StoreInfoIsReadOnly) 558 } 559 if(mLastObjectIDUsed < 0) 560 { 561 THROW_EXCEPTION(BackupStoreException, StoreInfoNotInitialised) 562 } 563 564 // Return the next object ID 565 return ++mLastObjectIDUsed; 566 567 mIsModified = true; 568 } 569 570 571 572 // -------------------------------------------------------------------------- 573 // 574 // Function 575 // Name: BackupStoreInfo::SetClientStoreMarker(int64_t) 576 // Purpose: Sets the client store marker 577 // Created: 2003/10/29 578 // 579 // -------------------------------------------------------------------------- 580 void BackupStoreInfo::SetClientStoreMarker(int64_t ClientStoreMarker) 581 { 582 if(mReadOnly) 583 { 584 THROW_EXCEPTION(BackupStoreException, StoreInfoIsReadOnly) 585 } 586 587 mClientStoreMarker = ClientStoreMarker; 588 589 mIsModified = true; 590 } 591 592 593 237 */ 238 239 240 // -------------------------------------------------------------------------- 241 // 242 // Function 243 // Name: BackupStoreRefCountDatabase::GetRefCount(int64_t 244 // ObjectID) 245 // Purpose: Get the number of references to the specified object 246 // out of the database 247 // Created: 2009/06/01 248 // 249 // -------------------------------------------------------------------------- 250 int32_t BackupStoreRefCountDatabase::GetRefCount(int64_t ObjectID) const 251 { 252 IOStream::pos_type offset = GetOffset(ObjectID); 253 254 if (GetSize() < offset + GetEntrySize()) 255 { 256 BOX_ERROR("attempted read of unknown refcount for object " << 257 BOX_FORMAT_OBJECTID(ObjectID)); 258 THROW_EXCEPTION(BackupStoreException, 259 UnknownObjectRefCountRequested); 260 } 261 262 mapDatabaseFile->Seek(offset, SEEK_SET); 263 264 refcount_t refcount; 265 if (mapDatabaseFile->Read(&refcount, sizeof(refcount)) != 266 sizeof(refcount)) 267 { 268 BOX_LOG_SYS_ERROR("short read on refcount database: " << 269 mFilename); 270 THROW_EXCEPTION(BackupStoreException, CouldNotLoadStoreInfo); 271 } 272 273 return ntohl(refcount); 274 } 275 276 int64_t BackupStoreRefCountDatabase::GetLastObjectIDUsed() const 277 { 278 return (GetSize() - sizeof(refcount_StreamFormat)) / 279 sizeof(refcount_t); 280 } 281 282 void BackupStoreRefCountDatabase::AddReference(int64_t ObjectID) 283 { 284 refcount_t refcount; 285 286 if (ObjectID > GetLastObjectIDUsed()) 287 { 288 // new object, assume no previous references 289 refcount = 0; 290 } 291 else 292 { 293 // read previous value from database 294 refcount = GetRefCount(ObjectID); 295 } 296 297 refcount++; 298 299 SetRefCount(ObjectID, refcount); 300 } 301 302 void BackupStoreRefCountDatabase::SetRefCount(int64_t ObjectID, 303 refcount_t NewRefCount) 304 { 305 IOStream::pos_type offset = GetOffset(ObjectID); 306 mapDatabaseFile->Seek(offset, SEEK_SET); 307 refcount_t RefCountNetOrder = htonl(NewRefCount); 308 mapDatabaseFile->Write(&RefCountNetOrder, sizeof(RefCountNetOrder)); 309 } 310 311 bool BackupStoreRefCountDatabase::RemoveReference(int64_t ObjectID) 312 { 313 refcount_t refcount = GetRefCount(ObjectID); // must exist in database 314 ASSERT(refcount > 0); 315 refcount--; 316 SetRefCount(ObjectID, refcount); 317 return (refcount > 0); 318 } 319 -
box/trunk/lib/backupstore/BackupStoreRefCountDatabase.h
r1868 r2534 2 2 // 3 3 // File 4 // Name: BackupStore Info.h4 // Name: BackupStoreRefCountDatabase.h 5 5 // Purpose: Main backup store information storage 6 6 // Created: 2003/08/28 … … 8 8 // -------------------------------------------------------------------------- 9 9 10 #ifndef BACKUPSTORE INFO__H11 #define BACKUPSTORE INFO__H10 #ifndef BACKUPSTOREREFCOUNTDATABASE__H 11 #define BACKUPSTOREREFCOUNTDATABASE__H 12 12 13 13 #include <memory> … … 15 15 #include <vector> 16 16 17 #include "BackupStoreAccountDatabase.h" 18 #include "FileStream.h" 19 17 20 class BackupStoreCheck; 21 class BackupStoreContext; 22 23 // set packing to one byte 24 #ifdef STRUCTURE_PACKING_FOR_WIRE_USE_HEADERS 25 #include "BeginStructPackForWire.h" 26 #else 27 BEGIN_STRUCTURE_PACKING_FOR_WIRE 28 #endif 29 30 typedef struct 31 { 32 uint32_t mMagicValue; // also the version number 33 uint32_t mAccountID; 34 } refcount_StreamFormat; 35 36 // Use default packing 37 #ifdef STRUCTURE_PACKING_FOR_WIRE_USE_HEADERS 38 #include "EndStructPackForWire.h" 39 #else 40 END_STRUCTURE_PACKING_FOR_WIRE 41 #endif 18 42 19 43 // -------------------------------------------------------------------------- 20 44 // 21 45 // Class 22 // Name: BackupStore Info23 // Purpose: Main backup store informationstorage24 // Created: 200 3/08/2846 // Name: BackupStoreRefCountDatabase 47 // Purpose: Backup store reference count database storage 48 // Created: 2009/06/01 25 49 // 26 50 // -------------------------------------------------------------------------- 27 class BackupStore Info51 class BackupStoreRefCountDatabase 28 52 { 29 53 friend class BackupStoreCheck; 54 friend class BackupStoreContext; 30 55 public: 31 ~BackupStore Info();56 ~BackupStoreRefCountDatabase(); 32 57 private: 33 58 // Creation through static functions only 34 BackupStoreInfo(); 59 BackupStoreRefCountDatabase(const BackupStoreAccountDatabase::Entry& 60 rAccount); 35 61 // No copying allowed 36 BackupStore Info(const BackupStoreInfo&);62 BackupStoreRefCountDatabase(const BackupStoreRefCountDatabase &); 37 63 38 64 public: 39 // Create a New account, saving a blank info object to the disc 40 static void CreateNew(int32_t AccountID, const std::string &rRootDir, int DiscSet, int64_t BlockSoftLimit, int64_t BlockHardLimit); 65 // Create a new database for a new account. This method will refuse 66 // to overwrite any existing file. 67 static void CreateNew(const BackupStoreAccountDatabase::Entry& rAccount) 68 { 69 Create(rAccount, false); 70 } 41 71 42 72 // Load it from the store 43 static std::auto_ptr<BackupStoreInfo> Load(int32_t AccountID, const std::string &rRootDir, int DiscSet, bool ReadOnly, int64_t *pRevisionID = 0); 44 45 // Has info been modified? 46 bool IsModified() const {return mIsModified;} 47 48 // Save modified infomation back to store 49 void Save(); 73 static std::auto_ptr<BackupStoreRefCountDatabase> Load(const 74 BackupStoreAccountDatabase::Entry& rAccount, bool ReadOnly); 50 75 51 76 // Data access functions 52 int32_t GetAccountID() const {return mAccountID;} 53 int64_t GetLastObjectIDUsed() const {return mLastObjectIDUsed;} 54 int64_t GetBlocksUsed() const {return mBlocksUsed;} 55 int64_t GetBlocksInOldFiles() const {return mBlocksInOldFiles;} 56 int64_t GetBlocksInDeletedFiles() const {return mBlocksInDeletedFiles;} 57 int64_t GetBlocksInDirectories() const {return mBlocksInDirectories;} 58 const std::vector<int64_t> &GetDeletedDirectories() const {return mDeletedDirectories;} 59 int64_t GetBlocksSoftLimit() const {return mBlocksSoftLimit;} 60 int64_t GetBlocksHardLimit() const {return mBlocksHardLimit;} 61 bool IsReadOnly() const {return mReadOnly;} 62 int GetDiscSetNumber() const {return mDiscSet;} 77 int32_t GetRefCount(int64_t ObjectID) const; 78 int64_t GetLastObjectIDUsed() const; 63 79 64 80 // Data modification functions 65 void ChangeBlocksUsed(int64_t Delta); 66 void ChangeBlocksInOldFiles(int64_t Delta); 67 void ChangeBlocksInDeletedFiles(int64_t Delta); 68 void ChangeBlocksInDirectories(int64_t Delta); 69 void CorrectAllUsedValues(int64_t Used, int64_t InOldFiles, int64_t InDeletedFiles, int64_t InDirectories); 70 void AddDeletedDirectory(int64_t DirID); 71 void RemovedDeletedDirectory(int64_t DirID); 72 void ChangeLimits(int64_t BlockSoftLimit, int64_t BlockHardLimit); 73 74 // Object IDs 75 int64_t AllocateObjectID(); 76 77 // Client marker set and get 78 int64_t GetClientStoreMarker() {return mClientStoreMarker;} 79 void SetClientStoreMarker(int64_t ClientStoreMarker); 81 void AddReference(int64_t ObjectID); 82 bool RemoveReference(int64_t ObjectID); 80 83 81 84 private: 82 static std::auto_ptr<BackupStoreInfo> CreateForRegeneration(int32_t AccountID, const std::string &rRootDir, 83 int DiscSet, int64_t LastObjectID, int64_t BlocksUsed, int64_t BlocksInOldFiles, 84 int64_t BlocksInDeletedFiles, int64_t BlocksInDirectories, int64_t BlockSoftLimit, int64_t BlockHardLimit); 85 // Create a new database for an existing account. Used during 86 // account checking if opening the old database throws an exception. 87 // This method will overwrite any existing file. 88 static void CreateForRegeneration(const 89 BackupStoreAccountDatabase::Entry& rAccount) 90 { 91 Create(rAccount, true); 92 } 85 93 86 private: 94 static void Create(const BackupStoreAccountDatabase::Entry& rAccount, 95 bool AllowOverwrite); 96 97 typedef int32_t refcount_t; 98 99 static std::string GetFilename(const BackupStoreAccountDatabase::Entry& 100 rAccount); 101 IOStream::pos_type GetSize() const 102 { 103 return mapDatabaseFile->GetPosition() + 104 mapDatabaseFile->BytesLeftToRead(); 105 } 106 IOStream::pos_type GetEntrySize() const 107 { 108 return sizeof(refcount_t); 109 } 110 IOStream::pos_type GetOffset(int64_t ObjectID) const 111 { 112 return ((ObjectID - 1) * GetEntrySize()) + 113 sizeof(refcount_StreamFormat); 114 } 115 void SetRefCount(int64_t ObjectID, refcount_t NewRefCount); 116 87 117 // Location information 88 int32_t mAccountID; 89 int mDiscSet; 118 BackupStoreAccountDatabase::Entry mAccount; 90 119 std::string mFilename; 91 120 bool mReadOnly; 92 121 bool mIsModified; 93 94 // Client infomation 95 int64_t mClientStoreMarker; 96 97 // Account information 98 int64_t mLastObjectIDUsed; 99 int64_t mBlocksUsed; 100 int64_t mBlocksInOldFiles; 101 int64_t mBlocksInDeletedFiles; 102 int64_t mBlocksInDirectories; 103 int64_t mBlocksSoftLimit; 104 int64_t mBlocksHardLimit; 105 std::vector<int64_t> mDeletedDirectories; 122 std::auto_ptr<FileStream> mapDatabaseFile; 106 123 }; 107 124 108 109 #endif // BACKUPSTOREINFO__H 110 111 125 #endif // BACKUPSTOREREFCOUNTDATABASE__H
Note: See TracChangeset
for help on using the changeset viewer.
