]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
erasure-code: move to ErasureCode::{encode,decode}{,chunk}
authorLoic Dachary <loic@dachary.org>
Tue, 3 Jun 2014 21:17:59 +0000 (23:17 +0200)
committerLoic Dachary <loic@dachary.org>
Wed, 6 Aug 2014 13:21:59 +0000 (15:21 +0200)
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 <loic@dachary.org>
src/erasure-code/ErasureCode.cc
src/erasure-code/ErasureCode.h
src/erasure-code/ErasureCodeInterface.h
src/erasure-code/isa/ErasureCodeIsa.cc
src/erasure-code/isa/ErasureCodeIsa.h
src/erasure-code/jerasure/ErasureCodeJerasure.cc
src/erasure-code/jerasure/ErasureCodeJerasure.h
src/test/erasure-code/ErasureCodeExample.h

index 8b432451909d5c3692b63d62969741f766411f92..75feeb812749fb718409724150027a006bce364c 100644 (file)
  */
 
 #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<int> &want_to_encode,
+                        const bufferlist &in,
+                        map<int, bufferlist> *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<int> &want_to_encode,
+                               map<int, bufferlist> *encoded)
+{
+  assert("ErasureCode::encode_chunks not implemented" == 0);
+}
+int ErasureCode::decode(const set<int> &want_to_read,
+                        const map<int, bufferlist> &chunks,
+                        map<int, bufferlist> *decoded)
+{
+  vector<int> have;
+  have.reserve(chunks.size());
+  for (map<int, bufferlist>::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<int>::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<int> &want_to_read,
+                               const map<int, bufferlist> &chunks,
+                               map<int, bufferlist> *decoded)
+{
+  assert("ErasureCode::decode_chunks not implemented" == 0);
+}
+
+
index 25b17c743721c6441cf493662ec4979f6bb83a8c..7ae2fd71eb9834460f90a215f5709a2cf06e464d 100644 (file)
 #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<int> &want_to_encode,
+                       const bufferlist &in,
+                       map<int, bufferlist> *encoded);
+
+    virtual int encode_chunks(const set<int> &want_to_encode,
+                              map<int, bufferlist> *encoded);
+
+    virtual int decode(const set<int> &want_to_read,
+                       const map<int, bufferlist> &chunks,
+                       map<int, bufferlist> *decoded);
+
+    virtual int decode_chunks(const set<int> &want_to_read,
+                              const map<int, bufferlist> &chunks,
+                              map<int, bufferlist> *decoded);
+
   };
 }
 
index 63de14e6ab011097414c1fe960cf0f2d7a4e1c8d..06ee373357af31fe9582b3325d6ca8bd9031e8b3 100644 (file)
@@ -302,6 +302,10 @@ namespace ceph {
                        const bufferlist &in,
                        map<int, bufferlist> *encoded) = 0;
 
+
+    virtual int encode_chunks(const set<int> &want_to_encode,
+                              map<int, bufferlist> *encoded) = 0;
+
     /**
      * Decode the **chunks** and store at least **want_to_read**
      * chunks in **decoded**.
@@ -339,6 +343,10 @@ namespace ceph {
                        const map<int, bufferlist> &chunks,
                        map<int, bufferlist> *decoded) = 0;
 
+    virtual int decode_chunks(const set<int> &want_to_read,
+                              const map<int, bufferlist> &chunks,
+                              map<int, bufferlist> *decoded) = 0;
+
     /**
      * Decode the first **get_data_chunk_count()** **chunks** and
      * concatenate them them into **decoded**.
index 0722374d9a7628aa02fdcf34d1c1bd3aa3b42574..da381a3dd246f4533a7aa328f68ac9fbd48cc769 100644 (file)
@@ -115,104 +115,38 @@ ErasureCodeIsa::minimum_to_decode_with_cost(const set<int> &want_to_read,
   return minimum_to_decode(want_to_read, available_chunks, minimum);
 }
 
-// -----------------------------------------------------------------------------
-
-int
-ErasureCodeIsa::encode(const set<int> &want_to_encode,
-                       const bufferlist &in,
-                       map<int, bufferlist> *encoded)
+int ErasureCodeIsa::encode_chunks(const set<int> &want_to_encode,
+                                  map<int, bufferlist> *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<int> &want_to_read,
-                       const map<int, bufferlist> &chunks,
-                       map<int, bufferlist> *decoded)
+int ErasureCodeIsa::decode_chunks(const set<int> &want_to_read,
+                                  const map<int, bufferlist> &chunks,
+                                  map<int, bufferlist> *decoded)
 {
-  vector<int> have;
-  have.reserve(chunks.size());
-
-  for (map<int, bufferlist>::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<int>::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);
 }
 
 // -----------------------------------------------------------------------------
index 385a8438fa313079064d48b7fe6f9d0b8d8e5a55..136ef5d5d62a16b5d81d2f18592c7691f31409ce 100644 (file)
 
 // -----------------------------------------------------------------------------
 #include "common/Mutex.h"
-#include "erasure-code/ErasureCodeInterface.h"
+#include "erasure-code/ErasureCode.h"
 // -----------------------------------------------------------------------------
 #include <list>
 // -----------------------------------------------------------------------------
 
-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<int> &want_to_read,
                                 const set<int> &available_chunks,
                                 set<int> *minimum);
+  virtual int encode_chunks(const set<int> &want_to_encode,
+                           map<int, bufferlist> *encoded);
 
   virtual int minimum_to_decode_with_cost(const set<int> &want_to_read,
                                           const map<int, int> &available,
                                           set<int> *minimum);
 
-  virtual int encode(const set<int> &want_to_encode,
-                     const bufferlist &in,
-                     map<int, bufferlist> *encoded);
-
-  virtual int decode(const set<int> &want_to_read,
-                     const map<int, bufferlist> &chunks,
-                     map<int, bufferlist> *decoded);
+  virtual int decode_chunks(const set<int> &want_to_read,
+                           const map<int, bufferlist> &chunks,
+                           map<int, bufferlist> *decoded);
 
   void init(const map<std::string, std::string> &parameters);
 
index e207c3aa612b9f81baf293967cbfc1d0a27074c8..b35e0bb47d575b9da6e4f9d41251c91f4883d19e 100644 (file)
@@ -14,8 +14,6 @@
  * 
  */
 
