Add jigdfs plugin. Still not working.
authorMaximilian Quellmalz <maximilian.quellmalz@mailbox.tu-dresden.de>
Fri, 6 Jun 2014 13:37:25 +0000 (15:37 +0200)
committerMaximilian Quellmalz <maximilian.quellmalz@mailbox.tu-dresden.de>
Fri, 6 Jun 2014 13:37:25 +0000 (15:37 +0200)
76 files changed:
Splitter-ng-plugin-jerasure-purejava/.classpath
Splitter-ng-plugin-jerasure-purejava/build.xml
Splitter-ng-plugin-jerasure-purejava/src/hpijerasureplugin/JavaCRS.java
Splitter-ng-plugin-jigdfs/.classpath [new file with mode: 0644]
Splitter-ng-plugin-jigdfs/.gitignore [new file with mode: 0644]
Splitter-ng-plugin-jigdfs/.project [new file with mode: 0644]
Splitter-ng-plugin-jigdfs/.settings/org.eclipse.jdt.core.prefs [new file with mode: 0644]
Splitter-ng-plugin-jigdfs/build.xml [new file with mode: 0644]
Splitter-ng-plugin-jigdfs/lib/bcprov-jdk16-141.jar [new file with mode: 0644]
Splitter-ng-plugin-jigdfs/lib/jxta.jar [new file with mode: 0644]
Splitter-ng-plugin-jigdfs/lib/log4j-1.2.15.jar [new file with mode: 0644]
Splitter-ng-plugin-jigdfs/src/jigdfsplugin/CodecJigDFS.java [new file with mode: 0644]
Splitter-ng-plugin-jigdfs/src/jigdfsplugin/SplitterPluginJigDFS.java [new file with mode: 0644]
Splitter-ng-plugin-jigdfs/src/jigdfsplugin/package-info.java [new file with mode: 0644]
Splitter-ng-plugin-jigdfs/src/log4j.properties [new file with mode: 0644]
Splitter-ng-plugin-jigdfs/src/org/jigdfs/baseClass/ResponseMsg.java [new file with mode: 0644]
Splitter-ng-plugin-jigdfs/src/org/jigdfs/baseInterface/Listenable.java [new file with mode: 0644]
Splitter-ng-plugin-jigdfs/src/org/jigdfs/baseInterface/Listener.java [new file with mode: 0644]
Splitter-ng-plugin-jigdfs/src/org/jigdfs/baseInterface/Plugin.java [new file with mode: 0644]
Splitter-ng-plugin-jigdfs/src/org/jigdfs/baseInterface/Pluginable.java [new file with mode: 0644]
Splitter-ng-plugin-jigdfs/src/org/jigdfs/exception/BaseException.java [new file with mode: 0644]
Splitter-ng-plugin-jigdfs/src/org/jigdfs/exception/NotImplementedException.java [new file with mode: 0644]
Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/base/InformationDispersalCodec.java [new file with mode: 0644]
Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/base/InformationDispersalCodecBase.java [new file with mode: 0644]
Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/base/InformationDispersalDecoder.java [new file with mode: 0644]
Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/base/InformationDispersalEncoder.java [new file with mode: 0644]
Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/cauchyreedsolomon/CauchyDecode.java [new file with mode: 0644]
Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/cauchyreedsolomon/CauchyEncode.java [new file with mode: 0644]
Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/cauchyreedsolomon/CauchyIDAParameters.java [new file with mode: 0644]
Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/cauchyreedsolomon/CauchyInformationDispersalCodec.java [new file with mode: 0644]
Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/cauchyreedsolomon/CauchyInformationDispersalDecoder.java [new file with mode: 0644]
Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/cauchyreedsolomon/CauchyInformationDispersalEncoder.java [new file with mode: 0644]
Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/cauchyreedsolomon/FiniteStack.java [new file with mode: 0644]
Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/cauchyreedsolomon/InitField.java [new file with mode: 0644]
Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/exception/IDADecodeException.java [new file with mode: 0644]
Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/exception/IDAEncodeException.java [new file with mode: 0644]
Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/exception/IDAException.java [new file with mode: 0644]
Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/exception/IDAInvalidParametersException.java [new file with mode: 0644]
Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/exception/IDAInvalidSliceCountException.java [new file with mode: 0644]
Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/exception/IDAInvalidSliceFormatException.java [new file with mode: 0644]
Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/exception/IDAInvalidSliceLengthException.java [new file with mode: 0644]
Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/exception/IDANotInitializedException.java [new file with mode: 0644]
Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/test/CRSBinaryFileDecodeTestClass.java [new file with mode: 0644]
Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/test/CRSBinaryFileEncodeTestClass.java [new file with mode: 0644]
Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/test/CRSStringTestClass.java [new file with mode: 0644]
Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/test/CRSTextFileTestClass.java [new file with mode: 0644]
Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/test/OriginalCRSTestClass.java [new file with mode: 0644]
Splitter-ng-plugin-jigdfs/src/org/jigdfs/jxta/core/JigDFSJXTANetworkManager.java [new file with mode: 0644]
Splitter-ng-plugin-jigdfs/src/org/jigdfs/jxta/core/JigDFSPeerGroupFactory.java [new file with mode: 0644]
Splitter-ng-plugin-jigdfs/src/org/jigdfs/jxta/core/JigDFSPeerNode.java [new file with mode: 0644]
Splitter-ng-plugin-jigdfs/src/org/jigdfs/jxta/exception/JXTAAlreadyInitializedException.java [new file with mode: 0644]
Splitter-ng-plugin-jigdfs/src/org/jigdfs/jxta/exception/JXTAException.java [new file with mode: 0644]
Splitter-ng-plugin-jigdfs/src/org/jigdfs/jxta/exception/JXTAInvalidParametersException.java [new file with mode: 0644]
Splitter-ng-plugin-jigdfs/src/org/jigdfs/jxta/exception/JXTANotInitializedException.java [new file with mode: 0644]
Splitter-ng-plugin-jigdfs/src/org/jigdfs/jxta/service/PeerGroupSearchService.java [new file with mode: 0644]
Splitter-ng-plugin-jigdfs/src/org/jigdfs/jxta/test/CreatePeerGroup.java [new file with mode: 0644]
Splitter-ng-plugin-jigdfs/src/org/jigdfs/jxta/test/PeerGroupSearchTest.java [new file with mode: 0644]
Splitter-ng-plugin-jigdfs/src/org/jigdfs/jxta/test/PeerGroupTest.java [new file with mode: 0644]
Splitter-ng-plugin-jigdfs/src/org/jigdfs/jxta/test/PeerTest.java [new file with mode: 0644]
Splitter-ng-plugin-jigdfs/src/org/jigdfs/jxta/utils/JXTAIDFactory.java [new file with mode: 0644]
Splitter-ng-plugin-jigdfs/src/org/jigdfs/jxta/utils/PeerGroupUtil.java [new file with mode: 0644]
Splitter-ng-plugin-jigdfs/src/org/jigdfs/jxta/utils/PeerNodeConfigurator.java [new file with mode: 0644]
Splitter-ng-plugin-jigdfs/src/org/jigdfs/jxta/utils/StdPeerGroupParamAdv.java [new file with mode: 0644]
Splitter-ng-plugin-jigdfs/src/org/jigdfs/jxta/wrapper/ServiceThreadedWrapper.java [new file with mode: 0644]
Splitter-ng-plugin-jigdfs/src/org/jigdfs/references/ida/originalcrs/CauchyDecode.java [new file with mode: 0644]
Splitter-ng-plugin-jigdfs/src/org/jigdfs/references/ida/originalcrs/CauchyEncode.java [new file with mode: 0644]
Splitter-ng-plugin-jigdfs/src/org/jigdfs/references/ida/originalcrs/FiniteStack.java [new file with mode: 0644]
Splitter-ng-plugin-jigdfs/src/org/jigdfs/references/ida/originalcrs/InitField.java [new file with mode: 0644]
Splitter-ng-plugin-jigdfs/src/org/jigdfs/references/ida/originalcrs/NativeIF.java [new file with mode: 0644]
Splitter-ng-plugin-jigdfs/src/org/jigdfs/references/ida/originalcrs/Parameters.java [new file with mode: 0644]
Splitter-ng-plugin-jigdfs/src/org/jigdfs/serivce/Service.java [new file with mode: 0644]
Splitter-ng-plugin-jigdfs/src/org/jigdfs/serivce/ServiceEvent.java [new file with mode: 0644]
Splitter-ng-plugin-jigdfs/src/org/jigdfs/serivce/ServiceListener.java [new file with mode: 0644]
Splitter-ng-plugin-jigdfs/src/org/jigdfs/serivce/ServiceResponseMsg.java [new file with mode: 0644]
Splitter-ng-test/src/SplitterTest.java
build.xml

index 6a2fd3e..4ac0014 100644 (file)
@@ -7,8 +7,8 @@
                        <attribute name="org.eclipse.jdt.launching.CLASSPATH_ATTR_LIBRARY_PATH_ENTRY" value="Splitter-ng-plugin-jerasure/lib"/>
                </attributes>
        </classpathentry>
-       <classpathentry combineaccessrules="false" exported="true" kind="src" path="/Splitter-ng"/>
        <classpathentry kind="lib" path="lib/guava-13.0.1.jar"/>
        <classpathentry kind="lib" path="lib/junit-4.4.jar"/>
+       <classpathentry combineaccessrules="false" kind="src" path="/Splitter-ng"/>
        <classpathentry kind="output" path="bin"/>
 </classpath>
index b1e567e..c98fb87 100644 (file)
@@ -71,7 +71,8 @@
     <target name ="makejar" depends="build" description="Create a jar for the project">
          <jar jarfile="bin/${ant.project.name}.jar" >
            <fileset dir="bin" includes="**/*.class" />
-           <fileset dir="lib" includes="**/*.jar" />
+               <!-- jar files not used. it also works without including them  -->
+           <!-- fileset dir="lib" includes="**/*.jar" /  -->
          </jar>
     </target>
        <target name="dist" depends="makejar" description="Create a distribution Directory wirth splitter-ng and all Plugins">
index 6eb9ddd..0bab5d3 100644 (file)
@@ -14,6 +14,10 @@ import de.uni_postdam.hpi.matrix.BitMatrix;
 import de.uni_postdam.hpi.matrix.Matrix;
 import de.uni_postdam.hpi.matrix.Schedule;
 
