Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // FileMerger.cpp : Defines the entry point for the console application.
- //
- #include "stdafx.h"
- #include "LineBuffer.h"
- using namespace FileMerger;
- char* FILES[] = {
- "All/amor_fa_.txt",
- "All/bertoldo.txt",
- "All/candid_t.txt",
- "All/convivio.txt",
- "All/dell_art.txt",
- "All/del_roma.txt",
- "All/del_tr_t.txt",
- "All/descartes_discorso_sul_metodo.txt",
- "All/de_vulga.txt",
- "All/dialogo_.txt",
- "All/diario_d.txt",
- "All/discorsi.txt",
- "All/don_chis.txt",
- "All/il_bugia.txt",
- "All/il_corsa.txt",
- "All/il_saggi.txt",
- "All/i_pirati.txt",
- "All/i_promes.txt",
- "All/la_banca.txt",
- "All/la_divin.txt",
- "All/la_ric_t.txt",
- "All/la_rivin.txt",
- "All/la_tigre.txt",
- "All/le_mecan.txt",
- "All/le_opere.txt",
- "All/le_tigri.txt",
- "All/l_adulat.txt",
- "All/l_amante.txt",
- "All/l_avaro.txt",
- "All/principe.txt",
- "All/sidereus.txt",
- "All/storia_d.txt",
- "All/sulla_or.txt" };
- #ifdef WIN32
- #define NOMINMAX
- #include <windows.h>
- #else
- //non mi ricordo
- #endif
- double currentTime()
- {
- double d;
- #ifdef WIN32
- __int64 freq, gTime;
- QueryPerformanceCounter((LARGE_INTEGER *)&gTime); // Get current count
- QueryPerformanceFrequency((LARGE_INTEGER *)&freq); // Get processor freq
- d = (double)(gTime)/(double)freq;
- #else
- struct timeval tv;
- gettimeofday(&tv, NULL );
- d = (double)tv.tv_usec/1000000 + (double)tv.tv_sec;
- #endif
- return d;
- }
- void merge( LineBuffer & input, FILE* output, size_t bytes )
- {
- DEBUG_ASSERT( output );
- DEBUG_ASSERT( !input.empty() );
- size_t written = 0, writtenToBuffer = 0;
- size_t bufferSize = input.getTotalSize() + input.size(); //total byte size + 1 byte for each \n
- char* buffer = (char*)malloc( bufferSize );
- int currentLine = 0;
- while( written < bytes )
- {
- char* ptr = buffer;
- size_t toWrite = min( bytes - written, bufferSize );
- input.shuffle(); //shuffle each time it's reused
- for( auto line : input )
- {
- memcpy( ptr, line.str, line.size );
- ptr += line.size;
- *ptr++ = '\n';
- if( ptr - buffer > toWrite ) //we can write a little more than toWrite, it's in the buffer anyway
- break;
- }
- fwrite( buffer, 1, toWrite, output );
- written += toWrite;
- }
- free( buffer );
- }
- inline bool isNumber( char c )
- {
- return c >= '0' && c <= '9';
- }
- string dostuff( int argc, char* argv[] )
- {
- if( argc < 2 )
- return "Il parametro opzionale -D serve per specificare\n"
- "la dimensione del file di output e va usato in questo modo:\n"
- "\n"
- "-D1MB crea un file di output della dimensione di 1 MB\n"
- "-D5MB crea un file di output della dimensione di 5 MB\n"
- "-D5GB crea un file di output della dimensione di 5 GB\n"
- "-D21GB crea un file di output della dimensione di 21 GB\n"
- "-D55GB crea un file di output della dimensione di 55 GB\n"
- "\n"
- "La dimensione minima del file di output dev'essere 1 MB\n"
- "La dimensione massima del file di output dev'essere 55 GB\n"
- "Se non viene specificato il parametro opzionale -D,\n"
- "il programma crea un file di output della dimensione di 1 MB\n"
- "\n"
- "Se non vengono rispettati i limiti di cui sopra, il programma\n"
- "emette un warning e termina immediatamente.\n"
- "Comunque, qualunque sia la dimensione specificata, il programma\n"
- "prima di proseguire controlla che ci sia sufficiente spazio libero\n"
- "su disco. Altrimenti avvisa ed esce.";
- //parse command line
- string outputPath = argv[1];
- string sizeStr = (argc > 2) ? argv[2] : "";
- size_t bytes = 1024*1024;
- if( !sizeStr.empty() )
- {
- //parse number
- bytes = 0;
- int digit = 1;
- for( int i = sizeStr.size() -1; i > 0; --i )
- {
- char c = sizeStr[i];
- if( isNumber( c ) )
- {
- bytes += (c - '0') * digit;
- digit *= 10;
- }
- }
- if( sizeStr.find( "GB") != string::npos )
- bytes *= 1024*1024*1024;
- else if( sizeStr.find( "MB" ) != string::npos )
- bytes *= 1024*1024;
- else if( sizeStr.find( "kB" ) != string::npos )
- bytes *= 1024;
- }
- double startTime = currentTime();
- LineBuffer buffer;
- //load files
- int prevLines = 0, prevSize = 0;
- for( char* path : FILES )
- buffer.addFile( path );
- if( buffer.empty() )
- return "Error: no lines loaded";
- cout << buffer.size() << " lines loaded in " << (currentTime() - startTime)*1000. << " ms" << endl;
- startTime = currentTime();
- //create output file
- FILE* outputFile = fopen( outputPath.c_str(), "w" );
- if( outputFile )
- {
- merge( buffer, outputFile, bytes );
- fclose( outputFile );
- cout << "created merged file in " << (currentTime() - startTime) << " ms" << endl;
- }
- else
- return "Error: can't create \"" + outputPath + "\"";
- return "Success!";
- }
- int main(int argc, char* argv[])
- {
- cout << dostuff( argc, argv ) << endl;
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement