35 0x10, 0x20, 0x40, 0x80,
36 0x100, 0x200, 0x400, 0x800,
37 0x1000, 0x2000, 0x4000, 0x8000,
38 0x10000, 0x20000, 0x40000, 0x80000,
39 0x100000, 0x200000, 0x400000, 0x800000,
40 0x1000000, 0x2000000, 0x4000000, 0x8000000,
41 0x10000000, 0x20000000, 0x40000000, 0x80000000};
44int is_data_in_parity(
int data_idx,
unsigned int parity_bm)
50int does_parity_have_data(
int parity_idx,
unsigned int data_bm)
56int parity_bit_lookup(xor_code_t *code_desc,
int index)
62int data_bit_lookup(xor_code_t *code_desc,
int index)
68int missing_elements_bm(xor_code_t *code_desc,
int *missing_elements,
int (*bit_lookup_func)(xor_code_t *code_desc,
int index))
73 while (missing_elements[i] > -1) {
74 bm |= bit_lookup_func(code_desc, missing_elements[i]);
82failure_pattern_t get_failure_pattern(xor_code_t *code_desc,
int *missing_idxs)
86 failure_pattern_t pattern = FAIL_PATTERN_0D_0P;
88 while (missing_idxs[i] > -1) {
90 if (num_failures >= code_desc->hd) {
91 pattern = FAIL_PATTERN_GE_HD;
94 case FAIL_PATTERN_0D_0P:
95 pattern = (missing_idxs[i] < code_desc->k) ? FAIL_PATTERN_1D_0P : FAIL_PATTERN_0D_1P;
97 case FAIL_PATTERN_1D_0P:
98 pattern = (missing_idxs[i] < code_desc->k) ? FAIL_PATTERN_2D_0P : FAIL_PATTERN_1D_1P;
100 case FAIL_PATTERN_2D_0P:
101 pattern = (missing_idxs[i] < code_desc->k) ? FAIL_PATTERN_3D_0P : FAIL_PATTERN_2D_1P;
103 case FAIL_PATTERN_3D_0P:
104 pattern = FAIL_PATTERN_GE_HD;
106 case FAIL_PATTERN_1D_1P:
107 pattern = (missing_idxs[i] < code_desc->k) ? FAIL_PATTERN_2D_1P : FAIL_PATTERN_1D_2P;
109 case FAIL_PATTERN_1D_2P:
110 pattern = FAIL_PATTERN_GE_HD;
112 case FAIL_PATTERN_2D_1P:
113 pattern = FAIL_PATTERN_GE_HD;
115 case FAIL_PATTERN_0D_1P:
116 pattern = (missing_idxs[i] < code_desc->k) ? FAIL_PATTERN_1D_1P : FAIL_PATTERN_0D_2P;
118 case FAIL_PATTERN_0D_2P:
119 pattern = (missing_idxs[i] < code_desc->k) ? FAIL_PATTERN_1D_2P : FAIL_PATTERN_0D_3P;
121 case FAIL_PATTERN_0D_3P:
122 pattern = FAIL_PATTERN_GE_HD;
124 case FAIL_PATTERN_GE_HD:
128 if (pattern == FAIL_PATTERN_GE_HD) {
138void fast_memcpy(
char *dst,
char *src,
int size)
141 memcpy(dst, src, size);
150void xor_bufs_and_store(
char *buf1,
char *buf2,
int blocksize)
153 int residual_bytes = num_unaligned_end(blocksize);
154 int fast_blocksize = blocksize > residual_bytes ? (blocksize - residual_bytes) : 0;
155 int fast_int_blocksize = fast_blocksize /
sizeof(__m128i);
157 __m128i *_buf1 = (__m128i*)buf1;
158 __m128i *_buf2 = (__m128i*)buf2;
163 for (i=0; i < fast_int_blocksize; i++) {
164 _buf2[i] = _mm_xor_si128(_buf1[i], _buf2[i]);
167 int residual_bytes = num_unaligned_end(blocksize);
168 int fast_blocksize = blocksize > residual_bytes ? (blocksize - residual_bytes) : 0;
169 int fast_int_blocksize = fast_blocksize /
sizeof(
unsigned long);
172 unsigned long*_buf1 = (
unsigned long*)buf1;
173 unsigned long*_buf2 = (
unsigned long*)buf2;
175 for (i=0; i < fast_int_blocksize; i++) {
176 _buf2[i] = _buf1[i] ^ _buf2[i];
183 for (i=fast_blocksize; i < blocksize; i++)
193 for (i=0; i < code_desc->k; i++) {
194 for (j=0; j < code_desc->m; j++) {
195 if (is_data_in_parity(i, code_desc->parity_bms[j])) {
196 xor_bufs_and_store(data[i], parity[j], blocksize);
203void selective_encode(xor_code_t *code_desc,
char **data,
char **parity,
int *missing_parity,
int blocksize)
206 for (i=0; i < code_desc->k; i++) {
208 while (missing_parity[j] > -1) {
209 int parity_index = missing_parity[j] - code_desc->k;
210 if (is_data_in_parity(i, code_desc->parity_bms[parity_index])) {
211 xor_bufs_and_store(data[i], parity[parity_index], blocksize);
219int * get_missing_parity(xor_code_t *code_desc,
int *missing_idxs)
221 int *missing_parity = (
int*)malloc(
sizeof(
int)*MAX_PARITY);
224 while (missing_idxs[i] > -1) {
225 if (missing_idxs[i] >= code_desc->k) {
226 missing_parity[j] = missing_idxs[i];
232 missing_parity[j] = -1;
233 return missing_parity;
237int * get_missing_data(xor_code_t *code_desc,
int *missing_idxs)
239 int *missing_data = (
int*)malloc(
sizeof(
int)*MAX_DATA);
242 while (missing_idxs[i] > -1) {
243 if (missing_idxs[i] < code_desc->k) {
244 missing_data[j] = missing_idxs[i];
250 missing_data[j] = -1;
257int xor_reconstruct_one(xor_code_t *code_desc,
char **data,
char **parity,
int *missing_idxs,
int index_to_reconstruct,
int blocksize)
259 int *missing_data = get_missing_data(code_desc, missing_idxs);
260 int *missing_parity = get_missing_parity(code_desc, missing_idxs);
268 if (index_to_reconstruct < code_desc->k) {
269 int connected_parity_idx = index_of_connected_parity(code_desc, index_to_reconstruct, missing_parity, missing_data);
271 if (connected_parity_idx >= 0) {
273 int relative_parity_idx = connected_parity_idx - code_desc->k;
274 int parity_bm = code_desc->parity_bms[relative_parity_idx];
276 fast_memcpy(data[index_to_reconstruct], parity[relative_parity_idx], blocksize);
278 for (i=0; i < code_desc->k; i++) {
279 if (parity_bm & (1 << i)) {
280 if (i != index_to_reconstruct) {
281 xor_bufs_and_store(data[i], data[index_to_reconstruct], blocksize);
288 ret = code_desc->decode(code_desc, data, parity, missing_idxs, blocksize, 1);
298 int num_data_missing = num_missing_data_in_parity(code_desc, index_to_reconstruct, missing_data);
300 if (num_data_missing == 0) {
301 int relative_parity_idx = index_to_reconstruct - code_desc->k;
302 int parity_bm = code_desc->parity_bms[relative_parity_idx];
304 memset(parity[relative_parity_idx], 0, blocksize);
306 for (i=0; i < code_desc->k; i++) {
307 if (parity_bm & (1 << i)) {
308 xor_bufs_and_store(data[i], parity[relative_parity_idx], blocksize);
314 ret = code_desc->decode(code_desc, data, parity, missing_idxs, blocksize, 1);
318 free(missing_parity);
323int num_missing_data_in_parity(xor_code_t *code_desc,
int parity_idx,
int *missing_data)
326 int num_missing_data = 0;
327 int relative_parity_index = parity_idx - code_desc->k;
328 if (missing_data == NULL) {
332 while (missing_data[i] > -1) {
333 if (does_parity_have_data(relative_parity_index, code_desc->data_bms[missing_data[i]]) > 0) {
339 return num_missing_data;
343int index_of_connected_parity(xor_code_t *code_desc,
int data_index,
int *missing_parity,
int *missing_data)
345 int parity_index = -1;
348 for (i=0; i < code_desc->m; i++) {
349 if (num_missing_data_in_parity(code_desc, i + code_desc->k, missing_data) > 1) {
352 if (is_data_in_parity(data_index, code_desc->parity_bms[i])) {
355 if (missing_parity == NULL) {
359 while (missing_parity[j] > -1) {
360 if ((code_desc->k + i) == missing_parity[j]) {
375 return parity_index > -1 ? parity_index + code_desc->k : parity_index;
379void remove_from_missing_list(
int element,
int *missing_list)
385 while (missing_list[i] > -1) {
386 if (missing_list[i] == element) {
388 missing_list[i] = -1;
395 for (i=elem_idx;i < num_elems-1;i++) {
396 int tmp = missing_list[i+1];
397 missing_list[i+1] = missing_list[i];
398 missing_list[i] = tmp;
int is_missing(int *missing_idxs, int index_to_check)
static const int g_bit_lookup[]
__attribute__((visibility("internal")))
int xor_reconstruct_one(xor_code_t *code_desc, char **data, char **parity, int *missing_idxs, int index_to_reconstruct, int blocksize)
void xor_code_encode(xor_code_t *code_desc, char **data, char **parity, int blocksize)