-#include <errno.h>
-#include <algorithm>
 #include "common/debug.h"
 #include "ErasureCodeJerasure.h"
 #include "crush/CrushWrapper.h"
@@ -116,59 +114,20 @@ int ErasureCodeJerasure::minimum_to_decode_with_cost(const set<int> &want_to_rea
   return minimum_to_decode(want_to_read, available_chunks, minimum);
 }
 
-int ErasureCodeJerasure::encode(const set<int> &want_to_encode,
-                                const bufferlist &in,
-                                map<int, bufferlist> *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<int> &want_to_encode,
+                                      map<int, bufferlist> *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<int> &want_to_read,
-                                const map<int, bufferlist> &chunks,
-                                map<int, bufferlist> *decoded)
+int ErasureCodeJerasure::decode_chunks(const set<int> &want_to_read,
+                                      const map<int, bufferlist> &chunks,
+                                      map<int, bufferlist> *decoded)
 {
-  vector<int> have;
-  have.reserve(chunks.size());
-  for (map<int, bufferlist>::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<int>::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<int> &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<int> &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,
index cda7e5bce218f8378db818183ca39967720c80ed..f7e5c3116b0f706790e966145928c612d6390a9f 100644 (file)
@@ -55,18 +55,16 @@ public:
   virtual int minimum_to_decode(const set<int> &want_to_read,
                                 const set<int> &available_chunks,
                                 set<int> *minimum);
+  virtual int encode_chunks(const set<int> &want_to_encode,
+                           map<int, bufferlist> *encoded);
 
   virtual int minimum_to_decode_with_cost(const set<int> &want_to_read,
                                           const map<int, int> &available,
                                           set<int> *minimum);
 
-  virtual int encode(const set<int> &want_to_encode,
-                     const bufferlist &in,
-                     map<int, bufferlist> *encoded);
-
-  virtual int decode(const set<int> &want_to_read,
-                     const map<int, bufferlist> &chunks,
-                     map<int, bufferlist> *decoded);
+  virtual int decode_chunks(const set<int> &want_to_read,
+                           const map<int, bufferlist> &chunks,
+                           map<int, bufferlist> *decoded);
 
   void init(const map<std::string,std::string> &parameters);
   virtual void jerasure_encode(char **data,
index e07a14237268d959fce1f6ab3ce051adb41e759f..2861b648c1ed79752a726b0df611ea6837f015c4 100644 (file)
@@ -138,6 +138,12 @@ public:
     return 0;
   }
 
+  virtual int encode_chunks(const set<int> &want_to_encode,
+                           map<int, bufferlist> *encoded) {
+    assert(0);
+    return 0;
+  }
+
   virtual int decode(const set<int> &want_to_read,
                      const map<int, bufferlist> &chunks,
                      map<int, bufferlist> *decoded) {
@@ -179,6 +185,14 @@ public:
     }
     return 0;
   }
+
+  virtual int decode_chunks(const set<int> &want_to_read,
+                           const map<int, bufferlist> &chunks,
+                           map<int, bufferlist> *decoded) {
+    assert(0);
+    return 0;
+  }
+
 };
 
 #endif