00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef __PAR2REPAIRER_H__
00027 #define __PAR2REPAIRER_H__
00028
00029 #include
00030 #include "parheaders.h"
00031
00032 #if WANT_CONCURRENT
00033
00034 #include
00035
00036 struct u32_hasher {
00037 static size_t hash(u32 i) { return static_castsize_t> (i); }
00038 static bool equal( u32 x, u32 y ) { return x == y; }
00039 };
00040
00041 struct string_hasher {
00042 static size_t hash(const std::string& x) {
00043 size_t h = 0;
00044 for (const char* s = x.c_str(); *s; ++s)
00045 h = (h*17)^*s;
00046 return h;
00047 }
00048 static bool equal( const std::string& x, const std::string& y ) { return x == y; }
00049 };
00050
00051 struct istring_hasher {
00052 static size_t hash(const std::string& x) {
00053 size_t h = 0;
00054 for (const char* s = x.c_str(); *s; ++s)
00055 h = (h*17)^ tolower(*s);
00056 return h;
00057 }
00058 static bool equal( const std::string& x, const std::string& y )
00059 { return x.length() == y.length() && 0 == stricmp(x.c_str(), y.c_str()); }
00060 };
00061
00062 template typename T>
00063 struct atomic_ptr : tbb::atomic {
00064
00065 T operator->(void) { return tbb::atomic::operator typename tbb::atomic::value_type(); }
00066 atomic_ptr& operator=(T t) { tbb::atomic::operator=(t); return *this; }
00067 };
00068
00069 class ConcurrentDiskFileMap {
00070 public:
00071 #if defined(WIN32) || defined(__APPLE_CC__)
00072 typedef tbb::concurrent_hash_map map_type;
00073 #else
00074 typedef tbb::concurrent_hash_map map_type;
00075 #endif
00076 ConcurrentDiskFileMap(void) {}
00077 ~ConcurrentDiskFileMap(void) {
00078 map_type::iterator fi;
00079 for (fi = _diskfilemap.begin(); fi != _diskfilemap.end(); ++fi)
00080 delete (*fi).second;
00081 }
00082
00083 bool Insert(DiskFile *diskfile) {
00084 assert(!diskfile->FileName().empty());
00085 map_type::accessor a;
00086 (bool) _diskfilemap.insert(a, diskfile->FileName());
00087 a->second = diskfile;
00088 return true;
00089 }
00090 void Remove(DiskFile *diskfile) {
00091 assert(!diskfile->FileName().empty());
00092 (bool) _diskfilemap.erase(diskfile->FileName());
00093 }
00094 DiskFile* Find(string filename) const {
00095 assert(!filename.empty());
00096 map_type::const_accessor a;
00097 return _diskfilemap.find(a, filename) ? a->second : NULL;
00098 }
00099
00100 protected:
00101 map_type _diskfilemap;
00102 };
00103
00104 #endif
00105
00106 class Par2Repairer
00107 {
00108 public:
00109 Par2Repairer(void);
00110 ~Par2Repairer(void);
00111
00112 Result Process(const CommandLine &commandline, bool dorepair);
00113
00114 sigc::signal sig_filename;
00115 sigc::signal sig_progress;
00116 sigc::signal sig_headers;
00117 sigc::signal sig_done;
00118
00119 protected:
00120
00121
00122 #if WANT_CONCURRENT
00123 public:
00124 #if WANT_CONCURRENT_SOURCE_VERIFICATION
00125 void VerifyOneSourceFile(Par2RepairerSourceFile *sourcefile, bool& finalresult);
00126 #endif
00127 void ProcessDataForOutputIndex(u32 outputstartindex, u32 outputendindex, size_t blocklength, u32 inputindex);
00128 #endif
00129
00130 bool LoadPacketsFromFile(string filename);
00131 #if WANT_CONCURRENT
00132 protected:
00133 #endif
00134
00135 bool LoadRecoveryPacket(DiskFile *diskfile, u64 offset, PACKET_HEADER &header);
00136
00137 bool LoadDescriptionPacket(DiskFile *diskfile, u64 offset, PACKET_HEADER &header);
00138
00139 bool LoadVerificationPacket(DiskFile *diskfile, u64 offset, PACKET_HEADER &header);
00140
00141 bool LoadMainPacket(DiskFile *diskfile, u64 offset, PACKET_HEADER &header);
00142
00143 bool LoadCreatorPacket(DiskFile *diskfile, u64 offset, PACKET_HEADER &header);
00144
00145
00146 bool LoadPacketsFromOtherFiles(string filename);
00147
00148
00149 bool LoadPacketsFromExtraFiles(const list<:extrafile> &extrafiles);
00150
00151
00152 bool CheckPacketConsistency(void);
00153
00154
00155
00156 bool CreateSourceFileList(void);
00157
00158
00159
00160 bool AllocateSourceBlocks(void);
00161
00162
00163
00164
00165 bool PrepareVerificationHashTable(void);
00166
00167
00168 bool ComputeWindowTable(void);
00169
00170
00171 bool VerifySourceFiles(void);
00172
00173
00174 bool VerifyExtraFiles(const list<:extrafile> &extrafiles);
00175
00176
00177 bool VerifyDataFile(DiskFile *diskfile, Par2RepairerSourceFile *sourcefile);
00178
00179
00180
00181
00182
00183
00184 bool ScanDataFile(DiskFile *diskfile,
00185 Par2RepairerSourceFile* &sourcefile,
00186 MatchType &matchtype,
00187 MD5Hash &hashfull,
00188 MD5Hash &hash16k,
00189 u32 &count);
00190
00191
00192 void UpdateVerificationResults(void);
00193
00194
00195 bool CheckVerificationResults(void);
00196
00197
00198 bool RenameTargetFiles(void);
00199
00200
00201
00202 bool CreateTargetFiles(void);
00203
00204
00205
00206
00207 bool ComputeRSmatrix(void);
00208
00209
00210 bool AllocateBuffers(size_t memorylimit);
00211
00212
00213 bool ProcessData(u64 blockoffset, size_t blocklength);
00214
00215
00216 bool VerifyTargetFiles(void);
00217
00218
00219 bool DeleteIncompleteTargetFiles(void);
00220
00221 protected:
00222 ParHeaders* headers;
00223 CommandLine::NoiseLevel noiselevel;
00224
00225 string searchpath;
00226
00227 bool firstpacket;
00228 MD5Hash setid;
00229 #if WANT_CONCURRENT
00230 tbb::concurrent_hash_map recoverypacketmap;
00231 ::atomic_ptr mainpacket;
00232 ::atomic_ptr creatorpacket;
00233
00234 ConcurrentDiskFileMap diskFileMap;
00235 #else
00236 map recoverypacketmap;
00237 MainPacket *mainpacket;
00238 CreatorPacket *creatorpacket;
00239
00240 DiskFileMap diskFileMap;
00241 #endif
00242
00243 map sourcefilemap;
00244 vector sourcefiles;
00245 vector verifylist;
00246
00247 u64 blocksize;
00248 u64 chunksize;
00249 u32 sourceblockcount;
00250 u32 availableblockcount;
00251 u32 missingblockcount;
00252
00253 bool blocksallocated;
00254 vector sourceblocks;
00255 vector targetblocks;
00256
00257 u32 windowtable[256];
00258 u32 windowmask;
00259
00260 bool blockverifiable;
00261 VerificationHashTable verificationhashtable;
00262 list unverifiablesourcefiles;
00263
00264 u32 completefilecount;
00265 u32 renamedfilecount;
00266 u32 damagedfilecount;
00267 u32 missingfilecount;
00268
00269 vector inputblocks;
00270 vector copyblocks;
00271 vector outputblocks;
00272
00273 ReedSolomon rs;
00274
00275 void *inputbuffer;
00276 void *outputbuffer;
00277
00278 #if WANT_CONCURRENT
00279 tbb::atomic progress;
00280 #else
00281 u64 progress;
00282 #endif
00283 u64 totaldata;
00284 u64 totalsize;
00285
00286 #if WANT_CONCURRENT
00287 unsigned concurrent_processing_level;
00288 tbb::mutex cout_mutex;
00289 tbb::atomic cout_in_use;
00290 tbb::tick_count last_cout;
00291 #endif
00292 };
00293
00294 #endif // __PAR2REPAIRER_H__