+/**
+ * @author max
+ *
+ */
 public class JavaCRS implements SplitterCodec {
 
        public final static String codecID = "JerasureJavaCRS";
@@ -44,14 +48,21 @@ public class JavaCRS implements SplitterCodec {
        private Matrix matrix;
        private BitMatrix bitmatrix;
        private Schedule[] schedules;
-       private byte[] coding_ptrs_flat;
-       private byte[][] data_ptrs;
-       private byte[]   data_ptrs_flat;
-       private byte[][] dataAndCoding_ptrs;
+       private byte[][]  coding_ptrs;
+       private byte[]    coding_ptrs_flat;
+       private byte[][]  data_ptrs;
+       private byte[]    data_ptrs_flat;
+       private byte[][]  dataAndCoding_ptrs;
+
  
        private boolean[] erasures;
        private int numerased=0;
+       private int[] row_to_device_id;
+       private int[] device_id_to_row;
+       private int codingFailed;
+       private int dataFailed;
 
+       
        
        public static final CodecDescription getCodecDescription(){
                //System.out.println("JerasureCodecParity: getCodecDescription: "+JerasureCodecParity.codecDescription);
@@ -93,44 +104,62 @@ public class JavaCRS implements SplitterCodec {
                packetsize=(int)codecParameter.get("packetsize");
                matrix= Cauchy.good_general_coding_matrix(k, m, w);
                bitmatrix = new BitMatrix(matrix, w);
-               this.schedules = bitmatrix.toSchedules(k, w);
                erasures = new boolean[k + m];
                
        }
 
-       @Override
-       public byte[][] decode(byte[][] dataAndCoding_ptrs, boolean [] erased){
-               //TODO Array Testen ob zulässig? eventuell nicht, da es hier bremsen könnte
-               int fragmentsize = dataAndCoding_ptrs[0].length;
-               /*
+       private void checkArraySizes(int fragmentsize) {
+               
                if (data_ptrs == null || (data_ptrs.length != k) || (data_ptrs[0].length != fragmentsize)){
                        data_ptrs = new byte[k][fragmentsize];
                }                       
                
-               if (coding_ptrs_flat == null || (coding_ptrs_flat.length != m) || (coding_ptrs_flat[0].length != fragmentsize)){
-                       coding_ptrs_flat = new byte[m][fragmentsize];
+               //Test reuse or create new
+               if (data_ptrs_flat == null || (data_ptrs_flat.length != k * fragmentsize)){
+                       data_ptrs_flat = new byte[k * fragmentsize];
                }
                
-               for (int i=0; i<k ; i++){
-                       data_ptrs[i]=dataAndCoding_ptrs[i];
+               
+               if (coding_ptrs_flat == null || (coding_ptrs_flat.length != m * fragmentsize)){
+                       coding_ptrs_flat = new byte[m * fragmentsize];
                }
-               for (int i=k; i<k+m ; i++){
-                       coding_ptrs_flat[i-k]=dataAndCoding_ptrs[i];
+               
+               if (coding_ptrs == null || (coding_ptrs.length != m ) || (coding_ptrs[0].length != fragmentsize)){
+                       coding_ptrs = new byte[m][fragmentsize];
                }
                
-               //Preparing Erasures
-               numerased=0;
-               for (int i=0; i<m+k; i++){
-                       if (erased[i]==true){
-                               erasures[numerased]=i;
-                               numerased++;
-                       }
+               if (dataAndCoding_ptrs == null || (dataAndCoding_ptrs.length != k+m) || (dataAndCoding_ptrs[0].length != fragmentsize)){
+                       dataAndCoding_ptrs = new byte[k+m][fragmentsize];
                }
-               erasures[numerased]=-1;
                
+       }
 
-               Jerasure.jerasure_bitmatrix_decode(k, m, w, bitmatrix, false, erasures, data_ptrs, coding_ptrs_flat, fragmentsize, packetsize);
-               */
+       @Override
+       public byte[][] decode(byte[][] dataAndCoding_ptrs, boolean [] erased){
+               //TODO Array Testen ob zulässig? eventuell nicht, da es hier bremsen könnte
+               int fragmentsize = dataAndCoding_ptrs[0].length;
+               
+               checkArraySizes(fragmentsize);
+               
+               //Fill into flat data parts
+               for (int i=0; i<k ; i++){
+                       System.arraycopy(dataAndCoding_ptrs[i],0,data_ptrs_flat,i * fragmentsize, fragmentsize);
+               }
+               //Fill into flat coding parts
+               for (int i=k; i<k+m ; i++){
+                       System.arraycopy(dataAndCoding_ptrs[i],0,coding_ptrs_flat,(i-k) * fragmentsize, fragmentsize);
+               }
+               
+               
+               this.erasures=erased;
+               BitMatrix decMatrix = this.generate_decoding_bitmatrix();
+               schedules = decMatrix.toSchedules(k, w);
+               data_ptrs_flat = Schedule.do_scheduled_operations(data_ptrs_flat, coding_ptrs_flat, schedules, packetsize, w);
+               //Data to Array
+               
+               for (int i = 0; i < k ; i++) {
+                       System.arraycopy(data_ptrs_flat, i * fragmentsize, data_ptrs[i], 0, fragmentsize);
+               }
                return data_ptrs;
        }
 
@@ -140,36 +169,123 @@ public class JavaCRS implements SplitterCodec {
                // buffersize%(sizeof(int)*w*k) == 0
                int fragmentsize = data_ptrs[0].length;
                
-               //Test reuse or create new
-               if (data_ptrs_flat == null || (data_ptrs_flat.length != k * fragmentsize)){
-                       data_ptrs_flat = new byte[k * fragmentsize];
-               }
+               checkArraySizes(fragmentsize);
+               
                //Fill into flat array
                for (int i=0; i<k ; i++) {
                        System.arraycopy(data_ptrs[i], 0, data_ptrs_flat, i * fragmentsize, fragmentsize);
                }
                
-               if (coding_ptrs_flat == null || (coding_ptrs_flat.length != m * fragmentsize)){
-                       coding_ptrs_flat = new byte[m * fragmentsize];
-               }
+               
                
                //coding_ptrs_flat = CodingUtils.enOrDecode(data_ptrs_flat, schedules, k, m, w, packetsize);
+               this.schedules = bitmatrix.toSchedules(k, w);
                coding_ptrs_flat = Schedule.do_scheduled_operations(data_ptrs_flat, coding_ptrs_flat, schedules, packetsize, w);
                
-               if (dataAndCoding_ptrs == null || (dataAndCoding_ptrs.length != k+m) || (dataAndCoding_ptrs[0].length != fragmentsize)){
-                       dataAndCoding_ptrs = new byte[k+m][fragmentsize];
-               }
-               //Data Blocks
+               
+               
+               //Fill into Array: Data Blocks
                for (int i=0; i<k ; i++){
                        dataAndCoding_ptrs[i]=data_ptrs[i];
                }
+               //Fill into Array: Coding Blocks
                for (int i=k; i<k+m ; i++){
-                       System.arraycopy(data_ptrs_flat, (i-k) * fragmentsize, dataAndCoding_ptrs[i], 0, fragmentsize);
+                       System.arraycopy(coding_ptrs_flat, (i-k) * fragmentsize, dataAndCoding_ptrs[i], 0, fragmentsize);
 
                }
                                
                return dataAndCoding_ptrs;
        }
 
+       public BitMatrix generate_decoding_bitmatrix() {
+
+               //updateErasures(); //wird nicht gebraucht, wurden an decode übergeben
+               update_erased_ids();
+
+               BitMatrix encodingMatrix = new BitMatrix(Cauchy.good_general_coding_matrix(k, m, w), w);
+               BitMatrix result = new BitMatrix(k, codingFailed + dataFailed, w);
 
+               if (dataFailed > 0) {
+                       BitMatrix decoding_matrix = new BitMatrix(k, k, w);
+                       decoding_matrix.toIdentity();
+                       for (int dataDeviceId = 0; dataDeviceId < k; dataDeviceId++) {
+                               if (!deviceOK(dataDeviceId)) {
+                                       decoding_matrix.copyRows(dataDeviceId * w, encodingMatrix,
+                                                       row_to_coding_id(dataDeviceId) * w, w);
+                               }
+                       }
+
+                       BitMatrix inverse = decoding_matrix.invert(w);
+
+                       for (int deviceId = 0; deviceId < dataFailed; deviceId++) {
+                               result.copyRows(deviceId * w, inverse,
+                                               row_to_device_id[deviceId + k] * w, w);
+                       }
+               }
+
+               for (int x = dataFailed; x < codingFailed + dataFailed; x++) {
+                       int codingId = row_to_coding_id(x + k);
+                       int currRow = x * w;
+                       result.copyRows(currRow, encodingMatrix, codingId * w, w);
+
+                       for (int dataDeviceId = 0; dataDeviceId < k; dataDeviceId++) {
+                               if (!deviceOK(dataDeviceId)) {
+                                       result.zero(dataDeviceId * w, currRow, w, w);
+                               }
+                       }
+
+                        //There's the yucky part 
+                       for (int dataId = 0; dataId < k; dataId++) {
+                               if (deviceOK(dataId)) {
+                                       continue;
+                               }
+                               result.do_yucky_decoding_stuff(encodingMatrix, currRow,
+                                               device_id_to_row[dataId] - k, dataId, codingId);
+                       }
+               }
+
+               return result;
+       }
+       private void update_erased_ids() {
+               row_to_device_id = new int[k + m];
+               device_id_to_row = new int[k + m];
+               codingFailed = 0;
+               dataFailed = 0;
+
+               int j = k, x = k;
+               for (int i = 0; i < k; i++) {
+                       if (!erasures[i]) {
+                               row_to_device_id[i] = i;
+                               device_id_to_row[i] = i;
+                       } else {
+                               while (erasures[j]) {
+                                       if (++j == erasures.length) {
+                                               throw new RuntimeException(
+                                                               "Not enough redundant parts!");
+                                       }
+                               }
+                               dataFailed++;
+                               row_to_device_id[i] = j;
+                               device_id_to_row[j] = i;
+                               j++;
+                               device_id_to_row[i] = x;
+                               row_to_device_id[x] = i;
+                               x++;
+                       }
+               }
+               for (int i = k; i < k + m; i++) {
+                       if (erasures[i]) {
+                               codingFailed++;
+                               row_to_device_id[x] = i;
+                               device_id_to_row[i] = x;
+                               x++;
+                       }
+               }
+       }
+       private int row_to_coding_id(int i) {
+               return row_to_device_id[i] - k;
+       }
+       private boolean deviceOK(int i) {
+               return row_to_device_id[i] == i;
+       }
 }
\ No newline at end of file
diff --git a/Splitter-ng-plugin-jigdfs/.classpath b/Splitter-ng-plugin-jigdfs/.classpath
new file mode 100644 (file)
index 0000000..93d7f1e
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+       <classpathentry kind="src" path="src"/>
+       <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
+       <classpathentry combineaccessrules="false" exported="true" kind="src" path="/Splitter-ng"/>
+       <classpathentry kind="output" path="bin"/>
+       <classpathentry kind="lib" path="lib/bcprov-jdk16-141.jar"/>
+       <classpathentry kind="lib" path="lib/log4j-1.2.15.jar"/>
+       <classpathentry kind="lib" path="lib/jxta.jar"/>
+</classpath>
diff --git a/Splitter-ng-plugin-jigdfs/.gitignore b/Splitter-ng-plugin-jigdfs/.gitignore
new file mode 100644 (file)
index 0000000..5e56e04
--- /dev/null
@@ -0,0 +1 @@
+/bin
diff --git a/Splitter-ng-plugin-jigdfs/.project b/Splitter-ng-plugin-jigdfs/.project
new file mode 100644 (file)
index 0000000..b001edd
--- /dev/null
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+       <name>Splitter-ng-plugin-jigdfs</name>
+       <comment></comment>
+       <projects>
+       </projects>
+       <buildSpec>
+               <buildCommand>
+                       <name>org.eclipse.jdt.core.javabuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+       </buildSpec>
+       <natures>
+               <nature>org.eclipse.jdt.core.javanature</nature>
+       </natures>
+</projectDescription>
diff --git a/Splitter-ng-plugin-jigdfs/.settings/org.eclipse.jdt.core.prefs b/Splitter-ng-plugin-jigdfs/.settings/org.eclipse.jdt.core.prefs
new file mode 100644 (file)
index 0000000..7341ab1
--- /dev/null
@@ -0,0 +1,11 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.7
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.7
diff --git a/Splitter-ng-plugin-jigdfs/build.xml b/Splitter-ng-plugin-jigdfs/build.xml
new file mode 100644 (file)
index 0000000..98c39b5
--- /dev/null
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<project basedir="." default="makejar" name="Splitter-ng-plugin-jigdfs">
+       <property environment="env" />
+       <property name="Splitter-ng.location" value="../Splitter-ng" />
+       <property name="debuglevel" value="source,lines,vars" />
+       <property name="target" value="1.7" />
+       <property name="source" value="1.7" />
+       <path id="Splitter-ng.classpath">
+               <pathelement location="${Splitter-ng.location}/bin" />
+       </path>
+       <path id="library.Project">
+               <fileset dir="lib/">
+                       <include name="**/*.jar"/>
+               </fileset>
+       </path>
+       <manifestclasspath property="lib.list" jarfile=".">
+       <classpath refid="library.Project" />
+       </manifestclasspath>
+       
+       <path id="Splitter-ng-plugin-jigdfs.classpath">
+               <pathelement location="bin" />
+               <pathelement location="lib" />
+               <fileset dir="lib">
+                       <include name="*.jar"/>
+               </fileset>
+               <pathelement location="." />
+               <path refid="Splitter-ng.classpath" />
+       </path>
+       <target name="init">
+               <mkdir dir="bin" />
+               <copy includeemptydirs="false" todir="bin">
+                       <fileset dir="src">
+                               <exclude name="**/*.uad" />
+                               <exclude name="**/*.ucd" />
+                               <exclude name="**/*.uld" />
+                               <exclude name="**/*.upd" />
+                               <exclude name="**/*.udd" />
+                               <exclude name="**/*.uod" />
+                               <exclude name="**/*.usd" />
+                               <exclude name="**/*.utd" />
+                               <exclude name="**/*.uud" />
+                               <exclude name="**/*.odd" />
+                               <exclude name="**/*.ead" />
+                               <exclude name="**/*.ecd" />
+                               <exclude name="**/*.eld" />
+                               <exclude name="**/*.epd" />
+                               <exclude name="**/*.edd" />
+                               <exclude name="**/*.eod" />
+                               <exclude name="**/*.esd" />
+                               <exclude name="**/*.etd" />
+                               <exclude name="**/*.eud" />
+                               <exclude name="**/*.urd" />
+                               <exclude name="**/*.uml" />
+                               <exclude name="**/*.ecore" />
+                               <exclude name="**/*.ucls" />
+                               <exclude name="**/*.useq" />
+                               <exclude name="**/*.java" />
+                       </fileset>
+               </copy>
+       </target>
+       <target name="clean">
+               <delete dir="bin" />
+       </target>
+       <target depends="clean" name="cleanall">
+               <ant antfile="build.xml" dir="${Splitter-ng.location}" inheritAll="false" target="clean" />
+       </target>
+       <target depends="build-subprojects,build-project" name="build" />
+       <target name="build-subprojects">
+               <ant antfile="build.xml" dir="${Splitter-ng.location}" inheritAll="false" target="build-project" />
+       </target>
+       <target depends="init" name="build-project">
+               <echo message="${ant.project.name}: ${ant.file}" />
+               <javac debug="true" debuglevel="${debuglevel}" destdir="bin" includeantruntime="false" source="${source}" target="${target}">
+                       <src path="src" />
+                       <classpath refid="Splitter-ng-plugin-jigdfs.classpath" />
+               </javac>
+       </target>
+       <target description="Build all projects which reference this project. Useful to propagate changes." name="build-refprojects" />
+       <target name="makejar" depends="build" description="Create a jar for the project">
+               <jar jarfile="bin/${ant.project.name}.jar" filesetmanifest="merge">
+                       <fileset dir="bin" includes="**/*.class" />
+                       <fileset dir="lib" includes="**/*.class" />
+                       <zipgroupfileset dir="lib" includes="*.jar" />
+                       <!--fileset dir="lib" includes="**/*.jar" /-->
+                       <manifest>
+                               <attribute name="Class-Path" value="${lib.list}"/>
+                       </manifest>
+               </jar>
+       </target>
+       <target name="dist" depends="makejar" description="Create a distribution Directory wirth splitter-ng and all Plugins">
+               <mkdir dir="../dist" />
+               <mkdir dir="../dist/plugin" />
+               <copy file="bin/${ant.project.name}.jar" todir="../dist/plugin/" />
+       </target>
+</project>
diff --git a/Splitter-ng-plugin-jigdfs/lib/bcprov-jdk16-141.jar b/Splitter-ng-plugin-jigdfs/lib/bcprov-jdk16-141.jar
new file mode 100644 (file)
index 0000000..f8aa8ce
Binary files /dev/null and b/Splitter-ng-plugin-jigdfs/lib/bcprov-jdk16-141.jar differ
diff --git a/Splitter-ng-plugin-jigdfs/lib/jxta.jar b/Splitter-ng-plugin-jigdfs/lib/jxta.jar
new file mode 100644 (file)
index 0000000..0a9ded5
Binary files /dev/null and b/Splitter-ng-plugin-jigdfs/lib/jxta.jar differ
diff --git a/Splitter-ng-plugin-jigdfs/lib/log4j-1.2.15.jar b/Splitter-ng-plugin-jigdfs/lib/log4j-1.2.15.jar
new file mode 100644 (file)
index 0000000..c930a6a
Binary files /dev/null and b/Splitter-ng-plugin-jigdfs/lib/log4j-1.2.15.jar differ
diff --git a/Splitter-ng-plugin-jigdfs/src/jigdfsplugin/CodecJigDFS.java b/Splitter-ng-plugin-jigdfs/src/jigdfsplugin/CodecJigDFS.java
new file mode 100644 (file)
index 0000000..7e7877e
--- /dev/null
@@ -0,0 +1,143 @@
+package jigdfsplugin;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.jigdfs.ida.base.InformationDispersalCodec;
+import org.jigdfs.ida.base.InformationDispersalDecoder;
+import org.jigdfs.ida.base.InformationDispersalEncoder;
+import org.jigdfs.ida.cauchyreedsolomon.CauchyInformationDispersalCodec;
+import org.jigdfs.ida.exception.IDAEncodeException;
+import org.jigdfs.ida.exception.IDAInvalidParametersException;
+import org.jigdfs.ida.exception.IDANotInitializedException;
+
+import splitterng.plugin.CodecDescription;
+import splitterng.plugin.interfaces.SplitterCodec;
+
+public class CodecJigDFS implements SplitterCodec {
+       public final static String codecID = "JigDFScodec";
+       public final static String codecName = "JigDFS Codec";
+       public final static String codecDescriptionText = "Dieser Codec verwendet JigDFS";
+       public final static Map <String, Integer []> codecParameterMinMax;
+       static {
+               // ParameterMinMax Map erstellen
+               Map <String, Integer []> tmpMap = new HashMap<String, Integer[]>();
+               tmpMap.put("k", new Integer[] {new Integer(1),new Integer(1)});
+               tmpMap.put("m", new Integer[] {new Integer(1),new Integer(1)});
+               tmpMap.put("packetsize", new Integer[] {new Integer(1),new Integer(1)});
+               // Weitere Parameter hier einfügen und deren Grenzen festlegen
+               codecParameterMinMax  = Collections.unmodifiableMap(tmpMap);                            
+       }
+       // codecDescription bauen und statisch zur Verfügung stellen
+       private static final CodecDescription codecDescription = new CodecDescription(codecID, codecName, codecDescriptionText, codecParameterMinMax);
+       public static final CodecDescription getCodecDescription(){
+               return CodecJigDFS.codecDescription;
+       }
+
+       private int k,m,packetsize;
+       private InformationDispersalCodec crsidacodec;
+       private InformationDispersalEncoder encoder;
+       private InformationDispersalDecoder decoder;
+       private byte [][] data_ptrs;
+       private byte [] data_ptrs_flat;
+       private List<byte[]> dataAndCoding_list;
+       private byte[][] dataAndCoding_ptrs;
+       
+       public CodecJigDFS(Map<String, Integer> codecParameter) {
+               
+               // Test CodecParameter
+               for (Entry<String, Integer[]> requiredEntry : CodecJigDFS.codecParameterMinMax
+                               .entrySet()) {
+                       if (codecParameter.containsKey(requiredEntry.getKey())) {
+                               // Test ob Parameter vorhanden und in den gültigen grenzen liegen
+                               if (codecParameter.get(requiredEntry.getKey()) < requiredEntry
+                                               .getValue()[0])
+                                       new IllegalArgumentException(
+                                                       "unzulässiger Wert für Parameter: "
+                                                                       + requiredEntry.getKey() + " < "
+                                                                       + requiredEntry.getValue()[0]);
+                               if (codecParameter.get(requiredEntry.getKey()) > requiredEntry
+                                               .getValue()[1])
+                                       new IllegalArgumentException(
+                                                       "unzulässiger Wert für Parameter: "
+                                                                       + requiredEntry.getKey() + " > "
+                                                                       + requiredEntry.getValue()[1]);
+                       } else {
+                               throw new IllegalArgumentException("Missing Codec Parameter: "
+                                               + requiredEntry.getKey());
+                       }
+                       k = (int) codecParameter.get("k");
+                       m = (int) codecParameter.get("m");
+                       packetsize = (int) codecParameter.get("packetsize");
+                       
+                       try {
+                               crsidacodec = new CauchyInformationDispersalCodec(k+m, m, packetsize);
+                               encoder = crsidacodec.getEncoder();
+                               decoder = crsidacodec.getDecoder();
+                       } catch (IDAInvalidParametersException e) {
+                               throw new IllegalArgumentException("JigDFS IDAInvalidParametersException: \n"+e.toString());
+                       } catch (IDANotInitializedException e) {
+                               throw new IllegalArgumentException("JigDFS IDANotInitializedException: \n"+e.toString());
+                       }
+               }
+       }
+
+       @Override
+       public byte[][] encode(byte[][] data_ptrs){
+               int fragmentsize = data_ptrs[0].length;
+               checkArraySizes(fragmentsize);
+               //Fill into flat data parts
+               for (int i=0; i<k ; i++){
+                       System.arraycopy(data_ptrs[i],0,data_ptrs_flat,i * fragmentsize, fragmentsize);
+               }
+               try {
+                       dataAndCoding_list = encoder.process(data_ptrs_flat);
+               } catch (IDAEncodeException e) {
+                       throw new IllegalArgumentException("JigDFS IDAEncodeException: \n"+e.toString());
+               } catch (IDANotInitializedException e) {
+                       throw new IllegalArgumentException("JigDFS IDANotInitializedException: \n"+e.toString());
+               }
+               dataAndCoding_ptrs = new byte[k+m][];
+               int i = 0;
+               for (byte[] part:dataAndCoding_list){
+                       dataAndCoding_ptrs[i++]=part;
+               }
+               return dataAndCoding_ptrs;
+       }
+
+       @Override
+       public byte[][] decode(byte[][] dataAndCoding_ptrs, boolean [] erased){
+               //decoder.process(encodedBuffers);
+               return null;
+       }
+       
+       private void checkArraySizes(int fragmentsize) {
+               
+               if (data_ptrs == null || (data_ptrs.length != k) || (data_ptrs[0].length != fragmentsize)){
+                       data_ptrs = new byte[k][fragmentsize];
+               }                       
+               
+               //Test reuse or create new
+               if (data_ptrs_flat == null || (data_ptrs_flat.length != k * fragmentsize)){
+                       data_ptrs_flat = new byte[k * fragmentsize];
+               }
+               
+               
+//             if (coding_ptrs_flat == null || (coding_ptrs_flat.length != m * fragmentsize)){
+//                     coding_ptrs_flat = new byte[m * fragmentsize];
+//             }
+//             
+//             if (coding_ptrs == null || (coding_ptrs.length != m ) || (coding_ptrs[0].length != fragmentsize)){
+//                     coding_ptrs = new byte[m][fragmentsize];
+//             }
+//             
+//             if (dataAndCoding_ptrs == null || (dataAndCoding_ptrs.length != k+m) || (dataAndCoding_ptrs[0].length != fragmentsize)){
+//                     dataAndCoding_ptrs = new byte[k+m][fragmentsize];
+//             }
+       }
+               
+
+}
\ No newline at end of file
diff --git a/Splitter-ng-plugin-jigdfs/src/jigdfsplugin/SplitterPluginJigDFS.java b/Splitter-ng-plugin-jigdfs/src/jigdfsplugin/SplitterPluginJigDFS.java
new file mode 100644 (file)
index 0000000..02eca5f
--- /dev/null
@@ -0,0 +1,52 @@
+package jigdfsplugin;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.Map;
+
+import splitterng.plugin.CodecDescription;
+import splitterng.plugin.PluginDescription;
+import splitterng.plugin.interfaces.Plugable;
+import splitterng.plugin.interfaces.SplitterCodec;
+
+public class SplitterPluginJigDFS implements Plugable {
+       private final String pluginID = "JigDFSPlugin";
+       private final String pluginName = "Plugin JigDFS";
+       private final String pluginDescriptionText = "Diese Plugin stellt die JigDFS Bibliothek als Codec zur Verfügung";
+       private final Collection<String> dependencies = Arrays.asList("");
+       private Collection<CodecDescription> codecDescriptions;
+       private PluginDescription pluginDescription;
+
+       public SplitterPluginJigDFS() {
+               this.codecDescriptions = new LinkedList<CodecDescription>();
+               this.codecDescriptions.add(CodecJigDFS.getCodecDescription());
+               // Weitere CodecBeschreibungen hier anhängen
+               this.pluginDescription = new PluginDescription(this.pluginID,
+                               this.pluginName, this.pluginDescriptionText,
+                               this.codecDescriptions, this.dependencies);
+       }
+
+       @Override
+       public PluginDescription getPluginDescription() {
+               return pluginDescription;
+       }
+
+       @Override
+       public Collection<CodecDescription> getCodecDescriptions() {
+               return codecDescriptions;
+       }
+
+       @Override
+       public SplitterCodec getNewSplitterCodec(String codecID,
+                       Map<String, Integer> codecParameter)
+                       throws IllegalArgumentException {
+               switch (codecID) {
+               case CodecJigDFS.codecID:
+                       return new CodecJigDFS(codecParameter);
+                       // Weitere Codecs hier erzeugen
+
+               default:
+                       throw new IllegalArgumentException("CodecID not known: " + codecID);
+               }
+       }
+}
\ No newline at end of file
diff --git a/Splitter-ng-plugin-jigdfs/src/jigdfsplugin/package-info.java b/Splitter-ng-plugin-jigdfs/src/jigdfsplugin/package-info.java
new file mode 100644 (file)
index 0000000..7d380fc
--- /dev/null
@@ -0,0 +1,8 @@
+/**
+ * 
+ */
+/**
+ * @author max
+ *
+ */
+package jigdfsplugin;
\ No newline at end of file
diff --git a/Splitter-ng-plugin-jigdfs/src/log4j.properties b/Splitter-ng-plugin-jigdfs/src/log4j.properties
new file mode 100644 (file)
index 0000000..ed6f0b2
--- /dev/null
@@ -0,0 +1,21 @@
+\r
+log4j.rootLogger=TRACE, STDOUT, R, CHAINSAW\r
+\r
+# Stdout\r
+log4j.appender.STDOUT=org.apache.log4j.varia.NullAppender\r
+log4j.appender.STDOUT.layout=org.apache.log4j.PatternLayout\r
+log4j.appender.STDOUT.layout.ConversionPattern=[%d{ISO8601}]%5p%6.6r[%t]%x - %C.%M(%F:%L) - %m%n\r
+\r
+# File\r
+log4j.appender.R=org.apache.log4j.RollingFileAppender\r
+log4j.appender.R.File=log/log4j.log\r
+log4j.appender.R.MaxFileSize=500KB\r
+log4j.appender.R.MaxBackupIndex=1\r
+log4j.appender.R.layout=org.apache.log4j.PatternLayout\r
+log4j.appender.R.layout.ConversionPattern=[%d{ISO8601}]%5p%6.6r[%t]%x - %C.%M(%F:%L) - %m%n\r
+\r
+#CHAINSAW\r
+log4j.appender.CHAINSAW=org.apache.log4j.net.SocketAppender\r
+log4j.appender.CHAINSAW.remoteHost=localhost\r
+log4j.appender.CHAINSAW.port=4560\r
+log4j.appender.CHAINSAW.locationInfo=false
\ No newline at end of file
diff --git a/Splitter-ng-plugin-jigdfs/src/org/jigdfs/baseClass/ResponseMsg.java b/Splitter-ng-plugin-jigdfs/src/org/jigdfs/baseClass/ResponseMsg.java
new file mode 100644 (file)
index 0000000..e04c428
--- /dev/null
@@ -0,0 +1,31 @@
+package org.jigdfs.baseClass;
+
+public abstract class ResponseMsg {
+    final String resultMessage;
+    final Object result;
+    final Object source;
+    
+    public ResponseMsg(String resultMessage, Object result, Object source){
+       this.resultMessage = resultMessage;
+       this.result = result;   
+       this.source = source;
+    }
+    
+    public ResponseMsg(String resultMessage, Object result) {
+       this.resultMessage = resultMessage;
+       this.result = result;
+       this.source = null;
+    }
+    
+    public String getResultMessage(){
+       return this.resultMessage;
+    }
+    
+    public Object getResult(){
+       return this.result;
+    }
+    
+    public Object getSource(){
+       return this.source;
+    }
+}
diff --git a/Splitter-ng-plugin-jigdfs/src/org/jigdfs/baseInterface/Listenable.java b/Splitter-ng-plugin-jigdfs/src/org/jigdfs/baseInterface/Listenable.java
new file mode 100644 (file)
index 0000000..7d616b8
--- /dev/null
@@ -0,0 +1,7 @@
+package org.jigdfs.baseInterface;
+
+import java.util.EventObject;
+
+public interface Listenable {
+   void notifyListeners(EventObject event);
+}
diff --git a/Splitter-ng-plugin-jigdfs/src/org/jigdfs/baseInterface/Listener.java b/Splitter-ng-plugin-jigdfs/src/org/jigdfs/baseInterface/Listener.java
new file mode 100644 (file)
index 0000000..e399fc6
--- /dev/null
@@ -0,0 +1,6 @@
+package org.jigdfs.baseInterface;
+
+import java.util.EventListener;
+
+public interface Listener extends EventListener {
+}
diff --git a/Splitter-ng-plugin-jigdfs/src/org/jigdfs/baseInterface/Plugin.java b/Splitter-ng-plugin-jigdfs/src/org/jigdfs/baseInterface/Plugin.java
new file mode 100644 (file)
index 0000000..45d2434
--- /dev/null
@@ -0,0 +1,10 @@
+package org.jigdfs.baseInterface;
+
+/**
+ * All plugin needs to implement this interface
+ * @author jbian
+ *
+ */
+public interface Plugin {
+
+}
diff --git a/Splitter-ng-plugin-jigdfs/src/org/jigdfs/baseInterface/Pluginable.java b/Splitter-ng-plugin-jigdfs/src/org/jigdfs/baseInterface/Pluginable.java
new file mode 100644 (file)
index 0000000..5945084
--- /dev/null
@@ -0,0 +1,10 @@
+package org.jigdfs.baseInterface;
+
+/**
+ * The class that is pluginable, such as an IDA algorithm or an encrytion algorithm
+ * @author jbian
+ *
+ */
+public interface Pluginable {
+
+}
diff --git a/Splitter-ng-plugin-jigdfs/src/org/jigdfs/exception/BaseException.java b/Splitter-ng-plugin-jigdfs/src/org/jigdfs/exception/BaseException.java
new file mode 100644 (file)
index 0000000..0c426ef
--- /dev/null
@@ -0,0 +1,71 @@
+package org.jigdfs.exception;
+
+import org.apache.log4j.Logger;
+
+//BaesException class borrowed from cleversafe.org Exception...
+public class BaseException extends Exception {
+       
+       private static final long serialVersionUID = 8831273457330260940L;
+       private static Logger logger = Logger.getLogger(BaseException.class.getName());
+       
+       public BaseException()
+          {
+             super();
+             if (logger.isTraceEnabled())
+                 logger.trace("Exception", this);
+          }
+
+          public BaseException(String reason, Throwable cause)
+          {
+             super(reason == null ? "" : reason, cause);
+             if (logger.isTraceEnabled())
+                 logger.trace("Exception: " + reason, this);
+          }
+
+          public BaseException(String reason)
+          {
+             super(reason);
+             if (logger.isTraceEnabled())
+                 logger.trace("Exception: " + reason, this);
+          }
+
+          public BaseException(Throwable cause)
+          {
+             super(cause);
+             if (logger.isTraceEnabled())
+                 logger.trace("Exception", this);
+          }
+
+          public String getMessage()
+          {
+             return super.getMessage();
+          }
+
+          public String toString()
+          {
+             StringBuffer fullMessage = new StringBuffer();
+
+             if (getMessage() != null)
+             {
+                fullMessage.append(getMessage());
+             }
+             else
+             {
+                fullMessage.append("(No message provided)");
+             }
+
+             if (getCause() != null)
+             {
+                fullMessage.append(", Caused by: ");
+                if (getCause().getMessage() != null)
+                {
+                   fullMessage.append(getCause().getMessage());
+                }
+                else // better then nothing
+                {
+                   fullMessage.append(getCause().getClass().getName());
+                }
+             }
+             return fullMessage.toString();
+          }
+}
diff --git a/Splitter-ng-plugin-jigdfs/src/org/jigdfs/exception/NotImplementedException.java b/Splitter-ng-plugin-jigdfs/src/org/jigdfs/exception/NotImplementedException.java
new file mode 100644 (file)
index 0000000..4fefe79
--- /dev/null
@@ -0,0 +1,28 @@
+package org.jigdfs.exception;
+
+import org.apache.log4j.Logger;
+
+/**
+ * Any feature that is not implemented should throw this exception or its
+ * derived exception.
+ * 
+ */
+public class NotImplementedException extends RuntimeException
+{
+
+   private static final long serialVersionUID = 2260199096341127562L;
+
+   private static Logger _logger = Logger.getLogger(NotImplementedException.class);
+   
+   public NotImplementedException()
+   {
+      super("This feature is not implemented.");
+      _logger.error("Exception: Unimplemented feature", this);
+   }
+
+   public NotImplementedException(String reason)
+   {
+      super(reason);
+      _logger.error("Exception: " + reason, this);
+   }
+}
diff --git a/Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/base/InformationDispersalCodec.java b/Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/base/InformationDispersalCodec.java
new file mode 100644 (file)
index 0000000..05e1a76
--- /dev/null
@@ -0,0 +1,90 @@
+package org.jigdfs.ida.base;
+
+import org.jigdfs.ida.exception.IDAInvalidParametersException;
+import org.jigdfs.ida.exception.IDANotInitializedException;
+
+/**
+ * IDA interface - combines an encoder and decoder
+ */
+public interface InformationDispersalCodec
+{
+   
+   /**
+    * 
+    * @return a name of codec
+    */
+   String getName();
+   
+   /**
+    * Sets the name of the codec
+    * @param name
+    */
+   void setName(String name);
+   
+   
+   /**
+    * @return Number of slices produced by this codec
+    */
+   int getNumSlices();
+       
+   
+   /**
+    * @return Number of slices needed to restore data
+    */
+   int getThreshold();
+   
+   /**
+    * @return The chunk size on which the IDA will operate
+    */
+   int getChunkSize();
+
+   /**
+    * Sets number of slices, needed for instantiating from configuration
+    * @param numSlices
+    */
+   void setNumSlices(int numSlices);
+   
+   /**
+    * Number of slices needed to restore data
+    * @param treshold
+    */
+   void setThreshold(int threshold);
+   
+   /**
+    * Chunk size for which the IDA will operate, typically the disk block size
+    * plus overhead due to datasource codecs
+    * @param inputSize
+    */
+   void setChunkSize(int inputSize);
+   
+   /**
+    * 
+    * @return
+    */
+   InformationDispersalEncoder getEncoder() throws IDANotInitializedException, IDAInvalidParametersException;
+
+   /**
+    * 
+    * @return
+    */
+   InformationDispersalDecoder getDecoder() throws IDANotInitializedException, IDAInvalidParametersException;
+   
+   /**
+    * Returns the blowup of this IDA.  For example, if encoded data is 30% larger than 
+    * the original input, this would return 1.3.
+    * @return Blowup of this IDA as a factor of the original data size (eg. 1.3)
+    */
+   float getBlowup();
+   
+   /**
+    * Returns the post-dispersed upper-bound size in bytes for data with a given input size.
+    * 
+    * @param inputDataSize
+    * @return
+    */
+   long getDispersedSize(long inputSize);
+
+
+}
+
+
diff --git a/Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/base/InformationDispersalCodecBase.java b/Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/base/InformationDispersalCodecBase.java
new file mode 100644 (file)
index 0000000..71751d9
--- /dev/null
@@ -0,0 +1,171 @@
+//
+// Cleversafe open-source code header - Version 1.2 - February 15, 2008
+//
+// Cleversafe Dispersed Storage(TM) is software for secure, private and
+// reliable storage of the world's data using information dispersal.
+//
+// Copyright (C) 2005-2008 Cleversafe, Inc.
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
+// USA.
+//
+// Contact Information: Cleversafe, 224 North Desplaines Street, Suite 500 
+// Chicago IL 60661
+// email licensing@cleversafe.org
+//
+// END-OF-HEADER
+//-----------------------
+// Author: mmotwani
+//
+// Date: May 30, 2007
+//---------------------
+
+package org.jigdfs.ida.base;
+
+import org.jigdfs.exception.NotImplementedException;
+import org.jigdfs.ida.exception.IDAInvalidParametersException;
+import org.jigdfs.ida.exception.IDANotInitializedException;
+
+/**
+ * Base abstract class that implements {@link InformationDispersalCodec} and
+ * contains common code for all codecs.
+ * 
+ * original from cleversafe, but revised to fit our need
+ * 
+ * @author Jiang Bian
+ */
+public abstract class InformationDispersalCodecBase implements
+               InformationDispersalCodec {
+       public static int DEFAULT_CHUNK_SIZE = 4096;
+
+       protected String name = null;
+
+       protected boolean isInitialized = false;
+       
+       // Number of slices
+       protected int numSlices = 0;
+
+       // Number of acceptable lost slices
+       protected int threshold = 0;
+
+       // Size of the chunk of data processed as input with each call to encode
+       protected int chunkSize = DEFAULT_CHUNK_SIZE;
+
+       // Encoder and decoder
+       protected static InformationDispersalEncoder _encoder = null;
+       protected static InformationDispersalDecoder _decoder = null;
+
+       protected abstract InformationDispersalEncoder getNewEncoder() throws IDAInvalidParametersException;
+
+       protected abstract InformationDispersalDecoder getNewDecoder() throws IDAInvalidParametersException;
+
+       // should never be called without params
+       protected InformationDispersalCodecBase() {
+               throw new NotImplementedException(
+                               "This should never be called without params");
+       }
+
+       protected InformationDispersalCodecBase(int numSlices, int threshold) {
+               this.numSlices = numSlices;
+               this.threshold = threshold;
+               this.chunkSize = DEFAULT_CHUNK_SIZE;
+       }
+
+       protected InformationDispersalCodecBase(int numSlices, int threshold,
+                       int chunkSize) {
+               this.numSlices = numSlices;
+               this.threshold = threshold;
+               this.chunkSize = chunkSize;
+       }
+
+       public InformationDispersalEncoder getEncoder() throws IDANotInitializedException, IDAInvalidParametersException {
+
+               if(!isInitialized) throw new IDANotInitializedException("the parameteres have not been initialized!");
+               
+               if (_encoder == null) {
+                       _encoder = getNewEncoder();
+               }
+               return _encoder;
+       }
+
+       public InformationDispersalDecoder getDecoder() throws IDANotInitializedException, IDAInvalidParametersException {
+
+               if(!isInitialized) throw new IDANotInitializedException("the parameteres have not been initialized!");
+               
+               if (_decoder == null) {
+                       _decoder = getNewDecoder();
+               }
+               return _decoder;
+       }
+
+       /**
+        * Initializes IDA's encoder and decoder
+        * @throws IDAInvalidParametersException 
+        */
+       protected void initialize() throws IDAInvalidParametersException {
+               _encoder = getNewEncoder();
+               _decoder = getNewDecoder();
+               isInitialized = true;
+       }
+
+       public int getNumSlices() {
+               return numSlices;
+       }
+
+       public int getThreshold() {
+               return threshold;
+       }
+
+       public int getChunkSize() {
+               return chunkSize;
+       }
+
+       /**
+        * @param numSlices
+        *            the numSlices to set
+        */
+       public void setNumSlices(int numSlices) {
+               this.numSlices = numSlices;
+       }
+
+       /**
+        * @param threshold
+        *            the threshold to set
+        */
+       public void setThreshold(int threshold) {
+               this.threshold = threshold;
+       }
+
+       /**
+        * @param chunkSize
+        *            the chunkSize to set
+        */
+       public void setChunkSize(int chunkSize) {
+               this.chunkSize = chunkSize;
+       }
+
+       public void setName(String name) {
+               this.name = name;
+       }
+
+       public String getName() {
+               return name;
+       }
+
+       public float getBlowup() {
+               return this.getNumSlices() / (float) (this.getThreshold());
+       }
+
+}
diff --git a/Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/base/InformationDispersalDecoder.java b/Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/base/InformationDispersalDecoder.java
new file mode 100644 (file)
index 0000000..8903f23
--- /dev/null
@@ -0,0 +1,58 @@
+package org.jigdfs.ida.base;
+
+import java.util.List;
+
+import org.jigdfs.ida.exception.IDADecodeException;
+import org.jigdfs.ida.exception.IDAInvalidParametersException;
+import org.jigdfs.ida.exception.IDANotInitializedException;
+
+
+
+public interface InformationDispersalDecoder
+{
+
+   /**
+    * Prepares the decoder to begin processing encoded data.
+    * 
+    * @throws IDAInvalidParametersException
+    */
+   public void initialize() throws IDAInvalidParametersException;
+
+
+   /**
+    * Performs a complete decoding operation or finishes a multiple-part
+    * decoding operation.
+    * 
+    * @param encodedBuffers A list of encoded buffers
+    * 
+    * @return Decoded data
+    * @throws IDADecodeException 
+    */
+   public byte[] process(List<byte[]> encodedBuffers) 
+      throws IDADecodeException, IDANotInitializedException;
+
+   /**
+    * Returns the number of slices
+    * 
+    * @return The number of slices
+    */
+   public int getNumSlices();
+
+   /**
+    * Returns the number of slices which are required to restore data.
+    * 
+    * @return The number of slices which are required to restore data
+    */
+   public int getThreshold();
+   
+   /**
+    * Returns the chunk size
+    * 
+    * @return The chunk size
+    */
+   public int getChunkSize();
+   
+   public void setNumSlices(int numSlices);
+   public void setThreshold(int threshold);
+   public void setChunkSize(int chunkSize);
+}
diff --git a/Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/base/InformationDispersalEncoder.java b/Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/base/InformationDispersalEncoder.java
new file mode 100644 (file)
index 0000000..e642c8f
--- /dev/null
@@ -0,0 +1,54 @@
+
+package org.jigdfs.ida.base;
+
+import java.util.List;
+
+import org.jigdfs.ida.exception.IDAEncodeException;
+import org.jigdfs.ida.exception.IDAInvalidParametersException;
+import org.jigdfs.ida.exception.IDANotInitializedException;
+
+
+public interface InformationDispersalEncoder
+{
+   /**
+    * Prepares the encoder to begin processing data.
+    */
+   public void initialize() throws IDAInvalidParametersException;
+
+   /**
+    * Performs a complete encoding operation or finishes a multiple-part
+    * encoding operation.
+    * 
+    * @param buffer
+    *           The data to encoded
+    * 
+    * @return A list of encoded data buffers
+    */
+   public List<byte[]> process(byte buffer[])
+         throws IDAEncodeException, IDANotInitializedException;
+
+   /**
+    * Returns the number of slices
+    * 
+    * @return The number of slices
+    */
+   public int getNumSlices();
+
+   /**
+    * Returns the number of slices which are required to restore data.
+    * 
+    * @return The number of slices which are required to restore data
+    */
+   public int getThreshold();
+   
+   /**
+    * Returns the chunk size
+    * 
+    * @return The chunk size
+    */
+   public int getChunkSize();
+   
+   public void setNumSlices(int numSlices);
+   public void setThreshold(int threshold);
+   public void setChunkSize(int chunkSize);
+}
diff --git a/Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/cauchyreedsolomon/CauchyDecode.java b/Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/cauchyreedsolomon/CauchyDecode.java
new file mode 100644 (file)
index 0000000..1c2b7f5
--- /dev/null
@@ -0,0 +1,359 @@
+//
+// Cleversafe open-source code header - Version 1.2 - February 15, 2008
+//
+// Cleversafe Dispersed Storage(TM) is software for secure, private and
+// reliable storage of the world's data using information dispersal.
+//
+// Copyright (C) 2005-2008 Cleversafe, Inc.
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
+// USA.
+//
+// Contact Information: Cleversafe, 224 North Desplaines Street, Suite 500 
+// Chicago IL 60661
+// email licensing@cleversafe.org
+//
+// END-OF-HEADER
+
+/**
+ * CauchyDecode.java
+ *
+ * @author   Hakim Weatherspoon
+ * @version  $Id: CauchyDecode.java,v 1.4 2004/05/14 00:46:01 hweather Exp $
+ *
+ * Copyright (c) 2001 Regents of the University of California.
+ * All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. 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.
+ *  3. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ **/
+
+package org.jigdfs.ida.cauchyreedsolomon;
+
+import java.util.*;
+
+/**
+ * CauchyEncode decodes a msg that was previously encoded using Cauchy
+ * Reed-Solomon method.
+ * 
+ * Move information from fragments into received message. Fill in parts of
+ * received message that requires no processing and figure out how many of the
+ * redundant fragments are needed. Nfirstrec is the number of fragments received
+ * from among the first Mfragments that carry portions of the unprocessed
+ * original message. Rec_index is an array that indicates which parts of the
+ * message are received. The pattern is the same within all Nsegs segments,
+ * 
+ * @author Hakim Weatherspoon
+ * @version $Id: CauchyDecode.java,v 1.4 2004/05/14 00:46:01 hweather Exp $
+ */
+public class CauchyDecode
+{
+   private static final int STACK_SIZE = 32;
+
+   private static Map<Integer, FiniteStack> _decodeTable = new HashMap<Integer, FiniteStack>();
+
+   /**
+    * decode uses the cauchy erasure coding method to decode an array of
+    * fragments back into a msg.
+    */
+
+   /*
+    * @param COLBIT == COLBIT is the bit that is used to make sure rows and
+    * columns have distinct field elements associated with them. @param BIT ==
+    * The BIT array is used to mask out single bits in equations: bit @param
+    * ExptoFE == ExptoFE is the table that goes from the exponent to the finite
+    * field element. @param FEtoExp == FEtoExp is the table that goes from the
+    * finite field element to the exponent. @param fragments == fragments are
+    * the array of fragments as output. @param message == is the message in int
+    * array format.
+    */
+   public static byte[] decode(
+         final byte[] rec_fragments,
+         final int Nrec,
+         final CauchyIDAParameters p) throws Exception
+   {
+      byte[] rec_message = new byte[p.getMessageLength()];
+      
+      int i, j, k, l, m, index, seg_ind;
+      int col_ind, row_ind, col_eqn, row_eqn;
+      int Nfirstrec, Nextra;
+      int ExpFE;
+
+      int diff;
+      
+      final int numSegments = p.getSegmentsPerSlice();
+      final int logOfField = p.getLogOfFieldLength();
+
+      final int[] COLBIT = InitField.getCOLBIT(logOfField);
+      final int[] BIT = InitField.getBIT(logOfField);
+      final int[] ExptoFE = InitField.getExptoFE(logOfField);
+      final int[] FEtoExp = InitField.getFEtoExp(logOfField);
+
+      Integer key = new Integer(p.getNumDataSlices() + numSegments * p.getNumCodeSlices()
+            * logOfField);
+      FiniteStack stack = (FiniteStack) _decodeTable.get(key);
+
+      if (stack == null)
+      {
+         synchronized (_decodeTable)
+         {
+            if ((stack = (FiniteStack) _decodeTable.get(key)) == null)
+            {
+               Object bucket = null;
+               stack = new FiniteStack(STACK_SIZE);
+               if ((bucket = _decodeTable.put(key, stack)) != null)
+                  System.err.println("CauchyDecode.decode: bucket=" + bucket
+                        + " for key=" + key + " stack=" + stack);
+            }
+         }
+      }
+
+      ArrayObj arrayObj = (ArrayObj) stack.pop();
+      if (arrayObj == null)
+         arrayObj = new ArrayObj(p.getNumDataSlices(), p.getNumCodeSlices(), numSegments, logOfField);
+
+      int[] Rec_index = arrayObj.Rec_index;
+      int[] Col_Ind = arrayObj.Col_Ind;
+      int[] Row_Ind = arrayObj.Row_Ind;
+      byte[] M = arrayObj.M;
+      int[] C = arrayObj.C;
+      int[] D = arrayObj.D;
+      int[] E = arrayObj.E;
+      int[] F = arrayObj.F;
+
+      if (Nrec < p.getNumDataSlices())
+      {
+         throw new Exception("Decode error");
+      }
+
+      /**
+       * Move information from fragments into received message. Fill in parts of
+       * received message that requires no processing and figure out how many of
+       * the redundant fragments are needed. Nfirstrec is the number of
+       * fragments received from among the first Mfragments that carry portions
+       * of the unprocessed original message. Rec_index is an array that
+       * indicates which parts of the message are received. The pattern is the
+       * same within all Nsegs segments,
+       */
+
+      Nfirstrec = 0;
+
+      m = 0;
+      for (i = 0; i < Nrec; i++)
+      {
+         index = rec_fragments[m];
+         if (index < p.getNumDataSlices())
+         {
+            j = index * p.getSliceLength();
+            Rec_index[index] = 1;
+
+            diff = (m + 1) - j;
+            
+            System.arraycopy(rec_fragments, j + diff, rec_message, j, numSegments * logOfField);
+            
+            Nfirstrec++;
+         }
+         m += p.getTotalSliceLength();
+      }
+
+      /**
+       * Nextra is the number of redundant fragments that need to be processed.
+       */
+      Nextra = p.getNumDataSlices() - Nfirstrec;
+
+      /**
+       * Compute the indices of the missing words in the message
+       */
+      col_ind = 0;
+      for (i = 0; i < p.getNumDataSlices(); i++)
+      {
+         if (Rec_index[i] == 0)
+            Col_Ind[col_ind++] = i;
+      }
+
+      /**
+       * Keep track of indices of extra fragments in Row_Ind array and
+       * initialize M array from the received extra fragments
+       */
+      row_ind = 0;
+      m = 0;
+      for (i = 0; i < Nrec; i++)
+      {
+         if (rec_fragments[m] >= p.getNumDataSlices())
+         {
+            k = numSegments * row_ind * logOfField;
+            Row_Ind[row_ind] = rec_fragments[m] - p.getNumDataSlices();
+            
+            System.arraycopy(rec_fragments, m + 1, M, k, numSegments * logOfField);
+            
+            row_ind++;
+            if (row_ind >= Nextra)
+               break;
+         }
+         m += p.getTotalSliceLength();
+      }
+
+      /**
+       * Adjust M array according to the equations and the contents of
+       * rec_message.
+       */
+      for (row_ind = 0; row_ind < Nextra; row_ind++)
+      {
+         for (col_ind = 0; col_ind < p.getNumDataSlices(); col_ind++)
+         {
+            if (Rec_index[col_ind] == 1)
+            {
+               ExpFE = (p.getMultiplicationFieldSize() - FEtoExp[Row_Ind[row_ind] ^ col_ind
+                     ^ COLBIT[0]])
+                     % p.getMultiplicationFieldSize();
+               for (row_eqn = 0; row_eqn < logOfField; row_eqn++)
+               {
+                  j = numSegments * (row_eqn + row_ind * logOfField);
+                  for (col_eqn = 0; col_eqn < logOfField; col_eqn++)
+                  {
+                     k = numSegments * (col_eqn + col_ind * logOfField);
+                     if ((ExptoFE[ExpFE + row_eqn] & BIT[col_eqn]) > 0)
+                     {
+                        
+                        diff = (k - j);
+                        int stop = j + numSegments;
+                        
+                        for (seg_ind = j; seg_ind < stop; seg_ind++)
+                        {
+                           M[seg_ind] ^= rec_message[seg_ind + diff];
+                        }
+
+                     }
+                  }
+               }
+            }
+         }
+      }
+
+      /**
+       * Compute the determinant of the matrix in the finite field and then
+       * compute the inverse matrix
+       */
+      for (row_ind = 0; row_ind < Nextra; row_ind++)
+      {
+         for (col_ind = 0; col_ind < Nextra; col_ind++)
+         {
+            if (col_ind != row_ind)
+            {
+               C[row_ind] += FEtoExp[Row_Ind[row_ind] ^ Row_Ind[col_ind]];
+               D[col_ind] += FEtoExp[Col_Ind[row_ind] ^ Col_Ind[col_ind]];
+            }
+            E[row_ind] += FEtoExp[Row_Ind[row_ind] ^ Col_Ind[col_ind]
+                  ^ COLBIT[0]];
+            F[col_ind] += FEtoExp[Row_Ind[row_ind] ^ Col_Ind[col_ind]
+                  ^ COLBIT[0]];
+         }
+      }
+
+      /**
+       * Fill in the recovered information in the message from the inverted
+       * matrix and from M.
+       */
+      for (row_ind = 0; row_ind < Nextra; row_ind++)
+      {
+         for (col_ind = 0; col_ind < Nextra; col_ind++)
+         {
+            ExpFE = E[col_ind] + F[row_ind] - C[col_ind] - D[row_ind]
+                  - FEtoExp[Row_Ind[col_ind] ^ Col_Ind[row_ind] ^ COLBIT[0]];
+            if (ExpFE < 0)
+               ExpFE = p.getMultiplicationFieldSize() - ((-ExpFE) % p.getMultiplicationFieldSize());
+            ExpFE = ExpFE % p.getMultiplicationFieldSize();
+            j = Col_Ind[row_ind] * logOfField * numSegments;
+            for (row_eqn = 0; row_eqn < logOfField; row_eqn++)
+            {
+               k = row_eqn * numSegments + j;
+               for (col_eqn = 0; col_eqn < logOfField; col_eqn++)
+               {
+                  l = numSegments * (col_eqn + col_ind * logOfField);
+                  if ((ExptoFE[ExpFE + row_eqn] & BIT[col_eqn]) > 0)
+                  {
+                     diff = (l - k);
+                     int stop = k + numSegments;
+                     
+                     for (seg_ind = k; seg_ind < stop; seg_ind++)
+                     {
+                        rec_message[seg_ind] ^= M[seg_ind + diff];
+                     }
+                     
+                  }
+               }
+            }
+         }
+      }
+
+      return rec_message;
+   }
+
+   private static class ArrayObj
+   {
+      public int[] Rec_index;
+
+      public int[] Col_Ind;
+
+      public int[] Row_Ind;
+
+      public int[] C;
+
+      public int[] D;
+
+      public int[] E;
+
+      public int[] F;
+
+      public byte[] M;
+
+      public ArrayObj(
+            int numMsgFrags,
+            int numRedundantFrags,
+            int nSegs,
+            int Lfield)
+      {
+         Rec_index = new int[numMsgFrags];
+         Col_Ind = new int[numMsgFrags];
+         Row_Ind = new int[numRedundantFrags];
+         C = new int[numRedundantFrags];
+         D = new int[numMsgFrags];
+         E = new int[numMsgFrags];
+         F = new int[numRedundantFrags];
+         M = new byte[nSegs * numRedundantFrags * Lfield];
+      }
+   }
+}
diff --git a/Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/cauchyreedsolomon/CauchyEncode.java b/Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/cauchyreedsolomon/CauchyEncode.java
new file mode 100644 (file)
index 0000000..4fca026
--- /dev/null
@@ -0,0 +1,214 @@
+//
+// Cleversafe open-source code header - Version 1.2 - February 15, 2008
+//
+// Cleversafe Dispersed Storage(TM) is software for secure, private and
+// reliable storage of the world's data using information dispersal.
+//
+// Copyright (C) 2005-2008 Cleversafe, Inc.
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
+// USA.
+//
+// Contact Information: Cleversafe, 224 North Desplaines Street, Suite 500 
+// Chicago IL 60661
+// email licensing@cleversafe.org
+//
+// END-OF-HEADER
+
+/**
+ * CauchyEncode.java
+ *
+ * @author   Hakim Weatherspoon
+ * @version  $Id: CauchyEncode.java,v 1.4 2004/05/14 00:46:01 hweather Exp $
+ *
+ * Copyright (c) 2001 Regents of the University of California.
+ * All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. 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.
+ *  3. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ **/
+
+package org.jigdfs.ida.cauchyreedsolomon;
+
+
+/**
+ * CauchyEncode erasure encodes an object using cauchy reed solomon method.
+ * 
+ * @author Hakim Weatherspoon
+ * @version $Id: CauchyEncode.java,v 1.4 2004/05/14 00:46:01 hweather Exp $
+ */
+public class CauchyEncode
+{
+   /**
+    * encode uses the cauchy erasure encoding method to encode a message into
+    * fragments.
+    */
+
+   /**
+    * @param COLBIT == COLBIT is the bit that is used to make sure rows and
+    * columns have distinct field elements associated with them.
+    * @param BIT == The BIT array is used to mask out single bits in equations: bit
+    * @param ExptoFE == ExptoFE is the table that goes from the exponent to the finite
+    * field element.
+    * @param FEtoExp == FEtoExp is the table that goes from the
+    * finite field element to the exponent.
+    * @param message == is the message in int array format.
+    */
+   public static byte[] encode(final byte[] message, final CauchyIDAParameters p)
+   {
+      //////////////////////////////////////////////////////////////////////////
+      // Local variable declaration
+      
+      // Array to be filled with data and code slices
+      byte slices[] = new byte[p.getTotalSliceLength() * p.getNumSlices()];
+
+      // Finite Field Parameters
+      final int[] COLBIT = InitField.getCOLBIT(p.getLogOfFieldLength());
+      final int[] equationBitMask = InitField.getBIT(p.getLogOfFieldLength());
+      final int[] exponentToFiniteFieldElement = InitField.getExptoFE(p.getLogOfFieldLength());
+      final int[] finiteFieldElementToExponent = InitField.getFEtoExp(p.getLogOfFieldLength());
+
+      // Constants taken from parameters
+      final int numSegments = p.getSegmentsPerSlice();
+      final int logOfField = p.getLogOfFieldLength();
+      final int numDataSlices = p.getNumDataSlices();
+      final int numCodeSlices = p.getNumCodeSlices();
+      final int multFieldSize = p.getMultiplicationFieldSize();
+      
+      // For Loop Iterators
+      int itr, row, col, rowEquation, columnEquation;
+      
+      // Miscellaneous variables used in code slice calculation
+      int sliceArrayPosition, messageArrayPosition;
+      int ExpFE, ExpFEplusRow;
+      int arrayPositionDifference, sliceArrayPositionPlusNumSegments;
+      int sliceArrayIterator;
+      
+      //////////////////////////////////////////////////////////////////////////
+
+      // Set the slice index in the first byte of every slices      
+      for (itr = 0; itr < p.getNumSlices(); itr++)
+      {
+         slices[itr * p.getTotalSliceLength()] = (byte) itr;
+      }
+
+      // Copy data slices from the message into position
+      int sliceOffset = 0;
+      for (itr = 0; itr < numDataSlices; itr++)
+      {
+         System.arraycopy(message, sliceOffset, slices, sliceOffset + itr + 1, p.getSliceLength());
+         sliceOffset += p.getSliceLength();
+      }
+
+      /*
+       * Pseudo code for Cauchy Reed-Solomon Encoding
+       *
+       *  for (codeSlice in CodeSlices) // 4
+       *  {
+       *     for (dataSlice in DataSlices) // 12
+       *     {
+       *        for (equationRow in FieldLength) // 8
+       *        {
+       *           for (equationCol in FieldLength) // 8
+       *           {
+       *              if (exponent[equationRow + exponent] & bit[equationCol] > 0)
+       *              {
+       *                 for (i = 0 to segments) // 43 (MessageLength / DataSlices / 8)
+       *                 {
+       *                    codeSlice[i + equationRow * segments] ^= dataSlice[i + equationCol * segments];
+       *                 }
+       *              }
+       *           }
+       *        }
+       *     }
+       *  }
+       *
+       */
+      
+      // Calculate code slices and put them into the correct position
+      for (row = 0; row < numCodeSlices; row++)
+      {
+         /**
+          * Compute values of equations applied to message and fill into
+          * fragment(row+DataSlices).
+          */
+         final int rowOffset = ((row + numDataSlices) * p.getTotalSliceLength()) + 1;   
+         
+         /**
+          * Second, fill in contents relevant portions of fragment
+          */
+         for (col = 0; col < numDataSlices; col++)
+         {
+            messageArrayPosition = col * p.getSliceLength();
+            
+            ExpFE = (multFieldSize - finiteFieldElementToExponent[row ^ col ^ COLBIT[0]])
+                  % multFieldSize;
+
+            for (rowEquation = 0; rowEquation < logOfField; rowEquation++)
+            {
+               ExpFEplusRow = ExpFE + rowEquation;
+               sliceArrayPosition = rowOffset + (rowEquation * numSegments);
+               
+               for (columnEquation = 0; columnEquation < logOfField; columnEquation++)
+               {
+                  if ((exponentToFiniteFieldElement[ExpFEplusRow] & equationBitMask[columnEquation]) > 0)
+                  {  
+                     /*
+                      * Warning: the following code is heavily optimized and difficult to read
+                      * The following loop is the result of much optimization
+                      * and is an attempt to use as few instructions as possible
+                      * within this very deeply nested loop.
+                      */
+                     arrayPositionDifference = ((columnEquation * numSegments + messageArrayPosition) - sliceArrayPosition);
+                     sliceArrayPositionPlusNumSegments = sliceArrayPosition + numSegments;
+                     sliceArrayIterator = sliceArrayPosition;
+                     
+                     while (sliceArrayIterator < sliceArrayPositionPlusNumSegments)
+                     {
+                        slices[sliceArrayIterator] ^= message[sliceArrayIterator + arrayPositionDifference];
+                        sliceArrayIterator++;
+                     }
+                     
+                  }
+               }
+            }
+         }
+      }
+      
+      return slices;
+   }
+   
+}
diff --git a/Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/cauchyreedsolomon/CauchyIDAParameters.java b/Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/cauchyreedsolomon/CauchyIDAParameters.java
new file mode 100644 (file)
index 0000000..ef1fd5a
--- /dev/null
@@ -0,0 +1,369 @@
+//
+// Cleversafe open-source code header - Version 1.2 - February 15, 2008
+//
+// Cleversafe Dispersed Storage(TM) is software for secure, private and
+// reliable storage of the world's data using information dispersal.
+//
+// Copyright (C) 2005-2008 Cleversafe, Inc.
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
+// USA.
+//
+// Contact Information: Cleversafe, 224 North Desplaines Street, Suite 500 
+// Chicago IL 60661
+// email licensing@cleversafe.org
+//
+// END-OF-HEADER
+
+/**
+ * Parameters.java
+ *
+ * @author   Hakim Weatherspoon
+ * @version  $Id: Parameters.java,v 1.4 2004/05/14 00:46:01 hweather Exp $
+ *
+ * Copyright (c) 2001 Regents of the University of California.
+ * All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. 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.
+ *  3. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ **/
+
+package org.jigdfs.ida.cauchyreedsolomon;
+
+/**
+ * Parameters are the parameters used to encode/decode an object.
+ * 
+ * @author Hakim Weatherspoon
+ * @version $Id: Parameters.java,v 1.4 2004/05/14 00:46:01 hweather Exp $
+ */
+public class CauchyIDAParameters
+{
+   /**
+    * chunkSize is the size of data that is will be sent to the IDA
+    * for each encoding.  Should include the block size plus any size change 
+    * introduced by the datasource codecs.
+    */
+   protected int chunkSize;
+
+   /**
+    * logOfFieldLength is the log of the length of the field.
+    */
+   protected int logOfFieldLength = 8;
+
+   /**
+    * segmentsPerFragment is the number of segments in a slice. Length of slice in bytes
+    * is segmentsPerFragment*logOfFieldLength.
+    */
+   protected int segmentsPerSlice = 43;
+
+   /**
+    * finiteFieldTableLength is 2^{logOfFieldLength}
+    */
+   protected int finiteFieldTableLength = 1 << logOfFieldLength;
+
+   /**
+    * SMultField is the size of the multiplicative field (2^{logOfFieldLength}-1) ==
+    * finiteFieldTableLength - 1.
+    */
+   protected int multiplicationFieldSize = (1 << logOfFieldLength) - 1;
+
+   /**
+    * sliceLength is the fragment length in words excluding the overhead for storing
+    * the index.
+    */
+   protected int sliceLength = segmentsPerSlice * logOfFieldLength;
+
+   /**
+    * totalSliceLEngth is the slice length in words including the overhead for storing
+    * the index.
+    */
+   protected int totalSliceLength = sliceLength + 1;
+
+   /**
+    * numDataSlices is the number of data slices
+    * 
+    * IMPORTANT: The max of numDataSlices + numCodeSlices is at most 2^{logOfFieldLength-1}.
+    * 
+    * logOfFieldLength must be set large enough to make this true else the encoding and
+    * decoding won't work
+    */
+   protected int numDataSlices;
+
+   /**
+    * numCodeSlices is the number of redundant fragments
+    * 
+    * IMPORTANT: The max of numDataSlices + numCodeSlices is at most 2^{logOfFieldLength-1}.
+    * 
+    * logOfFieldLength must be set large enough to make this true else the encoding and
+    * decoding won't work.
+    */
+   protected int numCodeSlices;
+
+   /**
+    * numSlices is the total number of slices sent.
+    */
+   protected int numSlices;
+
+   /**
+    * messageLength is the length of the message in bytes.
+    */
+   protected int messageLength;
+
+   /**
+    * dispersedMessageLength is the post-dispersal length of the message in words.
+    */
+   protected int dispersedMessageLength;
+
+   /**
+    * CONSTRUCTOR
+    * 
+    * Initialize Parameters for a number of messages.
+    * 
+    * @param numDataSlices =
+    *           numDataSlices is the number of message fragments.
+    * @param numCodeSlices =
+    *           numCodeSlices is the number of redundant fragments.
+    */
+   public CauchyIDAParameters(int numDataSlices, int numCodeSlices, int chunkSize)
+   {
+      this.chunkSize = chunkSize;
+      
+      this.numDataSlices = numDataSlices;
+      this.numCodeSlices = numCodeSlices;
+      
+      calculateOptimumSliceSize();
+
+      this.numSlices = this.numDataSlices + this.numCodeSlices;
+      this.messageLength = this.sliceLength * this.numDataSlices;
+      this.dispersedMessageLength = this.sliceLength * (this.numDataSlices + this.numCodeSlices);
+   }
+   
+   /**
+    * Calculates the optimum segmentsPerSlice and sliceLength values based on
+    * the amount of data the IDA is given to process at a time and the number
+    * of data slices.
+    */
+   private void calculateOptimumSliceSize()
+   {
+      // We add one to chunkSize to avoid cases where the block size
+      // exactly equals the message length, resulting in an entire additional
+      // block being created and filled with padding bytes. - JKR
+      final int tempChunkSize = this.chunkSize + 1;
+      
+      int sliceSize = tempChunkSize / this.numDataSlices;
+      
+      if (tempChunkSize % this.numDataSlices != 0)
+      {
+         sliceSize++;
+      }
+
+      // Round up to the nearest multiple of log of field length
+      if (sliceSize % this.logOfFieldLength > 0)
+      {
+         sliceSize += ((this.logOfFieldLength) - (sliceSize % this.logOfFieldLength));
+      }
+      
+
+      this.segmentsPerSlice = (sliceSize / this.logOfFieldLength);      
+      this.sliceLength = this.segmentsPerSlice * this.logOfFieldLength;
+      this.totalSliceLength = this.sliceLength + 1;
+   }
+
+   /**
+    * Returns the chunk size.
+    */
+   public int getChunkSize()
+   {
+      return chunkSize;
+   }
+
+   /**
+    * Returns the log of the length of the field.
+    */
+   public int getLogOfFieldLength()
+   {
+      return logOfFieldLength;
+   }
+
+   /**
+    * Returns the number of segments in a slice. Length of slice in bytes
+    * is segmentsPerSlice*logOfFieldLength.
+    */
+   public int getSegmentsPerSlice()
+   {
+      return segmentsPerSlice;
+   }
+
+   /**
+    * Returns 2^{logOfFieldLength}
+    */
+   public int getFiniteFieldTableLength()
+   {
+      return finiteFieldTableLength;
+   }
+
+   /**
+    * Returns the size of the multiplicative field (2^{logOfFieldLength}-1) ==
+    * finiteFieldTableLength - 1.
+    */
+   public int getMultiplicationFieldSize()
+   {
+      return multiplicationFieldSize;
+   }
+
+   /**
+    * Returns the fragment length in bytes excluding the overhead for storing
+    * the index.
+    */
+   public int getSliceLength()
+   {
+      return sliceLength;
+   }
+
+   /**
+    * Returns the fragment length in bytes including the overhead for storing
+    * the index.
+    */
+   public int getTotalSliceLength()
+   {
+      return totalSliceLength;
+   }
+
+   /**
+    * Returns the number of data slices
+    * 
+    * @return return == return the number of data slices.
+    * 
+    * IMPORTANT: The max of numDataSlices + numCodeSlices is at most 2^{logOfFieldLength-1}.
+    * 
+    * logOfFieldLength must be set large enough to make this true else the encoding and
+    * decoding won't work
+    */
+   public int getNumDataSlices()
+   {
+      return numDataSlices;
+   }
+
+   /**
+    * Returns the number of code slices
+    * 
+    * @return return == return the number of message fragments.
+    * 
+    * IMPORTANT: The max of numDataSlices + numCodeSlices is at most 2^{logOfFieldLength-1}.
+    * 
+    * logOfFieldLength must be set large enough to make this true else the encoding and
+    * decoding won't work.
+    */
+   public int getNumCodeSlices()
+   {
+      return numCodeSlices;
+   }
+
+   /**
+    * Returns the total number of slices sent.
+    */
+   public int getNumSlices()
+   {
+      return numSlices;
+   }
+
+   /**
+    * Returns the length of the message in bytes.
+    */
+   public int getMessageLength()
+   {
+      return messageLength;
+   }
+
+   /**
+    * Returns the length of the encoding in bytes.
+    */
+   public int getDispersedMessageLength()
+   {
+      return dispersedMessageLength;
+   }
+
+   /**
+    * logOfFieldLength (length of field) must be (1 <= logOfFieldLength <= 16) otherwise function
+    * returns false and logOfFieldLength stays default.
+    * 
+    * @param logOfFieldLength ==
+    *           number to set logOfFieldLength to, 1 <= logOfFieldLength <= 16.
+    * @return return==logOfFieldLength must be (1 <= logOfFieldLength <= 16) otherwise function
+    *         returns false and logOfFieldLength stays default
+    */
+   public boolean setLogOfFieldLength(int logOfFieldLength)
+   {
+      if (logOfFieldLength <= 8 && logOfFieldLength >= 1)
+         this.logOfFieldLength = logOfFieldLength;
+      else
+         return false;
+
+      resetParam();
+
+      return true;
+   }
+
+   public void setChunkSize(int chunkSize)
+   {
+      this.chunkSize = chunkSize;
+      
+      resetParam();
+   }
+
+   public void resetParam()
+   {
+      this.finiteFieldTableLength = 1 << this.logOfFieldLength;
+      this.multiplicationFieldSize = (1 << this.logOfFieldLength) - 1;
+      calculateOptimumSliceSize();
+      this.sliceLength = this.segmentsPerSlice * this.logOfFieldLength;
+      this.totalSliceLength = this.sliceLength + 1;
+   }
+   
+   public String toString() {
+          return "number of segments: " + this.segmentsPerSlice + "; "
+               + "slice size:" + this.getSliceLength() + "; "
+               + "message size:" + this.messageLength;
+   }
+
+   public static void main(String args[])
+   {
+      CauchyIDAParameters params = new CauchyIDAParameters(12, 4, 4096);
+      System.out.println("number of segments: " + params.segmentsPerSlice);
+      System.out.println("slice size:" + params.getSliceLength());
+      System.out.println("message size:" + params.messageLength);
+   }
+}
diff --git a/Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/cauchyreedsolomon/CauchyInformationDispersalCodec.java b/Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/cauchyreedsolomon/CauchyInformationDispersalCodec.java
new file mode 100644 (file)
index 0000000..87353cd
--- /dev/null
@@ -0,0 +1,90 @@
+
+package org.jigdfs.ida.cauchyreedsolomon;
+
+import org.jigdfs.ida.base.InformationDispersalCodec;
+import org.jigdfs.ida.base.InformationDispersalCodecBase;
+import org.jigdfs.ida.base.InformationDispersalDecoder;
+import org.jigdfs.ida.base.InformationDispersalEncoder;
+import org.jigdfs.ida.exception.*;
+
+
+
+/**
+ * Cauchy Reed-Solomon IDA implementation, encoder should be a singlton
+ */
+public class CauchyInformationDispersalCodec extends InformationDispersalCodecBase
+      implements
+         InformationDispersalCodec
+{
+  
+   /*
+    * this should never be called, this should be created with params...
+    */
+   protected CauchyInformationDispersalCodec()
+   {
+          super();        
+   }
+   
+   protected InformationDispersalEncoder getNewEncoder() throws IDAInvalidParametersException
+   {      
+      CauchyInformationDispersalEncoder encoder = new CauchyInformationDispersalEncoder(this.numSlices, this.threshold, this.chunkSize);
+      return encoder;
+   }
+   
+   protected InformationDispersalDecoder getNewDecoder() throws IDAInvalidParametersException
+   {
+      CauchyInformationDispersalDecoder decoder = new CauchyInformationDispersalDecoder(this.numSlices, this.threshold, this.chunkSize);
+      return decoder;
+   }
+
+  
+   
+   /**
+    * Construct a new Cauchy Reed-Solomon IDA
+    * 
+    * @param numSlices
+    *           Number of slices to produce
+    * @param threshold
+    *           Number of recoverable slice losses
+    * @param chunkSize
+    *           The size of data that the IDA will process at a time
+    */
+   public CauchyInformationDispersalCodec(int numSlices, int threshold, int chunkSize) throws
+         IDAInvalidParametersException
+   {
+      super(numSlices, threshold, chunkSize);
+      this.setName("optimizedcauchy");
+
+      if (this.numSlices < 1) 
+      {
+         throw new IDAInvalidParametersException("Number of slices must be positive");
+      }
+      if (this.threshold <= 0)
+      {
+         throw new IDAInvalidParametersException("Threshold must be greater than zero");
+      }
+      if (this.chunkSize < 1) 
+      {
+         throw new IDAInvalidParametersException("Chunk size must be positive");
+      }
+      
+      initialize();
+   }
+
+   
+   public long getDispersedSize(long inputSize)
+   {
+      CauchyIDAParameters parameters = new CauchyIDAParameters(this.threshold, this.numSlices - this.threshold, this.chunkSize);
+      
+      int sliceLength = parameters.getSliceLength();
+      
+      int messageLength = sliceLength * this.threshold;
+      
+      int encodedLength = parameters.getTotalSliceLength() * parameters.getNumSlices();
+      
+      return ((inputSize / messageLength) + 1) * encodedLength;
+   }
+
+
+
+}
diff --git a/Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/cauchyreedsolomon/CauchyInformationDispersalDecoder.java b/Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/cauchyreedsolomon/CauchyInformationDispersalDecoder.java
new file mode 100644 (file)
index 0000000..52bb958
--- /dev/null
@@ -0,0 +1,239 @@
+
+package org.jigdfs.ida.cauchyreedsolomon;
+
+import java.util.List;
+
+import org.apache.log4j.Logger;
+import org.jigdfs.ida.base.InformationDispersalCodecBase;
+import org.jigdfs.ida.base.InformationDispersalDecoder;
+import org.jigdfs.ida.exception.*;
+
+
+public class CauchyInformationDispersalDecoder implements InformationDispersalDecoder
+{
+   /** Cauchy IDA parameters */
+   private CauchyIDAParameters params = null;
+
+   /** Standard Message Length */
+   private int chunkSize = InformationDispersalCodecBase.DEFAULT_CHUNK_SIZE;
+   
+   /** The total number of slices */
+   private int numSlices;
+
+   /** The number of slices required to restore */
+   private int threshold;
+
+   private boolean initialized = false;
+
+   /** Buffer for unencoded data */
+   // private int data[];
+   /** Pre-allocated output buffer */
+   // private byte output[];
+   // private byte buffer[];
+   /** Buffer for encoded data */
+   // private int fragments[];
+   private static Logger logger = Logger.getLogger(CauchyInformationDispersalDecoder.class);
+
+   public CauchyInformationDispersalDecoder()
+   {
+   }
+
+   public CauchyInformationDispersalDecoder(int numSlices, int threshold, int chunkSize) throws IDAInvalidParametersException
+   {
+      this.numSlices = numSlices;
+      this.threshold = threshold;
+      this.chunkSize = chunkSize;
+      initialize();
+   }
+
+   public synchronized void initialize() throws IDAInvalidParametersException
+   {
+      // Configuration already calls initialize, but we need to reinitialize with the
+      // calculated block size after datasource codecs are applied.  This is a safety 
+      // measure which should be added back in the future, but is being removed as a quick
+      // fix -- JKR
+      //if (this.initialized == true)
+      //{
+      //   throw new IDAInvalidParametersException("Decoder may only be initialized once");
+      //}
+      if (this.numSlices < 1)
+      {
+         throw new IDAInvalidParametersException("Number of slices must be positive");
+      }
+      if (this.threshold <= 0)
+      {
+         throw new IDAInvalidParametersException("Threshold must be greater than zero");
+      }
+      if (this.chunkSize < 1)
+      {
+         throw new IDAInvalidParametersException("Chunk size must be positive");
+      }
+
+      this.params = new CauchyIDAParameters(numSlices - threshold, threshold, chunkSize);
+
+      if (logger.isTraceEnabled())
+      {
+         logger.trace(toString());
+      }
+      
+      this.initialized = true;
+   }
+
+   public byte[] process(List<byte[]> encodedBuffers) throws IDADecodeException,
+         IDANotInitializedException
+   {
+      if (!this.initialized)
+      {
+         throw new IDANotInitializedException("IDA is not initialized, Call initialize() first");
+      }
+
+      int fragmentSize = getFragmentSize();
+
+      byte data[];
+      byte fragments[] = new byte[encodedBuffers.size() * fragmentSize];
+      byte output[] = new byte[getMessageSize()];
+
+      // Establish slice length
+      int dataLength = -1;
+      for (int i = 0; i < encodedBuffers.size(); i++)
+      {
+         if (encodedBuffers.get(i) != null)
+         {
+            if (dataLength == -1)
+            {
+               dataLength = encodedBuffers.get(i).length;
+            }
+            else
+            {
+               assert dataLength == encodedBuffers.get(i).length : "Inconsistent slice length: "
+                     + encodedBuffers.get(i).length + " expected " + dataLength;
+            }
+         }
+      }
+      assert dataLength != -1 : "Data length can't be calculated";
+  
+      int outputBufferSize = dataLength / fragmentSize * getMessageSize();
+      if (outputBufferSize != output.length)
+      {
+         output = new byte[outputBufferSize];
+      }
+
+
+      int outputPosition = 0;
+
+      int encodedBufferPosition = 0;
+      do
+      {
+         // Copy encoded data into fragments array
+         int fragmentIdx = 0;
+         for (int i = 0; i < encodedBuffers.size() && (fragmentIdx < encodedBuffers.size()); i++)
+         {
+            // Skip null buffers
+            if (encodedBuffers.get(i) != null)
+            {
+               byte encodedBuffer[] = encodedBuffers.get(i);
+               int fragmentOffset = fragmentIdx * fragmentSize;
+               System.arraycopy(encodedBuffer, encodedBufferPosition, fragments, fragmentOffset,
+                          fragmentSize);
+               fragmentIdx++;
+            }
+         }
+
+         if (fragmentIdx < numSlices - threshold)
+         {
+            throw new IDAInvalidSliceCountException("Expected " + (numSlices - threshold) + " but got only "
+                  + fragmentIdx + " slices");
+         }
+         try
+         {//treshold=redundant fragments < data slices?
+                data = CauchyDecode.decode(fragments, fragmentIdx, params);
+         }
+         catch (Exception e)
+         {
+                e.printStackTrace();
+            throw new IDAInvalidSliceFormatException("Decode error");
+         }
+
+         System.arraycopy(data, 0, output, outputPosition, data.length);
+         outputPosition += data.length;
+
+         encodedBufferPosition += fragmentSize;
+      } while (encodedBufferPosition < dataLength);
+
+      // Truncate padding
+      int outputSize = output.length;
+      while (outputSize > 0 && output[outputSize - 1] == 0)
+      {
+         outputSize--;
+      }
+
+      outputSize--;
+
+      byte buffer[] = new byte[outputSize];
+      System.arraycopy(output, 0, buffer, 0, outputSize);
+
+      return buffer;
+   }
+
+
+   private int getMessageSize()
+   {
+      return params.getSliceLength() * params.getNumDataSlices();
+   }
+
+   private int getFragmentSize()
+   {
+      return params.getTotalSliceLength();
+   }
+
+   public int getNumSlices()
+   {
+      return numSlices;
+   }
+
+   public int getThreshold()
+   {
+      return threshold;
+   }
+
+   public int getChunkSize()
+   {
+      return chunkSize;
+   }
+
+   public void setNumSlices(int numSlices)
+   {
+      this.numSlices = numSlices;
+   }
+
+   public void setThreshold(int threshold)
+   {
+      this.threshold = threshold;
+   }
+   
+   public void setChunkSize(int chunkSize)
+   {
+      this.chunkSize = chunkSize;
+   }
+
+   @Override
+   public String toString()
+   {
+      StringBuffer stringBuff = new StringBuffer("");
+      
+      stringBuff.append("Slice count = " + numSlices + ", ");
+      stringBuff.append("threshold = " + threshold + ", ");
+      stringBuff.append("Message size: " + this.getMessageSize() + ", ");
+      stringBuff.append("Fragment size: " + this.getFragmentSize() + ", ");
+
+      stringBuff.append("Blowup = "
+            + ((float) getFragmentSize() * (float) numSlices / (float) getMessageSize()) + ", ");
+
+      stringBuff.append("Ideal = " + ((float) numSlices / (float) threshold));
+
+      return stringBuff.toString();
+   }
+   
+   
+}
+
diff --git a/Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/cauchyreedsolomon/CauchyInformationDispersalEncoder.java b/Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/cauchyreedsolomon/CauchyInformationDispersalEncoder.java
new file mode 100644 (file)
index 0000000..520a9c6
--- /dev/null
@@ -0,0 +1,227 @@
+
+package org.jigdfs.ida.cauchyreedsolomon;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+import org.jigdfs.ida.base.InformationDispersalCodecBase;
+import org.jigdfs.ida.base.InformationDispersalEncoder;
+import org.jigdfs.ida.exception.IDAEncodeException;
+import org.jigdfs.ida.exception.IDAInvalidParametersException;
+import org.jigdfs.ida.exception.IDANotInitializedException;
+
+
+
+public class CauchyInformationDispersalEncoder
+   implements InformationDispersalEncoder
+{
+   /** Cauchy IDA parameters */
+   private CauchyIDAParameters params = null;
+   
+   /** Chunk size */
+   private int chunkSize = InformationDispersalCodecBase.DEFAULT_CHUNK_SIZE;;
+   private int messageSize;
+   private int totalSliceLength;
+
+   private boolean initialized = false;
+  
+   /** Buffers for unencoded data */
+   // private int message[];
+
+   /** Buffer for encoded data */
+   // private int fragments[];
+
+   // private List<byte[]> outputBuffers;
+   
+   /** The total number of slices */
+   private int numSlices;
+   
+   /** The number of slices required to restore */
+   private int threshold;
+
+   private static Logger logger = Logger.getLogger(CauchyInformationDispersalEncoder.class);
+   
+   public CauchyInformationDispersalEncoder(int numSlices, int threshold, int chunkSize) throws IDAInvalidParametersException
+   {
+      this.numSlices = numSlices;
+      this.threshold = threshold;
+      this.chunkSize = chunkSize;
+      
+      initialize();
+   }
+
+   public synchronized void initialize() throws IDAInvalidParametersException
+   {
+      // Configuration already calls initialize, but we need to reinitialize with the
+      // calculated block size after datasource codecs are applied.  This is a safety 
+      // measure which should be added back in the future, but is being removed as a quick
+      // fix -- JKR
+      //if (this.initialized == true)
+      //{
+      //   throw new IDAInvalidParametersException("Encoder may only be initialized once");
+      //}
+      if (this.numSlices < 1) 
+      {
+         throw new IDAInvalidParametersException("Number of slices must be positive");
+      }
+      if (this.threshold <= 0)
+      {
+         throw new IDAInvalidParametersException("Threshold must be greater than zero");
+      }
+      if (this.chunkSize < 1)
+      {
+         throw new IDAInvalidParametersException("Chunk size must be positive");
+      }
+      if (this.threshold > this.numSlices) 
+      {
+         throw new IDAInvalidParametersException("Threshold must be less than or equal to number of slices");
+      }
+      
+      this.params = new CauchyIDAParameters(this.numSlices - this.threshold, this.threshold, this.chunkSize);
+      this.messageSize = params.getSliceLength() * params.getNumDataSlices();
+      this.totalSliceLength = params.getTotalSliceLength();
+      
+      if (logger.isTraceEnabled())
+      {
+         logger.trace(toString());
+      }
+      
+      this.initialized = true;
+   }
+
+
+
+   public List<byte[]> process(byte buffer[])
+      throws IDAEncodeException, IDANotInitializedException
+   {
+      if (!this.initialized)
+      {
+         throw new IDANotInitializedException(
+               "IDA is not initialized, Call initialize() first");
+      }
+      
+      byte message[] = new byte[getMessageSize()];
+
+      int inputPosition = 0;
+      int outputPosition = 0;
+
+      // Calculate the size of each output buffer
+      int outputSize = 
+         ((buffer.length + 1) / getMessageSize()) * getTotalSliceLength();
+
+      if ( (buffer.length + 1) % getMessageSize() != 0 )
+      {
+         outputSize += getTotalSliceLength();
+      }
+
+      // Allocate new buffers for output        
+      List<byte[]> outputBuffers  = new ArrayList<byte[]>(this.getNumSlices());   
+
+      // Allocate the output buffers
+      for (int fragmentIdx = 0; fragmentIdx < getNumSlices(); fragmentIdx++)
+      {
+         outputBuffers.add(new byte[outputSize]);
+      }
+      
+
+      while (outputPosition < outputSize)
+      {
+         final byte fillerByte = 1;
+         
+         // Copy data from the input buffer into the data buffer
+         int freeBufferSpace = buffer.length - inputPosition;
+         int maxWriteAmount = (message.length < freeBufferSpace ? message.length : freeBufferSpace);
+
+         System.arraycopy(buffer, inputPosition, message, 0, maxWriteAmount);
+         inputPosition += maxWriteAmount;
+         
+         // Add padding if needed
+         if (maxWriteAmount < message.length)
+         {
+            message[maxWriteAmount] = fillerByte;
+            Arrays.fill(message, maxWriteAmount+1, message.length, (byte) 0x00);
+         }
+
+         // Perform encoding of the data buffer into slices array
+         byte[] slices;
+         slices = CauchyEncode.encode(message, params);
+
+         // For each fragment
+         for (int fragmentIdx = 0; fragmentIdx < numSlices; fragmentIdx++)
+         {
+            byte fragment[] = outputBuffers.get(fragmentIdx);
+
+            int fragmentOffset = fragmentIdx * totalSliceLength;
+            
+            System.arraycopy(slices, fragmentOffset, fragment, outputPosition, totalSliceLength);
+         }
+
+         outputPosition += totalSliceLength;
+      }
+
+      return outputBuffers;
+   }
+
+   public int getNumSlices()
+   {
+      return numSlices;
+   }
+
+   public int getThreshold()
+   {
+      return threshold;
+   }
+      
+   private int getMessageSize()
+   {
+      return messageSize;
+   }
+
+   private int getTotalSliceLength()
+   {
+      return totalSliceLength;
+   }
+   
+   public int getChunkSize()
+   {
+      return chunkSize;
+   }
+   
+   public void setNumSlices(int numSlices)
+   {
+      this.numSlices = numSlices;
+   }
+   
+   public void setThreshold(int threshold)
+   {
+      this.threshold = threshold;
+   }
+   
+   public void setChunkSize(int inputMessageLength)
+   {
+      this.chunkSize = inputMessageLength;
+   }
+   
+   @Override
+   public String toString()
+   {
+      StringBuffer stringBuff = new StringBuffer("");
+      
+      stringBuff.append( "Slice count = " + numSlices + ", " );
+      stringBuff.append( "threshold = " + threshold + ", " );
+      stringBuff.append( "Message size: " + this.getMessageSize() + ", " );
+      stringBuff.append( "Fragment size: " + this.getTotalSliceLength() + ", " );
+
+      stringBuff.append( "Blowup = " + ( (float)getTotalSliceLength() *
+         (float)numSlices / (float)getMessageSize()) + ", " );
+      
+      stringBuff.append( "Ideal = " + ((float) numSlices / (float) threshold) );
+      
+      return stringBuff.toString();
+   }
+
+
+}
diff --git a/Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/cauchyreedsolomon/FiniteStack.java b/Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/cauchyreedsolomon/FiniteStack.java
new file mode 100644 (file)
index 0000000..450dac4
--- /dev/null
@@ -0,0 +1,158 @@
+//
+// Cleversafe open-source code header - Version 1.2 - February 15, 2008
+//
+// Cleversafe Dispersed Storage(TM) is software for secure, private and
+// reliable storage of the world's data using information dispersal.
+//
+// Copyright (C) 2005-2008 Cleversafe, Inc.
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
+// USA.
+//
+// Contact Information: Cleversafe, 224 North Desplaines Street, Suite 500 
+// Chicago IL 60661
+// email licensing@cleversafe.org
+//
+// END-OF-HEADER
+
+/*
+ * FiniteStack.java
+ *
+ * @author   Hakim Weatherspoon
+ * @version  $Id: FiniteStack.java,v 1.4 2004/05/14 00:46:18 hweather Exp $
+ *
+ *  Copyright (c) 2001 Regents of the University of California.  All
+ *  rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. 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.
+ *  3. Neither the name of the University 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 REGENTS 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
+ *  REGENTS 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.
+ */
+
+package org.jigdfs.ida.cauchyreedsolomon;
+
+/**
+ * A simple Stack of finite size.
+ * 
+ * @author Hakim Weatherspoon
+ * @version $Id: FiniteStack.java,v 1.4 2004/05/14 00:46:18 hweather Exp $
+ */
+public class FiniteStack
+{
+   // ////////////////// CONSTANTS ////////////////////
+   // ////////////////// STATIC VARIABLES ////////////////////
+   // ////////////////// VARIABLES ////////////////////
+   private int STACK_SIZE;
+
+   private Object[] _stack;
+
+   private int _head;
+
+   // ////////////////// CONSTRUCTORS ////////////////////
+
+   /**
+    * Constructs a new <code>Stack</code>.
+    */
+   public FiniteStack(int size)
+   {
+      STACK_SIZE = size;
+      _head = 0;
+      _stack = new Object[STACK_SIZE];
+   }
+
+   private boolean isFull()
+   {
+      return (_head == STACK_SIZE);
+   }
+
+   private boolean isEmpty()
+   {
+      return (_head == 0);
+   }
+
+   public boolean push(Object element)
+   {
+      synchronized (_stack)
+      {
+         if (isFull())
+            return false;
+         _stack[_head] = element;
+         _head = _head + 1;
+         return true;
+      }
+   }
+
+   public Object pop()
+   {
+      synchronized (_stack)
+      {
+         if (isEmpty())
+            return null;
+         _head = _head - 1;
+         Object element = _stack[_head];
+         _stack[_head] = null;
+         return element;
+      }
+   }
+
+   public int size()
+   {
+      synchronized (_stack)
+      {
+         return _head;
+      }
+   }
+
+   /**
+    * Returns a human-readable representation of this
+    * <code>CacheReserveState</code>.
+    */
+   public String toString()
+   {
+      String str = new String();
+
+      str += "<FiniteStack";
+      str += " size==" + _head;
+      str += " stackCapacity==" + STACK_SIZE;
+      for (int i = 0; i < _head; i++)
+         str += " stack[" + i + "]==" + _stack[i];
+      str += ">";
+
+      return str;
+   }
+
+}
diff --git a/Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/cauchyreedsolomon/InitField.java b/Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/cauchyreedsolomon/InitField.java
new file mode 100644 (file)
index 0000000..5ffea66
--- /dev/null
@@ -0,0 +1,245 @@
+//
+// Cleversafe open-source code header - Version 1.2 - February 15, 2008
+//
+// Cleversafe Dispersed Storage(TM) is software for secure, private and
+// reliable storage of the world's data using information dispersal.
+//
+// Copyright (C) 2005-2008 Cleversafe, Inc.
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
+// USA.
+//
+// Contact Information: Cleversafe, 224 North Desplaines Street, Suite 500 
+// Chicago IL 60661
+// email licensing@cleversafe.org
+//
+// END-OF-HEADER
+
+/**
+ * InitField.java 
+ *
+ * @author   Hakim Weatherspoon
+ * @version  $Id: InitField.java,v 1.4 2004/05/14 00:46:01 hweather Exp $
+ *
+ * Copyright (c) 2001 Regents of the University of California.
+ * All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. 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.
+ *  3. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ **/
+
+package org.jigdfs.ida.cauchyreedsolomon;
+
+/**
+ * InitField initializes the finite Field Element to Exponent (FEtoExp) table
+ * and the Exponent to finite Field Element (ExptoFE) table.
+ * 
+ * SMultField is the size of the multiplicative field (2^{Lfield}-1) ==
+ * TableLength - 1.
+ * 
+ * pCOLBIT is a pointer to the COLBIT, which is used to make sure rows and
+ * columns have distinct field elements associated with them. The BIT array is
+ * used to mask out single bits in equations: bit ExptoFE is the table that goes
+ * from the exponent to the finite field element. FEtoExp == FEtoExp is the
+ * table that goes from the finite field element to the exponent. Lfield is the
+ * log of the length of the field.
+ * 
+ * @author Hakim Weatherspoon
+ * @version $Id: InitField.java,v 1.4 2004/05/14 00:46:01 hweather Exp $
+ */
+public class InitField
+{
+   public static int MAXLFIELD = 16;
+
+   public static int COLBIT[][];
+
+   public static int BIT[][];
+
+   public static int ExptoFE[][];
+
+   public static int FEtoExp[][];
+
+   static
+   {
+      generateTables(MAXLFIELD);
+   }
+
+   /**
+    * Retrieve the COLBIT table for the input Lfield.
+    * 
+    * @param Lfield ==
+    *           the Lfield to retrieve a COLBIT table for.
+    */
+   public static int[] getCOLBIT(int Lfield)
+   {
+      return COLBIT[Lfield];
+   }
+
+   /**
+    * Retreve the BIT table for the input Lfield.
+    * 
+    * @param Lfield ==
+    *           the Lfield to retrieve a BIT table for.
+    */
+   public static int[] getBIT(int Lfield)
+   {
+      return BIT[Lfield];
+   }
+
+   /**
+    * Retreve the ExptoFE table for the input Lfield.
+    * 
+    * @param Lfield ==
+    *           the Lfield to retrieve a ExptoFE table for.
+    */
+   public static int[] getExptoFE(int Lfield)
+   {
+      return ExptoFE[Lfield];
+   }
+
+   /**
+    * Retreve the FEtoExp table for the input Lfield.
+    * 
+    * @param Lfield ==
+    *           the Lfield to retrieve a FEtoExp table for.
+    */
+   public static int[] getFEtoExp(int Lfield)
+   {
+      return FEtoExp[Lfield];
+   }
+
+   /**
+    * initField initializes the finite Field Element to Exponent (FEtoExp) table
+    * and the Exponent to finite Field Element (ExptoFE) table.
+    * 
+    * Recall SMultField = TableLength - 1 is the number of elements in the
+    * multiplicative group of the field.
+    * 
+    * @param pCOLBIT ==
+    *           is a pointer to the COLBIT, which is used to make sure rows and
+    *           columns have distinct field elements associated with them.
+    * @param BIT ==
+    *           The BIT array is used to mask out single bits in equations: bit
+    * @param ExptoFE ==
+    *           ExptoFE is the table that goes from the exponent to the finite
+    *           field element.
+    * @param FEtoExp ==
+    *           FEtoExp is the table that goes from the finite field element to
+    *           the exponent.
+    * @param Lfield ==
+    *           Lfield is the log of the length of the field..
+    */
+   public static void initField(
+         int[] pCOLBIT,
+         int[] BIT,
+         int[] ExptoFE,
+         int[] FEtoExp,
+         int Lfield)
+   {
+      /**
+       * Recall SMultField = TableLength - 1 is the number of elements in the
+       * multiplicative group of the field.
+       */
+      int SMultField = (1 << Lfield) - 1;
+
+      /**
+       * CARRYMASK is used to see when there is a carry in the polynomial and
+       * when it should be XOR'd with POLYMASK.
+       */
+      int CARRYMASK;
+
+      /**
+       * POLYMASK is the irreducible polynomial.
+       */
+      int POLYMASK[] = {
+            0x0, 0x3, 0x7, 0xB, 0x13, 0x25, 0x43, 0x83, 0x11D, 0x211, 0x409,
+            0x805, 0x1053, 0x201B, 0x402B, 0x8003, 0x1100B
+      };
+      int i;
+
+      BIT[0] = 0x1;
+
+      for (i = 1; i < Lfield; i++)
+         BIT[i] = BIT[i - 1] << 1;
+
+      pCOLBIT[0] = BIT[Lfield - 1];
+      CARRYMASK = pCOLBIT[0] << 1;
+      ExptoFE[0] = 0x1;
+
+      for (i = 1; i < SMultField + Lfield - 1; i++)
+      {
+         ExptoFE[i] = ExptoFE[i - 1] << 1;
+         if ((ExptoFE[i] & CARRYMASK) > 0)
+            ExptoFE[i] ^= POLYMASK[Lfield];
+      }
+
+      FEtoExp[0] = -1;
+      for (i = 0; i < SMultField; i++)
+         FEtoExp[ExptoFE[i]] = i;
+   }
+
+   /**
+    * This routine will generate tables for the input number of Lfields and
+    * output them to stdout.
+    * 
+    * @param maxLfield ==
+    *           maximum Lfield to produce fields for
+    */
+   public static void generateTables(int maxLfield)
+   {
+      /*
+       * TableLength = 2^Lfield COLBIT = new int[2] BIT = new int[16] ExptoFE =
+       * new int[TableLength + Lfield] FEtoExp = new int[TableLength]
+       */
+
+      COLBIT = new int[maxLfield + 1][];
+      BIT = new int[maxLfield + 1][];
+      ExptoFE = new int[maxLfield + 1][];
+      FEtoExp = new int[maxLfield + 1][];
+
+      for (int Lfield = 1; Lfield <= maxLfield; ++Lfield)
+      {
+         int TableLength = 1 << Lfield;
+         COLBIT[Lfield] = new int[1];
+         BIT[Lfield] = new int[16];
+         ExptoFE[Lfield] = new int[TableLength + Lfield];
+         FEtoExp[Lfield] = new int[TableLength];
+         initField(COLBIT[Lfield], BIT[Lfield], ExptoFE[Lfield],
+               FEtoExp[Lfield], Lfield);
+      }
+   }
+
+}
diff --git a/Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/exception/IDADecodeException.java b/Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/exception/IDADecodeException.java
new file mode 100644 (file)
index 0000000..e5c264a
--- /dev/null
@@ -0,0 +1,14 @@
+package org.jigdfs.ida.exception;
+
+public abstract class IDADecodeException extends IDAException {
+
+       private static final long serialVersionUID = 2166667129388317474L;
+
+       public IDADecodeException(String reason) {
+               super(reason);
+       }
+
+       public IDADecodeException(String reason, Throwable cause) {
+               super(reason, cause);
+       }
+}
diff --git a/Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/exception/IDAEncodeException.java b/Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/exception/IDAEncodeException.java
new file mode 100644 (file)
index 0000000..58d8729
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * IDAEncodeException
+ */
+
+package org.jigdfs.ida.exception;
+
+public abstract class IDAEncodeException extends IDAException {
+
+       private static final long serialVersionUID = 8142128197279943406L;
+
+       public IDAEncodeException(String reason) {
+               super(reason);
+       }
+
+       public IDAEncodeException(String reason, Throwable cause) {
+               super(reason, cause);
+       }
+}
diff --git a/Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/exception/IDAException.java b/Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/exception/IDAException.java
new file mode 100644 (file)
index 0000000..1ba12d6
--- /dev/null
@@ -0,0 +1,18 @@
+//Base Exception for all IDA exceptions
+
+package org.jigdfs.ida.exception;
+
+import org.jigdfs.exception.BaseException;
+
+public abstract class IDAException extends BaseException {
+
+       private static final long serialVersionUID = -8395584411924972673L;
+
+       public IDAException(String reason) {
+               super(reason);
+       }
+
+       public IDAException(String reason, Throwable cause) {
+               super(reason, cause);
+       }
+}
diff --git a/Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/exception/IDAInvalidParametersException.java b/Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/exception/IDAInvalidParametersException.java
new file mode 100644 (file)
index 0000000..60ff74a
--- /dev/null
@@ -0,0 +1,18 @@
+
+package org.jigdfs.ida.exception;
+
+public class IDAInvalidParametersException extends IDAException
+{
+   private static final long serialVersionUID = 1837113005051941698L;
+
+   
+   public IDAInvalidParametersException(String reason)
+   {
+      super(reason);
+   }
+
+   public IDAInvalidParametersException(String reason, Throwable cause)
+   {
+      super(reason, cause);
+   }
+}
diff --git a/Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/exception/IDAInvalidSliceCountException.java b/Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/exception/IDAInvalidSliceCountException.java
new file mode 100644 (file)
index 0000000..de2be57
--- /dev/null
@@ -0,0 +1,18 @@
+
+package org.jigdfs.ida.exception;
+
+public class IDAInvalidSliceCountException extends IDADecodeException
+{
+   private static final long serialVersionUID = -1530995737282100555L;
+
+   
+   public IDAInvalidSliceCountException(String reason)
+   {
+      super(reason);
+   }
+
+   public IDAInvalidSliceCountException(String reason, Throwable cause)
+   {
+      super(reason, cause);
+   }
+}
diff --git a/Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/exception/IDAInvalidSliceFormatException.java b/Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/exception/IDAInvalidSliceFormatException.java
new file mode 100644 (file)
index 0000000..b4cd0d9
--- /dev/null
@@ -0,0 +1,18 @@
+
+package org.jigdfs.ida.exception;
+
+public class IDAInvalidSliceFormatException extends IDADecodeException
+{
+   private static final long serialVersionUID = -8047476317165271412L;
+
+   
+   public IDAInvalidSliceFormatException(String reason)
+   {
+      super(reason);
+   }
+
+   public IDAInvalidSliceFormatException(String reason, Throwable cause)
+   {
+      super(reason, cause);
+   }
+}
diff --git a/Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/exception/IDAInvalidSliceLengthException.java b/Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/exception/IDAInvalidSliceLengthException.java
new file mode 100644 (file)
index 0000000..865f265
--- /dev/null
@@ -0,0 +1,18 @@
+
+package org.jigdfs.ida.exception;
+
+public class IDAInvalidSliceLengthException extends IDADecodeException
+{
+   private static final long serialVersionUID = -6630696463481056053L;
+
+   
+   public IDAInvalidSliceLengthException(String reason)
+   {
+      super(reason);
+   }
+
+   public IDAInvalidSliceLengthException(String reason, Throwable cause)
+   {
+      super(reason, cause);
+   }
+}
diff --git a/Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/exception/IDANotInitializedException.java b/Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/exception/IDANotInitializedException.java
new file mode 100644 (file)
index 0000000..e27c938
--- /dev/null
@@ -0,0 +1,18 @@
+package org.jigdfs.ida.exception;
+
+public class IDANotInitializedException extends IDAException
+{
+   private static final long serialVersionUID = -3586042062577454929L;
+
+   
+   public IDANotInitializedException(String reason)
+   {
+      super(reason);
+   }
+
+   public IDANotInitializedException(String reason, Throwable cause)
+   {
+      super(reason, cause);
+   }
+}
+
diff --git a/Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/test/CRSBinaryFileDecodeTestClass.java b/Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/test/CRSBinaryFileDecodeTestClass.java
new file mode 100644 (file)
index 0000000..37acc48
--- /dev/null
@@ -0,0 +1,132 @@
+package org.jigdfs.ida.test;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+import org.bouncycastle.crypto.Digest;
+import org.bouncycastle.crypto.digests.SHA256Digest;
+import org.bouncycastle.util.encoders.Hex;
+import org.jigdfs.ida.base.InformationDispersalCodec;
+import org.jigdfs.ida.base.InformationDispersalDecoder;
+
+import org.jigdfs.ida.cauchyreedsolomon.CauchyInformationDispersalCodec;
+
+
+public class CRSBinaryFileDecodeTestClass {
+       private static Logger logger = Logger
+                       .getLogger(CRSBinaryFileDecodeTestClass.class.getName());
+
+       public static void main(String[] args) throws Exception {
+               String fileName = "idg166-recovered.rar";
+               String fileHash = "74af6434a007a59ee2469cdd213d642f741d5917dea64df90896177a7f683da5";
+
+               InformationDispersalCodec crsidacodec = new CauchyInformationDispersalCodec(
+                               10, 3, 4096);
+
+               InformationDispersalDecoder decoder = crsidacodec.getDecoder();
+
+               List<byte[]> receivedFileSegments = new ArrayList<byte[]>();
+
+               Digest digestFunc = new SHA256Digest();
+               logger.info("Digest Function: " + digestFunc.getAlgorithmName());
+
+               byte[] digestByteArray = new byte[digestFunc.getDigestSize()];
+               String hexString = null;
+
+               InputStream in = null;
+               int readBytes;
+
+               try {
+                       File fileSegmentFolder = new File(fileHash);
+
+                       if (!fileSegmentFolder.exists()) {
+                               throw new IOException(fileSegmentFolder + " doesn't exist!");
+                       }
+                       /*
+                       // get the segment with the biggest length to create the
+                       // segmentBuffer
+                       // it's possible that the first is corrupted and the size is smaller
+                       // than the rest...
+                       
+                       long fileSegmentSize = 0;
+                       long thisSegmentSize = 0;
+
+                       for (File fileSegment : fileSegmentFolder.listFiles()) {
+                               thisSegmentSize = fileSegment.length();
+                               if (thisSegmentSize > fileSegmentSize) {
+                                       fileSegmentSize = thisSegmentSize;
+                               }
+                       }
+*/
+                       
+                       int validSegment = 0;
+
+                       for (File fileSegment : fileSegmentFolder.listFiles()) {
+                               if (fileSegment.exists() && fileSegment.isFile()) {
+                                       in = new FileInputStream(fileSegment);
+                                       byte[] segmentBuffer = new byte[(int) fileSegment.length()];
+                                       
+                                       readBytes = in.read(segmentBuffer);
+                                       logger.info("read file segment: " + fileSegment.getName()
+                                                       + "; " + readBytes + " bytes!");
+
+                                       digestFunc.reset();
+
+                                       digestFunc.update(segmentBuffer, 0, segmentBuffer.length);
+
+                                       digestFunc.doFinal(digestByteArray, 0);
+
+                                       hexString = new String(Hex.encode(digestByteArray));
+
+                                       if (!hexString.equals(fileSegment.getName())) {
+                                               logger.error("this file segment is invalid! "
+                                                               + fileSegment.getName() + " <> " + hexString);
+                                       } else {
+
+                                               receivedFileSegments.add(segmentBuffer);
+                                               validSegment++;
+                                               if (validSegment > 2) {
+                                                       break;
+                                               }
+                                       }
+
+                                       in.close();
+                               }
+                       }
+
+                       byte[] recoveredFile = decoder.process(receivedFileSegments);
+                       
+                       digestFunc.reset();
+
+                       digestFunc.update(recoveredFile, 0, recoveredFile.length);
+
+                       digestFunc.doFinal(digestByteArray, 0);
+
+                       hexString = new String(Hex.encode(digestByteArray));
+
+                       if (!hexString.equals(fileHash)) {
+                               throw new Exception(
+                                               "the recovered file hash value is not the same as original! "
+                                                               + hexString + " <> " + fileHash);
+                       }
+
+                       File file = new File(fileName);
+                       OutputStream out = new FileOutputStream(file);
+
+                       out.write(recoveredFile);
+                       out.flush();
+                       out.close();
+
+               } catch (Exception ex) {
+                       ex.printStackTrace();
+               }
+
+       }
+}
diff --git a/Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/test/CRSBinaryFileEncodeTestClass.java b/Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/test/CRSBinaryFileEncodeTestClass.java
new file mode 100644 (file)
index 0000000..671aa57
--- /dev/null
@@ -0,0 +1,104 @@
+package org.jigdfs.ida.test;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+import org.bouncycastle.crypto.Digest;
+import org.bouncycastle.crypto.digests.SHA256Digest;
+import org.bouncycastle.util.encoders.Hex;
+import org.jigdfs.ida.base.InformationDispersalCodec;
+import org.jigdfs.ida.base.InformationDispersalEncoder;
+import org.jigdfs.ida.cauchyreedsolomon.CauchyInformationDispersalCodec;
+
+
+public class CRSBinaryFileEncodeTestClass {
+private static Logger logger = Logger.getLogger(CRSBinaryFileEncodeTestClass.class.getName());
+       
+       public static void main(String[] args) throws Exception{
+               File file = new File("ReadMe.txt");
+               
+               if(!file.exists()) {
+                       throw new IOException("File " + file.getName() + "doesn't exist!");
+               }
+               
+               Digest digestFunc = new SHA256Digest(); 
+               logger.info("Digest Function: " + digestFunc.getAlgorithmName());
+               
+               byte[] digestByteArray = new byte[digestFunc.getDigestSize()];
+               String hexString = null;
+               
+               InformationDispersalCodec crsidacodec = new CauchyInformationDispersalCodec(10, 3, 4096);
+               
+               InformationDispersalEncoder encoder = crsidacodec.getEncoder();
+               
+               long fileSize = file.length();
+               logger.info("file size is " + fileSize + " bytes!");
+               
+               byte[] buffer = new byte[(int) (fileSize)];
+               int readBytes;
+               
+               try{
+                       InputStream in = new FileInputStream(file);
+                       /*
+                       while ((readBytes = in.read(buffer)) != -1) {
+                           logger.info("sized processed: " + sizeProcessed + "; " + Math.round(((double)sizeProcessed/(double)fileSize)) * 100 + "%");
+                           
+                           sizeProcessed += readBytes;
+                           
+                           
+                       }*/
+                       
+                       readBytes = in.read(buffer);
+                       logger.info("read " + readBytes + " bytes!");
+                       in.close();                     
+                       
+                       digestFunc.update(buffer, 0, buffer.length);
+                       
+                       digestFunc.doFinal(digestByteArray, 0);
+                       
+                       //hexString = HexUtil.bytesToHex(digestByteArray);
+                       hexString = new String(Hex.encode(digestByteArray));
+                       
+                       logger.info("file: " + file.getName() + "; hash: " + hexString);
+                       
+                       File fileSegmentFolder = new File(hexString);
+                       if(!fileSegmentFolder.exists()){
+                               fileSegmentFolder.mkdir();
+                       }                       
+                       
+                       List<byte[]> result = encoder.process(buffer);
+                       
+                       logger.info(result.size());                     
+                       
+                       for(byte[] b:result){
+                               logger.info("segment size: " + b.length + " bytes");                            
+                               digestFunc.reset();     
+                               digestFunc.update(b, 0, b.length);
+                               
+                               digestFunc.doFinal(digestByteArray, 0);
+                               
+                               hexString = new String(Hex.encode(digestByteArray));
+                               
+                               logger.info("the hash value: " + hexString);
+                               
+                               File fileSegment = new File(fileSegmentFolder, hexString);
+                               OutputStream out = new FileOutputStream(fileSegment);
+                               
+                               out.write(b);                           
+                               out.flush();
+                               out.close();
+                       }               
+                       
+                       
+               }catch(Exception ex){
+                       ex.printStackTrace();
+               }    
+               
+       }
+}
diff --git a/Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/test/CRSStringTestClass.java b/Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/test/CRSStringTestClass.java
new file mode 100644 (file)
index 0000000..8f3c5a9
--- /dev/null
@@ -0,0 +1,52 @@
+package org.jigdfs.ida.test;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+import org.jigdfs.ida.base.InformationDispersalCodec;
+import org.jigdfs.ida.base.InformationDispersalDecoder;
+import org.jigdfs.ida.base.InformationDispersalEncoder;
+import org.jigdfs.ida.cauchyreedsolomon.CauchyInformationDispersalCodec;
+import org.jigdfs.ida.exception.IDADecodeException;
+import org.jigdfs.ida.exception.IDAEncodeException;
+import org.jigdfs.ida.exception.IDAInvalidParametersException;
+import org.jigdfs.ida.exception.IDANotInitializedException;
+
+public class CRSStringTestClass {
+       
+       private static Logger logger = Logger.getLogger(CRSStringTestClass.class.getName());
+       
+       public static void main(String[] args) throws IDAInvalidParametersException, IDANotInitializedException, IDAEncodeException, IDADecodeException{
+               String testString = "hello world";
+               byte[] testByteArray = testString.getBytes();
+               
+               InformationDispersalCodec crsidacodec = new CauchyInformationDispersalCodec(16, 4, 4096);
+               
+               InformationDispersalEncoder encoder = crsidacodec.getEncoder();
+               
+               List<byte[]> result = encoder.process(testByteArray);
+               
+               logger.info(result.size());
+               /*
+               for(byte[] b:result){
+                       logger.debug(new String(b));
+               }
+               */
+               InformationDispersalDecoder decoder = crsidacodec.getDecoder();
+               
+               //manually remove some packets...
+               List<byte[]> receivedPackets = new ArrayList<byte[]>();
+               
+               //should need only 4 of them
+               receivedPackets.add(result.get(1));
+               receivedPackets.add(result.get(3));
+               receivedPackets.add(result.get(5));
+               receivedPackets.add(result.get(7));
+               receivedPackets.add(result.get(9));
+               
+               logger.info("Recovered string:" + new String(decoder.process(receivedPackets)));
+               
+               
+       }
+}
diff --git a/Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/test/CRSTextFileTestClass.java b/Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/test/CRSTextFileTestClass.java
new file mode 100644 (file)
index 0000000..e709c2e
--- /dev/null
@@ -0,0 +1,79 @@
+package org.jigdfs.ida.test;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+import org.jigdfs.ida.base.InformationDispersalCodec;
+import org.jigdfs.ida.base.InformationDispersalDecoder;
+import org.jigdfs.ida.base.InformationDispersalEncoder;
+import org.jigdfs.ida.cauchyreedsolomon.CauchyInformationDispersalCodec;
+
+
+public class CRSTextFileTestClass {
+private static Logger logger = Logger.getLogger(CRSTextFileTestClass.class.getName());
+       
+       public static void main(String[] args) throws Exception{
+               File file = new File("testinput.txt");
+               InputStream is = new FileInputStream(file);
+               
+               // Get the size of the file
+        long length = file.length();
+    
+        if (length > Integer.MAX_VALUE) {
+            
+            throw new Exception("file is too large!");
+        }
+    
+        // Create the byte array to hold the data
+        byte[] bytes = new byte[(int)length];
+        
+        int offset = 0;
+        int numRead = 0;
+        while (offset < bytes.length
+               && (numRead=is.read(bytes, offset, bytes.length-offset)) >= 0) {
+            offset += numRead;
+        }
+    
+        // Ensure all the bytes have been read in
+        if (offset < bytes.length) {
+            throw new IOException("Could not completely read file "+file.getName());
+        }
+    
+        // Close the input stream and return bytes
+        is.close();
+        
+        
+               InformationDispersalCodec crsidacodec = new CauchyInformationDispersalCodec(10, 3, 4096);
+               
+               InformationDispersalEncoder encoder = crsidacodec.getEncoder();
+               
+               List<byte[]> result = encoder.process(bytes);
+               
+               logger.info(result.size());
+               /*
+               for(byte[] b:result){
+                       logger.debug(new String(b));
+               }
+               */
+               InformationDispersalDecoder decoder = crsidacodec.getDecoder();
+               
+               //manually remove some packets...
+               List<byte[]> receivedPackets = new ArrayList<byte[]>();
+               
+               //should need only 4 of them
+               receivedPackets.add(result.get(1));
+               receivedPackets.add(result.get(3));
+               receivedPackets.add(result.get(5));
+               receivedPackets.add(result.get(7));
+               receivedPackets.add(result.get(9));
+               
+               logger.info("Recovered string:" + new String(decoder.process(receivedPackets)));
+               
+               
+       }
+}
diff --git a/Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/test/OriginalCRSTestClass.java b/Splitter-ng-plugin-jigdfs/src/org/jigdfs/ida/test/OriginalCRSTestClass.java
new file mode 100644 (file)
index 0000000..fc9546e
--- /dev/null
@@ -0,0 +1,126 @@
+package org.jigdfs.ida.test;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+import org.jigdfs.references.ida.originalcrs.CauchyEncode;
+import org.jigdfs.references.ida.originalcrs.Parameters;
+
+public class OriginalCRSTestClass {
+       private static Logger logger = Logger.getLogger(OriginalCRSTestClass.class
+                       .getName());
+
+       public static int messageSize = 0;
+       public static int fragmentSize = 0;
+       public static int numSlices = 0;
+       public static int threshold = 0;
+
+       public static Parameters p = null;
+
+       public static void main(String[] args) {
+               String testString = "hello world";
+               byte[] testByteArray = testString.getBytes();
+
+               numSlices = 16;
+               threshold = 12;
+               // (12, 4, 4096), 12 data slices and 4 encoding slices
+               p = new Parameters(threshold, numSlices - threshold);
+
+               messageSize = p.Plen() * p.Mfragments();
+               fragmentSize = p.Plentot();
+
+               logger.debug("Slice count = " + numSlices);
+               logger.debug("threshold = " + threshold);
+               logger.debug("Message size: " + messageSize);
+               logger.debug("Fragment size: " + fragmentSize);
+
+               logger
+                               .debug("Blowup = "
+                                               + ((float) fragmentSize * (float) numSlices / (float) messageSize));
+
+               logger.debug("Ideal = " + ((float) numSlices / (float) threshold));
+
+               List<byte[]> returnBuffer = encode(testByteArray);
+               
+               logger.debug(returnBuffer.size());
+               
+               /*
+               for(byte[] b:returnBuffer){
+                       logger.debug(new String(b));
+               }
+               */
+               
+
+       }
+
+       public static List<byte[]> encode(byte buffer[]) {
+
+               int message[] = new int[messageSize];
+
+               int fragments[] = new int[fragmentSize * numSlices];
+
+               List<byte[]> outputBuffers = new ArrayList<byte[]>();
+               for (int idx = 0; idx < numSlices; idx++) {
+                       outputBuffers.add(new byte[fragmentSize]);
+               }
+
+               int inputPosition = 0;
+               int outputPosition = 0;
+
+               // Calculate the size of each output buffer
+               int outputSize = ((buffer.length + 1) / messageSize) * fragmentSize;
+
+               if ((buffer.length + 1) % messageSize != 0) {
+                       outputSize += fragmentSize;
+               }
+
+               // If the output size is greater than the pre-allocated size
+               if (outputSize > fragmentSize) {
+                       // Allocate new buffers for output
+                       outputBuffers = new ArrayList<byte[]>();
+
+                       // Allocate the output buffers
+                       for (int fragmentIdx = 0; fragmentIdx < numSlices; fragmentIdx++) {
+                               outputBuffers.add(new byte[outputSize]);
+                       }
+               }
+
+               while (outputPosition < outputSize) {
+                       byte fillerByte = 1;
+
+                       // Copy data from the input buffer into the data buffer
+
+                       for (int dataPosition = 0; dataPosition < message.length; dataPosition++) {
+                               if (inputPosition < buffer.length) {
+                                       message[dataPosition] = buffer[inputPosition++];
+                               } else {
+                                       message[dataPosition] = fillerByte;
+                                       fillerByte = 0;
+                               }
+                       }
+
+                       // Encode the data buffer into the fragments array
+
+                       CauchyEncode.encode(fragments, message, p);
+
+                       // For each fragment
+                       for (int fragmentIdx = 0; fragmentIdx < numSlices; fragmentIdx++) {
+                               byte fragment[] = outputBuffers.get(fragmentIdx);
+
+                               int fragmentOffset = fragmentIdx * fragmentSize;
+
+                               for (int idx = 0; idx < fragmentSize; idx++) {
+                                       fragment[outputPosition + idx] = (byte) fragments[fragmentOffset
+                                                       + idx];
+                               }
+                       }
+
+                       outputPosition += fragmentSize;
+               }
+
+               // this.initialized = false;
+
+               return outputBuffers;
+       }
+}
diff --git a/Splitter-ng-plugin-jigdfs/src/org/jigdfs/jxta/core/JigDFSJXTANetworkManager.java b/Splitter-ng-plugin-jigdfs/src/org/jigdfs/jxta/core/JigDFSJXTANetworkManager.java
new file mode 100644 (file)
index 0000000..16effd6
--- /dev/null
@@ -0,0 +1,103 @@
+package org.jigdfs.jxta.core;
+
+import java.io.File;
+import java.io.IOException;
+
+import net.jxta.exception.PeerGroupException;
+import net.jxta.peergroup.PeerGroup;
+import net.jxta.platform.NetworkManager;
+
+import org.apache.log4j.Logger;
+import org.jigdfs.jxta.utils.PeerNodeConfigurator;
+
+public class JigDFSJXTANetworkManager {
+    private final static Logger logger = Logger
+           .getLogger(JigDFSJXTANetworkManager.class.getName());
+
+    private static PeerGroup netPeerGroup = null;
+
+    private static NetworkManager networkManager = null;
+    
+    private static JigDFSJXTANetworkManager jigDFSJXTANetworkManager = null;
+
+    final private String peerName;
+    final private String peerPrincipal;
+    final private String peerPassword;
+    final private String peerDescritpion;
+
+    final private File configureFile;
+    
+    final private PeerNodeConfigurator peerNodeConfigurator;
+
+    public PeerGroup getJigDFSNetPeerGroupFactory() throws IOException,
+           PeerGroupException {
+       if (netPeerGroup != null) {
+           return netPeerGroup;
+       }
+       start();
+       return netPeerGroup;
+    }
+    
+    private JigDFSJXTANetworkManager(String peerName, String peerDescription, String peerPrincipal,
+           String peerPassword) throws IOException{
+       this.peerName = peerName;
+       this.peerDescritpion = peerDescription;
+       this.peerPrincipal = peerPrincipal;
+       this.peerPassword = peerPassword;
+       this.configureFile = new File(new File(".jxtaConfig"), peerName);
+       
+       this.peerNodeConfigurator = new PeerNodeConfigurator(peerName, peerDescritpion, peerPrincipal, peerPassword);
+       this.peerNodeConfigurator.configurePeer();      
+       
+    }
+    
+    public static void initJXTANetworkManager(String peerName, String peerDescription, String peerPrincipal,
+           String peerPassword) throws IOException {
+       
+       
+       jigDFSJXTANetworkManager = new JigDFSJXTANetworkManager(peerName, peerDescription, peerPrincipal, peerPassword);
+       
+       
+    }
+    public static JigDFSJXTANetworkManager getInstance(){      
+       return jigDFSJXTANetworkManager;
+    }
+
+    public void start() throws IOException, PeerGroupException {
+       if (logger.isTraceEnabled()) {
+           logger
+                   .trace("start the jxta network and get the default netpeergroup!");
+       }
+       networkManager = new NetworkManager(NetworkManager.ConfigMode.EDGE,
+               this.peerName, configureFile.toURI());
+       netPeerGroup = networkManager.startNetwork();
+    }
+    
+    
+    
+
+    public void stop() {
+       if (networkManager != null) {
+           networkManager.stopNetwork();
+           if (logger.isTraceEnabled()) {
+               logger.trace("stop the jxta network...");
+           }
+       }
+    }
+
+    /**
+     * @return the peerName
+     */
+    public String getPeerName() {
+       return peerName;
+    }
+    
+    /**
+     * @return the peerNodeConfigurator
+     */
+    public PeerNodeConfigurator getPeerNodeConfigurator() {
+       return this.peerNodeConfigurator;
+    }
+    
+    
+}
diff --git a/Splitter-ng-plugin-jigdfs/src/org/jigdfs/jxta/core/JigDFSPeerGroupFactory.java b/Splitter-ng-plugin-jigdfs/src/org/jigdfs/jxta/core/JigDFSPeerGroupFactory.java
new file mode 100644 (file)
index 0000000..0f0cf21
--- /dev/null
@@ -0,0 +1,67 @@
+package org.jigdfs.jxta.core;
+
+import net.jxta.peergroup.PeerGroup;
+import net.jxta.peergroup.PeerGroupID;
+import net.jxta.protocol.PeerGroupAdvertisement;
+
+import org.apache.log4j.Logger;
+import org.jigdfs.jxta.utils.JXTAIDFactory;
+import org.jigdfs.jxta.utils.PeerGroupUtil;
+
+public class JigDFSPeerGroupFactory {
+    
+    private final static Logger logger = Logger.getLogger(JigDFSPeerGroupFactory.class
+           .getName());
+    
+    private static PeerGroupID jigDFSPeerGroupID = null;
+    private static PeerGroup jigDFSPeerGroup = null;
+    
+    static{
+       jigDFSPeerGroupID = JXTAIDFactory.createPeerGroupID("jigdfs-jxta-group");
+    }
+    /*
+    public static PeerGroup getJigDFSPeerGroup() throws Exception {
+       if(jigDFSPeerGroup == null){
+           createJigDFSPeerGroup();
+       }
+       return jigDFSPeerGroup;
+    }
+    */
+    public synchronized static PeerGroup createJigDFSPeerGroup(PeerGroup netPeerGroup) throws Exception{
+       
+       if(jigDFSPeerGroup != null) return jigDFSPeerGroup;     
+       
+       
+               PeerGroupAdvertisement peerGroupAdv = PeerGroupUtil.create(
+                       netPeerGroup, "jigdfs-jxta-group", "jigdfs-jxta-group", null,
+                       1000l, jigDFSPeerGroupID); // no password group
+
+               jigDFSPeerGroup = netPeerGroup.newGroup(peerGroupAdv);
+
+               netPeerGroup.publishGroup(peerGroupAdv.getName(), peerGroupAdv
+                       .getDescription());
+
+               
+               // publishing new group advertisements
+               // netPGDiscoveryService.publish(peerGroupAdv);
+               // netPGDiscoveryService.remotePublish(peerGroupAdv);
+
+               logger.info("New Peer Group Successfully created :-)");
+               logger.info("Publishing new Group Advertisements.");
+               logger.info("Group Information:");
+               logger.info("[===========================]");
+               logger.info("[+]Group Name: " + peerGroupAdv.getName() + "\n");
+               logger.info("[+]Group ID:" + peerGroupAdv.getPeerGroupID().toString()
+                       + "\n");
+               logger.info("[+]Group Description: " + peerGroupAdv.getDescription()
+                       + "\n");
+               logger.info("[+]Group Module ID: "
+                       + peerGroupAdv.getModuleSpecID().toString() + "\n");
+               logger.info("[+]Advertisement Type: " + peerGroupAdv.getAdvType()
+                       + "\n");
+               logger.info("[===========================]\n");
+               
+               return jigDFSPeerGroup;
+                  
+    }
+}
diff --git a/Splitter-ng-plugin-jigdfs/src/org/jigdfs/jxta/core/JigDFSPeerNode.java b/Splitter-ng-plugin-jigdfs/src/org/jigdfs/jxta/core/JigDFSPeerNode.java
new file mode 100644 (file)
index 0000000..fa2f24f
--- /dev/null
@@ -0,0 +1,131 @@
+package org.jigdfs.jxta.core;
+
+import java.io.IOException;
+
+import org.apache.log4j.Logger;
+import org.jigdfs.jxta.exception.JXTAInvalidParametersException;
+import org.jigdfs.jxta.utils.PeerGroupUtil;
+import org.jigdfs.jxta.utils.PeerNodeConfigurator;
+
+import net.jxta.discovery.DiscoveryService;
+import net.jxta.exception.PeerGroupException;
+import net.jxta.peergroup.PeerGroup;
+import net.jxta.protocol.PeerAdvertisement;
+
+public class JigDFSPeerNode {
+    private final static Logger logger = Logger.getLogger(JigDFSPeerNode.class
+           .getName());
+
+    final private PeerNodeConfigurator peerConfig;
+
+    final private PeerGroup netPeerGroup;
+    
+
+    final private JigDFSJXTANetworkManager jigDFSJXTANetworkManager;
+
+    private String peerName = null;
+
+    private PeerGroup jigDFSPeerGroup = null;
+
+    public JigDFSPeerNode(String peerName, String peerDescription,
+           String peerPrincipal, String peerPassword)
+           throws JXTAInvalidParametersException, IOException,
+           PeerGroupException {
+
+       if (peerName.isEmpty() || peerPrincipal.isEmpty()
+               || peerPassword.isEmpty()) {
+           throw new JXTAInvalidParametersException(
+                   "peerName, peerPrincipal, peerPassword, can't be null!");
+       }
+
+       this.peerName = peerName;
+
+       JigDFSJXTANetworkManager.initJXTANetworkManager(peerName,
+               peerDescription, peerPrincipal, peerPassword);
+       jigDFSJXTANetworkManager = JigDFSJXTANetworkManager.getInstance();
+
+       peerConfig = jigDFSJXTANetworkManager.getPeerNodeConfigurator();
+
+       netPeerGroup = jigDFSJXTANetworkManager.getJigDFSNetPeerGroupFactory();
+
+    }
+
+    public void joinJigDFSPeerGroup() {
+       if (this.jigDFSPeerGroup != null) {
+
+           logger.debug("joinning the PeerGroup: "
+                   + this.jigDFSPeerGroup.getPeerGroupName());
+           logger.debug("peer name: " + this.jigDFSPeerGroup.getPeerName());
+           logger.debug("parent group name: "
+                   + this.jigDFSPeerGroup.getParentGroup().getPeerGroupName());
+
+           PeerGroupUtil.joinToGroup(this.jigDFSPeerGroup); 
+           
+       }
+    }
+    
+    public void startPublishSelf(){
+       
+       final DiscoveryService s = jigDFSPeerGroup.getDiscoveryService();
+       final PeerAdvertisement peerAdv = jigDFSPeerGroup.getPeerAdvertisement();
+       
+       new Thread(new Runnable(){
+           @Override
+           public void run() {
+               while(true){
+               logger.debug("publish peerAdv about myself");
+               
+               try {
+                       s.publish(peerAdv);
+                       s.remotePublish(peerAdv);
+                       Thread.sleep(10 * 1000);
+                   } catch (InterruptedException e) {
+                       // TODO Auto-generated catch block
+                       e.printStackTrace();
+                   } catch (IOException e) {
+                       // TODO Auto-generated catch block
+
+                       e.printStackTrace();
+                       break;
+                   }
+               }
+           }
+           
+       }).start();
+       
+    }
+
+    public String toString() {
+       return "Peer Name: " + this.peerName + "; ";
+    }
+
+    /**
+     * @return the peerName
+     */
+    public String getPeerName() {
+       return peerName;
+    }
+
+    /**
+     * @return the netPeerGroup
+     */
+    public PeerGroup getNetPeerGroup() {
+       return netPeerGroup;
+    }
+
+    /**
+     * @param jigDFSPeerGroup
+     *            the jigDFSPeerGroup to set
+     */
+    public void setJigDFSPeerGroup(PeerGroup jigDFSPeerGroup) {
+       this.jigDFSPeerGroup = jigDFSPeerGroup;
+    }
+
+    /**
+     * @return the jigDFSPeerGroup
+     */
+    public PeerGroup getJigDFSPeerGroup() {
+       return jigDFSPeerGroup;
+    }
+
+}
diff --git a/Splitter-ng-plugin-jigdfs/src/org/jigdfs/jxta/exception/JXTAAlreadyInitializedException.java b/Splitter-ng-plugin-jigdfs/src/org/jigdfs/jxta/exception/JXTAAlreadyInitializedException.java
new file mode 100644 (file)
index 0000000..4d129f2
--- /dev/null
@@ -0,0 +1,18 @@
+package org.jigdfs.jxta.exception;
+
+public class JXTAAlreadyInitializedException extends JXTAException {
+    /**
+     * 
+     */
+    private static final long serialVersionUID = -4717103229640784439L;
+
+    public JXTAAlreadyInitializedException(String reason)
+    {
+       super(reason);
+    }
+
+    public JXTAAlreadyInitializedException(String reason, Throwable cause)
+    {
+       super(reason, cause);
+    }
+}
diff --git a/Splitter-ng-plugin-jigdfs/src/org/jigdfs/jxta/exception/JXTAException.java b/Splitter-ng-plugin-jigdfs/src/org/jigdfs/jxta/exception/JXTAException.java
new file mode 100644 (file)
index 0000000..64f9a4a
--- /dev/null
@@ -0,0 +1,19 @@
+package org.jigdfs.jxta.exception;\r
+\r
+import org.jigdfs.exception.BaseException;\r
+\r
+public abstract class JXTAException extends BaseException {\r
+\r
+       /**\r
+        * generated serialVersionUID;\r
+        */\r
+       private static final long serialVersionUID = 3024954603701313929L;\r
+\r
+       public JXTAException(String reason) {\r
+               super(reason);\r
+       }\r
+\r
+       public JXTAException(String reason, Throwable cause) {\r
+               super(reason, cause);\r
+       }\r
+}
\ No newline at end of file
diff --git a/Splitter-ng-plugin-jigdfs/src/org/jigdfs/jxta/exception/JXTAInvalidParametersException.java b/Splitter-ng-plugin-jigdfs/src/org/jigdfs/jxta/exception/JXTAInvalidParametersException.java
new file mode 100644 (file)
index 0000000..1ea3fc0
--- /dev/null
@@ -0,0 +1,20 @@
+package org.jigdfs.jxta.exception;\r
+\r
+public class JXTAInvalidParametersException extends JXTAException\r
+{\r
+      \r
+   /**\r
+        * \r
+        */\r
+       private static final long serialVersionUID = -4413016304505371550L;\r
+\r
+public JXTAInvalidParametersException(String reason)\r
+   {\r
+      super(reason);\r
+   }\r
+\r
+   public JXTAInvalidParametersException(String reason, Throwable cause)\r
+   {\r
+      super(reason, cause);\r
+   }\r
+}\r
diff --git a/Splitter-ng-plugin-jigdfs/src/org/jigdfs/jxta/exception/JXTANotInitializedException.java b/Splitter-ng-plugin-jigdfs/src/org/jigdfs/jxta/exception/JXTANotInitializedException.java
new file mode 100644 (file)
index 0000000..311f510
--- /dev/null
@@ -0,0 +1,22 @@
+package org.jigdfs.jxta.exception;
+
+
+public class JXTANotInitializedException  extends JXTAException {
+   
+
+    
+    /**
+     * 
+     */
+    private static final long serialVersionUID = -6061177153055954046L;
+
+    public JXTANotInitializedException(String reason)
+    {
+       super(reason);
+    }
+
+    public JXTANotInitializedException(String reason, Throwable cause)
+    {
+       super(reason, cause);
+    }
+}
diff --git a/Splitter-ng-plugin-jigdfs/src/org/jigdfs/jxta/service/PeerGroupSearchService.java b/Splitter-ng-plugin-jigdfs/src/org/jigdfs/jxta/service/PeerGroupSearchService.java
new file mode 100644 (file)
index 0000000..2f4e8c1
--- /dev/null
@@ -0,0 +1,327 @@
+package org.jigdfs.jxta.service;
+
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.EventObject;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import net.jxta.discovery.DiscoveryEvent;
+import net.jxta.discovery.DiscoveryListener;
+import net.jxta.document.Advertisement;
+import net.jxta.exception.PeerGroupException;
+import net.jxta.peergroup.PeerGroup;
+import net.jxta.peergroup.PeerGroupID;
+import net.jxta.protocol.PeerGroupAdvertisement;
+
+import org.apache.log4j.Logger;
+import org.jigdfs.baseInterface.Listenable;
+import org.jigdfs.jxta.utils.PeerGroupUtil;
+import org.jigdfs.serivce.Service;
+import org.jigdfs.serivce.ServiceEvent;
+import org.jigdfs.serivce.ServiceListener;
+import org.jigdfs.serivce.ServiceResponseMsg;
+
+/**
+ * PeerGroupSearchSerice, now it only supports search by either PeerGroupID or
+ * by the group name, but in the future, it should support search by both
+ * 
+ * @author jbian
+ * 
+ */
+public class PeerGroupSearchService extends Service implements Listenable {
+
+    public enum SearchType {
+       PeerGroupID("GID"), Name("Name"), Description("Desc"), MSID("MSID"); // [Name,
+                                                                            // GID,
+                                                                            // Desc,
+                                                                            // MSID]
+
+       private String searchField = null;
+
+       SearchType(String searchField) {
+           this.searchField = searchField;
+       }
+
+       /**
+        * @param searchField
+        *            the searchField to set
+        */
+       public void setSearchField(String searchField) {
+           this.searchField = searchField;
+       }
+
+       /**
+        * @return the searchField
+        */
+       public String getSearchField() {
+           return searchField;
+       }
+    }
+
+    final private long WAIT_TIME = 10 * 1000;
+    final private long MAX_TRY = 5;
+
+    private static Logger logger = Logger
+           .getLogger(PeerGroupSearchService.class.getName());
+
+    private boolean isFound = false;
+
+    private Set<ServiceListener> serviceListenerList = new HashSet<ServiceListener>();
+
+    private PeerGroup netPeerGroup = null;
+
+    private PeerGroup appPeerGroup = null;
+
+    private String searchTerm = null;
+
+    /**
+     * searchType, search by PeerGroupID or PeerGroup name
+     */
+    private SearchType searchType = null;
+
+    /**
+     * constructor of this service, search based on PeerGroupID
+     * 
+     * @param peerGroupID
+     */
+    public PeerGroupSearchService(PeerGroupID peerGroupID,
+           PeerGroup netPeerGroup) {
+       this.searchTerm = peerGroupID.toString();
+       this.searchType = SearchType.PeerGroupID;
+       this.netPeerGroup = netPeerGroup;
+    }
+
+    /**
+     * constructor of this service, search based on PeerGroup name
+     * 
+     * @param peerGroupName
+     */
+    public PeerGroupSearchService(String peerGroupName, PeerGroup netPeerGroup) {
+       this.searchTerm = peerGroupName;
+       this.searchType = SearchType.Name;
+       this.netPeerGroup = netPeerGroup;
+    }
+
+    private void searchPeerGroup() throws PeerGroupException, IOException {
+       if (this.netPeerGroup == null) {
+           logger.error("netPeerGroup is null!");
+
+           return;
+       }
+
+       // search for the group locally
+       logger.debug("Searching for the group locally");
+
+       List<PeerGroupAdvertisement> peerGroupAdvsList = PeerGroupUtil
+               .getLocalPeerGroupAdvertisements(netPeerGroup, this.searchType
+                       .getSearchField(), this.searchTerm);
+
+       if (peerGroupAdvsList != null && peerGroupAdvsList.size() > 0) {
+           if (logger.isTraceEnabled()) {
+               logger.trace("JigDFS found in Local advertisement.");
+           }
+           this.appPeerGroup = netPeerGroup.newGroup(peerGroupAdvsList.get(0));
+
+           this.isFound = true;
+           ServiceResponseMsg response = new ServiceResponseMsg("PeerGroup "
+                   + this.searchTerm + " is found!", this.appPeerGroup, this);
+           ServiceEvent serviceEvent = new ServiceEvent(this, response);
+           notifyListeners(serviceEvent);
+           return;
+
+       } else {
+
+           logger.debug("No Group Found in Local advertisement.");
+           logger.debug("Starting Remote Search...");
+
+           DiscoveryListener peerGroupDiscoveryListener = new DiscoveryListener() {
+               @Override
+               public void discoveryEvent(DiscoveryEvent event) {
+
+                   logger.debug("Got a Discovery Event");
+
+                   Enumeration<Advertisement> res = event.getSearchResults();
+                   if (res != null) {
+                       if (!res.hasMoreElements()) {
+                           logger.error("empty search results...");
+                       }
+                       while (res.hasMoreElements()) {
+
+                           Advertisement adv = res.nextElement();
+
+                           logger.debug("Adv Type: "
+                                   + adv.getAdvType().toString());
+
+                           if (adv instanceof PeerGroupAdvertisement) {
+                               PeerGroupAdvertisement peerGroupAdv = (PeerGroupAdvertisement) adv;
+
+                               logger
+                                       .debug("Peer Group name from getSearchResults() = "
+                                               + peerGroupAdv.getName());
+
+                               try {
+                                   appPeerGroup = netPeerGroup
+                                           .newGroup(peerGroupAdv);
+                                   isFound = true;
+                                   ServiceResponseMsg response = new ServiceResponseMsg(
+                                           "PeerGroup "
+                                                   + PeerGroupSearchService.this.searchTerm
+                                                   + " is found!",
+                                           PeerGroupSearchService.this.appPeerGroup,
+                                           PeerGroupSearchService.this);
+                                   ServiceEvent serviceEvent = new ServiceEvent(
+                                           PeerGroupSearchService.this,
+                                           response);
+                                   notifyListeners(serviceEvent);
+
+                               } catch (PeerGroupException e) {
+                                   logger
+                                           .error("Exception while creating the PeerGroup"
+                                                   + " from the received Peer Group Advertisement"
+                                                   + e.getMessage());
+                                   e.printStackTrace();
+                               }
+
+                           } else {
+
+                               logger
+                                       .debug("The Received event is an instance of "
+                                               + adv.getClass()
+                                               + " and it will be ignored.");
+
+                           }
+                       }
+                   } else {
+                       logger.error("empty search results...");
+                   }
+
+               }
+
+           };
+
+           int count = 1;
+           while (!isFound) {
+               if (logger.isTraceEnabled()) {
+                   logger.trace("send a discory message, search for "
+                           + this.searchType.getSearchField() + "="
+                           + this.searchTerm);
+               }
+               PeerGroupUtil.discoverRemotePeerGroupAdvertisements(
+                       netPeerGroup, this.searchType.getSearchField(), "*"
+                               + this.searchTerm + "*",
+                       peerGroupDiscoveryListener);
+               try {
+                   if (logger.isTraceEnabled()) {
+                       logger.trace("wait for " + WAIT_TIME);
+                   }
+                   Thread.sleep(WAIT_TIME);
+               } catch (InterruptedException e) {
+
+                   e.printStackTrace();
+               }
+
+               if (count > MAX_TRY) {
+                   if (logger.isTraceEnabled()) {
+                       logger.trace("tried " + MAX_TRY
+                               + " times, still nothing found!");
+                   }
+
+                   ServiceResponseMsg response = new ServiceResponseMsg(
+                           "PeerGroup " + this.searchTerm + " is not found!",
+                           null, this);
+                   ServiceEvent serviceEvent = new ServiceEvent(this, response);
+                   notifyListeners(serviceEvent);
+
+                   break;
+               }
+           }
+       }
+    }
+
+    @Override
+    public void runService() throws PeerGroupException, IOException {
+       this.searchPeerGroup();
+    }
+
+    /**
+     * @param searchType
+     *            the searchType to set
+     */
+    public void setSearchType(SearchType searchType) {
+       this.searchType = searchType;
+    }
+
+    /**
+     * @return the searchType
+     */
+    public SearchType getSearchType() {
+       return searchType;
+    }
+
+    /**
+     * @param netPeerGroup
+     *            the netPeerGroup to set
+     */
+    public void setNetPeerGroup(PeerGroup netPeerGroup) {
+       this.netPeerGroup = netPeerGroup;
+    }
+
+    /**
+     * @return the netPeerGroup
+     */
+    public PeerGroup getNetPeerGroup() {
+       return netPeerGroup;
+    }
+
+    /**
+     * @param appPeerGroup
+     *            the appPeerGroup to set
+     */
+    public void setAppPeerGroup(PeerGroup appPeerGroup) {
+       this.appPeerGroup = appPeerGroup;
+    }
+
+    /**
+     * @return the appPeerGroup
+     */
+    public PeerGroup getAppPeerGroup() {
+       return appPeerGroup;
+    }
+
+    /**
+     * @return the isFound
+     */
+    public boolean isFound() {
+       return isFound;
+    }
+
+    @Override
+    public Object getResult() {
+       return this.appPeerGroup;
+    }
+
+    public void addListener(ServiceListener listener) {
+       this.serviceListenerList.add(listener);
+    }
+
+    public void removeListener(ServiceListener listener) {
+       this.serviceListenerList.remove(listener);
+    }
+
+    /**
+     * @return the serviceListenerList
+     */
+    public Set<ServiceListener> getServiceListenerList() {
+       return serviceListenerList;
+    }
+
+    @Override
+    public void notifyListeners(EventObject event) {
+       for (ServiceListener l : this.serviceListenerList) {
+           l.serviceFinishedEvent((ServiceEvent) event);
+       }
+    }
+
+}
diff --git a/Splitter-ng-plugin-jigdfs/src/org/jigdfs/jxta/test/CreatePeerGroup.java b/Splitter-ng-plugin-jigdfs/src/org/jigdfs/jxta/test/CreatePeerGroup.java
new file mode 100644 (file)
index 0000000..45183dc
--- /dev/null
@@ -0,0 +1,139 @@
+package org.jigdfs.jxta.test;
+
+import java.io.*;
+import java.util.Arrays;
+import java.util.Enumeration;
+
+import net.jxta.discovery.DiscoveryEvent;
+import net.jxta.discovery.DiscoveryListener;
+import net.jxta.discovery.DiscoveryService;
+import net.jxta.document.Advertisement;
+import net.jxta.exception.PeerGroupException;
+import net.jxta.peergroup.PeerGroup;
+import net.jxta.peergroup.PeerGroupID;
+import net.jxta.platform.NetworkManager;
+import net.jxta.protocol.PeerAdvertisement;
+import net.jxta.protocol.PeerGroupAdvertisement;
+
+import org.apache.log4j.Logger;
+
+import org.jigdfs.jxta.utils.JXTAIDFactory;
+import org.jigdfs.jxta.utils.PeerGroupUtil;
+
+public class CreatePeerGroup {
+       private final static Logger logger = Logger.getLogger(CreatePeerGroup.class
+                       .getName());
+
+       public static void main(String[] args) throws Exception {
+               /*
+                * JigDFSPeerNode jigDFSPeerNode = new JigDFSPeerNode("test-1",
+                * "principal", "password");
+                * 
+                * final PeerGroup netPeerGroup = jigDFSPeerNode.getNetPeerGroup();
+                */
+               NetworkManager networkManager =  new NetworkManager(NetworkManager.ConfigMode.ADHOC, "NetPeerGroup", new File(new File(".cache"), "NetPeerGroup").toURI());
+               final PeerGroup netPeerGroup = networkManager.startNetwork();
+
+               final PeerGroupID peerGroupID = JXTAIDFactory
+                               .createPeerGroupID("jigdfs-jxta-group");
+               final PeerGroupAdvertisement peerGroupAdv = PeerGroupUtil.create(
+                               netPeerGroup, "jigdfs-jxta-group", "jigdfs-jxta-group",
+                               "whatever", 1000l, peerGroupID);
+               
+               logger.info(Arrays.asList(peerGroupAdv.getIndexFields()));
+               
+               final PeerGroup jigDFSPeerGroup = netPeerGroup.newGroup(peerGroupAdv);
+               
+               final DiscoveryListener peerDiscoveryListener = new DiscoveryListener(){
+
+                       @Override
+                       public void discoveryEvent(DiscoveryEvent event) {
+                               if (logger.isTraceEnabled()) {
+                                       logger.trace("Got a Discovery Event");
+                                   }
+
+                                   Enumeration<Advertisement> res = event.getSearchResults();
+                                   if (res != null) {
+                                       if (!res.hasMoreElements()) {
+                                           logger.error("empty search results...");
+                                       }
+                                       while (res.hasMoreElements()) {
+                                          
+                                           Advertisement adv = res.nextElement();
+                                           if (logger.isTraceEnabled()) {
+                                               logger.trace("Adv Type: "
+                                                       + adv.getAdvType().toString());
+                                           }
+
+                                           if (adv instanceof PeerAdvertisement) {
+                                               PeerAdvertisement peerAdv = (PeerAdvertisement) adv;                                            
+                                               logger.debug("i found Peer " + peerAdv.getName());
+                                           } else {
+                                               if (logger.isTraceEnabled()) {
+                                                   logger
+                                                           .trace("The Received event is an instance of "
+                                                                   + adv.getClass()
+                                                                   + " and it will be ignored.");
+                                               }
+
+                                           }
+                                       }
+                                   } else {
+                                       logger.error("empty search results...");
+                                   }           
+                       }
+                       
+               };
+               
+               final DiscoveryService jigDFSGroupDiscoveryService = jigDFSPeerGroup.getDiscoveryService();
+               
+               new Thread(new Runnable() {
+                       @Override
+                       public void run() {
+                               while (true) {
+                                       logger.info("send discovery message to search for peers!");
+                                       jigDFSGroupDiscoveryService.getRemoteAdvertisements(null, DiscoveryService.PEER, null, null, 10, peerDiscoveryListener);
+                                       
+                                       try {
+                                               Thread.sleep(20000);
+                                       } catch (InterruptedException e) {
+                                               // TODO Auto-generated catch block
+                                               e.printStackTrace();
+                                       }
+                               }
+                       }
+               }).start();
+
+               final DiscoveryService s = netPeerGroup.getDiscoveryService();
+               
+               new Thread(new Runnable() {
+
+                       @Override
+                       public void run() {
+                               while (true) {
+                                       logger.info("publish the group!");
+
+                                       try {
+                                               s.publish(jigDFSPeerGroup.getAllPurposePeerGroupImplAdvertisement());
+                                               s.remotePublish(jigDFSPeerGroup.getAllPurposePeerGroupImplAdvertisement());
+                                               jigDFSPeerGroup.publishGroup("jigdfs-jxta-group",
+                                                               "jigdfs-jxta-group");
+                                               Thread.sleep(20000);
+                                       } catch (IOException e) {
+                                               // TODO Auto-generated catch block
+                                               e.printStackTrace();
+                                       } catch (InterruptedException e) {
+                                               // TODO Auto-generated catch block
+                                               e.printStackTrace();
+                                       } catch (Exception e) {
+                                               // TODO Auto-generated catch block
+                                               e.printStackTrace();
+                                       }
+
+                               }
+                       }
+
+               }).start();
+       }
+
+}
diff --git a/Splitter-ng-plugin-jigdfs/src/org/jigdfs/jxta/test/PeerGroupSearchTest.java b/Splitter-ng-plugin-jigdfs/src/org/jigdfs/jxta/test/PeerGroupSearchTest.java
new file mode 100644 (file)
index 0000000..d2f55cf
--- /dev/null
@@ -0,0 +1,130 @@
+package org.jigdfs.jxta.test;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Enumeration;
+
+import net.jxta.discovery.DiscoveryEvent;
+import net.jxta.discovery.DiscoveryListener;
+import net.jxta.discovery.DiscoveryService;
+import net.jxta.document.Advertisement;
+import net.jxta.exception.PeerGroupException;
+import net.jxta.peergroup.PeerGroup;
+import net.jxta.peergroup.PeerGroupID;
+import net.jxta.platform.NetworkManager;
+import net.jxta.protocol.PeerGroupAdvertisement;
+
+import org.apache.log4j.Logger;
+import org.jigdfs.jxta.core.JigDFSPeerNode;
+import org.jigdfs.jxta.exception.JXTAInvalidParametersException;
+import org.jigdfs.jxta.service.PeerGroupSearchService.SearchType;
+import org.jigdfs.jxta.utils.JXTAIDFactory;
+import org.jigdfs.jxta.utils.PeerGroupUtil;
+
+public class PeerGroupSearchTest {
+
+    private final static Logger logger = Logger.getLogger(PeerGroupSearchTest.class
+           .getName());
+    /**
+     * @param args
+     * @throws IOException 
+     * @throws PeerGroupException 
+     * @throws JXTAInvalidParametersException 
+     */
+    public static void main(String[] args) throws JXTAInvalidParametersException, PeerGroupException, IOException {
+       /*JigDFSPeerNode jigDFSPeerNode = new JigDFSPeerNode("test-0", "principal", "password" );
+       
+       final PeerGroup netPeerGroup = jigDFSPeerNode.getNetPeerGroup();
+       */
+       
+       NetworkManager networkManager =  new NetworkManager(NetworkManager.ConfigMode.ADHOC, "NetPeerGroup",  new File(new File(".cache"), "NetPeerGroup").toURI());
+       
+       final PeerGroup netPeerGroup = networkManager.startNetwork();
+       
+       
+       DiscoveryListener peerGroupDiscoveryListener = new DiscoveryListener() {
+               @Override
+               public void discoveryEvent(DiscoveryEvent event) {
+                   
+                   if (logger.isTraceEnabled()) {
+                       logger.trace("Got a Discovery Event");
+                   }
+
+                   Enumeration<Advertisement> res = event.getSearchResults();
+                   if (res != null) {
+                       if (!res.hasMoreElements()) {
+                           logger.error("empty search results...");
+                       }
+                       while (res.hasMoreElements()) {
+                          
+                           Advertisement adv = res.nextElement();
+                           if (logger.isTraceEnabled()) {
+                               logger.trace("Adv Type: "
+                                       + adv.getAdvType().toString());
+                           }
+
+                           if (adv instanceof PeerGroupAdvertisement) {
+                               PeerGroupAdvertisement peerGroupAdv = (PeerGroupAdvertisement) adv;
+                               if (logger.isTraceEnabled()) {
+                                   logger
+                                           .trace("Peer Group name from getSearchResults() = "
+                                                   + peerGroupAdv.getName());
+                               }
+                               try {
+                                   PeerGroup appPeerGroup = netPeerGroup.newGroup(peerGroupAdv);
+                                   logger.info("found " + appPeerGroup.getPeerGroupName());
+                                   logger.info("-----------------------------------------");
+                                   logger.info(appPeerGroup.getParentGroup().getPeerGroupName());
+                                   logger.info(appPeerGroup.getPeerGroupID());
+                                   logger.info("-----------------------------------------");
+                                   System.exit(0);
+                                   
+                               } catch (PeerGroupException e) {
+                                   logger
+                                           .error("Exception while creating the PeerGroup"
+                                                   + " from the received Peer Group Advertisement"
+                                                   + e.getMessage());
+                                   e.printStackTrace();
+                               }
+
+                           } else {
+                               if (logger.isTraceEnabled()) {
+                                   logger
+                                           .trace("The Received event is an instance of "
+                                                   + adv.getClass()
+                                                   + " and it will be ignored.");
+                               }
+
+                           }
+                       }
+                   } else {
+                       logger.error("empty search results...");
+                   }
+
+               }
+
+           };
+           
+           final PeerGroupID peerGroupID = JXTAIDFactory
+               .createPeerGroupID("jigdfs-jxta-group");
+           
+           final DiscoveryService s = netPeerGroup.getDiscoveryService();
+
+           long waittime = 6 * 1000L;
+           
+           while(true){
+               try {
+                    System.out.println("Sleeping for :" + waittime);
+                    Thread.sleep(waittime);
+                } catch (Exception e) {
+                    // ignored
+                }
+                System.out.println("Sending a Discovery Message");
+               s.getRemoteAdvertisements(null, DiscoveryService.GROUP, null, null, 10, peerGroupDiscoveryListener);
+           }
+           //System.in.read();
+       // PeerGroupUtil.discoverRemotePeerGroupAdvertisements(netPeerGroup, "NAME", "jigdfs-jxta-group", peerGroupDiscoveryListener);
+
+    }
+
+}
diff --git a/Splitter-ng-plugin-jigdfs/src/org/jigdfs/jxta/test/PeerGroupTest.java b/Splitter-ng-plugin-jigdfs/src/org/jigdfs/jxta/test/PeerGroupTest.java
new file mode 100644 (file)
index 0000000..7d72e59
--- /dev/null
@@ -0,0 +1,43 @@
+package org.jigdfs.jxta.test;
+
+import java.io.File;
+import java.util.Arrays;
+
+import net.jxta.exception.PeerGroupException;
+import net.jxta.peergroup.NetPeerGroupFactory;
+import net.jxta.peergroup.PeerGroup;
+import net.jxta.peergroup.PeerGroupID;
+import net.jxta.platform.NetworkConfigurator;
+import net.jxta.protocol.ConfigParams;
+import net.jxta.protocol.PeerGroupAdvertisement;
+
+import org.apache.log4j.Logger;
+import org.jigdfs.jxta.utils.JXTAIDFactory;
+import org.jigdfs.jxta.utils.PeerGroupUtil;
+
+public class PeerGroupTest {
+       private static Logger logger = Logger.getLogger(PeerGroupTest.class.getName());
+       
+       public static void main(String[] args) throws Exception {
+               String peerName = "test";
+               
+               NetworkConfigurator localConfig = new NetworkConfigurator(
+                               NetworkConfigurator.EDGE_NODE, new File(new File(
+                                               ".jxtaConfig"), peerName).toURI());
+               
+               NetPeerGroupFactory factory = new NetPeerGroupFactory(
+                               (ConfigParams) localConfig.getPlatformConfig(), new File(
+                                               new File(".jxtaConfig"), peerName).toURI());
+               
+               PeerGroup netPeerGroup = factory.getInterface();
+               PeerGroupID peerGroupID = JXTAIDFactory.createPeerGroupID("jigdfs-jxta-group");
+               PeerGroupAdvertisement peerGroupAdv = PeerGroupUtil.create(netPeerGroup, "jigdfs-jxta-group", "jigdfs-jxta-group", "whatever", 1000l, peerGroupID);
+               
+               
+               
+               logger.info(Arrays.asList(peerGroupAdv.getIndexFields()));
+
+               
+
+       }
+}
diff --git a/Splitter-ng-plugin-jigdfs/src/org/jigdfs/jxta/test/PeerTest.java b/Splitter-ng-plugin-jigdfs/src/org/jigdfs/jxta/test/PeerTest.java
new file mode 100644 (file)
index 0000000..37ba83d
--- /dev/null
@@ -0,0 +1,83 @@
+package org.jigdfs.jxta.test;
+
+import java.io.IOException;
+
+import net.jxta.discovery.DiscoveryEvent;
+import net.jxta.discovery.DiscoveryListener;
+import net.jxta.exception.PeerGroupException;
+import net.jxta.peergroup.PeerGroup;
+
+import org.apache.log4j.Logger;
+import org.jigdfs.jxta.core.JigDFSPeerNode;
+import org.jigdfs.jxta.exception.JXTAInvalidParametersException;
+import org.jigdfs.jxta.service.PeerGroupSearchService;
+import org.jigdfs.serivce.ServiceEvent;
+import org.jigdfs.serivce.ServiceListener;
+
+public class PeerTest {
+    private final static Logger logger = Logger.getLogger(PeerTest.class
+           .getName());
+    
+    public static void main(String[] args) throws JXTAInvalidParametersException, PeerGroupException, IOException{
+       final JigDFSPeerNode jigDFSPeerNode = new JigDFSPeerNode("test-0", "i am test-0", "test-0", "iloveusm" );
+       
+       logger.info("create searchListener");
+       
+       final PeerGroupSearchService peerGroupSearchService = new PeerGroupSearchService("jigdfs-jxta-group", jigDFSPeerNode.getNetPeerGroup());
+       
+       ServiceListener searchListener = new ServiceListener(){
+           @Override
+           public void serviceFinishedEvent(ServiceEvent event) {
+               logger.info("get an event " + event.getSource().getClass().getName());
+               Object result = event.getServiceResponseMsg().getResult();
+               
+               if(result != null && result instanceof PeerGroup) {
+                   PeerGroup jigDFSPeerGroup = (PeerGroup) result;                 
+                  
+                   logger.info("i found gorup " + jigDFSPeerGroup.getPeerGroupName());
+                   jigDFSPeerNode.setJigDFSPeerGroup(jigDFSPeerGroup);
+                   jigDFSPeerNode.joinJigDFSPeerGroup();
+                   jigDFSPeerNode.startPublishSelf();
+                       
+                   peerGroupSearchService.removeListener(this);
+               }
+               
+               
+           }
+           
+       };
+       
+       
+       peerGroupSearchService.addListener(searchListener);
+       
+       
+       
+       new Thread(new Runnable(){
+           @Override
+           public void run() {
+               try {
+                   peerGroupSearchService.runService();
+               } catch (PeerGroupException e) {
+                   // TODO Auto-generated catch block
+                   e.printStackTrace();
+               } catch (IOException e) {
+                   // TODO Auto-generated catch block
+                   e.printStackTrace();
+               }               
+           }
+           
+       }).start();
+       
+       while(!peerGroupSearchService.isFound()){
+           try {
+               logger.info("not found! keep waiting");
+               Thread.sleep(10*1000);
+           } catch (InterruptedException e) {
+               // TODO Auto-generated catch block
+               e.printStackTrace();
+           }
+       }
+       
+       
+    }
+}
diff --git a/Splitter-ng-plugin-jigdfs/src/org/jigdfs/jxta/utils/JXTAIDFactory.java b/Splitter-ng-plugin-jigdfs/src/org/jigdfs/jxta/utils/JXTAIDFactory.java
new file mode 100644 (file)
index 0000000..64b6449
--- /dev/null
@@ -0,0 +1,85 @@
+package org.jigdfs.jxta.utils;\r
+\r
+import org.apache.log4j.Logger;\r
+import org.bouncycastle.crypto.Digest;\r
+import org.bouncycastle.crypto.digests.SHA256Digest;\r
+import org.bouncycastle.util.encoders.Hex;\r
+\r
+import net.jxta.id.IDFactory;\r
+import net.jxta.peer.PeerID;\r
+import net.jxta.peergroup.PeerGroupID;\r
+\r
+public class JXTAIDFactory {\r
+       private static Logger logger = Logger.getLogger(JXTAIDFactory.class\r
+                       .getName());\r
+\r
+       private static final String SEED = "jigdfs-whatever";\r
+\r
+       /**\r
+        * Given a peer name generates a Peer ID who's value is chosen based upon\r
+        * that name.\r
+        * \r
+        * @param peerName\r
+        *            instance name\r
+        * @param peerGroupID\r
+        *            the group ID encoding\r
+        * @return The PeerID value\r
+        */\r
+       public static PeerID createPeerID(final PeerGroupID peerGroupID, final String peerName) {\r
+               // Use lower case to avoid any locale conversion inconsistencies\r
+               String seed = (peerName + SEED).toLowerCase();\r
+\r
+               byte[] digestByteArray = getSHA256Hash(seed);\r
+\r
+               if (logger.isTraceEnabled()) {\r
+                       logger.trace("Peer: " + peerName + "; seed Hash Value: "\r
+                                       + new String(Hex.encode(digestByteArray)));\r
+               }\r
+\r
+               return IDFactory.newPeerID(peerGroupID, digestByteArray);\r
+       }\r
+       \r
+       \r
+       /**\r
+     * Given a group name generates a Peer Group ID who's value is chosen based upon that name.\r
+     *\r
+     * @param groupName group name encoding value\r
+     * @return The PeerGroupID value\r
+     */\r
+    public static PeerGroupID createPeerGroupID(final String groupName) {\r
+        // Use lower case to avoid any locale conversion inconsistencies\r
+       String seed = (groupName + SEED).toLowerCase();\r
+\r
+               byte[] digestByteArray = getSHA256Hash(seed);\r
+               \r
+               if (logger.isTraceEnabled()) {\r
+                       logger.trace("PeerGroup Name: " + groupName + "; seed Hash Value: "\r
+                                       + new String(Hex.encode(digestByteArray)));\r
+               }\r
+               \r
+               \r
+        return IDFactory.newPeerGroupID(PeerGroupID.defaultNetPeerGroupID, digestByteArray);\r
+    }\r
+    \r
+    \r
+    private static byte[] getSHA256Hash(final String input){\r
+        // Use lower case to avoid any locale conversion inconsistencies\r
+       String seed = (input + SEED).toLowerCase();\r
+\r
+               byte[] seedByteArray = seed.getBytes();\r
+\r
+               Digest digestFunc = new SHA256Digest();\r
+               if (logger.isTraceEnabled()) {\r
+                       logger.trace("Digest Function: " + digestFunc.getAlgorithmName()\r
+                                       + "Digest Size: " + digestFunc.getDigestSize());\r
+               }\r
+\r
+               byte[] digestByteArray = new byte[digestFunc.getDigestSize()];\r
+\r
+               digestFunc.update(seedByteArray, 0, seedByteArray.length);\r
+\r
+               digestFunc.doFinal(digestByteArray, 0);\r
+\r
+               return seedByteArray;\r
+    }\r
+}\r
diff --git a/Splitter-ng-plugin-jigdfs/src/org/jigdfs/jxta/utils/PeerGroupUtil.java b/Splitter-ng-plugin-jigdfs/src/org/jigdfs/jxta/utils/PeerGroupUtil.java
new file mode 100644 (file)
index 0000000..81729c1
--- /dev/null
@@ -0,0 +1,341 @@
+/*
+*  Copyright (c) 2001 Sun Microsystems, Inc.  All rights
+*  reserved.
+*
+*  Redistribution and use in source and binary forms, with or without
+*  modification, are permitted provided that the following conditions
+*  are met:
+*
+*  1. Redistributions of source code must retain the above copyright
+*  notice, this list of conditions and the following disclaimer.
+*
+*  2. 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.
+*
+*  3. The end-user documentation included with the redistribution,
+*  if any, must include the following acknowledgment:
+*  "This product includes software developed by the
+*  Sun Microsystems, Inc. for Project JXTA."
+*  Alternately, this acknowledgment may appear in the software itself,
+*  if and wherever such third-party acknowledgments normally appear.
+*
+*  4. The names "Sun", "Sun Microsystems, Inc.", "JXTA" and "Project JXTA"
+*  must not be used to endorse or promote products derived from this
+*  software without prior written permission. For written
+*  permission, please contact Project JXTA at http://www.jxta.org.
+*
+*  5. Products derived from this software may not be called "JXTA",
+*  nor may "JXTA" appear in their name, without prior written
+*  permission of Sun.
+*
+*  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 APACHE SOFTWARE FOUNDATION OR
+*  ITS 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 software consists of voluntary contributions made by many
+*  individuals on behalf of Project JXTA.  For more
+*  information on Project JXTA, please see
+*  <http://www.jxta.org/>.
+*
+*  This license is based on the BSD license adopted by the Apache Foundation.
+*
+*  $Id: PeerGroupUtil.java,v 1.7 2007/05/28 22:00:51 nano Exp $
+*/
+
+package org.jigdfs.jxta.utils;
+
+import net.jxta.credential.AuthenticationCredential;
+import net.jxta.credential.Credential;
+import net.jxta.discovery.DiscoveryListener;
+import net.jxta.discovery.DiscoveryService;
+import net.jxta.document.*;
+import net.jxta.id.ID;
+import net.jxta.id.IDFactory;
+import net.jxta.impl.membership.passwd.PasswdMembershipService;
+import net.jxta.membership.Authenticator;
+import net.jxta.membership.MembershipService;
+import net.jxta.peergroup.PeerGroup;
+import net.jxta.peergroup.PeerGroupID;
+import net.jxta.platform.ModuleClassID;
+import net.jxta.platform.ModuleSpecID;
+import net.jxta.protocol.ModuleImplAdvertisement;
+import net.jxta.protocol.PeerGroupAdvertisement;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.*;
+
+import org.apache.log4j.Logger;
+import org.jigdfs.jxta.core.JigDFSPeerNode;
+import org.jigdfs.jxta.exception.JXTAInvalidParametersException;
+
+
+/**
+ * @author james todd [gonzo at jxta dot org]
+ * @version $Id: PeerGroupUtil.java,v 1.7 2007/05/28 22:00:51 nano Exp $
+ */
+
+public class PeerGroupUtil {
+
+    private final static Logger logger = Logger.getLogger(PeerGroupUtil.class
+           .getName());
+    
+    public static final String MEMBERSHIP_ID = "jigdfs-user";
+
+    private static final long MILLISECONDS_IN_A_WEEK = 7 * 24 * 60 * 60 * 1000;
+
+    /**
+     * Create a new PeerGroupAdvertisment  from which a
+     * new PeerGroup will be created.
+     * <p/>
+     * See "Create a Secure Peer Group" in
+     * <a href="http://www.jxta.org/docs/JxtaProgGuide_v2.pdf">Jxta
+     * Programmers Guide</a> for how to create a secure group. Most
+     * of the code in this class is taken direcly from that chapter
+     *
+     * @param parentGroup the parent PeerGroup
+     * @param name        the name of the new PeerGroup
+     * @param description the description of the new PeerGroup
+     * @param password    the password for the new Peergroup.
+     *                    If it is null or an empty string this
+     *                    peer group is not password protected
+     * @return a new  PeerGroupAdvertisement
+     */
+    public static PeerGroupAdvertisement create(PeerGroup parentGroup, String name,
+                                                String description, String password, long expiration)
+            throws Exception {
+        return create(parentGroup, name, description, password, expiration, null);
+    }
+
+    public static PeerGroupAdvertisement create(PeerGroup parentGroup, String name,
+                                                String description, String password, long expiration, PeerGroupID id)
+            throws Exception {
+        PeerGroupAdvertisement pga;
+        ModuleImplAdvertisement mia;
+        boolean passProt = (password != null &&
+                !password.trim().equals(""));
+
+        // create the ModuleImplAdvertisement and publish it
+        mia = parentGroup.getAllPurposePeerGroupImplAdvertisement();
+
+        if (passProt) {
+            createPasswordModuleImpl(mia);
+        }
+
+        parentGroup.getDiscoveryService().publish(mia);
+        parentGroup.getDiscoveryService().remotePublish(mia);
+
+        // create the PeerGroupAdvertisment and publish it
+        pga = (PeerGroupAdvertisement) AdvertisementFactory.newAdvertisement(
+                PeerGroupAdvertisement.getAdvertisementType());
+        pga.setPeerGroupID(id != null ? id : IDFactory.newPeerGroupID());
+        pga.setName(name);
+        pga.setDescription(description);
+        pga.setModuleSpecID(mia.getModuleSpecID());
+
+        if (passProt) {
+            StructuredTextDocument login =
+                    (StructuredTextDocument)
+                            StructuredDocumentFactory.newStructuredDocument(
+                                    MimeMediaType.XMLUTF8, "Param");
+            String loginString =
+                    MEMBERSHIP_ID + ":" + PasswdMembershipService.makePsswd(password) +
+                            ":";
+            TextElement loginElement =
+                    login.createElement("login", loginString);
+
+            login.appendChild(loginElement);
+            pga.putServiceParam(PeerGroup.membershipClassID, login);
+        }
+
+        DiscoveryService ds = parentGroup.getDiscoveryService();
+
+        ds.publish(pga, expiration != 0 ?
+                expiration : 2 * MILLISECONDS_IN_A_WEEK,
+                expiration != 0 ? expiration : 2 * MILLISECONDS_IN_A_WEEK);
+        ds.remotePublish(pga, expiration != 0 ?
+                expiration : 2 * MILLISECONDS_IN_A_WEEK);
+
+        return pga;
+    }
+
+    // indexed field [Name, GID, Desc, MSID]
+    public static List<PeerGroupAdvertisement> getLocalPeerGroupAdvertisements(PeerGroup pg, String fieldName, String value) {
+        List<PeerGroupAdvertisement> p = new ArrayList<PeerGroupAdvertisement>();
+
+        try {
+            for (Enumeration<Advertisement> gas = pg.getDiscoveryService().
+                    getLocalAdvertisements(DiscoveryService.GROUP,
+                               (fieldName != null ? fieldName : null), value);
+                 gas.hasMoreElements();) {
+                Object o = gas.nextElement();
+
+                if (o instanceof PeerGroupAdvertisement) {
+                    p.add((PeerGroupAdvertisement) o);
+                }
+            }
+        } catch (IOException ioe) {
+        }
+
+        return p;
+    }
+
+    public static void discoverRemotePeerGroupAdvertisements(PeerGroup pg, String fieldName, String value,
+                                    DiscoveryListener listener) {
+       
+        DiscoveryService s = pg.getDiscoveryService();
+
+        s.getRemoteAdvertisements(null, DiscoveryService.GROUP,
+                       (fieldName != null ? fieldName : null), value, 10, listener);
+    }
+
+    /**
+     * Updates the ModuleImplAdvertisement  of the PeerGroupAdvertisement
+     * to reflect the fact that we want to use the PasswordService in order
+     * to manage the membership in this group
+     *
+     * @param mia the ModuleImplAdvertisement  to update
+     */
+    private static void createPasswordModuleImpl(ModuleImplAdvertisement mia)
+            throws Exception {
+        StdPeerGroupParamAdv stdPgParams = new StdPeerGroupParamAdv(mia.getParam());
+        Map<ModuleClassID, Object> params = stdPgParams.getServices();
+        boolean found = false;
+
+        // loop until the MembershipService is found
+        for (Iterator<ModuleClassID> pi = params.keySet().iterator();
+             pi.hasNext() && !found;) {
+            ModuleClassID serviceID = pi.next();
+
+            if (serviceID.equals(PeerGroup.membershipClassID)) {
+                // get the  Advertisement for the MembershipService
+                ModuleImplAdvertisement memServices = (ModuleImplAdvertisement)
+                        params.get(serviceID);
+
+                // create a new Advertisement describing the password service
+                ModuleImplAdvertisement newMemServices =
+                        createPasswordServiceImpl(memServices);
+
+                // update the services hashtable
+                params.remove(serviceID);
+                params.put(PeerGroup.membershipClassID, newMemServices);
+                found = true;
+
+                // and update the Service parameters list for the
+                // ModuleImplAdvertisement
+                mia.setParam((Element) stdPgParams.getDocument(
+                        MimeMediaType.XMLUTF8));
+
+                // change the ModuleSpecID since this
+                if (!mia.getModuleSpecID().equals(
+                        PeerGroup.allPurposePeerGroupSpecID)) {
+                    mia.setModuleSpecID(IDFactory.newModuleSpecID(
+                            mia.getModuleSpecID().getBaseClass()));
+                } else {
+                    ID passID = ID.nullID;
+
+                    try {
+                        passID = IDFactory.fromURI(new URI("urn", "jxta:uuid-" +
+                                "DeadBeefDeafBabaFeedBabe00000001" +
+                                "04" + "06", null));
+                    } catch (URISyntaxException use) {
+                        use.printStackTrace();
+                    }
+
+                    mia.setModuleSpecID((ModuleSpecID) passID);
+                }
+            }
+        }
+    }
+
+    /**
+     * Create the ModuleImplAdvertisement that describes the
+     * PasswordService that this group is going to use
+     *
+     * @param template the previous ModuleImplAdvertisement that we use as
+     *                 a template
+     * @return the  ModuleImplAdvertisement that describes the
+     *         PasswordService that this group is going to use
+     */
+    private static ModuleImplAdvertisement createPasswordServiceImpl(
+            ModuleImplAdvertisement template) {
+        ModuleImplAdvertisement passMember = (ModuleImplAdvertisement)
+                AdvertisementFactory.newAdvertisement(
+                        ModuleImplAdvertisement.getAdvertisementType());
+
+        passMember.setModuleSpecID(PasswdMembershipService.passwordMembershipSpecID);
+        passMember.setCode(PasswdMembershipService.class.getName());
+        passMember.setDescription("Membership Services for MyJXTA");
+        passMember.setCompat(template.getCompat());
+        passMember.setUri(template.getUri());
+        passMember.setProvider(template.getProvider());
+
+        return passMember;
+    }
+    
+    public static void joinToGroup(PeerGroup group) //This method will join to either found group or created group
+    {
+        StructuredDocument creds = null;
+        
+        logger.debug("Joining into " + group.getPeerGroupName() + "...");    
+        
+        
+        try{
+            //Athenticate and join to group
+        AuthenticationCredential authCred = new AuthenticationCredential(group,null,creds);
+        MembershipService membership = group.getMembershipService();
+        Authenticator auth = membership.apply(authCred);
+            if(auth.isReadyForJoin()){
+                Credential myCred = membership.join(auth);
+                
+                logger.debug("===== Group Details =====");
+                             
+                
+                StructuredTextDocument doc = (StructuredTextDocument)myCred.getDocument(new MimeMediaType("text/plain"));
+                StringWriter out = new StringWriter();
+                doc.sendToWriter(out);
+                
+                //System.out.println(out.toString());
+                if(logger.isTraceEnabled()){
+                    logger.trace(out.toString());
+                    
+                }
+                
+                //Publishing Peer Advertisements.
+                DiscoveryService groupDiscoveryService = group.getDiscoveryService();
+                
+                logger.debug("Peer Name : " + group.getPeerName() + " is now online :-)");
+                logger.debug("Obtaining SaEeDGroup Services.");
+                logger.debug("Publishing Peer Advertisement.");
+                
+                
+                groupDiscoveryService.publish(group.getPeerAdvertisement());
+                groupDiscoveryService.remotePublish(group.getPeerAdvertisement());
+                
+                logger.debug("[===========================]\n");
+            }
+            else{
+               logger.fatal("[!!]Fatal Error: Cannot Join to The Group!");
+                //System.exit(-1);
+            }            
+        }catch(Exception e){
+               logger.fatal("[!]Fatal Error: " + e.getMessage());
+                e.printStackTrace();
+                //System.exit(-1);
+            }
+    }
+}
diff --git a/Splitter-ng-plugin-jigdfs/src/org/jigdfs/jxta/utils/PeerNodeConfigurator.java b/Splitter-ng-plugin-jigdfs/src/org/jigdfs/jxta/utils/PeerNodeConfigurator.java
new file mode 100644 (file)
index 0000000..f4b8e93
--- /dev/null
@@ -0,0 +1,59 @@
+package org.jigdfs.jxta.utils;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.log4j.Logger;
+import org.jigdfs.jxta.core.JigDFSPeerNode;
+
+import net.jxta.platform.NetworkConfigurator;
+import net.jxta.platform.NetworkManager;
+
+public class PeerNodeConfigurator {
+    private final static Logger logger = Logger.getLogger(JigDFSPeerNode.class
+           .getName());
+
+    final private String peerName;
+    final private String peerPrincipal;
+    final private String peerPassword;
+    final private String peerDescritpion;
+
+    final private File configureFile;
+
+    public PeerNodeConfigurator(String peerName, String peerDescritpion, String peerPrincipal,
+           String peerPassword) {
+       this.peerName = peerName;
+       this.peerDescritpion = peerDescritpion;
+       this.peerPrincipal = peerPrincipal;
+       this.peerPassword = peerPassword;
+       this.configureFile = new File(new File(".jxtaConfig"), peerName);
+    }
+
+    public void configurePeer() throws IOException {
+       NetworkConfigurator configurator = new NetworkConfigurator(
+               NetworkConfigurator.EDGE_NODE, this.configureFile.toURI());
+       if (configurator.exists()) {
+           if (logger.isTraceEnabled()) {
+               logger.trace("local Config exist");
+           }
+
+       } else {
+           NetworkManager networkManager = new NetworkManager(NetworkManager.ConfigMode.EDGE, peerName, configureFile.toURI());
+            networkManager.setUseDefaultSeeds(true);
+            networkManager.setConfigPersistent(true);
+            
+            configurator = networkManager.getConfigurator();
+            
+            configurator.setName(peerName);
+            configurator.setPrincipal(peerPrincipal);
+            configurator.setPassword(peerPassword);
+
+           
+            configurator.save();
+
+       }
+       
+    }
+
+    
+}
diff --git a/Splitter-ng-plugin-jigdfs/src/org/jigdfs/jxta/utils/StdPeerGroupParamAdv.java b/Splitter-ng-plugin-jigdfs/src/org/jigdfs/jxta/utils/StdPeerGroupParamAdv.java
new file mode 100644 (file)
index 0000000..913e6bc
--- /dev/null
@@ -0,0 +1,279 @@
+package org.jigdfs.jxta.utils;\r
+\r
+import net.jxta.document.*;\r
+import net.jxta.id.IDFactory;\r
+import net.jxta.logging.Logging;\r
+import net.jxta.peergroup.PeerGroup;\r
+import net.jxta.platform.ModuleClassID;\r
+import net.jxta.platform.ModuleSpecID;\r
+import net.jxta.protocol.ModuleImplAdvertisement;\r
+\r
+import java.net.URI;\r
+import java.util.Enumeration;\r
+import java.util.HashMap;\r
+import java.util.Map;\r
+import java.util.logging.Level;\r
+import java.util.logging.Logger;\r
+\r
+/**\r
+ * Not actually an advertisement, but often acts as part of one.\r
+ *\r
+ * This internal class will eventually be removed. It has several\r
+ * problems which make it difficult to support. (The most obvious that it\r
+ * provides poor abstraction and provides references to its' own internal data\r
+ * structures). This class is expected to be replaced by a public API class\r
+ * performing a similar function though such an alternative is not yet available.\r
+ * You are encouraged to copy this code into your own application or service if\r
+ * if you depend upon it.\r
+ *\r
+ * Nanosek: class was moved into the myjxta repository\r
+ */\r
+public class StdPeerGroupParamAdv {\r
+\r
+    /**\r
+     * Logger\r
+     */\r
+    private static final Logger LOG = Logger.getLogger(StdPeerGroupParamAdv.class.getName());\r
+\r
+    private static final String PARAM_TAG = "Parm";\r
+    private static final String PROTO_TAG = "Proto";\r
+    private static final String APP_TAG = "App";\r
+    private static final String SVC_TAG = "Svc";\r
+    private static final String MCID_TAG = "MCID";\r
+    private static final String MSID_TAG = "MSID";\r
+    private static final String MIA_TAG = ModuleImplAdvertisement.getAdvertisementType();\r
+\r
+    // In the future we should be able to manipulate all modules regardless of\r
+    // their kind, but right now it helps to keep them categorized as follows.\r
+\r
+    /**\r
+     * The services which will be loaded for this peer group.\r
+     * <p/>\r
+     * <ul>\r
+     *     <li>Keys are {@link net.jxta.platform.ModuleClassID}.</li>\r
+     *     <li>Values are {@link net.jxta.platform.ModuleSpecID} or\r
+     *     {@link net.jxta.protocol.ModuleImplAdvertisement}.</li>\r
+     * </ul>\r
+     */\r
+    private final Map<ModuleClassID, Object> services = new HashMap<ModuleClassID, Object>();\r
+\r
+    /**\r
+     * The protocols (message transports) which will be loaded for this peer\r
+     * group.\r
+     * <p/>\r
+     * <ul>\r
+     *     <li>Keys are {@link net.jxta.platform.ModuleClassID}.</li>\r
+     *     <li>Values are {@link net.jxta.platform.ModuleSpecID} or\r
+     *     {@link net.jxta.protocol.ModuleImplAdvertisement}.</li>\r
+     * </ul>\r
+     */\r
+    private final Map<ModuleClassID, Object> transports = new HashMap<ModuleClassID, Object>();\r
+\r
+    /**\r
+     * The applications which will be loaded for this peer group.\r
+     * <p/>\r
+     * <ul>\r
+     *     <li>Keys are {@link net.jxta.platform.ModuleClassID}.</li>\r
+     *     <li>Values are {@link net.jxta.platform.ModuleSpecID} or\r
+     *     {@link net.jxta.protocol.ModuleImplAdvertisement}.</li>\r
+     * </ul>\r
+     */\r
+    private final Map<ModuleClassID, Object> apps = new HashMap<ModuleClassID, Object>();\r
+\r
+    /**\r
+     * Private constructor for new instances.\r
+     */\r
+    public StdPeerGroupParamAdv() {\r
+    }\r
+\r
+    /**\r
+     * Private constructor for serialized instances.\r
+     *\r
+     * @param root the root element\r
+     */\r
+    public StdPeerGroupParamAdv(Element root) {\r
+        if (!(root instanceof XMLElement)) {\r
+            throw new IllegalArgumentException(getClass().getName() + " only supports XMLElement");\r
+        }\r
+        initialize((XMLElement) root);\r
+    }\r
+\r
+    /**\r
+     * Return the services entries described in this Advertisement.\r
+     * <p/>\r
+     * The result (very unwisely) is the internal hashmap of this\r
+     * Advertisement. Modifying it results in changes to this Advertisement.\r
+     * For safety the Map should be copied before being modified.\r
+     *\r
+     * @return the services entries described in this Advertisement.\r
+     */\r
+    public Map<ModuleClassID, Object> getServices() {\r
+        return services;\r
+    }\r
+\r
+    private void initialize(XMLElement doc) {\r
+\r
+        if (!doc.getName().equals(PARAM_TAG)) {\r
+            throw new IllegalArgumentException("Can not construct " + getClass().getName() + "from doc containing a " + doc.getName());\r
+        }\r
+\r
+        // set defaults\r
+        int appCount = 0;\r
+        Enumeration<XMLElement> modules = doc.getChildren();\r
+\r
+        while (modules.hasMoreElements()) {\r
+            XMLElement module = modules.nextElement();\r
+            String tagName = module.getName();\r
+\r
+            Map<ModuleClassID, Object> theTable;\r
+\r
+            if (SVC_TAG.equals(tagName)) {\r
+                theTable = services;\r
+            } else if (APP_TAG.equals(tagName)) {\r
+                theTable = apps;\r
+            } else if (PROTO_TAG.equals(tagName)) {\r
+                theTable = transports;\r
+            } else {\r
+                if (net.jxta.logging.Logging.SHOW_WARNING && LOG.isLoggable(Level.WARNING)) {\r
+                    LOG.log(Level.WARNING, "Unhandled top-level tag : " + tagName);\r
+                }\r
+                continue;\r
+            }\r
+\r
+            ModuleSpecID specID = null;\r
+            ModuleClassID classID = null;\r
+            ModuleImplAdvertisement inLineAdv = null;\r
+\r
+            try {\r
+                if (module.getTextValue() != null) {\r
+                    specID = (ModuleSpecID) IDFactory.fromURI(new URI(module.getTextValue()));\r
+                }\r
+\r
+                // Check for children anyway.\r
+                Enumeration<XMLElement> fields = module.getChildren();\r
+\r
+                while (fields.hasMoreElements()) {\r
+                    XMLElement field = fields.nextElement();\r
+\r
+                    String fieldName = field.getName();\r
+\r
+                    if (MCID_TAG.equals(fieldName)) {\r
+                        classID = (ModuleClassID) IDFactory.fromURI(new URI(field.getTextValue()));\r
+                    } else if (MSID_TAG.equals(field.getName())) {\r
+                        specID = (ModuleSpecID) IDFactory.fromURI(new URI(field.getTextValue()));\r
+                    } else if (MIA_TAG.equals(field.getName())) {\r
+                        inLineAdv = (ModuleImplAdvertisement) AdvertisementFactory.newAdvertisement(field);\r
+                    } else {\r
+                        if (Logging.SHOW_WARNING && LOG.isLoggable(Level.WARNING)) {\r
+                            LOG.log(Level.WARNING, "Unhandled field : " + fieldName);\r
+                        }\r
+                    }\r
+                }\r
+            } catch (Exception any) {\r
+                if (Logging.SHOW_WARNING && LOG.isLoggable(Level.WARNING)) {\r
+                    LOG.log(Level.WARNING, "Broken entry; skipping", any);\r
+                }\r
+                continue;\r
+            }\r
+\r
+            if (inLineAdv == null && specID == null) {\r
+                if (Logging.SHOW_WARNING && LOG.isLoggable(Level.WARNING)) {\r
+                    LOG.warning("Insufficent entry; skipping");\r
+                }\r
+                continue;\r
+            }\r
+\r
+            Object theValue;\r
+\r
+            if (inLineAdv != null) {\r
+                specID = inLineAdv.getModuleSpecID();\r
+                theValue = inLineAdv;\r
+            } else {\r
+                theValue = specID;\r
+            }\r
+\r
+            if (classID == null) {\r
+                classID = specID.getBaseClass();\r
+            }\r
+\r
+            // For applications, the role does not matter. We just create a\r
+            // unique role ID on the fly.\r
+            // When outputing the adv we get rid of it to save space.\r
+\r
+            if (theTable == apps) {\r
+                // Only the first (or only) one may use the base class.\r
+                if (classID == PeerGroup.applicationClassID) {\r
+                    if (appCount++ != 0) {\r
+                        classID = IDFactory.newModuleClassID(classID);\r
+                    }\r
+                }\r
+            }\r
+            theTable.put(classID, theValue);\r
+        }\r
+    }\r
+\r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    public Document getDocument(MimeMediaType encodeAs) {\r
+        StructuredDocument doc = StructuredDocumentFactory.newStructuredDocument(encodeAs, PARAM_TAG);\r
+\r
+        outputModules(doc, services, SVC_TAG);\r
+        outputModules(doc, transports, PROTO_TAG);\r
+        outputModules(doc, apps, APP_TAG);\r
+\r
+        return doc;\r
+    }\r
+\r
+    private void outputModules(StructuredDocument doc, Map<ModuleClassID, Object> modulesTable, String mainTag) {\r
+\r
+        for (Map.Entry<ModuleClassID, Object> entry : modulesTable.entrySet()) {\r
+            ModuleClassID mcid = entry.getKey();\r
+            Object val = entry.getValue();\r
+            Element m;\r
+\r
+            // For applications, we ignore the role ID. It is not meaningfull,\r
+            // and a new one is assigned on the fly when loading this adv.\r
+\r
+            if (val instanceof Advertisement) {\r
+                m = doc.createElement(mainTag);\r
+                doc.appendChild(m);\r
+\r
+                if (modulesTable != apps && !mcid.equals(mcid.getBaseClass())) {\r
+                    // It is not an app and there is a role ID. Output it.\r
+                    Element i = doc.createElement(MCID_TAG, mcid.toString());\r
+\r
+                    m.appendChild(i);\r
+                }\r
+\r
+                StructuredDocument advdoc = (StructuredDocument) ((Advertisement) val).getDocument(doc.getMimeType());\r
+\r
+                StructuredDocumentUtils.copyElements(doc, m, advdoc);\r
+            } else if (val instanceof ModuleSpecID) {\r
+                if (modulesTable == apps || mcid.equals(mcid.getBaseClass())) {\r
+                    // Either it is an app or there is no role ID.\r
+                    // So the specId is good enough.\r
+                    m = doc.createElement(mainTag, val.toString());\r
+                    doc.appendChild(m);\r
+                } else {\r
+                    // The role ID matters, so the classId must be separate.\r
+                    m = doc.createElement(mainTag);\r
+                    doc.appendChild(m);\r
+\r
+                    Element i;\r
+\r
+                    i = doc.createElement(MCID_TAG, mcid.toString());\r
+                    m.appendChild(i);\r
+\r
+                    i = doc.createElement(MSID_TAG, val.toString());\r
+                    m.appendChild(i);\r
+                }\r
+            } else {\r
+                if (Logging.SHOW_WARNING && LOG.isLoggable(Level.WARNING)) {\r
+                    LOG.warning("unsupported class in modules table");\r
+                }\r
+                throw new IllegalStateException("unsupported class in modules table : " + val);\r
+            }\r
+        }\r
+    }\r
+}\r
diff --git a/Splitter-ng-plugin-jigdfs/src/org/jigdfs/jxta/wrapper/ServiceThreadedWrapper.java b/Splitter-ng-plugin-jigdfs/src/org/jigdfs/jxta/wrapper/ServiceThreadedWrapper.java
new file mode 100644 (file)
index 0000000..910ecac
--- /dev/null
@@ -0,0 +1,107 @@
+package org.jigdfs.jxta.wrapper;
+
+import java.util.ArrayList;
+import java.util.EventObject;
+import java.util.List;
+
+import org.jigdfs.baseInterface.Listenable;
+import org.jigdfs.baseInterface.Listener;
+import org.jigdfs.jxta.exception.JXTANotInitializedException;
+import org.jigdfs.serivce.Service;
+
+/**
+ * The ServiceThreadWrapper wraps an service and make it runnable in a thread It
+ * must be thread-safe
+ * 
+ * @author jbian
+ * 
+ */
+
+public class ServiceThreadedWrapper implements Runnable, Listenable {
+
+    private Object result = null;
+
+    private boolean isRunning = false;
+
+    private Service service = null;
+
+    public ServiceThreadedWrapper(Service service) {
+       this.service = service;
+    }
+    
+    private List<Listener> listenerList = new ArrayList<Listener>();
+
+    @Override
+    public void run() {
+       if (this.service == null) {
+           try {
+               throw new JXTANotInitializedException(
+                       "the service has not been initialized!");
+           } catch (JXTANotInitializedException e) {
+               e.printStackTrace();
+               return;
+           }
+       }
+
+       /*
+        * synchronized on the class, there is only one NetPeerGroup can be used for search 
+        * */
+       synchronized (ServiceThreadedWrapper.class) {
+
+           this.isRunning = true;
+
+           while (this.service.isRunning()) {
+               try {
+                   this.service.runService();
+               } catch (InterruptedException iEx) {
+
+               } catch (Exception e) {
+                   // TODO Auto-generated catch block
+                   e.printStackTrace();
+               }
+           }
+
+           this.result = this.service.getResult();
+
+           this.isRunning = false;
+       }
+    }
+
+    /**
+     * @param isRunning
+     *            the isRunning to set
+     */
+    public void setRunning(boolean isRunning) {
+       this.isRunning = isRunning;
+    }
+
+    /**
+     * @return the isRunning
+     */
+    public boolean isRunning() {
+       return isRunning;
+    }
+
+    /**
+     * @param result
+     *            the result to set
+     */
+    public void setResult(Object result) {
+       this.result = result;
+    }
+
+    /**
+     * @return the result
+     */
+    public Object getResult() {
+       return result;
+    }
+
+
+    @Override
+    public void notifyListeners(EventObject event) {
+       // TODO Auto-generated method stub
+       
+    }
+
+}
diff --git a/Splitter-ng-plugin-jigdfs/src/org/jigdfs/references/ida/originalcrs/CauchyDecode.java b/Splitter-ng-plugin-jigdfs/src/org/jigdfs/references/ida/originalcrs/CauchyDecode.java
new file mode 100644 (file)
index 0000000..7e68adc
--- /dev/null
@@ -0,0 +1,373 @@
+//
+// Cleversafe open-source code header - Version 1.2 - February 15, 2008
+//
+// Cleversafe Dispersed Storage(TM) is software for secure, private and
+// reliable storage of the world's data using information dispersal.
+//
+// Copyright (C) 2005-2008 Cleversafe, Inc.
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
+// USA.
+//
+// Contact Information: Cleversafe, 224 North Desplaines Street, Suite 500 
+// Chicago IL 60661
+// email licensing@cleversafe.org
+//
+// END-OF-HEADER
+
+/**
+ * CauchyDecode.java
+ *
+ * @author   Hakim Weatherspoon
+ * @version  $Id: CauchyDecode.java,v 1.4 2004/05/14 00:46:01 hweather Exp $
+ *
+ * Copyright (c) 2001 Regents of the University of California.
+ * All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. 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.
+ *  3. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ **/
+
+package org.jigdfs.references.ida.originalcrs;
+
+import java.util.*;
+
+/**
+ * CauchyEncode decodes a msg that was previously encoded using Cauchy
+ * Reed-Solomon method.
+ * 
+ * Move information from fragments into received message. Fill in parts of
+ * received message that requires no processing and figure out how many of the
+ * redundant fragments are needed. Nfirstrec is the number of fragments received
+ * from among the first Mfragments that carry portions of the unprocessed
+ * original message. Rec_index is an array that indicates which parts of the
+ * message are received. The pattern is the same within all Nsegs segments,
+ * 
+ * @author Hakim Weatherspoon
+ * @version $Id: CauchyDecode.java,v 1.4 2004/05/14 00:46:01 hweather Exp $
+ */
+public class CauchyDecode
+{
+   private static final int STACK_SIZE = 32;
+
+   private static Map<Integer, FiniteStack> _decodeTable = new HashMap<Integer, FiniteStack>();
+
+   /**
+    * decode uses the cauchy erasure coding method to decode an array of
+    * fragments back into a msg.
+    */
+
+   /*
+    * @param COLBIT == COLBIT is the bit that is used to make sure rows and
+    * columns have distinct field elements associated with them. @param BIT ==
+    * The BIT array is used to mask out single bits in equations: bit @param
+    * ExptoFE == ExptoFE is the table that goes from the exponent to the finite
+    * field element. @param FEtoExp == FEtoExp is the table that goes from the
+    * finite field element to the exponent. @param fragments == fragments are
+    * the array of fragments as output. @param message == is the message in int
+    * array format.
+    */
+   public static void decode(
+         int[] rec_fragments /* in */,
+         int Nrec /* in */,
+         int[] rec_message /* out */,
+         Parameters p /* in */) throws Exception
+   {
+      int i, j, k, l, m, index, seg_ind;
+      int col_ind, row_ind, col_eqn, row_eqn;
+      int Nfirstrec, Nextra;
+      int ExpFE;
+
+      int[] COLBIT = InitField.getCOLBIT(p.Lfield());
+      int[] BIT = InitField.getBIT(p.Lfield());
+      int[] ExptoFE = InitField.getExptoFE(p.Lfield());
+      int[] FEtoExp = InitField.getFEtoExp(p.Lfield());
+
+      Integer key = new Integer(p.Mfragments() + p.Nsegs() * p.Rfragments()
+            * p.Lfield());
+      FiniteStack stack = (FiniteStack) _decodeTable.get(key);
+
+      if (stack == null)
+      {
+         synchronized (_decodeTable)
+         {
+            if ((stack = (FiniteStack) _decodeTable.get(key)) == null)
+            {
+               Object bucket = null;
+               stack = new FiniteStack(STACK_SIZE);
+               if ((bucket = _decodeTable.put(key, stack)) != null)
+                  System.err.println("CauchyDecode.decode: bucket=" + bucket
+                        + " for key=" + key + " stack=" + stack);
+            }
+         }
+      }
+
+      ArrayObj arrayObj = (ArrayObj) stack.pop();
+      if (arrayObj == null)
+         arrayObj = new ArrayObj(p.Mfragments(), p.Rfragments(), p.Nsegs(), p
+               .Lfield());
+
+      int[] Rec_index = arrayObj.Rec_index;
+      int[] Col_Ind = arrayObj.Col_Ind;
+      int[] Row_Ind = arrayObj.Row_Ind;
+      int[] M = arrayObj.M;
+      int[] C = arrayObj.C;
+      int[] D = arrayObj.D;
+      int[] E = arrayObj.E;
+      int[] F = arrayObj.F;
+
+      /**
+       * Initialize arrays
+       */
+      for (i = 0; i < p.Mfragments(); i++)
+         D[i] = E[i] = 0;
+
+      /**
+       * Initialize arrays
+       */
+      for (i = 0; i < p.Rfragments(); i++)
+         C[i] = F[i] = 0;
+
+      /**
+       * Initialize the received message
+       */
+      for (i = 0; i < p.Mlen(); i++)
+         rec_message[i] = 0;
+
+      if (Nrec < p.Mfragments())
+      {
+         throw new Exception("Decode error");
+      }
+
+      /**
+       * Move information from fragments into received message. Fill in parts of
+       * received message that requires no processing and figure out how many of
+       * the redundant fragments are needed. Nfirstrec is the number of
+       * fragments received from among the first Mfragments that carry portions
+       * of the unprocessed original message. Rec_index is an array that
+       * indicates which parts of the message are received. The pattern is the
+       * same within all Nsegs segments,
+       */
+
+      Nfirstrec = 0;
+      for (i = 0; i < p.Mfragments(); i++)
+         Rec_index[i] = 0;
+
+      m = 0;
+      for (i = 0; i < Nrec; i++)
+      {
+         index = rec_fragments[m];
+         if (index < p.Mfragments())
+         {
+            j = index * p.Plen();
+            Rec_index[index] = 1;
+            for (row_eqn = 0; row_eqn < p.Lfield(); row_eqn++)
+            {
+               k = row_eqn * p.Nsegs();
+               l = j + k;
+               for (seg_ind = 0; seg_ind < p.Nsegs(); seg_ind++)
+                  rec_message[seg_ind + l] = rec_fragments[m + 1 + seg_ind + k];
+            }
+            Nfirstrec++;
+         }
+         m += p.Plentot();
+      }
+
+      /**
+       * Nextra is the number of redundant fragments that need to be processed.
+       */
+      Nextra = p.Mfragments() - Nfirstrec;
+
+      /**
+       * Compute the indices of the missing words in the message
+       */
+      col_ind = 0;
+      for (i = 0; i < p.Mfragments(); i++)
+      {
+         if (Rec_index[i] == 0)
+            Col_Ind[col_ind++] = i;
+      }
+
+      /**
+       * Keep track of indices of extra fragments in Row_Ind array and
+       * initialize M array from the received extra fragments
+       */
+      row_ind = 0;
+      m = 0;
+      for (i = 0; i < Nrec; i++)
+      {
+         if (rec_fragments[m] >= p.Mfragments())
+         {
+            k = p.Nsegs() * row_ind * p.Lfield();
+            Row_Ind[row_ind] = rec_fragments[m] - p.Mfragments();
+            for (row_eqn = 0; row_eqn < p.Lfield(); row_eqn++)
+            {
+               j = row_eqn * p.Nsegs();
+               for (seg_ind = 0; seg_ind < p.Nsegs(); seg_ind++)
+               {
+                  M[k] = rec_fragments[m + 1 + seg_ind + j];
+                  k++;
+               }
+            }
+            row_ind++;
+            if (row_ind >= Nextra)
+               break;
+         }
+         m += p.Plentot();
+      }
+
+      /**
+       * Adjust M array according to the equations and the contents of
+       * rec_message.
+       */
+      for (row_ind = 0; row_ind < Nextra; row_ind++)
+      {
+         for (col_ind = 0; col_ind < p.Mfragments(); col_ind++)
+         {
+            if (Rec_index[col_ind] == 1)
+            {
+               ExpFE = (p.SMultField() - FEtoExp[Row_Ind[row_ind] ^ col_ind
+                     ^ COLBIT[0]])
+                     % p.SMultField();
+               for (row_eqn = 0; row_eqn < p.Lfield(); row_eqn++)
+               {
+                  j = p.Nsegs() * (row_eqn + row_ind * p.Lfield());
+                  for (col_eqn = 0; col_eqn < p.Lfield(); col_eqn++)
+                  {
+                     k = p.Nsegs() * (col_eqn + col_ind * p.Lfield());
+                     if ((ExptoFE[ExpFE + row_eqn] & BIT[col_eqn]) > 0)
+                     {
+                        for (seg_ind = 0; seg_ind < p.Nsegs(); seg_ind++)
+                        {
+                           M[j + seg_ind] ^= rec_message[k + seg_ind];
+                        }
+                     }
+                  }
+               }
+            }
+         }
+      }
+
+      /**
+       * Compute the determinant of the matrix in the finite field and then
+       * compute the inverse matrix
+       */
+      for (row_ind = 0; row_ind < Nextra; row_ind++)
+      {
+         for (col_ind = 0; col_ind < Nextra; col_ind++)
+         {
+            if (col_ind != row_ind)
+            {
+               C[row_ind] += FEtoExp[Row_Ind[row_ind] ^ Row_Ind[col_ind]];
+               D[col_ind] += FEtoExp[Col_Ind[row_ind] ^ Col_Ind[col_ind]];
+            }
+            E[row_ind] += FEtoExp[Row_Ind[row_ind] ^ Col_Ind[col_ind]
+                  ^ COLBIT[0]];
+            F[col_ind] += FEtoExp[Row_Ind[row_ind] ^ Col_Ind[col_ind]
+                  ^ COLBIT[0]];
+         }
+      }
+
+      /**
+       * Fill in the recovered information in the message from the inverted
+       * matrix and from M.
+       */
+      for (row_ind = 0; row_ind < Nextra; row_ind++)
+      {
+         for (col_ind = 0; col_ind < Nextra; col_ind++)
+         {
+            ExpFE = E[col_ind] + F[row_ind] - C[col_ind] - D[row_ind]
+                  - FEtoExp[Row_Ind[col_ind] ^ Col_Ind[row_ind] ^ COLBIT[0]];
+            if (ExpFE < 0)
+               ExpFE = p.SMultField() - ((-ExpFE) % p.SMultField());
+            ExpFE = ExpFE % p.SMultField();
+            j = Col_Ind[row_ind] * p.Lfield() * p.Nsegs();
+            for (row_eqn = 0; row_eqn < p.Lfield(); row_eqn++)
+            {
+               k = row_eqn * p.Nsegs() + j;
+               for (col_eqn = 0; col_eqn < p.Lfield(); col_eqn++)
+               {
+                  l = p.Nsegs() * (col_eqn + col_ind * p.Lfield());
+                  if ((ExptoFE[ExpFE + row_eqn] & BIT[col_eqn]) > 0)
+                  {
+                     for (seg_ind = 0; seg_ind < p.Nsegs(); seg_ind++)
+                     {
+                        rec_message[seg_ind + k] ^= M[l];
+                        l++;
+                     }
+                  }
+               }
+            }
+         }
+      }
+
+   }
+
+   private static class ArrayObj
+   {
+      public int[] Rec_index;
+
+      public int[] Col_Ind;
+
+      public int[] Row_Ind;
+
+      public int[] C;
+
+      public int[] D;
+
+      public int[] E;
+
+      public int[] F;
+
+      public int[] M;
+
+      public ArrayObj(
+            int numMsgFrags,
+            int numRedundantFrags,
+            int nSegs,
+            int Lfield)
+      {
+         Rec_index = new int[numMsgFrags];
+         Col_Ind = new int[numMsgFrags];
+         Row_Ind = new int[numRedundantFrags];
+         C = new int[numRedundantFrags];
+         D = new int[numMsgFrags];
+         E = new int[numMsgFrags];
+         F = new int[numRedundantFrags];
+         M = new int[nSegs * numRedundantFrags * Lfield];
+      }
+   }
+}
diff --git a/Splitter-ng-plugin-jigdfs/src/org/jigdfs/references/ida/originalcrs/CauchyEncode.java b/Splitter-ng-plugin-jigdfs/src/org/jigdfs/references/ida/originalcrs/CauchyEncode.java
new file mode 100644 (file)
index 0000000..4cfd8f5
--- /dev/null
@@ -0,0 +1,168 @@
+//
+// Cleversafe open-source code header - Version 1.2 - February 15, 2008
+//
+// Cleversafe Dispersed Storage(TM) is software for secure, private and
+// reliable storage of the world's data using information dispersal.
+//
+// Copyright (C) 2005-2008 Cleversafe, Inc.
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
+// USA.
+//
+// Contact Information: Cleversafe, 224 North Desplaines Street, Suite 500 
+// Chicago IL 60661
+// email licensing@cleversafe.org
+//
+// END-OF-HEADER
+
+/**
+ * CauchyEncode.java
+ *
+ * @author   Hakim Weatherspoon
+ * @version  $Id: CauchyEncode.java,v 1.4 2004/05/14 00:46:01 hweather Exp $
+ *
+ * Copyright (c) 2001 Regents of the University of California.
+ * All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. 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.
+ *  3. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ **/
+
+package org.jigdfs.references.ida.originalcrs;
+
+/**
+ * CauchyEncode erasure encodes an object using cauchy reed solomon method.
+ * 
+ * @author Hakim Weatherspoon
+ * @version $Id: CauchyEncode.java,v 1.4 2004/05/14 00:46:01 hweather Exp $
+ */
+public class CauchyEncode
+{
+
+   /**
+    * encode uses the cauchy erasure encoding method to encode a message into
+    * fragments.
+    */
+
+   /*
+    * @param COLBIT == COLBIT is the bit that is used to make sure rows and
+    * columns have distinct field elements associated with them. @param BIT ==
+    * The BIT array is used to mask out single bits in equations: bit @param
+    * ExptoFE == ExptoFE is the table that goes from the exponent to the finite
+    * field element. @param FEtoExp == FEtoExp is the table that goes from the
+    * finite field element to the exponent. @param fragments == fragments are
+    * the array of fragments as output. @param message == is the message in int
+    * array format.
+    */
+   public static void encode(
+         int[] fragments /* out */,
+         int[] message /* in */,
+         Parameters p /* in */)
+   {
+      int i, j, k, l, m, ind_seg, col_eqn, row_eqn, ind_eqn;
+      int row, col, ExpFE;
+
+      int[] COLBIT = InitField.getCOLBIT(p.Lfield());
+      int[] BIT = InitField.getBIT(p.Lfield());
+      int[] ExptoFE = InitField.getExptoFE(p.Lfield());
+      int[] FEtoExp = InitField.getFEtoExp(p.Lfield());
+
+      /**
+       * Set the identifier in all the fragments to be sent
+       */
+      for (i = 0; i < p.Nfragments(); i++)
+         fragments[i * p.Plentot()] = i;
+
+      k = 0;
+      j = 0;
+      for (i = 0; i < p.Mfragments(); i++)
+      {
+         k++;
+         for (ind_eqn = 0; ind_eqn < p.Lfield(); ind_eqn++)
+         {
+            for (ind_seg = 0; ind_seg < p.Nsegs(); ind_seg++)
+            {
+               fragments[k] = message[j];
+               j++;
+               k++;
+            }
+         }
+      }
+
+      /**
+       * Fill in values for remaining Rfragments fragments
+       */
+      for (row = 0; row < p.Rfragments(); row++)
+      {
+         /**
+          * Compute values of equations applied to message and fill into
+          * fragment(row+Mfragments).
+          * 
+          * First, zero out contents relevant portions of fragment
+          */
+         j = (row + p.Mfragments()) * p.Plentot();
+         for (i = 1; i < p.Plentot(); i++)
+            fragments[j + i] = 0;
+
+         /**
+          * Second, fill in contents relevant portions of fragment
+          */
+         for (col = 0; col < p.Mfragments(); col++)
+         {
+            m = col * p.Lfield() * p.Nsegs();
+            ExpFE = (p.SMultField() - FEtoExp[row ^ col ^ COLBIT[0]])
+                  % p.SMultField();
+
+            for (row_eqn = 0; row_eqn < p.Lfield(); row_eqn++)
+            {
+               k = row_eqn * p.Nsegs();
+               for (col_eqn = 0; col_eqn < p.Lfield(); col_eqn++)
+               {
+                  if ((ExptoFE[ExpFE + row_eqn] & BIT[col_eqn]) > 0)
+                  {
+                     l = col_eqn * p.Nsegs() + m;
+                     for (ind_seg = 0; ind_seg < p.Nsegs(); ind_seg++)
+                     {
+                        fragments[j + 1 + ind_seg + k] ^= message[ind_seg + l];
+                     }
+                  }
+               }
+            }
+         }
+      }
+
+   }
+}
diff --git a/Splitter-ng-plugin-jigdfs/src/org/jigdfs/references/ida/originalcrs/FiniteStack.java b/Splitter-ng-plugin-jigdfs/src/org/jigdfs/references/ida/originalcrs/FiniteStack.java
new file mode 100644 (file)
index 0000000..7805ecd
--- /dev/null
@@ -0,0 +1,158 @@
+//
+// Cleversafe open-source code header - Version 1.2 - February 15, 2008
+//
+// Cleversafe Dispersed Storage(TM) is software for secure, private and
+// reliable storage of the world's data using information dispersal.
+//
+// Copyright (C) 2005-2008 Cleversafe, Inc.
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
+// USA.
+//
+// Contact Information: Cleversafe, 224 North Desplaines Street, Suite 500 
+// Chicago IL 60661
+// email licensing@cleversafe.org
+//
+// END-OF-HEADER
+
+/*
+ * FiniteStack.java
+ *
+ * @author   Hakim Weatherspoon
+ * @version  $Id: FiniteStack.java,v 1.4 2004/05/14 00:46:18 hweather Exp $
+ *
+ *  Copyright (c) 2001 Regents of the University of California.  All
+ *  rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. 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.
+ *  3. Neither the name of the University 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 REGENTS 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
+ *  REGENTS 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.
+ */
+
+package org.jigdfs.references.ida.originalcrs;
+
+/**
+ * A simple Stack of finite size.
+ * 
+ * @author Hakim Weatherspoon
+ * @version $Id: FiniteStack.java,v 1.4 2004/05/14 00:46:18 hweather Exp $
+ */
+public class FiniteStack
+{
+   // ////////////////// CONSTANTS ////////////////////
+   // ////////////////// STATIC VARIABLES ////////////////////
+   // ////////////////// VARIABLES ////////////////////
+   private int STACK_SIZE;
+
+   private Object[] _stack;
+
+   private int _head;
+
+   // ////////////////// CONSTRUCTORS ////////////////////
+
+   /**
+    * Constructs a new <code>Stack</code>.
+    */
+   public FiniteStack(int size)
+   {
+      STACK_SIZE = size;
+      _head = 0;
+      _stack = new Object[STACK_SIZE];
+   }
+
+   private boolean isFull()
+   {
+      return (_head == STACK_SIZE);
+   }
+
+   private boolean isEmpty()
+   {
+      return (_head == 0);
+   }
+
+   public boolean push(Object element)
+   {
+      synchronized (_stack)
+      {
+         if (isFull())
+            return false;
+         _stack[_head] = element;
+         _head = _head + 1;
+         return true;
+      }
+   }
+
+   public Object pop()
+   {
+      synchronized (_stack)
+      {
+         if (isEmpty())
+            return null;
+         _head = _head - 1;
+         Object element = _stack[_head];
+         _stack[_head] = null;
+         return element;
+      }
+   }
+
+   public int size()
+   {
+      synchronized (_stack)
+      {
+         return _head;
+      }
+   }
+
+   /**
+    * Returns a human-readable representation of this
+    * <code>CacheReserveState</code>.
+    */
+   public String toString()
+   {
+      String str = new String();
+
+      str += "<FiniteStack";
+      str += " size==" + _head;
+      str += " stackCapacity==" + STACK_SIZE;
+      for (int i = 0; i < _head; i++)
+         str += " stack[" + i + "]==" + _stack[i];
+      str += ">";
+
+      return str;
+   }
+
+}
diff --git a/Splitter-ng-plugin-jigdfs/src/org/jigdfs/references/ida/originalcrs/InitField.java b/Splitter-ng-plugin-jigdfs/src/org/jigdfs/references/ida/originalcrs/InitField.java
new file mode 100644 (file)
index 0000000..32e2887
--- /dev/null
@@ -0,0 +1,245 @@
+//
+// Cleversafe open-source code header - Version 1.2 - February 15, 2008
+//
+// Cleversafe Dispersed Storage(TM) is software for secure, private and
+// reliable storage of the world's data using information dispersal.
+//
+// Copyright (C) 2005-2008 Cleversafe, Inc.
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
+// USA.
+//
+// Contact Information: Cleversafe, 224 North Desplaines Street, Suite 500 
+// Chicago IL 60661
+// email licensing@cleversafe.org
+//
+// END-OF-HEADER
+
+/**
+ * InitField.java 
+ *
+ * @author   Hakim Weatherspoon
+ * @version  $Id: InitField.java,v 1.4 2004/05/14 00:46:01 hweather Exp $
+ *
+ * Copyright (c) 2001 Regents of the University of California.
+ * All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. 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.
+ *  3. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ **/
+
+package org.jigdfs.references.ida.originalcrs;
+
+/**
+ * InitField initializes the finite Field Element to Exponent (FEtoExp) table
+ * and the Exponent to finite Field Element (ExptoFE) table.
+ * 
+ * SMultField is the size of the multiplicative field (2^{Lfield}-1) ==
+ * TableLength - 1.
+ * 
+ * pCOLBIT is a pointer to the COLBIT, which is used to make sure rows and
+ * columns have distinct field elements associated with them. The BIT array is
+ * used to mask out single bits in equations: bit ExptoFE is the table that goes
+ * from the exponent to the finite field element. FEtoExp == FEtoExp is the
+ * table that goes from the finite field element to the exponent. Lfield is the
+ * log of the length of the field.
+ * 
+ * @author Hakim Weatherspoon
+ * @version $Id: InitField.java,v 1.4 2004/05/14 00:46:01 hweather Exp $
+ */
+public class InitField
+{
+   public static int MAXLFIELD = 16;
+
+   public static int COLBIT[][];
+
+   public static int BIT[][];
+
+   public static int ExptoFE[][];
+
+   public static int FEtoExp[][];
+
+   static
+   {
+      generateTables(MAXLFIELD);
+   }
+
+   /**
+    * Retrieve the COLBIT table for the input Lfield.
+    * 
+    * @param Lfield ==
+    *           the Lfield to retrieve a COLBIT table for.
+    */
+   public static int[] getCOLBIT(int Lfield)
+   {
+      return COLBIT[Lfield];
+   }
+
+   /**
+    * Retreve the BIT table for the input Lfield.
+    * 
+    * @param Lfield ==
+    *           the Lfield to retrieve a BIT table for.
+    */
+   public static int[] getBIT(int Lfield)
+   {
+      return BIT[Lfield];
+   }
+
+   /**
+    * Retreve the ExptoFE table for the input Lfield.
+    * 
+    * @param Lfield ==
+    *           the Lfield to retrieve a ExptoFE table for.
+    */
+   public static int[] getExptoFE(int Lfield)
+   {
+      return ExptoFE[Lfield];
+   }
+
+   /**
+    * Retreve the FEtoExp table for the input Lfield.
+    * 
+    * @param Lfield ==
+    *           the Lfield to retrieve a FEtoExp table for.
+    */
+   public static int[] getFEtoExp(int Lfield)
+   {
+      return FEtoExp[Lfield];
+   }
+
+   /**
+    * initField initializes the finite Field Element to Exponent (FEtoExp) table
+    * and the Exponent to finite Field Element (ExptoFE) table.
+    * 
+    * Recall SMultField = TableLength - 1 is the number of elements in the
+    * multiplicative group of the field.
+    * 
+    * @param pCOLBIT ==
+    *           is a pointer to the COLBIT, which is used to make sure rows and
+    *           columns have distinct field elements associated with them.
+    * @param BIT ==
+    *           The BIT array is used to mask out single bits in equations: bit
+    * @param ExptoFE ==
+    *           ExptoFE is the table that goes from the exponent to the finite
+    *           field element.
+    * @param FEtoExp ==
+    *           FEtoExp is the table that goes from the finite field element to
+    *           the exponent.
+    * @param Lfield ==
+    *           Lfield is the log of the length of the field..
+    */
+   public static void initField(
+         int[] pCOLBIT,
+         int[] BIT,
+         int[] ExptoFE,
+         int[] FEtoExp,
+         int Lfield)
+   {
+      /**
+       * Recall SMultField = TableLength - 1 is the number of elements in the
+       * multiplicative group of the field.
+       */
+      int SMultField = (1 << Lfield) - 1;
+
+      /**
+       * CARRYMASK is used to see when there is a carry in the polynomial and
+       * when it should be XOR'd with POLYMASK.
+       */
+      int CARRYMASK;
+
+      /**
+       * POLYMASK is the irreducible polynomial.
+       */
+      int POLYMASK[] = {
+            0x0, 0x3, 0x7, 0xB, 0x13, 0x25, 0x43, 0x83, 0x11D, 0x211, 0x409,
+            0x805, 0x1053, 0x201B, 0x402B, 0x8003, 0x1100B
+      };
+      int i;
+
+      BIT[0] = 0x1;
+
+      for (i = 1; i < Lfield; i++)
+         BIT[i] = BIT[i - 1] << 1;
+
+      pCOLBIT[0] = BIT[Lfield - 1];
+      CARRYMASK = pCOLBIT[0] << 1;
+      ExptoFE[0] = 0x1;
+
+      for (i = 1; i < SMultField + Lfield - 1; i++)
+      {
+         ExptoFE[i] = ExptoFE[i - 1] << 1;
+         if ((ExptoFE[i] & CARRYMASK) > 0)
+            ExptoFE[i] ^= POLYMASK[Lfield];
+      }
+
+      FEtoExp[0] = -1;
+      for (i = 0; i < SMultField; i++)
+         FEtoExp[ExptoFE[i]] = i;
+   }
+
+   /**
+    * This routine will generate tables for the input number of Lfields and
+    * output them to stdout.
+    * 
+    * @param maxLfield ==
+    *           maximum Lfield to produce fields for
+    */
+   public static void generateTables(int maxLfield)
+   {
+      /*
+       * TableLength = 2^Lfield COLBIT = new int[2] BIT = new int[16] ExptoFE =
+       * new int[TableLength + Lfield] FEtoExp = new int[TableLength]
+       */
+
+      COLBIT = new int[maxLfield + 1][];
+      BIT = new int[maxLfield + 1][];
+      ExptoFE = new int[maxLfield + 1][];
+      FEtoExp = new int[maxLfield + 1][];
+
+      for (int Lfield = 1; Lfield <= maxLfield; ++Lfield)
+      {
+         int TableLength = 1 << Lfield;
+         COLBIT[Lfield] = new int[1];
+         BIT[Lfield] = new int[16];
+         ExptoFE[Lfield] = new int[TableLength + Lfield];
+         FEtoExp[Lfield] = new int[TableLength];
+         initField(COLBIT[Lfield], BIT[Lfield], ExptoFE[Lfield],
+               FEtoExp[Lfield], Lfield);
+      }
+   }
+
+}
diff --git a/Splitter-ng-plugin-jigdfs/src/org/jigdfs/references/ida/originalcrs/NativeIF.java b/Splitter-ng-plugin-jigdfs/src/org/jigdfs/references/ida/originalcrs/NativeIF.java
new file mode 100644 (file)
index 0000000..e5f069c
--- /dev/null
@@ -0,0 +1,132 @@
+//
+// Cleversafe open-source code header - Version 1.2 - February 15, 2008
+//
+// Cleversafe Dispersed Storage(TM) is software for secure, private and
+// reliable storage of the world's data using information dispersal.
+//
+// Copyright (C) 2005-2008 Cleversafe, Inc.
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
+// USA.
+//
+// Contact Information: Cleversafe, 224 North Desplaines Street, Suite 500 
+// Chicago IL 60661
+// email licensing@cleversafe.org
+//
+// END-OF-HEADER
+
+package org.jigdfs.references.ida.originalcrs;
+
+public class NativeIF
+{
+
+   /**
+    * encode uses the cauchy erasure encoding method to encode a message into
+    * fragments.
+    * 
+    * @return return == time in microseconds to encode the msg into fragments.
+    */
+
+   /*
+    * @param COLBIT == COLBIT is the bit that is used to make sure rows and
+    * columns have distinct field elements associated with them. @param BIT ==
+    * The BIT array is used to mask out single bits in equations: bit @param
+    * ExptoFE == ExptoFE is the table that goes from the exponent to the finite
+    * field element. @param FEtoExp == FEtoExp is the table that goes from the
+    * finite field element to the exponent. @param fragments == fragments are
+    * the array of fragments as output. @param message == is the message in int
+    * array format.
+    */
+   public static native long cauchy_encode_using_c_helper(
+         byte[] message /* in */,
+         int Mfragments /* in */,
+         int Rfragments /* in */,
+         int NSegs /* in */,
+         int Lfield /* in */,
+         byte[] fragments /* out */);
+
+   /**
+    * encode uses the cauchy erasure encoding method to encode a message into
+    * fragments.
+    * 
+    * FIXME!!!
+    * 
+    * @return return == time in microseconds to encode the msg into fragments.
+    */
+
+   /*
+    * @param COLBIT == COLBIT is the bit that is used to make sure rows and
+    * columns have distinct field elements associated with them. @param BIT ==
+    * The BIT array is used to mask out single bits in equations: bit @param
+    * ExptoFE == ExptoFE is the table that goes from the exponent to the finite
+    * field element. @param FEtoExp == FEtoExp is the table that goes from the
+    * finite field element to the exponent. @param fragments == fragments are
+    * the array of fragments as output. @param message == is the message in int
+    * array format.
+    */
+   public static native long cauchy_encode_and_verify_using_c_helper(
+         byte[] message /* in */,
+         int Mfragments /* in */,
+         int Rfragments /* in */,
+         int NSegs /* in */,
+         int Lfield /* in */,
+         int[] fragments /* out */,
+         int[] intFrags2,
+         byte[] frags3,
+         int[] message2,
+         byte[] message3);
+
+   /**
+    * decode uses the cauchy erasure coding method to decode an array of
+    * fragments back into a msg.
+    * 
+    * FIXME
+    * 
+    * @return return == time in milleseconds to decode fragments into a msg.
+    */
+
+   /*
+    * @param COLBIT == COLBIT is the bit that is used to make sure rows and
+    * columns have distinct field elements associated with them. @param BIT ==
+    * The BIT array is used to mask out single bits in equations: bit @param
+    * ExptoFE == ExptoFE is the table that goes from the exponent to the finite
+    * field element. @param FEtoExp == FEtoExp is the table that goes from the
+    * finite field element to the exponent. @param fragments == fragments are
+    * the array of fragments as output. @param message == is the message in int
+    * array format.
+    */
+   public static native long cauchy_decode_using_c_helper(
+         byte[] rec_fragments /* in */,
+         int Nrec /* in */,
+         int Mfragments /* in */,
+         int Rfragments /* in */,
+         int NSegs /* in */,
+         int Lfield /* in */,
+         byte[] rec_message /* out */);
+
+   public static boolean available = false;
+
+   static
+   {
+      try
+      {
+         System.loadLibrary( "cauchy_ida" );
+         available = true;   
+      } catch (UnsatisfiedLinkError e1)
+      {         
+         available = false;
+      }
+   }
+}
diff --git a/Splitter-ng-plugin-jigdfs/src/org/jigdfs/references/ida/originalcrs/Parameters.java b/Splitter-ng-plugin-jigdfs/src/org/jigdfs/references/ida/originalcrs/Parameters.java
new file mode 100644 (file)
index 0000000..406f72a
--- /dev/null
@@ -0,0 +1,318 @@
+//
+// Cleversafe open-source code header - Version 1.2 - February 15, 2008
+//
+// Cleversafe Dispersed Storage(TM) is software for secure, private and
+// reliable storage of the world's data using information dispersal.
+//
+// Copyright (C) 2005-2008 Cleversafe, Inc.
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
+// USA.
+//
+// Contact Information: Cleversafe, 224 North Desplaines Street, Suite 500 
+// Chicago IL 60661
+// email licensing@cleversafe.org
+//
+// END-OF-HEADER
+
+/**
+ * Parameters.java
+ *
+ * @author   Hakim Weatherspoon
+ * @version  $Id: Parameters.java,v 1.4 2004/05/14 00:46:01 hweather Exp $
+ *
+ * Copyright (c) 2001 Regents of the University of California.
+ * All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. 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.
+ *  3. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ **/
+
+package org.jigdfs.references.ida.originalcrs;
+
+/**
+ * Parameters are the parameters used to encode/decode an object.
+ * 
+ * @author Hakim Weatherspoon
+ * @version $Id: Parameters.java,v 1.4 2004/05/14 00:46:01 hweather Exp $
+ */
+public class Parameters
+{
+
+   /**
+    * Lfield is the log of the length of the field.
+    */
+   protected int _Lfield = 8;
+
+   /**
+    * Nsegs is the number of segments in a fragment. Length of fragment in bytes
+    * is 4*Nsegs*Lfield.
+    */
+   protected int _Nsegs = 43;
+
+   /**
+    * TableLength is 2^{Lfield}
+    */
+   protected int _TableLength = 1 << _Lfield;
+
+   /**
+    * SMultField is the size of the multiplicative field (2^{Lfield}-1) ==
+    * TableLength - 1.
+    */
+   protected int _SMultField = (1 << _Lfield) - 1;
+
+   /**
+    * Plen is the fragment length in words excluding the overhead for storing
+    * the index.
+    */
+   protected int _Plen = _Nsegs * _Lfield;
+
+   /**
+    * Plentot is the fragment length in words including the overhead for storing
+    * the index.
+    */
+   protected int _Plentot = _Plen + 1;
+
+   /**
+    * Mfragments is the number of message fragments
+    * 
+    * IMPORTANT: The max of Mfragments and Rfragments is at most 2^{Lfield-1}.
+    * 
+    * Lfield must be set large enough to make this true else the encoding and
+    * decoding won't work
+    */
+   protected int _Mfragments;
+
+   /**
+    * Rfragments is the number of redundant fragments
+    * 
+    * IMPORTANT: The max of Mfragments and Rfragments is at most 2^{Lfield-1}.
+    * 
+    * Lfield must be set large enough to make this true else the encoding and
+    * decoding won't work.
+    */
+   protected int _Rfragments;
+
+   /**
+    * Nfragments is the total number of fragments sent.
+    */
+   protected int _Nfragments;
+
+   /**
+    * Mlen is the length of the message in words.
+    */
+   protected int _Mlen;
+
+   /**
+    * Elen is the length of the encoding in words.
+    */
+   protected int _Elen;
+
+   /**
+    * CONSTRUCTOR
+    * 
+    * Initialize Parameters for a number of messages.
+    * 
+    * @param Mfragments =
+    *           Mfragments is the number of message fragments.
+    * @param Rfragments =
+    *           Rfragments is the number of redundant fragments.
+    */
+   public Parameters(/* in */int Mfragments,
+   /* in */int Rfragments)
+   {
+      _Mfragments = Mfragments;
+      _Rfragments = Rfragments;
+
+      _Nfragments = _Mfragments + _Rfragments;
+      // _Mseglen = _Mfragments * _Lfield;
+      _Mlen = _Plen * _Mfragments;
+      _Elen = _Plen * (_Mfragments + _Rfragments);
+   }
+
+   /**
+    * Lfield is the log of the length of the field.
+    */
+   public int Lfield()
+   {
+      return _Lfield;
+   }
+
+   /**
+    * Nsegs is the number of segments in a fragment. Length of fragment in bytes
+    * is 4*Nsegs*Lfield.
+    */
+   public int Nsegs()
+   {
+      return _Nsegs;
+   }
+
+   /**
+    * TableLength is 2^{Lfield}
+    */
+   public int TableLength()
+   {
+      return _TableLength;
+   }
+
+   /**
+    * SMultField is the size of the multiplicative field (2^{Lfield}-1) ==
+    * TableLength - 1.
+    */
+   public int SMultField()
+   {
+      return _SMultField;
+   }
+
+   /**
+    * Plen is the fragment length in words excluding the overhead for storing
+    * the index.
+    */
+   public int Plen()
+   {
+      return _Plen;
+   }
+
+   /**
+    * Plentot is the fragment length in words including the overhead for storing
+    * the index.
+    */
+   public int Plentot()
+   {
+      return _Plentot;
+   }
+
+   /**
+    * Mfragments is the number of message fragments
+    * 
+    * @return return == return the number of message fragments.
+    * 
+    * IMPORTANT: The max of Mfragments and Rfragments is at most 2^{Lfield-1}.
+    * 
+    * Lfield must be set large enough to make this true else the encoding and
+    * decoding won't work
+    */
+   public int Mfragments()
+   {
+      return _Mfragments;
+   }
+
+   /**
+    * Rfragments is the number of redundant fragments
+    * 
+    * @return return == return the number of message fragments.
+    * 
+    * IMPORTANT: The max of Mfragments and Rfragments is at most 2^{Lfield-1}.
+    * 
+    * Lfield must be set large enough to make this true else the encoding and
+    * decoding won't work.
+    */
+   public int Rfragments()
+   {
+      return _Rfragments;
+   }
+
+   /**
+    * Nfragments is the total number of fragments sent.
+    */
+   public int Nfragments()
+   {
+      return _Nfragments;
+   }
+
+   /**
+    * Mlen is the length of the message in words.
+    */
+   public int Mlen()
+   {
+      return _Mlen;
+   }
+
+   /**
+    * Elen is the length of the encoding in words.
+    */
+   public int Elen()
+   {
+      return _Elen;
+   }
+
+   /**
+    * Nsegs is the number of segments in each fragment in which to perform the
+    * Galois Field operations.
+    * 
+    * @param n == number to set Nsegs to, n > 0.
+    * @return return==false if n <= 0, otherwise returns true.
+    */
+   public boolean setNsegs(int n)
+   {
+      if (n < 1)
+         return false;
+      _Nsegs = n;
+      resetParam();
+
+      return true;
+   }
+
+   /**
+    * Lfield (length of field) must be (1 <= Lfield <= 16) otherwise function
+    * returns false and Lfield stays default.
+    * 
+    * @param n ==
+    *           number to set Lfield to, 1 <= Lfield <= 16.
+    * @return return==Lfield must be (1 <= Lfield <= 16) otherwise function
+    *         returns false and Lfield stays default
+    */
+   public boolean setLfield(int n)
+   {
+      if (n <= 16 && n >= 1)
+         _Lfield = n;
+      else
+         return false;
+
+      resetParam();
+
+      return true;
+   }
+
+   public void resetParam()
+   {
+      _TableLength = 1 << _Lfield;
+      _SMultField = (1 << _Lfield) - 1;
+      _Plen = _Nsegs * _Lfield;
+      _Plentot = _Plen + 1;
+   }
+
+}
diff --git a/Splitter-ng-plugin-jigdfs/src/org/jigdfs/serivce/Service.java b/Splitter-ng-plugin-jigdfs/src/org/jigdfs/serivce/Service.java
new file mode 100644 (file)
index 0000000..1eea8f7
--- /dev/null
@@ -0,0 +1,32 @@
+package org.jigdfs.serivce;
+
+import java.io.IOException;
+
+import net.jxta.exception.PeerGroupException;
+
+/**
+ * Service base class
+ * @author jbian
+ *
+ */
+public abstract class Service { 
+    
+    public abstract Object getResult();
+    
+    /**
+     * 
+     */
+    protected boolean isRunning = false;
+        
+    protected void setIsRunning(boolean isRunning){
+       this.isRunning = isRunning;
+    }
+    
+    public boolean isRunning() {
+       return isRunning;
+    }
+    /**
+     * run this service
+     */
+    public abstract void runService() throws Exception;
+}
diff --git a/Splitter-ng-plugin-jigdfs/src/org/jigdfs/serivce/ServiceEvent.java b/Splitter-ng-plugin-jigdfs/src/org/jigdfs/serivce/ServiceEvent.java
new file mode 100644 (file)
index 0000000..0029794
--- /dev/null
@@ -0,0 +1,32 @@
+package org.jigdfs.serivce;
+
+import java.util.EventObject;
+
+public class ServiceEvent extends EventObject {
+
+    private ServiceResponseMsg serviceResponseMsg = null;
+    /**
+     * 
+     */
+    private static final long serialVersionUID = -7254048369983067435L;
+
+    public ServiceEvent(Object source, ServiceResponseMsg serviceResponseMsg) {
+       super(source);
+       this.serviceResponseMsg = serviceResponseMsg;
+    }
+
+    /**
+     * @param serviceResponseMsg the serviceResponseMsg to set
+     */
+    public void setServiceResponseMsg(ServiceResponseMsg serviceResponseMsg) {
+       this.serviceResponseMsg = serviceResponseMsg;
+    }
+
+    /**
+     * @return the serviceResponseMsg
+     */
+    public ServiceResponseMsg getServiceResponseMsg() {
+       return serviceResponseMsg;
+    }
+
+}
diff --git a/Splitter-ng-plugin-jigdfs/src/org/jigdfs/serivce/ServiceListener.java b/Splitter-ng-plugin-jigdfs/src/org/jigdfs/serivce/ServiceListener.java
new file mode 100644 (file)
index 0000000..68a6aee
--- /dev/null
@@ -0,0 +1,7 @@
+package org.jigdfs.serivce;
+
+import org.jigdfs.baseInterface.Listener;
+
+public interface ServiceListener extends Listener {
+    void serviceFinishedEvent(ServiceEvent event);
+}
diff --git a/Splitter-ng-plugin-jigdfs/src/org/jigdfs/serivce/ServiceResponseMsg.java b/Splitter-ng-plugin-jigdfs/src/org/jigdfs/serivce/ServiceResponseMsg.java
new file mode 100644 (file)
index 0000000..5fa6e8b
--- /dev/null
@@ -0,0 +1,14 @@
+package org.jigdfs.serivce;
+
+import org.jigdfs.baseClass.ResponseMsg;
+
+public class ServiceResponseMsg extends ResponseMsg {
+
+    public ServiceResponseMsg(String resultMessage, Object result, Object source) {
+       super(resultMessage, result, source);
+    }
+    
+    public ServiceResponseMsg(String resultMessage, Object result) {
+       super(resultMessage, result);   
+    }    
+}
index e3848d6..0c6e3ea 100644 (file)
@@ -191,8 +191,8 @@ public class SplitterTest implements SplitterCallback {
                                        Map<String, Integer> codecParameter11 = new TreeMap<String, Integer>();
                                        codecParameter11.put("k", 3);
                                        codecParameter11.put("m", 3);
-                                       codecParameter11.put("w", 16);
-                                       codecParameter11.put("packetsize", 64);
+                                       codecParameter11.put("w", 8);
+                                       codecParameter11.put("packetsize", 32);
                                        System.out.println("\t\tinitialisiere mit" + " k="
                                                        + codecParameter11.get("k") + " m="
                                                        + codecParameter11.get("m") + " w="
@@ -206,7 +206,7 @@ public class SplitterTest implements SplitterCallback {
                                        
                                        // Metadaten bauen vorlage
                                        Map<String, Object> metadatajerasure11 = new TreeMap<String, Object>();
-                                       metadatajerasure11.put("fragmentsize", (int) 4096);
+                                       metadatajerasure11.put("fragmentsize", (int) 256);
                                        // Beleiebige weitere Metadaten
                                        
                                        splitter_metadata_map.put(splitterjerasure11, metadatajerasure11);
index 7dc0a58..48f4217 100644 (file)
--- a/build.xml
+++ b/build.xml
@@ -6,6 +6,7 @@
        <property name="Splitter-ng-plugin-jerasure.location" value="Splitter-ng-plugin-jerasure" />
        <property name="Splitter-ng-plugin-jerasure-purejava.location" value="Splitter-ng-plugin-jerasure-purejava" />
        <property name="Splitter-ng-plugin-raid1.location" value="Splitter-ng-plugin-raid1" />
+       <property name="Splitter-ng-plugin-jigdfs.location" value="Splitter-ng-plugin-jigdfs" />
        <property name="Splitter-ng-test.location" value="Splitter-ng-test" />
        <target name="init">
                <exec executable="git" failonerror="no">
                <ant antfile="build.xml" dir="${Splitter-ng-plugin-jerasure.location}" inheritAll="false" target="build" />
                <ant antfile="build.xml" dir="${Splitter-ng-plugin-jerasure-purejava.location}" inheritAll="false" target="build" />
                <ant antfile="build.xml" dir="${Splitter-ng-plugin-raid1.location}" inheritAll="false" target="build" />
+               <ant antfile="build.xml" dir="${Splitter-ng-plugin-jigdfs.location}" inheritAll="false" target="build" />
                <ant antfile="build.xml" dir="${Splitter-ng-test.location}" inheritAll="false" target="build" />
        </target>
-       <target name="distall" depends="init" description="Build and Distribute Splitter-NG, all Plugins and Splitter-test to ./dist">
+       <target name="distall" depends="init,splitter,test,jsharing,jerasure,jerasure-purejava,raid1" description="Build and Distribute Splitter-NG, all Plugins and Splitter-test to ./dist"/>
+       
+       <target name="splitter" depends="init" >
                <ant antfile="build.xml" dir="${Splitter-ng.location}" inheritAll="false" target="dist" />
+       </target>
+       <target name="test" depends="splitter" >
+               <ant antfile="build.xml" dir="${Splitter-ng-test.location}" inheritAll="false" target="dist" />
+       </target>
+       <target name="jsharing" depends="splitter" >
                <ant antfile="build.xml" dir="${Splitter-ng-plugin-JSharing.location}" inheritAll="false" target="dist" />
+       </target>
+       <target name="jerasure" depends="splitter" >
                <ant antfile="build.xml" dir="${Splitter-ng-plugin-jerasure.location}" inheritAll="false" target="dist" />
+       </target>
+       <target name="jerasure-purejava" depends="splitter" >
                <ant antfile="build.xml" dir="${Splitter-ng-plugin-jerasure-purejava.location}" inheritAll="false" target="dist" />
+       </target>
+       <target name="raid1" depends="splitter" >
                <ant antfile="build.xml" dir="${Splitter-ng-plugin-raid1.location}" inheritAll="false" target="dist" />
-               <ant antfile="build.xml" dir="${Splitter-ng-test.location}" inheritAll="false" target="dist" />
        </target>
+       <target name="jigdfs" depends="splitter" >
+               <ant antfile="build.xml" dir="${Splitter-ng-plugin-jigdfs.location}" inheritAll="false" target="dist" />
+       </target>
+
+       
 </project>