-
-
Save bloodeagle40234/f5b5c39e93cd79136e33da8a5b50fdc7 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <isa-l/erasure_code.h> | |
#include <isa-l/gf_vect_mul.h> | |
#include <isa-l/types.h> | |
#include <string.h> | |
#include <stdlib.h> | |
#include <stdio.h> | |
#include <assert.h> | |
static void mult_and_xor_row(unsigned char *to_row, | |
unsigned char *from_row, | |
unsigned char val, | |
int num_elems) | |
{ | |
int i; | |
for (i = 0; i < num_elems; i++) { | |
to_row[i] ^= gf_mul(val, from_row[i]); | |
} | |
} | |
int main(){ | |
// Generate g_tbls from encode matrix encode_matrix | |
int k = 10, m = 10, i = 0, j = 0; | |
int blocksize = 1024; | |
unsigned char **data; | |
unsigned char **parity; | |
unsigned char *encode_matrix; | |
unsigned char *g_tbls; | |
unsigned char *decode_matrix; | |
unsigned char *decode_inverse; | |
unsigned char *inverse_rows; | |
unsigned char **decoded_elements; | |
unsigned char **available_fragments; | |
unsigned char *expected; | |
expected = malloc(sizeof(unsigned char) * blocksize); | |
memset(expected, 'x', blocksize); | |
// allocate initial data/parity memory | |
data = malloc(sizeof(unsigned char*) * k); | |
for(i = 0; i < k; i++){ | |
data[i] = malloc(sizeof(unsigned char) * blocksize); | |
memset(data[i], 'x', blocksize); | |
} | |
parity = malloc(sizeof(unsigned char*) * m); | |
for(i = 0; i < m; i++){ | |
parity[i] = malloc(sizeof(unsigned char) * blocksize); | |
memset(parity[i], 'x', blocksize); | |
} | |
// sanity | |
for (i = 0; i < k; i++){ | |
assert(memcmp(data[i], expected, blocksize) == 0); | |
} | |
for (i = 0; i < m; i++){ | |
assert(memcmp(parity[i], expected, blocksize) == 0); | |
} | |
// preare encode | |
encode_matrix = malloc(sizeof(unsigned char) * k * (k + m)); | |
gf_gen_rs_matrix(encode_matrix, k + m, k); | |
g_tbls = malloc(sizeof(unsigned char) * (k * m * 32)); | |
// encode | |
ec_init_tables(k, m, &encode_matrix[k * k], g_tbls); | |
ec_encode_data(blocksize, k, m, g_tbls, (unsigned char**)data, | |
(unsigned char**)parity); | |
// sanity (data is same but parities filled by something) | |
for (i = 0; i < k; i++){ | |
assert(memcmp(data[i], expected, blocksize) == 0); | |
} | |
for (i = 0; i < m; i++){ | |
assert(memcmp(parity[i], expected, blocksize) != 0); | |
} | |
printf("encode succeeded\n"); | |
// available frags for a bad pattern: [0, 1, 2, 3, 4, 6, 7, 10, 12, 15] | |
// [0, 1, 2, 3, 4, 6, 7, 10, 12, 14] is ok. | |
// prare decode | |
decode_matrix = malloc(sizeof(unsigned char) * k * k); | |
// set available fragments to decode matrix | |
int l = 0; | |
i = j = 0; | |
while (i < k && l < k + m){ | |
if (l != 5 & l != 8 & l != 9 & l != 11 & l != 13 & l != 14 & | |
l != 16 & l != 17 & l != 18 & l != 19){ | |
printf("%d\n", l); | |
for (j = 0; j < k; j++) { | |
decode_matrix[(k * i) + j] = encode_matrix[(k * l) + j]; | |
} | |
i++; | |
} | |
l++; | |
} | |
decode_inverse = (unsigned char*)malloc(sizeof(unsigned char) * k * k); | |
gf_invert_matrix(decode_matrix, decode_inverse, k); | |
inverse_rows = (unsigned char*)malloc(sizeof(unsigned char*) * k * 10); | |
memset(inverse_rows, 0, sizeof(unsigned char*) * k * 10); | |
l = 0; | |
for (i = 0; i < k; i++){ | |
if (i == 5 | i == 8 | i == 9){ | |
for (j = 0; j < k; j++) { | |
inverse_rows[(l * k) + j] = decode_inverse[(i * k) + j]; | |
} | |
l++; | |
} | |
} | |
for (i = k; i < k + m; i++){ | |
// Parity is missing | |
if (i == 11 | i == 13 | i == 14 | i == 16 | i == 17 | i == 18 | i == 19){ | |
int d_idx_avail = 0; | |
int d_idx_unavail = 0; | |
for (j = 0; j < k; j++) { | |
// This data is available, so we can use the encode matrix | |
if (j != 5 & j != 8 & j != 9 & j != 11 & j != 13 & j != 14 & | |
j != 16 & j != 17 & j != 18 & j != 19){ | |
inverse_rows[(l * k) + d_idx_avail] ^= encode_matrix[(i * k) + j]; | |
d_idx_avail++; | |
} else { | |
mult_and_xor_row(&inverse_rows[l * k], | |
&inverse_rows[d_idx_unavail * k], | |
encode_matrix[(i * k) + j], | |
k); | |
d_idx_unavail++; | |
} | |
} | |
l++; | |
} | |
} | |
decoded_elements = (unsigned char**)malloc(sizeof(unsigned char*)*10); | |
available_fragments = (unsigned char**)malloc(sizeof(unsigned char*)*k); | |
j = 0; | |
for (i = 0; i < k + m; i++) { | |
if (i == 5 | i == 8 | i == 9 | i == 11 | i == 13 | i == 14 | | |
i == 16 | i == 17 | i == 18 | i == 19){ | |
continue; | |
} | |
if (j == k) { | |
break; | |
} | |
if (i < k) { | |
available_fragments[j] = (unsigned char*)data[i]; | |
} else { | |
available_fragments[j] = (unsigned char*)parity[i-k]; | |
} | |
j++; | |
} | |
// Grab pointers to memory needed for missing data fragments | |
j = 0; | |
for (i = 0; i < k; i++) { | |
if (i == 5 | i == 8 | i == 9){ | |
decoded_elements[j] = (unsigned char*)data[i]; | |
j++; | |
} | |
} | |
for (i = k; i < k + m; i++) { | |
if (i == 11 | i == 13 | i == 14 | i == 16 | i == 17 | i == 18 | i == 19){ | |
decoded_elements[j] = (unsigned char*)parity[i - k]; | |
j++; | |
} | |
} | |
// sanity | |
for(i = 0; i < k; i++){ | |
assert(memcmp(available_fragments[0], expected, blocksize) == 0); | |
} | |
ec_init_tables(k, 10, inverse_rows, g_tbls); | |
ec_encode_data(blocksize, k, 10, g_tbls, | |
(unsigned char**)available_fragments, | |
(unsigned char**)decoded_elements); | |
// check the decoded data | |
for (i = 0; i < k; i++){ | |
printf("%i\n", i); | |
assert(memcmp(data[i], expected, blocksize) == 0); | |
} | |
// cleanup | |
for(i = 0; i < k; i++) free(data[i]); | |
free(data); | |
for(i = 0; i < m; i++) free(parity[i]); | |
free(parity); | |
free(encode_matrix); | |
free(g_tbls); | |
free(decode_matrix); | |
free(decode_inverse); | |
free(inverse_rows); | |
free(decoded_elements); | |
free(available_fragments); | |
free(expected); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment