Skip to content

Instantly share code, notes, and snippets.

@bloodeagle40234
Created November 2, 2016 11:51
Show Gist options
  • Save bloodeagle40234/f5b5c39e93cd79136e33da8a5b50fdc7 to your computer and use it in GitHub Desktop.
Save bloodeagle40234/f5b5c39e93cd79136e33da8a5b50fdc7 to your computer and use it in GitHub Desktop.
#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