diff options
author | Sage Weil <sage@inktank.com> | 2013-09-23 15:14:22 -0700 |
---|---|---|
committer | Sage Weil <sage@inktank.com> | 2013-09-23 15:14:22 -0700 |
commit | 816cbbfea34900329ad5cbbbffbc8f881ea846ce (patch) | |
tree | db0cd74342cc6b0c3cd1791e609b3feb97adee4b | |
parent | 0eb0c3e0f3d7f8d32eb0cdf4abaf40d9fdb4d0a3 (diff) | |
parent | c32c51a3f3feff8d734bd9330306905888c6cf8d (diff) | |
download | ceph-816cbbfea34900329ad5cbbbffbc8f881ea846ce.tar.gz |
Merge pull request #619 from dachary/wip-erasure-pad
ErasureCode: optimize padding calculation
Reviewed-by: Sage Weil <sage@inktank.com>
-rw-r--r-- | src/osd/ErasureCodePluginJerasure/ErasureCodeJerasure.cc | 162 | ||||
-rw-r--r-- | src/osd/ErasureCodePluginJerasure/ErasureCodeJerasure.h | 10 | ||||
-rw-r--r-- | src/test/osd/TestErasureCodeJerasure.cc | 21 | ||||
-rw-r--r-- | src/test/osd/TestErasureCodePluginJerasure.cc | 15 |
4 files changed, 131 insertions, 77 deletions
diff --git a/src/osd/ErasureCodePluginJerasure/ErasureCodeJerasure.cc b/src/osd/ErasureCodePluginJerasure/ErasureCodeJerasure.cc index aa22144bb6e..2368cc6c711 100644 --- a/src/osd/ErasureCodePluginJerasure/ErasureCodeJerasure.cc +++ b/src/osd/ErasureCodePluginJerasure/ErasureCodeJerasure.cc @@ -35,7 +35,8 @@ static ostream& _prefix(std::ostream* _dout) return *_dout << "ErasureCodeJerasure: "; } -void ErasureCodeJerasure::init(const map<std::string,std::string> ¶meters) { +void ErasureCodeJerasure::init(const map<std::string,std::string> ¶meters) +{ dout(10) << "technique=" << technique << dendl; parse(parameters); prepare(); @@ -43,7 +44,8 @@ void ErasureCodeJerasure::init(const map<std::string,std::string> ¶meters) { int ErasureCodeJerasure::minimum_to_decode(const set<int> &want_to_read, const set<int> &available_chunks, - set<int> *minimum) { + set<int> *minimum) +{ if (includes(available_chunks.begin(), available_chunks.end(), want_to_read.begin(), want_to_read.end())) { *minimum = want_to_read; @@ -60,7 +62,8 @@ int ErasureCodeJerasure::minimum_to_decode(const set<int> &want_to_read, int ErasureCodeJerasure::minimum_to_decode_with_cost(const set<int> &want_to_read, const map<int, int> &available, - set<int> *minimum) { + set<int> *minimum) +{ set <int> available_chunks; for (map<int, int>::const_iterator i = available.begin(); i != available.end(); @@ -71,9 +74,13 @@ int ErasureCodeJerasure::minimum_to_decode_with_cost(const set<int> &want_to_rea int ErasureCodeJerasure::encode(const set<int> &want_to_encode, const bufferlist &in, - map<int, bufferlist> *encoded) { - unsigned in_length = pad_in_length(in.length()); - dout(10) << "encode adjusted buffer length from " << in.length() << " to " << in_length << dendl; + map<int, bufferlist> *encoded) +{ + unsigned alignment = get_alignment(); + unsigned tail = in.length() % alignment; + unsigned in_length = in.length() + ( tail ? ( alignment - tail ) : 0 ); + dout(10) << "encode adjusted buffer length from " << in.length() + << " to " << in_length << dendl; assert(in_length % k == 0); unsigned blocksize = in_length / k; unsigned length = blocksize * ( k + m ); @@ -103,7 +110,8 @@ int ErasureCodeJerasure::encode(const set<int> &want_to_encode, int ErasureCodeJerasure::decode(const set<int> &want_to_read, const map<int, bufferlist> &chunks, - map<int, bufferlist> *decoded) { + map<int, bufferlist> *decoded) +{ unsigned blocksize = (*chunks.begin()).second.length(); int erasures[k + m + 1]; int erasures_count = 0; @@ -133,7 +141,8 @@ int ErasureCodeJerasure::decode(const set<int> &want_to_read, int ErasureCodeJerasure::to_int(const std::string &name, const map<std::string,std::string> ¶meters, - int default_value) { + int default_value) +{ if (parameters.find(name) == parameters.end() || parameters.find(name)->second.size() == 0) { dout(10) << name << " defaults to " << default_value << dendl; @@ -153,7 +162,8 @@ int ErasureCodeJerasure::to_int(const std::string &name, return r; } -bool ErasureCodeJerasure::is_prime(int value) { +bool ErasureCodeJerasure::is_prime(int value) +{ int prime55[] = { 2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71, 73,79,83,89,97,101,103,107,109,113,127,131,137,139,149, @@ -172,34 +182,39 @@ bool ErasureCodeJerasure::is_prime(int value) { // void ErasureCodeJerasureReedSolomonVandermonde::jerasure_encode(char **data, char **coding, - int blocksize) { + int blocksize) +{ jerasure_matrix_encode(k, m, w, matrix, data, coding, blocksize); } int ErasureCodeJerasureReedSolomonVandermonde::jerasure_decode(int *erasures, char **data, char **coding, - int blocksize) { - return jerasure_matrix_decode(k, m, w, matrix, 1, erasures, data, coding, blocksize); + int blocksize) +{ + return jerasure_matrix_decode(k, m, w, matrix, 1, + erasures, data, coding, blocksize); } -unsigned ErasureCodeJerasureReedSolomonVandermonde::pad_in_length(unsigned in_length) { - while (in_length%(k*w*sizeof(int)) != 0) - in_length++; - return in_length; +unsigned ErasureCodeJerasureReedSolomonVandermonde::get_alignment() +{ + return k*w*sizeof(int); } -void ErasureCodeJerasureReedSolomonVandermonde::parse(const map<std::string,std::string> ¶meters) { +void ErasureCodeJerasureReedSolomonVandermonde::parse(const map<std::string,std::string> ¶meters) +{ k = to_int("erasure-code-k", parameters, DEFAULT_K); m = to_int("erasure-code-m", parameters, DEFAULT_M); w = to_int("erasure-code-w", parameters, DEFAULT_W); if (w != 8 && w != 16 && w != 32) { - derr << "ReedSolomonVandermonde: w=" << w << " must be one of {8, 16, 32} : revert to 8 " << dendl; + derr << "ReedSolomonVandermonde: w=" << w + << " must be one of {8, 16, 32} : revert to 8 " << dendl; w = 8; } } -void ErasureCodeJerasureReedSolomonVandermonde::prepare() { +void ErasureCodeJerasureReedSolomonVandermonde::prepare() +{ matrix = reed_sol_vandermonde_coding_matrix(k, m, w); } @@ -208,34 +223,38 @@ void ErasureCodeJerasureReedSolomonVandermonde::prepare() { // void ErasureCodeJerasureReedSolomonRAID6::jerasure_encode(char **data, char **coding, - int blocksize) { + int blocksize) +{ reed_sol_r6_encode(k, w, data, coding, blocksize); } int ErasureCodeJerasureReedSolomonRAID6::jerasure_decode(int *erasures, - char **data, - char **coding, - int blocksize) { + char **data, + char **coding, + int blocksize) +{ return jerasure_matrix_decode(k, m, w, matrix, 1, erasures, data, coding, blocksize); } -unsigned ErasureCodeJerasureReedSolomonRAID6::pad_in_length(unsigned in_length) { - while (in_length%(k*w*sizeof(int)) != 0) - in_length++; - return in_length; +unsigned ErasureCodeJerasureReedSolomonRAID6::get_alignment() +{ + return k*w*sizeof(int); } -void ErasureCodeJerasureReedSolomonRAID6::parse(const map<std::string,std::string> ¶meters) { +void ErasureCodeJerasureReedSolomonRAID6::parse(const map<std::string,std::string> ¶meters) +{ k = to_int("erasure-code-k", parameters, DEFAULT_K); m = 2; w = to_int("erasure-code-w", parameters, DEFAULT_W); if (w != 8 && w != 16 && w != 32) { - derr << "ReedSolomonRAID6: w=" << w << " must be one of {8, 16, 32} : revert to 8 " << dendl; + derr << "ReedSolomonRAID6: w=" << w + << " must be one of {8, 16, 32} : revert to 8 " << dendl; w = 8; } } -void ErasureCodeJerasureReedSolomonRAID6::prepare() { +void ErasureCodeJerasureReedSolomonRAID6::prepare() +{ matrix = reed_sol_r6_coding_matrix(k, w); } @@ -243,32 +262,37 @@ void ErasureCodeJerasureReedSolomonRAID6::prepare() { // ErasureCodeJerasureCauchy // void ErasureCodeJerasureCauchy::jerasure_encode(char **data, - char **coding, - int blocksize) { - jerasure_schedule_encode(k, m, w, schedule, data, coding, blocksize, packetsize); + char **coding, + int blocksize) +{ + jerasure_schedule_encode(k, m, w, schedule, + data, coding, blocksize, packetsize); } int ErasureCodeJerasureCauchy::jerasure_decode(int *erasures, - char **data, - char **coding, - int blocksize) { - return jerasure_schedule_decode_lazy(k, m, w, bitmatrix, erasures, data, coding, blocksize, packetsize, 1); + char **data, + char **coding, + int blocksize) +{ + return jerasure_schedule_decode_lazy(k, m, w, bitmatrix, + erasures, data, coding, blocksize, packetsize, 1); } -unsigned ErasureCodeJerasureCauchy::pad_in_length(unsigned in_length) { - while (in_length%(k*w*packetsize*sizeof(int)) != 0) - in_length++; - return in_length; +unsigned ErasureCodeJerasureCauchy::get_alignment() +{ + return k*w*packetsize*sizeof(int); } -void ErasureCodeJerasureCauchy::parse(const map<std::string,std::string> ¶meters) { +void ErasureCodeJerasureCauchy::parse(const map<std::string,std::string> ¶meters) +{ k = to_int("erasure-code-k", parameters, DEFAULT_K); m = to_int("erasure-code-m", parameters, DEFAULT_M); w = to_int("erasure-code-w", parameters, DEFAULT_W); packetsize = to_int("erasure-code-packetsize", parameters, DEFAULT_PACKETSIZE); } -void ErasureCodeJerasureCauchy::prepare_schedule(int *matrix) { +void ErasureCodeJerasureCauchy::prepare_schedule(int *matrix) +{ bitmatrix = jerasure_matrix_to_bitmatrix(k, m, w, matrix); schedule = jerasure_smart_bitmatrix_to_schedule(k, m, w, bitmatrix); } @@ -276,7 +300,8 @@ void ErasureCodeJerasureCauchy::prepare_schedule(int *matrix) { // // ErasureCodeJerasureCauchyOrig // -void ErasureCodeJerasureCauchyOrig::prepare() { +void ErasureCodeJerasureCauchyOrig::prepare() +{ int *matrix = cauchy_original_coding_matrix(k, m, w); prepare_schedule(matrix); free(matrix); @@ -285,7 +310,8 @@ void ErasureCodeJerasureCauchyOrig::prepare() { // // ErasureCodeJerasureCauchyGood // -void ErasureCodeJerasureCauchyGood::prepare() { +void ErasureCodeJerasureCauchyGood::prepare() +{ int *matrix = cauchy_good_general_coding_matrix(k, m, w); prepare_schedule(matrix); free(matrix); @@ -294,7 +320,8 @@ void ErasureCodeJerasureCauchyGood::prepare() { // // ErasureCodeJerasureLiberation // -ErasureCodeJerasureLiberation::~ErasureCodeJerasureLiberation() { +ErasureCodeJerasureLiberation::~ErasureCodeJerasureLiberation() +{ if (bitmatrix) free(bitmatrix); if (schedule) @@ -303,24 +330,28 @@ ErasureCodeJerasureLiberation::~ErasureCodeJerasureLiberation() { void ErasureCodeJerasureLiberation::jerasure_encode(char **data, char **coding, - int blocksize) { - jerasure_schedule_encode(k, m, w, schedule, data, coding, blocksize, packetsize); + int blocksize) +{ + jerasure_schedule_encode(k, m, w, schedule, data, + coding, blocksize, packetsize); } int ErasureCodeJerasureLiberation::jerasure_decode(int *erasures, char **data, char **coding, - int blocksize) { - return jerasure_schedule_decode_lazy(k, m, w, bitmatrix, erasures, data, coding, blocksize, packetsize, 1); + int blocksize) +{ + return jerasure_schedule_decode_lazy(k, m, w, bitmatrix, erasures, data, + coding, blocksize, packetsize, 1); } -unsigned ErasureCodeJerasureLiberation::pad_in_length(unsigned in_length) { - while (in_length%(k*w*packetsize*sizeof(int)) != 0) - in_length++; - return in_length; +unsigned ErasureCodeJerasureLiberation::get_alignment() +{ + return k*w*packetsize*sizeof(int); } -void ErasureCodeJerasureLiberation::parse(const map<std::string,std::string> ¶meters) { +void ErasureCodeJerasureLiberation::parse(const map<std::string,std::string> ¶meters) +{ k = to_int("erasure-code-k", parameters, DEFAULT_K); m = to_int("erasure-code-m", parameters, DEFAULT_M); w = to_int("erasure-code-w", parameters, DEFAULT_W); @@ -340,18 +371,21 @@ void ErasureCodeJerasureLiberation::parse(const map<std::string,std::string> &pa error = true; } if ((packetsize%(sizeof(int))) != 0) { - derr << "packetsize=" << packetsize << " must be a multiple of sizeof(int) = " << sizeof(int) << dendl; + derr << "packetsize=" << packetsize + << " must be a multiple of sizeof(int) = " << sizeof(int) << dendl; error = true; } if (error) { - derr << "reverting to k=" << DEFAULT_K << ", w=" << DEFAULT_W << ", packetsize=" << DEFAULT_PACKETSIZE << dendl; + derr << "reverting to k=" << DEFAULT_K << ", w=" + << DEFAULT_W << ", packetsize=" << DEFAULT_PACKETSIZE << dendl; k = DEFAULT_K; w = DEFAULT_W; packetsize = DEFAULT_PACKETSIZE; } } -void ErasureCodeJerasureLiberation::prepare() { +void ErasureCodeJerasureLiberation::prepare() +{ bitmatrix = liberation_coding_bitmatrix(k, w); schedule = jerasure_smart_bitmatrix_to_schedule(k, m, w, bitmatrix); } @@ -359,7 +393,8 @@ void ErasureCodeJerasureLiberation::prepare() { // // ErasureCodeJerasureBlaumRoth // -void ErasureCodeJerasureBlaumRoth::prepare() { +void ErasureCodeJerasureBlaumRoth::prepare() +{ bitmatrix = blaum_roth_coding_bitmatrix(k, w); schedule = jerasure_smart_bitmatrix_to_schedule(k, m, w, bitmatrix); } @@ -367,7 +402,8 @@ void ErasureCodeJerasureBlaumRoth::prepare() { // // ErasureCodeJerasureLiber8tion // -void ErasureCodeJerasureLiber8tion::parse(const map<std::string,std::string> ¶meters) { +void ErasureCodeJerasureLiber8tion::parse(const map<std::string,std::string> ¶meters) +{ k = to_int("erasure-code-k", parameters, DEFAULT_K); m = DEFAULT_M; w = DEFAULT_W; @@ -383,13 +419,15 @@ void ErasureCodeJerasureLiber8tion::parse(const map<std::string,std::string> &pa error = true; } if (error) { - derr << "reverting to k=" << DEFAULT_K << ", packetsize=" << DEFAULT_PACKETSIZE << dendl; + derr << "reverting to k=" << DEFAULT_K << ", packetsize=" + << DEFAULT_PACKETSIZE << dendl; k = DEFAULT_K; packetsize = DEFAULT_PACKETSIZE; } } -void ErasureCodeJerasureLiber8tion::prepare() { +void ErasureCodeJerasureLiber8tion::prepare() +{ bitmatrix = liber8tion_coding_bitmatrix(k); schedule = jerasure_smart_bitmatrix_to_schedule(k, m, w, bitmatrix); } diff --git a/src/osd/ErasureCodePluginJerasure/ErasureCodeJerasure.h b/src/osd/ErasureCodePluginJerasure/ErasureCodeJerasure.h index 7728751c383..fc76ed7b1e2 100644 --- a/src/osd/ErasureCodePluginJerasure/ErasureCodeJerasure.h +++ b/src/osd/ErasureCodePluginJerasure/ErasureCodeJerasure.h @@ -56,7 +56,7 @@ public: char **data, char **coding, int blocksize) = 0; - virtual unsigned pad_in_length(unsigned in_length) = 0; + virtual unsigned get_alignment() = 0; virtual void parse(const map<std::string,std::string> ¶meters) = 0; virtual void prepare() = 0; static int to_int(const std::string &name, @@ -88,7 +88,7 @@ public: char **data, char **coding, int blocksize); - virtual unsigned pad_in_length(unsigned in_length); + virtual unsigned get_alignment(); virtual void parse(const map<std::string,std::string> ¶meters); virtual void prepare(); }; @@ -115,7 +115,7 @@ public: char **data, char **coding, int blocksize); - virtual unsigned pad_in_length(unsigned in_length); + virtual unsigned get_alignment(); virtual void parse(const map<std::string,std::string> ¶meters); virtual void prepare(); }; @@ -149,7 +149,7 @@ public: char **data, char **coding, int blocksize); - virtual unsigned pad_in_length(unsigned in_length); + virtual unsigned get_alignment(); virtual void parse(const map<std::string,std::string> ¶meters); void prepare_schedule(int *matrix); }; @@ -196,7 +196,7 @@ public: char **data, char **coding, int blocksize); - virtual unsigned pad_in_length(unsigned in_length); + virtual unsigned get_alignment(); virtual void parse(const map<std::string,std::string> ¶meters); virtual void prepare(); }; diff --git a/src/test/osd/TestErasureCodeJerasure.cc b/src/test/osd/TestErasureCodeJerasure.cc index 22aaff7e5fa..2e601af38b2 100644 --- a/src/test/osd/TestErasureCodeJerasure.cc +++ b/src/test/osd/TestErasureCodeJerasure.cc @@ -58,7 +58,8 @@ TYPED_TEST(ErasureCodeTest, encode_decode) EXPECT_EQ(4u, encoded.size()); unsigned length = encoded[0].length(); EXPECT_EQ(0, strncmp(encoded[0].c_str(), in.c_str(), length)); - EXPECT_EQ(0, strncmp(encoded[1].c_str(), in.c_str() + length, in.length() - length)); + EXPECT_EQ(0, strncmp(encoded[1].c_str(), in.c_str() + length, + in.length() - length)); // all chunks are available @@ -72,7 +73,8 @@ TYPED_TEST(ErasureCodeTest, encode_decode) EXPECT_EQ(4u, decoded.size()); EXPECT_EQ(length, decoded[0].length()); EXPECT_EQ(0, strncmp(decoded[0].c_str(), in.c_str(), length)); - EXPECT_EQ(0, strncmp(decoded[1].c_str(), in.c_str() + length, in.length() - length)); + EXPECT_EQ(0, strncmp(decoded[1].c_str(), in.c_str() + length, + in.length() - length)); } // two chunks are missing @@ -90,7 +92,8 @@ TYPED_TEST(ErasureCodeTest, encode_decode) EXPECT_EQ(4u, decoded.size()); EXPECT_EQ(length, decoded[0].length()); EXPECT_EQ(0, strncmp(decoded[0].c_str(), in.c_str(), length)); - EXPECT_EQ(0, strncmp(decoded[1].c_str(), in.c_str() + length, in.length() - length)); + EXPECT_EQ(0, strncmp(decoded[1].c_str(), in.c_str() + length, + in.length() - length)); } } @@ -204,6 +207,12 @@ int main(int argc, char **argv) return RUN_ALL_TESTS(); } -// Local Variables: -// compile-command: "cd ../.. ; make -j4 && make unittest_erasure_code_jerasure && valgrind --tool=memcheck ./unittest_erasure_code_jerasure --gtest_filter=*.* --log-to-stderr=true --debug-osd=20" -// End: +/* + * Local Variables: + * compile-command: "cd ../.. ; make -j4 && + * make unittest_erasure_code_jerasure && + * valgrind --tool=memcheck --leak-check=full \ + * ./unittest_erasure_code_jerasure \ + * --gtest_filter=*.* --log-to-stderr=true --debug-osd=20" + * End: + */ diff --git a/src/test/osd/TestErasureCodePluginJerasure.cc b/src/test/osd/TestErasureCodePluginJerasure.cc index fe819c71a39..2f558937595 100644 --- a/src/test/osd/TestErasureCodePluginJerasure.cc +++ b/src/test/osd/TestErasureCodePluginJerasure.cc @@ -51,7 +51,8 @@ TEST(ErasureCodePlugin, factory) } } -int main(int argc, char **argv) { +int main(int argc, char **argv) +{ vector<const char*> args; argv_to_vec(argc, (const char **)argv, args); @@ -62,6 +63,12 @@ int main(int argc, char **argv) { return RUN_ALL_TESTS(); } -// Local Variables: -// compile-command: "cd ../.. ; make -j4 && make unittest_erasure_code_jerasure_plugin && valgrind --tool=memcheck ./unittest_erasure_code_jerasure_plugin --gtest_filter=*.* --log-to-stderr=true --debug-osd=20" -// End: +/* + * Local Variables: + * compile-command: "cd ../.. ; make -j4 && + * make unittest_erasure_code_plugin_jerasure && + * valgrind --tool=memcheck ./unittest_erasure_code_plugin_jerasure \ + * --gtest_filter=*.* --log-to-stderr=true --debug-osd=20" + * End: + */ + |