Adding the current jerasure 1.2A

master
Jim Plank 2013-10-01 13:25:12 -04:00
commit b5745fa4f1
36 changed files with 9852 additions and 0 deletions

BIN
Examples/.swp Executable file

Binary file not shown.

90
Examples/cauchy_01.c Executable file
View File

@ -0,0 +1,90 @@
/* Examples/cauchy_01.c
Jerasure - A C/C++ Library for a Variety of Reed-Solomon and RAID-6 Erasure Coding Techniques
Revision 1.2A
May 24, 2011
James S. Plank
Department of Electrical Engineering and Computer Science
University of Tennessee
Knoxville, TN 37996
plank@cs.utk.edu
Copyright (c) 2011, James S. Plank
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
- Neither the name of the University of Tennessee nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "jerasure.h"
#include "reed_sol.h"
#define talloc(type, num) (type *) malloc(sizeof(type)*(num))
usage(char *s)
{
fprintf(stderr, "usage: cauchy_01 n w - Prints the number of ones in the bitmatrix representation of n in GF(2^w).\n");
fprintf(stderr, " \n");
fprintf(stderr, " It also prints out the bit-matrix and confirms that the number of ones is correct.\n");
fprintf(stderr, " \n");
fprintf(stderr, "This demonstrates: cauchy_n_ones()\n");
fprintf(stderr, " jerasure_matrix_to_bitmatrix()\n");
fprintf(stderr, " jerasure_print_bitmatrix()\n");
if (s != NULL) fprintf(stderr, "%s\n", s);
exit(1);
}
int main(int argc, char **argv)
{
int n, i, no, w;
int *bitmatrix;
if (argc != 3) usage(NULL);
if (sscanf(argv[1], "%d", &n) == 0 || n <= 0) usage("Bad n");
if (sscanf(argv[2], "%d", &w) == 0 || w <= 0 || w > 32) usage("Bad w");
if (w < 30 && n >= (1 << w)) usage("n is too big");
bitmatrix = jerasure_matrix_to_bitmatrix(1, 1, w, &n);
no = 0;
for (i = 0; i < w*w; i++) no += bitmatrix[i];
printf("# Ones: %d\n", cauchy_n_ones(n, w));
printf("\n");
printf("Bitmatrix has %d ones\n", no);
printf("\n");
jerasure_print_bitmatrix(bitmatrix, w, w, w);
return 0;
}

210
Examples/cauchy_02.c Executable file
View File

@ -0,0 +1,210 @@
/* Examples/cauchy_02.c
Jerasure - A C/C++ Library for a Variety of Reed-Solomon and RAID-6 Erasure Coding Techniques
Revision 1.2A
May 24, 2011
James S. Plank
Department of Electrical Engineering and Computer Science
University of Tennessee
Knoxville, TN 37996
plank@cs.utk.edu
Copyright (c) 2011, James S. Plank
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
- Neither the name of the University of Tennessee nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
/*
revised by S. Simmerman
2/25/08
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "jerasure.h"
#include "cauchy.h"
#define talloc(type, num) (type *) malloc(sizeof(type)*(num))
usage(char *s)
{
fprintf(stderr, "usage: cauchy_02 k m w - Scheduled CRS coding example with the original matrix in GF(2^w).\n");
fprintf(stderr, " \n");
fprintf(stderr, " k+m must be <= 2^w. It sets up a Cauchy distribution matrix using the original\n");
fprintf(stderr, " Cauchy Distribution matrix construction algorithm, then it encodes\n");
fprintf(stderr, " k devices of w*%d bytes using smart bit-matrix scheduling.\n", sizeof(long));
fprintf(stderr, " It decodes using bit-matrix scheduling as well.\n");
fprintf(stderr, " \n");
fprintf(stderr, "This demonstrates: cauchy_original_coding_matrix()\n");
fprintf(stderr, " cauchy_xy_coding_matrix()\n");
fprintf(stderr, " cauchy_n_ones()\n");
fprintf(stderr, " jerasure_smart_bitmatrix_to_schedule()\n");
fprintf(stderr, " jerasure_schedule_encode()\n");
fprintf(stderr, " jerasure_schedule_decode_lazy()\n");
fprintf(stderr, " jerasure_print_matrix()\n");
fprintf(stderr, " jerasure_get_stats()\n");
if (s != NULL) fprintf(stderr, "%s\n", s);
exit(1);
}
static void print_data_and_coding(int k, int m, int w, int psize,
char **data, char **coding)
{
int i, j, x, n, sp;
long l;
if(k > m) n = k;
else n = m;
sp = psize * 2 + (psize/4) + 12;
printf("%-*sCoding\n", sp, "Data");
for(i = 0; i < n; i++) {
for (j = 0; j < w; j++) {
if(i < k) {
if(j==0) printf("D%-2d p%-2d:", i,j);
else printf(" p%-2d:", j);
for(x = 0; x < psize; x +=4) {
memcpy(&l, data[i]+j*psize+x, sizeof(long));
printf(" %08lx", l);
}
printf(" ");
}
else printf("%*s", sp, "");
if(i < m) {
if(j==0) printf("C%-2d p%-2d:", i,j);
else printf(" p%-2d:", j);
for(x = 0; x < psize; x +=4) {
memcpy(&l, coding[i]+j*psize+x, sizeof(long));
printf(" %08lx", l);
}
}
printf("\n");
}
}
printf("\n");
}
int main(int argc, char **argv)
{
long l;
int k, w, i, j, m;
int *matrix, *bitmatrix, *m2, *x, *y;
char **data, **coding, **ptrs;
int **smart;
int no;
int *erasures, *erased;
double stats[3];
if (argc != 4) usage(NULL);
if (sscanf(argv[1], "%d", &k) == 0 || k <= 0) usage("Bad k");
if (sscanf(argv[2], "%d", &m) == 0 || m <= 0) usage("Bad m");
if (sscanf(argv[3], "%d", &w) == 0 || w <= 0 || w > 32) usage("Bad w");
if (w < 30 && (k+m) > (1 << w)) usage("k + m is too big");
matrix = cauchy_original_coding_matrix(k, m, w);
if (matrix == NULL) {
usage("couldn't make coding matrix");
}
no = 0;
for (i = 0; i < k*m; i++) {
no += cauchy_n_ones(matrix[i], w);
}
printf("Matrix has %d ones\n\n", no);
jerasure_print_matrix(matrix, m, k, w);
printf("\n", no);
bitmatrix = jerasure_matrix_to_bitmatrix(k, m, w, matrix);
smart = jerasure_smart_bitmatrix_to_schedule(k, m, w, bitmatrix);
srand48(0);
data = talloc(char *, k);
for (i = 0; i < k; i++) {
data[i] = talloc(char, sizeof(long)*w);
for (j = 0; j < w; j++) {
l = lrand48();
memcpy(data[i]+j*sizeof(long), &l, sizeof(long));
}
}
coding = talloc(char *, m);
for (i = 0; i < m; i++) {
coding[i] = talloc(char, sizeof(long)*w);
}
jerasure_schedule_encode(k, m, w, smart, data, coding, w*sizeof(long), sizeof(long));
jerasure_get_stats(stats);
printf("Smart Encoding Complete: - %.0lf XOR'd bytes\n\n", stats[0]);
print_data_and_coding(k, m, w, sizeof(long), data, coding);
erasures = talloc(int, (m+1));
erased = talloc(int, (k+m));
for (i = 0; i < m+k; i++) erased[i] = 0;
for (i = 0; i < m; ) {
erasures[i] = lrand48()%(k+m);
if (erased[erasures[i]] == 0) {
erased[erasures[i]] = 1;
bzero((erasures[i] < k) ? data[erasures[i]] : coding[erasures[i]-k], sizeof(long)*w);
i++;
}
}
erasures[i] = -1;
printf("Erased %d random devices:\n\n", m);
print_data_and_coding(k, m, w, sizeof(long), data, coding);
jerasure_schedule_decode_lazy(k, m, w, bitmatrix, erasures, data, coding, w*sizeof(long), sizeof(long), 1);
jerasure_get_stats(stats);
printf("State of the system after decoding: %.0lf XOR'd bytes\n\n", stats[0]);
print_data_and_coding(k, m, w, sizeof(long), data, coding);
x = talloc(int, m);
y = talloc(int, k);
if (x == NULL || y == NULL) { perror("malloc"); exit(1); }
for (i = 0; i < m; i++) x[i] = i;
for (i = 0; i < k; i++) y[i] = m+i;
m2 = cauchy_xy_coding_matrix(k, m, w, x, y);
if (memcmp(matrix, m2, sizeof(int)*k*m) != 0) {
printf("Error -- the matrices made by original and xy don't match\n");
exit(1);
} else {
printf("Generated the identical matrix using cauchy_xy_coding_matrix()\n");
}
return 0;
}

204
Examples/cauchy_03.c Executable file
View File

@ -0,0 +1,204 @@
/* Examples/cauchy_03.c
* James S. Plank
Jerasure - A C/C++ Library for a Variety of Reed-Solomon and RAID-6 Erasure Coding Techniques
Revision 1.2A
May 24, 2011
James S. Plank
Department of Electrical Engineering and Computer Science
University of Tennessee
Knoxville, TN 37996
plank@cs.utk.edu
Copyright (c) 2011, James S. Plank
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
- Neither the name of the University of Tennessee nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
/*
revised by S. Simmerman
2/25/08
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "jerasure.h"
#include "cauchy.h"
#define talloc(type, num) (type *) malloc(sizeof(type)*(num))
usage(char *s)
{
fprintf(stderr, "usage: cauchy_03 k m w - Scheduled CRS coding example with improved matrix in GF(2^w).\n");
fprintf(stderr, " \n");
fprintf(stderr, " k+m must be <= 2^w. It sets up a Cauchy distribution matrix using the original\n");
fprintf(stderr, " Cauchy Distribution matrix construction algorithm, then improves it\n");
fprintf(stderr, " with cauchy_improve_coding_matrix(). Then it does the same encoding and\n");
fprintf(stderr, " decoding as cauchy_02.\n");
fprintf(stderr, " \n");
fprintf(stderr, "This demonstrates: cauchy_original_coding_matrix()\n");
fprintf(stderr, " cauchy_improve_coding_matrix()\n");
fprintf(stderr, " cauchy_n_ones()\n");
fprintf(stderr, " jerasure_smart_bitmatrix_to_schedule()\n");
fprintf(stderr, " jerasure_schedule_encode()\n");
fprintf(stderr, " jerasure_schedule_decode_lazy()\n");
fprintf(stderr, " jerasure_print_matrix()\n");
fprintf(stderr, " jerasure_get_stats()\n");
if (s != NULL) fprintf(stderr, "%s\n", s);
exit(1);
}
static void print_data_and_coding(int k, int m, int w, int psize,
char **data, char **coding)
{
int i, j, x, n, sp;
long l;
if(k > m) n = k;
else n = m;
sp = psize * 2 + (psize/4) + 12;
printf("%-*sCoding\n", sp, "Data");
for(i = 0; i < n; i++) {
for (j = 0; j < w; j++) {
if(i < k) {
if(j==0) printf("D%-2d p%-2d:", i,j);
else printf(" p%-2d:", j);
for(x = 0; x < psize; x +=4) {
memcpy(&l, data[i]+j*psize+x, sizeof(long));
printf(" %08lx", l);
}
printf(" ");
}
else printf("%*s", sp, "");
if(i < m) {
if(j==0) printf("C%-2d p%-2d:", i,j);
else printf(" p%-2d:", j);
for(x = 0; x < psize; x +=4) {
memcpy(&l, coding[i]+j*psize+x, sizeof(long));
printf(" %08lx", l);
}
}
printf("\n");
}
}
printf("\n");
}
int main(int argc, char **argv)
{
long l;
int k, w, i, j, m;
int *matrix, *bitmatrix, *m2, *x, *y;
char **data, **coding, **ptrs;
int **smart;
int no;
int *erasures, *erased;
double stats[3];
if (argc != 4) usage(NULL);
if (sscanf(argv[1], "%d", &k) == 0 || k <= 0) usage("Bad k");
if (sscanf(argv[2], "%d", &m) == 0 || m <= 0) usage("Bad m");
if (sscanf(argv[3], "%d", &w) == 0 || w <= 0 || w > 32) usage("Bad w");
if (w < 30 && (k+m) > (1 << w)) usage("k + m is too big");
matrix = cauchy_original_coding_matrix(k, m, w);
if (matrix == NULL) {
usage("couldn't make coding matrix");
}
no = 0;
for (i = 0; i < k*m; i++) {
no += cauchy_n_ones(matrix[i], w);
}
printf("The Original Matrix has %d ones\n", no);
cauchy_improve_coding_matrix(k, m, w, matrix);
no = 0;
for (i = 0; i < k*m; i++) {
no += cauchy_n_ones(matrix[i], w);
}
printf("The Improved Matrix has %d ones\n\n", no);
jerasure_print_matrix(matrix, m, k, w);
printf("\n", no);
bitmatrix = jerasure_matrix_to_bitmatrix(k, m, w, matrix);
smart = jerasure_smart_bitmatrix_to_schedule(k, m, w, bitmatrix);
srand48(0);
data = talloc(char *, k);
for (i = 0; i < k; i++) {
data[i] = talloc(char, sizeof(long)*w);
for (j = 0; j < w; j++) {
l = lrand48();
memcpy(data[i]+j*sizeof(long), &l, sizeof(long));
}
}
coding = talloc(char *, m);
for (i = 0; i < m; i++) {
coding[i] = talloc(char, sizeof(long)*w);
}
jerasure_schedule_encode(k, m, w, smart, data, coding, w*sizeof(long), sizeof(long));
jerasure_get_stats(stats);
printf("Smart Encoding Complete: - %.0lf XOR'd bytes\n\n", stats[0]);
print_data_and_coding(k, m, w, sizeof(long), data, coding);
erasures = talloc(int, (m+1));
erased = talloc(int, (k+m));
for (i = 0; i < m+k; i++) erased[i] = 0;
for (i = 0; i < m; ) {
erasures[i] = lrand48()%(k+m);
if (erased[erasures[i]] == 0) {
erased[erasures[i]] = 1;
bzero((erasures[i] < k) ? data[erasures[i]] : coding[erasures[i]-k], sizeof(long)*w);
i++;
}
}
erasures[i] = -1;
printf("Erased %d random devices:\n\n", m);
print_data_and_coding(k, m, w, sizeof(long), data, coding);
jerasure_schedule_decode_lazy(k, m, w, bitmatrix, erasures, data, coding, w*sizeof(long), sizeof(long), 1);
jerasure_get_stats(stats);
printf("State of the system after decoding: %.0lf XOR'd bytes\n\n", stats[0]);
print_data_and_coding(k, m, w, sizeof(long), data, coding);
return 0;
}

198
Examples/cauchy_04.c Executable file
View File

@ -0,0 +1,198 @@
/* Examples/cauchy_04.c
* James S. Plank
Jerasure - A C/C++ Library for a Variety of Reed-Solomon and RAID-6 Erasure Coding Techniques
Revision 1.2A
May 24, 2011
James S. Plank
Department of Electrical Engineering and Computer Science
University of Tennessee
Knoxville, TN 37996
plank@cs.utk.edu
Copyright (c) 2011, James S. Plank
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
- Neither the name of the University of Tennessee nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
/*
revised by S. Simmerman
2/25/08
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "jerasure.h"
#include "cauchy.h"
#define talloc(type, num) (type *) malloc(sizeof(type)*(num))
usage(char *s)
{
fprintf(stderr, "usage: cauchy_04 k m w - Scheduled CRS coding example with a good matrix in GF(2^w).\n");
fprintf(stderr, " \n");
fprintf(stderr, " k+m must be <= 2^w. It sets up a Cauchy distribution matrix using \n");
fprintf(stderr, " cauchy_good_coding_matrix(), then it encodes\n");
fprintf(stderr, " k devices of w*%d bytes using smart bit-matrix scheduling.\n", sizeof(long));
fprintf(stderr, " It decodes using bit-matrix scheduling as well.\n");
fprintf(stderr, " \n");
fprintf(stderr, "This demonstrates: cauchy_original_coding_matrix()\n");
fprintf(stderr, " cauchy_n_ones()\n");
fprintf(stderr, " jerasure_smart_bitmatrix_to_schedule()\n");
fprintf(stderr, " jerasure_schedule_encode()\n");
fprintf(stderr, " jerasure_schedule_decode_lazy()\n");
fprintf(stderr, " jerasure_print_matrix()\n");
fprintf(stderr, " jerasure_get_stats()\n");
if (s != NULL) fprintf(stderr, "%s\n", s);
exit(1);
}
static void print_data_and_coding(int k, int m, int w, int psize,
char **data, char **coding)
{
int i, j, x, n, sp;
long l;
if(k > m) n = k;
else n = m;
sp = psize * 2 + (psize/4) + 12;
printf("%-*sCoding\n", sp, "Data");
for(i = 0; i < n; i++) {
for (j = 0; j < w; j++) {
if(i < k) {
if(j==0) printf("D%-2d p%-2d:", i,j);
else printf(" p%-2d:", j);
for(x = 0; x < psize; x +=4) {
memcpy(&l, data[i]+j*psize+x, sizeof(long));
printf(" %08lx", l);
}
printf(" ");
}
else printf("%*s", sp, "");
if(i < m) {
if(j==0) printf("C%-2d p%-2d:", i,j);
else printf(" p%-2d:", j);
for(x = 0; x < psize; x +=4) {
memcpy(&l, coding[i]+j*psize+x, sizeof(long));
printf(" %08lx", l);
}
}
printf("\n");
}
}
printf("\n");
}
int main(int argc, char **argv)
{
long l;
int k, w, i, j, m;
int *matrix, *bitmatrix;
char **data, **coding, **ptrs;
int **smart;
int no;
int *erasures, *erased;
double stats[3];
if (argc != 4) usage(NULL);
if (sscanf(argv[1], "%d", &k) == 0 || k <= 0) usage("Bad k");
if (sscanf(argv[2], "%d", &m) == 0 || m <= 0) usage("Bad m");
if (sscanf(argv[3], "%d", &w) == 0 || w <= 0 || w > 32) usage("Bad w");
if (w < 30 && (k+m) > (1 << w)) usage("k + m is too big");
matrix = cauchy_good_general_coding_matrix(k, m, w);
if (matrix == NULL) {
usage("couldn't make coding matrix");
}
no = 0;
for (i = 0; i < k*m; i++) {
no += cauchy_n_ones(matrix[i], w);
}
printf("Matrix has %d ones\n\n", no);
jerasure_print_matrix(matrix, m, k, w);
printf("\n");
bitmatrix = jerasure_matrix_to_bitmatrix(k, m, w, matrix);
smart = jerasure_smart_bitmatrix_to_schedule(k, m, w, bitmatrix);
srand48(0);
data = talloc(char *, k);
for (i = 0; i < k; i++) {
data[i] = talloc(char, sizeof(long)*w);
for (j = 0; j < w; j++) {
l = lrand48();
memcpy(data[i]+j*sizeof(long), &l, sizeof(long));
}
}
coding = talloc(char *, m);
for (i = 0; i < m; i++) {
coding[i] = talloc(char, sizeof(long)*w);
}
jerasure_schedule_encode(k, m, w, smart, data, coding, w*sizeof(long), sizeof(long));
jerasure_get_stats(stats);
printf("Smart Encoding Complete: - %.0lf XOR'd bytes\n\n", stats[0]);
print_data_and_coding(k, m, w, sizeof(long), data, coding);
erasures = talloc(int, (m+1));
erased = talloc(int, (k+m));
for (i = 0; i < m+k; i++) erased[i] = 0;
for (i = 0; i < m; ) {
erasures[i] = lrand48()%(k+m);
if (erased[erasures[i]] == 0) {
erased[erasures[i]] = 1;
bzero((erasures[i] < k) ? data[erasures[i]] : coding[erasures[i]-k], sizeof(long)*w);
i++;
}
}
erasures[i] = -1;
printf("Erased %d random pieces of data/coding:\n\n", m);
print_data_and_coding(k, m, w, sizeof(long), data, coding);
jerasure_schedule_decode_lazy(k, m, w, bitmatrix, erasures, data, coding, w*sizeof(long), sizeof(long), 1);
jerasure_get_stats(stats);
printf("State of the system after decoding: %.0lf XOR'd bytes\n\n", stats[0]);
print_data_and_coding(k, m, w, sizeof(long), data, coding);
return 0;
}

399
Examples/decoder.c Executable file
View File

@ -0,0 +1,399 @@
/* Examples/decoder.c
* Catherine D. Schuman, James S. Plank
Jerasure - A C/C++ Library for a Variety of Reed-Solomon and RAID-6 Erasure Coding Techniques
Revision 1.2A
May 24, 2011
James S. Plank
Department of Electrical Engineering and Computer Science
University of Tennessee
Knoxville, TN 37996
plank@cs.utk.edu
Copyright (c) 2011, James S. Plank
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
- Neither the name of the University of Tennessee nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
/*
This program takes as input an inputfile, k, m, a coding
technique, w, and packetsize. It is the companion program
of encoder.c, which creates k+m files. This program assumes
that up to m erasures have occurred in the k+m files. It
reads in the k+m files or marks the file as erased. It then
recreates the original file and creates a new file with the
suffix "decoded" with the decoded contents of the file.
This program does not error check command line arguments because
it is assumed that encoder.c has been called previously with the
same arguments, and encoder.c does error check.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <signal.h>
#include "jerasure.h"
#include "reed_sol.h"
#include "galois.h"
#include "cauchy.h"
#include "liberation.h"
#define N 10
enum Coding_Technique {Reed_Sol_Van, Reed_Sol_R6_Op, Cauchy_Orig, Cauchy_Good, Liberation, Blaum_Roth, Liber8tion, RDP, EVENODD, No_Coding};
char *Methods[N] = {"reed_sol_van", "reed_sol_r6_op", "cauchy_orig", "cauchy_good", "liberation", "blaum_roth", "liber8tion", "rdp", "evenodd", "no_coding"};
/* Global variables for signal handler */
enum Coding_Technique method;
int readins, n;
/* Function prototype */
void ctrl_bs_handler(int dummy);
int main (int argc, char **argv) {
FILE *fp; // File pointer
/* Jerasure arguments */
char **data;
char **coding;
int *erasures;
int *erased;
int *matrix;
int *bitmatrix;
/* Parameters */
int k, m, w, packetsize, buffersize;
enum Coding_Technique tech;
char *c_tech;
int i, j; // loop control variables
int blocksize; // size of individual files
int origsize; // size of file before padding
int total; // used to write data, not padding to file
struct stat status; // used to find size of individual files
int numerased; // number of erased files
/* Used to recreate file names */
char *temp;
char *cs1, *cs2, *extension;
char *fname;
int md;
char *curdir;
/* Used to time decoding */
struct timeval t1, t2, t3, t4;
struct timezone tz;
double tsec;
double totalsec;
signal(SIGQUIT, ctrl_bs_handler);
matrix = NULL;
bitmatrix = NULL;
totalsec = 0.0;
/* Start timing */
gettimeofday(&t1, &tz);
/* Error checking parameters */
if (argc != 2) {
fprintf(stderr, "usage: inputfile\n");
exit(0);
}
curdir = (char *)malloc(sizeof(char)*100);
getcwd(curdir, 100);
/* Begin recreation of file names */
cs1 = (char*)malloc(sizeof(char)*strlen(argv[1]));
cs2 = strrchr(argv[1], '/');
if (cs2 != NULL) {
cs2++;
strcpy(cs1, cs2);
}
else {
strcpy(cs1, argv[1]);
}
cs2 = strchr(cs1, '.');
if (cs2 != NULL) {
extension = strdup(cs2);
*cs2 = '\0';
} else {
extension = strdup("");
}
fname = (char *)malloc(sizeof(char*)*(100+strlen(argv[1])+10));
/* Read in parameters from metadata file */
sprintf(fname, "%s/Coding/%s_meta.txt", curdir, cs1);
fp = fopen(fname, "rb");
if (fp == NULL) {
fprintf(stderr, "Error: no metadata file %s\n", fname);
exit(1);
}
temp = (char *)malloc(sizeof(char)*(strlen(argv[1])+10));
fscanf(fp, "%s", temp);
if (fscanf(fp, "%d", &origsize) != 1) {
fprintf(stderr, "Original size is not valid\n");
exit(0);
}
if (fscanf(fp, "%d %d %d %d %d", &k, &m, &w, &packetsize, &buffersize) != 5) {
fprintf(stderr, "Parameters are not correct\n");
exit(0);
}
c_tech = (char *)malloc(sizeof(char)*(strlen(argv[1])+10));
fscanf(fp, "%s", c_tech);
fscanf(fp, "%d", &tech);
method = tech;
fscanf(fp, "%d", &readins);
fclose(fp);
/* Allocate memory */
erased = (int *)malloc(sizeof(int)*(k+m));
for (i = 0; i < k+m; i++)
erased[i] = 0;
erasures = (int *)malloc(sizeof(int)*(k+m));
data = (char **)malloc(sizeof(char *)*k);
coding = (char **)malloc(sizeof(char *)*m);
if (buffersize != origsize) {
for (i = 0; i < k; i++) {
data[i] = (char *)malloc(sizeof(char)*(buffersize/k));
}
for (i = 0; i < m; i++) {
coding[i] = (char *)malloc(sizeof(char)*(buffersize/k));
}
blocksize = buffersize/k;
}
sprintf(temp, "%d", k);
md = strlen(temp);
gettimeofday(&t3, &tz);
/* Create coding matrix or bitmatrix */
switch(tech) {
case No_Coding:
break;
case Reed_Sol_Van:
matrix = reed_sol_vandermonde_coding_matrix(k, m, w);
break;
case Reed_Sol_R6_Op:
matrix = reed_sol_r6_coding_matrix(k, w);
break;
case Cauchy_Orig:
matrix = cauchy_original_coding_matrix(k, m, w);
bitmatrix = jerasure_matrix_to_bitmatrix(k, m, w, matrix);
break;
case Cauchy_Good:
matrix = cauchy_good_general_coding_matrix(k, m, w);
bitmatrix = jerasure_matrix_to_bitmatrix(k, m, w, matrix);
break;
case Liberation:
bitmatrix = liberation_coding_bitmatrix(k, w);
break;
case Blaum_Roth:
bitmatrix = blaum_roth_coding_bitmatrix(k, w);
break;
case Liber8tion:
bitmatrix = liber8tion_coding_bitmatrix(k);
}
gettimeofday(&t4, &tz);
tsec = 0.0;
tsec += t4.tv_usec;
tsec -= t3.tv_usec;
tsec /= 1000000.0;
tsec += t4.tv_sec;
tsec -= t3.tv_sec;
totalsec += tsec;
/* Begin decoding process */
total = 0;
n = 1;
while (n <= readins) {
numerased = 0;
/* Open files, check for erasures, read in data/coding */
for (i = 1; i <= k; i++) {
sprintf(fname, "%s/Coding/%s_k%0*d%s", curdir, cs1, md, i, extension);
fp = fopen(fname, "rb");
if (fp == NULL) {
erased[i-1] = 1;
erasures[numerased] = i-1;
numerased++;
//printf("%s failed\n", fname);
}
else {
if (buffersize == origsize) {
stat(fname, &status);
blocksize = status.st_size;
data[i-1] = (char *)malloc(sizeof(char)*blocksize);
fread(data[i-1], sizeof(char), blocksize, fp);
}
else {
fseek(fp, blocksize*(n-1), SEEK_SET);
fread(data[i-1], sizeof(char), buffersize/k, fp);
}
fclose(fp);
}
}
for (i = 1; i <= m; i++) {
sprintf(fname, "%s/Coding/%s_m%0*d%s", curdir, cs1, md, i, extension);
fp = fopen(fname, "rb");
if (fp == NULL) {
erased[k+(i-1)] = 1;
erasures[numerased] = k+i-1;
numerased++;
//printf("%s failed\n", fname);
}
else {
if (buffersize == origsize) {
stat(fname, &status);
blocksize = status.st_size;
coding[i-1] = (char *)malloc(sizeof(char)*blocksize);
fread(coding[i-1], sizeof(char), blocksize, fp);
}
else {
fseek(fp, blocksize*(n-1), SEEK_SET);
fread(coding[i-1], sizeof(char), blocksize, fp);
}
fclose(fp);
}
}
/* Finish allocating data/coding if needed */
if (n == 1) {
for (i = 0; i < numerased; i++) {
if (erasures[i] < k) {
data[erasures[i]] = (char *)malloc(sizeof(char)*blocksize);
}
else {
coding[erasures[i]-k] = (char *)malloc(sizeof(char)*blocksize);
}
}
}
erasures[numerased] = -1;
gettimeofday(&t3, &tz);
/* Choose proper decoding method */
if (tech == Reed_Sol_Van || tech == Reed_Sol_R6_Op) {
i = jerasure_matrix_decode(k, m, w, matrix, 1, erasures, data, coding, blocksize);
}
else if (tech == Cauchy_Orig || tech == Cauchy_Good || tech == Liberation || tech == Blaum_Roth || tech == Liber8tion) {
i = jerasure_schedule_decode_lazy(k, m, w, bitmatrix, erasures, data, coding, blocksize, packetsize, 1);
}
else {
fprintf(stderr, "Not a valid coding technique.\n");
exit(0);
}
gettimeofday(&t4, &tz);
/* Exit if decoding was unsuccessful */
if (i == -1) {
fprintf(stderr, "Unsuccessful!\n");
exit(0);
}
/* Create decoded file */
sprintf(fname, "%s/Coding/%s_decoded%s", curdir, cs1, extension);
if (n == 1) {
fp = fopen(fname, "wb");
}
else {
fp = fopen(fname, "ab");
}
for (i = 0; i < k; i++) {
if (total+blocksize <= origsize) {
fwrite(data[i], sizeof(char), blocksize, fp);
total+= blocksize;
}
else {
for (j = 0; j < blocksize; j++) {
if (total < origsize) {
fprintf(fp, "%c", data[i][j]);
total++;
}
else {
break;
}
}
}
}
n++;
fclose(fp);
tsec = 0.0;
tsec += t4.tv_usec;
tsec -= t3.tv_usec;
tsec /= 1000000.0;
tsec += t4.tv_sec;
tsec -= t3.tv_sec;
totalsec += tsec;
}
/* Free allocated memory */
free(cs1);
free(extension);
free(fname);
free(data);
free(coding);
free(erasures);
free(erased);
/* Stop timing and print time */
gettimeofday(&t2, &tz);
tsec = 0;
tsec += t2.tv_usec;
tsec -= t1.tv_usec;
tsec /= 1000000.0;
tsec += t2.tv_sec;
tsec -= t1.tv_sec;
printf("Decoding (MB/sec): %0.10f\n", (origsize/1024/1024)/totalsec);
printf("De_Total (MB/sec): %0.10f\n\n", (origsize/1024/1024)/tsec);
}
void ctrl_bs_handler(int dummy) {
time_t mytime;
mytime = time(0);
fprintf(stderr, "\n%s\n", ctime(&mytime));
fprintf(stderr, "You just typed ctrl-\\ in decoder.c\n");
fprintf(stderr, "Total number of read ins = %d\n", readins);
fprintf(stderr, "Current read in: %d\n", n);
fprintf(stderr, "Method: %s\n\n", Methods[method]);
signal(SIGQUIT, ctrl_bs_handler);
}

