]> AND Private Git Repository - Cipher_code.git/blob - IDA_new/jerasure/Examples/decoder.c
Logo AND Algorithmique Numérique Distribuée

Private GIT Repository
yes
[Cipher_code.git] / IDA_new / jerasure / Examples / decoder.c
1 /* *
2  * Copyright (c) 2014, James S. Plank and Kevin Greenan
3  * All rights reserved.
4  *
5  * Jerasure - A C/C++ Library for a Variety of Reed-Solomon and RAID-6 Erasure
6  * Coding Techniques
7  *
8  * Revision 2.0: Galois Field backend now links to GF-Complete
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  *
14  *  - Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  *
17  *  - Redistributions in binary form must reproduce the above copyright
18  *    notice, this list of conditions and the following disclaimer in
19  *    the documentation and/or other materials provided with the
20  *    distribution.
21  *
22  *  - Neither the name of the University of Tennessee nor the names of its
23  *    contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30  * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
31  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
32  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
33  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
34  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
36  * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37  * POSSIBILITY OF SUCH DAMAGE.
38  */
39
40 /* Jerasure's authors:
41
42    Revision 2.x - 2014: James S. Plank and Kevin M. Greenan.
43    Revision 1.2 - 2008: James S. Plank, Scott Simmerman and Catherine D. Schuman.
44    Revision 1.0 - 2007: James S. Plank.
45  */
46
47 /* 
48 This program takes as input an inputfile, k, m, a coding
49 technique, w, and packetsize.  It is the companion program
50 of encoder.c, which creates k+m files.  This program assumes 
51 that up to m erasures have occurred in the k+m files.  It
52 reads in the k+m files or marks the file as erased. It then
53 recreates the original file and creates a new file with the
54 suffix "decoded" with the decoded contents of the file.
55
56 This program does not error check command line arguments because 
57 it is assumed that encoder.c has been called previously with the
58 same arguments, and encoder.c does error check.
59 */
60
61 #include <stdio.h>
62 #include <stdlib.h>
63 #include <string.h>
64 #include <time.h>
65 #include <assert.h>
66 #include <unistd.h>
67 #include <sys/time.h>
68 #include <sys/stat.h>
69 #include <signal.h>
70 #include <unistd.h>
71 #include "jerasure.h"
72 #include "reed_sol.h"
73 #include "galois.h"
74 #include "cauchy.h"
75 #include "liberation.h"
76 #include "timing.h"
77
78 #define N 10
79
80 enum Coding_Technique {Reed_Sol_Van, Reed_Sol_R6_Op, Cauchy_Orig, Cauchy_Good, Liberation, Blaum_Roth, Liber8tion, RDP, EVENODD, No_Coding};
81
82 char *Methods[N] = {"reed_sol_van", "reed_sol_r6_op", "cauchy_orig", "cauchy_good", "liberation", "blaum_roth", "liber8tion", "rdp", "evenodd", "no_coding"};
83
84 /* Global variables for signal handler */
85 enum Coding_Technique method;
86 int readins, n;
87
88 /* Function prototype */
89 void ctrl_bs_handler(int dummy);
90
91 int main (int argc, char **argv) {
92         FILE *fp;                               // File pointer
93
94         /* Jerasure arguments */
95         char **data;
96         char **coding;
97         int *erasures;
98         int *erased;
99         int *matrix;
100         int *bitmatrix;
101         
102         /* Parameters */
103         int k, m, w, packetsize, buffersize;
104         int tech;
105         char *c_tech;
106         
107         int i, j;                               // loop control variable, s
108         int blocksize = 0;                      // size of individual files
109         int origsize;                   // size of file before padding
110         int total;                              // used to write data, not padding to file
111         struct stat status;             // used to find size of individual files
112         int numerased;                  // number of erased files
113                 
114         /* Used to recreate file names */
115         char *temp;
116         char *cs1, *cs2, *extension;
117         char *fname;
118         int md;
119         char *curdir;
120
121         /* Used to time decoding */
122         struct timing t1, t2, t3, t4;
123         double tsec;
124         double totalsec;
125
126         
127         signal(SIGQUIT, ctrl_bs_handler);
128
129         matrix = NULL;
130         bitmatrix = NULL;
131         totalsec = 0.0;
132         
133         /* Start timing */
134         timing_set(&t1);
135
136         /* Error checking parameters */
137         if (argc != 2) {
138                 fprintf(stderr, "usage: inputfile\n");
139                 exit(0);
140         }
141         curdir = (char *)malloc(sizeof(char)*1000);
142         assert(curdir == getcwd(curdir, 1000));
143         
144         /* Begin recreation of file names */
145         cs1 = (char*)malloc(sizeof(char)*strlen(argv[1]));
146         cs2 = strrchr(argv[1], '/');
147         if (cs2 != NULL) {
148                 cs2++;
149                 strcpy(cs1, cs2);
150         }
151         else {
152                 strcpy(cs1, argv[1]);
153         }
154         cs2 = strchr(cs1, '.');
155         if (cs2 != NULL) {
156                 extension = strdup(cs2);
157                 *cs2 = '\0';
158         } else {
159            extension = strdup("");
160         }       
161         fname = (char *)malloc(sizeof(char*)*(100+strlen(argv[1])+20));
162
163         /* Read in parameters from metadata file */
164         sprintf(fname, "%s/Coding/%s_meta.txt", curdir, cs1);
165
166         fp = fopen(fname, "rb");
167         if (fp == NULL) {
168           fprintf(stderr, "Error: no metadata file %s\n", fname);
169           exit(1);
170         }
171         temp = (char *)malloc(sizeof(char)*(strlen(argv[1])+20));
172         if (fscanf(fp, "%s", temp) != 1) {
173                 fprintf(stderr, "Metadata file - bad format\n");
174                 exit(0);
175         }
176         
177         if (fscanf(fp, "%d", &origsize) != 1) {
178                 fprintf(stderr, "Original size is not valid\n");
179                 exit(0);
180         }
181         if (fscanf(fp, "%d %d %d %d %d", &k, &m, &w, &packetsize, &buffersize) != 5) {
182                 fprintf(stderr, "Parameters are not correct\n");
183                 exit(0);
184         }
185         c_tech = (char *)malloc(sizeof(char)*(strlen(argv[1])+20));
186         if (fscanf(fp, "%s", c_tech) != 1) {
187                 fprintf(stderr, "Metadata file - bad format\n");
188                 exit(0);
189         }
190         if (fscanf(fp, "%d", &tech) != 1) {
191                 fprintf(stderr, "Metadata file - bad format\n");
192                 exit(0);
193         }
194         method = tech;
195         if (fscanf(fp, "%d", &readins) != 1) {
196                 fprintf(stderr, "Metadata file - bad format\n");
197                 exit(0);
198         }
199         fclose(fp);     
200
201         /* Allocate memory */
202         erased = (int *)malloc(sizeof(int)*(k+m));
203         for (i = 0; i < k+m; i++)
204                 erased[i] = 0;
205         erasures = (int *)malloc(sizeof(int)*(k+m));
206
207         data = (char **)malloc(sizeof(char *)*k);
208         coding = (char **)malloc(sizeof(char *)*m);
209         if (buffersize != origsize) {
210                 for (i = 0; i < k; i++) {
211                         data[i] = (char *)malloc(sizeof(char)*(buffersize/k));
212                 }
213                 for (i = 0; i < m; i++) {
214                         coding[i] = (char *)malloc(sizeof(char)*(buffersize/k));
215                 }
216                 blocksize = buffersize/k;
217         }
218
219         sprintf(temp, "%d", k);
220         md = strlen(temp);
221         timing_set(&t3);
222
223         /* Create coding matrix or bitmatrix */
224         switch(tech) {
225                 case No_Coding:
226                         break;
227                 case Reed_Sol_Van:
228                         matrix = reed_sol_vandermonde_coding_matrix(k, m, w);
229                         break;
230                 case Reed_Sol_R6_Op:
231                         matrix = reed_sol_r6_coding_matrix(k, w);
232                         break;
233                 case Cauchy_Orig:
234                         matrix = cauchy_original_coding_matrix(k, m, w);
235                         bitmatrix = jerasure_matrix_to_bitmatrix(k, m, w, matrix);
236                         break;
237                 case Cauchy_Good:
238                         matrix = cauchy_good_general_coding_matrix(k, m, w);
239                         bitmatrix = jerasure_matrix_to_bitmatrix(k, m, w, matrix);
240                         break;
241                 case Liberation:
242                         bitmatrix = liberation_coding_bitmatrix(k, w);
243                         break;
244                 case Blaum_Roth:
245                         bitmatrix = blaum_roth_coding_bitmatrix(k, w);
246                         break;
247                 case Liber8tion:
248                         bitmatrix = liber8tion_coding_bitmatrix(k);
249         }
250         timing_set(&t4);
251         totalsec += timing_delta(&t3, &t4);
252         
253         /* Begin decoding process */
254         total = 0;
255         n = 1;  
256         while (n <= readins) {
257                 numerased = 0;
258                 /* Open files, check for erasures, read in data/coding */       
259                 for (i = 1; i <= k; i++) {
260                         sprintf(fname, "%s/Coding/%s_k%0*d%s", curdir, cs1, md, i, extension);
261                         fp = fopen(fname, "rb");
262                         if (fp == NULL) {
263                                 erased[i-1] = 1;
264                                 erasures[numerased] = i-1;
265                                 numerased++;
266                                 //printf("%s failed\n", fname);
267                         }
268                         else {
269                                 if (buffersize == origsize) {
270                                         stat(fname, &status);
271                                         blocksize = status.st_size;
272                                         data[i-1] = (char *)malloc(sizeof(char)*blocksize);
273                                         assert(blocksize == fread(data[i-1], sizeof(char), blocksize, fp));
274                                 }
275                                 else {
276                                         fseek(fp, blocksize*(n-1), SEEK_SET); 
277                                         assert(buffersize/k == fread(data[i-1], sizeof(char), buffersize/k, fp));
278                                 }
279                                 fclose(fp);
280                         }
281                 }
282                 for (i = 1; i <= m; i++) {
283                         sprintf(fname, "%s/Coding/%s_m%0*d%s", curdir, cs1, md, i, extension);
284                                 fp = fopen(fname, "rb");
285                         if (fp == NULL) {
286                                 erased[k+(i-1)] = 1;
287                                 erasures[numerased] = k+i-1;
288                                 numerased++;
289                                 //printf("%s failed\n", fname);
290                         }
291                         else {
292                                 if (buffersize == origsize) {
293                                         stat(fname, &status);
294                                         blocksize = status.st_size;
295                                         coding[i-1] = (char *)malloc(sizeof(char)*blocksize);
296                                         assert(blocksize == fread(coding[i-1], sizeof(char), blocksize, fp));
297                                 }
298                                 else {
299                                         fseek(fp, blocksize*(n-1), SEEK_SET);
300                                         assert(blocksize == fread(coding[i-1], sizeof(char), blocksize, fp));
301                                 }       
302                                 fclose(fp);
303                         }
304                 }
305                 /* Finish allocating data/coding if needed */
306                 if (n == 1) {
307                         for (i = 0; i < numerased; i++) {
308                                 if (erasures[i] < k) {
309                                         data[erasures[i]] = (char *)malloc(sizeof(char)*blocksize);
310                                 }
311                                 else {
312                                         coding[erasures[i]-k] = (char *)malloc(sizeof(char)*blocksize);
313                                 }
314                         }
315                 }
316                 
317                 erasures[numerased] = -1;
318                 timing_set(&t3);
319         
320                 /* Choose proper decoding method */
321                 if (tech == Reed_Sol_Van || tech == Reed_Sol_R6_Op) {
322                         i = jerasure_matrix_decode(k, m, w, matrix, 1, erasures, data, coding, blocksize);
323                 }
324                 else if (tech == Cauchy_Orig || tech == Cauchy_Good || tech == Liberation || tech == Blaum_Roth || tech == Liber8tion) {
325                         i = jerasure_schedule_decode_lazy(k, m, w, bitmatrix, erasures, data, coding, blocksize, packetsize, 1);
326                 }
327                 else {
328                         fprintf(stderr, "Not a valid coding technique.\n");
329                         exit(0);
330                 }
331                 timing_set(&t4);
332         
333                 /* Exit if decoding was unsuccessful */
334                 if (i == -1) {
335                         fprintf(stderr, "Unsuccessful!\n");
336                         exit(0);
337                 }
338         
339                 /* Create decoded file */
340                 sprintf(fname, "%s/Coding/%s_decoded%s", curdir, cs1, extension);
341                 if (n == 1) {
342                         fp = fopen(fname, "wb");
343                 }
344                 else {
345                         fp = fopen(fname, "ab");
346                 }
347                 for (i = 0; i < k; i++) {
348                         if (total+blocksize <= origsize) {
349                                 fwrite(data[i], sizeof(char), blocksize, fp);
350                                 total+= blocksize;
351                         }
352                         else {
353                                 for (j = 0; j < blocksize; j++) {
354                                         if (total < origsize) {
355                                                 fprintf(fp, "%c", data[i][j]);
356                                                 total++;
357                                         }
358                                         else {
359                                                 break;
360                                         }
361                                         
362                                 }
363                         }
364                 }
365                 n++;
366                 fclose(fp);
367                 totalsec += timing_delta(&t3, &t4);
368         }
369         
370         /* Free allocated memory */
371         free(cs1);
372         free(extension);
373         free(fname);
374         free(data);
375         free(coding);
376         free(erasures);
377         free(erased);
378         
379         /* Stop timing and print time */
380         timing_set(&t2);
381         tsec = timing_delta(&t1, &t2);
382         printf("Decoding (MB/sec): %0.10f\n", (((double) origsize)/1024.0/1024.0)/totalsec);
383         printf("De_Total (MB/sec): %0.10f\n\n", (((double) origsize)/1024.0/1024.0)/tsec);
384
385         return 0;
386 }       
387
388 void ctrl_bs_handler(int dummy) {
389         time_t mytime;
390         mytime = time(0);
391         fprintf(stderr, "\n%s\n", ctime(&mytime));
392         fprintf(stderr, "You just typed ctrl-\\ in decoder.c\n");
393         fprintf(stderr, "Total number of read ins = %d\n", readins);
394         fprintf(stderr, "Current read in: %d\n", n);
395         fprintf(stderr, "Method: %s\n\n", Methods[method]);
396         signal(SIGQUIT, ctrl_bs_handler);
397 }