summaryrefslogtreecommitdiff
path: root/lib/backupclient/BackupStoreFileCmbDiff.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/backupclient/BackupStoreFileCmbDiff.cpp')
-rw-r--r--lib/backupclient/BackupStoreFileCmbDiff.cpp326
1 files changed, 0 insertions, 326 deletions
diff --git a/lib/backupclient/BackupStoreFileCmbDiff.cpp b/lib/backupclient/BackupStoreFileCmbDiff.cpp
deleted file mode 100644
index 1a88fa3f..00000000
--- a/lib/backupclient/BackupStoreFileCmbDiff.cpp
+++ /dev/null
@@ -1,326 +0,0 @@
-// --------------------------------------------------------------------------
-//
-// File
-// Name: BackupStoreFileCmbDiff.cpp
-// Purpose: Combine two diffs together
-// Created: 12/7/04
-//
-// --------------------------------------------------------------------------
-
-#include "Box.h"
-
-#include <new>
-#include <stdlib.h>
-
-#include "BackupStoreFile.h"
-#include "BackupStoreFileWire.h"
-#include "BackupStoreObjectMagic.h"
-#include "BackupStoreException.h"
-#include "BackupStoreConstants.h"
-#include "BackupStoreFilename.h"
-
-#include "MemLeakFindOn.h"
-
-// --------------------------------------------------------------------------
-//
-// Function
-// Name: BackupStoreFile::CombineDiffs(IOStream &, IOStream &, IOStream &rOut)
-// Purpose: Given two diffs, combine them into a single diff, to produce a diff
-// which, combined with the original file, creates the result of applying
-// rDiff, then rDiff2. Two opens of rDiff2 are required
-// Created: 12/7/04
-//
-// --------------------------------------------------------------------------
-void BackupStoreFile::CombineDiffs(IOStream &rDiff1, IOStream &rDiff2, IOStream &rDiff2b, IOStream &rOut)
-{
- // Skip header of first diff, record where the data starts, and skip to the index
- int64_t diff1DataStarts = 0;
- {
- // Read the header for the From file
- file_StreamFormat diff1Hdr;
- if(!rDiff1.ReadFullBuffer(&diff1Hdr, sizeof(diff1Hdr), 0))
- {
- THROW_EXCEPTION(BackupStoreException, FailedToReadBlockOnCombine)
- }
- if(ntohl(diff1Hdr.mMagicValue) != OBJECTMAGIC_FILE_MAGIC_VALUE_V1)
- {
- THROW_EXCEPTION(BackupStoreException, BadBackupStoreFile)
- }
- // Skip over the filename and attributes of the From file
- // BLOCK
- {
- BackupStoreFilename filename2;
- filename2.ReadFromStream(rDiff1, IOStream::TimeOutInfinite);
- int32_t size_s;
- if(!rDiff1.ReadFullBuffer(&size_s, sizeof(size_s), 0 /* not interested in bytes read if this fails */))
- {
- THROW_EXCEPTION(CommonException, StreamableMemBlockIncompleteRead)
- }
- int size = ntohl(size_s);
- // Skip forward the size
- rDiff1.Seek(size, IOStream::SeekType_Relative);
- }
- // Record position
- diff1DataStarts = rDiff1.GetPosition();
- // Skip to index
- rDiff1.Seek(0 - (((box_ntoh64(diff1Hdr.mNumBlocks)) * sizeof(file_BlockIndexEntry)) + sizeof(file_BlockIndexHeader)), IOStream::SeekType_End);
- }
-
- // Read the index of the first diff
- // Header first
- file_BlockIndexHeader diff1IdxHdr;
- if(!rDiff1.ReadFullBuffer(&diff1IdxHdr, sizeof(diff1IdxHdr), 0))
- {
- THROW_EXCEPTION(BackupStoreException, CouldntReadEntireStructureFromStream)
- }
- if(ntohl(diff1IdxHdr.mMagicValue) != OBJECTMAGIC_FILE_BLOCKS_MAGIC_VALUE_V1)
- {
- THROW_EXCEPTION(BackupStoreException, BadBackupStoreFile)
- }
- int64_t diff1NumBlocks = box_ntoh64(diff1IdxHdr.mNumBlocks);
- // Allocate some memory
- int64_t *diff1BlockStartPositions = (int64_t*)::malloc((diff1NumBlocks + 1) * sizeof(int64_t));
- if(diff1BlockStartPositions == 0)
- {
- throw std::bad_alloc();
- }
-
- // Buffer data
- void *buffer = 0;
- int bufferSize = 0;
-
- try
- {
- // Then the entries:
- // For each entry, want to know if it's in the file, and if so, how big it is.
- // We'll store this as an array of file positions in the file, with an additioal
- // entry on the end so that we can work out the length of the last block.
- // If an entry isn't in the file, then store 0 - (position in other file).
- int64_t diff1Position = diff1DataStarts;
- for(int64_t b = 0; b < diff1NumBlocks; ++b)
- {
- file_BlockIndexEntry e;
- if(!rDiff1.ReadFullBuffer(&e, sizeof(e), 0))
- {
- THROW_EXCEPTION(BackupStoreException, CouldntReadEntireStructureFromStream)
- }
-
- // Where's the block?
- int64_t blockEn = box_ntoh64(e.mEncodedSize);
- if(blockEn <= 0)
- {
- // Just store the negated block number
- diff1BlockStartPositions[b] = blockEn;
- }
- else
- {
- // Block is present in this file
- diff1BlockStartPositions[b] = diff1Position;
- diff1Position += blockEn;
- }
- }
-
- // Finish off the list, so the last entry can have it's size calcuated.
- diff1BlockStartPositions[diff1NumBlocks] = diff1Position;
-
- // Now read the second diff's header, copying it to the out file
- file_StreamFormat diff2Hdr;
- if(!rDiff2.ReadFullBuffer(&diff2Hdr, sizeof(diff2Hdr), 0))
- {
- THROW_EXCEPTION(BackupStoreException, FailedToReadBlockOnCombine)
- }
- if(ntohl(diff2Hdr.mMagicValue) != OBJECTMAGIC_FILE_MAGIC_VALUE_V1)
- {
- THROW_EXCEPTION(BackupStoreException, BadBackupStoreFile)
- }
- // Copy
- rOut.Write(&diff2Hdr, sizeof(diff2Hdr));
- // Copy over filename and attributes
- // BLOCK
- {
- BackupStoreFilename filename;
- filename.ReadFromStream(rDiff2, IOStream::TimeOutInfinite);
- filename.WriteToStream(rOut);
- StreamableMemBlock attr;
- attr.ReadFromStream(rDiff2, IOStream::TimeOutInfinite);
- attr.WriteToStream(rOut);
- }
-
- // Get to the index of rDiff2b, and read the header
- MoveStreamPositionToBlockIndex(rDiff2b);
- file_BlockIndexHeader diff2IdxHdr;
- if(!rDiff2b.ReadFullBuffer(&diff2IdxHdr, sizeof(diff2IdxHdr), 0))
- {
- THROW_EXCEPTION(BackupStoreException, CouldntReadEntireStructureFromStream)
- }
- if(ntohl(diff2IdxHdr.mMagicValue) != OBJECTMAGIC_FILE_BLOCKS_MAGIC_VALUE_V1)
- {
- THROW_EXCEPTION(BackupStoreException, BadBackupStoreFile)
- }
- int64_t diff2NumBlocks = box_ntoh64(diff2IdxHdr.mNumBlocks);
- int64_t diff2IndexEntriesStart = rDiff2b.GetPosition();
-
- // Then read all the entries
- int64_t diff2FilePosition = rDiff2.GetPosition();
- for(int64_t b = 0; b < diff2NumBlocks; ++b)
- {
- file_BlockIndexEntry e;
- if(!rDiff2b.ReadFullBuffer(&e, sizeof(e), 0))
- {
- THROW_EXCEPTION(BackupStoreException, CouldntReadEntireStructureFromStream)
- }
-
- // What do to next about copying data
- bool copyBlock = false;
- int copySize = 0;
- int64_t copyFrom = 0;
- bool fromFileDiff1 = false;
-
- // Where's the block?
- int64_t blockEn = box_ntoh64(e.mEncodedSize);
- if(blockEn > 0)
- {
- // Block is present in this file -- copy to out
- copyBlock = true;
- copyFrom = diff2FilePosition;
- copySize = (int)blockEn;
-
- // Move pointer onwards
- diff2FilePosition += blockEn;
- }
- else
- {
- // Block isn't present here -- is it present in the old one?
- int64_t blockIndex = 0 - blockEn;
- if(blockIndex < 0 || blockIndex > diff1NumBlocks)
- {
- THROW_EXCEPTION(BackupStoreException, BadBackupStoreFile)
- }
- if(diff1BlockStartPositions[blockIndex] > 0)
- {
- // Block is in the old diff file, copy it across
- copyBlock = true;
- copyFrom = diff1BlockStartPositions[blockIndex];
- int nb = blockIndex + 1;
- while(diff1BlockStartPositions[nb] <= 0)
- {
- // This is safe, because the last entry will terminate it properly!
- ++nb;
- ASSERT(nb <= diff1NumBlocks);
- }
- copySize = diff1BlockStartPositions[nb] - copyFrom;
- fromFileDiff1 = true;
- }
- }
- //TRACE4("%d %d %lld %d\n", copyBlock, copySize, copyFrom, fromFileDiff1);
-
- // Copy data to the output file?
- if(copyBlock)
- {
- // Allocate enough space
- if(bufferSize < copySize || buffer == 0)
- {
- // Free old block
- if(buffer != 0)
- {
- ::free(buffer);
- buffer = 0;
- bufferSize = 0;
- }
- // Allocate new block
- buffer = ::malloc(copySize);
- if(buffer == 0)
- {
- throw std::bad_alloc();
- }
- bufferSize = copySize;
- }
- ASSERT(bufferSize >= copySize);
-
- // Load in the data
- if(fromFileDiff1)
- {
- rDiff1.Seek(copyFrom, IOStream::SeekType_Absolute);
- if(!rDiff1.ReadFullBuffer(buffer, copySize, 0))
- {
- THROW_EXCEPTION(BackupStoreException, FailedToReadBlockOnCombine)
- }
- }
- else
- {
- rDiff2.Seek(copyFrom, IOStream::SeekType_Absolute);
- if(!rDiff2.ReadFullBuffer(buffer, copySize, 0))
- {
- THROW_EXCEPTION(BackupStoreException, FailedToReadBlockOnCombine)
- }
- }
- // Write out data
- rOut.Write(buffer, copySize);
- }
- }
-
- // Write the modified header
- diff2IdxHdr.mOtherFileID = diff1IdxHdr.mOtherFileID;
- rOut.Write(&diff2IdxHdr, sizeof(diff2IdxHdr));
-
- // Then we'll write out the index, reading the data again
- rDiff2b.Seek(diff2IndexEntriesStart, IOStream::SeekType_Absolute);
- for(int64_t b = 0; b < diff2NumBlocks; ++b)
- {
- file_BlockIndexEntry e;
- if(!rDiff2b.ReadFullBuffer(&e, sizeof(e), 0))
- {
- THROW_EXCEPTION(BackupStoreException, CouldntReadEntireStructureFromStream)
- }
-
- // Where's the block?
- int64_t blockEn = box_ntoh64(e.mEncodedSize);
-
- // If it's not in this file, it needs modification...
- if(blockEn <= 0)
- {
- int64_t blockIndex = 0 - blockEn;
- // In another file. Need to translate this against the other diff
- if(diff1BlockStartPositions[blockIndex] > 0)
- {
- // Block is in the first diff file, stick in size
- int nb = blockIndex + 1;
- while(diff1BlockStartPositions[nb] <= 0)
- {
- // This is safe, because the last entry will terminate it properly!
- ++nb;
- ASSERT(nb <= diff1NumBlocks);
- }
- int64_t size = diff1BlockStartPositions[nb] - diff1BlockStartPositions[blockIndex];
- e.mEncodedSize = box_hton64(size);
- }
- else
- {
- // Block in the original file, use translated value
- e.mEncodedSize = box_hton64(diff1BlockStartPositions[blockIndex]);
- }
- }
-
- // Write entry
- rOut.Write(&e, sizeof(e));
- }
- }
- catch(...)
- {
- // clean up
- ::free(diff1BlockStartPositions);
- if(buffer != 0)
- {
- ::free(buffer);
- }
- throw;
- }
-
- // Clean up allocated memory
- ::free(diff1BlockStartPositions);
- if(buffer != 0)
- {
- ::free(buffer);
- }
-}
-