636
Examples/encoder.c Executable file
View File

@ -0,0 +1,636 @@
/* Examples/encoder.c
* Catherine D. Schuman, James S. Plank
Jerasure - A C/C++ Library for a Variety of Reed-Solomon and RAID-6 Erasure Coding Techniques
Revision 1.2A
May 24, 2011
James S. Plank
Department of Electrical Engineering and Computer Science
University of Tennessee
Knoxville, TN 37996
plank@cs.utk.edu
Copyright (c) 2011, James S. Plank
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
- Neither the name of the University of Tennessee nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
/*
This program takes as input an inputfile, k, m, a coding
technique, w, and packetsize. It creates k+m files from
the original file so that k of these files are parts of
the original file and m of the files are encoded based on
the given coding technique. The format of the created files
is the file name with "_k#" or "_m#" and then the extension.
(For example, inputfile test.txt would yield file "test_k1.txt".)
*/
#include <sys/time.h>
#include <sys/stat.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <signal.h>
#include "jerasure.h"
#include "reed_sol.h"
#include "galois.h"
#include "cauchy.h"
#include "liberation.h"
#define N 10
enum Coding_Technique {Reed_Sol_Van, Reed_Sol_R6_Op, Cauchy_Orig, Cauchy_Good, Liberation, Blaum_Roth, Liber8tion, RDP, EVENODD, No_Coding};
char *Methods[N] = {"reed_sol_van", "reed_sol_r6_op", "cauchy_orig", "cauchy_good", "liberation", "blaum_roth", "liber8tion", "no_coding"};
/* Global variables for signal handler */
int readins, n;
enum Coding_Technique method;
/* Function prototypes */
int is_prime(int w);
void ctrl_bs_handler(int dummy);
int jfread(void *ptr, int size, int nmembers, FILE *stream)
{
int nd;
int *li, i;
if (stream != NULL) return fread(ptr, size, nmembers, stream);
nd = size/sizeof(int);
li = (int *) ptr;
for (i = 0; i < nd; i++) li[i] = mrand48();
return size;
}
int main (int argc, char **argv) {
FILE *fp, *fp2; // file pointers
char *memblock; // reading in file
char *block; // padding file
int size, newsize; // size of file and temp size
struct stat status; // finding file size
enum Coding_Technique tech; // coding technique (parameter)
int k, m, w, packetsize; // parameters
int buffersize; // paramter
int i, j; // loop control variables
int blocksize; // size of k+m files
int total;
int extra;
/* Jerasure Arguments */
char **data;
char **coding;
int *matrix;
int *bitmatrix;
int **schedule;
int *erasure;
int *erased;
/* Creation of file name variables */
char temp[5];
char *s1, *s2, *extension;
char *fname;
int md;
char *curdir;
/* Timing variables */
struct timeval t1, t2, t3, t4;
struct timezone tz;
double tsec;
double totalsec;
struct timeval start, stop;
/* Find buffersize */
int up, down;
signal(SIGQUIT, ctrl_bs_handler);
/* Start timing */
gettimeofday(&t1, &tz);
totalsec = 0.0;
matrix = NULL;
bitmatrix = NULL;
schedule = NULL;
/* Error check Arguments*/
if (argc != 8) {
fprintf(stderr, "usage: inputfile k m coding_technique w (packetsize) (buffersize)\n");
fprintf(stderr, "\nChoose one of the following coding techniques: \nreed_sol_van, \nreed_sol_r6_op, \ncauchy_orig, \ncauchy_good, \nliberation, \nblaum_roth, \nliber8tion");
exit(0);
}
/* Conversion of parameters and error checking */
if (sscanf(argv[2], "%d", &k) == 0 || k <= 0) {
fprintf(stderr, "Invalid value for k\n");
exit(0);
}
if (sscanf(argv[3], "%d", &m) == 0 || m < 0) {
fprintf(stderr, "Invalid value for m\n");
exit(0);
}
if (sscanf(argv[5],"%d", &w) == 0 || w <= 0) {
fprintf(stderr, "Invalid value for w.\n");
exit(0);
}
if (argc == 6) {
packetsize = 0;
}
else {
if (sscanf(argv[6], "%d", &packetsize) == 0 || packetsize < 0) {
fprintf(stderr, "Invalid value for packetsize.\n");
exit(0);
}
}
if (argc != 8) {
buffersize = 0;
}
else {
if (sscanf(argv[7], "%d", &buffersize) == 0 || buffersize < 0) {
fprintf(stderr, "Invalid value for buffersize\n");
exit(0);
}
}
/* Determine proper buffersize by finding the closest valid buffersize to the input value */
if (buffersize != 0) {
if (packetsize != 0 && buffersize%(sizeof(int)*w*k*packetsize) != 0) {
up = buffersize;
down = buffersize;
while (up%(sizeof(int)*w*k*packetsize) != 0 && (down%(sizeof(int)*w*k*packetsize) != 0)) {
up++;
if (down == 0) {
down--;
}
}
if (up%(sizeof(int)*w*k*packetsize) == 0) {
buffersize = up;
}
else {
if (down != 0) {
buffersize = down;
}
}
}
else if (packetsize == 0 && buffersize%(sizeof(int)*w*k) != 0) {
up = buffersize;
down = buffersize;
while (up%(sizeof(int)*w*k) != 0 && down%(sizeof(int)*w*k) != 0) {
up++;
down--;
}
if (up%(sizeof(int)*w*k) == 0) {
buffersize = up;
}
else {
buffersize = down;
}
}
}
/* Setting of coding technique and error checking */
if (strcmp(argv[4], "no_coding") == 0) {
tech = No_Coding;
}
else if (strcmp(argv[4], "reed_sol_van") == 0) {
tech = Reed_Sol_Van;
if (w != 8 && w != 16 && w != 32) {
fprintf(stderr, "w must be one of {8, 16, 32}\n");
exit(0);
}
}
else if (strcmp(argv[4], "reed_sol_r6_op") == 0) {
if (m != 2) {
fprintf(stderr, "m must be equal to 2\n");
exit(0);
}
if (w != 8 && w != 16 && w != 32) {
fprintf(stderr, "w must be one of {8, 16, 32}\n");
exit(0);
}
tech = Reed_Sol_R6_Op;
}
else if (strcmp(argv[4], "cauchy_orig") == 0) {
tech = Cauchy_Orig;
if (packetsize == 0) {
fprintf(stderr, "Must include packetsize.\n");
exit(0);
}
}
else if (strcmp(argv[4], "cauchy_good") == 0) {
tech = Cauchy_Good;
if (packetsize == 0) {
fprintf(stderr, "Must include packetsize.\n");
exit(0);
}
}
else if (strcmp(argv[4], "liberation") == 0) {
if (k > w) {
fprintf(stderr, "k must be less than or equal to w\n");
exit(0);
}
if (w <= 2 || !(w%2) || !is_prime(w)) {
fprintf(stderr, "w must be greater than two and w must be prime\n");
exit(0);
}
if (packetsize == 0) {
fprintf(stderr, "Must include packetsize.\n");
exit(0);
}
if ((packetsize%(sizeof(int))) != 0) {
fprintf(stderr, "packetsize must be a multiple of sizeof(int)\n");
exit(0);
}
tech = Liberation;
}
else if (strcmp(argv[4], "blaum_roth") == 0) {
if (k > w) {
fprintf(stderr, "k must be less than or equal to w\n");
exit(0);
}
if (w <= 2 || !((w+1)%2) || !is_prime(w+1)) {
fprintf(stderr, "w must be greater than two and w+1 must be prime\n");
exit(0);
}
if (packetsize == 0) {
fprintf(stderr, "Must include packetsize.\n");
exit(0);
}
if ((packetsize%(sizeof(int))) != 0) {
fprintf(stderr, "packetsize must be a multiple of sizeof(int)\n");
exit(0);
}
tech = Blaum_Roth;
}
else if (strcmp(argv[4], "liber8tion") == 0) {
if (packetsize == 0) {
fprintf(stderr, "Must include packetsize\n");
exit(0);
}
if (w != 8) {
fprintf(stderr, "w must equal 8\n");
exit(0);
}
if (m != 2) {
fprintf(stderr, "m must equal 2\n");
exit(0);
}
if (k > w) {
fprintf(stderr, "k must be less than or equal to w\n");
exit(0);
}
tech = Liber8tion;
}
else {
fprintf(stderr, "Not a valid coding technique. Choose one of the following: reed_sol_van, reed_sol_r6_op, cauchy_orig, cauchy_good, liberation, blaum_roth, liber8tion, no_coding\n");
exit(0);
}
/* Set global variable method for signal handler */
method = tech;
/* Get current working directory for construction of file names */
curdir = (char*)malloc(sizeof(char)*1000);
getcwd(curdir, 1000);
if (argv[1][0] != '-') {
/* Open file and error check */
fp = fopen(argv[1], "rb");
if (fp == NULL) {
fprintf(stderr, "Unable to open file.\n");
exit(0);
}
/* Create Coding directory */
i = mkdir("Coding", S_IRWXU);
if (i == -1 && errno != EEXIST) {
fprintf(stderr, "Unable to create Coding directory.\n");
exit(0);
}
/* Determine original size of file */
stat(argv[1], &status);
size = status.st_size;
} else {
if (sscanf(argv[1]+1, "%d", &size) != 1 || size <= 0) {
fprintf(stderr, "Files starting with '-' should be sizes for randomly created input\n");
exit(1);
}
fp = NULL;
srand48(time(0));
}
newsize = size;
/* Find new size by determining next closest multiple */
if (packetsize != 0) {
if (size%(k*w*packetsize*sizeof(int)) != 0) {
while (newsize%(k*w*packetsize*sizeof(int)) != 0)
newsize++;
}
}
else {
if (size%(k*w*sizeof(int)) != 0) {
while (newsize%(k*w*sizeof(int)) != 0)
newsize++;
}
}
if (buffersize != 0) {
while (newsize%buffersize != 0) {
newsize++;
}
}
/* Determine size of k+m files */
blocksize = newsize/k;
/* Allow for buffersize and determine number of read-ins */
if (size > buffersize && buffersize != 0) {
if (newsize%buffersize != 0) {
readins = newsize/buffersize;
}
else {
readins = newsize/buffersize;
}
block = (char *)malloc(sizeof(char)*buffersize);
blocksize = buffersize/k;
}
else {
readins = 1;
buffersize = size;
block = (char *)malloc(sizeof(char)*newsize);
}
/* Break inputfile name into the filename and extension */
s1 = (char*)malloc(sizeof(char)*(strlen(argv[1])+10));
s2 = strrchr(argv[1], '/');
if (s2 != NULL) {
s2++;
strcpy(s1, s2);
}
else {
strcpy(s1, argv[1]);
}
s2 = strchr(s1, '.');
if (s2 != NULL) {
extension = strdup(s2);
*s2 = '\0';
} else {
extension = strdup("");
}
/* Allocate for full file name */
fname = (char*)malloc(sizeof(char)*(strlen(argv[1])+strlen(curdir)+10));
sprintf(temp, "%d", k);
md = strlen(temp);
/* Allocate data and coding */
data = (char **)malloc(sizeof(char*)*k);
coding = (char **)malloc(sizeof(char*)*m);
for (i = 0; i < m; i++) {
coding[i] = (char *)malloc(sizeof(char)*blocksize);
if (coding[i] == NULL) { perror("malloc"); exit(1); }
}
/* Create coding matrix or bitmatrix and schedule */
gettimeofday(&t3, &tz);
switch(tech) {
case No_Coding:
break;
case Reed_Sol_Van:
matrix = reed_sol_vandermonde_coding_matrix(k, m, w);
break;
case Cauchy_Orig:
matrix = cauchy_original_coding_matrix(k, m, w);
bitmatrix = jerasure_matrix_to_bitmatrix(k, m, w, matrix);
schedule = jerasure_smart_bitmatrix_to_schedule(k, m, w, bitmatrix);
break;
case Cauchy_Good:
matrix = cauchy_good_general_coding_matrix(k, m, w);
bitmatrix = jerasure_matrix_to_bitmatrix(k, m, w, matrix);
schedule = jerasure_smart_bitmatrix_to_schedule(k, m, w, bitmatrix);
break;
case Liberation:
bitmatrix = liberation_coding_bitmatrix(k, w);
schedule = jerasure_smart_bitmatrix_to_schedule(k, m, w, bitmatrix);
break;
case Blaum_Roth:
bitmatrix = blaum_roth_coding_bitmatrix(k, w);
schedule = jerasure_smart_bitmatrix_to_schedule(k, m, w, bitmatrix);
break;
case Liber8tion:
bitmatrix = liber8tion_coding_bitmatrix(k);
schedule = jerasure_smart_bitmatrix_to_schedule(k, m, w, bitmatrix);
break;
}
gettimeofday(&start, &tz);
gettimeofday(&t4, &tz);
tsec = 0.0;
tsec += t4.tv_usec;
tsec -= t3.tv_usec;
tsec /= 1000000.0;
tsec += t4.tv_sec;
tsec -= t3.tv_sec;
totalsec += tsec;
/* Read in data until finished */
n = 1;
total = 0;
while (n <= readins) {
/* Check if padding is needed, if so, add appropriate
number of zeros */
if (total < size && total+buffersize <= size) {
total += jfread(block, sizeof(char), buffersize, fp);
}
else if (total < size && total+buffersize > size) {
extra = jfread(block, sizeof(char), buffersize, fp);
for (i = extra; i < buffersize; i++) {
block[i] = '0';
}
}
else if (total == size) {
for (i = 0; i < buffersize; i++) {
block[i] = '0';
}
}
/* Set pointers to point to file data */
for (i = 0; i < k; i++) {
data[i] = block+(i*blocksize);
}
gettimeofday(&t3, &tz);
/* Encode according to coding method */
switch(tech) {
case No_Coding:
break;
case Reed_Sol_Van:
jerasure_matrix_encode(k, m, w, matrix, data, coding, blocksize);
break;
case Reed_Sol_R6_Op:
reed_sol_r6_encode(k, w, data, coding, blocksize);
break;
case Cauchy_Orig:
jerasure_schedule_encode(k, m, w, schedule, data, coding, blocksize, packetsize);
break;
case Cauchy_Good:
jerasure_schedule_encode(k, m, w, schedule, data, coding, blocksize, packetsize);
break;
case Liberation:
jerasure_schedule_encode(k, m, w, schedule, data, coding, blocksize, packetsize);
break;
case Blaum_Roth:
jerasure_schedule_encode(k, m, w, schedule, data, coding, blocksize, packetsize);
break;
case Liber8tion:
jerasure_schedule_encode(k, m, w, schedule, data, coding, blocksize, packetsize);
break;
}
gettimeofday(&t4, &tz);
/* Write data and encoded data to k+m files */
for (i = 1; i <= k; i++) {
if (fp == NULL) {
bzero(data[i-1], blocksize);
} else {
sprintf(fname, "%s/Coding/%s_k%0*d%s", curdir, s1, md, i, extension);
if (n == 1) {
fp2 = fopen(fname, "wb");
}
else {
fp2 = fopen(fname, "ab");
}
fwrite(data[i-1], sizeof(char), blocksize, fp2);
fclose(fp2);
}
}
for (i = 1; i <= m; i++) {
if (fp == NULL) {
bzero(data[i-1], blocksize);
} else {
sprintf(fname, "%s/Coding/%s_m%0*d%s", curdir, s1, md, i, extension);
if (n == 1) {
fp2 = fopen(fname, "wb");
}
else {
fp2 = fopen(fname, "ab");
}
fwrite(coding[i-1], sizeof(char), blocksize, fp2);
fclose(fp2);
}
}
n++;
/* Calculate encoding time */
tsec = 0.0;
tsec += t4.tv_usec;
tsec -= t3.tv_usec;
tsec /= 1000000.0;
tsec += t4.tv_sec;
tsec -= t3.tv_sec;
totalsec += tsec;
}
/* Create metadata file */
if (fp != NULL) {
sprintf(fname, "%s/Coding/%s_meta.txt", curdir, s1);
fp2 = fopen(fname, "wb");
fprintf(fp2, "%s\n", argv[1]);
fprintf(fp2, "%d\n", size);
fprintf(fp2, "%d %d %d %d %d\n", k, m, w, packetsize, buffersize);
fprintf(fp2, "%s\n", argv[4]);
fprintf(fp2, "%d\n", tech);
fprintf(fp2, "%d\n", readins);
fclose(fp2);
}
/* Free allocated memory */
free(s1);
free(fname);
free(block);
free(curdir);
/* Calculate rate in MB/sec and print */
gettimeofday(&t2, &tz);
tsec = 0.0;
tsec += t2.tv_usec;
tsec -= t1.tv_usec;
tsec /= 1000000.0;
tsec += t2.tv_sec;
tsec -= t1.tv_sec;
printf("Encoding (MB/sec): %0.10f\n", (size/1024/1024)/totalsec);
printf("En_Total (MB/sec): %0.10f\n", (size/1024/1024)/tsec);
}
/* is_prime returns 1 if number if prime, 0 if not prime */
int is_prime(int w) {
int prime55[] = {2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,
73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,
181,191,193,197,199,211,223,227,229,233,239,241,251,257};
int i;
for (i = 0; i < 55; i++) {
if (w%prime55[i] == 0) {
if (w == prime55[i]) return 1;
else { return 0; }
}
}
}
/* Handles ctrl-\ event */
void ctrl_bs_handler(int dummy) {
time_t mytime;
mytime = time(0);
fprintf(stderr, "\n%s\n", ctime(&mytime));
fprintf(stderr, "You just typed ctrl-\\ in encoder.c.\n");
fprintf(stderr, "Total number of read ins = %d\n", readins);
fprintf(stderr, "Current read in: %d\n", n);
fprintf(stderr, "Method: %s\n\n", Methods[method]);
signal(SIGQUIT, ctrl_bs_handler);
}

88
Examples/jerasure_01.c Executable file
View File

