Advertisement
Guest User

Untitled

a guest
Jan 14th, 2013
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.73 KB | None | 0 0
  1. // FileMerger.cpp : Defines the entry point for the console application.
  2. //
  3.  
  4. #include "stdafx.h"
  5.  
  6. #include "LineBuffer.h"
  7.  
  8. using namespace FileMerger;
  9.  
  10. char* FILES[] = {
  11. "All/amor_fa_.txt",
  12. "All/bertoldo.txt",
  13. "All/candid_t.txt",
  14. "All/convivio.txt",
  15. "All/dell_art.txt",
  16. "All/del_roma.txt",
  17. "All/del_tr_t.txt",
  18. "All/descartes_discorso_sul_metodo.txt",
  19. "All/de_vulga.txt",
  20. "All/dialogo_.txt",
  21. "All/diario_d.txt",
  22. "All/discorsi.txt",
  23. "All/don_chis.txt",
  24. "All/il_bugia.txt",
  25. "All/il_corsa.txt",
  26. "All/il_saggi.txt",
  27. "All/i_pirati.txt",
  28. "All/i_promes.txt",
  29. "All/la_banca.txt",
  30. "All/la_divin.txt",
  31. "All/la_ric_t.txt",
  32. "All/la_rivin.txt",
  33. "All/la_tigre.txt",
  34. "All/le_mecan.txt",
  35. "All/le_opere.txt",
  36. "All/le_tigri.txt",
  37. "All/l_adulat.txt",
  38. "All/l_amante.txt",
  39. "All/l_avaro.txt",
  40. "All/principe.txt",
  41. "All/sidereus.txt",
  42. "All/storia_d.txt",
  43. "All/sulla_or.txt" };
  44.  
  45. #ifdef WIN32
  46. #define NOMINMAX
  47. #include <windows.h>
  48. #else
  49. //non mi ricordo
  50. #endif
  51.  
  52. double currentTime()
  53. {
  54. double d;
  55. #ifdef WIN32
  56. __int64 freq, gTime;
  57. QueryPerformanceCounter((LARGE_INTEGER *)&gTime); // Get current count
  58. QueryPerformanceFrequency((LARGE_INTEGER *)&freq); // Get processor freq
  59. d = (double)(gTime)/(double)freq;
  60. #else
  61. struct timeval tv;
  62. gettimeofday(&tv, NULL );
  63. d = (double)tv.tv_usec/1000000 + (double)tv.tv_sec;
  64. #endif
  65. return d;
  66. }
  67.  
  68. void merge( LineBuffer & input, FILE* output, size_t bytes )
  69. {
  70. DEBUG_ASSERT( output );
  71. DEBUG_ASSERT( !input.empty() );
  72.  
  73. size_t written = 0, writtenToBuffer = 0;
  74.  
  75. size_t bufferSize = input.getTotalSize() + input.size(); //total byte size + 1 byte for each \n
  76. char* buffer = (char*)malloc( bufferSize );
  77.  
  78. int currentLine = 0;
  79.  
  80. while( written < bytes )
  81. {
  82. char* ptr = buffer;
  83. size_t toWrite = min( bytes - written, bufferSize );
  84.  
  85. input.shuffle(); //shuffle each time it's reused
  86.  
  87. for( auto line : input )
  88. {
  89. memcpy( ptr, line.str, line.size );
  90. ptr += line.size;
  91. *ptr++ = '\n';
  92.  
  93. if( ptr - buffer > toWrite ) //we can write a little more than toWrite, it's in the buffer anyway
  94. break;
  95. }
  96.  
  97. fwrite( buffer, 1, toWrite, output );
  98. written += toWrite;
  99. }
  100.  
  101. free( buffer );
  102. }
  103.  
  104. inline bool isNumber( char c )
  105. {
  106. return c >= '0' && c <= '9';
  107. }
  108.  
  109. string dostuff( int argc, char* argv[] )
  110. {
  111. if( argc < 2 )
  112. return "Il parametro opzionale -D serve per specificare\n"
  113. "la dimensione del file di output e va usato in questo modo:\n"
  114. "\n"
  115. "-D1MB crea un file di output della dimensione di 1 MB\n"
  116. "-D5MB crea un file di output della dimensione di 5 MB\n"
  117. "-D5GB crea un file di output della dimensione di 5 GB\n"
  118. "-D21GB crea un file di output della dimensione di 21 GB\n"
  119. "-D55GB crea un file di output della dimensione di 55 GB\n"
  120. "\n"
  121. "La dimensione minima del file di output dev'essere 1 MB\n"
  122. "La dimensione massima del file di output dev'essere 55 GB\n"
  123. "Se non viene specificato il parametro opzionale -D,\n"
  124. "il programma crea un file di output della dimensione di 1 MB\n"
  125. "\n"
  126. "Se non vengono rispettati i limiti di cui sopra, il programma\n"
  127. "emette un warning e termina immediatamente.\n"
  128. "Comunque, qualunque sia la dimensione specificata, il programma\n"
  129. "prima di proseguire controlla che ci sia sufficiente spazio libero\n"
  130. "su disco. Altrimenti avvisa ed esce.";
  131.  
  132. //parse command line
  133. string outputPath = argv[1];
  134. string sizeStr = (argc > 2) ? argv[2] : "";
  135. size_t bytes = 1024*1024;
  136.  
  137. if( !sizeStr.empty() )
  138. {
  139. //parse number
  140. bytes = 0;
  141. int digit = 1;
  142. for( int i = sizeStr.size() -1; i > 0; --i )
  143. {
  144. char c = sizeStr[i];
  145. if( isNumber( c ) )
  146. {
  147. bytes += (c - '0') * digit;
  148. digit *= 10;
  149. }
  150. }
  151.  
  152. if( sizeStr.find( "GB") != string::npos )
  153. bytes *= 1024*1024*1024;
  154. else if( sizeStr.find( "MB" ) != string::npos )
  155. bytes *= 1024*1024;
  156. else if( sizeStr.find( "kB" ) != string::npos )
  157. bytes *= 1024;
  158. }
  159.  
  160. double startTime = currentTime();
  161.  
  162. LineBuffer buffer;
  163.  
  164. //load files
  165. int prevLines = 0, prevSize = 0;
  166. for( char* path : FILES )
  167. buffer.addFile( path );
  168.  
  169. if( buffer.empty() )
  170. return "Error: no lines loaded";
  171.  
  172. cout << buffer.size() << " lines loaded in " << (currentTime() - startTime)*1000. << " ms" << endl;
  173.  
  174. startTime = currentTime();
  175.  
  176. //create output file
  177. FILE* outputFile = fopen( outputPath.c_str(), "w" );
  178.  
  179. if( outputFile )
  180. {
  181. merge( buffer, outputFile, bytes );
  182.  
  183. fclose( outputFile );
  184.  
  185. cout << "created merged file in " << (currentTime() - startTime) << " ms" << endl;
  186. }
  187. else
  188. return "Error: can't create \"" + outputPath + "\"";
  189.  
  190. return "Success!";
  191. }
  192.  
  193. int main(int argc, char* argv[])
  194. {
  195. cout << dostuff( argc, argv ) << endl;
  196. return 0;
  197. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement