From: Loic Dachary Date: Fri, 20 Dec 2013 00:43:12 +0000 (+0100) Subject: erasure-code: erasure code decode interface helper X-Git-Tag: v0.78~335^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=refs%2Fpull%2F963%2Fhead;p=ceph.git erasure-code: erasure code decode interface helper 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 --- diff --git a/src/osd/ErasureCodeInterface.h b/src/osd/ErasureCodeInterface.h index 52845f61a32..f123adefded 100644 --- a/src/osd/ErasureCodeInterface.h +++ b/src/osd/ErasureCodeInterface.h @@ -318,6 +318,29 @@ namespace ceph { virtual int decode(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**. + * + * 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 &chunks, + bufferlist *decoded) { + set want_to_read; + for (unsigned int i = 0; i < get_data_chunk_count(); i++) + want_to_read.insert(i); + map 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 ErasureCodeInterfaceRef; diff --git a/src/test/osd/TestErasureCodeExample.cc b/src/test/osd/TestErasureCodeExample.cc index 17e77a0bdaa..faa863ec2ac 100644 --- a/src/test/osd/TestErasureCodeExample.cc +++ b/src/test/osd/TestErasureCodeExample.cc @@ -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 encoded; + EXPECT_EQ(0, example.encode(set(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 degraded; + degraded[0] = encoded[0]; + EXPECT_EQ(-ERANGE, example.decode_concat(degraded, &out)); +} + int main(int argc, char **argv) { vector 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: + */ +