@ -0,0 +1,88 @@
/* Examples/jerasure_01.c
* James S. Plank
Jerasure - A C/C++ Library for a Variety of Reed-Solomon and RAID-6 Erasure Coding Techniques
Revision 1.2A
May 24, 2011
James S. Plank
Department of Electrical Engineering and Computer Science
University of Tennessee
Knoxville, TN 37996
plank@cs.utk.edu
Copyright (c) 2011, James S. Plank
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
- Neither the name of the University of Tennessee nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <stdlib.h>
#include "jerasure.h"
#define talloc(type, num) (type *) malloc(sizeof(type)*(num))
usage(char *s)
{
fprintf(stderr, "usage: jerasure_01 r c w - creates and prints out a matrix in GF(2^w).\n\n");
fprintf(stderr, " Element i,j is equal to 2^(i*c+j)\n");
fprintf(stderr, " \n");
fprintf(stderr, "This demonstrates jerasure_print_matrix().\n");
if (s != NULL) fprintf(stderr, "%s\n", s);
exit(1);
}
int main(int argc, char **argv)
{
int r, c, w, i, n;
int *matrix;
if (argc != 4) usage(NULL);
if (sscanf(argv[1], "%d", &r) == 0 || r <= 0) usage("Bad r");
if (sscanf(argv[2], "%d", &c) == 0 || c <= 0) usage("Bad c");
if (sscanf(argv[3], "%d", &w) == 0 || w <= 0) usage("Bad w");
matrix = talloc(int, r*c);
n = 1;
for (i = 0; i < r*c; i++) {
matrix[i] = n;
n = galois_single_multiply(n, 2, w);
}
jerasure_print_matrix(matrix, r, c, w);
return 0;
}

86
Examples/jerasure_02.c Executable file
View File

@ -0,0 +1,86 @@
/* Examples/jerasure_02.c
Jerasure - A C/C++ Library for a Variety of Reed-Solomon and RAID-6 Erasure Coding Techniques
Revision 1.2A
May 24, 2011
James S. Plank
Department of Electrical Engineering and Computer Science
University of Tennessee
Knoxville, TN 37996
plank@cs.utk.edu
Copyright (c) 2011, James S. Plank
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
- Neither the name of the University of Tennessee nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <stdlib.h>
#include "jerasure.h"
#define talloc(type, num) (type *) malloc(sizeof(type)*(num))
usage(char *s)
{
fprintf(stderr, "usage: jerasure_02 r c w - Converts the matrix of jerasure_01 to a bit matrix.\n");
fprintf(stderr, " \n");
fprintf(stderr, "This demonstrates jerasure_print_bitmatrix() and jerasure_matrix_to_bitmatrix().\n");
if (s != NULL) fprintf(stderr, "%s\n", s);
exit(1);
}
int main(int argc, char **argv)
{
int r, c, w, i, n;
int *matrix;
int *bitmatrix;
if (argc != 4) usage(NULL);
if (sscanf(argv[1], "%d", &r) == 0 || r <= 0) usage("Bad r");
if (sscanf(argv[2], "%d", &c) == 0 || c <= 0) usage("Bad c");
if (sscanf(argv[3], "%d", &w) == 0 || w <= 0) usage("Bad w");
matrix = talloc(int, r*c);
n = 1;
for (i = 0; i < r*c; i++) {
matrix[i] = n;
n = galois_single_multiply(n, 2, w);
}
bitmatrix = jerasure_matrix_to_bitmatrix(c, r, w, matrix);
jerasure_print_bitmatrix(bitmatrix, r*w, c*w, w);
return 0;
}

113
Examples/jerasure_03.c Executable file
View File

@ -0,0 +1,113 @@
/* Examples/jerasure_03.c
Jerasure - A C/C++ Library for a Variety of Reed-Solomon and RAID-6 Erasure Coding Techniques
Revision 1.2A
May 24, 2011
James S. Plank
Department of Electrical Engineering and Computer Science
University of Tennessee
Knoxville, TN 37996
plank@cs.utk.edu
Copyright (c) 2011, James S. Plank
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
- Neither the name of the University of Tennessee nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "jerasure.h"
#define talloc(type, num) (type *) malloc(sizeof(type)*(num))
usage(char *s)
{
fprintf(stderr, "usage: jerasure_03 k w - Creates a kxk Cauchy matrix in GF(2^w). \n\n");
fprintf(stderr, " k must be < 2^w. Element i,j is 1/(i+(2^w-j-1)). (If that is\n");
fprintf(stderr, " 1/0, then it sets it to zero). \n");
fprintf(stderr, " It then tests whether that matrix is invertible.\n");
fprintf(stderr, " If it is invertible, then it prints out the inverse.\n");
fprintf(stderr, " Finally, it prints the product of the matrix and its inverse.\n");
fprintf(stderr, " \n");
fprintf(stderr, "This demonstrates: jerasure_print_matrix()\n");
fprintf(stderr, " jerasure_invertible_matrix()\n");
fprintf(stderr, " jerasure_invert_matrix()\n");
fprintf(stderr, " jerasure_matrix_multiply().\n");
if (s != NULL) fprintf(stderr, "%s\n", s);
exit(1);
}
int main(int argc, char **argv)
{
unsigned int k, w, i, j, n;
int *matrix;
int *matrix_copy;
int *inverse;
int *identity;
if (argc != 3) usage(NULL);
if (sscanf(argv[1], "%d", &k) == 0 || k <= 0) usage("Bad k");
if (sscanf(argv[2], "%d", &w) == 0 || w <= 0 || w > 31) usage("Bad w");
if (k >= (1 << w)) usage("K too big");
matrix = talloc(int, k*k);
matrix_copy = talloc(int, k*k);
inverse = talloc(int, k*k);
for (i = 0; i < k; i++) {
for (j = 0; j < k; j++) {
n = i ^ ((1 << w)-1-j);
matrix[i*k+j] = (n == 0) ? 0 : galois_single_divide(1, n, w);
}
}
printf("The Cauchy Matrix:\n");
jerasure_print_matrix(matrix, k, k, w);
memcpy(matrix_copy, matrix, sizeof(int)*k*k);
i = jerasure_invertible_matrix(matrix_copy, k, w);
printf("\nInvertible: %s\n", (i == 1) ? "Yes" : "No");
if (i == 1) {
printf("\nInverse:\n");
memcpy(matrix_copy, matrix, sizeof(int)*k*k);
i = jerasure_invert_matrix(matrix_copy, inverse, k, w);
jerasure_print_matrix(inverse, k, k, w);
identity = jerasure_matrix_multiply(inverse, matrix, k, k, k, k, w);
printf("\nInverse times matrix (should be identity):\n");
jerasure_print_matrix(identity, k, k, w);
}
return 0;
}

111
Examples/jerasure_04.c Executable file
View File

@ -0,0 +1,111 @@
/* Examples/jerasure_04.c
Jerasure - A C/C++ Library for a Variety of Reed-Solomon and RAID-6 Erasure Coding Techniques
Revision 1.2A
May 24, 2011
James S. Plank
Department of Electrical Engineering and Computer Science
University of Tennessee
Knoxville, TN 37996
plank@cs.utk.edu
Copyright (c) 2011, James S. Plank
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
- Neither the name of the University of Tennessee nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "jerasure.h"
#define talloc(type, num) (type *) malloc(sizeof(type)*(num))
usage(char *s)
{
fprintf(stderr, "usage: jerasure_04 k w - Performs the analogous bit-matrix operations to jerasure_03.\n\n");
fprintf(stderr, " It converts the matrix to a kw*kw bit matrix and does the same operations.\n");
fprintf(stderr, " k must be < 2^w.\n");
fprintf(stderr, "This demonstrates: jerasure_print_bitmatrix()\n");
fprintf(stderr, " jerasure_matrix_to_bitmatrix()\n");
fprintf(stderr, " jerasure_invertible_bitmatrix()\n");
fprintf(stderr, " jerasure_invert_bitmatrix()\n");
fprintf(stderr, " jerasure_matrix_multiply().\n");
if (s != NULL) fprintf(stderr, "%s\n", s);
exit(1);
}
int main(int argc, char **argv)
{
unsigned int k, w, i, j, n;
int *matrix;
int *bitmatrix;
int *bitmatrix_copy;
int *inverse;
int *identity;
if (argc != 3) usage(NULL);
if (sscanf(argv[1], "%d", &k) == 0 || k <= 0) usage("Bad k");
if (sscanf(argv[2], "%d", &w) == 0 || w <= 0 || w > 31) usage("Bad w");
if (k >= (1 << w)) usage("K too big");
matrix = talloc(int, k*k);
bitmatrix_copy = talloc(int, k*w*k*w);
inverse = talloc(int, k*w*k*w);
for (i = 0; i < k; i++) {
for (j = 0; j < k; j++) {
n = i ^ ((1 << w)-1-j);
matrix[i*k+j] = (n == 0) ? 0 : galois_single_divide(1, n, w);
}
}
bitmatrix = jerasure_matrix_to_bitmatrix(k, k, w, matrix);
printf("The Cauchy Bit-Matrix:\n");
jerasure_print_bitmatrix(bitmatrix, k*w, k*w, w);
memcpy(bitmatrix_copy, bitmatrix, sizeof(int)*k*w*k*w);
i = jerasure_invertible_bitmatrix(bitmatrix_copy, k*w);
printf("\nInvertible: %s\n", (i == 1) ? "Yes" : "No");
if (i == 1) {
printf("\nInverse:\n");
memcpy(bitmatrix_copy, bitmatrix, sizeof(int)*k*w*k*w);
i = jerasure_invert_bitmatrix(bitmatrix_copy, inverse, k*w);
jerasure_print_bitmatrix(inverse, k*w, k*w, w);
identity = jerasure_matrix_multiply(inverse, bitmatrix, k*w, k*w, k*w, k*w, 2);
printf("\nInverse times matrix (should be identity):\n");
jerasure_print_bitmatrix(identity, k*w, k*w, w);
}
return 0;
}

217
Examples/jerasure_05.c Executable file
View File

@ -0,0 +1,217 @@
/* Examples/jerasure_05.c
Jerasure - A C/C++ Library for a Variety of Reed-Solomon and RAID-6 Erasure Coding Techniques
Revision 1.2A
May 24, 2011
James S. Plank
Department of Electrical Engineering and Computer Science
University of Tennessee
Knoxville, TN 37996
plank@cs.utk.edu
Copyright (c) 2011, James S. Plank
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
- Neither the name of the University of Tennessee nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
/*
revised by S. Simmerman
2/25/08
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "jerasure.h"
#define talloc(type, num) (type *) malloc(sizeof(type)*(num))
usage(char *s)
{
fprintf(stderr, "usage: jerasure_05 k m w size - Does a simple Reed-Solomon coding example in GF(2^w).\n");
fprintf(stderr, " \n");
fprintf(stderr, " k+m must be <= 2^w. w can be 8, 16 or 32.\n");
fprintf(stderr, " It sets up a Cauchy distribution matrix and encodes\n");
fprintf(stderr, " k devices of size bytes with it. Then it decodes.\n", sizeof(long));
fprintf(stderr, " After that, it decodes device 0 by using jerasure_make_decoding_matrix()\n");
fprintf(stderr, " and jerasure_matrix_dotprod().\n");
fprintf(stderr, " \n");
fprintf(stderr, "This demonstrates: jerasure_matrix_encode()\n");
fprintf(stderr, " jerasure_matrix_decode()\n");
fprintf(stderr, " jerasure_print_matrix()\n");
fprintf(stderr, " jerasure_make_decoding_matrix()\n");
fprintf(stderr, " jerasure_matrix_dotprod()\n");
if (s != NULL) fprintf(stderr, "\n%s\n\n", s);
exit(1);
}
static void print_data_and_coding(int k, int m, int w, int size,
char **data, char **coding)
{
int i, j, x;
int n, sp;
long l;
if(k > m) n = k;
else n = m;
sp = size * 2 + size/(w/8) + 8;
printf("%-*sCoding\n", sp, "Data");
for(i = 0; i < n; i++) {
if(i < k) {
printf("D%-2d:", i);
for(j=0;j< size; j+=(w/8)) {
printf(" ");
for(x=0;x < w/8;x++){
printf("%02x", (unsigned char)data[i][j+x]);
}
}
printf(" ");
}
else printf("%*s", sp, "");
if(i < m) {
printf("C%-2d:", i);
for(j=0;j< size; j+=(w/8)) {
printf(" ");
for(x=0;x < w/8;x++){
printf("%02x", (unsigned char)coding[i][j+x]);
}
}
}
printf("\n");
}
printf("\n");
}
int main(int argc, char **argv)
{
long l;
int k, m, w, size;
int i, j;
int *matrix;
char **data, **coding;
int *erasures, *erased;
int *decoding_matrix, *dm_ids;
if (argc != 5) usage(NULL);
if (sscanf(argv[1], "%d", &k) == 0 || k <= 0) usage("Bad k");
if (sscanf(argv[2], "%d", &m) == 0 || m <= 0) usage("Bad m");
if (sscanf(argv[3], "%d", &w) == 0 || (w != 8 && w != 16 && w != 32))
usage("Bad w");
if (w < 32 && k + m > (1 << w)) usage("k + m must be <= 2 ^ w");
if (sscanf(argv[4], "%d", &size) == 0 || size % sizeof(long) != 0)
usage("size must be multiple of sizeof(long)");
matrix = talloc(int, m*k);
for (i = 0; i < m; i++) {
for (j = 0; j < k; j++) {
matrix[i*k+j] = galois_single_divide(1, i ^ (m + j), w);
}
}
printf("The Coding Matrix (the last m rows of the Distribution Matrix):\n\n");
jerasure_print_matrix(matrix, m, k, w);
printf("\n");
srand48(0);
data = talloc(char *, k);
for (i = 0; i < k; i++) {
data[i] = talloc(char, size);
for(j = 0; j < size; j+=sizeof(long)) {
l = lrand48();
memcpy(data[i] + j, &l, sizeof(long));
}
}
coding = talloc(char *, m);
for (i = 0; i < m; i++) {
coding[i] = talloc(char, size);
}
jerasure_matrix_encode(k, m, w, matrix, data, coding, size);
printf("Encoding Complete:\n\n");
print_data_and_coding(k, m, w, size, data, coding);
erasures = talloc(int, (m+1));
erased = talloc(int, (k+m));
for (i = 0; i < m+k; i++) erased[i] = 0;
l = 0;
for (i = 0; i < m; ) {
erasures[i] = lrand48()%(k+m);
if (erased[erasures[i]] == 0) {
erased[erasures[i]] = 1;
bzero((erasures[i] < k) ? data[erasures[i]] : coding[erasures[i]-k], size);
i++;
}
}
erasures[i] = -1;
printf("Erased %d random devices:\n\n", m);
print_data_and_coding(k, m, w, size, data, coding);
i = jerasure_matrix_decode(k, m, w, matrix, 0, erasures, data, coding, size);
printf("State of the system after decoding:\n\n");
print_data_and_coding(k, m, w, size, data, coding);
decoding_matrix = talloc(int, k*k);
dm_ids = talloc(int, k);
for (i = 0; i < m; i++) erased[i] = 1;
for (; i < k+m; i++) erased[i] = 0;
jerasure_make_decoding_matrix(k, m, w, matrix, erased, decoding_matrix, dm_ids);
printf("Suppose we erase the first %d devices. Here is the decoding matrix:\n\n", m);
jerasure_print_matrix(decoding_matrix, k, k, w);
printf("\n");
printf("And dm_ids:\n\n");
jerasure_print_matrix(dm_ids, 1, k, w);
bzero(data[0], size);
jerasure_matrix_dotprod(k, w, decoding_matrix, dm_ids, 0, data, coding, size);
printf("\nAfter calling jerasure_matrix_dotprod, we calculate the value of device #0 to be:\n\n");
printf("D0 :");
for(i=0;i< size; i+=(w/8)) {
printf(" ");
for(j=0;j < w/8;j++){
printf("%02x", (unsigned char)data[0][i+j]);
}
}
printf("\n\n");
return 0;
}

220
Examples/jerasure_06.c Executable file
View File

@ -0,0 +1,220 @@
/* Examples/jerasure_06.c
Jerasure - A C/C++ Library for a Variety of Reed-Solomon and RAID-6 Erasure Coding Techniques
Revision 1.2A
May 24, 2011
James S. Plank
Department of Electrical Engineering and Computer Science
University of Tennessee
Knoxville, TN 37996
plank@cs.utk.edu
Copyright (c) 2011, James S. Plank
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
- Neither the name of the University of Tennessee nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
/*
revised by S. Simmerman
2/25/08
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "jerasure.h"
#define talloc(type, num) (type *) malloc(sizeof(type)*(num))
usage(char *s)
{
fprintf(stderr, "usage: jerasure_06 k m w packetsize\n");
fprintf(stderr, "Does a simple Cauchy Reed-Solomon coding example in GF(2^w).\n");
fprintf(stderr, " \n");
fprintf(stderr, " k+m must be < 2^w. Packetsize must be a multiple of sizeof(long)\n");
fprintf(stderr, " It sets up a Cauchy distribution matrix and encodes k devices of w*packetsize bytes.\n");
fprintf(stderr, " After that, it decodes device 0 by using jerasure_make_decoding_bitmatrix()\n");
fprintf(stderr, " and jerasure_bitmatrix_dotprod().\n");
fprintf(stderr, " \n");
fprintf(stderr, "This demonstrates: jerasure_bitmatrix_encode()\n");
fprintf(stderr, " jerasure_bitmatrix_decode()\n");
fprintf(stderr, " jerasure_print_bitmatrix()\n");
fprintf(stderr, " jerasure_make_decoding_bitmatrix()\n");
fprintf(stderr, " jerasure_bitmatrix_dotprod()\n");
if (s != NULL) fprintf(stderr, "\n%s\n\n", s);
exit(1);
}
static void print_data_and_coding(int k, int m, int w, int psize,
char **data, char **coding)
{
int i, j, x, n, sp;
long l;
if(k > m) n = k;
else n = m;
sp = psize * 2 + (psize/4) + 12;
printf("%-*sCoding\n", sp, "Data");
for(i = 0; i < n; i++) {
for (j = 0; j < w; j++) {
if(i < k) {
if(j==0) printf("D%-2d p%-2d:", i,j);
else printf(" p%-2d:", j);
for(x = 0; x < psize; x +=4) {
memcpy(&l, data[i]+j*psize+x, sizeof(long));
printf(" %08lx", l);
}
printf(" ");
}
else printf("%*s", sp, "");
if(i < m) {
if(j==0) printf("C%-2d p%-2d:", i,j);
else printf(" p%-2d:", j);
for(x = 0; x < psize; x +=4) {
memcpy(&l, coding[i]+j*psize+x, sizeof(long));
printf(" %08lx", l);
}
}
printf("\n");
}
}
printf("\n");
}
int main(int argc, char **argv)
{
long l;
int k, w, i, j, m, psize, x;
int *matrix, *bitmatrix;
char **data, **coding;
int *erasures, *erased;
int *decoding_matrix, *dm_ids;
if (argc != 5) usage(NULL);
if (sscanf(argv[1], "%d", &k) == 0 || k <= 0) usage("Bad k");
if (sscanf(argv[2], "%d", &m) == 0 || m <= 0) usage("Bad m");
if (sscanf(argv[3], "%d", &w) == 0 || w <= 0 || w > 32) usage("Bad w");
if (w < 30 && (k+m) > (1 << w)) usage("k + m is too big");
if (sscanf(argv[4], "%d", &psize) == 0 || psize <= 0) usage("Bad packetsize");
if(psize%sizeof(long) != 0) usage("Packetsize must be multiple of sizeof(long)");
matrix = talloc(int, m*k);
for (i = 0; i < m; i++) {
for (j = 0; j < k; j++) {
matrix[i*k+j] = galois_single_divide(1, i ^ (m + j), w);
}
}
bitmatrix = jerasure_matrix_to_bitmatrix(k, m, w, matrix);
printf("Last (m * w) rows of the Binary Distribution Matrix:\n\n");
jerasure_print_bitmatrix(bitmatrix, w*m, w*k, w);
printf("\n");
srand48(0);
data = talloc(char *, k);
for (i = 0; i < k; i++) {
data[i] = talloc(char, psize*w);
for (j = 0; j < w; j++) {
for(x = 0; x < psize; x += 4) {
l = lrand48();
memcpy(data[i]+j*psize+x, &l, sizeof(long));
}
}
}
coding = talloc(char *, m);
for (i = 0; i < m; i++) {
coding[i] = talloc(char, psize*w);
}
jerasure_bitmatrix_encode(k, m, w, bitmatrix, data, coding, w*psize, psize);
printf("Encoding Complete:\n\n");
print_data_and_coding(k, m, w, psize, data, coding);
erasures = talloc(int, (m+1));
erased = talloc(int, (k+m));
for (i = 0; i < m+k; i++) erased[i] = 0;
for (i = 0; i < m; ) {
erasures[i] = lrand48()%(k+m);
if (erased[erasures[i]] == 0) {
erased[erasures[i]] = 1;
bzero((erasures[i] < k) ? data[erasures[i]] : coding[erasures[i]-k], psize*w);
i++;
}
}
erasures[i] = -1;
printf("Erased %d random devices:\n\n", m);
print_data_and_coding(k, m, w, psize, data, coding);
i = jerasure_bitmatrix_decode(k, m, w, bitmatrix, 0, erasures, data, coding,
w*psize, psize);
printf("State of the system after decoding:\n\n");
print_data_and_coding(k, m, w, psize, data, coding);
decoding_matrix = talloc(int, k*k*w*w);
dm_ids = talloc(int, k);
for (i = 0; i < m; i++) erased[i] = 1;
for (; i < k+m; i++) erased[i] = 0;
jerasure_make_decoding_bitmatrix(k, m, w, bitmatrix, erased, decoding_matrix, dm_ids);
printf("Suppose we erase the first %d devices. Here is the decoding matrix:\n\n", m);
jerasure_print_bitmatrix(decoding_matrix, k*w, k*w, w);
printf("\n");
printf("And dm_ids:\n\n");
jerasure_print_matrix(dm_ids, 1, k, w);
//memcpy(&l, data[0], sizeof(long));
//printf("\nThe value of device #%d, word 0 is: %lx\n", 0, l);
bzero(data[0], w*psize);
jerasure_bitmatrix_dotprod(k, w, decoding_matrix, dm_ids, 0, data, coding, w*psize, psize);
printf("\nAfter calling jerasure_matrix_dotprod, we calculate the value of device #0, packet 0 to be:\n");
printf("\nD0 p0 :");
for(i = 0; i < psize; i +=sizeof(long)) {
memcpy(&l, data[0]+i, sizeof(long));
printf(" %08lx", l);
}
printf("\n\n");
//memcpy(&l, data[0], sizeof(long));
return 0;
}

206
Examples/jerasure_07.c Executable file
View File

@ -0,0 +1,206 @@
/* Examples/jerasure_07.c
Jerasure - A C/C++ Library for a Variety of Reed-Solomon and RAID-6 Erasure Coding Techniques
Revision 1.2A
May 24, 2011
James S. Plank
Department of Electrical Engineering and Computer Science
University of Tennessee
Knoxville, TN 37996
plank@cs.utk.edu
Copyright (c) 2011, James S. Plank
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
- Neither the name of the University of Tennessee nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
/*
revised by S. Simmerman
2/25/08
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "jerasure.h"
#define talloc(type, num) (type *) malloc(sizeof(type)*(num))
usage(char *s)
{
fprintf(stderr, "usage: jerasure_07 k m w - Scheduled Cauchy Reed-Solomon coding example in GF(2^w).\n");
fprintf(stderr, " \n");
fprintf(stderr, " k+m must be <= 2^w. It sets up a Cauchy distribution matrix and encodes\n");
fprintf(stderr, " k sets of w*%d bytes. It uses bit-matrix scheduling, both smart and dumb.\n", sizeof(long));
fprintf(stderr, " It decodes using bit-matrix scheduling, then shows an example of\n");
fprintf(stderr, " using jerasure_do_scheduled_operations().\n");
fprintf(stderr, " \n");
fprintf(stderr, "This demonstrates: jerasure_dumb_bitmatrix_to_schedule()\n");
fprintf(stderr, " jerasure_smart_bitmatrix_to_schedule()\n");
fprintf(stderr, " jerasure_schedule_encode()\n");
fprintf(stderr, " jerasure_schedule_decode_lazy()\n");
fprintf(stderr, " jerasure_do_scheduled_operations()\n");
fprintf(stderr, " jerasure_get_stats()\n");
if (s != NULL) fprintf(stderr, "%s\n", s);
exit(1);
}
static void print_data_and_coding(int k, int m, int w, int psize,
char **data, char **coding)
{
int i, j, x, n, sp;
long l;
if(k > m) n = k;
else n = m;
sp = psize * 2 + (psize/4) + 12;
printf("%-*sCoding\n", sp, "Data");
for(i = 0; i < n; i++) {
for (j = 0; j < w; j++) {
if(i < k) {
if(j==0) printf("D%-2d p%-2d:", i,j);
else printf(" p%-2d:", j);
for(x = 0; x < psize; x +=4) {
memcpy(&l, data[i]+j*psize+x, sizeof(long));
printf(" %08lx", l);
}
printf(" ");
}
else printf("%*s", sp, "");
if(i < m) {
if(j==0) printf("C%-2d p%-2d:", i,j);
else printf(" p%-2d:", j);
for(x = 0; x < psize; x +=4) {
memcpy(&l, coding[i]+j*psize+x, sizeof(long));
printf(" %08lx", l);
}
}
printf("\n");
}
}
printf("\n");
}
int main(int argc, char **argv)
{
long l;
int k, w, i, j, m;
int *matrix, *bitmatrix;
char **data, **coding, **ptrs;
int **smart, **dumb;
int *erasures, *erased;
double stats[3];
if (argc != 4) usage(NULL);
if (sscanf(argv[1], "%d", &k) == 0 || k <= 0) usage("Bad k");
if (sscanf(argv[2], "%d", &m) == 0 || m <= 0) usage("Bad m");
if (sscanf(argv[3], "%d", &w) == 0 || w <= 0 || w > 32) usage("Bad m");
if (w < 30 && (k+m) > (1 << w)) usage("k + m is too big");
matrix = talloc(int, m*k);
for (i = 0; i < m; i++) {
for (j = 0; j < k; j++) {
matrix[i*k+j] = galois_single_divide(1, i ^ (m + j), w);
}
}
bitmatrix = jerasure_matrix_to_bitmatrix(k, m, w, matrix);
printf("Last m rows of the Binary Distribution Matrix:\n\n");
jerasure_print_bitmatrix(bitmatrix, w*m, w*k, w);
printf("\n");
dumb = jerasure_dumb_bitmatrix_to_schedule(k, m, w, bitmatrix);
smart = jerasure_smart_bitmatrix_to_schedule(k, m, w, bitmatrix);
srand48(0);
data = talloc(char *, k);
for (i = 0; i < k; i++) {
data[i] = talloc(char, sizeof(long)*w);
for (j = 0; j < w; j++) {
l = lrand48();
memcpy(data[i]+j*sizeof(long), &l, sizeof(long));
}
}
coding = talloc(char *, m);
for (i = 0; i < m; i++) {
coding[i] = talloc(char, sizeof(long)*w);
}
jerasure_schedule_encode(k, m, w, dumb, data, coding, w*sizeof(long), sizeof(long));
jerasure_get_stats(stats);
printf("Dumb Encoding Complete: - %.0lf XOR'd bytes\n\n", stats[0]);
print_data_and_coding(k, m, w, sizeof(long), data, coding);
jerasure_schedule_encode(k, m, w, smart, data, coding, w*sizeof(long), sizeof(long));
jerasure_get_stats(stats);
printf("Smart Encoding Complete: - %.0lf XOR'd bytes\n\n", stats[0]);
print_data_and_coding(k, m, w, sizeof(long), data, coding);
erasures = talloc(int, (m+1));
erased = talloc(int, (k+m));
for (i = 0; i < m+k; i++) erased[i] = 0;
for (i = 0; i < m; ) {
erasures[i] = lrand48()%(k+m);
if (erased[erasures[i]] == 0) {
erased[erasures[i]] = 1;
bzero((erasures[i] < k) ? data[erasures[i]] : coding[erasures[i]-k], sizeof(long)*w);
i++;
}
}
erasures[i] = -1;
printf("Erased %d random devices:\n\n", m);
print_data_and_coding(k, m, w, sizeof(long), data, coding);
jerasure_schedule_decode_lazy(k, m, w, bitmatrix, erasures, data, coding, w*sizeof(long), sizeof(long), 1);
jerasure_get_stats(stats);
printf("State of the system after decoding: %.0lf XOR'd bytes\n\n", stats[0]);
print_data_and_coding(k, m, w, sizeof(long), data, coding);
ptrs = talloc(char *, (k+m));
for (i = 0; i < k; i++) ptrs[i] = data[i];
for (i = 0; i < m; i++) ptrs[k+i] = coding[i];
for (j = 0; j < m; j++) bzero(coding[j], sizeof(long)*w);
jerasure_do_scheduled_operations(ptrs, smart, sizeof(long));
printf("State of the system after deleting the coding devices and\n");
printf("using jerasure_do_scheduled_operations(): %.0lf XOR'd bytes\n\n", stats[0]);
print_data_and_coding(k, m, w, sizeof(long), data, coding);
return 0;
}

214
Examples/jerasure_08.c Executable file
View File

@ -0,0 +1,214 @@
/* Examples/jerasure_08.c
Jerasure - A C/C++ Library for a Variety of Reed-Solomon and RAID-6 Erasure Coding Techniques
Revision 1.2A
May 24, 2011
James S. Plank
Department of Electrical Engineering and Computer Science
University of Tennessee
Knoxville, TN 37996
plank@cs.utk.edu
Copyright (c) 2011, James S. Plank
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
- Neither the name of the University of Tennessee nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
/*
revised by S. Simmerman
2/25/08
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "jerasure.h"
#define talloc(type, num) (type *) malloc(sizeof(type)*(num))
usage(char *s)
{
fprintf(stderr, "usage: jerasure_08 k w - Example schedule cache usage with RAID-6\n");
fprintf(stderr, " \n");
fprintf(stderr, " m=2. k+m must be <= 2^w. It sets up a RAID-6 distribution matrix and encodes\n");
fprintf(stderr, " k sets of w*%d bytes. It creates a schedule cache for decoding.\n", sizeof(long));
fprintf(stderr, " It demonstrates using the schedule cache for both encoding and decoding.\n");
fprintf(stderr, " Then it demonstrates using jerasure_do_parity() to re-encode the first.\n");
fprintf(stderr, " coding device\n");
fprintf(stderr, " \n");
fprintf(stderr, "This demonstrates: jerasure_generate_schedule_cache()\n");
fprintf(stderr, " jerasure_smart_bitmatrix_to_schedule()\n");
fprintf(stderr, " jerasure_schedule_encode()\n");
fprintf(stderr, " jerasure_schedule_decode_cache()\n");
fprintf(stderr, " jerasure_free_schedule()\n");
fprintf(stderr, " jerasure_free_schedule_cache()\n");
fprintf(stderr, " jerasure_get_stats()\n");
fprintf(stderr, " jerasure_do_parity()\n");
if (s != NULL) fprintf(stderr, "%s\n", s);
exit(1);
}
static void print_data_and_coding(int k, int m, int w, int psize,
char **data, char **coding)
{
int i, j, x, n, sp;
long l;
if(k > m) n = k;
else n = m;
sp = psize * 2 + (psize/4) + 12;
printf("%-*sCoding\n", sp, "Data");
for(i = 0; i < n; i++) {
for (j = 0; j < w; j++) {
if(i < k) {
if(j==0) printf("D%-2d p%-2d:", i,j);
else printf(" p%-2d:", j);
for(x = 0; x < psize; x +=4) {
memcpy(&l, data[i]+j*psize+x, sizeof(long));
printf(" %08lx", l);
}
printf(" ");
}
else printf("%*s", sp, "");
if(i < m) {
if(j==0) printf("C%-2d p%-2d:", i,j);
else printf(" p%-2d:", j);
for(x = 0; x < psize; x +=4) {
memcpy(&l, coding[i]+j*psize+x, sizeof(long));
printf(" %08lx", l);
}
}
printf("\n");
}
}
printf("\n");
}
int main(int argc, char **argv)
{
long l;
int k, w, i, j, m;
int *matrix, *bitmatrix;
char **data, **coding, **ptrs;
int **smart, ***cache;
int *erasures, *erased;
double stats[3];
if (argc != 3) usage(NULL);
if (sscanf(argv[1], "%d", &k) == 0 || k <= 0) usage("Bad k");
if (sscanf(argv[2], "%d", &w) == 0 || w <= 0 || w > 32) usage("Bad m");
m = 2;
if (w < 30 && (k+m) > (1 << w)) usage("k + m is too big");
matrix = talloc(int, m*k);
for (j = 0; j < k; j++) matrix[j] = 1;
i = 1;
for (j = 0; j < k; j++) {
matrix[k+j] = i;
i = galois_single_multiply(i, 2, w);
}
bitmatrix = jerasure_matrix_to_bitmatrix(k, m, w, matrix);
smart = jerasure_smart_bitmatrix_to_schedule(k, m, w, bitmatrix);
cache = jerasure_generate_schedule_cache(k, m, w, bitmatrix, 1);
srand48(0);
data = talloc(char *, k);
for (i = 0; i < k; i++) {
data[i] = talloc(char, sizeof(long)*w);
for (j = 0; j < w; j++) {
l = lrand48();
memcpy(data[i]+j*sizeof(long), &l, sizeof(long));
}
}
coding = talloc(char *, m);
for (i = 0; i < m; i++) {
coding[i] = talloc(char, sizeof(long)*w);
}
jerasure_schedule_encode(k, m, w, smart, data, coding, w*sizeof(long), sizeof(long));
jerasure_get_stats(stats);
printf("Encoding Complete: - %.0lf XOR'd bytes\n\n", stats[0]);
print_data_and_coding(k, m, w, sizeof(long), data, coding);
erasures = talloc(int, (m+1));
erasures[0] = k;
erasures[1] = k+1;
erasures[2] = -1;
for (j = 0; j < m; j++) bzero(coding[j], sizeof(long)*w);
jerasure_schedule_decode_cache(k, m, w, cache, erasures, data, coding, w*sizeof(long), sizeof(long));
jerasure_get_stats(stats);
printf("Encoding Using the Schedule Cache: - %.0lf XOR'd bytes\n\n", stats[0]);
print_data_and_coding(k, m, w, sizeof(long), data, coding);
erased = talloc(int, (k+m));
for (i = 0; i < m+k; i++) erased[i] = 0;
for (i = 0; i < m; ) {
erasures[i] = lrand48()%(k+m);
if (erased[erasures[i]] == 0) {
erased[erasures[i]] = 1;
bzero((erasures[i] < k) ? data[erasures[i]] : coding[erasures[i]-k], sizeof(long)*w);
i++;
}
}
erasures[i] = -1;
printf("Erased %d random devices:\n\n", m);
print_data_and_coding(k, m, w, sizeof(long), data, coding);
jerasure_schedule_decode_cache(k, m, w, cache, erasures, data, coding, w*sizeof(long), sizeof(long));
jerasure_get_stats(stats);
printf("State of the system after decoding: %.0lf XOR'd bytes\n\n", stats[0]);
print_data_and_coding(k, m, w, sizeof(long), data, coding);
bzero(coding[0], sizeof(long)*w);
jerasure_do_parity(k, data, coding[0], sizeof(long)*w);
printf("State of the system after deleting coding device 0 and using\n");
printf("jerasure_do_parity to re-encode it:\n\n");
print_data_and_coding(k, m, w, sizeof(long), data, coding);
jerasure_free_schedule(smart);
jerasure_free_schedule_cache(k, m, cache);
printf("Smart schedule and cache freed\n\n");
return 0;
}

190
Examples/liberation_01.c Executable file
View File

@ -0,0 +1,190 @@
/* Examples/liberation_01.c
Jerasure - A C/C++ Library for a Variety of Reed-Solomon and RAID-6 Erasure Coding Techniques
Revision 1.2A
May 24, 2011
James S. Plank
Department of Electrical Engineering and Computer Science
University of Tennessee
Knoxville, TN 37996
plank@cs.utk.edu
Copyright (c) 2011, James S. Plank
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
- Neither the name of the University of Tennessee nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
/*
revised by S. Simmerman
2/25/08
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "jerasure.h"
#include "liberation.h"
#define talloc(type, num) (type *) malloc(sizeof(type)*(num))
usage(char *s)
{
fprintf(stderr, "usage: liberation_01 k w - Liberation RAID-6 coding/decoding example in GF(2^w).\n");
fprintf(stderr, " \n");
fprintf(stderr, " w must be prime and k <= w. It sets up a Liberation bit-matrix\n");
fprintf(stderr, " then it encodes k devices of w*%d bytes using dumb bit-matrix scheduling.\n", sizeof(long));
fprintf(stderr, " It decodes using smart bit-matrix scheduling.\n");
fprintf(stderr, " \n");
fprintf(stderr, "This demonstrates: liberation_coding_bitmatrix()\n");
fprintf(stderr, " jerasure_smart_bitmatrix_to_schedule()\n");
fprintf(stderr, " jerasure_dumb_bitmatrix_to_schedule()\n");
fprintf(stderr, " jerasure_schedule_encode()\n");
fprintf(stderr, " jerasure_schedule_decode_lazy()\n");
fprintf(stderr, " jerasure_print_bitmatrix()\n");
fprintf(stderr, " jerasure_get_stats()\n");
if (s != NULL) fprintf(stderr, "%s\n", s);
exit(1);
}
static void print_data_and_coding(int k, int m, int w, int psize,
char **data, char **coding)
{
int i, j, x, n, sp;
long l;
if(k > m) n = k;
else n = m;
sp = psize * 2 + (psize/4) + 12;
printf("%-*sCoding\n", sp, "Data");
for(i = 0; i < n; i++) {
for (j = 0; j < w; j++) {
if(i < k) {
if(j==0) printf("D%-2d p%-2d:", i,j);
else printf(" p%-2d:", j);
for(x = 0; x < psize; x +=4) {
memcpy(&l, data[i]+j*psize+x, sizeof(long));
printf(" %08lx", l);
}
printf(" ");
}
else printf("%*s", sp, "");
if(i < m) {
if(j==0) printf("C%-2d p%-2d:", i,j);
else printf(" p%-2d:", j);
for(x = 0; x < psize; x +=4) {
memcpy(&l, coding[i]+j*psize+x, sizeof(long));
printf(" %08lx", l);
}
}
printf("\n");
}
}
printf("\n");
}
int main(int argc, char **argv)
{
long l;
int k, w, i, j, m;
int *bitmatrix;
char **data, **coding, **ptrs;
int **dumb;
int *erasures, *erased;
double stats[3];
if (argc != 3) usage(NULL);
if (sscanf(argv[1], "%d", &k) == 0 || k <= 0) usage("Bad k");
if (sscanf(argv[2], "%d", &w) == 0 || w <= 0 || w > 32) usage("Bad w");
m = 2;
if (w < k) usage("k is too big");
bitmatrix = liberation_coding_bitmatrix(k, w);
if (bitmatrix == NULL) {
usage("couldn't make coding matrix");
}
printf("Coding Bit-Matrix:\n\n");
jerasure_print_bitmatrix(bitmatrix, w*m, w*k, w);
printf("\n");
dumb = jerasure_dumb_bitmatrix_to_schedule(k, m, w, bitmatrix);
srand48(0);
data = talloc(char *, k);
for (i = 0; i < k; i++) {
data[i] = talloc(char, sizeof(long)*w);
for (j = 0; j < w; j++) {
l = lrand48();
memcpy(data[i]+j*sizeof(long), &l, sizeof(long));
}
}
coding = talloc(char *, m);
for (i = 0; i < m; i++) {
coding[i] = talloc(char, sizeof(long)*w);
}
jerasure_schedule_encode(k, m, w, dumb, data, coding, w*sizeof(long), sizeof(long));
jerasure_get_stats(stats);
printf("Smart Encoding Complete: - %.0lf XOR'd bytes\n\n", stats[0]);
print_data_and_coding(k, m, w, sizeof(long), data, coding);
erasures = talloc(int, (m+1));
erased = talloc(int, (k+m));
for (i = 0; i < m+k; i++) erased[i] = 0;
for (i = 0; i < m; ) {
erasures[i] = lrand48()%(k+m);
if (erased[erasures[i]] == 0) {
erased[erasures[i]] = 1;
bzero((erasures[i] < k) ? data[erasures[i]] : coding[erasures[i]-k], sizeof(long)*w);
i++;
}
}
erasures[i] = -1;
printf("Erased %d random devices:\n\n", m);
print_data_and_coding(k, m, w, sizeof(long), data, coding);
jerasure_schedule_decode_lazy(k, m, w, bitmatrix, erasures, data, coding, w*sizeof(long), sizeof(long), 1);
jerasure_get_stats(stats);
printf("State of the system after decoding: %.0lf XOR'd bytes\n\n", stats[0]);
print_data_and_coding(k, m, w, sizeof(long), data, coding);
return 0;
}

186
Examples/makefile Executable file
View File

@ -0,0 +1,186 @@
# Examples/makefile
# Jerasure - A C/C++ Library for a Variety of Reed-Solomon and RAID-6 Erasure Coding Techniques
#
# Revision 1.2A
# May 24, 2011
#
# James S. Plank
# Department of Electrical Engineering and Computer Science
# University of Tennessee
# Knoxville, TN 37996
# plank@cs.utk.edu
#
# Copyright (c) 2011, James S. Plank
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# - Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# - Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# - Neither the name of the University of Tennessee nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
# WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
CC = gcc
CFLAGS = -O2 -I$(HOME)/include
ALL = jerasure_01 \
jerasure_02 \
jerasure_03 \
jerasure_04 \
jerasure_05 \
jerasure_06 \
jerasure_07 \
jerasure_08 \
reed_sol_01 \
reed_sol_02 \
reed_sol_03 \
reed_sol_04 \
cauchy_01 \
cauchy_02 \
cauchy_03 \
cauchy_04 \
liberation_01 \
encoder \
decoder \
all: $(ALL)
clean:
rm -f core *.o $(ALL) a.out cauchy.h cauchy.c liberation.h liberation.c reed_sol.c reed_sol.h\
jerasure.c jerasure.h galois.c galois.h
.SUFFIXES: .c .o
.c.o:
$(CC) $(CFLAGS) -c $*.c
liberation.h: ../liberation.h
rm -f liberation.h ; cp ../liberation.h . ; chmod 0444 liberation.h
liberation.c: ../liberation.c
rm -f liberation.c ; cp ../liberation.c . ; chmod 0444 liberation.c
cauchy.h: ../cauchy.h
rm -f cauchy.h ; cp ../cauchy.h . ; chmod 0444 cauchy.h
cauchy.c: ../cauchy.c
rm -f cauchy.c ; cp ../cauchy.c . ; chmod 0444 cauchy.c
reed_sol.h: ../reed_sol.h
rm -f reed_sol.h ; cp ../reed_sol.h . ; chmod 0444 reed_sol.h
reed_sol.c: ../reed_sol.c
rm -f reed_sol.c ; cp ../reed_sol.c . ; chmod 0444 reed_sol.c
jerasure.h: ../jerasure.h
rm -f jerasure.h ; cp ../jerasure.h . ; chmod 0444 jerasure.h
jerasure.c: ../jerasure.c
rm -f jerasure.c ; cp ../jerasure.c . ; chmod 0444 jerasure.c
galois.h: ../galois.h
rm -f galois.h ; cp ../galois.h . ; chmod 0444 galois.h
galois.c: ../galois.c
rm -f galois.c ; cp ../galois.c . ; chmod 0444 galois.c
galois.o: galois.h
jerasure.o: jerasure.h galois.h
jerasure_01.o: galois.h jerasure.h
jerasure_01: jerasure_01.o galois.o jerasure.o
$(CC) $(CFLAGS) -o jerasure_01 jerasure_01.o jerasure.o galois.o
jerasure_02.o: galois.h jerasure.h
jerasure_02: jerasure_02.o galois.o jerasure.o
$(CC) $(CFLAGS) -o jerasure_02 jerasure_02.o jerasure.o galois.o
jerasure_03.o: galois.h jerasure.h
jerasure_03: jerasure_03.o galois.o jerasure.o
$(CC) $(CFLAGS) -o jerasure_03 jerasure_03.o jerasure.o galois.o
jerasure_04.o: galois.h jerasure.h
jerasure_04: jerasure_04.o galois.o jerasure.o
$(CC) $(CFLAGS) -o jerasure_04 jerasure_04.o jerasure.o galois.o
jerasure_05.o: galois.h jerasure.h
jerasure_05: jerasure_05.o galois.o jerasure.o
$(CC) $(CFLAGS) -o jerasure_05 jerasure_05.o jerasure.o galois.o
jerasure_06.o: galois.h jerasure.h
jerasure_06: jerasure_06.o galois.o jerasure.o
$(CC) $(CFLAGS) -o jerasure_06 jerasure_06.o jerasure.o galois.o
jerasure_07.o: galois.h jerasure.h
jerasure_07: jerasure_07.o galois.o jerasure.o
$(CC) $(CFLAGS) -o jerasure_07 jerasure_07.o jerasure.o galois.o
jerasure_08.o: galois.h jerasure.h
jerasure_08: jerasure_08.o galois.o jerasure.o
$(CC) $(CFLAGS) -o jerasure_08 jerasure_08.o jerasure.o galois.o
reed_sol_01.o: galois.h reed_sol.h jerasure.h
reed_sol_01: reed_sol_01.o galois.o jerasure.o reed_sol.o
$(CC) $(CFLAGS) -o reed_sol_01 reed_sol_01.o reed_sol.o jerasure.o galois.o
reed_sol_02.o: galois.h reed_sol.h jerasure.h
reed_sol_02: reed_sol_02.o galois.o jerasure.o reed_sol.o
$(CC) $(CFLAGS) -o reed_sol_02 reed_sol_02.o reed_sol.o jerasure.o galois.o
reed_sol_03.o: galois.h reed_sol.h jerasure.h
reed_sol_03: reed_sol_03.o galois.o jerasure.o reed_sol.o
$(CC) $(CFLAGS) -o reed_sol_03 reed_sol_03.o reed_sol.o jerasure.o galois.o
reed_sol_04.o: galois.h reed_sol.h jerasure.h
reed_sol_04: reed_sol_04.o galois.o jerasure.o reed_sol.o
$(CC) $(CFLAGS) -o reed_sol_04 reed_sol_04.o reed_sol.o jerasure.o galois.o
cauchy_01.o: galois.h cauchy.h jerasure.h
cauchy_01: cauchy_01.o galois.o jerasure.o cauchy.o
$(CC) $(CFLAGS) -o cauchy_01 cauchy_01.o cauchy.o jerasure.o galois.o
cauchy_02.o: galois.h cauchy.h jerasure.h
cauchy_02: cauchy_02.o galois.o jerasure.o cauchy.o
$(CC) $(CFLAGS) -o cauchy_02 cauchy_02.o cauchy.o jerasure.o galois.o
cauchy_03.o: galois.h cauchy.h jerasure.h
cauchy_03: cauchy_03.o galois.o jerasure.o cauchy.o
$(CC) $(CFLAGS) -o cauchy_03 cauchy_03.o cauchy.o jerasure.o galois.o
cauchy_04.o: galois.h cauchy.h jerasure.h
cauchy_04: cauchy_04.o galois.o jerasure.o cauchy.o
$(CC) $(CFLAGS) -o cauchy_04 cauchy_04.o cauchy.o jerasure.o galois.o
liberation_01.o: galois.h liberation.h jerasure.h
liberation_01: liberation_01.o galois.o jerasure.o liberation.o
$(CC) $(CFLAGS) -o liberation_01 liberation_01.o liberation.o jerasure.o galois.o
encoder.o: galois.h liberation.h jerasure.h reed_sol.h cauchy.h
encoder: encoder.o galois.o jerasure.o liberation.o reed_sol.o cauchy.o
$(CC) $(CFLAGS) -o encoder encoder.o liberation.o jerasure.o galois.o reed_sol.o cauchy.o
decoder.o: galois.h liberation.h jerasure.h reed_sol.h cauchy.h
decoder: decoder.o galois.o jerasure.o liberation.o reed_sol.o cauchy.o
$(CC) $(CFLAGS) -o decoder decoder.o liberation.o jerasure.o galois.o reed_sol.o cauchy.o

177
Examples/reed_sol_01.c Executable file
View File

@ -0,0 +1,177 @@
/* Examples/reed_sol_01.c
Jerasure - A C/C++ Library for a Variety of Reed-Solomon and RAID-6 Erasure Coding Techniques
Revision 1.2A
May 24, 2011
James S. Plank
Department of Electrical Engineering and Computer Science
University of Tennessee
Knoxville, TN 37996
plank@cs.utk.edu
Copyright (c) 2011, James S. Plank
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
- Neither the name of the University of Tennessee nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
/*
revised by S. Simmerman
2/25/08
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "jerasure.h"
#include "reed_sol.h"
#define talloc(type, num) (type *) malloc(sizeof(type)*(num))
usage(char *s)
{
fprintf(stderr, "usage: reed_sol_01 k m w - Does a simple Reed-Solomon coding example in GF(2^w).\n");
fprintf(stderr, " \n");
fprintf(stderr, " w must be 8, 16 or 32. k+m must be <= 2^w. It sets up a classic\n");
fprintf(stderr, " Vandermonde-based distribution matrix and encodes k devices of\n");
fprintf(stderr, " %d bytes each with it. Then it decodes.\n", sizeof(long));
fprintf(stderr, " \n");
fprintf(stderr, "This demonstrates: jerasure_matrix_encode()\n");
fprintf(stderr, " jerasure_matrix_decode()\n");
fprintf(stderr, " jerasure_print_matrix()\n");
fprintf(stderr, " reed_sol_vandermonde_coding_matrix()\n");
if (s != NULL) fprintf(stderr, "%s\n", s);
exit(1);
}
static void print_data_and_coding(int k, int m, int w, int size,
char **data, char **coding)
{
int i, j, x;
int n, sp;
long l;
if(k > m) n = k;
else n = m;
sp = size * 2 + size/(w/8) + 8;
printf("%-*sCoding\n", sp, "Data");
for(i = 0; i < n; i++) {
if(i < k) {
printf("D%-2d:", i);
for(j=0;j< size; j+=(w/8)) {
printf(" ");
for(x=0;x < w/8;x++){
printf("%02x", (unsigned char)data[i][j+x]);
}
}
printf(" ");
}
else printf("%*s", sp, "");
if(i < m) {
printf("C%-2d:", i);
for(j=0;j< size; j+=(w/8)) {
printf(" ");
for(x=0;x < w/8;x++){
printf("%02x", (unsigned char)coding[i][j+x]);
}
}
}
printf("\n");
}
printf("\n");
}
int main(int argc, char **argv)
{
long l;
int k, w, i, j, m;
int *matrix;
char **data, **coding;
int *erasures, *erased;
int *decoding_matrix, *dm_ids;
if (argc != 4) usage(NULL);
if (sscanf(argv[1], "%d", &k) == 0 || k <= 0) usage("Bad k");
if (sscanf(argv[2], "%d", &m) == 0 || m <= 0) usage("Bad m");
if (sscanf(argv[3], "%d", &w) == 0 || (w != 8 && w != 16 && w != 32)) usage("Bad w");
if (w <= 16 && k + m > (1 << w)) usage("k + m is too big");
matrix = reed_sol_vandermonde_coding_matrix(k, m, w);
printf("Last m rows of the Distribution Matrix:\n\n");
jerasure_print_matrix(matrix, m, k, w);
printf("\n");
srand48(0);
data = talloc(char *, k);
for (i = 0; i < k; i++) {
data[i] = talloc(char, sizeof(long));
l = lrand48();
memcpy(data[i], &l, sizeof(long));
}
coding = talloc(char *, m);
for (i = 0; i < m; i++) {
coding[i] = talloc(char, sizeof(long));
}
jerasure_matrix_encode(k, m, w, matrix, data, coding, sizeof(long));
printf("Encoding Complete:\n\n");
print_data_and_coding(k, m, w, sizeof(long), data, coding);
erasures = talloc(int, (m+1));
erased = talloc(int, (k+m));
for (i = 0; i < m+k; i++) erased[i] = 0;
l = 0;
for (i = 0; i < m; ) {
erasures[i] = lrand48()%(k+m);
if (erased[erasures[i]] == 0) {
erased[erasures[i]] = 1;
memcpy((erasures[i] < k) ? data[erasures[i]] : coding[erasures[i]-k], &l, sizeof(long));
i++;
}
}
erasures[i] = -1;
printf("Erased %d random devices:\n\n", m);
print_data_and_coding(k, m, w, sizeof(long), data, coding);
i = jerasure_matrix_decode(k, m, w, matrix, 1, erasures, data, coding, sizeof(long));
printf("State of the system after decoding:\n\n");
print_data_and_coding(k, m, w, sizeof(long), data, coding);
return 0;
}

101
Examples/reed_sol_02.c Executable file
View File

@ -0,0 +1,101 @@
/* Examples/reed_sol_02.c
Jerasure - A C/C++ Library for a Variety of Reed-Solomon and RAID-6 Erasure Coding Techniques
Revision 1.2A
May 24, 2011
James S. Plank
Department of Electrical Engineering and Computer Science
University of Tennessee
Knoxville, TN 37996
plank@cs.utk.edu
Copyright (c) 2011, James S. Plank
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
- Neither the name of the University of Tennessee nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "jerasure.h"
#include "reed_sol.h"
#define talloc(type, num) (type *) malloc(sizeof(type)*(num))
usage(char *s)
{
fprintf(stderr, "usage: reed_sol_02 k m w - Vandermonde matrices in GF(2^w).\n");
fprintf(stderr, " \n");
fprintf(stderr, " k+m must be <= 2^w. This simply prints out the \n");
fprintf(stderr, " Vandermonde matrix in GF(2^w), and then the distribution\n");
fprintf(stderr, " matrix that is constructed from it. See [Plank-Ding-05] for\n");
fprintf(stderr, " information on how this construction proceeds\n");
fprintf(stderr, " \n");
fprintf(stderr, "This demonstrates: reed_sol_extended_vandermonde_matrix()\n");
fprintf(stderr, " reed_sol_big_vandermonde_coding_matrix()\n");
fprintf(stderr, " reed_sol_vandermonde_coding_matrix()\n");
fprintf(stderr, " jerasure_print_matrix()\n");
if (s != NULL) fprintf(stderr, "%s\n", s);
exit(1);
}
int main(int argc, char **argv)
{
long l;
int k, w, i, j, m;
int *matrix;
if (argc != 4) usage(NULL);
if (sscanf(argv[1], "%d", &k) == 0 || k <= 0) usage("Bad k");
if (sscanf(argv[2], "%d", &m) == 0 || m <= 0) usage("Bad m");
if (sscanf(argv[3], "%d", &w) == 0 || w <= 0 || w > 32) usage("Bad w");
if (w <= 30 && k + m > (1 << w)) usage("k + m is too big");
matrix = reed_sol_extended_vandermonde_matrix(k+m, k, w);
printf("Extended Vandermonde Matrix:\n\n");
jerasure_print_matrix(matrix, k+m, k, w);
printf("\n");
matrix = reed_sol_big_vandermonde_distribution_matrix(k+m, k, w);
printf("Vandermonde Distribution Matrix:\n\n");
jerasure_print_matrix(matrix, k+m, k, w);
printf("\n");
matrix = reed_sol_vandermonde_coding_matrix(k, m, w);
printf("Vandermonde Coding Matrix:\n\n");
jerasure_print_matrix(matrix, m, k, w);
printf("\n");
return 0;
}

178
Examples/reed_sol_03.c Executable file
View File

@ -0,0 +1,178 @@
/* Examples/reed_sol_03.c
Jerasure - A C/C++ Library for a Variety of Reed-Solomon and RAID-6 Erasure Coding Techniques
Revision 1.2A
May 24, 2011
James S. Plank
Department of Electrical Engineering and Computer Science
University of Tennessee
Knoxville, TN 37996
plank@cs.utk.edu
Copyright (c) 2011, James S. Plank
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
- Neither the name of the University of Tennessee nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
/*
revised by S. Simmerman
2/25/08
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "jerasure.h"
#include "reed_sol.h"
#define talloc(type, num) (type *) malloc(sizeof(type)*(num))
usage(char *s)
{
fprintf(stderr, "usage: reed_sol_03 k w - Does a simple RAID-6 coding example in GF(2^w).\n");
fprintf(stderr, " \n");
fprintf(stderr, " w must be 8, 16 or 32. k+2 must be <= 2^w. It sets up a classic\n");
fprintf(stderr, " RAID-6 coding matrix based on Anvin's optimization and encodes\n");
fprintf(stderr, " %d-byte devices with it. Then it decodes.\n", sizeof(long));
fprintf(stderr, " \n");
fprintf(stderr, "This demonstrates: reed_sol_r6_encode()\n");
fprintf(stderr, " reed_sol_r6_coding_matrix()\n");
fprintf(stderr, " jerasure_matrix_decode()\n");
fprintf(stderr, " jerasure_print_matrix()\n");
if (s != NULL) fprintf(stderr, "%s\n", s);
exit(1);
}
static void print_data_and_coding(int k, int m, int w, int size,
char **data, char **coding)
{
int i, j, x;
int n, sp;
long l;
if(k > m) n = k;
else n = m;
sp = size * 2 + size/(w/8) + 8;
printf("%-*sCoding\n", sp, "Data");
for(i = 0; i < n; i++) {
if(i < k) {
printf("D%-2d:", i);
for(j=0;j< size; j+=(w/8)) {
printf(" ");
for(x=0;x < w/8;x++){
printf("%02x", (unsigned char)data[i][j+x]);
}
}
printf(" ");
}
else printf("%*s", sp, "");
if(i < m) {
printf("C%-2d:", i);
for(j=0;j< size; j+=(w/8)) {
printf(" ");
for(x=0;x < w/8;x++){
printf("%02x", (unsigned char)coding[i][j+x]);
}
}
}
printf("\n");
}
printf("\n");
}
int main(int argc, char **argv)
{
long l;
int k, w, i, j, m;
int *matrix;
char **data, **coding;
int *erasures, *erased;
int *decoding_matrix, *dm_ids;
if (argc != 3) usage(NULL);
if (sscanf(argv[1], "%d", &k) == 0 || k <= 0) usage("Bad k");
if (sscanf(argv[2], "%d", &w) == 0 || (w != 8 && w != 16 && w != 32)) usage("Bad w");
m = 2;
if (w <= 16 && k + m > (1 << w)) usage("k + m is too big");
matrix = reed_sol_r6_coding_matrix(k, w);
printf("Last 2 rows of the Distribution Matrix:\n\n");
jerasure_print_matrix(matrix, m, k, w);
printf("\n");
srand48(0);
data = talloc(char *, k);
for (i = 0; i < k; i++) {
data[i] = talloc(char, sizeof(long));
l = lrand48();
memcpy(data[i], &l, sizeof(long));
}
coding = talloc(char *, m);
for (i = 0; i < m; i++) {
coding[i] = talloc(char, sizeof(long));
}
reed_sol_r6_encode(k, w, data, coding, sizeof(long));
printf("Encoding Complete:\n\n");
print_data_and_coding(k, m, w, sizeof(long), data, coding);
erasures = talloc(int, (m+1));
erased = talloc(int, (k+m));
for (i = 0; i < m+k; i++) erased[i] = 0;
l = 0;
for (i = 0; i < m; ) {
erasures[i] = lrand48()%(k+m);
if (erased[erasures[i]] == 0) {
erased[erasures[i]] = 1;
memcpy((erasures[i] < k) ? data[erasures[i]] : coding[erasures[i]-k], &l, sizeof(long));
i++;
}
}
erasures[i] = -1;
printf("Erased %d random devices:\n\n", m);
print_data_and_coding(k, m, w, sizeof(long), data, coding);
i = jerasure_matrix_decode(k, m, w, matrix, 1, erasures, data, coding, sizeof(long));
printf("State of the system after decoding:\n\n");
print_data_and_coding(k, m, w, sizeof(long), data, coding);
return 0;
}

112
Examples/reed_sol_04.c Executable file
View File

@ -0,0 +1,112 @@
/* Examples/reed_sol_04.c
Jerasure - A C/C++ Library for a Variety of Reed-Solomon and RAID-6 Erasure Coding Techniques
Revision 1.2A
May 24, 2011
James S. Plank
Department of Electrical Engineering and Computer Science
University of Tennessee
Knoxville, TN 37996
plank@cs.utk.edu
Copyright (c) 2011, James S. Plank
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
- Neither the name of the University of Tennessee nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "jerasure.h"
#include "reed_sol.h"
#define talloc(type, num) (type *) malloc(sizeof(type)*(num))
usage(char *s)
{
fprintf(stderr, "usage: reed_sol_04 w - Shows reed_sol_galois_wXX_region_multby_2\n");
fprintf(stderr, " \n");
fprintf(stderr, " w must be 8, 16 or 32. Sets up an array of 4 random words in\n");
fprintf(stderr, " GF(2^w) and multiplies them by two. \n");
fprintf(stderr, " \n");
fprintf(stderr, "This demonstrates: reed_sol_galois_w08_region_multby_2()\n");
fprintf(stderr, " reed_sol_galois_w16_region_multby_2()\n");
fprintf(stderr, " reed_sol_galois_w32_region_multby_2()\n");
if (s != NULL) fprintf(stderr, "%s\n", s);
exit(1);
}
int main(int argc, char **argv)
{
unsigned char *x, *y;
unsigned short *xs, *ys;
unsigned int *xi, *yi;
int *a32, *copy;
int i;
int w;
if (argc != 2) usage(NULL);
if (sscanf(argv[1], "%d", &w) == 0 || (w != 8 && w != 16 && w != 32)) usage("Bad w");
srand48(time(0));
a32 = talloc(int, 4);
copy = talloc(int, 4);
y = (unsigned char *) a32;
for (i = 0; i < 4*sizeof(int); i++) y[i] = lrand48()%255;
memcpy(copy, a32, sizeof(int)*4);
if (w == 8) {
x = (unsigned char *) copy;
y = (unsigned char *) a32;
reed_sol_galois_w08_region_multby_2((char *) a32, sizeof(int)*4);
for (i = 0; i < 4*sizeof(int)/sizeof(char); i++) {
printf("Char %2d: %3u *2 = %3u\n", i, x[i], y[i]);
}
} else if (w == 16) {
xs = (unsigned short *) copy;
ys = (unsigned short *) a32;
reed_sol_galois_w16_region_multby_2((char *) a32, sizeof(int)*4);
for (i = 0; i < 4*sizeof(int)/sizeof(short); i++) {
printf("Short %2d: %5u *2 = %5u\n", i, xs[i], ys[i]);
}
} else if (w == 32) {
xi = (unsigned int *) copy;
yi = (unsigned int *) a32;
reed_sol_galois_w16_region_multby_2((char *) a32, sizeof(int)*4);
for (i = 0; i < 4*sizeof(int)/sizeof(int); i++) {
printf("Int %2d: %10u *2 = %10u\n", i, xi[i], yi[i]);
}
}
}

32
License.txt Executable file
View File

@ -0,0 +1,32 @@
Copyright (c) 2011, James S. Plank
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
- Neither the name of the University of Tennessee nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

12
README.nd Executable file
View File

@ -0,0 +1,12 @@
This is revision 1.2A of Jerasure. It is basically equivalent to revision 1.2
except it is released under the New BSD license.
See technical report CS-08-627 for a description of the code.
There are two directories:
The home directory contains the jerasure code.
The Examples directory contains the example programs.
The makefile assumes that Examples is a subdirectory of the home directory.

12
README.txt Executable file
View File

@ -0,0 +1,12 @@
This is revision 1.2A of Jerasure. It is basically equivalent to revision 1.2
except it is released under the New BSD license.
See technical report CS-08-627 for a description of the code.
There are two directories:
The home directory contains the jerasure code.
The Examples directory contains the example programs.
The makefile assumes that Examples is a subdirectory of the home directory.

408
cauchy.c Executable file
View File

@ -0,0 +1,408 @@
/* cauchy.c
* James S. Plank
Jerasure - A C/C++ Library for a Variety of Reed-Solomon and RAID-6 Erasure Coding Techniques
Revision 1.2A
May 24, 2011
James S. Plank
Department of Electrical Engineering and Computer Science
University of Tennessee
Knoxville, TN 37996
plank@cs.utk.edu
Copyright (c) 2011, James S. Plank
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
- Neither the name of the University of Tennessee nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "galois.h"
#include "jerasure.h"
#include "cauchy.h"
static int PPs[33] = { -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1 };
static int NOs[33];
static int ONEs[33][33];
static int *cbest_0;
static int *cbest_1;
static int cbest_2[3];
static int cbest_3[7];
static int cbest_4[15];
static int cbest_5[31];
static int cbest_6[63];
static int cbest_7[127];
static int cbest_8[255];
static int cbest_9[511];
static int cbest_10[1023];
static int cbest_11[1023];
static int *cbest_12, *cbest_13, *cbest_14, *cbest_15, *cbest_16, *cbest_17, *cbest_18, *cbest_19, *cbest_20,
*cbest_21, *cbest_22, *cbest_23, *cbest_24, *cbest_25, *cbest_26, *cbest_27, *cbest_28, *cbest_29, *cbest_30,
*cbest_31, *cbest_32;
static int cbest_max_k[33] = { -1, -1, 3, 7, 15, 31, 63, 127, 255, 511, 1023, 1023, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1 };
static int cbest_init = 0;
static int *cbest_all[33];
#define talloc(type, num) (type *) malloc(sizeof(type)*(num))
int cauchy_n_ones(int n, int w)
{
int no;
int cno;
int nones;
int i, j;
int highbit;
highbit = (1 << (w-1));
if (PPs[w] == -1) {
nones = 0;
PPs[w] = galois_single_multiply(highbit, 2, w);
for (i = 0; i < w; i++) {
if (PPs[w] & (1 << i)) {
ONEs[w][nones] = (1 << i);
nones++;
}
}
NOs[w] = nones;
}
no = 0;
for (i = 0; i < w; i++) if (n & (1 << i)) no++;
cno = no;
for (i = 1; i < w; i++) {
if (n & highbit) {
n ^= highbit;
n <<= 1;
n ^= PPs[w];
cno--;
for (j = 0; j < NOs[w]; j++) {
cno += (n & ONEs[w][j]) ? 1 : -1;
}
} else {
n <<= 1;
}
no += cno;
}
return no;
}
int *cauchy_original_coding_matrix(int k, int m, int w)
{
int *matrix;
int i, j, index;
if (w < 31 && (k+m) > (1 << w)) return NULL;
matrix = talloc(int, k*m);
if (matrix == NULL) return NULL;
index = 0;
for (i = 0; i < m; i++) {
for (j = 0; j < k; j++) {
matrix[index] = galois_single_divide(1, (i ^ (m+j)), w);
index++;
}
}
return matrix;
}
int *cauchy_xy_coding_matrix(int k, int m, int w, int *X, int *Y)
{
int index, i, j;
int *matrix;
matrix = talloc(int, k*m);
if (matrix == NULL) { return NULL; }
index = 0;
for (i = 0; i < m; i++) {
for (j = 0; j < k; j++) {
matrix[index] = galois_single_divide(1, (X[i] ^ Y[j]), w);
index++;
}
}
return matrix;
}
void cauchy_improve_coding_matrix(int k, int m, int w, int *matrix)
{
int index, i, j, x;
int tmp;
int bno, tno, bno_index;
for (j = 0; j < k; j++) {
if (matrix[j] != 1) {
tmp = galois_single_divide(1, matrix[j], w);
index = j;
for (i = 0; i < m; i++) {
matrix[index] = galois_single_multiply(matrix[index], tmp, w);
index += k;
}
}
}
for (i = 1; i < m; i++) {
bno = 0;
index = i*k;
for (j = 0; j < k; j++) bno += cauchy_n_ones(matrix[index+j], w);
bno_index = -1;
for (j = 0; j < k; j++) {
if (matrix[index+j] != 1) {
tmp = galois_single_divide(1, matrix[index+j], w);
tno = 0;
for (x = 0; x < k; x++) {
tno += cauchy_n_ones(galois_single_multiply(matrix[index+x], tmp, w), w);
}
if (tno < bno) {
bno = tno;
bno_index = j;
}
}
}
if (bno_index != -1) {
tmp = galois_single_divide(1, matrix[index+bno_index], w);
for (j = 0; j < k; j++) {
matrix[index+j] = galois_single_multiply(matrix[index+j], tmp, w);
}
}
}
}
int *cauchy_good_general_coding_matrix(int k, int m, int w)
{
int *matrix, i;
if (m == 2 && k <= cbest_max_k[w]) {
matrix = talloc(int, k*m);
if (matrix == NULL) return NULL;
if (!cbest_init) {
cbest_init = 1;
cbest_all[0] = cbest_0; cbest_all[1] = cbest_1; cbest_all[2] = cbest_2; cbest_all[3] = cbest_3; cbest_all[4] =
cbest_4; cbest_all[5] = cbest_5; cbest_all[6] = cbest_6; cbest_all[7] = cbest_7; cbest_all[8] = cbest_8;
cbest_all[9] = cbest_9; cbest_all[10] = cbest_10; cbest_all[11] = cbest_11; cbest_all[12] = cbest_12;
cbest_all[13] = cbest_13; cbest_all[14] = cbest_14; cbest_all[15] = cbest_15; cbest_all[16] = cbest_16;
cbest_all[17] = cbest_17; cbest_all[18] = cbest_18; cbest_all[19] = cbest_19; cbest_all[20] = cbest_20;
cbest_all[21] = cbest_21; cbest_all[22] = cbest_22; cbest_all[23] = cbest_23; cbest_all[24] = cbest_24;
cbest_all[25] = cbest_25; cbest_all[26] = cbest_26; cbest_all[27] = cbest_27; cbest_all[28] = cbest_28;
cbest_all[29] = cbest_29; cbest_all[30] = cbest_30; cbest_all[31] = cbest_31; cbest_all[32] = (int *) cbest_32;
}
for (i = 0; i < k; i++) {
matrix[i] = 1;
matrix[i+k] = cbest_all[w][i];
}
return matrix;
} else {
matrix = cauchy_original_coding_matrix(k, m, w);
if (matrix == NULL) return NULL;
cauchy_improve_coding_matrix(k, m, w, matrix);
return matrix;
}
}
static int cbest_2[3] = { 1, 2, 3 };
static int cbest_3[7] = { 1, 2, 5, 4, 7, 3, 6 };
static int cbest_4[15] = { 1, 2, 9, 4, 8, 13, 3, 6, 12, 5, 11, 15, 10, 14, 7 };
static int cbest_5[31] = { 1, 2, 18, 4, 9, 8, 22, 16, 3, 11, 19, 5, 10, 6, 20, 27, 13, 23, 26, 12,
17, 25, 24, 31, 30, 7, 15, 21, 29, 14, 28 };
static int cbest_6[63] = { 1, 2, 33, 4, 8, 49, 16, 32, 57, 3, 6, 12, 24, 48, 5, 35, 9, 37, 10, 17,
41, 51, 56, 61, 18, 28, 53, 14, 20, 34, 7, 13, 25, 36, 59, 26, 39, 40, 45, 50, 60, 52, 63,
11, 30, 55, 19, 22, 29, 43, 58, 15, 21, 38, 44, 47, 62, 27, 54, 42, 31, 23, 46 };
static int cbest_7[127] = { 1, 2, 68, 4, 34, 8, 17, 16, 76, 32, 38, 3, 64, 69, 5, 19, 35, 70, 6, 9,
18, 102, 10, 36, 85, 12, 21, 42, 51, 72, 77, 84, 20, 25, 33, 50, 78, 98, 24, 39, 49, 100, 110
, 48, 65, 93, 40, 66, 71, 92, 7, 46, 55, 87, 96, 103, 106, 11, 23, 37, 54, 81, 86, 108, 13,
22, 27, 43, 53, 73, 80, 14, 26, 52, 74, 79, 99, 119, 44, 95, 101, 104, 111, 118, 29, 59, 89,
94, 117, 28, 41, 58, 67, 88, 115, 116, 47, 57, 83, 97, 107, 114, 127, 56, 82, 109, 113, 126,
112, 125, 15, 63, 75, 123, 124, 31, 45, 62, 91, 105, 122, 30, 61, 90, 121, 60, 120 };
static int cbest_8[255] = { 1, 2, 142, 4, 71, 8, 70, 173, 3, 35, 143, 16, 17, 67, 134, 140, 172, 6, 34
, 69, 201, 216, 5, 33, 86, 12, 65, 138, 158, 159, 175, 10, 32, 43, 66, 108, 130, 193, 234, 9,
24, 25, 50, 68, 79, 100, 132, 174, 200, 217, 20, 21, 42, 48, 87, 169, 41, 54, 64, 84, 96, 117
, 154, 155, 165, 226, 77, 82, 135, 136, 141, 168, 192, 218, 238, 7, 18, 19, 39, 40, 78, 113,
116, 128, 164, 180, 195, 205, 220, 232, 14, 26, 27, 58, 109, 156, 157, 203, 235, 13, 28, 29, 38
, 51, 56, 75, 85, 90, 101, 110, 112, 139, 171, 11, 37, 49, 52, 76, 83, 102, 119, 131, 150, 151
, 167, 182, 184, 188, 197, 219, 224, 45, 55, 80, 94, 97, 133, 170, 194, 204, 221, 227, 236, 36,
47, 73, 92, 98, 104, 118, 152, 153, 166, 202, 207, 239, 251, 22, 23, 44, 74, 91, 148, 149, 161
, 181, 190, 233, 46, 59, 88, 137, 146, 147, 163, 196, 208, 212, 222, 250, 57, 81, 95, 106, 111,
129, 160, 176, 199, 243, 249, 15, 53, 72, 93, 103, 115, 125, 162, 183, 185, 189, 206, 225, 255,
186, 210, 230, 237, 242, 248, 30, 31, 62, 89, 99, 105, 114, 121, 124, 178, 209, 213, 223, 228,
241, 254, 60, 191, 198, 247, 120, 240, 107, 127, 144, 145, 177, 211, 214, 246, 245, 123, 126,
187, 231, 253, 63, 179, 229, 244, 61, 122, 215, 252 };
static int cbest_9[511] = { 1, 2, 264, 4, 132, 8, 66, 16, 33, 32, 280, 64, 140, 128, 3, 70, 265, 5,
133, 256, 266, 6, 9, 35, 67, 134, 268, 396, 10, 17, 34, 330, 12, 18, 68, 198, 297, 20, 37, 74
, 136, 148, 165, 281, 296, 24, 36, 41, 65, 82, 99, 164, 272, 282, 388, 40, 49, 98, 141, 194,
284, 328, 412, 48, 97, 129, 142, 196, 346, 71, 72, 96, 130, 313, 392, 80, 206, 257, 267, 312,
334, 7, 135, 156, 173, 192, 258, 269, 397, 404, 11, 78, 144, 161, 172, 260, 270, 299, 331, 344,
398, 13, 19, 39, 69, 86, 103, 160, 167, 199, 202, 298, 322, 384, 14, 21, 38, 43, 75, 102, 137,
149, 166, 204, 289, 332, 408, 462, 22, 25, 42, 51, 83, 101, 138, 150, 273, 283, 288, 301, 350,
389, 429, 26, 50, 76, 100, 195, 274, 285, 300, 329, 363, 390, 413, 428, 28, 45, 84, 143, 197,
200, 214, 231, 276, 286, 315, 320, 347, 362, 414, 458, 44, 53, 73, 90, 107, 131, 152, 169, 181,
230, 314, 338, 361, 393, 400, 454, 460, 52, 57, 81, 106, 115, 168, 175, 180, 207, 229, 305, 335
, 348, 360, 394, 421, 478, 56, 105, 114, 157, 163, 174, 193, 210, 227, 228, 259, 304, 317, 326,
405, 420, 445, 79, 104, 113, 145, 158, 162, 212, 226, 261, 271, 316, 345, 379, 399, 406, 444,
450, 456, 87, 88, 112, 146, 203, 225, 262, 291, 323, 336, 378, 385, 425, 452, 474, 15, 205, 222
, 224, 239, 290, 303, 333, 367, 377, 386, 409, 424, 431, 463, 470, 476, 23, 139, 151, 189, 208,
238, 302, 324, 351, 366, 376, 410, 430, 437, 27, 47, 77, 94, 111, 177, 188, 237, 275, 293, 342,
365, 391, 436, 448, 29, 46, 55, 85, 110, 119, 171, 176, 183, 201, 215, 218, 235, 236, 277, 287,
292, 321, 355, 364, 415, 417, 459, 466, 472, 30, 54, 59, 91, 109, 118, 153, 170, 182, 220, 234,
278, 307, 339, 354, 401, 416, 423, 441, 455, 461, 468, 495, 58, 108, 117, 154, 233, 306, 319,
349, 353, 383, 395, 402, 422, 440, 447, 479, 494, 92, 116, 211, 232, 318, 327, 340, 352, 382,
446, 493, 61, 159, 213, 216, 247, 309, 381, 407, 427, 451, 457, 464, 491, 492, 60, 89, 123, 147
, 185, 246, 263, 308, 337, 371, 380, 426, 433, 453, 475, 487, 490, 122, 184, 191, 223, 245, 370,
387, 432, 439, 471, 477, 486, 489, 511, 121, 179, 190, 209, 243, 244, 295, 325, 359, 369, 411,
438, 485, 488, 510, 95, 120, 178, 242, 294, 343, 358, 368, 419, 449, 483, 484, 509, 219, 241,
357, 418, 443, 467, 473, 482, 507, 508, 31, 221, 240, 255, 279, 356, 442, 469, 481, 503, 506,
155, 254, 403, 480, 502, 505, 63, 93, 127, 253, 311, 341, 375, 501, 504, 62, 126, 187, 217, 251
, 252, 310, 374, 435, 465, 499, 500, 125, 186, 250, 373, 434, 498, 124, 249, 372, 497, 248, 496
};
static int cbest_10[1023] = { 1, 2, 516, 4, 258, 8, 129, 16, 32, 580, 64, 128, 290, 145, 256, 3, 512,
517, 5, 259, 518, 588, 6, 9, 18, 36, 72, 144, 774, 10, 17, 131, 262, 288, 524, 645, 12, 33,
133, 266, 294, 387, 532, 576, 581, 20, 34, 65, 137, 274, 548, 582, 24, 66, 291, 838, 40, 68,
130, 147, 161, 322, 644, 709, 806, 48, 132, 193, 257, 386, 596, 80, 136, 298, 419, 612, 661, 772
, 96, 149, 260, 272, 306, 403, 513, 146, 153, 160, 264, 292, 385, 514, 519, 544, 584, 589, 708,
870, 7, 19, 37, 73, 192, 354, 590, 770, 775, 11, 38, 74, 177, 263, 289, 418, 520, 525, 534, 641
, 660, 725, 802, 836, 846, 13, 22, 76, 148, 209, 267, 295, 320, 330, 402, 526, 528, 533, 577,
647, 717, 804, 14, 21, 26, 35, 44, 135, 152, 165, 201, 275, 304, 384, 401, 435, 549, 578, 583,
604, 608, 782, 903, 25, 52, 67, 88, 139, 270, 296, 391, 417, 550, 620, 653, 790, 834, 839, 41,
50, 69, 104, 141, 176, 278, 302, 323, 395, 423, 540, 598, 640, 705, 724, 807, 866, 28, 42, 49,
70, 82, 100, 163, 208, 282, 310, 556, 592, 597, 646, 663, 677, 711, 716, 868, 878, 81, 134, 151
, 164, 195, 200, 299, 326, 352, 362, 400, 434, 564, 613, 657, 768, 773, 902, 967, 97, 138, 155,
169, 197, 261, 273, 307, 358, 390, 416, 433, 451, 614, 652, 733, 800, 814, 844, 854, 935, 56, 84
, 98, 140, 181, 217, 265, 293, 328, 338, 394, 422, 515, 545, 585, 704, 788, 822, 871, 919, 162,
179, 276, 355, 407, 427, 546, 586, 591, 616, 662, 669, 676, 710, 727, 741, 771, 780, 901, 39, 75
, 150, 157, 194, 211, 225, 268, 280, 308, 314, 389, 411, 439, 521, 530, 535, 628, 656, 721, 803,
832, 837, 842, 847, 966, 23, 77, 112, 154, 168, 196, 300, 321, 331, 393, 421, 432, 450, 522, 527
, 529, 552, 606, 643, 673, 693, 713, 732, 805, 864, 874, 934, 999, 15, 27, 45, 54, 78, 90, 108,
180, 216, 305, 483, 560, 579, 600, 605, 609, 719, 778, 783, 852, 876, 886, 899, 918, 983, 46, 53
, 89, 167, 178, 185, 203, 213, 271, 297, 324, 334, 336, 360, 370, 406, 426, 467, 542, 551, 610,
621, 649, 668, 726, 740, 786, 791, 810, 820, 835, 900, 917, 931, 951, 965, 975, 30, 51, 105, 156
, 205, 210, 224, 279, 303, 356, 366, 388, 405, 410, 438, 449, 459, 536, 541, 594, 599, 622, 655,
720, 812, 818, 862, 867, 933, 29, 43, 71, 83, 92, 101, 106, 143, 173, 283, 311, 312, 346, 392,
409, 420, 437, 443, 557, 566, 593, 642, 659, 672, 692, 707, 712, 737, 757, 869, 879, 911, 998,
60, 102, 241, 327, 353, 363, 399, 425, 482, 558, 565, 624, 679, 718, 735, 749, 769, 798, 898,
963, 982, 58, 86, 166, 183, 184, 202, 212, 219, 233, 286, 359, 431, 466, 615, 636, 648, 689, 729
, 801, 815, 840, 845, 850, 855, 884, 916, 930, 950, 964, 974, 981, 995, 1015, 57, 85, 99, 120,
171, 199, 204, 229, 318, 329, 339, 368, 404, 448, 458, 465, 499, 654, 671, 685, 784, 789, 823,
872, 882, 915, 932, 949, 997, 1007, 116, 142, 159, 172, 277, 408, 436, 442, 455, 481, 491, 547,
572, 587, 617, 630, 658, 665, 706, 723, 736, 756, 776, 781, 816, 860, 894, 897, 910, 947, 991,
114, 221, 240, 269, 281, 309, 315, 332, 342, 344, 378, 398, 424, 441, 475, 487, 531, 618, 629,
678, 695, 734, 743, 748, 808, 833, 843, 929, 943, 962, 973, 113, 182, 189, 218, 227, 232, 301,
364, 374, 430, 457, 523, 553, 562, 602, 607, 688, 728, 753, 796, 830, 865, 875, 927, 980, 994,
1014, 55, 79, 91, 109, 170, 187, 198, 215, 228, 284, 415, 464, 498, 554, 561, 601, 670, 675, 684
, 715, 745, 765, 779, 848, 853, 877, 887, 909, 914, 948, 979, 996, 1006, 1013, 47, 110, 158, 249
, 316, 325, 335, 337, 361, 371, 397, 447, 454, 480, 490, 497, 538, 543, 611, 632, 664, 722, 787,
811, 821, 880, 896, 913, 946, 961, 971, 990, 1011, 31, 94, 220, 245, 357, 367, 429, 440, 474,
486, 537, 595, 623, 651, 681, 694, 701, 742, 759, 813, 819, 858, 863, 892, 928, 942, 945, 972,
989, 993, 1003, 1023, 62, 93, 107, 188, 207, 226, 237, 243, 313, 340, 347, 376, 456, 471, 473,
507, 567, 568, 626, 752, 890, 907, 926, 1005, 61, 103, 124, 175, 186, 214, 372, 414, 453, 463,
489, 503, 559, 625, 638, 674, 691, 714, 731, 739, 744, 764, 794, 799, 828, 908, 925, 939, 959,
978, 1012, 59, 87, 122, 248, 287, 350, 396, 413, 446, 485, 495, 496, 637, 751, 826, 841, 851,
885, 912, 941, 960, 970, 977, 1010, 118, 121, 235, 244, 319, 369, 382, 428, 445, 574, 650, 667,
680, 700, 758, 761, 785, 873, 883, 944, 988, 992, 1002, 1009, 1022, 117, 206, 223, 231, 236, 242
, 470, 472, 506, 573, 631, 687, 777, 817, 856, 861, 895, 906, 987, 1004, 1021, 115, 174, 191, 333
, 343, 345, 379, 452, 462, 469, 488, 502, 505, 619, 690, 697, 730, 738, 755, 809, 888, 924, 938,
958, 969, 1019, 253, 365, 375, 412, 484, 494, 501, 563, 603, 750, 767, 792, 797, 831, 923, 940,
957, 976, 1001, 234, 251, 285, 348, 444, 479, 555, 634, 666, 760, 824, 849, 905, 955, 1008, 111,
222, 230, 247, 317, 380, 461, 511, 539, 633, 686, 703, 747, 881, 937, 986, 1020, 95, 190, 468,
493, 504, 570, 696, 754, 859, 893, 968, 985, 1018, 63, 126, 252, 341, 377, 500, 569, 627, 683,
766, 891, 922, 956, 1000, 1017, 125, 239, 250, 373, 478, 639, 795, 829, 904, 921, 954, 123, 246,
351, 460, 477, 510, 702, 746, 763, 827, 936, 953, 119, 383, 492, 509, 575, 984, 682, 699, 857,
1016, 238, 255, 889, 920, 476, 762, 793, 952, 349, 508, 635, 825, 381, 698, 254, 571, 127 };
static int cbest_11[1023] = { 1,
2, 1026, 4, 513, 8, 16, 1282, 32, 64, 641, 128, 256, 512, 1346, 1024, 3, 673, 1027, 5, 10, 20, 40, 80, 160, 320,
640, 6, 9, 515, 1030, 1280, 1539, 17, 517, 1034, 1283, 12, 18, 33, 521, 1042, 1362, 34, 65, 529, 1058, 1286, 1795,
24, 36, 66, 129, 545, 643, 1090, 1290, 1667, 68, 130, 257, 577, 645, 672, 1154, 1298, 1344, 48, 72, 132, 258, 336,
649, 681, 1314, 1347, 136, 168, 260, 514, 657, 769, 1538, 1923, 84, 96, 144, 264, 516, 1025, 1350, 1410, 1859, 42,
272, 520, 705, 1032, 1354, 11, 21, 41, 81, 161, 192, 288, 321, 528, 675, 1028, 1537, 1699, 1794, 7, 22, 82, 162,
322, 544, 642, 677, 897, 1031, 1046, 1066, 1106, 1186, 1281, 1366, 1378, 1666, 14, 44, 164, 324, 384, 523, 533,
553, 576, 593, 644, 833, 1035, 1040, 1288, 1360, 1987, 13, 19, 28, 88, 328, 519, 648, 680, 689, 1043, 1056, 1284,
1363, 1474, 1543, 1793, 1955, 26, 35, 56, 176, 656, 768, 1038, 1059, 1088, 1287, 1302, 1322, 1442, 1547, 1665,
1922, 25, 37, 52, 67, 112, 340, 352, 525, 531, 737, 1091, 1152, 1291, 1296, 1555, 1858, 1875, 38, 69, 74, 104, 131,
224, 547, 651, 661, 683, 704, 721, 961, 1050, 1062, 1155, 1299, 1312, 1345, 1370, 1571, 1799, 49, 70, 73, 133, 138,
148, 170, 208, 259, 337, 448, 537, 549, 579, 647, 674, 929, 1094, 1294, 1315, 1352, 1536, 1603, 1671, 1698, 1803,
1921, 50, 134, 137, 169, 261, 266, 276, 296, 338, 416, 581, 676, 896, 1074, 1098, 1158, 1348, 1394, 1408, 1675,
1707, 1811, 1857, 2019, 76, 85, 97, 145, 262, 265, 522, 532, 552, 561, 585, 592, 653, 659, 685, 771, 832, 849,
1064, 1162, 1194, 1306, 1318, 1351, 1386, 1411, 1506, 1683, 1827, 1986, 2003, 43, 86, 98, 140, 146, 172, 273, 344,
518, 688, 773, 1033, 1110, 1122, 1170, 1355, 1490, 1542, 1697, 1792, 1927, 1954, 100, 193, 268, 274, 289, 597, 609,
665, 697, 707, 777, 1029, 1044, 1104, 1184, 1330, 1364, 1376, 1414, 1546, 1664, 1731, 1863, 1931, 1963, 23, 46, 83,
92, 152, 163, 184, 194, 290, 323, 368, 524, 530, 555, 693, 709, 736, 753, 785, 993, 1036, 1047, 1067, 1107, 1187,
1218, 1320, 1358, 1367, 1379, 1418, 1450, 1545, 1554, 1867, 1874, 1939, 1985, 15, 30, 45, 60, 90, 120, 165, 180,
196, 240, 280, 292, 325, 330, 360, 385, 480, 546, 650, 660, 679, 682, 713, 720, 745, 801, 899, 960, 977, 1041,
1289, 1361, 1426, 1472, 1541, 1570, 1703, 1798, 1953, 29, 58, 89, 116, 166, 200, 232, 326, 329, 386, 464, 535, 536,
548, 578, 595, 646, 835, 901, 928, 1048, 1057, 1070, 1190, 1285, 1300, 1368, 1382, 1440, 1475, 1559, 1579, 1602,
1619, 1670, 1802, 1879, 1891, 1920, 27, 57, 177, 304, 388, 527, 557, 580, 691, 725, 837, 905, 937, 1039, 1054,
1089, 1114, 1292, 1303, 1323, 1374, 1443, 1553, 1674, 1706, 1715, 1801, 1810, 1856, 1873, 1991, 2018, 2035, 53,
106, 113, 178, 212, 332, 341, 353, 392, 424, 541, 560, 584, 601, 652, 658, 684, 770, 841, 848, 913, 1060, 1082,
1096, 1153, 1202, 1297, 1402, 1478, 1522, 1569, 1673, 1682, 1705, 1797, 1826, 1959, 1995, 2002, 2027, 39, 54, 75,
105, 114, 225, 342, 354, 400, 539, 569, 739, 772, 1051, 1063, 1078, 1092, 1138, 1160, 1192, 1304, 1313, 1326, 1371,
1384, 1398, 1446, 1482, 1514, 1551, 1601, 1669, 1696, 1763, 1815, 1835, 1926, 71, 139, 149, 171, 209, 226, 298,
356, 449, 565, 596, 608, 625, 663, 664, 696, 706, 723, 741, 776, 853, 865, 963, 1072, 1095, 1130, 1156, 1250, 1295,
1310, 1353, 1392, 1687, 1730, 1747, 1809, 1862, 1930, 1962, 1971, 2007, 2017, 51, 78, 108, 135, 150, 210, 228, 267,
277, 297, 339, 348, 417, 450, 551, 554, 587, 617, 655, 687, 692, 708, 752, 784, 931, 965, 992, 1009, 1075, 1099,
1159, 1174, 1234, 1316, 1338, 1349, 1395, 1409, 1458, 1494, 1504, 1544, 1563, 1575, 1681, 1825, 1866, 1883, 1929,
1938, 1961, 1984, 2001, 77, 142, 174, 263, 278, 346, 376, 418, 452, 496, 583, 669, 678, 701, 712, 729, 744, 761,
800, 898, 933, 969, 976, 1001, 1065, 1108, 1120, 1163, 1168, 1195, 1307, 1319, 1334, 1356, 1387, 1416, 1448, 1488,
1507, 1540, 1607, 1702, 1807, 1865, 1925, 1952, 87, 99, 141, 147, 156, 173, 188, 216, 248, 270, 300, 345, 372, 420,
456, 488, 534, 563, 594, 667, 699, 757, 779, 789, 809, 834, 851, 900, 1102, 1111, 1123, 1171, 1328, 1412, 1491,
1558, 1578, 1587, 1611, 1618, 1679, 1711, 1729, 1861, 1878, 1890, 1907, 1943, 2023, 94, 101, 124, 154, 186, 244,
269, 275, 284, 526, 556, 589, 690, 724, 775, 836, 904, 936, 945, 981, 1045, 1068, 1105, 1166, 1185, 1198, 1216,
1331, 1365, 1377, 1390, 1415, 1430, 1510, 1552, 1577, 1714, 1800, 1819, 1831, 1872, 1899, 1937, 1990, 2034, 47, 62,
93, 102, 122, 153, 185, 195, 282, 291, 312, 362, 369, 432, 468, 540, 599, 600, 611, 715, 747, 840, 857, 912, 1037,
1052, 1112, 1126, 1219, 1321, 1359, 1372, 1419, 1424, 1451, 1568, 1623, 1635, 1672, 1691, 1701, 1704, 1723, 1796,
1958, 1994, 2011, 2026, 2043, 31, 61, 91, 121, 181, 197, 202, 234, 241, 281, 293, 308, 331, 361, 370, 481, 538,
568, 613, 695, 711, 738, 755, 781, 787, 995, 1080, 1118, 1178, 1188, 1210, 1380, 1400, 1427, 1473, 1498, 1530,
1550, 1557, 1600, 1617, 1668, 1719, 1735, 1762, 1779, 1814, 1834, 1843, 1877, 1889, 1935, 1967, 1993, 2025, 2039,
59, 117, 167, 182, 198, 201, 233, 242, 294, 327, 387, 465, 482, 559, 564, 605, 624, 662, 722, 740, 803, 852, 864,
881, 907, 917, 939, 962, 979, 997, 1049, 1071, 1086, 1146, 1191, 1206, 1222, 1266, 1301, 1324, 1369, 1383, 1406,
1422, 1441, 1454, 1480, 1512, 1526, 1549, 1686, 1713, 1739, 1746, 1771, 1808, 1833, 1871, 1970, 1989, 2006, 2016,
2033, 118, 305, 334, 364, 389, 394, 404, 426, 466, 484, 543, 550, 573, 586, 603, 616, 633, 654, 686, 717, 749, 793,
805, 843, 873, 903, 930, 964, 1008, 1055, 1115, 1128, 1142, 1200, 1226, 1258, 1293, 1308, 1375, 1476, 1520, 1562,
1574, 1680, 1824 };

53
cauchy.h Executable file
View File

@ -0,0 +1,53 @@
/* cauchy.h
* James S. Plank
Jerasure - A C/C++ Library for a Variety of Reed-Solomon and RAID-6 Erasure Coding Techniques
Revision 1.2A
May 24, 2011
James S. Plank
Department of Electrical Engineering and Computer Science
University of Tennessee
Knoxville, TN 37996
plank@cs.utk.edu
Copyright (c) 2011, James S. Plank
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
- Neither the name of the University of Tennessee nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
extern int *cauchy_original_coding_matrix(int k, int m, int w);
extern int *cauchy_xy_coding_matrix(int k, int m, int w, int *x, int *y);
extern void cauchy_improve_coding_matrix(int k, int m, int w, int *matrix);
extern int *cauchy_good_general_coding_matrix(int k, int m, int w);
extern int cauchy_n_ones(int n, int w);

1985
cauchy_best_r6.c Executable file

File diff suppressed because it is too large Load Diff

823
galois.c Executable file
View File

@ -0,0 +1,823 @@
/* Galois.c
* James S. Plank
Jerasure - A C/C++ Library for a Variety of Reed-Solomon and RAID-6 Erasure Coding Techniques
Revision 1.2A
May 24, 2011
James S. Plank
Department of Electrical Engineering and Computer Science
University of Tennessee
Knoxville, TN 37996
plank@cs.utk.edu
Copyright (c) 2011, James S. Plank
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
- Neither the name of the University of Tennessee nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "galois.h"
#define NONE (10)
#define TABLE (11)
#define SHIFT (12)
#define LOGS (13)
#define SPLITW8 (14)
static int prim_poly[33] =
{ 0,
/* 1 */ 1,
/* 2 */ 07,
/* 3 */ 013,
/* 4 */ 023,
/* 5 */ 045,
/* 6 */ 0103,
/* 7 */ 0211,
/* 8 */ 0435,
/* 9 */ 01021,
/* 10 */ 02011,
/* 11 */ 04005,
/* 12 */ 010123,
/* 13 */ 020033,
/* 14 */ 042103,
/* 15 */ 0100003,
/* 16 */ 0210013,
/* 17 */ 0400011,
/* 18 */ 01000201,
/* 19 */ 02000047,
/* 20 */ 04000011,
/* 21 */ 010000005,
/* 22 */ 020000003,
/* 23 */ 040000041,
/* 24 */ 0100000207,
/* 25 */ 0200000011,
/* 26 */ 0400000107,
/* 27 */ 01000000047,
/* 28 */ 02000000011,
/* 29 */ 04000000005,
/* 30 */ 010040000007,
/* 31 */ 020000000011,
/* 32 */ 00020000007 }; /* Really 40020000007, but we're omitting the high order bit */
static int mult_type[33] =
{ NONE,
/* 1 */ TABLE,
/* 2 */ TABLE,
/* 3 */ TABLE,
/* 4 */ TABLE,
/* 5 */ TABLE,
/* 6 */ TABLE,
/* 7 */ TABLE,
/* 8 */ TABLE,
/* 9 */ TABLE,
/* 10 */ LOGS,
/* 11 */ LOGS,
/* 12 */ LOGS,
/* 13 */ LOGS,
/* 14 */ LOGS,
/* 15 */ LOGS,
/* 16 */ LOGS,
/* 17 */ LOGS,
/* 18 */ LOGS,
/* 19 */ LOGS,
/* 20 */ LOGS,
/* 21 */ LOGS,
/* 22 */ LOGS,
/* 23 */ SHIFT,
/* 24 */ SHIFT,
/* 25 */ SHIFT,
/* 26 */ SHIFT,
/* 27 */ SHIFT,
/* 28 */ SHIFT,
/* 29 */ SHIFT,
/* 30 */ SHIFT,
/* 31 */ SHIFT,
/* 32 */ SPLITW8 };
static int nw[33] = { 0, (1 << 1), (1 << 2), (1 << 3), (1 << 4),
(1 << 5), (1 << 6), (1 << 7), (1 << 8), (1 << 9), (1 << 10),
(1 << 11), (1 << 12), (1 << 13), (1 << 14), (1 << 15), (1 << 16),
(1 << 17), (1 << 18), (1 << 19), (1 << 20), (1 << 21), (1 << 22),
(1 << 23), (1 << 24), (1 << 25), (1 << 26), (1 << 27), (1 << 28),
(1 << 29), (1 << 30), (1 << 31), -1 };
static int nwm1[33] = { 0, (1 << 1)-1, (1 << 2)-1, (1 << 3)-1, (1 << 4)-1,
(1 << 5)-1, (1 << 6)-1, (1 << 7)-1, (1 << 8)-1, (1 << 9)-1, (1 << 10)-1,
(1 << 11)-1, (1 << 12)-1, (1 << 13)-1, (1 << 14)-1, (1 << 15)-1, (1 << 16)-1,
(1 << 17)-1, (1 << 18)-1, (1 << 19)-1, (1 << 20)-1, (1 << 21)-1, (1 << 22)-1,
(1 << 23)-1, (1 << 24)-1, (1 << 25)-1, (1 << 26)-1, (1 << 27)-1, (1 << 28)-1,
(1 << 29)-1, (1 << 30)-1, 0x7fffffff, 0xffffffff };
static int *galois_log_tables[33] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
static int *galois_ilog_tables[33] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
static int *galois_mult_tables[33] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
static int *galois_div_tables[33] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
/* Special case for w = 32 */
static int *galois_split_w8[7] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL };
int galois_create_log_tables(int w)
{
int j, b;
if (w > 30) return -1;
if (galois_log_tables[w] != NULL) return 0;
galois_log_tables[w] = (int *) malloc(sizeof(int)*nw[w]);
if (galois_log_tables[w] == NULL) return -1;
galois_ilog_tables[w] = (int *) malloc(sizeof(int)*nw[w]*3);
if (galois_ilog_tables[w] == NULL) {
free(galois_log_tables[w]);
galois_log_tables[w] = NULL;
return -1;
}
for (j = 0; j < nw[w]; j++) {
galois_log_tables[w][j] = nwm1[w];
galois_ilog_tables[w][j] = 0;
}
b = 1;
for (j = 0; j < nwm1[w]; j++) {
if (galois_log_tables[w][b] != nwm1[w]) {
fprintf(stderr, "Galois_create_log_tables Error: j=%d, b=%d, B->J[b]=%d, J->B[j]=%d (0%o)\n",
j, b, galois_log_tables[w][b], galois_ilog_tables[w][j], (b << 1) ^ prim_poly[w]);
exit(1);
}
galois_log_tables[w][b] = j;
galois_ilog_tables[w][j] = b;
b = b << 1;
if (b & nw[w]) b = (b ^ prim_poly[w]) & nwm1[w];
}
for (j = 0; j < nwm1[w]; j++) {
galois_ilog_tables[w][j+nwm1[w]] = galois_ilog_tables[w][j];
galois_ilog_tables[w][j+nwm1[w]*2] = galois_ilog_tables[w][j];
}
galois_ilog_tables[w] += nwm1[w];
return 0;
}
int galois_logtable_multiply(int x, int y, int w)
{
int sum_j;
if (x == 0 || y == 0) return 0;
sum_j = galois_log_tables[w][x] + galois_log_tables[w][y];
/* if (sum_j >= nwm1[w]) sum_j -= nwm1[w]; Don't need to do this,
because we replicate the ilog table twice. */
return galois_ilog_tables[w][sum_j];
}
int galois_logtable_divide(int x, int y, int w)
{
int sum_j;
int z;
if (y == 0) return -1;
if (x == 0) return 0;
sum_j = galois_log_tables[w][x] - galois_log_tables[w][y];
/* if (sum_j < 0) sum_j += nwm1[w]; Don't need to do this, because we replicate the ilog table twice. */
z = galois_ilog_tables[w][sum_j];
return z;
}
int galois_create_mult_tables(int w)
{
int j, x, y, logx;
if (w >= 14) return -1;
if (galois_mult_tables[w] != NULL) return 0;
galois_mult_tables[w] = (int *) malloc(sizeof(int) * nw[w] * nw[w]);
if (galois_mult_tables[w] == NULL) return -1;
galois_div_tables[w] = (int *) malloc(sizeof(int) * nw[w] * nw[w]);
if (galois_div_tables[w] == NULL) {
free(galois_mult_tables[w]);
galois_mult_tables[w] = NULL;
return -1;
}
if (galois_log_tables[w] == NULL) {
if (galois_create_log_tables(w) < 0) {
free(galois_mult_tables[w]);
free(galois_div_tables[w]);
galois_mult_tables[w] = NULL;
galois_div_tables[w] = NULL;
return -1;
}
}
/* Set mult/div tables for x = 0 */
j = 0;
galois_mult_tables[w][j] = 0; /* y = 0 */
galois_div_tables[w][j] = -1;
j++;
for (y = 1; y < nw[w]; y++) { /* y > 0 */
galois_mult_tables[w][j] = 0;
galois_div_tables[w][j] = 0;
j++;
}
for (x = 1; x < nw[w]; x++) { /* x > 0 */
galois_mult_tables[w][j] = 0; /* y = 0 */
galois_div_tables[w][j] = -1;
j++;
logx = galois_log_tables[w][x];
for (y = 1; y < nw[w]; y++) { /* y > 0 */
galois_mult_tables[w][j] = galois_ilog_tables[w][logx+galois_log_tables[w][y]];
galois_div_tables[w][j] = galois_ilog_tables[w][logx-galois_log_tables[w][y]];
j++;
}
}
return 0;
}
int galois_ilog(int value, int w)
{
if (galois_ilog_tables[w] == NULL) {
if (galois_create_log_tables(w) < 0) {
fprintf(stderr, "Error: galois_ilog - w is too big. Sorry\n");
exit(1);
}
}
return galois_ilog_tables[w][value];
}
int galois_log(int value, int w)
{
if (galois_log_tables[w] == NULL) {
if (galois_create_log_tables(w) < 0) {
fprintf(stderr, "Error: galois_log - w is too big. Sorry\n");
exit(1);
}
}
return galois_log_tables[w][value];
}
int galois_shift_multiply(int x, int y, int w)
{
int prod;
int i, j, ind;
int k;
int scratch[33];
prod = 0;
for (i = 0; i < w; i++) {
scratch[i] = y;
if (y & (1 << (w-1))) {
y = y << 1;
y = (y ^ prim_poly[w]) & nwm1[w];
} else {
y = y << 1;
}
}
for (i = 0; i < w; i++) {
ind = (1 << i);
if (ind & x) {
j = 1;
for (k = 0; k < w; k++) {
prod = prod ^ (j & scratch[i]);
j = (j << 1);
}
}
}
return prod;
}
int galois_single_multiply(int x, int y, int w)
{
int sum_j;
int z;
if (x == 0 || y == 0) return 0;
if (mult_type[w] == TABLE) {
if (galois_mult_tables[w] == NULL) {
if (galois_create_mult_tables(w) < 0) {
fprintf(stderr, "ERROR -- cannot make multiplication tables for w=%d\n", w);
exit(1);
}
}
return galois_mult_tables[w][(x<<w)|y];
} else if (mult_type[w] == LOGS) {
if (galois_log_tables[w] == NULL) {
if (galois_create_log_tables(w) < 0) {
fprintf(stderr, "ERROR -- cannot make log tables for w=%d\n", w);
exit(1);
}
}
sum_j = galois_log_tables[w][x] + galois_log_tables[w][y];
z = galois_ilog_tables[w][sum_j];
return z;
} else if (mult_type[w] == SPLITW8) {
if (galois_split_w8[0] == NULL) {
if (galois_create_split_w8_tables() < 0) {
fprintf(stderr, "ERROR -- cannot make log split_w8_tables for w=%d\n", w);
exit(1);
}
}
return galois_split_w8_multiply(x, y);
} else if (mult_type[w] == SHIFT) {
return galois_shift_multiply(x, y, w);
}
fprintf(stderr, "Galois_single_multiply - no implementation for w=%d\n", w);
exit(1);
}
int galois_multtable_multiply(int x, int y, int w)
{
return galois_mult_tables[w][(x<<w)|y];
}
int galois_single_divide(int a, int b, int w)
{
int sum_j;
if (mult_type[w] == TABLE) {
if (galois_div_tables[w] == NULL) {
if (galois_create_mult_tables(w) < 0) {
fprintf(stderr, "ERROR -- cannot make multiplication tables for w=%d\n", w);
exit(1);
}
}
return galois_div_tables[w][(a<<w)|b];
} else if (mult_type[w] == LOGS) {
if (b == 0) return -1;
if (a == 0) return 0;
if (galois_log_tables[w] == NULL) {
if (galois_create_log_tables(w) < 0) {
fprintf(stderr, "ERROR -- cannot make log tables for w=%d\n", w);
exit(1);
}
}
sum_j = galois_log_tables[w][a] - galois_log_tables[w][b];
return galois_ilog_tables[w][sum_j];
} else {
if (b == 0) return -1;
if (a == 0) return 0;
sum_j = galois_inverse(b, w);
return galois_single_multiply(a, sum_j, w);
}
fprintf(stderr, "Galois_single_divide - no implementation for w=%d\n", w);
exit(1);
}
int galois_shift_divide(int a, int b, int w)
{
int inverse;
if (b == 0) return -1;
if (a == 0) return 0;
inverse = galois_shift_inverse(b, w);
return galois_shift_multiply(a, inverse, w);
}
int galois_multtable_divide(int x, int y, int w)
{
return galois_div_tables[w][(x<<w)|y];
}
void galois_w08_region_multiply(char *region, /* Region to multiply */
int multby, /* Number to multiply by */
int nbytes, /* Number of bytes in region */
char *r2, /* If r2 != NULL, products go here */
int add)
{
unsigned char *ur1, *ur2, *cp;
unsigned char prod;
int i, srow, j;
unsigned long l, *lp2;
unsigned char *lp;
int sol;
ur1 = (unsigned char *) region;
ur2 = (r2 == NULL) ? ur1 : (unsigned char *) r2;
/* This is used to test its performance with respect to just calling galois_single_multiply
if (r2 == NULL || !add) {
for (i = 0; i < nbytes; i++) ur2[i] = galois_single_multiply(ur1[i], multby, 8);
} else {
for (i = 0; i < nbytes; i++) {
ur2[i] = (ur2[i]^galois_single_multiply(ur1[i], multby, 8));
}
}
*/
if (galois_mult_tables[8] == NULL) {
if (galois_create_mult_tables(8) < 0) {
fprintf(stderr, "galois_08_region_multiply -- couldn't make multiplication tables\n");
exit(1);
}
}
srow = multby * nw[8];
if (r2 == NULL || !add) {
for (i = 0; i < nbytes; i++) {
prod = galois_mult_tables[8][srow+ur1[i]];
ur2[i] = prod;
}
} else {
sol = sizeof(long);
lp2 = &l;
lp = (unsigned char *) lp2;
for (i = 0; i < nbytes; i += sol) {
cp = ur2+i;
lp2 = (unsigned long *) cp;
for (j = 0; j < sol; j++) {
prod = galois_mult_tables[8][srow+ur1[i+j]];
lp[j] = prod;
}
*lp2 = (*lp2) ^ l;
}
}
return;
}
void galois_w16_region_multiply(char *region, /* Region to multiply */
int multby, /* Number to multiply by */
int nbytes, /* Number of bytes in region */
char *r2, /* If r2 != NULL, products go here */
int add)
{
unsigned short *ur1, *ur2, *cp;
int prod;
int i, log1, j, log2;
unsigned long l, *lp2, *lptop;
unsigned short *lp;
int sol;
ur1 = (unsigned short *) region;
ur2 = (r2 == NULL) ? ur1 : (unsigned short *) r2;
nbytes /= 2;
/* This is used to test its performance with respect to just calling galois_single_multiply */
/*
if (r2 == NULL || !add) {
for (i = 0; i < nbytes; i++) ur2[i] = galois_single_multiply(ur1[i], multby, 16);
} else {
for (i = 0; i < nbytes; i++) {
ur2[i] = (ur2[i]^galois_single_multiply(ur1[i], multby, 16));
}
}
return;
*/
if (multby == 0) {
if (!add) {
lp2 = (unsigned long *) ur2;
ur2 += nbytes;
lptop = (unsigned long *) ur2;
while (lp2 < lptop) { *lp2 = 0; lp2++; }
}
return;
}
if (galois_log_tables[16] == NULL) {
if (galois_create_log_tables(16) < 0) {
fprintf(stderr, "galois_16_region_multiply -- couldn't make log tables\n");
exit(1);
}
}
log1 = galois_log_tables[16][multby];
if (r2 == NULL || !add) {
for (i = 0; i < nbytes; i++) {
if (ur1[i] == 0) {
ur2[i] = 0;
} else {
prod = galois_log_tables[16][ur1[i]] + log1;
ur2[i] = galois_ilog_tables[16][prod];
}
}
} else {
sol = sizeof(long)/2;
lp2 = &l;
lp = (unsigned short *) lp2;
for (i = 0; i < nbytes; i += sol) {
cp = ur2+i;
lp2 = (unsigned long *) cp;
for (j = 0; j < sol; j++) {
if (ur1[i+j] == 0) {
lp[j] = 0;
} else {
log2 = galois_log_tables[16][ur1[i+j]];
prod = log2 + log1;
lp[j] = galois_ilog_tables[16][prod];
}
}
*lp2 = (*lp2) ^ l;
}
}
return;
}
/* This will destroy mat, by the way */
void galois_invert_binary_matrix(int *mat, int *inv, int rows)
{
int cols, i, j, k;
int tmp;
cols = rows;
for (i = 0; i < rows; i++) inv[i] = (1 << i);
/* First -- convert into upper triangular */
for (i = 0; i < cols; i++) {
/* Swap rows if we ave a zero i,i element. If we can't swap, then the
matrix was not invertible */
if ((mat[i] & (1 << i)) == 0) {
for (j = i+1; j < rows && (mat[j] & (1 << i)) == 0; j++) ;
if (j == rows) {
fprintf(stderr, "galois_invert_matrix: Matrix not invertible!!\n");
exit(1);
}
tmp = mat[i]; mat[i] = mat[j]; mat[j] = tmp;
tmp = inv[i]; inv[i] = inv[j]; inv[j] = tmp;
}
/* Now for each j>i, add A_ji*Ai to Aj */
for (j = i+1; j != rows; j++) {
if ((mat[j] & (1 << i)) != 0) {
mat[j] ^= mat[i];
inv[j] ^= inv[i];
}
}
}
/* Now the matrix is upper triangular. Start at the top and multiply down */
for (i = rows-1; i >= 0; i--) {
for (j = 0; j < i; j++) {
if (mat[j] & (1 << i)) {
/* mat[j] ^= mat[i]; */
inv[j] ^= inv[i];
}
}
}
}
int galois_inverse(int y, int w)
{
if (y == 0) return -1;
if (mult_type[w] == SHIFT || mult_type[w] == SPLITW8) return galois_shift_inverse(y, w);
return galois_single_divide(1, y, w);
}
int galois_shift_inverse(int y, int w)
{
int mat[1024], mat2[32];
int inv[1024], inv2[32];
int ind, i, j, k, prod;
for (i = 0; i < w; i++) {
mat2[i] = y;
if (y & nw[w-1]) {
y = y << 1;
y = (y ^ prim_poly[w]) & nwm1[w];
} else {
y = y << 1;
}
}
galois_invert_binary_matrix(mat2, inv2, w);
return inv2[0];
}
int *galois_get_mult_table(int w)
{
if (galois_mult_tables[w] == NULL) {
if (galois_create_mult_tables(w)) {
return NULL;
}
}
return galois_mult_tables[w];
}
int *galois_get_div_table(int w)
{
if (galois_mult_tables[w] == NULL) {
if (galois_create_mult_tables(w)) {
return NULL;
}
}
return galois_div_tables[w];
}
int *galois_get_log_table(int w)
{
if (galois_log_tables[w] == NULL) {
if (galois_create_log_tables(w)) {
return NULL;
}
}
return galois_log_tables[w];
}
int *galois_get_ilog_table(int w)
{
if (galois_ilog_tables[w] == NULL) {
if (galois_create_log_tables(w)) {
return NULL;
}
}
return galois_ilog_tables[w];
}
void galois_w32_region_multiply(char *region, /* Region to multiply */
int multby, /* Number to multiply by */
int nbytes, /* Number of bytes in region */
char *r2, /* If r2 != NULL, products go here */
int add)
{
unsigned int *ur1, *ur2, *cp, *ur2top;
unsigned long *lp2, *lptop;
int i, j, a, b, accumulator, i8, j8, k;
int acache[4];
ur1 = (unsigned int *) region;
ur2 = (r2 == NULL) ? ur1 : (unsigned int *) r2;
nbytes /= sizeof(int);
ur2top = ur2 + nbytes;
if (galois_split_w8[0]== NULL) {
if (galois_create_split_w8_tables(8) < 0) {
fprintf(stderr, "galois_32_region_multiply -- couldn't make split multiplication tables\n");
exit(1);
}
}
/* If we're overwriting r2, then we can't do better than just calling split_multiply.
We'll inline it here to save on the procedure call overhead */
i8 = 0;
for (i = 0; i < 4; i++) {
acache[i] = (((multby >> i8) & 255) << 8);
i8 += 8;
}
if (!add) {
for (k = 0; k < nbytes; k++) {
accumulator = 0;
for (i = 0; i < 4; i++) {
a = acache[i];
j8 = 0;
for (j = 0; j < 4; j++) {
b = ((ur1[k] >> j8) & 255);
accumulator ^= galois_split_w8[i+j][a|b];
j8 += 8;
}
}
ur2[k] = accumulator;
}
} else {
for (k = 0; k < nbytes; k++) {
accumulator = 0;
for (i = 0; i < 4; i++) {
a = acache[i];
j8 = 0;
for (j = 0; j < 4; j++) {
b = ((ur1[k] >> j8) & 255);
accumulator ^= galois_split_w8[i+j][a|b];
j8 += 8;
}
}
ur2[k] = (ur2[k] ^ accumulator);
}
}
return;
}
void galois_region_xor( char *r1, /* Region 1 */
char *r2, /* Region 2 */
char *r3, /* Sum region (r3 = r1 ^ r2) -- can be r1 or r2 */
int nbytes) /* Number of bytes in region */
{
long *l1;
long *l2;
long *l3;
long *ltop;
char *ctop;
ctop = r1 + nbytes;
ltop = (long *) ctop;
l1 = (long *) r1;
l2 = (long *) r2;
l3 = (long *) r3;
while (l1 < ltop) {
*l3 = ((*l1) ^ (*l2));
l1++;
l2++;
l3++;
}
}
int galois_create_split_w8_tables()
{
int p1, p2, i, j, p1elt, p2elt, index, ishift, jshift, *table;
if (galois_split_w8[0] != NULL) return 0;
if (galois_create_mult_tables(8) < 0) return -1;
for (i = 0; i < 7; i++) {
galois_split_w8[i] = (int *) malloc(sizeof(int) * (1 << 16));
if (galois_split_w8[i] == NULL) {
for (i--; i >= 0; i--) free(galois_split_w8[i]);
return -1;
}
}
for (i = 0; i < 4; i += 3) {
ishift = i * 8;
for (j = ((i == 0) ? 0 : 1) ; j < 4; j++) {
jshift = j * 8;
table = galois_split_w8[i+j];
index = 0;
for (p1 = 0; p1 < 256; p1++) {
p1elt = (p1 << ishift);
for (p2 = 0; p2 < 256; p2++) {
p2elt = (p2 << jshift);
table[index] = galois_shift_multiply(p1elt, p2elt, 32);
index++;
}
}
}
}
return 0;
}
int galois_split_w8_multiply(int x, int y)
{
int i, j, a, b, accumulator, i8, j8;
accumulator = 0;
i8 = 0;
for (i = 0; i < 4; i++) {
a = (((x >> i8) & 255) << 8);
j8 = 0;
for (j = 0; j < 4; j++) {
b = ((y >> j8) & 255);
accumulator ^= galois_split_w8[i+j][a|b];
j8 += 8;
}
i8 += 8;
}
return accumulator;
}

