From 9a820105849a0fa51b5753965941b1143035cd6e Mon Sep 17 00:00:00 2001 From: Loic Dachary Date: Thu, 29 Aug 2013 15:00:20 +0200 Subject: [PATCH] ErasureCodeJerasure: define technique Liberation technique == "liberation" parse : default to K=7, M=2 and W=7 and packetsize = 8. If any of the following constraints is not satisfied, revert to the default: * K > W * W > 2 * W is a prime number * packetsize must not be zero * packetsize must be a multiple of sizeof(int) pad_in_length : pad to a multiple of k*w*packetsize*sizeof(int) prepare, jerasure_encode, jerasure_decode map directly to the matching jerasure functions https://github.com/dachary/ceph/tree/wip-5879 refs #5879 Signed-off-by: Loic Dachary --- .../ErasureCodeJerasure.cc | 65 +++++++++++++++++++ .../ErasureCodeJerasure.h | 29 +++++++++ src/test/osd/TestErasureCodeJerasure.cc | 1 + 3 files changed, 95 insertions(+) diff --git a/src/osd/ErasureCodePluginJerasure/ErasureCodeJerasure.cc b/src/osd/ErasureCodePluginJerasure/ErasureCodeJerasure.cc index 6283915b65a..386a025d621 100644 --- a/src/osd/ErasureCodePluginJerasure/ErasureCodeJerasure.cc +++ b/src/osd/ErasureCodePluginJerasure/ErasureCodeJerasure.cc @@ -284,3 +284,68 @@ void ErasureCodeJerasureCauchyGood::prepare() { prepare_schedule(matrix); free(matrix); } + +// +// ErasureCodeJerasureLiberation +// +ErasureCodeJerasureLiberation::~ErasureCodeJerasureLiberation() { + if (bitmatrix) + free(bitmatrix); + if (schedule) + jerasure_free_schedule(schedule); +} + +void ErasureCodeJerasureLiberation::jerasure_encode(char **data, + char **coding, + 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); +} + +unsigned ErasureCodeJerasureLiberation::pad_in_length(unsigned in_length) { + while (in_length%(k*w*packetsize*sizeof(int)) != 0) + in_length++; + return in_length; +} + +void ErasureCodeJerasureLiberation::parse(const map ¶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); + + bool error = false; + if (k > w) { + derr << "k=" << k << " must be less than or equal to w=" << w << dendl; + error = true; + } + if (w <= 2 || !is_prime(w)) { + derr << "w=" << w << " must be greater than two and be prime" << dendl; + error = true; + } + if (packetsize == 0) { + derr << "packetsize=" << packetsize << " must be set" << dendl; + error = true; + } + if ((packetsize%(sizeof(int))) != 0) { + 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; + k = DEFAULT_K; + w = DEFAULT_W; + packetsize = DEFAULT_PACKETSIZE; + } +} + +void ErasureCodeJerasureLiberation::prepare() { + bitmatrix = liberation_coding_bitmatrix(k, w); + 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 5484b5e2a22..00f7599f1fd 100644 --- a/src/osd/ErasureCodePluginJerasure/ErasureCodeJerasure.h +++ b/src/osd/ErasureCodePluginJerasure/ErasureCodeJerasure.h @@ -171,4 +171,33 @@ public: virtual void prepare(); }; + +class ErasureCodeJerasureLiberation : public ErasureCodeJerasure { +public: + static const int DEFAULT_K = 2; + static const int DEFAULT_M = 2; + static const int DEFAULT_W = 7; + static const int DEFAULT_PACKETSIZE = 8; + int *bitmatrix; + int **schedule; + int packetsize; + + ErasureCodeJerasureLiberation(const char *technique = "liberation") : + ErasureCodeJerasure(technique), + bitmatrix(0), + schedule(0) + { } + virtual ~ErasureCodeJerasureLiberation(); + + virtual void jerasure_encode(char **data, + char **coding, + int blocksize); + virtual int jerasure_decode(int *erasures, + char **data, + char **coding, + int blocksize); + virtual unsigned pad_in_length(unsigned in_length); + virtual void parse(const map ¶meters); + virtual void prepare(); +}; #endif diff --git a/src/test/osd/TestErasureCodeJerasure.cc b/src/test/osd/TestErasureCodeJerasure.cc index f35c01f125d..b46e1bd0d62 100644 --- a/src/test/osd/TestErasureCodeJerasure.cc +++ b/src/test/osd/TestErasureCodeJerasure.cc @@ -30,6 +30,7 @@ typedef ::testing::Types< ErasureCodeJerasureReedSolomonRAID6, ErasureCodeJerasureCauchyOrig, ErasureCodeJerasureCauchyGood, + ErasureCodeJerasureLiberation, > JerasureTypes; TYPED_TEST_CASE(ErasureCodeTest, JerasureTypes);