From: Loic Dachary Date: Tue, 3 Jun 2014 21:17:59 +0000 (+0200) Subject: erasure-code: move to ErasureCode::{encode,decode}{,chunk} X-Git-Tag: v0.85~67^2~4 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=4ff981f4d66bc915e82d91a8d2946d6861089df8;p=ceph.git erasure-code: move to ErasureCode::{encode,decode}{,chunk} The bulk of ErasureCode{Jerasure,Isa}::encode and ErasureCode{Jerasure,Isa}::decode is dealing with alignment and buffer allocation. This is moved to ErasureCode::encode and ErasureCode::decode respectively. The jerasure/isa specific code is isolated in the new ErasureCode{Jerasure,Isa}::encode_chunks and ErasureCode{Jerasure,Isa}::decode_chunks virtual functions. http://tracker.ceph.com/issues/8496 Refs: #8496 Signed-off-by: Loic Dachary --- diff --git a/src/erasure-code/ErasureCode.cc b/src/erasure-code/ErasureCode.cc index 8b432451909d5..75feeb812749f 100644 --- a/src/erasure-code/ErasureCode.cc +++ b/src/erasure-code/ErasureCode.cc @@ -15,3 +15,95 @@ */ #include "ErasureCode.h" +int ErasureCode::encode_prepare(const bufferlist &raw, + bufferlist *prepared) const +{ + unsigned int k = get_data_chunk_count(); + unsigned int m = get_chunk_count() - k; + unsigned blocksize = get_chunk_size(raw.length()); + unsigned padded_length = blocksize * k; + *prepared = raw; + if (padded_length - raw.length() > 0) { + bufferptr pad(padded_length - raw.length()); + pad.zero(); + prepared->push_back(pad); + } + unsigned coding_length = blocksize * m; + bufferptr coding(buffer::create_page_aligned(coding_length)); + prepared->push_back(coding); + prepared->rebuild_page_aligned(); + return 0; +} + +int ErasureCode::encode(const set &want_to_encode, + const bufferlist &in, + map *encoded) +{ + unsigned int k = get_data_chunk_count(); + unsigned int m = get_chunk_count() - k; + bufferlist out; + int err = encode_prepare(in, &out); + if (err) + return err; + unsigned blocksize = get_chunk_size(in.length()); + for (unsigned int i = 0; i < k + m; i++) { + bufferlist &chunk = (*encoded)[i]; + chunk.substr_of(out, i * blocksize, blocksize); + } + encode_chunks(want_to_encode, encoded); + for (unsigned int i = 0; i < k + m; i++) { + if (want_to_encode.count(i) == 0) + encoded->erase(i); + } + return 0; +} + +int ErasureCode::encode_chunks(const set &want_to_encode, + map *encoded) +{ + assert("ErasureCode::encode_chunks not implemented" == 0); +} + +int ErasureCode::decode(const set &want_to_read, + const map &chunks, + map *decoded) +{ + vector have; + have.reserve(chunks.size()); + for (map::const_iterator i = chunks.begin(); + i != chunks.end(); + ++i) { + have.push_back(i->first); + } + if (includes( + have.begin(), have.end(), want_to_read.begin(), want_to_read.end())) { + for (set::iterator i = want_to_read.begin(); + i != want_to_read.end(); + ++i) { + (*decoded)[*i] = chunks.find(*i)->second; + } + return 0; + } + unsigned int k = get_data_chunk_count(); + unsigned int m = get_chunk_count() - k; + unsigned blocksize = (*chunks.begin()).second.length(); + for (unsigned int i = 0; i < k + m; i++) { + if (chunks.find(i) == chunks.end()) { + bufferptr ptr(buffer::create_page_aligned(blocksize)); + (*decoded)[i].push_front(ptr); + } else { + (*decoded)[i] = chunks.find(i)->second; + (*decoded)[i].rebuild_page_aligned(); + } + } + return decode_chunks(want_to_read, chunks, decoded); +} + +int ErasureCode::decode_chunks(const set &want_to_read, + const map &chunks, + map *decoded) +{ + assert("ErasureCode::decode_chunks not implemented" == 0); +} + + diff --git a/src/erasure-code/ErasureCode.h b/src/erasure-code/ErasureCode.h index 25b17c743721c..7ae2fd71eb983 100644 --- a/src/erasure-code/ErasureCode.h +++ b/src/erasure-code/ErasureCode.h @@ -17,6 +17,11 @@ #ifndef CEPH_ERASURE_CODE_H #define CEPH_ERASURE_CODE_H +/*! @file ErasureCode.h + @brief Base class for erasure code plugins implementors + + */ + #include "ErasureCodeInterface.h" namespace ceph { @@ -25,6 +30,23 @@ namespace ceph { public: virtual ~ErasureCode() {} + int encode_prepare(const bufferlist &raw, bufferlist *prepared) const; + + virtual int encode(const set &want_to_encode, + const bufferlist &in, + map *encoded); + + virtual int encode_chunks(const set &want_to_encode, + map *encoded); + + virtual int decode(const set &want_to_read, + const map &chunks, + map *decoded); + + virtual int decode_chunks(const set &want_to_read, + const map &chunks, + map *decoded); + }; } diff --git a/src/erasure-code/ErasureCodeInterface.h b/src/erasure-code/ErasureCodeInterface.h index 63de14e6ab011..06ee373357af3 100644 --- a/src/erasure-code/ErasureCodeInterface.h +++ b/src/erasure-code/ErasureCodeInterface.h @@ -302,6 +302,10 @@ namespace ceph { const bufferlist &in, map *encoded) = 0; + + virtual int encode_chunks(const set &want_to_encode, + map *encoded) = 0; + /** * Decode the **chunks** and store at least **want_to_read** * chunks in **decoded**. @@ -339,6 +343,10 @@ namespace ceph { const map &chunks, map *decoded) = 0; + virtual int decode_chunks(const set &want_to_read, + const map &chunks, + map *decoded) = 0; + /** * Decode the first **get_data_chunk_count()** **chunks** and * concatenate them them into **decoded**. diff --git a/src/erasure-code/isa/ErasureCodeIsa.cc b/src/erasure-code/isa/ErasureCodeIsa.cc index 0722374d9a762..da381a3dd246f 100644 --- a/src/erasure-code/isa/ErasureCodeIsa.cc +++ b/src/erasure-code/isa/ErasureCodeIsa.cc @@ -115,104 +115,38 @@ ErasureCodeIsa::minimum_to_decode_with_cost(const set &want_to_read, return minimum_to_decode(want_to_read, available_chunks, minimum); } -// ----------------------------------------------------------------------------- - -int -ErasureCodeIsa::encode(const set &want_to_encode, - const bufferlist &in, - map *encoded) +int ErasureCodeIsa::encode_chunks(const set &want_to_encode, + map *encoded) { - unsigned blocksize = get_chunk_size(in.length()); - unsigned padded_length = blocksize * k; - dout(10) << "encode adjusted buffer length from " << in.length() - << " to " << padded_length << dendl; - assert(padded_length % k == 0); - bufferlist out(in); - - if (padded_length - in.length() > 0) { - bufferptr pad(padded_length - in.length()); - pad.zero(); - out.push_back(pad); - } - unsigned coding_length = blocksize * m; - bufferptr coding(buffer::create_page_aligned(coding_length)); - out.push_back(coding); - out.rebuild_page_aligned(); char *chunks[k + m]; - - for (int i = 0; i < k + m; i++) { - bufferlist &chunk = (*encoded)[i]; - chunk.substr_of(out, i * blocksize, blocksize); - chunks[i] = chunk.c_str(); - } - - isa_encode(&chunks[0], &chunks[k], blocksize); - - for (int i = 0; i < k + m; i++) { - if (want_to_encode.count(i) == 0) - encoded->erase(i); - } - + for (int i = 0; i < k + m; i++) + chunks[i] = (*encoded)[i].c_str(); + isa_encode(&chunks[0], &chunks[k], (*encoded)[0].length()); return 0; } -// ----------------------------------------------------------------------------- - -int -ErasureCodeIsa::decode(const set &want_to_read, - const map &chunks, - map *decoded) +int ErasureCodeIsa::decode_chunks(const set &want_to_read, + const map &chunks, + map *decoded) { - vector have; - have.reserve(chunks.size()); - - for (map::const_iterator i = chunks.begin(); - i != chunks.end(); - ++i) { - have.push_back(i->first); - } - - if (includes( - have.begin(), - have.end(), - want_to_read.begin(), - want_to_read.end())) { - for (set::iterator i = want_to_read.begin(); - i != want_to_read.end(); - ++i) { - (*decoded)[*i] = chunks.find(*i)->second; - } - return 0; - } unsigned blocksize = (*chunks.begin()).second.length(); int erasures[k + m + 1]; int erasures_count = 0; char *data[k]; char *coding[m]; - - for (int i = 0; i < k + m; i++) { + for (int i = 0; i < k + m; i++) { if (chunks.find(i) == chunks.end()) { erasures[erasures_count] = i; erasures_count++; - bufferptr ptr(buffer::create_page_aligned(blocksize)); - (*decoded)[i].push_front(ptr); - } else { - (*decoded)[i] = chunks.find(i)->second; - (*decoded)[i].rebuild_page_aligned(); } - if (i < k) { + if (i < k) data[i] = (*decoded)[i].c_str(); - } else { + else coding[i - k] = (*decoded)[i].c_str(); - } } erasures[erasures_count] = -1; - - if (erasures_count > 0) { - int retc = isa_decode(erasures, data, coding, blocksize); - return retc; - } else - return 0; + assert(erasures_count > 0); + return isa_decode(erasures, data, coding, blocksize); } // ----------------------------------------------------------------------------- diff --git a/src/erasure-code/isa/ErasureCodeIsa.h b/src/erasure-code/isa/ErasureCodeIsa.h index 385a8438fa313..136ef5d5d62a1 100644 --- a/src/erasure-code/isa/ErasureCodeIsa.h +++ b/src/erasure-code/isa/ErasureCodeIsa.h @@ -27,12 +27,12 @@ // ----------------------------------------------------------------------------- #include "common/Mutex.h" -#include "erasure-code/ErasureCodeInterface.h" +#include "erasure-code/ErasureCode.h" // ----------------------------------------------------------------------------- #include // ----------------------------------------------------------------------------- -class ErasureCodeIsa : public ErasureCodeInterface { +class ErasureCodeIsa : public ErasureCode { public: enum eMatrix {kVandermonde=0, kCauchy=1}; @@ -76,18 +76,16 @@ public: virtual int minimum_to_decode(const set &want_to_read, const set &available_chunks, set *minimum); + virtual int encode_chunks(const set &want_to_encode, + map *encoded); virtual int minimum_to_decode_with_cost(const set &want_to_read, const map &available, set *minimum); - virtual int encode(const set &want_to_encode, - const bufferlist &in, - map *encoded); - - virtual int decode(const set &want_to_read, - const map &chunks, - map *decoded); + virtual int decode_chunks(const set &want_to_read, + const map &chunks, + map *decoded); void init(const map ¶meters); diff --git a/src/erasure-code/jerasure/ErasureCodeJerasure.cc b/src/erasure-code/jerasure/ErasureCodeJerasure.cc index e207c3aa612b9..b35e0bb47d575 100644 --- a/src/erasure-code/jerasure/ErasureCodeJerasure.cc +++ b/src/erasure-code/jerasure/ErasureCodeJerasure.cc @@ -14,8 +14,6 @@ * */ -#include -#include #include "common/debug.h" #include "ErasureCodeJerasure.h" #include "crush/CrushWrapper.h" @@ -116,59 +114,20 @@ int ErasureCodeJerasure::minimum_to_decode_with_cost(const set &want_to_rea return minimum_to_decode(want_to_read, available_chunks, minimum); } -int ErasureCodeJerasure::encode(const set &want_to_encode, - const bufferlist &in, - map *encoded) -{ - unsigned blocksize = get_chunk_size(in.length()); - unsigned padded_length = blocksize * k; - if (in.length() != padded_length) - dout(10) << "encode adjusted buffer length from " << in.length() - << " to " << padded_length << dendl; - bufferlist out(in); - if (padded_length - in.length() > 0) { - bufferptr pad(padded_length - in.length()); - pad.zero(); - out.push_back(pad); - } - unsigned coding_length = blocksize * m; - bufferptr coding(buffer::create_page_aligned(coding_length)); - out.push_back(coding); - out.rebuild_page_aligned(); +int ErasureCodeJerasure::encode_chunks(const set &want_to_encode, + map *encoded) +{ char *chunks[k + m]; - for (int i = 0; i < k + m; i++) { - bufferlist &chunk = (*encoded)[i]; - chunk.substr_of(out, i * blocksize, blocksize); - chunks[i] = chunk.c_str(); - } - jerasure_encode(&chunks[0], &chunks[k], blocksize); - for (int i = 0; i < k + m; i++) { - if (want_to_encode.count(i) == 0) - encoded->erase(i); - } + for (int i = 0; i < k + m; i++) + chunks[i] = (*encoded)[i].c_str(); + jerasure_encode(&chunks[0], &chunks[k], (*encoded)[0].length()); return 0; } -int ErasureCodeJerasure::decode(const set &want_to_read, - const map &chunks, - map *decoded) +int ErasureCodeJerasure::decode_chunks(const set &want_to_read, + const map &chunks, + map *decoded) { - vector have; - have.reserve(chunks.size()); - for (map::const_iterator i = chunks.begin(); - i != chunks.end(); - ++i) { - have.push_back(i->first); - } - if (includes( - have.begin(), have.end(), want_to_read.begin(), want_to_read.end())) { - for (set::iterator i = want_to_read.begin(); - i != want_to_read.end(); - ++i) { - (*decoded)[*i] = chunks.find(*i)->second; - } - return 0; - } unsigned blocksize = (*chunks.begin()).second.length(); int erasures[k + m + 1]; int erasures_count = 0; @@ -178,11 +137,6 @@ int ErasureCodeJerasure::decode(const set &want_to_read, if (chunks.find(i) == chunks.end()) { erasures[erasures_count] = i; erasures_count++; - bufferptr ptr(buffer::create_page_aligned(blocksize)); - (*decoded)[i].push_front(ptr); - } else { - (*decoded)[i] = chunks.find(i)->second; - (*decoded)[i].rebuild_page_aligned(); } if (i < k) data[i] = (*decoded)[i].c_str(); @@ -191,10 +145,8 @@ int ErasureCodeJerasure::decode(const set &want_to_read, } erasures[erasures_count] = -1; - if (erasures_count > 0) - return jerasure_decode(erasures, data, coding, blocksize); - else - return 0; + assert(erasures_count > 0); + return jerasure_decode(erasures, data, coding, blocksize); } int ErasureCodeJerasure::to_int(const std::string &name, diff --git a/src/erasure-code/jerasure/ErasureCodeJerasure.h b/src/erasure-code/jerasure/ErasureCodeJerasure.h index cda7e5bce218f..f7e5c3116b0f7 100644 --- a/src/erasure-code/jerasure/ErasureCodeJerasure.h +++ b/src/erasure-code/jerasure/ErasureCodeJerasure.h @@ -55,18 +55,16 @@ public: virtual int minimum_to_decode(const set &want_to_read, const set &available_chunks, set *minimum); + virtual int encode_chunks(const set &want_to_encode, + map *encoded); virtual int minimum_to_decode_with_cost(const set &want_to_read, const map &available, set *minimum); - virtual int encode(const set &want_to_encode, - const bufferlist &in, - map *encoded); - - virtual int decode(const set &want_to_read, - const map &chunks, - map *decoded); + virtual int decode_chunks(const set &want_to_read, + const map &chunks, + map *decoded); void init(const map ¶meters); virtual void jerasure_encode(char **data, diff --git a/src/test/erasure-code/ErasureCodeExample.h b/src/test/erasure-code/ErasureCodeExample.h index e07a14237268d..2861b648c1ed7 100644 --- a/src/test/erasure-code/ErasureCodeExample.h +++ b/src/test/erasure-code/ErasureCodeExample.h @@ -138,6 +138,12 @@ public: return 0; } + virtual int encode_chunks(const set &want_to_encode, + map *encoded) { + assert(0); + return 0; + } + virtual int decode(const set &want_to_read, const map &chunks, map *decoded) { @@ -179,6 +185,14 @@ public: } return 0; } + + virtual int decode_chunks(const set &want_to_read, + const map &chunks, + map *decoded) { + assert(0); + return 0; + } + }; #endif