liberasurecode 1.8.0
Erasure Code API library
Loading...
Searching...
No Matches
xor_hd_code.c
Go to the documentation of this file.
1/* * Copyright (c) 2013, Kevin Greenan (kmgreen2@gmail.com)
2 * All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * Redistributions of source code must retain the above copyright notice, this
8 * list of conditions and the following disclaimer.
9 *
10 * Redistributions in binary form must reproduce the above copyright notice, this
11 * list of conditions and the following disclaimer in the documentation and/or
12 * other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY
13 * THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
14 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
15 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
16 * EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
17 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
18 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
19 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
20 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
21 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
22 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 */
24
25#include <stdio.h>
26#include <stdlib.h>
27#include <string.h>
28#include "xor_code.h"
29#include "xor_hd_code_defs.h"
30
31/*
32 * Returns -1 if not possible
33 */
34static int fragments_needed_one_data(xor_code_t *code_desc, int *missing_data, int *missing_parity, unsigned int *data_bm, unsigned int *parity_bm)
35{
36 int data_index = missing_data[0];
37 int parity_index = index_of_connected_parity(code_desc, data_index, missing_parity, missing_data);
38
39 if (parity_index < 0) {
40 return -1;
41 }
42
43 // Include all data elements except for this one
44 *data_bm |= (code_desc->parity_bms[parity_index-code_desc->k]);
45
46 // Include this parity element
47 *parity_bm |= (1 << (parity_index-code_desc->k));
48 *data_bm &= ~((unsigned int)1 << data_index);
49
50 return 0;
51}
52
53/*
54 * Returns -1 if not possible
55 */
56static int fragments_needed_two_data(xor_code_t *code_desc, int *missing_data, int *missing_parity, unsigned int *data_bm, unsigned int *parity_bm)
57{
58 // Verify that missing_data[2] == -1?
59 int data_index = missing_data[0];
60 int parity_index = index_of_connected_parity(code_desc, data_index, missing_parity, missing_data);
61 int ret;
62
63 if (parity_index < 0) {
64 data_index = missing_data[1];
65 parity_index = index_of_connected_parity(code_desc, data_index, missing_parity, missing_data);
66 if (parity_index < 0) {
67 return -1;
68 }
69 missing_data[1] = -1;
70 } else {
71 missing_data[0] = missing_data[1];
72 missing_data[1] = -1;
73 }
74
75 // Include all data elements except for this one
76 *data_bm |= (code_desc->parity_bms[parity_index-code_desc->k]);
77
78 // Include this parity element
79 *parity_bm |= (1 << (parity_index-code_desc->k));
80
81 ret = fragments_needed_one_data(code_desc, missing_data, missing_parity, data_bm, parity_bm);
82
83 *data_bm &= ~((unsigned int)1 << data_index);
84
85 return ret;
86}
87
88/*
89 * Returns -1 if not possible
90 */
91static int fragments_needed_three_data(xor_code_t *code_desc, int *missing_data, int *missing_parity, unsigned int *data_bm, unsigned int *parity_bm)
92{
93 int i = 0;
94 int parity_index = -1;
95 int data_index = -1;
96 int tmp_parity_bm = -1;
97 int contains_2d = -1;
98 int contains_3d = -1;
99 int ret = 0;
100
101 /*
102 * Try to find a parity that only contains
103 * one of the missing data elements.
104 */
105 while (missing_data[i] > -1) {
106 parity_index = index_of_connected_parity(code_desc, missing_data[i], missing_parity, missing_data);
107 if (parity_index > -1) {
108 data_index = missing_data[i];
109 tmp_parity_bm = code_desc->parity_bms[parity_index-code_desc->k];
110 break;
111 }
112 i++;
113 }
114 /*
115 * If we cannot find a parity that is connected to only
116 * one missing element, we must find a parity that is
117 * connected to exactly 2 (P) and another that is connected
118 * to exactly 3 (Q) (it should exist!!!).
119 *
120 * We XOR those parities together and use it to recover
121 * the element that is not connected to P.
122 */
123 if (parity_index < 0) {
124
125 for (i=0;i < code_desc->m;i++) {
126 int num_missing = num_missing_data_in_parity(code_desc, code_desc->k+i, missing_data);
127 if (num_missing == 2 && contains_2d < 0) {
128 contains_2d = i;
129 } else if (num_missing == 3 && contains_3d < 0) {
130 contains_3d = i;
131 }
132 }
133
134 if (contains_2d < 0 || contains_3d < 0) {
135 return -1;
136 }
137
138 // P XOR Q
139 tmp_parity_bm = code_desc->parity_bms[contains_2d] ^ code_desc->parity_bms[contains_3d];
140
141 i=0;
142 data_index = -1;
143 while (missing_data[i] > -1) {
144 if (is_data_in_parity(missing_data[i], tmp_parity_bm)) {
145 data_index = missing_data[i];
146 break;
147 }
148 i++;
149 }
150
151 if (data_index < 0) {
152 return -1;
153 }
154 }
155
156 remove_from_missing_list(data_index, missing_data);
157
158 if (parity_index > -1) {
159 // Include this parity element
160 *parity_bm |= (1 << (parity_index-code_desc->k));
161 // Include all data elements except for this one
162 *data_bm |= code_desc->parity_bms[parity_index-code_desc->k];
163 } else {
164 // Include both parity elements
165 *parity_bm |= (1 << (contains_2d-code_desc->k));
166 *parity_bm |= (1 << (contains_3d-code_desc->k));
167 // And all other data elements that didn't cancel out
168 *data_bm |= tmp_parity_bm;
169 }
170
171 ret = fragments_needed_two_data(code_desc, missing_data, missing_parity, data_bm, parity_bm);
172
173 *data_bm &= ~((unsigned int)1 << data_index);
174
175 return ret;
176}
177
178static int fragments_needed_one_data_local(xor_code_t *code_desc,
179 int fragment_to_reconstruct,
180 int *fragments_to_exclude,
181 unsigned int *data_bm,
182 unsigned int *parity_bm)
183{
184 int *missing_data = get_missing_data(code_desc, fragments_to_exclude);
185 int *missing_parity = get_missing_parity(code_desc, fragments_to_exclude);
186 int parity_index = index_of_connected_parity(code_desc, fragment_to_reconstruct, missing_parity, missing_data);
187 free(missing_data);
188 free(missing_parity);
189
190 if (parity_index < 0) {
191 return -1;
192 }
193
194 // Include all data elements except for this one
195 *data_bm |= (code_desc->parity_bms[parity_index-code_desc->k]);
196
197 // Include this parity element
198 *parity_bm |= (1 << (parity_index-code_desc->k));
199 *data_bm &= ~((unsigned int)1 << fragment_to_reconstruct);
200
201 return 0;
202}
203
204int xor_hd_fragments_needed(xor_code_t *code_desc, int *fragments_to_reconstruct, int *fragments_to_exclude, int *fragments_needed)
205{
206 failure_pattern_t pattern = get_failure_pattern(code_desc, fragments_to_reconstruct);
207 unsigned int data_bm = 0, parity_bm = 0;
208 int ret = -1;
209 int *missing_idxs = NULL;
210 int i, j;
211
220 if (pattern == FAIL_PATTERN_1D_0P) {
221 // Since we have landed on this failure pattern, fragments_to_reconstruct[0] is defined.
222 ret = fragments_needed_one_data_local(code_desc, fragments_to_reconstruct[0], fragments_to_exclude, &data_bm, &parity_bm);
223 }
224
229 if (ret == -1) {
233 missing_idxs = (int*)malloc(sizeof(int)*(code_desc->k + code_desc->m));
234 if (NULL == missing_idxs) {
235 ret = -1;
236 goto out;
237 }
238
239 i = 0;
240 j = 0;
241 while (fragments_to_reconstruct[i] > -1) {
242 missing_idxs[j] = fragments_to_reconstruct[i];
243 i++;
244 j++;
245 }
246 i = 0;
247 while (fragments_to_exclude[i] > -1) {
248 missing_idxs[j] = fragments_to_exclude[i];
249 i++;
250 j++;
251 }
252 // End of list
253 missing_idxs[j] = -1;
254
255 pattern = get_failure_pattern(code_desc, missing_idxs);
256
257 switch(pattern) {
258 case FAIL_PATTERN_0D_0P:
259 break;
260 case FAIL_PATTERN_1D_0P:
261 {
262 int *missing_data = get_missing_data(code_desc, missing_idxs);
263 ret = fragments_needed_one_data(code_desc, missing_data, NULL, &data_bm, &parity_bm);
264 free(missing_data);
265 break;
266 }
267 case FAIL_PATTERN_2D_0P:
268 {
269 int *missing_data = get_missing_data(code_desc, missing_idxs);
270 ret = fragments_needed_two_data(code_desc, missing_data, NULL, &data_bm, &parity_bm);
271 free(missing_data);
272 break;
273 }
274 case FAIL_PATTERN_3D_0P:
275 {
276 int *missing_data = get_missing_data(code_desc, missing_idxs);
277 ret = fragments_needed_three_data(code_desc, missing_data, NULL, &data_bm, &parity_bm);
278 free(missing_data);
279 break;
280 }
281 case FAIL_PATTERN_1D_1P:
282 {
283 int *missing_data = get_missing_data(code_desc, missing_idxs);
284 int *missing_parity = get_missing_parity(code_desc, missing_idxs);
285 unsigned int missing_data_bm = missing_elements_bm(code_desc, missing_data, data_bit_lookup);
286 ret = fragments_needed_one_data(code_desc, missing_data, missing_parity, &data_bm, &parity_bm);
287 // OR all parities
288 i=0;
289 while (missing_parity[i] > -1) {
290 data_bm |= code_desc->parity_bms[missing_parity[i]-code_desc->k];
291 data_bm &= ~(missing_data_bm);
292 i++;
293 }
294 free(missing_parity);
295 free(missing_data);
296 break;
297 }
298 case FAIL_PATTERN_1D_2P:
299 {
300 int *missing_data = get_missing_data(code_desc, missing_idxs);
301 int *missing_parity = get_missing_parity(code_desc, missing_idxs);
302 int missing_data_bm = missing_elements_bm(code_desc, missing_data, data_bit_lookup);
303 ret = fragments_needed_one_data(code_desc, missing_data, missing_parity, &data_bm, &parity_bm);
304 // OR all parities
305 i=0;
306 while (missing_parity[i] > -1) {
307 data_bm |= code_desc->parity_bms[missing_parity[i]-code_desc->k];
308 data_bm &= ~(missing_data_bm);
309 i++;
310 }
311 free(missing_parity);
312 free(missing_data);
313 break;
314 }
315 case FAIL_PATTERN_2D_1P:
316 {
317 int *missing_data = get_missing_data(code_desc, missing_idxs);
318 int *missing_parity = get_missing_parity(code_desc, missing_idxs);
319 unsigned int missing_data_bm = missing_elements_bm(code_desc, missing_data, data_bit_lookup);
320 ret = fragments_needed_two_data(code_desc, missing_data, missing_parity, &data_bm, &parity_bm);
321 // OR all parities
322 i=0;
323 while (missing_parity[i] > -1) {
324 data_bm |= code_desc->parity_bms[missing_parity[i]-code_desc->k];
325 data_bm &= ~(missing_data_bm);
326 i++;
327 }
328 free(missing_parity);
329 free(missing_data);
330 break;
331 }
332 case FAIL_PATTERN_0D_1P:
333 {
334 int *missing_parity = get_missing_parity(code_desc, missing_idxs);
335 // OR all of the parities
336 i=0;
337 while (missing_parity[i] > -1) {
338 data_bm |= code_desc->parity_bms[missing_parity[i]-code_desc->k];
339 i++;
340 }
341 free(missing_parity);
342 ret = 0;
343 break;
344 }
345 case FAIL_PATTERN_0D_2P:
346 {
347 int *missing_parity = get_missing_parity(code_desc, missing_idxs);
348 // OR all of the parities
349 i=0;
350 while (missing_parity[i] > -1) {
351 data_bm |= code_desc->parity_bms[missing_parity[i]-code_desc->k];
352 i++;
353 }
354 free(missing_parity);
355 ret = 0;
356 break;
357 }
358 case FAIL_PATTERN_0D_3P:
359 {
360 int *missing_parity = get_missing_parity(code_desc, missing_idxs);
361 // OR all of the parities
362 i=0;
363 while (missing_parity[i] > -1) {
364 data_bm |= code_desc->parity_bms[missing_parity[i]-code_desc->k];
365 i++;
366 }
367 free(missing_parity);
368 ret = 0;
369 break;
370 }
371 case FAIL_PATTERN_GE_HD:
372 default:
373 ret = -1;
374 break;
375 }
376 }
377
378 if (ret >= 0) {
379 i=0;
380 j=0;
381 while (data_bm) {
382 if (data_bm & 1) {
383 fragments_needed[j] = i;
384 j++;
385 }
386 i++;
387 data_bm >>= 1;
388 }
389
390 i=0;
391 while (parity_bm) {
392 if (parity_bm & 1) {
393 fragments_needed[j] = i + code_desc->k;
394 j++;
395 }
396 i++;
397 parity_bm >>= 1;
398 }
399
400 fragments_needed[j] = -1;
401 }
402
403out:
404 if (NULL != missing_idxs) {
405 free(missing_idxs);
406 }
407
408 return ret;
409}
410
411/*
412 * There is one unavailable data element, so any available parity connected to
413 * the data element is sufficient to decode.
414 */
415static void decode_one_data(xor_code_t *code_desc, char **data, char **parity, int *missing_data, int *missing_parity, int blocksize)
416{
417 // Verify that missing_data[1] == -1?
418 int data_index = missing_data[0];
419 int parity_index = index_of_connected_parity(code_desc, data_index, missing_parity, missing_data);
420 int i;
421
422 // Copy the appropriate parity into the data buffer
423 fast_memcpy(data[data_index], parity[parity_index-code_desc->k], blocksize);
424
425 for (i=0; i < code_desc->k; i++) {
426 if (i != data_index && is_data_in_parity(i, code_desc->parity_bms[parity_index-code_desc->k])) {
427 xor_bufs_and_store(data[i], data[data_index], blocksize);
428 }
429 }
430}
431
432static int decode_two_data(xor_code_t *code_desc, char **data, char **parity, int *missing_data, int *missing_parity, int blocksize)
433{
434 // Verify that missing_data[2] == -1?
435 int data_index = missing_data[0];
436 int parity_index = index_of_connected_parity(code_desc, data_index, missing_parity, missing_data);
437 int i;
438
439 if (parity_index < 0) {
440 data_index = missing_data[1];
441 parity_index = index_of_connected_parity(code_desc, data_index, missing_parity, missing_data);
442 if (parity_index < 0) {
443 fprintf(stderr, "Shit is broken, cannot find a proper parity!!!\n");
444 return -2;
445 }
446 missing_data[1] = -1;
447 } else {
448 missing_data[0] = missing_data[1];
449 missing_data[1] = -1;
450 }
451
452 // Copy the appropriate parity into the data buffer
453 fast_memcpy(data[data_index], parity[parity_index-code_desc->k], blocksize);
454
455 for (i=0; i < code_desc->k; i++) {
456 if (i != data_index && is_data_in_parity(i, code_desc->parity_bms[parity_index-code_desc->k])) {
457 xor_bufs_and_store(data[i], data[data_index], blocksize);
458 }
459 }
460 decode_one_data(code_desc, data, parity, missing_data, missing_parity, blocksize);
461
462 return 0;
463}
464
465static int decode_three_data(xor_code_t *code_desc, char **data, char **parity, int *missing_data, int *missing_parity, int blocksize)
466{
467 int i = 0;
468 int parity_index = -1;
469 int data_index = -1;
470 unsigned int parity_bm = -1;
471 char *parity_buffer = NULL;
472
473 /*
474 * Try to find a parity that only contains
475 * one of the missing data elements.
476 */
477 while (missing_data[i] > -1) {
478 parity_index = index_of_connected_parity(code_desc, missing_data[i], missing_parity, missing_data);
479 if (parity_index > -1) {
480 data_index = missing_data[i];
481 parity_buffer = parity[parity_index-code_desc->k];
482 parity_bm = code_desc->parity_bms[parity_index-code_desc->k];
483 break;
484 }
485 i++;
486 }
487
488 /*
489 * If we cannot find a parity that is connected to only
490 * one missing element, we must find a parity that is
491 * connected to exactly 2 (P) and another that is connected
492 * to exactly 3 (Q) (it should exist!!!).
493 *
494 * We XOR those parities together and use it to recover
495 * the element that is not connected to P.
496 */
497 if (parity_index < 0) {
498 int contains_2d = -1;
499 int contains_3d = -1;
500
501 for (i=0;i < code_desc->m;i++) {
502 int num_missing = num_missing_data_in_parity(code_desc, code_desc->k+i, missing_data);
503 if (num_missing == 2 && contains_2d < 0) {
504 contains_2d = i;
505 } else if (num_missing == 3 && contains_3d < 0) {
506 contains_3d = i;
507 }
508 }
509
510 if (contains_2d < 0 || contains_3d < 0) {
511 fprintf(stderr, "Shit is broken, cannot find a proper parity (2 and 3-connected parities)!!!\n");
512 return -2;
513 }
514
515 if (posix_memalign((void **) &parity_buffer, 16, blocksize) != 0) {
516 fprintf(stderr, "Can't get aligned memory!\n");
517 return -1;
518 }
519
520 // P XOR Q
521 parity_bm = code_desc->parity_bms[contains_2d] ^ code_desc->parity_bms[contains_3d];
522
523 // Create buffer with P XOR Q -> parity_buffer
524 fast_memcpy(parity_buffer, parity[contains_2d], blocksize);
525 xor_bufs_and_store(parity[contains_3d], parity_buffer, blocksize);
526
527 i=0;
528 data_index = -1;
529 while (missing_data[i] > -1) {
530 if (is_data_in_parity(missing_data[i], parity_bm)) {
531 data_index = missing_data[i];
532 break;
533 }
534 i++;
535 }
536
537 if (data_index < 0) {
538 fprintf(stderr, "Shit is broken, cannot construct equations to repair 3 failures!!!\n");
539 return -2;
540 }
541 // Copy the appropriate parity into the data buffer
542 fast_memcpy(data[data_index], parity_buffer, blocksize);
543 // Free up the buffer we allocated above
544 free(parity_buffer);
545 } else {
546 // Copy the appropriate parity into the data buffer
547 fast_memcpy(data[data_index], parity_buffer, blocksize);
548 }
549
550
551 for (i=0; i < code_desc->k; i++) {
552 if (i != data_index && is_data_in_parity(i, parity_bm)) {
553 xor_bufs_and_store(data[i], data[data_index], blocksize);
554 }
555 }
556
557 remove_from_missing_list(data_index, missing_data);
558
559 return decode_two_data(code_desc, data, parity, missing_data, missing_parity, blocksize);
560}
561
562int xor_hd_decode(xor_code_t *code_desc, char **data, char **parity, int *missing_idxs, int blocksize, int decode_parity)
563{
564 int ret = 0;
565 failure_pattern_t pattern = get_failure_pattern(code_desc, missing_idxs);
566
567 switch(pattern) {
568 case FAIL_PATTERN_0D_0P:
569 break;
570 case FAIL_PATTERN_1D_0P:
571 {
572 int *missing_data = get_missing_data(code_desc, missing_idxs);
573 decode_one_data(code_desc, data, parity, missing_data, NULL, blocksize);
574 free(missing_data);
575 break;
576 }
577 case FAIL_PATTERN_2D_0P:
578 {
579 int *missing_data = get_missing_data(code_desc, missing_idxs);
580 ret = decode_two_data(code_desc, data, parity, missing_data, NULL, blocksize);
581 free(missing_data);
582 break;
583 }
584 case FAIL_PATTERN_3D_0P:
585 {
586 int *missing_data = get_missing_data(code_desc, missing_idxs);
587 ret = decode_three_data(code_desc, data, parity, missing_data, NULL, blocksize);
588 free(missing_data);
589 break;
590 }
591 case FAIL_PATTERN_1D_1P:
592 {
593 int *missing_data = get_missing_data(code_desc, missing_idxs);
594 int *missing_parity = get_missing_parity(code_desc, missing_idxs);
595 decode_one_data(code_desc, data, parity, missing_data, missing_parity, blocksize);
596 if (decode_parity) {
597 selective_encode(code_desc, data, parity, missing_parity, blocksize);
598 }
599 free(missing_parity);
600 free(missing_data);
601 break;
602 }
603 case FAIL_PATTERN_1D_2P:
604 {
605 int *missing_data = get_missing_data(code_desc, missing_idxs);
606 int *missing_parity = get_missing_parity(code_desc, missing_idxs);
607 decode_one_data(code_desc, data, parity, missing_data, missing_parity, blocksize);
608 if (decode_parity) {
609 selective_encode(code_desc, data, parity, missing_parity, blocksize);
610 }
611 free(missing_data);
612 free(missing_parity);
613 break;
614 }
615 case FAIL_PATTERN_2D_1P:
616 {
617 int *missing_data = get_missing_data(code_desc, missing_idxs);
618 int *missing_parity = get_missing_parity(code_desc, missing_idxs);
619 ret = decode_two_data(code_desc, data, parity, missing_data, missing_parity, blocksize);
620 if (decode_parity) {
621 selective_encode(code_desc, data, parity, missing_parity, blocksize);
622 }
623 free(missing_parity);
624 free(missing_data);
625 break;
626 }
627 case FAIL_PATTERN_0D_1P:
628 if (decode_parity) {
629 int *missing_parity = get_missing_parity(code_desc, missing_idxs);
630 selective_encode(code_desc, data, parity, missing_parity, blocksize);
631 free(missing_parity);
632 }
633 break;
634 case FAIL_PATTERN_0D_2P:
635 if (decode_parity) {
636 int *missing_parity = get_missing_parity(code_desc, missing_idxs);
637 selective_encode(code_desc, data, parity, missing_parity, blocksize);
638 free(missing_parity);
639 }
640 break;
641 case FAIL_PATTERN_0D_3P:
642 if (decode_parity) {
643 int *missing_parity = get_missing_parity(code_desc, missing_idxs);
644 selective_encode(code_desc, data, parity, missing_parity, blocksize);
645 free(missing_parity);
646 }
647 break;
648 case FAIL_PATTERN_GE_HD:
649 default:
650 ret = -1;
651 break;
652 }
653
654 return ret;
655}
656
657xor_code_t* init_xor_hd_code(int k, int m, int hd)
658{
659 xor_code_t *code_desc = NULL;
660 int is_valid = 0;
661
662 if (hd == 3) {
663 if (m == 6) {
664 if (k <= 15 && k >= 6) {
665 is_valid = 1;
666 }
667 } else if (m == 5) {
668 if (k <= 10 && k >= 5) {
669 is_valid = 1;
670 }
671 } else if (m == 3 && k == 3) {
672 is_valid = 1;
673 }
674 }
675
676 if (hd == 4) {
677 if (m == 6) {
678 if (k <= 20 && k >= 6) {
679 is_valid = 1;
680 }
681 } else if (m == 5) {
682 if (k <= 10 && k >= 5) {
683 is_valid = 1;
684 }
685 }
686 }
687
688 if (is_valid) {
689 code_desc = (xor_code_t*)malloc(sizeof(xor_code_t));
690 code_desc->parity_bms = PARITY_BM_ARY(k, m, hd);
691 code_desc->data_bms = DATA_BM_ARY(k, m, hd);
692 code_desc->k = k;
693 code_desc->m = m;
694 code_desc->hd = hd;
695 code_desc->decode = xor_hd_decode;
696 code_desc->encode = xor_code_encode;
697 code_desc->fragments_needed = xor_hd_fragments_needed;
698 }
699
700 return code_desc;
701}
702
void xor_code_encode(xor_code_t *code_desc, char **data, char **parity, int blocksize)
Definition: xor_code.c:189
static int fragments_needed_one_data(xor_code_t *code_desc, int *missing_data, int *missing_parity, unsigned int *data_bm, unsigned int *parity_bm)
Definition: xor_hd_code.c:34
static int fragments_needed_two_data(xor_code_t *code_desc, int *missing_data, int *missing_parity, unsigned int *data_bm, unsigned int *parity_bm)
Definition: xor_hd_code.c:56
xor_code_t * init_xor_hd_code(int k, int m, int hd)
Definition: xor_hd_code.c:657
static int decode_two_data(xor_code_t *code_desc, char **data, char **parity, int *missing_data, int *missing_parity, int blocksize)
Definition: xor_hd_code.c:432
static int fragments_needed_one_data_local(xor_code_t *code_desc, int fragment_to_reconstruct, int *fragments_to_exclude, unsigned int *data_bm, unsigned int *parity_bm)
Definition: xor_hd_code.c:178
int xor_hd_fragments_needed(xor_code_t *code_desc, int *fragments_to_reconstruct, int *fragments_to_exclude, int *fragments_needed)
Definition: xor_hd_code.c:204
static void decode_one_data(xor_code_t *code_desc, char **data, char **parity, int *missing_data, int *missing_parity, int blocksize)
Definition: xor_hd_code.c:415
int xor_hd_decode(xor_code_t *code_desc, char **data, char **parity, int *missing_idxs, int blocksize, int decode_parity)
Definition: xor_hd_code.c:562
static int fragments_needed_three_data(xor_code_t *code_desc, int *missing_data, int *missing_parity, unsigned int *data_bm, unsigned int *parity_bm)
Definition: xor_hd_code.c:91
static int decode_three_data(xor_code_t *code_desc, char **data, char **parity, int *missing_data, int *missing_parity, int blocksize)
Definition: xor_hd_code.c:465