Skip to content

Commit 6b733e9

Browse files
jamieprydeaainscow
authored andcommitted
erasure-code: Rewrite the encode_chunks interface for all plugins
We have changed the encode_chunks interface to take an in map and an out map. The in map contains the data shards to be encoded. The out map contains the empty buffers that the plugin will write the parity data to. The old non-optimized EC path has been updated to call the new encode_chunks interface from erasurecode.cc The new EC optimizations path calls the encode_chunks interface from ECUtils. Signed-off-by: Jamie Pryde <[email protected]> Signed-off-by: Alex Ainscow <[email protected]>
1 parent 3a1106c commit 6b733e9

40 files changed

+2278
-831
lines changed

src/erasure-code/ErasureCode.cc

Lines changed: 213 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -119,11 +119,18 @@ int ErasureCode::sanity_check_k_m(int k, int m, ostream *ss)
119119
return 0;
120120
}
121121

122-
int ErasureCode::chunk_index(unsigned int i) const
122+
shard_id_t ErasureCode::chunk_index(raw_shard_id_t i) const
123123
{
124-
return chunk_mapping.size() > i ? chunk_mapping[i] : i;
124+
return chunk_mapping.size() > uint64_t(i) ? chunk_mapping[static_cast<int>(i)] : shard_id_t(int8_t(i));
125125
}
126126

127+
[[deprecated]]
128+
unsigned int ErasureCode::chunk_index(unsigned int i) const
129+
{
130+
return static_cast<unsigned int>(chunk_mapping.size() > uint64_t(i) ? chunk_mapping[i] : shard_id_t(i));
131+
}
132+
133+
[[deprecated]]
127134
int ErasureCode::_minimum_to_decode(const set<int> &want_to_read,
128135
const set<int> &available_chunks,
129136
set<int> *minimum)
@@ -143,6 +150,26 @@ int ErasureCode::_minimum_to_decode(const set<int> &want_to_read,
143150
return 0;
144151
}
145152

153+
int ErasureCode::_minimum_to_decode(const shard_id_set &want_to_read,
154+
const shard_id_set &available_chunks,
155+
shard_id_set *minimum)
156+
{
157+
if (available_chunks.includes(want_to_read)) {
158+
*minimum = want_to_read;
159+
} else {
160+
unsigned int k = get_data_chunk_count();
161+
if (available_chunks.size() < (unsigned)k)
162+
return -EIO;
163+
shard_id_set::const_iterator i;
164+
unsigned j;
165+
for (i = available_chunks.begin(), j = 0; j < (unsigned)k; ++i, j++)
166+
minimum->insert(*i);
167+
}
168+
return 0;
169+
}
170+
171+
IGNORE_DEPRECATED
172+
[[deprecated]]
146173
int ErasureCode::minimum_to_decode(const set<int> &want_to_read,
147174
const set<int> &available_chunks,
148175
map<int, vector<pair<int, int>>> *minimum)
@@ -159,7 +186,28 @@ int ErasureCode::minimum_to_decode(const set<int> &want_to_read,
159186
}
160187
return 0;
161188
}
189+
END_IGNORE_DEPRECATED
190+
191+
int ErasureCode::minimum_to_decode(const shard_id_set &want_to_read,
192+
const shard_id_set &available_chunks,
193+
shard_id_set &minimum_set,
194+
shard_id_map<vector<pair<int, int>>> *minimum_sub_chunks)
195+
{
196+
int r = _minimum_to_decode(want_to_read, available_chunks, &minimum_set);
197+
if (minimum_sub_chunks == nullptr) return r;
198+
if (r != 0) {
199+
return r;
200+
}
201+
vector<pair<int, int>> default_subchunks;
202+
default_subchunks.push_back(make_pair(0, get_sub_chunk_count()));
203+
for (auto &&id : minimum_set) {
204+
minimum_sub_chunks->emplace(id, default_subchunks);
205+
}
206+
return 0;
207+
}
162208

209+
IGNORE_DEPRECATED
210+
[[deprecated]]
163211
int ErasureCode::minimum_to_decode_with_cost(const set<int> &want_to_read,
164212
const map<int, int> &available,
165213
set<int> *minimum)
@@ -171,7 +219,22 @@ int ErasureCode::minimum_to_decode_with_cost(const set<int> &want_to_read,
171219
available_chunks.insert(i->first);
172220
return _minimum_to_decode(want_to_read, available_chunks, minimum);
173221
}
222+
END_IGNORE_DEPRECATED
174223

