| 1 | // -------------------------------------------------------------------------- |
|---|
| 2 | // |
|---|
| 3 | // File |
|---|
| 4 | // Name: BackupStoreInfo.cpp |
|---|
| 5 | // Purpose: Main backup store information storage |
|---|
| 6 | // Created: 2003/08/28 |
|---|
| 7 | // |
|---|
| 8 | // -------------------------------------------------------------------------- |
|---|
| 9 | |
|---|
| 10 | #include "Box.h" |
|---|
| 11 | |
|---|
| 12 | #include <algorithm> |
|---|
| 13 | |
|---|
| 14 | #include "Archive.h" |
|---|
| 15 | #include "BackupStoreInfo.h" |
|---|
| 16 | #include "BackupStoreException.h" |
|---|
| 17 | #include "RaidFileWrite.h" |
|---|
| 18 | #include "RaidFileRead.h" |
|---|
| 19 | |
|---|
| 20 | #include "MemLeakFindOn.h" |
|---|
| 21 | |
|---|
| 22 | // set packing to one byte |
|---|
| 23 | #ifdef STRUCTURE_PACKING_FOR_WIRE_USE_HEADERS |
|---|
| 24 | #include "BeginStructPackForWire.h" |
|---|
| 25 | #else |
|---|
| 26 | BEGIN_STRUCTURE_PACKING_FOR_WIRE |
|---|
| 27 | #endif |
|---|
| 28 | |
|---|
| 29 | // ****************** |
|---|
| 30 | // make sure the defaults in CreateNew are modified! |
|---|
| 31 | // ****************** |
|---|
| 32 | // Old version, grandfathered, do not change! |
|---|
| 33 | typedef struct |
|---|
| 34 | { |
|---|
| 35 | int32_t mMagicValue; // also the version number |
|---|
| 36 | int32_t mAccountID; |
|---|
| 37 | int64_t mClientStoreMarker; |
|---|
| 38 | int64_t mLastObjectIDUsed; |
|---|
| 39 | int64_t mBlocksUsed; |
|---|
| 40 | int64_t mBlocksInOldFiles; |
|---|
| 41 | int64_t mBlocksInDeletedFiles; |
|---|
| 42 | int64_t mBlocksInDirectories; |
|---|
| 43 | int64_t mBlocksSoftLimit; |
|---|
| 44 | int64_t mBlocksHardLimit; |
|---|
| 45 | uint32_t mCurrentMarkNumber; |
|---|
| 46 | uint32_t mOptionsPresent; // bit mask of optional elements present |
|---|
| 47 | int64_t mNumberDeletedDirectories; |
|---|
| 48 | // Then loads of int64_t IDs for the deleted directories |
|---|
| 49 | } info_StreamFormat_1; |
|---|
| 50 | |
|---|
| 51 | #define INFO_MAGIC_VALUE_1 0x34832476 |
|---|
| 52 | #define INFO_MAGIC_VALUE_2 0x494e4632 /* INF2 */ |
|---|
| 53 | |
|---|
| 54 | // Use default packing |
|---|
| 55 | #ifdef STRUCTURE_PACKING_FOR_WIRE_USE_HEADERS |
|---|
| 56 | #include "EndStructPackForWire.h" |
|---|
| 57 | #else |
|---|
| 58 | END_STRUCTURE_PACKING_FOR_WIRE |
|---|
| 59 | #endif |
|---|
| 60 | |
|---|
| 61 | #ifdef BOX_RELEASE_BUILD |
|---|
| 62 | #define NUM_DELETED_DIRS_BLOCK 256 |
|---|
| 63 | #else |
|---|
| 64 | #define NUM_DELETED_DIRS_BLOCK 2 |
|---|
| 65 | #endif |
|---|
| 66 | |
|---|
| 67 | #define INFO_FILENAME "info" |
|---|
| 68 | |
|---|
| 69 | // -------------------------------------------------------------------------- |
|---|
| 70 | // |
|---|
| 71 | // Function |
|---|
| 72 | // Name: BackupStoreInfo::BackupStoreInfo() |
|---|
| 73 | // Purpose: Default constructor |
|---|
| 74 | // Created: 2003/08/28 |
|---|
| 75 | // |
|---|
| 76 | // -------------------------------------------------------------------------- |
|---|
| 77 | BackupStoreInfo::BackupStoreInfo() |
|---|
| 78 | : mAccountID(-1), |
|---|
| 79 | mDiscSet(-1), |
|---|
| 80 | mReadOnly(true), |
|---|
| 81 | mIsModified(false), |
|---|
| 82 | mClientStoreMarker(0), |
|---|
| 83 | mLastObjectIDUsed(-1), |
|---|
| 84 | mBlocksUsed(0), |
|---|
| 85 | mBlocksInCurrentFiles(0), |
|---|
| 86 | mBlocksInOldFiles(0), |
|---|
| 87 | mBlocksInDeletedFiles(0), |
|---|
| 88 | mBlocksInDirectories(0), |
|---|
| 89 | mNumFiles(0), |
|---|
| 90 | mNumOldFiles(0), |
|---|
| 91 | mNumDeletedFiles(0), |
|---|
| 92 | mNumDirectories(0) |
|---|
| 93 | { |
|---|
| 94 | } |
|---|
| 95 | |
|---|
| 96 | // -------------------------------------------------------------------------- |
|---|
| 97 | // |
|---|
| 98 | // Function |
|---|
| 99 | // Name: BackupStoreInfo::~BackupStoreInfo |
|---|
| 100 | // Purpose: Destructor |
|---|
| 101 | // Created: 2003/08/28 |
|---|
| 102 | // |
|---|
| 103 | // -------------------------------------------------------------------------- |
|---|
| 104 | BackupStoreInfo::~BackupStoreInfo() |
|---|
| 105 | { |
|---|
| 106 | } |
|---|
| 107 | |
|---|
| 108 | // -------------------------------------------------------------------------- |
|---|
| 109 | // |
|---|
| 110 | // Function |
|---|
| 111 | // Name: BackupStoreInfo::CreateNew(int32_t, const std::string &, int) |
|---|
| 112 | // Purpose: Create a new info file on disc |
|---|
| 113 | // Created: 2003/08/28 |
|---|
| 114 | // |
|---|
| 115 | // -------------------------------------------------------------------------- |
|---|
| 116 | void BackupStoreInfo::CreateNew(int32_t AccountID, const std::string &rRootDir, int DiscSet, int64_t BlockSoftLimit, int64_t BlockHardLimit) |
|---|
| 117 | { |
|---|
| 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 | |
|---|
| 126 | // Generate the filename |
|---|
| 127 | ASSERT(rRootDir[rRootDir.size() - 1] == '/' || |
|---|
| 128 | rRootDir[rRootDir.size() - 1] == DIRECTORY_SEPARATOR_ASCHAR); |
|---|
| 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. |
|---|
| 141 | // Created: 2003/08/28 |
|---|
| 142 | // |
|---|
| 143 | // -------------------------------------------------------------------------- |
|---|
| 144 | std::auto_ptr<BackupStoreInfo> BackupStoreInfo::Load(int32_t AccountID, |
|---|
| 145 | const std::string &rRootDir, int DiscSet, bool ReadOnly, |
|---|
| 146 | int64_t *pRevisionID) |
|---|
| 147 | { |
|---|
| 148 | // Generate the filename |
|---|
| 149 | std::string fn(rRootDir + INFO_FILENAME); |
|---|
| 150 | |
|---|
| 151 | // Open the file for reading (passing on optional request for revision ID) |
|---|
| 152 | std::auto_ptr<RaidFileRead> rf(RaidFileRead::Open(DiscSet, fn, pRevisionID)); |
|---|
| 153 | |
|---|
| 154 | // Read in format and version |
|---|
| 155 | int32_t magic; |
|---|
| 156 | if(!rf->ReadFullBuffer(&magic, sizeof(magic), 0)) |
|---|
| 157 | { |
|---|
| 158 | THROW_FILE_ERROR("Failed to read store info file: " |
|---|
| 159 | "short read of magic number", fn, |
|---|
| 160 | BackupStoreException, CouldNotLoadStoreInfo); |
|---|
| 161 | } |
|---|
| 162 | |
|---|
| 163 | bool v1 = false, v2 = false; |
|---|
| 164 | |
|---|
| 165 | if(ntohl(magic) == INFO_MAGIC_VALUE_1) |
|---|
| 166 | { |
|---|
| 167 | v1 = true; |
|---|
| 168 | } |
|---|
| 169 | else if(ntohl(magic) == INFO_MAGIC_VALUE_2) |
|---|
| 170 | { |
|---|
| 171 | v2 = true; |
|---|
| 172 | } |
|---|
| 173 | else |
|---|
| 174 | { |
|---|
| 175 | THROW_FILE_ERROR("Failed to read store info file: " |
|---|
| 176 | "unknown magic " << BOX_FORMAT_HEX32(ntohl(magic)), |
|---|
| 177 | fn, BackupStoreException, BadStoreInfoOnLoad); |
|---|
| 178 | } |
|---|
| 179 | |
|---|
| 180 | // Make new object |
|---|
| 181 | std::auto_ptr<BackupStoreInfo> info(new BackupStoreInfo); |
|---|
| 182 | |
|---|
| 183 | // Put in basic location info |
|---|
| 184 | info->mAccountID = AccountID; |
|---|
| 185 | info->mDiscSet = DiscSet; |
|---|
| 186 | info->mFilename = fn; |
|---|
| 187 | info->mReadOnly = ReadOnly; |
|---|
| 188 | |
|---|
| 189 | int64_t numDelObj; |
|---|
| 190 | |
|---|
| 191 | if (v1) |
|---|
| 192 | { |
|---|
| 193 | // Read in a header |
|---|
| 194 | info_StreamFormat_1 hdr; |
|---|
| 195 | rf->Seek(0, IOStream::SeekType_Absolute); |
|---|
| 196 | |
|---|
| 197 | if(!rf->ReadFullBuffer(&hdr, sizeof(hdr), |
|---|
| 198 | 0 /* not interested in bytes read if this fails */)) |
|---|
| 199 | { |
|---|
| 200 | THROW_FILE_ERROR("Failed to read store info header", |
|---|
| 201 | fn, BackupStoreException, CouldNotLoadStoreInfo); |
|---|
| 202 | } |
|---|
| 203 | |
|---|
| 204 | // Check it |
|---|
| 205 | if((int32_t)ntohl(hdr.mAccountID) != AccountID) |
|---|
| 206 | { |
|---|
| 207 | THROW_FILE_ERROR("Found wrong account ID in store info", |
|---|
| 208 | fn, BackupStoreException, BadStoreInfoOnLoad); |
|---|
| 209 | } |
|---|
| 210 | |
|---|
| 211 | // Insert info from file |
|---|
| 212 | info->mClientStoreMarker = box_ntoh64(hdr.mClientStoreMarker); |
|---|
| 213 | info->mLastObjectIDUsed = box_ntoh64(hdr.mLastObjectIDUsed); |
|---|
| 214 | info->mBlocksUsed = box_ntoh64(hdr.mBlocksUsed); |
|---|
| 215 | info->mBlocksInOldFiles = box_ntoh64(hdr.mBlocksInOldFiles); |
|---|
| 216 | info->mBlocksInDeletedFiles = box_ntoh64(hdr.mBlocksInDeletedFiles); |
|---|
| 217 | info->mBlocksInDirectories = box_ntoh64(hdr.mBlocksInDirectories); |
|---|
| 218 | info->mBlocksSoftLimit = box_ntoh64(hdr.mBlocksSoftLimit); |
|---|
| 219 | info->mBlocksHardLimit = box_ntoh64(hdr.mBlocksHardLimit); |
|---|
| 220 | |
|---|
| 221 | // Load up array of deleted objects |
|---|
| 222 | numDelObj = box_ntoh64(hdr.mNumberDeletedDirectories); |
|---|
| 223 | } |
|---|
| 224 | else if(v2) |
|---|
| 225 | { |
|---|
| 226 | Archive archive(*rf, IOStream::TimeOutInfinite); |
|---|
| 227 | |
|---|
| 228 | // Check it |
|---|
| 229 | int32_t FileAccountID; |
|---|
| 230 | archive.Read(FileAccountID); |
|---|
| 231 | if (FileAccountID != AccountID) |
|---|
| 232 | { |
|---|
| 233 | THROW_FILE_ERROR("Found wrong account ID in store " |
|---|
| 234 | "info: " << BOX_FORMAT_HEX32(FileAccountID), |
|---|
| 235 | fn, BackupStoreException, BadStoreInfoOnLoad); |
|---|
| 236 | } |
|---|
| 237 | |
|---|
| 238 | archive.Read(info->mAccountName); |
|---|
| 239 | archive.Read(info->mClientStoreMarker); |
|---|
| 240 | archive.Read(info->mLastObjectIDUsed); |
|---|
| 241 | archive.Read(info->mBlocksUsed); |
|---|
| 242 | archive.Read(info->mBlocksInCurrentFiles); |
|---|
| 243 | archive.Read(info->mBlocksInOldFiles); |
|---|
| 244 | archive.Read(info->mBlocksInDeletedFiles); |
|---|
| 245 | archive.Read(info->mBlocksInDirectories); |
|---|
| 246 | archive.Read(info->mBlocksSoftLimit); |
|---|
| 247 | archive.Read(info->mBlocksHardLimit); |
|---|
| 248 | archive.Read(info->mNumFiles); |
|---|
| 249 | archive.Read(info->mNumOldFiles); |
|---|
| 250 | archive.Read(info->mNumDeletedFiles); |
|---|
| 251 | archive.Read(info->mNumDirectories); |
|---|
| 252 | archive.Read(numDelObj); |
|---|
| 253 | } |
|---|
| 254 | |
|---|
| 255 | // Then load them in |
|---|
| 256 | if(numDelObj > 0) |
|---|
| 257 | { |
|---|
| 258 | int64_t objs[NUM_DELETED_DIRS_BLOCK]; |
|---|
| 259 | |
|---|
| 260 | int64_t toload = numDelObj; |
|---|
| 261 | while(toload > 0) |
|---|
| 262 | { |
|---|
| 263 | // How many in this one? |
|---|
| 264 | int b = (toload > NUM_DELETED_DIRS_BLOCK)?NUM_DELETED_DIRS_BLOCK:((int)(toload)); |
|---|
| 265 | |
|---|
| 266 | if(!rf->ReadFullBuffer(objs, b * sizeof(int64_t), 0 /* not interested in bytes read if this fails */)) |
|---|
| 267 | { |
|---|
| 268 | THROW_EXCEPTION(BackupStoreException, CouldNotLoadStoreInfo) |
|---|
| 269 | } |
|---|
| 270 | |
|---|
| 271 | // Add them |
|---|
| 272 | for(int t = 0; t < b; ++t) |
|---|
| 273 | { |
|---|
| 274 | info->mDeletedDirectories.push_back(box_ntoh64(objs[t])); |
|---|
| 275 | } |
|---|
| 276 | |
|---|
| 277 | // Number loaded |
|---|
| 278 | toload -= b; |
|---|
| 279 | } |
|---|
| 280 | } |
|---|
| 281 | |
|---|
| 282 | // Final check |
|---|
| 283 | if(static_cast<int64_t>(info->mDeletedDirectories.size()) != numDelObj) |
|---|
| 284 | { |
|---|
| 285 | THROW_EXCEPTION(BackupStoreException, BadStoreInfoOnLoad) |
|---|
| 286 | } |
|---|
| 287 | |
|---|
| 288 | // return it to caller |
|---|
| 289 | return info; |
|---|
| 290 | } |
|---|
| 291 | |
|---|
| 292 | |
|---|
| 293 | // -------------------------------------------------------------------------- |
|---|
| 294 | // |
|---|
| 295 | // Function |
|---|
| 296 | // Name: BackupStoreInfo::CreateForRegeneration(...) |
|---|
| 297 | // Purpose: Return an object which can be used to save for regeneration. |
|---|
| 298 | // Created: 23/4/04 |
|---|
| 299 | // |
|---|
| 300 | // -------------------------------------------------------------------------- |
|---|
| 301 | std::auto_ptr<BackupStoreInfo> BackupStoreInfo::CreateForRegeneration( |
|---|
| 302 | int32_t AccountID, const std::string& rAccountName, |
|---|
| 303 | const std::string &rRootDir, int DiscSet, |
|---|
| 304 | int64_t LastObjectID, int64_t BlocksUsed, |
|---|
| 305 | int64_t BlocksInCurrentFiles, int64_t BlocksInOldFiles, |
|---|
| 306 | int64_t BlocksInDeletedFiles, int64_t BlocksInDirectories, |
|---|
| 307 | int64_t BlockSoftLimit, int64_t BlockHardLimit) |
|---|
| 308 | { |
|---|
| 309 | // Generate the filename |
|---|
| 310 | std::string fn(rRootDir + INFO_FILENAME); |
|---|
| 311 | |
|---|
| 312 | // Make new object |
|---|
| 313 | std::auto_ptr<BackupStoreInfo> info(new BackupStoreInfo); |
|---|
| 314 | |
|---|
| 315 | // Put in basic info |
|---|
| 316 | info->mAccountID = AccountID; |
|---|
| 317 | info->mAccountName = rAccountName; |
|---|
| 318 | info->mDiscSet = DiscSet; |
|---|
| 319 | info->mFilename = fn; |
|---|
| 320 | info->mReadOnly = false; |
|---|
| 321 | |
|---|
| 322 | // Insert info starting info |
|---|
| 323 | info->mClientStoreMarker = 0; |
|---|
| 324 | info->mLastObjectIDUsed = LastObjectID; |
|---|
| 325 | info->mBlocksUsed = BlocksUsed; |
|---|
| 326 | info->mBlocksInCurrentFiles = BlocksInCurrentFiles; |
|---|
| 327 | info->mBlocksInOldFiles = BlocksInOldFiles; |
|---|
| 328 | info->mBlocksInDeletedFiles = BlocksInDeletedFiles; |
|---|
| 329 | info->mBlocksInDirectories = BlocksInDirectories; |
|---|
| 330 | info->mBlocksSoftLimit = BlockSoftLimit; |
|---|
| 331 | info->mBlocksHardLimit = BlockHardLimit; |
|---|
| 332 | |
|---|
| 333 | // return it to caller |
|---|
| 334 | return info; |
|---|
| 335 | } |
|---|
| 336 | |
|---|
| 337 | |
|---|
| 338 | // -------------------------------------------------------------------------- |
|---|
| 339 | // |
|---|
| 340 | // Function |
|---|
| 341 | // Name: BackupStoreInfo::Save(bool allowOverwrite) |
|---|
| 342 | // Purpose: Save modified info back to disc |
|---|
| 343 | // Created: 2003/08/28 |
|---|
| 344 | // |
|---|
| 345 | // -------------------------------------------------------------------------- |
|---|
| 346 | void BackupStoreInfo::Save(bool allowOverwrite) |
|---|
| 347 | { |
|---|
| 348 | // Make sure we're initialised (although should never come to this) |
|---|
| 349 | if(mFilename.empty() || mAccountID == -1 || mDiscSet == -1) |
|---|
| 350 | { |
|---|
| 351 | THROW_EXCEPTION(BackupStoreException, Internal) |
|---|
| 352 | } |
|---|
| 353 | |
|---|
| 354 | // Can we do this? |
|---|
| 355 | if(mReadOnly) |
|---|
| 356 | { |
|---|
| 357 | THROW_EXCEPTION(BackupStoreException, StoreInfoIsReadOnly) |
|---|
| 358 | } |
|---|
| 359 | |
|---|
| 360 | // Then... open a write file |
|---|
| 361 | RaidFileWrite rf(mDiscSet, mFilename); |
|---|
| 362 | rf.Open(allowOverwrite); |
|---|
| 363 | |
|---|
| 364 | // Make header |
|---|
| 365 | int32_t magic = htonl(INFO_MAGIC_VALUE_2); |
|---|
| 366 | rf.Write(&magic, sizeof(magic)); |
|---|
| 367 | Archive archive(rf, IOStream::TimeOutInfinite); |
|---|
| 368 | |
|---|
| 369 | archive.Write(mAccountID); |
|---|
| 370 | archive.Write(mAccountName); |
|---|
| 371 | archive.Write(mClientStoreMarker); |
|---|
| 372 | archive.Write(mLastObjectIDUsed); |
|---|
| 373 | archive.Write(mBlocksUsed); |
|---|
| 374 | archive.Write(mBlocksInCurrentFiles); |
|---|
| 375 | archive.Write(mBlocksInOldFiles); |
|---|
| 376 | archive.Write(mBlocksInDeletedFiles); |
|---|
| 377 | archive.Write(mBlocksInDirectories); |
|---|
| 378 | archive.Write(mBlocksSoftLimit); |
|---|
| 379 | archive.Write(mBlocksHardLimit); |
|---|
| 380 | archive.Write(mNumFiles); |
|---|
| 381 | archive.Write(mNumOldFiles); |
|---|
| 382 | archive.Write(mNumDeletedFiles); |
|---|
| 383 | archive.Write(mNumDirectories); |
|---|
| 384 | |
|---|
| 385 | int64_t numDelObj = mDeletedDirectories.size(); |
|---|
| 386 | archive.Write(numDelObj); |
|---|
| 387 | |
|---|
| 388 | // Write the deleted object list |
|---|
| 389 | if(mDeletedDirectories.size() > 0) |
|---|
| 390 | { |
|---|
| 391 | int64_t objs[NUM_DELETED_DIRS_BLOCK]; |
|---|
| 392 | |
|---|
| 393 | int tosave = mDeletedDirectories.size(); |
|---|
| 394 | std::vector<int64_t>::iterator i(mDeletedDirectories.begin()); |
|---|
| 395 | while(tosave > 0) |
|---|
| 396 | { |
|---|
| 397 | // How many in this one? |
|---|
| 398 | int b = (tosave > NUM_DELETED_DIRS_BLOCK)?NUM_DELETED_DIRS_BLOCK:((int)(tosave)); |
|---|
| 399 | |
|---|
| 400 | // Add them |
|---|
| 401 | for(int t = 0; t < b; ++t) |
|---|
| 402 | { |
|---|
| 403 | ASSERT(i != mDeletedDirectories.end()); |
|---|
| 404 | objs[t] = box_hton64((*i)); |
|---|
| 405 | i++; |
|---|
| 406 | } |
|---|
| 407 | |
|---|
| 408 | // Write |
|---|
| 409 | rf.Write(objs, b * sizeof(int64_t)); |
|---|
| 410 | |
|---|
| 411 | // Number saved |
|---|
| 412 | tosave -= b; |
|---|
| 413 | } |
|---|
| 414 | } |
|---|
| 415 | |
|---|
| 416 | // Commit it to disc, converting it to RAID now |
|---|
| 417 | rf.Commit(true); |
|---|
| 418 | |
|---|
| 419 | // Mark is as not modified |
|---|
| 420 | mIsModified = false; |
|---|
| 421 | } |
|---|
| 422 | |
|---|
| 423 | int BackupStoreInfo::ReportChangesTo(BackupStoreInfo& rOldInfo) |
|---|
| 424 | { |
|---|
| 425 | int numChanges = 0; |
|---|
| 426 | |
|---|
| 427 | #define COMPARE(attribute) \ |
|---|
| 428 | if (rOldInfo.Get ## attribute () != Get ## attribute ()) \ |
|---|
| 429 | { \ |
|---|
| 430 | BOX_WARNING(#attribute " changed from " << \ |
|---|
| 431 | rOldInfo.Get ## attribute () << " to " << \ |
|---|
| 432 | Get ## attribute ()); \ |
|---|
| 433 | numChanges++; \ |
|---|
| 434 | } |
|---|
| 435 | |
|---|
| 436 | COMPARE(AccountID); |
|---|
| 437 | COMPARE(AccountName); |
|---|
| 438 | COMPARE(LastObjectIDUsed); |
|---|
| 439 | COMPARE(BlocksUsed); |
|---|
| 440 | COMPARE(BlocksInCurrentFiles); |
|---|
| 441 | COMPARE(BlocksInOldFiles); |
|---|
| 442 | COMPARE(BlocksInDeletedFiles); |
|---|
| 443 | COMPARE(BlocksInDirectories); |
|---|
| 444 | COMPARE(BlocksSoftLimit); |
|---|
| 445 | COMPARE(BlocksHardLimit); |
|---|
| 446 | COMPARE(NumFiles); |
|---|
| 447 | COMPARE(NumOldFiles); |
|---|
| 448 | COMPARE(NumDeletedFiles); |
|---|
| 449 | COMPARE(NumDirectories); |
|---|
| 450 | |
|---|
| 451 | #undef COMPARE |
|---|
| 452 | |
|---|
| 453 | return numChanges; |
|---|
| 454 | } |
|---|
| 455 | |
|---|
| 456 | #define APPLY_DELTA(field, delta) \ |
|---|
| 457 | if(mReadOnly) \ |
|---|
| 458 | { \ |
|---|
| 459 | THROW_EXCEPTION(BackupStoreException, StoreInfoIsReadOnly) \ |
|---|
| 460 | } \ |
|---|
| 461 | \ |
|---|
| 462 | if((field + delta) < 0) \ |
|---|
| 463 | { \ |
|---|
| 464 | THROW_EXCEPTION_MESSAGE(BackupStoreException, \ |
|---|
| 465 | StoreInfoBlockDeltaMakesValueNegative, \ |
|---|
| 466 | "Failed to reduce " << #field << " from " << \ |
|---|
| 467 | field << " by " << delta); \ |
|---|
| 468 | } \ |
|---|
| 469 | \ |
|---|
| 470 | field += delta; \ |
|---|
| 471 | mIsModified = true; |
|---|
| 472 | |
|---|
| 473 | // -------------------------------------------------------------------------- |
|---|
| 474 | // |
|---|
| 475 | // Function |
|---|
| 476 | // Name: BackupStoreInfo::ChangeBlocksUsed(int32_t) |
|---|
| 477 | // Purpose: Change number of blocks used, by a delta amount |
|---|
| 478 | // Created: 2003/08/28 |
|---|
| 479 | // |
|---|
| 480 | // -------------------------------------------------------------------------- |
|---|
| 481 | void BackupStoreInfo::ChangeBlocksUsed(int64_t Delta) |
|---|
| 482 | { |
|---|
| 483 | APPLY_DELTA(mBlocksUsed, Delta); |
|---|
| 484 | } |
|---|
| 485 | |
|---|
| 486 | // -------------------------------------------------------------------------- |
|---|
| 487 | // |
|---|
| 488 | // Function |
|---|
| 489 | // Name: BackupStoreInfo::ChangeBlocksInCurrentFiles(int32_t) |
|---|
| 490 | // Purpose: Change number of blocks in current files, by a delta |
|---|
| 491 | // amount |
|---|
| 492 | // Created: 2010/08/26 |
|---|
| 493 | // |
|---|
| 494 | // -------------------------------------------------------------------------- |
|---|
| 495 | void BackupStoreInfo::ChangeBlocksInCurrentFiles(int64_t Delta) |
|---|
| 496 | { |
|---|
| 497 | APPLY_DELTA(mBlocksInCurrentFiles, Delta); |
|---|
| 498 | } |
|---|
| 499 | |
|---|
| 500 | // -------------------------------------------------------------------------- |
|---|
| 501 | // |
|---|
| 502 | // Function |
|---|
| 503 | // Name: BackupStoreInfo::ChangeBlocksInOldFiles(int32_t) |
|---|
| 504 | // Purpose: Change number of blocks in old files, by a delta amount |
|---|
| 505 | // Created: 2003/08/28 |
|---|
| 506 | // |
|---|
| 507 | // -------------------------------------------------------------------------- |
|---|
| 508 | void BackupStoreInfo::ChangeBlocksInOldFiles(int64_t Delta) |
|---|
| 509 | { |
|---|
| 510 | APPLY_DELTA(mBlocksInOldFiles, Delta); |
|---|
| 511 | } |
|---|
| 512 | |
|---|
| 513 | // -------------------------------------------------------------------------- |
|---|
| 514 | // |
|---|
| 515 | // Function |
|---|
| 516 | // Name: BackupStoreInfo::ChangeBlocksInDeletedFiles(int32_t) |
|---|
| 517 | // Purpose: Change number of blocks in deleted files, by a delta amount |
|---|
| 518 | // Created: 2003/08/28 |
|---|
| 519 | // |
|---|
| 520 | // -------------------------------------------------------------------------- |
|---|
| 521 | void BackupStoreInfo::ChangeBlocksInDeletedFiles(int64_t Delta) |
|---|
| 522 | { |
|---|
| 523 | APPLY_DELTA(mBlocksInDeletedFiles, Delta); |
|---|
| 524 | } |
|---|
| 525 | |
|---|
| 526 | // -------------------------------------------------------------------------- |
|---|
| 527 | // |
|---|
| 528 | // Function |
|---|
| 529 | // Name: BackupStoreInfo::ChangeBlocksInDirectories(int32_t) |
|---|
| 530 | // Purpose: Change number of blocks in directories, by a delta amount |
|---|
| 531 | // Created: 2003/08/28 |
|---|
| 532 | // |
|---|
| 533 | // -------------------------------------------------------------------------- |
|---|
| 534 | void BackupStoreInfo::ChangeBlocksInDirectories(int64_t Delta) |
|---|
| 535 | { |
|---|
| 536 | APPLY_DELTA(mBlocksInDirectories, Delta); |
|---|
| 537 | } |
|---|
| 538 | |
|---|
| 539 | void BackupStoreInfo::AdjustNumFiles(int64_t increase) |
|---|
| 540 | { |
|---|
| 541 | APPLY_DELTA(mNumFiles, increase); |
|---|
| 542 | } |
|---|
| 543 | |
|---|
| 544 | void BackupStoreInfo::AdjustNumOldFiles(int64_t increase) |
|---|
| 545 | { |
|---|
| 546 | APPLY_DELTA(mNumOldFiles, increase); |
|---|
| 547 | } |
|---|
| 548 | |
|---|
| 549 | void BackupStoreInfo::AdjustNumDeletedFiles(int64_t increase) |
|---|
| 550 | { |
|---|
| 551 | APPLY_DELTA(mNumDeletedFiles, increase); |
|---|
| 552 | } |
|---|
| 553 | |
|---|
| 554 | void BackupStoreInfo::AdjustNumDirectories(int64_t increase) |
|---|
| 555 | { |
|---|
| 556 | APPLY_DELTA(mNumDirectories, increase); |
|---|
| 557 | } |
|---|
| 558 | |
|---|
| 559 | // -------------------------------------------------------------------------- |
|---|
| 560 | // |
|---|
| 561 | // Function |
|---|
| 562 | // Name: BackupStoreInfo::CorrectAllUsedValues(int64_t, int64_t, int64_t, int64_t) |
|---|
| 563 | // Purpose: Set all the usage counts to specific values -- use for correcting in housekeeping |
|---|
| 564 | // if something when wrong during the backup connection, and the store info wasn't |
|---|
| 565 | // saved back to disc. |
|---|
| 566 | // Created: 15/12/03 |
|---|
| 567 | // |
|---|
| 568 | // -------------------------------------------------------------------------- |
|---|
| 569 | void BackupStoreInfo::CorrectAllUsedValues(int64_t Used, int64_t InOldFiles, int64_t InDeletedFiles, int64_t InDirectories) |
|---|
| 570 | { |
|---|
| 571 | if(mReadOnly) |
|---|
| 572 | { |
|---|
| 573 | THROW_EXCEPTION(BackupStoreException, StoreInfoIsReadOnly) |
|---|
| 574 | } |
|---|
| 575 | |
|---|
| 576 | // Set the values |
|---|
| 577 | mBlocksUsed = Used; |
|---|
| 578 | mBlocksInOldFiles = InOldFiles; |
|---|
| 579 | mBlocksInDeletedFiles = InDeletedFiles; |
|---|
| 580 | mBlocksInDirectories = InDirectories; |
|---|
| 581 | |
|---|
| 582 | mIsModified = true; |
|---|
| 583 | } |
|---|
| 584 | |
|---|
| 585 | |
|---|
| 586 | // -------------------------------------------------------------------------- |
|---|
| 587 | // |
|---|
| 588 | // Function |
|---|
| 589 | // Name: BackupStoreInfo::AddDeletedDirectory(int64_t) |
|---|
| 590 | // Purpose: Add a directory ID to the deleted list |
|---|
| 591 | // Created: 2003/08/28 |
|---|
| 592 | // |
|---|
| 593 | // -------------------------------------------------------------------------- |
|---|
| 594 | void BackupStoreInfo::AddDeletedDirectory(int64_t DirID) |
|---|
| 595 | { |
|---|
| 596 | if(mReadOnly) |
|---|
| 597 | { |
|---|
| 598 | THROW_EXCEPTION(BackupStoreException, StoreInfoIsReadOnly) |
|---|
| 599 | } |
|---|
| 600 | |
|---|
| 601 | mDeletedDirectories.push_back(DirID); |
|---|
| 602 | |
|---|
| 603 | mIsModified = true; |
|---|
| 604 | } |
|---|
| 605 | |
|---|
| 606 | // -------------------------------------------------------------------------- |
|---|
| 607 | // |
|---|
| 608 | // Function |
|---|
| 609 | // Name: BackupStoreInfo::RemovedDeletedDirectory(int64_t) |
|---|
| 610 | // Purpose: Remove a directory from the deleted list |
|---|
| 611 | // Created: 2003/08/28 |
|---|
| 612 | // |
|---|
| 613 | // -------------------------------------------------------------------------- |
|---|
| 614 | void BackupStoreInfo::RemovedDeletedDirectory(int64_t DirID) |
|---|
| 615 | { |
|---|
| 616 | if(mReadOnly) |
|---|
| 617 | { |
|---|
| 618 | THROW_EXCEPTION(BackupStoreException, StoreInfoIsReadOnly) |
|---|
| 619 | } |
|---|
| 620 | |
|---|
| 621 | std::vector<int64_t>::iterator i(std::find(mDeletedDirectories.begin(), mDeletedDirectories.end(), DirID)); |
|---|
| 622 | if(i == mDeletedDirectories.end()) |
|---|
| 623 | { |
|---|
| 624 | THROW_EXCEPTION(BackupStoreException, StoreInfoDirNotInList) |
|---|
| 625 | } |
|---|
| 626 | mDeletedDirectories.erase(i); |
|---|
| 627 | |
|---|
| 628 | mIsModified = true; |
|---|
| 629 | } |
|---|
| 630 | |
|---|
| 631 | // -------------------------------------------------------------------------- |
|---|
| 632 | // |
|---|
| 633 | // Function |
|---|
| 634 | // Name: BackupStoreInfo::ChangeLimits(int64_t, int64_t) |
|---|
| 635 | // Purpose: Change the soft and hard limits |
|---|
| 636 | // Created: 15/12/03 |
|---|
| 637 | // |
|---|
| 638 | // -------------------------------------------------------------------------- |
|---|
| 639 | void BackupStoreInfo::ChangeLimits(int64_t BlockSoftLimit, int64_t BlockHardLimit) |
|---|
| 640 | { |
|---|
| 641 | if(mReadOnly) |
|---|
| 642 | { |
|---|
| 643 | THROW_EXCEPTION(BackupStoreException, StoreInfoIsReadOnly) |
|---|
| 644 | } |
|---|
| 645 | |
|---|
| 646 | mBlocksSoftLimit = BlockSoftLimit; |
|---|
| 647 | mBlocksHardLimit = BlockHardLimit; |
|---|
| 648 | |
|---|
| 649 | mIsModified = true; |
|---|
| 650 | } |
|---|
| 651 | |
|---|
| 652 | |
|---|
| 653 | // -------------------------------------------------------------------------- |
|---|
| 654 | // |
|---|
| 655 | // Function |
|---|
| 656 | // Name: BackupStoreInfo::AllocateObjectID() |
|---|
| 657 | // Purpose: Allocate an ID for a new object in the store. |
|---|
| 658 | // Created: 2003/09/03 |
|---|
| 659 | // |
|---|
| 660 | // -------------------------------------------------------------------------- |
|---|
| 661 | int64_t BackupStoreInfo::AllocateObjectID() |
|---|
| 662 | { |
|---|
| 663 | if(mReadOnly) |
|---|
| 664 | { |
|---|
| 665 | THROW_EXCEPTION(BackupStoreException, StoreInfoIsReadOnly) |
|---|
| 666 | } |
|---|
| 667 | if(mLastObjectIDUsed < 0) |
|---|
| 668 | { |
|---|
| 669 | THROW_EXCEPTION(BackupStoreException, StoreInfoNotInitialised) |
|---|
| 670 | } |
|---|
| 671 | |
|---|
| 672 | // Return the next object ID |
|---|
| 673 | return ++mLastObjectIDUsed; |
|---|
| 674 | |
|---|
| 675 | mIsModified = true; |
|---|
| 676 | } |
|---|
| 677 | |
|---|
| 678 | |
|---|
| 679 | |
|---|
| 680 | // -------------------------------------------------------------------------- |
|---|
| 681 | // |
|---|
| 682 | // Function |
|---|
| 683 | // Name: BackupStoreInfo::SetClientStoreMarker(int64_t) |
|---|
| 684 | // Purpose: Sets the client store marker |
|---|
| 685 | // Created: 2003/10/29 |
|---|
| 686 | // |
|---|
| 687 | // -------------------------------------------------------------------------- |
|---|
| 688 | void BackupStoreInfo::SetClientStoreMarker(int64_t ClientStoreMarker) |
|---|
| 689 | { |
|---|
| 690 | if(mReadOnly) |
|---|
| 691 | { |
|---|
| 692 | THROW_EXCEPTION(BackupStoreException, StoreInfoIsReadOnly) |
|---|
| 693 | } |
|---|
| 694 | |
|---|
| 695 | mClientStoreMarker = ClientStoreMarker; |
|---|
| 696 | |
|---|
| 697 | mIsModified = true; |
|---|
| 698 | } |
|---|
| 699 | |
|---|
| 700 | |
|---|
| 701 | // -------------------------------------------------------------------------- |
|---|
| 702 | // |
|---|
| 703 | // Function |
|---|
| 704 | // Name: BackupStoreInfo::SetAccountName(const std::string&) |
|---|
| 705 | // Purpose: Sets the account name |
|---|
| 706 | // Created: 2008/08/22 |
|---|
| 707 | // |
|---|
| 708 | // -------------------------------------------------------------------------- |
|---|
| 709 | void BackupStoreInfo::SetAccountName(const std::string& rName) |
|---|
| 710 | { |
|---|
| 711 | if(mReadOnly) |
|---|
| 712 | { |
|---|
| 713 | THROW_EXCEPTION(BackupStoreException, StoreInfoIsReadOnly) |
|---|
| 714 | } |
|---|
| 715 | |
|---|
| 716 | mAccountName = rName; |
|---|
| 717 | |
|---|
| 718 | mIsModified = true; |
|---|
| 719 | } |
|---|
| 720 | |
|---|
| 721 | |
|---|