using namespace std;
+static const unsigned int bytes_in_block = 0x800;
+
unsigned long long current_time() {
unsigned long long rc = 0;
time_t now_tt = time( 0 );
return rc;
}
-template<class I, class O>
-bool copy_until_full( I begin, I end, O out, unsigned long long &space ) {
- const unsigned long long block_size = 0x200ULL;
+template<class I, class O, class INT>
+bool copy_until_full( I begin, I end, O out, INT &space ) {
bool complete = true;
I i = begin;
while( 0 != space && i != end ) {
- unsigned long long size = (*i)->getFileSize();
- unsigned long long blocks = size & ( ~(block_size-1) );
- if( blocks < size ) blocks += block_size;
+ INT size = (*i)->getFileSize();
+ INT blocksize = blocks( size ) * bytes_in_block;
- if( blocks <= space ) {
- space -= blocks;
+ if( blocksize <= space ) {
+ space -= blocksize;
out = *i;
++out;
} else {
cmp );
}
+template<class INT>
+INT blocks( const INT &bytes ) {
+ INT numblocks = bytes / bytes_in_block;
+ if( 0 != bytes % bytes_in_block ) numblocks++;
+
+ return numblocks;
+}
+
+template<class ITER, class INT>
+void sizes( ITER begin, const ITER &end, INT &numblocks, INT &numbytes ) {
+ numblocks = 0;
+ numbytes = 0;
+
+ while( begin != end ) {
+ INT filesize = (*begin)->getFileSize();
+
+ numbytes += filesize;
+ numblocks += blocks( filesize );
+ begin++;
+ }
+}
+
int main() {
// Parse the list of current files on stdin
file_set current;
// Now find the list of files to backup.
file_set backups;
+ insert_iterator<file_set> backups_i( backups, backups.begin() );
// backup all added files
- copy( added.begin(), added.end(), inserter( backups, backups.begin() ) );
+ copy( added.begin(), added.end(), backups_i );
+
+ // Track the total size of added files
+ unsigned long long added_blocks, added_bytes;
+ sizes( backups.begin(), backups.end(), added_blocks, added_bytes );
+ file_vector modified_files;
// Backup files that have been modified
file_set::iterator i = common.begin(), j = old_common.begin();
for( ; i != common.end(); ++i, ++j ) {
(*i)->setLastBackupDate( (*j)->getLastBackupDate() );
- if( needs_backup( *j, *i ) ) backups.insert( *i );
+ if( needs_backup( *j, *i ) ) modified_files.push_back( *i );
}
+ copy( modified_files.begin(), modified_files.end(), backups_i );
+
+ // Track the total size of modified files
+ unsigned long long modified_blocks, modified_bytes;
+ sizes( modified_files.begin(), modified_files.end(), modified_blocks, modified_bytes );
+
// Now, sort the backups by filesize and build a list that'll fit on a DVD
file_vector backups_s;
copy( backups.begin(), backups.end(), back_inserter( backups_s ) );
final_i,
space );
+ // Track the size filled up by essential backups
+ unsigned long long essential_blocks, essential_bytes;
+ sizes( final.begin(), final.end(), essential_blocks, essential_bytes );
+
// Now, sort the non-backed-up list by last_backup_date and back-fill
if( 0 != space ) {
file_vector leftovers;
copy_until_full( leftovers.begin(), leftovers.end(), final_i, space );
}
+ // Track the total size to be copied to the dvd
+ unsigned long long total_blocks, total_bytes;
+ sizes( final.begin(), final.end(), total_blocks, total_bytes );
+
unsigned long long now = current_time();
for( file_set::iterator k = final.begin(); k != final.end(); ++k ) {
(*k)->setLastBackupDate( now );
// Write the 'final' list to stdout
copy( final.begin(), final.end(), ostream_iterator<FileData*>( cout, "" ) );
- if( ! complete ) { cerr << "incomplete" << endl; }
+ cerr << "Need backing up..." << endl;
+ cerr << " Added Bytes: " << added_bytes << endl;
+ cerr << " Added Blocks: " << added_blocks << endl;
+ cerr << " Modified Bytes: " << modified_bytes << endl;
+ cerr << " Modified Blocks: " << modified_blocks << endl << endl;
+
+ cerr << "Will be backed up..." << endl;
+ cerr << " Essential Bytes: " << essential_bytes << endl;
+ cerr << " Essential Blocks: " << essential_blocks << endl;
+ cerr << " Total Bytes: " << total_bytes << endl;
+ cerr << " Total Blocks: " << total_blocks << endl << endl;
+
+ if( ! complete ) { cerr << "Backup is incomplete!" << endl; }
// Clean-up
for( file_set::iterator i = backed_up.begin(); i != backed_up.end(); ++i ) { delete *i; }