mirror of
https://github.com/ceph/ceph
synced 2025-02-20 17:37:29 +00:00
EC-ISA: provide a 10% faster simple parity operation for (k, m=1). Add simple parity unit test for k=4,m=1
This commit is contained in:
parent
3de7b7c52c
commit
516101ae99
@ -248,8 +248,13 @@ ErasureCodeIsaDefault::isa_encode(char **data,
|
||||
char **coding,
|
||||
int blocksize)
|
||||
{
|
||||
ec_encode_data(blocksize, k, m, g_encode_tbls,
|
||||
(unsigned char**) data, (unsigned char**) coding);
|
||||
|
||||
if (m==1)
|
||||
// single parity stripe
|
||||
region_xor( (unsigned char**) data, (unsigned char*) coding[0], k, blocksize );
|
||||
else
|
||||
ec_encode_data(blocksize, k, m, g_encode_tbls,
|
||||
(unsigned char**) data, (unsigned char**) coding);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@ -382,6 +387,15 @@ ErasureCodeIsaDefault::isa_decode(int *erasures,
|
||||
}
|
||||
}
|
||||
|
||||
if (m==1) {
|
||||
// single parity decoding
|
||||
assert (1 == nerrs);
|
||||
dout(20) << "isa_decode: reconstruct using region xor [" << erasures[0] << "]" << dendl;
|
||||
region_xor(recover_source, recover_target[0], k, blocksize);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
if ((matrixtype == kVandermonde) &&
|
||||
(nerrs == 1) &&
|
||||
(erasures[0] < (k + 1))) {
|
||||
|
@ -137,7 +137,7 @@ public:
|
||||
return g_decode_tbls_lru.size();
|
||||
}
|
||||
|
||||
// we implement an LRU cache for coding matrix - the cache size is sufficient up to (10,4) decodings
|
||||
// we implement an LRU cache for coding matrix - the cache size is sufficient up to (12,4) decodings
|
||||
typedef std::pair<std::list<std::string>::iterator, bufferptr> lru_entry_t;
|
||||
|
||||
std::map<std::string, lru_entry_t> g_decode_tbls_map;
|
||||
|
@ -607,6 +607,104 @@ TYPED_TEST(IsaErasureCodeTest, isa_cauchy_exhaustive)
|
||||
EXPECT_EQ(2516, Isa.get_tbls_lru_size());
|
||||
}
|
||||
|
||||
TYPED_TEST(IsaErasureCodeTest, isa_xor_codec)
|
||||
{
|
||||
// Test all possible failure scenarios and reconstruction cases for
|
||||
// a (4,1) RAID-5 like configuration
|
||||
|
||||
TypeParam Isa;
|
||||
map<std::string, std::string> parameters;
|
||||
parameters["k"] = "4";
|
||||
parameters["m"] = "1";
|
||||
Isa.init(parameters);
|
||||
|
||||
int k = 4;
|
||||
int m = 1;
|
||||
|
||||
#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"
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||
in_ptr.append(payload, strlen(payload));
|
||||
bufferlist in;
|
||||
in.push_front(in_ptr);
|
||||
|
||||
set<int>want_to_encode;
|
||||
|
||||
map<int, bufferlist> encoded;
|
||||
for (int i = 0; i < (k + m); i++) {
|
||||
want_to_encode.insert(i);
|
||||
}
|
||||
|
||||
|
||||
EXPECT_EQ(0, Isa.encode(want_to_encode,
|
||||
in,
|
||||
&encoded));
|
||||
|
||||
EXPECT_EQ((unsigned) (k + m), encoded.size());
|
||||
|
||||
unsigned length = encoded[0].length();
|
||||
|
||||
for (int i = 0; i < k; i++) {
|
||||
EXPECT_EQ(0, strncmp(encoded[i].c_str(), in.c_str() + (i * length), length));
|
||||
}
|
||||
|
||||
buffer::ptr enc[k + m];
|
||||
// create buffers with a copy of the original data to be able to compare it after decoding
|
||||
{
|
||||
for (int i = 0; i < (k + m); i++) {
|
||||
buffer::ptr newenc(buffer::create_page_aligned(LARGE_ENOUGH));
|
||||
enc[i] = newenc;
|
||||
enc[i].zero();
|
||||
enc[i].set_length(0);
|
||||
enc[i].append(encoded[i].c_str(), length);
|
||||
}
|
||||
}
|
||||
|
||||
// loop through all possible loss scenarios
|
||||
bool err = true;
|
||||
int cnt_cf = 0;
|
||||
|
||||
for (int l1 = 0; l1 < (k + m); l1++) {
|
||||
map<int, bufferlist> degraded = encoded;
|
||||
set<int> want_to_decode;
|
||||
degraded.erase(l1);
|
||||
want_to_decode.insert(l1);
|
||||
err = DecodeAndVerify(Isa, degraded, want_to_decode, enc, length);
|
||||
EXPECT_EQ(0, err);
|
||||
cnt_cf++;
|
||||
degraded[l1] = encoded[l1];
|
||||
want_to_decode.erase(l1);
|
||||
}
|
||||
EXPECT_EQ(5, cnt_cf);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
vector<const char*> args;
|
||||
|
Loading…
Reference in New Issue
Block a user