29#include "xor_hd_code_defs.h"
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)
36 int data_index = missing_data[0];
37 int parity_index = index_of_connected_parity(code_desc, data_index, missing_parity, missing_data);
39 if (parity_index < 0) {
44 *data_bm |= (code_desc->parity_bms[parity_index-code_desc->k]);
47 *parity_bm |= (1 << (parity_index-code_desc->k));
48 *data_bm &= ~((
unsigned int)1 << data_index);
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)
59 int data_index = missing_data[0];
60 int parity_index = index_of_connected_parity(code_desc, data_index, missing_parity, missing_data);
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) {
71 missing_data[0] = missing_data[1];
76 *data_bm |= (code_desc->parity_bms[parity_index-code_desc->k]);
79 *parity_bm |= (1 << (parity_index-code_desc->k));
83 *data_bm &= ~((
unsigned int)1 << data_index);
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)
94 int parity_index = -1;
96 int tmp_parity_bm = -1;
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];
123 if (parity_index < 0) {
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) {
129 }
else if (num_missing == 3 && contains_3d < 0) {
134 if (contains_2d < 0 || contains_3d < 0) {
139 tmp_parity_bm = code_desc->parity_bms[contains_2d] ^ code_desc->parity_bms[contains_3d];
143 while (missing_data[i] > -1) {
144 if (is_data_in_parity(missing_data[i], tmp_parity_bm)) {
145 data_index = missing_data[i];
151 if (data_index < 0) {
156 remove_from_missing_list(data_index, missing_data);
158 if (parity_index > -1) {
160 *parity_bm |= (1 << (parity_index-code_desc->k));
162 *data_bm |= code_desc->parity_bms[parity_index-code_desc->k];
165 *parity_bm |= (1 << (contains_2d-code_desc->k));
166 *parity_bm |= (1 << (contains_3d-code_desc->k));
168 *data_bm |= tmp_parity_bm;
173 *data_bm &= ~((
unsigned int)1 << data_index);
179 int fragment_to_reconstruct,
180 int *fragments_to_exclude,
181 unsigned int *data_bm,
182 unsigned int *parity_bm)
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);
188 free(missing_parity);
190 if (parity_index < 0) {
195 *data_bm |= (code_desc->parity_bms[parity_index-code_desc->k]);
198 *parity_bm |= (1 << (parity_index-code_desc->k));
199 *data_bm &= ~((
unsigned int)1 << fragment_to_reconstruct);
204int xor_hd_fragments_needed(xor_code_t *code_desc,
int *fragments_to_reconstruct,
int *fragments_to_exclude,
int *fragments_needed)
206 failure_pattern_t pattern = get_failure_pattern(code_desc, fragments_to_reconstruct);
207 unsigned int data_bm = 0, parity_bm = 0;
209 int *missing_idxs = NULL;
220 if (pattern == FAIL_PATTERN_1D_0P) {
233 missing_idxs = (
int*)malloc(
sizeof(
int)*(code_desc->k + code_desc->m));
234 if (NULL == missing_idxs) {
241 while (fragments_to_reconstruct[i] > -1) {
242 missing_idxs[j] = fragments_to_reconstruct[i];
247 while (fragments_to_exclude[i] > -1) {
248 missing_idxs[j] = fragments_to_exclude[i];
253 missing_idxs[j] = -1;
255 pattern = get_failure_pattern(code_desc, missing_idxs);
258 case FAIL_PATTERN_0D_0P:
260 case FAIL_PATTERN_1D_0P:
262 int *missing_data = get_missing_data(code_desc, missing_idxs);
267 case FAIL_PATTERN_2D_0P:
269 int *missing_data = get_missing_data(code_desc, missing_idxs);
274 case FAIL_PATTERN_3D_0P:
276 int *missing_data = get_missing_data(code_desc, missing_idxs);
281 case FAIL_PATTERN_1D_1P:
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);
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);
294 free(missing_parity);
298 case FAIL_PATTERN_1D_2P:
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);
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);
311 free(missing_parity);
315 case FAIL_PATTERN_2D_1P:
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);
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);
328 free(missing_parity);
332 case FAIL_PATTERN_0D_1P:
334 int *missing_parity = get_missing_parity(code_desc, missing_idxs);
337 while (missing_parity[i] > -1) {
338 data_bm |= code_desc->parity_bms[missing_parity[i]-code_desc->k];
341 free(missing_parity);
345 case FAIL_PATTERN_0D_2P:
347 int *missing_parity = get_missing_parity(code_desc, missing_idxs);
350 while (missing_parity[i] > -1) {
351 data_bm |= code_desc->parity_bms[missing_parity[i]-code_desc->k];
354 free(missing_parity);
358 case FAIL_PATTERN_0D_3P:
360 int *missing_parity = get_missing_parity(code_desc, missing_idxs);
363 while (missing_parity[i] > -1) {
364 data_bm |= code_desc->parity_bms[missing_parity[i]-code_desc->k];
367 free(missing_parity);
371 case FAIL_PATTERN_GE_HD:
383 fragments_needed[j] = i;
393 fragments_needed[j] = i + code_desc->k;
400 fragments_needed[j] = -1;
404 if (NULL != missing_idxs) {
415static void decode_one_data(xor_code_t *code_desc,
char **data,
char **parity,
int *missing_data,
int *missing_parity,
int blocksize)
418 int data_index = missing_data[0];
419 int parity_index = index_of_connected_parity(code_desc, data_index, missing_parity, missing_data);
423 fast_memcpy(data[data_index], parity[parity_index-code_desc->k], blocksize);
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);
432static int decode_two_data(xor_code_t *code_desc,
char **data,
char **parity,
int *missing_data,
int *missing_parity,
int blocksize)
435 int data_index = missing_data[0];
436 int parity_index = index_of_connected_parity(code_desc, data_index, missing_parity, missing_data);
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");
446 missing_data[1] = -1;
448 missing_data[0] = missing_data[1];
449 missing_data[1] = -1;
453 fast_memcpy(data[data_index], parity[parity_index-code_desc->k], blocksize);
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);
460 decode_one_data(code_desc, data, parity, missing_data, missing_parity, blocksize);
465static int decode_three_data(xor_code_t *code_desc,
char **data,
char **parity,
int *missing_data,
int *missing_parity,
int blocksize)
468 int parity_index = -1;
470 unsigned int parity_bm = -1;
471 char *parity_buffer = NULL;
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];
497 if (parity_index < 0) {
498 int contains_2d = -1;
499 int contains_3d = -1;
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) {
505 }
else if (num_missing == 3 && contains_3d < 0) {
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");
515 if (posix_memalign((
void **) &parity_buffer, 16, blocksize) != 0) {
516 fprintf(stderr,
"Can't get aligned memory!\n");
521 parity_bm = code_desc->parity_bms[contains_2d] ^ code_desc->parity_bms[contains_3d];
524 fast_memcpy(parity_buffer, parity[contains_2d], blocksize);
525 xor_bufs_and_store(parity[contains_3d], parity_buffer, blocksize);
529 while (missing_data[i] > -1) {
530 if (is_data_in_parity(missing_data[i], parity_bm)) {
531 data_index = missing_data[i];
537 if (data_index < 0) {
538 fprintf(stderr,
"Shit is broken, cannot construct equations to repair 3 failures!!!\n");
542 fast_memcpy(data[data_index], parity_buffer, blocksize);
547 fast_memcpy(data[data_index], parity_buffer, blocksize);
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);
557 remove_from_missing_list(data_index, missing_data);
559 return decode_two_data(code_desc, data, parity, missing_data, missing_parity, blocksize);
562int xor_hd_decode(xor_code_t *code_desc,
char **data,
char **parity,
int *missing_idxs,
int blocksize,
int decode_parity)
565 failure_pattern_t pattern = get_failure_pattern(code_desc, missing_idxs);
568 case FAIL_PATTERN_0D_0P:
570 case FAIL_PATTERN_1D_0P:
572 int *missing_data = get_missing_data(code_desc, missing_idxs);
573 decode_one_data(code_desc, data, parity, missing_data, NULL, blocksize);
577 case FAIL_PATTERN_2D_0P:
579 int *missing_data = get_missing_data(code_desc, missing_idxs);
580 ret =
decode_two_data(code_desc, data, parity, missing_data, NULL, blocksize);
584 case FAIL_PATTERN_3D_0P:
586 int *missing_data = get_missing_data(code_desc, missing_idxs);
591 case FAIL_PATTERN_1D_1P:
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);
597 selective_encode(code_desc, data, parity, missing_parity, blocksize);
599 free(missing_parity);
603 case FAIL_PATTERN_1D_2P:
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);
609 selective_encode(code_desc, data, parity, missing_parity, blocksize);
612 free(missing_parity);
615 case FAIL_PATTERN_2D_1P:
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);
621 selective_encode(code_desc, data, parity, missing_parity, blocksize);
623 free(missing_parity);
627 case FAIL_PATTERN_0D_1P:
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);
634 case FAIL_PATTERN_0D_2P:
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);
641 case FAIL_PATTERN_0D_3P:
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);
648 case FAIL_PATTERN_GE_HD:
659 xor_code_t *code_desc = NULL;
664 if (k <= 15 && k >= 6) {
668 if (k <= 10 && k >= 5) {
671 }
else if (m == 3 && k == 3) {
678 if (k <= 20 && k >= 6) {
682 if (k <= 10 && k >= 5) {
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);
void xor_code_encode(xor_code_t *code_desc, char **data, char **parity, int blocksize)
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)
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)
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)
static int decode_three_data(xor_code_t *code_desc, char **data, char **parity, int *missing_data, int *missing_parity, int blocksize)