224+
int ErasureCode::minimum_to_decode_with_cost(const shard_id_set &want_to_read,
225+
const shard_id_map<int> &available,
226+
shard_id_set *minimum)
227+
{
228+
shard_id_set available_chunks;
229+
for (shard_id_map<int>::const_iterator i = available.begin();
230+
i != available.end();
231+
++i)
232+
available_chunks.insert(i->first);
233+
return _minimum_to_decode(want_to_read, available_chunks, minimum);
234+
}
235+
236+
IGNORE_DEPRECATED
237+
[[deprecated]]
175238
int ErasureCode::encode_prepare(const bufferlist &raw,
176239
map<int, bufferlist> &encoded) const
177240
{
@@ -208,7 +271,47 @@ int ErasureCode::encode_prepare(const bufferlist &raw,
208271

209272
return 0;
210273
}
274+
END_IGNORE_DEPRECATED
275+
276+
int ErasureCode::encode_prepare(const bufferlist &raw,
277+
shard_id_map<bufferlist> &encoded) const
278+
{
279+
unsigned int k = get_data_chunk_count();
280+
unsigned int m = get_chunk_count() - k;
281+
unsigned blocksize = get_chunk_size(raw.length());
282+
unsigned padded_chunks = k - raw.length() / blocksize;
283+
bufferlist prepared = raw;
284+
285+
for (raw_shard_id_t i; i < k - padded_chunks; ++i) {
286+
bufferlist &chunk = encoded[chunk_index(i)];
287+
chunk.substr_of(prepared, (int)i * blocksize, blocksize);
288+
chunk.rebuild_aligned_size_and_memory(blocksize, SIMD_ALIGN);
289+
ceph_assert(chunk.is_contiguous());
290+
}
291+
if (padded_chunks) {
292+
unsigned remainder = raw.length() - (k - padded_chunks) * blocksize;
293+
bufferptr buf(buffer::create_aligned(blocksize, SIMD_ALIGN));
294+
295+
raw.begin((k - padded_chunks) * blocksize).copy(remainder, buf.c_str());
296+
buf.zero(remainder, blocksize - remainder);
297+
encoded[chunk_index(raw_shard_id_t(k - padded_chunks))].push_back(std::move(buf));
298+
299+
for (raw_shard_id_t i(k - padded_chunks + 1); i < k; ++i) {
300+
bufferptr buf(buffer::create_aligned(blocksize, SIMD_ALIGN));
301+
buf.zero();
302+
encoded[chunk_index(i)].push_back(std::move(buf));
303+
}
304+
}
305+
for (raw_shard_id_t i(k); i < k + m; ++i) {
306+
bufferlist &chunk = encoded[chunk_index(i)];
307+
chunk.push_back(buffer::create_aligned(blocksize, SIMD_ALIGN));
308+
}
309+
310+
return 0;
311+
}
211312

313+
IGNORE_DEPRECATED
314+
[[deprecated]]
212315
int ErasureCode::encode(const set<int> &want_to_encode,
213316
const bufferlist &in,
214317
map<int, bufferlist> *encoded)
@@ -226,7 +329,46 @@ int ErasureCode::encode(const set<int> &want_to_encode,
226329
}
227330
return 0;
228331
}
332+
END_IGNORE_DEPRECATED
333+
334+
int ErasureCode::encode(const shard_id_set &want_to_encode,
335+
const bufferlist &in,
336+
shard_id_map<bufferlist> *encoded)
337+
{
338+
unsigned int k = get_data_chunk_count();
339+
unsigned int m = get_chunk_count() - k;
340+
341+
if (!encoded || !encoded->empty()){
342+
return -EINVAL;
343+
}
344+
int err = encode_prepare(in, *encoded);
345+
if (err)
346+
return err;
347+
348+
shard_id_map<bufferptr> in_shards(get_chunk_count());
349+
shard_id_map<bufferptr> out_shards(get_chunk_count());
350+
351+
for (raw_shard_id_t raw_shard; raw_shard < get_chunk_count(); ++raw_shard) {
352+
shard_id_t shard = chunk_index(raw_shard);
353+
if (!encoded->contains(shard)) continue;
354+
355+
auto bp = encoded->at(shard).begin().get_current_ptr();
356+
ceph_assert(bp.length() == encoded->at(shard).length());
357+
358+
if (raw_shard < k) in_shards[shard] = bp;
359+
else out_shards[shard] = bp;
360+
}
361+
362+
encode_chunks(in_shards, out_shards);
363+
for (shard_id_t i; i < k + m; ++i) {
364+
if (want_to_encode.count(i) == 0)
365+
encoded->erase(i);}
366+
367+
return 0;
368+
}
229369

370+
IGNORE_DEPRECATED
371+
[[deprecated]]
230372
int ErasureCode::_decode(const set<int> &want_to_read,
231373
const map<int, bufferlist> &chunks,
232374
map<int, bufferlist> *decoded)
@@ -264,21 +406,84 @@ int ErasureCode::_decode(const set<int> &want_to_read,
264406
}
265407
return decode_chunks(want_to_read, chunks, decoded);
266408
}
409+
END_IGNORE_DEPRECATED
267410