111
galois.h Executable file
View File

@ -0,0 +1,111 @@
/* Galois.h
* James S. Plank
Jerasure - A C/C++ Library for a Variety of Reed-Solomon and RAID-6 Erasure Coding Techniques
Revision 1.2A
May 24, 2011
James S. Plank
Department of Electrical Engineering and Computer Science
University of Tennessee
Knoxville, TN 37996
plank@cs.utk.edu
Copyright (c) 2011, James S. Plank
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
- Neither the name of the University of Tennessee nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _GALOIS_H
#define _GALOIS_H
#include <stdio.h>
#include <stdlib.h>
extern int galois_single_multiply(int a, int b, int w);
extern int galois_single_divide(int a, int b, int w);
extern int galois_log(int value, int w);
extern int galois_ilog(int value, int w);
extern int galois_create_log_tables(int w); /* Returns 0 on success, -1 on failure */
extern int galois_logtable_multiply(int x, int y, int w);
extern int galois_logtable_divide(int x, int y, int w);
extern int galois_create_mult_tables(int w); /* Returns 0 on success, -1 on failure */
extern int galois_multtable_multiply(int x, int y, int w);
extern int galois_multtable_divide(int x, int y, int w);
extern int galois_shift_multiply(int x, int y, int w);
extern int galois_shift_divide(int x, int y, int w);
extern int galois_create_split_w8_tables();
extern int galois_split_w8_multiply(int x, int y);
extern int galois_inverse(int x, int w);
extern int galois_shift_inverse(int y, int w);
extern int *galois_get_mult_table(int w);
extern int *galois_get_div_table(int w);
extern int *galois_get_log_table(int w);
extern int *galois_get_ilog_table(int w);
void galois_region_xor( char *r1, /* Region 1 */
char *r2, /* Region 2 */
char *r3, /* Sum region (r3 = r1 ^ r2) -- can be r1 or r2 */
int nbytes); /* Number of bytes in region */
/* These multiply regions in w=8, w=16 and w=32. They are much faster
than calling galois_single_multiply. The regions must be long word aligned. */
void galois_w08_region_multiply(char *region, /* Region to multiply */
int multby, /* Number to multiply by */
int nbytes, /* Number of bytes in region */
char *r2, /* If r2 != NULL, products go here.
Otherwise region is overwritten */
int add); /* If (r2 != NULL && add) the produce is XOR'd with r2 */
void galois_w16_region_multiply(char *region, /* Region to multiply */
int multby, /* Number to multiply by */
int nbytes, /* Number of bytes in region */
char *r2, /* If r2 != NULL, products go here.
Otherwise region is overwritten */
int add); /* If (r2 != NULL && add) the produce is XOR'd with r2 */
void galois_w32_region_multiply(char *region, /* Region to multiply */
int multby, /* Number to multiply by */
int nbytes, /* Number of bytes in region */
char *r2, /* If r2 != NULL, products go here.
Otherwise region is overwritten */
int add); /* If (r2 != NULL && add) the produce is XOR'd with r2 */
#endif

