0005b48cc27d44987d430c2ab70c7470385c2be6
[splitter-ng] / Splitter-ng-plugin-jigdfs / src / jigdfsplugin / CodecJigDFS.java
1 package jigdfsplugin;
2 import java.util.ArrayList;
3 import java.util.Arrays;
4 import java.util.Collections;
5 import java.util.HashMap;
6 import java.util.List;
7 import java.util.Map;
8 import java.util.Map.Entry;
9
10 import org.jigdfs.ida.base.InformationDispersalCodec;
11 import org.jigdfs.ida.base.InformationDispersalDecoder;
12 import org.jigdfs.ida.base.InformationDispersalEncoder;
13 import org.jigdfs.ida.cauchyreedsolomon.CauchyInformationDispersalCodec;
14 import org.jigdfs.ida.exception.IDADecodeException;
15 import org.jigdfs.ida.exception.IDAEncodeException;
16 import org.jigdfs.ida.exception.IDAInvalidParametersException;
17 import org.jigdfs.ida.exception.IDANotInitializedException;
18
19 import splitterng.plugin.CodecDescription;
20 import splitterng.plugin.interfaces.SplitterCodec;
21
22 public class CodecJigDFS implements SplitterCodec {
23         public final static String codecID = "JigDFScodec";
24         public final static String codecName = "JigDFS Codec";
25         public final static String codecDescriptionText = "Dieser Codec verwendet JigDFS";
26         public final static Map <String, Integer []> codecParameterMinMax;
27         static {
28                 // ParameterMinMax Map erstellen
29                 Map <String, Integer []> tmpMap = new HashMap<String, Integer[]>();
30                 tmpMap.put("k", new Integer[] {new Integer(1),new Integer(1)});
31                 tmpMap.put("m", new Integer[] {new Integer(1),new Integer(1)});
32                 tmpMap.put("packetsize", new Integer[] {new Integer(1),new Integer(4096)});
33                 // Weitere Parameter hier einfügen und deren Grenzen festlegen
34                 codecParameterMinMax  = Collections.unmodifiableMap(tmpMap);                            
35         }
36         // codecDescription bauen und statisch zur Verfügung stellen
37         private static final CodecDescription codecDescription = new CodecDescription(codecID, codecName, codecDescriptionText, codecParameterMinMax);
38         public static final CodecDescription getCodecDescription(){
39                 return CodecJigDFS.codecDescription;
40         }
41
42         private int k,m,packetsize;
43         private InformationDispersalCodec crsidacodec;
44         private InformationDispersalEncoder encoder;
45         private InformationDispersalDecoder decoder;
46         private byte [][] data_ptrs;
47         private byte [] data_ptrs_flat;
48         private List<byte[]> dataAndCoding_list;
49         private byte[][] dataAndCoding_ptrs;
50         private byte [] dataAndCoding_ptrs_flat;
51         
52         public CodecJigDFS(int k, int m) {
53                 //Simple Constructor for testing with SplitterPluginJigDFS/Main()
54                 Map<String, Integer> codecParameter = new HashMap<String, Integer>();
55                 codecParameter.put("k", k);
56                 codecParameter.put("m", m);
57 //              codecParameter.put("packetsize", 4096);
58                 codecParameter.put("packetsize", 64);
59                 init(codecParameter);
60         }
61         
62         public CodecJigDFS(Map<String, Integer> codecParameter) {
63                 init(codecParameter);
64         }
65         
66         private void init(Map<String, Integer> codecParameter) {
67                 // Test CodecParameter
68                 for (Entry<String, Integer[]> requiredEntry : CodecJigDFS.codecParameterMinMax
69                                 .entrySet()) {
70                         if (codecParameter.containsKey(requiredEntry.getKey())) {
71                                 // Test ob Parameter vorhanden und in den gültigen grenzen liegen
72                                 if (codecParameter.get(requiredEntry.getKey()) < requiredEntry
73                                                 .getValue()[0])
74                                         new IllegalArgumentException(
75                                                         "unzulässiger Wert für Parameter: "
76                                                                         + requiredEntry.getKey() + " < "
77                                                                         + requiredEntry.getValue()[0]);
78                                 if (codecParameter.get(requiredEntry.getKey()) > requiredEntry
79                                                 .getValue()[1])
80                                         new IllegalArgumentException(
81                                                         "unzulässiger Wert für Parameter: "
82                                                                         + requiredEntry.getKey() + " > "
83                                                                         + requiredEntry.getValue()[1]);
84                         } else {
85                                 throw new IllegalArgumentException("Missing Codec Parameter: "
86                                                 + requiredEntry.getKey());
87                         }
88                         k = (int) codecParameter.get("k");
89                         m = (int) codecParameter.get("m");
90                         packetsize = (int) codecParameter.get("packetsize");
91                         
92                         try {
93                                 crsidacodec = new CauchyInformationDispersalCodec(k+m, m, packetsize);
94                                 encoder = crsidacodec.getEncoder();
95                                 decoder = crsidacodec.getDecoder();
96                         } catch (IDAInvalidParametersException e) {
97                                 throw new IllegalArgumentException("JigDFS IDAInvalidParametersException: \n"+e.toString());
98                         } catch (IDANotInitializedException e) {
99                                 throw new IllegalArgumentException("JigDFS IDANotInitializedException: \n"+e.toString());
100                         }
101                 }
102         }
103
104         @Override
105         public byte[][] encode(byte[][] data_ptrs){
106                 int fragmentsize = data_ptrs[0].length;
107                 checkArraySizes(fragmentsize);
108                 //Fill into flat data parts
109                 for (int i=0; i<k ; i++){
110                         System.arraycopy(data_ptrs[i],0,data_ptrs_flat,i * fragmentsize, fragmentsize);
111                 }
112                 try {
113                         dataAndCoding_list = encoder.process(data_ptrs_flat);
114                 } catch (IDAEncodeException e) {
115                         throw new IllegalArgumentException("JigDFS IDAEncodeException: \n"+e.toString());
116                 } catch (IDANotInitializedException e) {
117                         throw new IllegalArgumentException("JigDFS IDANotInitializedException: \n"+e.toString());
118                 }
119                 dataAndCoding_ptrs = new byte[k+m][];
120                 int i = 0;
121                 for (byte[] part : dataAndCoding_list){
122                         dataAndCoding_ptrs[i++]=part;
123                 }
124                 return dataAndCoding_ptrs;
125         }
126
127         @Override
128         public byte[][] decode(byte[][] dataAndCoding_ptrs, boolean [] erased){
129                 
130                 dataAndCoding_list = new ArrayList <byte[]> (Arrays.asList(dataAndCoding_ptrs));
131                 for (int i=0; i<erased.length; i++){
132                         //JigDFS needs null pointer for missing fragments
133                         if (erased[i]) {
134                                 dataAndCoding_list.set(i, null);
135                         }
136                 }
137                 
138                 //Test reuse or create new
139                 int fragmentsize = dataAndCoding_ptrs[0].length;
140                 if (data_ptrs_flat == null || (data_ptrs_flat.length != k * fragmentsize)){
141                         data_ptrs_flat = new byte[k * fragmentsize];
142                 }
143                         
144                 try {
145                         data_ptrs_flat = decoder.process(dataAndCoding_list);
146                 } catch (IDANotInitializedException e) {
147                         throw new IllegalArgumentException("JigDFS IDANotInitializedException: \n"+e.toString());
148                 } catch (IDADecodeException e) {
149                         throw new IllegalArgumentException("JigDFS IDADecodeException: \n"+e.toString());
150                 }
151                 
152                 fragmentsize = data_ptrs_flat.length/k;
153                 if (data_ptrs == null || (data_ptrs.length != k) || (data_ptrs[0].length != fragmentsize)){
154                         data_ptrs = new byte[k][fragmentsize];
155                 }                       
156
157                 for (int i = 0; i<k ; i++){
158                         System.arraycopy(data_ptrs_flat, i*(fragmentsize), data_ptrs[i], 0, fragmentsize);
159                 }
160                 
161                 return data_ptrs;
162                 
163         }
164         
165         private void checkArraySizes(int fragmentsize) {
166                 
167                 if (data_ptrs == null || (data_ptrs.length != k) || (data_ptrs[0].length != fragmentsize)){
168                         data_ptrs = new byte[k][fragmentsize];
169                 }                       
170                 
171                 //Test reuse or create new
172                 if (data_ptrs_flat == null || (data_ptrs_flat.length != k * fragmentsize)){
173                         data_ptrs_flat = new byte[k * fragmentsize];
174                 }
175                 
176                 if (dataAndCoding_ptrs == null || (dataAndCoding_ptrs.length != k+m) || (dataAndCoding_ptrs[0].length != fragmentsize)){
177                         dataAndCoding_ptrs = new byte[k+m][fragmentsize];
178                 }
179                 if (dataAndCoding_ptrs_flat == null || (dataAndCoding_ptrs_flat.length != fragmentsize)){
180                         dataAndCoding_ptrs_flat = new byte[(k+m) * fragmentsize];
181                 }
182                 
183 //              if (coding_ptrs_flat == null || (coding_ptrs_flat.length != m * fragmentsize)){
184 //                      coding_ptrs_flat = new byte[m * fragmentsize];
185 //              }
186 //              
187 //              if (coding_ptrs == null || (coding_ptrs.length != m ) || (coding_ptrs[0].length != fragmentsize)){
188 //                      coding_ptrs = new byte[m][fragmentsize];
189 //              }
190 //              
191         }
192                 
193
194 }