liberasurecode 1.6.3
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 break;
374 }
375 }
376
377 if (ret >= 0) {
378 i=0;
379 j=0;
380 while (data_bm) {
381 if (data_bm & 1) {
382 fragments_needed[j] = i;
383 j++;
384 }
385 i++;
386 data_bm >>= 1;
387 }
388
389 i=0;
390 while (parity_bm) {
391 if (parity_bm & 1) {
392 fragments_needed[j] = i + code_desc->k;
393 j++;
394 }
395 i++;
396 parity_bm >>= 1;
397 }
398
399 fragments_needed[j] = -1;
400 }
401
402out:
403 if (NULL != missing_idxs) {
404 free(missing_idxs);
405 }
406
407 return ret;
408}
409
410/*
411 * There is one unavailable data element, so any available parity connected to
412 * the data element is sufficient to decode.
413 */
414static void decode_one_data(xor_code_t *code_desc, char **data, char **parity, int *missing_data, int *missing_parity, int blocksize)
415{
416 // Verify that missing_data[1] == -1?
417 int data_index = missing_data[0];
418 int parity_index = index_of_connected_parity(code_desc, data_index, missing_parity, missing_data);
419 int i;
420
421 // Copy the appropriate parity into the data buffer
422 fast_memcpy(data[data_index], parity[parity_index-code_desc->k], blocksize);
423
424 for (i=0; i < code_desc->k; i++) {
425 if (i != data_index && is_data_in_parity(i, code_desc->parity_bms[parity_index-code_desc->k])) {
426 xor_bufs_and_store(data[i], data[data_index], blocksize);
427 }
428 }
429}
430
431static int decode_two_data(xor_code_t *code_desc, char **data, char **parity, int *missing_data, int *missing_parity, int blocksize)
432{
433 // Verify that missing_data[2] == -1?
434 int data_index = missing_data[0];
435 int parity_index = index_of_connected_parity(code_desc, data_index, missing_parity, missing_data);
436 int i;
437
438 if (parity_index < 0) {
439 data_index = missing_data[1];
440 parity_index = index_of_connected_parity(code_desc, data_index, missing_parity, missing_data);
441 if (parity_index < 0) {
442 fprintf(stderr, "Shit is broken, cannot find a proper parity!!!\n");
443 return -2;
444 }
445 missing_data[1] = -1;
446 } else {
447 missing_data[0] = missing_data[1];
448 missing_data[1] = -1;
449 }
450
451 // Copy the appropriate parity into the data buffer
452 fast_memcpy(data[data_index], parity[parity_index-code_desc->k], blocksize);
453
454 for (i=0; i < code_desc->k; i++) {
455 if (i != data_index && is_data_in_parity(i, code_desc->parity_bms[parity_index-code_desc->k])) {
456 xor_bufs_and_store(data[i], data[data_index], blocksize);
457 }
458 }
459 decode_one_data(code_desc, data, parity, missing_data, missing_parity, blocksize);
460
461 return 0;
462}
463
464static int decode_three_data(xor_code_t *code_desc, char **data, char **parity, int *missing_data, int *missing_parity, int blocksize)
465{
466 int i = 0;
467 int parity_index = -1;
468 int data_index = -1;
469 unsigned int parity_bm = -1;
470 char *parity_buffer = NULL;
471
472 /*
473 * Try to find a parity that only contains
474 * one of the missing data elements.
475 */
476 while (missing_data[i] > -1) {
477 parity_index = index_of_connected_parity(code_desc, missing_data[i], missing_parity, missing_data);
478 if (parity_index > -1) {
479 data_index = missing_data[i];
480 parity_buffer = parity[parity_index-code_desc->k];
481 parity_bm = code_desc->parity_bms[parity_index-code_desc->k];
482 break;
483 }
484 i++;
485 }
486
487 /*
488 * If we cannot find a parity that is connected to only
489 * one missing element, we must find a parity that is
490 * connected to exactly 2 (P) and another that is connected
491 * to exactly 3 (Q) (it should exist!!!).
492 *
493 * We XOR those parities together and use it to recover
494 * the element that is not connected to P.
495 */
496 if (parity_index < 0) {
497 int contains_2d = -1;
498 int contains_3d = -1;
499
500 for (i=0;i < code_desc->m;i++) {
501 int num_missing = num_missing_data_in_parity(code_desc, code_desc->k+i, missing_data);
502 if (num_missing == 2 && contains_2d < 0) {
503 contains_2d = i;
504 } else if (num_missing == 3 && contains_3d < 0) {
505 contains_3d = i;
506 }
507 }
508
509 if (contains_2d < 0 || contains_3d < 0) {
510 fprintf(stderr, "Shit is broken, cannot find a proper parity (2 and 3-connected parities)!!!\n");
511 return -2;
512 }
513
514 if (posix_memalign((void **) &parity_buffer, 16, blocksize) != 0) {
515 fprintf(stderr, "Can't get aligned memory!\n");
516 return -1;
517 }
518
519 // P XOR Q
520 parity_bm = code_desc->parity_bms[contains_2d] ^ code_desc->parity_bms[contains_3d];
521
522 // Create buffer with P XOR Q -> parity_buffer
523 fast_memcpy(parity_buffer, parity[contains_2d], blocksize);
524 xor_bufs_and_store(parity[contains_3d], parity_buffer, blocksize);
525
526 i=0;
527 data_index = -1;
528 while (missing_data[i] > -1) {
529 if (is_data_in_parity(missing_data[i], parity_bm)) {
530 data_index = missing_data[i];
531 break;
532 }
533 i++;
534 }
535
536 if (data_index < 0) {
537 fprintf(stderr, "Shit is broken, cannot construct equations to repair 3 failures!!!\n");
538 return -2;
539 }
540 // Copy the appropriate parity into the data buffer
541 fast_memcpy(data[data_index], parity_buffer, blocksize);
542 // Free up the buffer we allocated above
543 free(parity_buffer);
544 } else {
545 // Copy the appropriate parity into the data buffer
546 fast_memcpy(data[data_index], parity_buffer, blocksize);
547 }
548
549
550 for (i=0; i < code_desc->k; i++) {
551 if (i != data_index && is_data_in_parity(i, parity_bm)) {
552 xor_bufs_and_store(data[i], data[data_index], blocksize);
553 }
554 }
555
556 remove_from_missing_list(data_index, missing_data);
557
558 return decode_two_data(code_desc, data, parity, missing_data, missing_parity, blocksize);
559}
560
561int xor_hd_decode(xor_code_t *code_desc, char **data, char **parity, int *missing_idxs, int blocksize, int decode_parity)
562{
563 int ret = 0;
564 failure_pattern_t pattern = get_failure_pattern(code_desc, missing_idxs);
565
566 switch(pattern) {
567 case FAIL_PATTERN_0D_0P:
568 break;
569 case FAIL_PATTERN_1D_0P:
570 {
571 int *missing_data = get_missing_data(code_desc, missing_idxs);
572 decode_one_data(code_desc, data, parity, missing_data, NULL, blocksize);
573 free(missing_data);
574 break;
575 }
576 case FAIL_PATTERN_2D_0P:
577 {
578 int *missing_data = get_missing_data(code_desc, missing_idxs);
579 ret = decode_two_data(code_desc, data, parity, missing_data, NULL, blocksize);
580 free(missing_data);
581 break;
582 }
583 case FAIL_PATTERN_3D_0P:
584 {
585 int *missing_data = get_missing_data(code_desc, missing_idxs);
586 ret = decode_three_data(code_desc, data, parity, missing_data, NULL, blocksize);
587 free(missing_data);
588 break;
589 }
590 case FAIL_PATTERN_1D_1P:
591 {
592 int *missing_data = get_missing_data(code_desc, missing_idxs);
593 int *missing_parity = get_missing_parity(code_desc, missing_idxs);
594 decode_one_data(code_desc, data, parity, missing_data, missing_parity, blocksize);
595 if (decode_parity) {
596 selective_encode(code_desc, data, parity, missing_parity, blocksize);
597 }
598 free(missing_parity);
599 free(missing_data);
600 break;
601 }
602 case FAIL_PATTERN_1D_2P:
603 {
604 int *missing_data = get_missing_data(code_desc, missing_idxs);
605 int *missing_parity = get_missing_parity(code_desc, missing_idxs);
606 decode_one_data(code_desc, data, parity, missing_data, missing_parity, blocksize);
607 if (decode_parity) {
608 selective_encode(code_desc, data, parity, missing_parity, blocksize);
609 }
610 free(missing_data);
611 free(missing_parity);
612 break;
613 }
614 case FAIL_PATTERN_2D_1P:
615 {
616 int *missing_data = get_missing_data(code_desc, missing_idxs);
617 int *missing_parity = get_missing_parity(code_desc, missing_idxs);
618 ret = decode_two_data(code_desc, data, parity, missing_data, missing_parity, blocksize);
619 if (decode_parity) {
620 selective_encode(code_desc, data, parity, missing_parity, blocksize);
621 }
622 free(missing_parity);
623 free(missing_data);
624 break;
625 }
626 case FAIL_PATTERN_0D_1P:
627 if (decode_parity) {
628 int *missing_parity = get_missing_parity(code_desc, missing_idxs);
629 selective_encode(code_desc, data, parity, missing_parity, blocksize);
630 free(missing_parity);
631 }
632 break;
633 case FAIL_PATTERN_0D_2P:
634 if (decode_parity) {
635 int *missing_parity = get_missing_parity(code_desc, missing_idxs);
636 selective_encode(code_desc, data, parity, missing_parity, blocksize);
637 free(missing_parity);
638 }
639 break;
640 case FAIL_PATTERN_0D_3P:
641 if (decode_parity) {
642 int *missing_parity = get_missing_parity(code_desc, missing_idxs);
643 selective_encode(code_desc, data, parity, missing_parity, blocksize);
644 free(missing_parity);
645 }
646 break;
647 case FAIL_PATTERN_GE_HD:
648 default:
649 break;
650 }
651
652 return ret;
653}
654
655xor_code_t* init_xor_hd_code(int k, int m, int hd)
656{
657 xor_code_t *code_desc = NULL;
658 int is_valid = 0;
659
660 if (hd == 3) {
661 if (m == 6) {
662 if (k <= 15 && k >= 6) {
663 is_valid = 1;
664 }
665 } else if (m == 5) {
666 if (k <= 10 && k >= 5) {
667 is_valid = 1;
668 }
669 } else if (m == 3 && k == 3) {
670 is_valid = 1;
671 }
672 }
673
674 if (hd == 4) {
675 if (m == 6) {
676 if (k <= 20 && k >= 6) {
677 is_valid = 1;
678 }
679 } else if (m == 5) {
680 if (k <= 10 && k >= 5) {
681 is_valid = 1;
682 }
683 }
684 }
685
686 if (is_valid) {
687 code_desc = (xor_code_t*)malloc(sizeof(xor_code_t));
688 code_desc->parity_bms = PARITY_BM_ARY(k, m, hd);
689 code_desc->data_bms = DATA_BM_ARY(k, m, hd);
690 code_desc->k = k;
691 code_desc->m = m;
692 code_desc->hd = hd;
693 code_desc->decode = xor_hd_decode;
694 code_desc->encode = xor_code_encode;
695 code_desc->fragments_needed = xor_hd_fragments_needed;
696 }
697
698 return code_desc;
699}
700
void selective_encode(xor_code_t *code_desc, char **data, char **parity, int *missing_parity, int blocksize)
Definition xor_code.c:193
int is_data_in_parity(int data_idx, unsigned int parity_bm)
Definition xor_code.c:43
int data_bit_lookup(xor_code_t *code_desc, int index)
Definition xor_code.c:58
void remove_from_missing_list(int element, int *missing_list)
Definition xor_code.c:363
void xor_bufs_and_store(char *buf1, char *buf2, int blocksize)
Definition xor_code.c:141
int missing_elements_bm(xor_code_t *code_desc, int *missing_elements, int(*bit_lookup_func)(xor_code_t *code_desc, int index))
Definition xor_code.c:63
int index_of_connected_parity(xor_code_t *code_desc, int data_index, int *missing_parity, int *missing_data)
Definition xor_code.c:328
int * get_missing_parity(xor_code_t *code_desc, int *missing_idxs)
Definition xor_code.c:208
int * get_missing_data(xor_code_t *code_desc, int *missing_idxs)
Definition xor_code.c:225
int num_missing_data_in_parity(xor_code_t *code_desc, int parity_idx, int *missing_data)
Definition xor_code.c:309
failure_pattern_t get_failure_pattern(xor_code_t *code_desc, int *missing_idxs)
Definition xor_code.c:76
void fast_memcpy(char *dst, char *src, int size)
Definition xor_code.c:130
void xor_code_encode(xor_code_t *code_desc, char **data, char **parity, int blocksize)
Definition xor_code.c:180
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)
static int decode_two_data(xor_code_t *code_desc, char **data, char **parity, int *missing_data, int *missing_parity, int blocksize)
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)
int xor_hd_fragments_needed(xor_code_t *code_desc, int *fragments_to_reconstruct, int *fragments_to_exclude, int *fragments_needed)
static void decode_one_data(xor_code_t *code_desc, char **data, char **parity, int *missing_data, int *missing_parity, int blocksize)
int xor_hd_decode(xor_code_t *code_desc, char **data, char **parity, int *missing_idxs, int blocksize, int decode_parity)
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)