1382
jerasure.c Executable file

File diff suppressed because it is too large Load Diff

300
jerasure.h Executable file
View File

@ -0,0 +1,300 @@
/* jerasure.h - header of kernel procedures
* James S. Plank
Jerasure - A C/C++ Library for a Variety of Reed-Solomon and RAID-6 Erasure Coding Techniques
Revision 1.2A
May 24, 2011
James S. Plank
Department of Electrical Engineering and Computer Science
University of Tennessee
Knoxville, TN 37996
plank@cs.utk.edu
Copyright (c) 2011, James S. Plank
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
- Neither the name of the University of Tennessee nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _JERASURE_H
#define _JERASURE_H
/* This uses procedures from the Galois Field arithmetic library */
#include "galois.h"
/* ------------------------------------------------------------ */
/* In all of the routines below:
k = Number of data devices
m = Number of coding devices
w = Word size
data_ptrs = An array of k pointers to data which is size bytes.
Size must be a multiple of sizeof(long).
Pointers must also be longword aligned.
coding_ptrs = An array of m pointers to coding data which is size bytes.
packetsize = The size of a coding block with bitmatrix coding.
When you code with a bitmatrix, you will use w packets
of size packetsize.
matrix = an array of k*m integers.
It represents an m by k matrix.
Element i,j is in matrix[i*k+j];
bitmatrix = an array of k*m*w*w integers.
It represents an mw by kw matrix.
Element i,j is in matrix[i*k*w+j];
erasures = an array of id's of erased devices.
Id's are integers between 0 and k+m-1.
Id's 0 to k-1 are id's of data devices.
Id's k to k+m-1 are id's of coding devices:
Coding device id = id-k.
If there are e erasures, erasures[e] = -1.
schedule = an array of schedule operations.
If there are m operations, then schedule[m][0] = -1.
operation = an array of 5 integers:
0 = operation: 0 for copy, 1 for xor (-1 for end)
1 = source device (0 - k+m-1)
2 = source packet (0 - w-1)
3 = destination device (0 - k+m-1)
4 = destination packet (0 - w-1)
*/
/* --------------------------------------------------------------- */
/* Bitmatrices / schedules ---------------------------------------- */
/*
- jerasure_matrix_to_bitmatrix turns a m X k matrix in GF(2^w) into a
wm X wk bitmatrix (in GF(2)). This is
explained in the Cauchy Reed-Solomon coding
paper.
- jerasure_dumb_bitmatrix_to_schedule turns a bitmatrix into a schedule
using the straightforward algorithm -- just
schedule the dot products defined by each
row of the matrix.
- jerasure_smart_bitmatrix_to_schedule turns a bitmatrix into a schedule,
but tries to use previous dot products to
calculate new ones. This is the optimization
explained in the original Liberation code paper.
- jerasure_generate_schedule_cache precalcalculate all the schedule for the
given distribution bitmatrix. M must equal 2.
- jerasure_free_schedule frees a schedule that was allocated with
jerasure_XXX_bitmatrix_to_schedule.
- jerasure_free_schedule_cache frees a schedule cache that was created with
jerasure_generate_schedule_cache.
*/
int *jerasure_matrix_to_bitmatrix(int k, int m, int w, int *matrix);
int **jerasure_dumb_bitmatrix_to_schedule(int k, int m, int w, int *bitmatrix);
int **jerasure_smart_bitmatrix_to_schedule(int k, int m, int w, int *bitmatrix);
int ***jerasure_generate_schedule_cache(int k, int m, int w, int *bitmatrix, int smart);
void jerasure_free_schedule(int **schedule);
void jerasure_free_schedule_cache(int k, int m, int ***cache);
/* ------------------------------------------------------------ */
/* Encoding - these are all straightforward. jerasure_matrix_encode only
works with w = 8|16|32. */
void jerasure_do_parity(int k, char **data_ptrs, char *parity_ptr, int size);
void jerasure_matrix_encode(int k, int m, int w, int *matrix,
char **data_ptrs, char **coding_ptrs, int size);
void jerasure_bitmatrix_encode(int k, int m, int w, int *bitmatrix,
char **data_ptrs, char **coding_ptrs, int size, int packetsize);
void jerasure_schedule_encode(int k, int m, int w, int **schedule,
char **data_ptrs, char **coding_ptrs, int size, int packetsize);
/* ------------------------------------------------------------ */
/* Decoding. -------------------------------------------------- */
/* These return integers, because the matrix may not be invertible.
The parameter row_k_ones should be set to 1 if row k of the matrix
(or rows kw to (k+1)w+1) of th distribution matrix are all ones
(or all identity matrices). Then you can improve the performance
of decoding when there is more than one failure, and the parity
device didn't fail. You do it by decoding all but one of the data
devices, and then decoding the last data device from the data devices
and the parity device.
jerasure_schedule_decode_lazy generates the schedule on the fly.
jerasure_matrix_decode only works when w = 8|16|32.
jerasure_make_decoding_matrix/bitmatrix make the k*k decoding matrix
(or wk*wk bitmatrix) by taking the rows corresponding to k
non-erased devices of the distribution matrix, and then
inverting that matrix.
You should already have allocated the decoding matrix and
dm_ids, which is a vector of k integers. These will be
filled in appropriately. dm_ids[i] is the id of element
i of the survivors vector. I.e. row i of the decoding matrix
times dm_ids equals data drive i.
Both of these routines take "erased" instead of "erasures".
Erased is a vector with k+m elements, which has 0 or 1 for
each device's id, according to whether the device is erased.
jerasure_erasures_to_erased allocates and returns erased from erasures.
*/
int jerasure_matrix_decode(int k, int m, int w,
int *matrix, int row_k_ones, int *erasures,
char **data_ptrs, char **coding_ptrs, int size);
int jerasure_bitmatrix_decode(int k, int m, int w,
int *bitmatrix, int row_k_ones, int *erasures,
char **data_ptrs, char **coding_ptrs, int size, int packetsize);
int jerasure_schedule_decode_lazy(int k, int m, int w, int *bitmatrix, int *erasures,
char **data_ptrs, char **coding_ptrs, int size, int packetsize,
int smart);
int jerasure_schedule_decode_cache(int k, int m, int w, int ***scache, int *erasures,
char **data_ptrs, char **coding_ptrs, int size, int packetsize);
int jerasure_make_decoding_matrix(int k, int m, int w, int *matrix, int *erased,
int *decoding_matrix, int *dm_ids);
int jerasure_make_decoding_bitmatrix(int k, int m, int w, int *matrix, int *erased,
int *decoding_matrix, int *dm_ids);
int *jerasure_erasures_to_erased(int k, int m, int *erasures);
/* ------------------------------------------------------------ */
/* These perform dot products and schedules. -------------------*/
/*
src_ids is a matrix of k id's (0 - k-1 for data devices, k - k+m-1
for coding devices) that identify the source devices. Dest_id is
the id of the destination device.
jerasure_matrix_dotprod only works when w = 8|16|32.
jerasure_do_scheduled_operations executes the schedule on w*packetsize worth of
bytes from each device. ptrs is an array of pointers which should have as many
elements as the highest referenced device in the schedule.
*/
void jerasure_matrix_dotprod(int k, int w, int *matrix_row,
int *src_ids, int dest_id,
char **data_ptrs, char **coding_ptrs, int size);
void jerasure_bitmatrix_dotprod(int k, int w, int *bitmatrix_row,
int *src_ids, int dest_id,
char **data_ptrs, char **coding_ptrs, int size, int packetsize);
void jerasure_do_scheduled_operations(char **ptrs, int **schedule, int packetsize);
/* ------------------------------------------------------------ */
/* Matrix Inversion ------------------------------------------- */
/*
The two matrix inversion functions work on rows*rows matrices of
ints. If a bitmatrix, then each int will just be zero or one.
Otherwise, they will be elements of gf(2^w). Obviously, you can
do bit matrices with crs_invert_matrix() and set w = 1, but
crs_invert_bitmatrix will be more efficient.
The two invertible functions return whether a matrix is invertible.
They are more efficient than the inverstion functions.
Mat will be destroyed when the matrix inversion or invertible
testing is done. Sorry.
Inv must be allocated by the caller.
The two invert_matrix functions return 0 on success, and -1 if the
matrix is uninvertible.
The two invertible function simply return whether the matrix is
invertible. (0 or 1). Mat will be destroyed.
*/
int jerasure_invert_matrix(int *mat, int *inv, int rows, int w);
int jerasure_invert_bitmatrix(int *mat, int *inv, int rows);
int jerasure_invertible_matrix(int *mat, int rows, int w);
int jerasure_invertible_bitmatrix(int *mat, int rows);
/* ------------------------------------------------------------ */
/* Basic matrix operations -------------------------------------*/
/*
Each of the print_matrix routines require a w. In jerasure_print_matrix,
this is to calculate the field width. In jerasure_print_bitmatrix, it is
to put spaces between the bits.
jerasure_matrix_multiply is a simple matrix multiplier in GF(2^w). It returns a r1*c2
matrix, which is the product of the two input matrices. It allocates
the product. Obviously, c1 should equal r2. However, this is not
validated by the procedure.
*/
void jerasure_print_matrix(int *matrix, int rows, int cols, int w);
void jerasure_print_bitmatrix(int *matrix, int rows, int cols, int w);
int *jerasure_matrix_multiply(int *m1, int *m2, int r1, int c1, int r2, int c2, int w);
/* ------------------------------------------------------------ */
/* Stats ------------------------------------------------------ */
/*
jerasure_get_stats fills in a vector of three doubles:
fill_in[0] is the number of bytes that have been XOR'd
fill_in[1] is the number of bytes that have been copied
fill_in[2] is the number of bytes that have been multiplied
by a constant in GF(2^w)
When jerasure_get_stats() is called, it resets its values.
*/
void jerasure_get_stats(double *fill_in);
#endif

