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;
}
}
+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);
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:
+ */
+