--- a/reedsolomon.cpp +++ b/reedsolomon.cpp @@ -51,7 +51,7 @@ u32 gcd(u32 a, u32 b) } } -bool ReedSolomon::SetInput(const vector &present) +template<> bool ReedSolomon::SetInput(const vector &present) { inputcount = (u32)present.size(); @@ -80,7 +80,7 @@ bool ReedSolomon::SetInput(const vector &present) return true; } -bool ReedSolomon::SetInput(u32 count) +template<> bool ReedSolomon::SetInput(u32 count) { inputcount = count; @@ -101,15 +101,8 @@ bool ReedSolomon::SetInput(u32 count) return true; } -bool ReedSolomon::Process(size_t size, u32 inputindex, const void *inputbuffer, u32 outputindex, void *outputbuffer) +template<> bool ReedSolomon::InternalProcess(const Galois8 &factor, size_t size, const void *inputbuffer, void *outputbuffer) { - // Look up the appropriate element in the RS matrix - Galois8 factor = leftmatrix[outputindex * (datapresent + datamissing) + inputindex]; - - // Do nothing if the factor happens to be 0 - if (factor == 0) - return eSuccess; - #ifdef LONGMULTIPLY // The 8-bit long multiplication tables Galois8 *table = glmt->tables; @@ -189,7 +182,7 @@ bool ReedSolomon::Process(size_t size, u32 inputindex, const void *inpu // Set which of the source files are present and which are missing // and compute the base values to use for the vandermonde matrix. -bool ReedSolomon::SetInput(const vector &present) +template<> bool ReedSolomon::SetInput(const vector &present) { inputcount = (u32)present.size(); @@ -233,7 +226,7 @@ bool ReedSolomon::SetInput(const vector &present) // Record that the specified number of source files are all present // and compute the base values to use for the vandermonde matrix. -bool ReedSolomon::SetInput(u32 count) +template<> bool ReedSolomon::SetInput(u32 count) { inputcount = count; @@ -267,15 +260,8 @@ bool ReedSolomon::SetInput(u32 count) return true; } -bool ReedSolomon::Process(size_t size, u32 inputindex, const void *inputbuffer, u32 outputindex, void *outputbuffer) +template<> bool ReedSolomon::InternalProcess(const Galois16 &factor, size_t size, const void *inputbuffer, void *outputbuffer) { - // Look up the appropriate element in the RS matrix - - Galois16 factor = leftmatrix[outputindex * (datapresent + datamissing) + inputindex]; - // Do nothing if the factor happens to be 0 - if (factor == 0) - return eSuccess; - #ifdef LONGMULTIPLY // The 8-bit long multiplication tables Galois16 *table = glmt->tables; --- a/reedsolomon.h +++ b/reedsolomon.h @@ -64,7 +64,8 @@ public: const void *inputbuffer, // Buffer containing input data u32 outputindex, // The row in the RS matrix void *outputbuffer); // Buffer containing output data - +private: + bool InternalProcess(const g &factor, size_t size, const void *inputbuffer, void *outputbuffer); // Optimization protected: // Perform Gaussian Elimination bool GaussElim(CommandLine::NoiseLevel noiselevel, @@ -146,6 +147,20 @@ inline ReedSolomon::~ReedSolomon(void) #endif } +template +inline bool ReedSolomon::Process(size_t size, u32 inputindex, const void *inputbuffer, u32 outputindex, void *outputbuffer) +{ + // Optimization: it occurs frequently the function exits early on, so inline the start. + // This resulted in a speed gain of approx. 8% in repairing. + + // Look up the appropriate element in the RS matrix + g factor = leftmatrix[outputindex * (datapresent + datamissing) + inputindex]; + // Do nothing if the factor happens to be 0 + if (factor == 0) + return eSuccess; + return this->InternalProcess (factor, size, inputbuffer, outputbuffer); +} + u32 gcd(u32 a, u32 b); // Record whether the recovery block with the specified @@ -242,11 +257,14 @@ inline bool ReedSolomon::Compute(CommandLine::NoiseLevel noiselevel) // One row for each present recovery block that will be used for a missing data block for (unsigned int row=0; row CommandLine::nlQuiet) { int progress = row * 1000 / (datamissing+parmissing); cout << "Constructing: " << progress/10 << '.' << progress%10 << "%\r" << flush; } +#endif // Get the exponent of the next present recovery block while (!outputrow->present) @@ -286,11 +304,14 @@ inline bool ReedSolomon::Compute(CommandLine::NoiseLevel noiselevel) outputrow = outputrows.begin(); for (unsigned int row=0; row CommandLine::nlQuiet) { int progress = (row+datamissing) * 1000 / (datamissing+parmissing); cout << "Constructing: " << progress/10 << '.' << progress%10 << "%\r" << flush; } +#endif // Get the exponent of the next missing recovery block while (outputrow->present) @@ -420,6 +441,8 @@ inline bool ReedSolomon::GaussElim(CommandLine::NoiseLevel noiselevel, unsign // For every other row in the matrix for (unsigned int row2=0; row2 CommandLine::nlQuiet) { int newprogress = (row*rows+row2) * 1000 / (datamissing*rows); @@ -429,6 +452,7 @@ inline bool ReedSolomon::GaussElim(CommandLine::NoiseLevel noiselevel, unsign cout << "Solving: " << progress/10 << '.' << progress%10 << "%\r" << flush; } } +#endif if (row != row2) {