411+
int ErasureCode::_decode(const shard_id_set &want_to_read,
412+
const shard_id_map<bufferlist> &chunks,
413+
shard_id_map<bufferlist> *decoded)
414+
{
415+
shard_id_set have;
416+
417+
if (!decoded || !decoded->empty()){
418+
return -EINVAL;
419+
}
420+
if (!want_to_read.empty() && chunks.empty()) {
421+
return -1;
422+
}
423+
424+
for (auto &&[shard, _] : chunks) {
425+
have.insert(shard);
426+
}
427+
if (have.includes(want_to_read)) {
428+
for (auto &&shard : want_to_read) {
429+
(*decoded)[shard] = chunks.at(shard);
430+
}
431+
return 0;
432+
}
433+
unsigned int k = get_data_chunk_count();
434+
unsigned int m = get_chunk_count() - k;
435+
unsigned blocksize = (*chunks.begin()).second.length();
436+
shard_id_set erasures;
437+
for (shard_id_t i; i < k + m; ++i) {
438+
if (!chunks.contains(i)) {
439+
bufferlist tmp;
440+
bufferptr ptr(buffer::create_aligned(blocksize, SIMD_ALIGN));
441+
tmp.push_back(ptr);
442+
tmp.claim_append((*decoded)[i]);
443+
(*decoded)[i].swap(tmp);
444+
erasures.insert(i);
445+
} else {
446+
(*decoded)[i] = chunks.find(i)->second;
447+
(*decoded)[i].rebuild_aligned(SIMD_ALIGN);
448+
}
449+
bufferlist &bl = (*decoded)[i];
450+
if (bl.length() != bl.begin().get_current_ptr().length()) {
451+
bl.rebuild();
452+
}
453+
}
454+
shard_id_map<bufferptr> in(get_chunk_count());
455+
shard_id_map<bufferptr> out(get_chunk_count());
456+
for (auto&& [shard, list] : *decoded) {
457+
auto bp = list.begin().get_current_ptr();
458+
ceph_assert(bp.length() == list.length());
459+
if (erasures.find(shard) == erasures.end()) in[shard] = bp;
460+
else out[shard] = bp;
461+
}
462+
return decode_chunks(want_to_read, in, out);
463+
}
464+
465+
[[deprecated]]
268466
int ErasureCode::decode(const set<int> &want_to_read,
269467
const map<int, bufferlist> &chunks,
270468
map<int, bufferlist> *decoded, int chunk_size)
271469
{
272470
return _decode(want_to_read, chunks, decoded);
273471
}
274472

473+
int ErasureCode::decode(const shard_id_set &want_to_read,
474+
const shard_id_map<bufferlist> &chunks,
475+
shard_id_map<bufferlist> *decoded, int chunk_size)
476+
{
477+
return _decode(want_to_read, chunks, decoded);
478+
}
479+
275480
int ErasureCode::parse(const ErasureCodeProfile &profile,
276481
ostream *ss)
277482
{
278483
return to_mapping(profile, ss);
279484
}
280485

281-
const vector<int> &ErasureCode::get_chunk_mapping() const {
486+
const vector<shard_id_t> &ErasureCode::get_chunk_mapping() const {
282487
return chunk_mapping;
283488
}
284489

@@ -291,7 +496,7 @@ int ErasureCode::to_mapping(const ErasureCodeProfile &profile,
291496
vector<int> coding_chunk_mapping;
292497
for(std::string::iterator it = mapping.begin(); it != mapping.end(); ++it) {
293498
if (*it == 'D')
294-
chunk_mapping.push_back(position);
499+
chunk_mapping.push_back(shard_id_t(position));
295500
else
296501
coding_chunk_mapping.push_back(position);
297502
position++;
@@ -353,6 +558,8 @@ int ErasureCode::to_string(const std::string &name,
353558
return 0;
354559
}
355560

561+
IGNORE_DEPRECATED
562+
[[deprecated]]
356563
int ErasureCode::decode_concat(const set<int>& want_to_read,
357564
const map<int, bufferlist> &chunks,
358565
bufferlist *decoded)
@@ -375,6 +582,7 @@ int ErasureCode::decode_concat(const set<int>& want_to_read,
375582
return r;
376583
}
377584

585+
[[deprecated]]
378586
int ErasureCode::decode_concat(const map<int, bufferlist> &chunks,
379587
bufferlist *decoded)
380588
{
@@ -384,4 +592,5 @@ int ErasureCode::decode_concat(const map<int, bufferlist> &chunks,
384592
}
385593
return decode_concat(want_to_read, chunks, decoded);
386594
}
595+
END_IGNORE_DEPRECATED
387596
}

0 commit comments

Comments
 (0)