liberasurecode  1.6.3
Erasure Code API library
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  */
34 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)
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  */
56 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)
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  */
91 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)
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 
178 static 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 
204 int 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 
402 out:
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  */
414 static 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 
431 static 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 
464 static 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 
561 int 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 
655 xor_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
int * get_missing_data(xor_code_t *code_desc, int *missing_idxs)
Definition: xor_code.c:225
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 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
int * get_missing_parity(xor_code_t *code_desc, int *missing_idxs)
Definition: xor_code.c:208
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)
Definition: xor_hd_code.c:655
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:431
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:414
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:561
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:464