| 237 | } |
| 238 | |
| 239 | [[deprecated]] |
| 240 | int _decode(const std::set<int> &want_to_read, |
| 241 | const std::map<int, bufferlist> &chunks, |
| 242 | std::map<int, bufferlist> *decoded) override { |
| 243 | // |
| 244 | // All chunks have the same size |
| 245 | // |
| 246 | unsigned chunk_length = (*chunks.begin()).second.length(); |
| 247 | for (std::set<int>::iterator i = want_to_read.begin(); |
| 248 | i != want_to_read.end(); |
| 249 | ++i) { |
| 250 | if (chunks.find(*i) != chunks.end()) { |
| 251 | // |
| 252 | // If the chunk is available, just copy the bufferptr pointer |
| 253 | // to the decoded argument. |
| 254 | // |
| 255 | (*decoded)[*i] = chunks.find(*i)->second; |
| 256 | } else if(chunks.size() != 2) { |
| 257 | // |
| 258 | // If a chunk is missing and there are not enough chunks |
| 259 | // to recover, abort. |
| 260 | // |
| 261 | return -ERANGE; |
| 262 | } else { |
| 263 | // |
| 264 | // No matter what the missing chunk is, XOR of the other |
| 265 | // two recovers it. |
| 266 | // |
| 267 | std::map<int, bufferlist>::const_iterator k = chunks.begin(); |
| 268 | const char *a = k->second.front().c_str(); |
| 269 | ++k; |
| 270 | const char *b = k->second.front().c_str(); |
| 271 | bufferptr chunk(chunk_length); |
| 272 | char *c = chunk.c_str(); |
| 273 | for (unsigned j = 0; j < chunk_length; j++) { |
| 274 | c[j] = a[j] ^ b[j]; |
| 275 | } |
| 276 | |
| 277 | bufferlist tmp; |
| 278 | tmp.append(chunk); |
| 279 | tmp.claim_append((*decoded)[*i]); |
| 280 | (*decoded)[*i].swap(tmp); |
| 281 | } |
| 282 | } |
| 283 | return 0; |
| 284 | } |
| 285 | |
| 286 | |
| 287 | int _decode(const shard_id_set &want_to_read, |
no test coverage detected