]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
erasure-code: erasure code decode interface helper 963/head
authorLoic Dachary <loic@dachary.org>
Fri, 20 Dec 2013 00:43:12 +0000 (01:43 +0100)
committerLoic Dachary <loic@dachary.org>
Fri, 10 Jan 2014 18:44:09 +0000 (19:44 +0100)
The decode_concat method is implemented, documented and tested. It is a
convenience method to concatenate chunks into a single bufferlist.

Signed-off-by: Loic Dachary <loic@dachary.org>
src/osd/ErasureCodeInterface.h
src/test/osd/TestErasureCodeExample.cc

index 52845f61a3229746a4c6d2ee498fad179f3bd45e..f123adefded3213049564716d41cf1d180f43379 100644 (file)
@@ -318,6 +318,29 @@ namespace ceph {
     virtual int decode(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**.
+     *
+     * Returns 0 on success.
+     *
+     * @param [in] chunks map chunk indexes to chunk data
+     * @param [out] decoded concatenante of the data chunks
+     * @return **0** on success or a negative errno on error.
+     */
+    int decode_concat(const map<int, bufferlist> &chunks,
+                     bufferlist *decoded) {
+      set<int> want_to_read;
+      for (unsigned int i = 0; i < get_data_chunk_count(); i++)
+       want_to_read.insert(i);
+      map<int, bufferlist> decoded_map;
+      int r = decode(want_to_read, chunks, &decoded_map);
+      if (r == 0)
+       for (unsigned int i = 0; i < get_data_chunk_count(); i++)
+         decoded->claim_append(decoded_map[i]);
+      return r;
+    }
   };
 
   typedef std::tr1::shared_ptr<ErasureCodeInterface> ErasureCodeInterfaceRef;
index 17e77a0bdaac63a92f0fc628b82342e07b3a9e92..faa863ec2acca00f221af22e4749a6489b163879 100644 (file)
@@ -164,6 +164,43 @@ TEST(ErasureCodeExample, encode_decode)
   }
 }
 
+TEST(ErasureCodeExample, decode)
+{
+  ErasureCodeExample example;
+
+#define LARGE_ENOUGH 2048
+  bufferptr in_ptr(buffer::create_page_aligned(LARGE_ENOUGH));
+  in_ptr.zero();
+  in_ptr.set_length(0);
+  const char *payload =
+    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
+    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
+    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
+    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
+    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
+  in_ptr.append(payload, strlen(payload));
+  bufferlist in;
+  in.push_front(in_ptr);
+  int want_to_encode[] = { 0, 1, 2 };
+  map<int, bufferlist> encoded;
+  EXPECT_EQ(0, example.encode(set<int>(want_to_encode, want_to_encode+3),
+                              in,
+                              &encoded));
+  EXPECT_EQ(3u, encoded.size());
+
+  // successfull decode
+  bufferlist out;
+  EXPECT_EQ(0, example.decode_concat(encoded, &out));
+  bufferlist usable;
+  usable.substr_of(out, 0, in.length());
+  EXPECT_TRUE(usable == in);
+
+  // cannot recover
+  map<int, bufferlist> degraded;  
+  degraded[0] = encoded[0];
+  EXPECT_EQ(-ERANGE, example.decode_concat(degraded, &out));
+}
+
 int main(int argc, char **argv) {
   vector<const char*> args;
   argv_to_vec(argc, (const char **)argv, args);
@@ -175,6 +212,15 @@ int main(int argc, char **argv) {
   return RUN_ALL_TESTS();
 }
 
-// Local Variables:
-// compile-command: "cd ../.. ; make -j4 && make unittest_erasure_code_example && valgrind  --leak-check=full --tool=memcheck ./unittest_erasure_code_example --gtest_filter=*.* --log-to-stderr=true --debug-osd=20"
-// End:
+/*
+ * Local Variables:
+ * compile-command: "cd ../.. ; 
+ *   make -j4 && 
+ *   make unittest_erasure_code_example && 
+ *   valgrind  --leak-check=full --tool=memcheck \
+ *      ./unittest_erasure_code_example --gtest_filter=*.* \
+ *      --log-to-stderr=true --debug-osd=20
+ * "
+ * End:
+ */
+