265
liberation.c Executable file
View File

@ -0,0 +1,265 @@
/* liberation.c
* James S. Plank
Jerasure - A C/C++ Library for a Variety of Reed-Solomon and RAID-6 Erasure Coding Techniques
Revision 1.2A
May 24, 2011
James S. Plank
Department of Electrical Engineering and Computer Science
University of Tennessee
Knoxville, TN 37996
plank@cs.utk.edu
Copyright (c) 2011, James S. Plank
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
- Neither the name of the University of Tennessee nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "galois.h"
#include "jerasure.h"
#include "liberation.h"
#define talloc(type, num) (type *) malloc(sizeof(type)*(num))
int *liberation_coding_bitmatrix(int k, int w)
{
int *matrix, i, j, index;
if (k > w) return NULL;
matrix = talloc(int, 2*k*w*w);
if (matrix == NULL) return NULL;
bzero(matrix, sizeof(int)*2*k*w*w);
/* Set up identity matrices */
for(i = 0; i < w; i++) {
index = i*k*w+i;
for (j = 0; j < k; j++) {
matrix[index] = 1;
index += w;
}
}
/* Set up liberation matrices */
for (j = 0; j < k; j++) {
index = k*w*w+j*w;
for (i = 0; i < w; i++) {
matrix[index+(j+i)%w] = 1;
index += (k*w);
}
if (j > 0) {
i = (j*((w-1)/2))%w;
matrix[k*w*w+j*w+i*k*w+(i+j-1)%w] = 1;
}
}
return matrix;
}
int *liber8tion_coding_bitmatrix(int k)
{
int *matrix, i, j, index;
int w;
w = 8;
if (k > w) return NULL;
matrix = talloc(int, 2*k*w*w);
if (matrix == NULL) return NULL;
bzero(matrix, sizeof(int)*2*k*w*w);
/* Set up identity matrices */
for(i = 0; i < w; i++) {
index = i*k*w+i;
for (j = 0; j < k; j++) {
matrix[index] = 1;
index += w;
}
}
/* Set up liber8tion matrices */
index = k*w*w;
if (k == 0) return matrix;
matrix[index+0*k*w+0*w+0] = 1;
matrix[index+1*k*w+0*w+1] = 1;
matrix[index+2*k*w+0*w+2] = 1;
matrix[index+3*k*w+0*w+3] = 1;
matrix[index+4*k*w+0*w+4] = 1;
matrix[index+5*k*w+0*w+5] = 1;
matrix[index+6*k*w+0*w+6] = 1;
matrix[index+7*k*w+0*w+7] = 1;
if (k == 1) return matrix;
matrix[index+0*k*w+1*w+7] = 1;
matrix[index+1*k*w+1*w+3] = 1;
matrix[index+2*k*w+1*w+0] = 1;
matrix[index+3*k*w+1*w+2] = 1;
matrix[index+4*k*w+1*w+6] = 1;
matrix[index+5*k*w+1*w+1] = 1;
matrix[index+6*k*w+1*w+5] = 1;
matrix[index+7*k*w+1*w+4] = 1;
matrix[index+4*k*w+1*w+7] = 1;
if (k == 2) return matrix;
matrix[index+0*k*w+2*w+6] = 1;
matrix[index+1*k*w+2*w+2] = 1;
matrix[index+2*k*w+2*w+4] = 1;
matrix[index+3*k*w+2*w+0] = 1;
matrix[index+4*k*w+2*w+7] = 1;
matrix[index+5*k*w+2*w+3] = 1;
matrix[index+6*k*w+2*w+1] = 1;
matrix[index+7*k*w+2*w+5] = 1;
matrix[index+1*k*w+2*w+3] = 1;
if (k == 3) return matrix;
matrix[index+0*k*w+3*w+2] = 1;
matrix[index+1*k*w+3*w+5] = 1;
matrix[index+2*k*w+3*w+7] = 1;
matrix[index+3*k*w+3*w+6] = 1;
matrix[index+4*k*w+3*w+0] = 1;
matrix[index+5*k*w+3*w+3] = 1;
matrix[index+6*k*w+3*w+4] = 1;
matrix[index+7*k*w+3*w+1] = 1;
matrix[index+5*k*w+3*w+4] = 1;
if (k == 4) return matrix;
matrix[index+0*k*w+4*w+5] = 1;
matrix[index+1*k*w+4*w+6] = 1;
matrix[index+2*k*w+4*w+1] = 1;
matrix[index+3*k*w+4*w+7] = 1;
matrix[index+4*k*w+4*w+2] = 1;
matrix[index+5*k*w+4*w+4] = 1;
matrix[index+6*k*w+4*w+3] = 1;
matrix[index+7*k*w+4*w+0] = 1;
matrix[index+2*k*w+4*w+0] = 1;
if (k == 5) return matrix;
matrix[index+0*k*w+5*w+1] = 1;
matrix[index+1*k*w+5*w+2] = 1;
matrix[index+2*k*w+5*w+3] = 1;
matrix[index+3*k*w+5*w+4] = 1;
matrix[index+4*k*w+5*w+5] = 1;
matrix[index+5*k*w+5*w+6] = 1;
matrix[index+6*k*w+5*w+7] = 1;
matrix[index+7*k*w+5*w+0] = 1;
matrix[index+7*k*w+5*w+2] = 1;
if (k == 6) return matrix;
matrix[index+0*k*w+6*w+3] = 1;
matrix[index+1*k*w+6*w+0] = 1;
matrix[index+2*k*w+6*w+6] = 1;
matrix[index+3*k*w+6*w+5] = 1;
matrix[index+4*k*w+6*w+1] = 1;
matrix[index+5*k*w+6*w+7] = 1;
matrix[index+6*k*w+6*w+4] = 1;
matrix[index+7*k*w+6*w+2] = 1;
matrix[index+6*k*w+6*w+5] = 1;
if (k == 7) return matrix;
matrix[index+0*k*w+7*w+4] = 1;
matrix[index+1*k*w+7*w+7] = 1;
matrix[index+2*k*w+7*w+1] = 1;
matrix[index+3*k*w+7*w+5] = 1;
matrix[index+4*k*w+7*w+3] = 1;
matrix[index+5*k*w+7*w+2] = 1;
matrix[index+6*k*w+7*w+0] = 1;
matrix[index+7*k*w+7*w+6] = 1;
matrix[index+3*k*w+7*w+1] = 1;
return matrix;
}
int *blaum_roth_coding_bitmatrix(int k, int w)
{
int *matrix, i, j, index, l, m, p;
if (k > w) return NULL ;
matrix = talloc(int, 2*k*w*w);
if (matrix == NULL) return NULL;
bzero(matrix, sizeof(int)*2*k*w*w);
/* Set up identity matrices */
for(i = 0; i < w; i++) {
index = i*k*w+i;
for (j = 0; j < k; j++) {
matrix[index] = 1;
index += w;
}
}
/* Set up blaum_roth matrices -- Ignore identity */
p = w+1;
for (j = 0; j < k; j++) {
index = k*w*w+j*w;
if (j == 0) {
for (l = 0; l < w; l++) {
matrix[index+l] = 1;
index += k*w;
}
} else {
i = j;
for (l = 1; l <= w; l++) {
if (l != p-i) {
m = l+i;
if (m >= p) m -= p;
m--;
matrix[index+m] = 1;
} else {
matrix[index+i-1] = 1;
if (i%2 == 0) {
m = i/2;
} else {
m = (p/2) + 1 + (i/2);
}
m--;
matrix[index+m] = 1;
}
index += k*w;
}
}
}
return matrix;
}

