int r = _decode(want_to_read, chunks, &decoded_map);
if (r == 0) {
for (unsigned int i = 0; i < get_data_chunk_count(); i++) {
- if (decoded_map.contains(chunk_index(i))) {
+ // XXX: the ErasureCodeInterface allows `decode()` to return
+ // *at least* `want_to_read chunks`; that is, they may more.
+ // Some implementations are consistently exact but jerasure
+ // is quirky: it outputs more only when deailing with degraded.
+ // The check below uniforms the behavior.
+ if (want_to_read.contains(chunk_index(i)) &&
+ decoded_map.contains(chunk_index(i))) {
decoded->claim_append(decoded_map[chunk_index(i)]);
}
}
bufferlist out;
EXPECT_EQ(0, example.decode_concat(encoded, &out));
bufferlist usable;
+ EXPECT_EQ(2u*encoded[0].length(), out.length());
usable.substr_of(out, 0, in.length());
EXPECT_TRUE(usable == in);
// partial chunk decode
- map<int, bufferlist> partial_decode;
- partial_decode[0] = encoded[0];
+ map<int, bufferlist> partial_decode = encoded;
set<int> partial_want_to_read{want_to_encode, want_to_encode+1};
+ EXPECT_EQ(1u, partial_want_to_read.size());
+ out.clear();
EXPECT_EQ(0, example.decode_concat(partial_want_to_read,
partial_decode,
&out));
+ EXPECT_EQ(out.length(), encoded[0].length());
+
+ // partial degraded chunk decode
+ partial_decode = encoded;
+ partial_decode.erase(0);
+ EXPECT_EQ(1, partial_want_to_read.size());
+ out.clear();
+ EXPECT_EQ(0, example.decode_concat(partial_want_to_read,
+ partial_decode,
+ &out));
+ EXPECT_EQ(out.length(), encoded[0].length());
// cannot recover
map<int, bufferlist> degraded;
EXPECT_EQ(0, memcmp(decoded[1].c_str(), in.c_str() + length,
in.length() - length));
}
+
+ // partial decode with the exact-sized decode_concat()
+ {
+ map<int, bufferlist> partial_decode = encoded;
+ // we have everything but want only the first chunk
+ set<int> partial_want_to_read = { 0 };
+ EXPECT_EQ(1u, partial_want_to_read.size());
+ bufferlist out;
+ EXPECT_EQ(0, jerasure.decode_concat(partial_want_to_read,
+ partial_decode,
+ &out));
+ EXPECT_EQ(out.length(), partial_decode[0].length());
+ }
+
+ // partial degraded decode with the exact-sized decode_concat()
+ {
+ map<int, bufferlist> partial_decode = encoded;
+ // we have everything but what we really want
+ partial_decode.erase(0);
+ set<int> partial_want_to_read = { 0 };
+ EXPECT_EQ(1u, partial_want_to_read.size());
+ bufferlist out;
+ EXPECT_EQ(0, jerasure.decode_concat(partial_want_to_read,
+ partial_decode,
+ &out));
+ EXPECT_EQ(out.length(), encoded[0].length());
+ }
}
}