56
liberation.h Executable file
View File

@ -0,0 +1,56 @@
/* liberation.h
* James S. Plank
Jerasure - A C/C++ Library for a Variety of Reed-Solomon and RAID-6 Erasure Coding Techniques
Revision 1.2A
May 24, 2011
James S. Plank
Department of Electrical Engineering and Computer Science
University of Tennessee
Knoxville, TN 37996
plank@cs.utk.edu
Copyright (c) 2011, James S. Plank
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
- Neither the name of the University of Tennessee nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _LIBERATION
extern int *liberation_coding_bitmatrix(int k, int w);
extern int *liber8tion_coding_bitmatrix(int k);
extern int *blaum_roth_coding_bitmatrix(int k, int w);
#endif

49
makefile Executable file
View File

@ -0,0 +1,49 @@
# Makefile
# James S. Plank
#
# JERASURE - Library for Erasure Coding
# Copright (C) 2007 James S. Plank
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
#
# James S. Plank
# Department of Electrical Engineering and Computer Science
# University of Tennessee
# Knoxville, TN 37996
# plank@cs.utk.edu
# $Revision: 1.0 $
# $Date: 2007/09/25 15:12:20 $
CC = gcc
CFLAGS = -O3 -I$(HOME)/include
ALL = galois.o jerasure.o reed_sol.o cauchy.o liberation.o
all: $(ALL)
clean:
rm -f core *.o $(ALL) a.out
.SUFFIXES: .c .o
.c.o:
$(CC) $(CFLAGS) -c $*.c
galois.o: galois.h
jerasure.o: jerasure.h galois.h
reed_sol.o: jerasure.h galois.h reed_sol.h
cauchy.o: jerasure.h galois.h cauchy.h
liberation.o: jerasure.h galois.h liberation.h

369
reed_sol.c Executable file
View File

@ -0,0 +1,369 @@
/* reed_sol.c
* James S. Plank
Jerasure - A C/C++ Library for a Variety of Reed-Solomon and RAID-6 Erasure Coding Techniques
Revision 1.2A
May 24, 2011
James S. Plank
Department of Electrical Engineering and Computer Science
University of Tennessee
Knoxville, TN 37996
plank@cs.utk.edu
Copyright (c) 2011, James S. Plank
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
- Neither the name of the University of Tennessee nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "galois.h"
#include "jerasure.h"
#include "reed_sol.h"
#define talloc(type, num) (type *) malloc(sizeof(type)*(num))
int *reed_sol_r6_coding_matrix(int k, int w)
{
int *matrix;
int i, tmp;
if (w != 8 && w != 16 && w != 32) return NULL;
matrix = talloc(int, 2*k);
if (matrix == NULL) return NULL;
for (i = 0; i < k; i++) matrix[i] = 1;
matrix[k] = 1;
tmp = 1;
for (i = 1; i < k; i++) {
tmp = galois_single_multiply(tmp, 2, w);
matrix[k+i] = tmp;
}
return matrix;
}
int *reed_sol_vandermonde_coding_matrix(int k, int m, int w)
{
int tmp;
int i, j, index;
int *vdm, *dist;
vdm = reed_sol_big_vandermonde_distribution_matrix(k+m, k, w);
if (vdm == NULL) return NULL;
dist = talloc(int, m*k);
if (dist == NULL) {
free(vdm);
return NULL;
}
i = k*k;
for (j = 0; j < m*k; j++) {
dist[j] = vdm[i];
i++;
}
free(vdm);
return dist;
}
static int prim32 = -1;
#define rgw32_mask(v) ((v) & 0x80000000)
void reed_sol_galois_w32_region_multby_2(char *region, int nbytes)
{
int *l1;
int *ltop;
char *ctop;
if (prim32 == -1) prim32 = galois_single_multiply((1 << 31), 2, 32);
ctop = region + nbytes;
ltop = (int *) ctop;
l1 = (int *) region;
while (l1 < ltop) {
*l1 = ((*l1) << 1) ^ ((*l1 & 0x80000000) ? prim32 : 0);
l1++;
}
}
static int prim08 = -1;
static int mask08_1 = -1;
static int mask08_2 = -1;
void reed_sol_galois_w08_region_multby_2(char *region, int nbytes)
{
unsigned int *l1;
unsigned int *ltop;
char *ctop;
unsigned int tmp, tmp2;
if (prim08 == -1) {
tmp = galois_single_multiply((1 << 7), 2, 8);
prim08 = 0;
while (tmp != 0) {
prim08 |= tmp;
tmp = (tmp << 8);
}
tmp = (1 << 8) - 2;
mask08_1 = 0;
while (tmp != 0) {
mask08_1 |= tmp;
tmp = (tmp << 8);
}
tmp = (1 << 7);
mask08_2 = 0;
while (tmp != 0) {
mask08_2 |= tmp;
tmp = (tmp << 8);
}
}
ctop = region + nbytes;
ltop = (unsigned int *) ctop;
l1 = (unsigned int *) region;
while (l1 < ltop) {
tmp = ((*l1) << 1) & mask08_1;
tmp2 = (*l1) & mask08_2;
tmp2 = ((tmp2 << 1) - (tmp2 >> 7));
*l1 = (tmp ^ (tmp2 & prim08));
l1++;
}
}
static int prim16 = -1;
static int mask16_1 = -1;
static int mask16_2 = -1;
void reed_sol_galois_w16_region_multby_2(char *region, int nbytes)
{
unsigned int *l1;
unsigned int *ltop;
char *ctop;
unsigned int tmp, tmp2;
if (prim16 == -1) {
tmp = galois_single_multiply((1 << 15), 2, 16);
prim16 = 0;
while (tmp != 0) {
prim16 |= tmp;
tmp = (tmp << 16);
}
tmp = (1 << 16) - 2;
mask16_1 = 0;
while (tmp != 0) {
mask16_1 |= tmp;
tmp = (tmp << 16);
}
tmp = (1 << 15);
mask16_2 = 0;
while (tmp != 0) {
mask16_2 |= tmp;
tmp = (tmp << 16);
}
}
ctop = region + nbytes;
ltop = (unsigned int *) ctop;
l1 = (unsigned int *) region;
while (l1 < ltop) {
tmp = ((*l1) << 1) & mask16_1;
tmp2 = (*l1) & mask16_2;
tmp2 = ((tmp2 << 1) - (tmp2 >> 15));
*l1 = (tmp ^ (tmp2 & prim16));
l1++;
}
}
int reed_sol_r6_encode(int k, int w, char **data_ptrs, char **coding_ptrs, int size)
{
int i;
/* First, put the XOR into coding region 0 */
memcpy(coding_ptrs[0], data_ptrs[0], size);
for (i = 1; i < k; i++) galois_region_xor(coding_ptrs[0], data_ptrs[i], coding_ptrs[0], size);
/* Next, put the sum of (2^j)*Dj into coding region 1 */
memcpy(coding_ptrs[1], data_ptrs[k-1], size);
for (i = k-2; i >= 0; i--) {
switch (w) {
case 8: reed_sol_galois_w08_region_multby_2(coding_ptrs[1], size); break;
case 16: reed_sol_galois_w16_region_multby_2(coding_ptrs[1], size); break;
case 32: reed_sol_galois_w32_region_multby_2(coding_ptrs[1], size); break;
default: return 0;
}
galois_region_xor(coding_ptrs[1], data_ptrs[i], coding_ptrs[1], size);
}
return 1;
}
int *reed_sol_extended_vandermonde_matrix(int rows, int cols, int w)
{
int *vdm;
int i, j, k;
if (w < 30 && (1 << w) < rows) return NULL;
if (w < 30 && (1 << w) < cols) return NULL;
vdm = talloc(int, rows*cols);
if (vdm == NULL) { return NULL; }
vdm[0] = 1;
for (j = 1; j < cols; j++) vdm[j] = 0;
if (rows == 1) return vdm;
i=(rows-1)*cols;
for (j = 0; j < cols-1; j++) vdm[i+j] = 0;
vdm[i+j] = 1;
if (rows == 2) return vdm;
for (i = 1; i < rows-1; i++) {
k = 1;
for (j = 0; j < cols; j++) {
vdm[i*cols+j] = k;
k = galois_single_multiply(k, i, w);
}
}
return vdm;
}
int *reed_sol_big_vandermonde_distribution_matrix(int rows, int cols, int w)
{
int *dist;
int i, j, k;
int sindex, srindex, siindex, tmp;
if (cols >= rows) return NULL;
dist = reed_sol_extended_vandermonde_matrix(rows, cols, w);
if (dist == NULL) return NULL;
sindex = 0;
for (i = 1; i < cols; i++) {
sindex += cols;
/* Find an appropriate row -- where i,i != 0 */
srindex = sindex+i;
for (j = i; j < rows && dist[srindex] == 0; j++) srindex += cols;
if (j >= rows) { /* This should never happen if rows/w are correct */
fprintf(stderr, "reed_sol_big_vandermonde_distribution_matrix(%d,%d,%d) - couldn't make matrix\n",
rows, cols, w);
exit(1);
}
/* If necessary, swap rows */
if (j != i) {
srindex -= i;
for (k = 0; k < cols; k++) {
tmp = dist[srindex+k];
dist[srindex+k] = dist[sindex+k];
dist[sindex+k] = tmp;
}
}
/* If Element i,i is not equal to 1, multiply the column by 1/i */
if (dist[sindex+i] != 1) {
tmp = galois_single_divide(1, dist[sindex+i], w);
srindex = i;
for (j = 0; j < rows; j++) {
dist[srindex] = galois_single_multiply(tmp, dist[srindex], w);
srindex += cols;
}
}
/* Now, for each element in row i that is not in column 1, you need
to make it zero. Suppose that this is column j, and the element
at i,j = e. Then you want to replace all of column j with
(col-j + col-i*e). Note, that in row i, col-i = 1 and col-j = e.
So (e + 1e) = 0, which is indeed what we want. */
for (j = 0; j < cols; j++) {
tmp = dist[sindex+j];
if (j != i && tmp != 0) {
srindex = j;
siindex = i;
for (k = 0; k < rows; k++) {
dist[srindex] = dist[srindex] ^ galois_single_multiply(tmp, dist[siindex], w);
srindex += cols;
siindex += cols;
}
}
}
}
/* We desire to have row k be all ones. To do that, multiply
the entire column j by 1/dist[k,j]. Then row j by 1/dist[j,j]. */
sindex = cols*cols;
for (j = 0; j < cols; j++) {
tmp = dist[sindex];
if (tmp != 1) {
tmp = galois_single_divide(1, tmp, w);
srindex = sindex;
for (i = cols; i < rows; i++) {
dist[srindex] = galois_single_multiply(tmp, dist[srindex], w);
srindex += cols;
}
}
sindex++;
}
/* Finally, we'd like the first column of each row to be all ones. To
do that, we multiply the row by the inverse of the first element. */
sindex = cols*(cols+1);
for (i = cols+1; i < rows; i++) {
tmp = dist[sindex];
if (tmp != 1) {
tmp = galois_single_divide(1, tmp, w);
for (j = 0; j < cols; j++) dist[sindex+j] = galois_single_multiply(dist[sindex+j], tmp, w);
}
sindex += cols;
}
return dist;
}

59
reed_sol.h Executable file
View File

@ -0,0 +1,59 @@
/* reed_sol.h
* James S. Plank
Jerasure - A C/C++ Library for a Variety of Reed-Solomon and RAID-6 Erasure Coding Techniques
Revision 1.2A
May 24, 2011
James S. Plank
Department of Electrical Engineering and Computer Science
University of Tennessee
Knoxville, TN 37996
plank@cs.utk.edu
Copyright (c) 2011, James S. Plank
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
- Neither the name of the University of Tennessee nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
extern int *reed_sol_vandermonde_coding_matrix(int k, int m, int w);
extern int *reed_sol_extended_vandermonde_matrix(int rows, int cols, int w);
extern int *reed_sol_big_vandermonde_distribution_matrix(int rows, int cols, int w);
extern int reed_sol_r6_encode(int k, int w, char **data_ptrs, char **coding_ptrs, int size);
extern int *reed_sol_r6_coding_matrix(int k, int w);
extern void reed_sol_galois_w08_region_multby_2(char *region, int nbytes);
extern void reed_sol_galois_w16_region_multby_2(char *region, int nbytes);
extern void reed_sol_galois_w32_region_multby_2(char *region, int nbytes);