[freenet-cvs] r17917 - trunk/freenet/src/net/i2p/util

nextgens at freenetproject.org nextgens at freenetproject.org
Fri Feb 15 06:19:18 UTC 2008


Author: nextgens
Date: 2008-02-15 06:19:18 +0000 (Fri, 15 Feb 2008)
New Revision: 17917

Modified:
   trunk/freenet/src/net/i2p/util/NativeBigInteger.java
Log:
indent

Modified: trunk/freenet/src/net/i2p/util/NativeBigInteger.java
===================================================================
--- trunk/freenet/src/net/i2p/util/NativeBigInteger.java	2008-02-15 06:18:35 UTC (rev 17916)
+++ trunk/freenet/src/net/i2p/util/NativeBigInteger.java	2008-02-15 06:19:18 UTC (rev 17917)
@@ -96,79 +96,76 @@
  *
  */
 public class NativeBigInteger extends BigInteger {
-    /** did we load the native lib correctly? */
-    private static boolean _nativeOk = false;
-    /** 
-     * do we want to dump some basic success/failure info to stderr during 
-     * initialization?  this would otherwise use the Log component, but this makes
-     * it easier for other systems to reuse this class
-     */
-    private static final boolean _doLog = true;
-    
-    private final static String JBIGI_OPTIMIZATION_K6         	= "k6";
-    private final static String JBIGI_OPTIMIZATION_K6_2       	= "k62";
-    private final static String JBIGI_OPTIMIZATION_K6_3			= "k63";
-    private final static String JBIGI_OPTIMIZATION_ATHLON   	= "athlon";
-    private final static String JBIGI_OPTIMIZATION_X86_64    	= "x86_64";
-    private final static String JBIGI_OPTIMIZATION_X86_64_32    = "x86_64_32";
-    private final static String JBIGI_OPTIMIZATION_PENTIUM    	= "pentium";
-    private final static String JBIGI_OPTIMIZATION_PENTIUMMMX 	= "pentiummmx";
-    private final static String JBIGI_OPTIMIZATION_PENTIUM2 	= "pentium2";
-    private final static String JBIGI_OPTIMIZATION_PENTIUM3 	= "pentium3";
-    private final static String JBIGI_OPTIMIZATION_PENTIUM4 	= "pentium4";
-    private final static String JBIGI_OPTIMIZATION_PPC 			= "ppc";
 
-    private final static String sCPUType; //The CPU Type to optimize for (one of the above strings)
-    
-    private static final long serialVersionUID = 0xc5392a97bb283dd2L;
-    
-    static {
-    	sCPUType = resolveCPUType();
-   		loadNative();
-    }
-    
-	 /** Tries to resolve the best type of CPU that we have an optimized jbigi-dll/so for.
-	  * @return A string containing the CPU-type or null if CPU type is unknown
-	  */
-    private static String resolveCPUType() {
+	/** did we load the native lib correctly? */
+	private static boolean _nativeOk = false;
+	/** 
+	 * do we want to dump some basic success/failure info to stderr during 
+	 * initialization?  this would otherwise use the Log component, but this makes
+	 * it easier for other systems to reuse this class
+	 */
+	private static final boolean _doLog = true;
+	private final static String JBIGI_OPTIMIZATION_K6 = "k6";
+	private final static String JBIGI_OPTIMIZATION_K6_2 = "k62";
+	private final static String JBIGI_OPTIMIZATION_K6_3 = "k63";
+	private final static String JBIGI_OPTIMIZATION_ATHLON = "athlon";
+	private final static String JBIGI_OPTIMIZATION_X86_64 = "x86_64";
+	private final static String JBIGI_OPTIMIZATION_X86_64_32 = "x86_64_32";
+	private final static String JBIGI_OPTIMIZATION_PENTIUM = "pentium";
+	private final static String JBIGI_OPTIMIZATION_PENTIUMMMX = "pentiummmx";
+	private final static String JBIGI_OPTIMIZATION_PENTIUM2 = "pentium2";
+	private final static String JBIGI_OPTIMIZATION_PENTIUM3 = "pentium3";
+	private final static String JBIGI_OPTIMIZATION_PENTIUM4 = "pentium4";
+	private final static String JBIGI_OPTIMIZATION_PPC = "ppc";
+	private final static String sCPUType; //The CPU Type to optimize for (one of the above strings)
+	private static final long serialVersionUID = 0xc5392a97bb283dd2L;
+
+	static {
+		sCPUType = resolveCPUType();
+		loadNative();
+	}
+
+	/** Tries to resolve the best type of CPU that we have an optimized jbigi-dll/so for.
+	 * @return A string containing the CPU-type or null if CPU type is unknown
+	 */
+	private static String resolveCPUType() {
 		try {
-			if(System.getProperty("os.arch").toLowerCase().matches("(i?[x0-9]86_64|amd64)")){
-					return JBIGI_OPTIMIZATION_X86_64;
-			}else 	if(System.getProperty("os.arch").toLowerCase().matches("(ppc)")){
-					System.out.println("Detected PowerPC!");
-					return JBIGI_OPTIMIZATION_PPC;
-			}else{
+			if(System.getProperty("os.arch").toLowerCase().matches("(i?[x0-9]86_64|amd64)"))
+				return JBIGI_OPTIMIZATION_X86_64;
+			else if(System.getProperty("os.arch").toLowerCase().matches("(ppc)")) {
+				System.out.println("Detected PowerPC!");
+				return JBIGI_OPTIMIZATION_PPC;
+			} else {
 				CPUInfo c = CPUID.getInfo();
-				if (c instanceof AMDCPUInfo) {
+				if(c instanceof AMDCPUInfo) {
 					AMDCPUInfo amdcpu = (AMDCPUInfo) c;
-					if (amdcpu.IsAthlon64Compatible())
+					if(amdcpu.IsAthlon64Compatible())
 						return JBIGI_OPTIMIZATION_X86_64_32;
-					if (amdcpu.IsAthlonCompatible())
+					if(amdcpu.IsAthlonCompatible())
 						return JBIGI_OPTIMIZATION_ATHLON;
-					if (amdcpu.IsK6_3_Compatible())
+					if(amdcpu.IsK6_3_Compatible())
 						return JBIGI_OPTIMIZATION_K6_3;
-					if (amdcpu.IsK6_2_Compatible())
+					if(amdcpu.IsK6_2_Compatible())
 						return JBIGI_OPTIMIZATION_K6_2;
-					if (amdcpu.IsK6Compatible())
+					if(amdcpu.IsK6Compatible())
 						return JBIGI_OPTIMIZATION_K6;
-				} else {
-					if (c instanceof IntelCPUInfo) {
+				} else
+					if(c instanceof IntelCPUInfo) {
 						IntelCPUInfo intelcpu = (IntelCPUInfo) c;
-						if (intelcpu.IsPentium4Compatible())
+						if(intelcpu.IsPentium4Compatible())
 							return JBIGI_OPTIMIZATION_PENTIUM4;
-						if (intelcpu.IsPentium3Compatible())
+						if(intelcpu.IsPentium3Compatible())
 							return JBIGI_OPTIMIZATION_PENTIUM3;
-						if (intelcpu.IsPentium2Compatible())
+						if(intelcpu.IsPentium2Compatible())
 							return JBIGI_OPTIMIZATION_PENTIUM2;
-						if (intelcpu.IsPentiumMMXCompatible())
+						if(intelcpu.IsPentiumMMXCompatible())
 							return JBIGI_OPTIMIZATION_PENTIUMMMX;
-						if (intelcpu.IsPentiumCompatible())
+						if(intelcpu.IsPentiumCompatible())
 							return JBIGI_OPTIMIZATION_PENTIUM;
 					}
-				}
 			}
 			return null;
-		} catch (UnknownCPUException e) {
+		} catch(UnknownCPUException e) {
 			return null; //TODO: Log something here maybe..
 		}
 	}
@@ -184,47 +181,47 @@
 	 *            big endian twos complement representation of the modulus
 	 * @return big endian twos complement representation of (base ^ exponent) % modulus
 	 */
-    public native static byte[] nativeModPow(byte base[], byte exponent[], byte modulus[]);
- 
-    /**
-     * Converts a BigInteger byte-array to a 'double'
-     * @param ba Big endian twos complement representation of the BigInteger to convert to a double
-     * @return The plain double-value represented by 'ba'
-     */
-    public native static double nativeDoubleValue(byte ba[]);
+	public native static byte[] nativeModPow(byte base[], byte exponent[], byte modulus[]);
 
-    private byte[] cachedBa=null;
-    
-    public NativeBigInteger(byte val[]) {
-        super(val);
-        // Takes up too much RAM
+	/**
+	 * Converts a BigInteger byte-array to a 'double'
+	 * @param ba Big endian twos complement representation of the BigInteger to convert to a double
+	 * @return The plain double-value represented by 'ba'
+	 */
+	public native static double nativeDoubleValue(byte ba[]);
+	private byte[] cachedBa = null;
+
+	public NativeBigInteger(byte val[]) {
+		super(val);
+	// Takes up too much RAM
 //        int targetLength = bitLength() / 8 + 1;
 //        if(val.length == targetLength)
 //            cachedBa = val;
-    }
+	}
 
-    public NativeBigInteger(int signum, byte magnitude[]) {
-        super(signum, magnitude);
-    }
+	public NativeBigInteger(int signum, byte magnitude[]) {
+		super(signum, magnitude);
+	}
 
-    public NativeBigInteger(int bitlen, int certainty, Random rnd) {
-        super(bitlen, certainty, rnd);
-    }
+	public NativeBigInteger(int bitlen, int certainty, Random rnd) {
+		super(bitlen, certainty, rnd);
+	}
 
-    public NativeBigInteger(int numbits, Random rnd) {
-        super(numbits, rnd);
-    }
+	public NativeBigInteger(int numbits, Random rnd) {
+		super(numbits, rnd);
+	}
 
-    public NativeBigInteger(String val) {
-        super(val);
-    }
+	public NativeBigInteger(String val) {
+		super(val);
+	}
 
-    public NativeBigInteger(String val, int radix) {
-        super(val, radix);
-    }
+	public NativeBigInteger(String val, int radix) {
+		super(val, radix);
+	}
+
 	/**Creates a new NativeBigInteger with the same value
-	*  as the supplied BigInteger. Warning!, not very efficent
-	*/
+	 *  as the supplied BigInteger. Warning!, not very efficent
+	 */
 	public NativeBigInteger(BigInteger integer) {
 		//Now, why doesn't sun provide a constructor
 		//like this one in BigInteger?
@@ -232,388 +229,373 @@
 	}
 
 	public BigInteger modPow(BigInteger exponent, BigInteger m) {
-        if (_nativeOk)
-            return new NativeBigInteger(nativeModPow(toByteArray(), exponent.toByteArray(), m.toByteArray()));
-        else
-            return new NativeBigInteger(super.modPow(exponent, m));
-    }
-    public byte[] toByteArray(){
-    	if(cachedBa == null) //Since we are immutable it is safe to never update the cached ba after it has initially been generated
-    		cachedBa = super.toByteArray();
-    	return cachedBa;
-    }
-    
-    public String toString(int radix) {
-        if(radix == 16) return toHexString();
-        return super.toString(radix);
-    }
-    
-    public String toHexString() {
-        byte[] buf = toByteArray();
-        return HexUtil.bytesToHex(buf);
-    }
-    
-    public double doubleValue() {
-        if (_nativeOk)
-            return nativeDoubleValue(toByteArray());
-        else
-            return super.doubleValue();
-    }
-    /**
-     * 
-     * @return True iff native methods will be used by this class
-     */
-    public static boolean isNative(){
-    	return _nativeOk;
-    }
- 
-    /**
-     * <p>Compare the BigInteger.modPow/doubleValue vs the NativeBigInteger.modPow/doubleValue of some 
-     * really big (2Kbit) numbers 100 different times and benchmark the 
-     * performance (or shit a brick if they don't match).  </p>
-     *
-     */
-    public static void main(String args[]) {
-        runModPowTest(100);
-        runDoubleValueTest(100);
-    }
+		if(_nativeOk)
+			return new NativeBigInteger(nativeModPow(toByteArray(), exponent.toByteArray(), m.toByteArray()));
+		else
+			return new NativeBigInteger(super.modPow(exponent, m));
+	}
 
-    /* the sample numbers are elG generator/prime so we can test with reasonable numbers */
-    private final static byte[] _sampleGenerator = new BigInteger("2").toByteArray();
-    private final static byte[] _samplePrime = new BigInteger("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
-                                                              + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
-                                                              + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
-                                                              + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
-                                                              + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"
-                                                              + "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"
-                                                              + "83655D23DCA3AD961C62F356208552BB9ED529077096966D"
-                                                              + "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"
-                                                              + "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9"
-                                                              + "DE2BCBF6955817183995497CEA956AE515D2261898FA0510"
-                                                              + "15728E5A8AACAA68FFFFFFFFFFFFFFFF", 16).toByteArray();
+	public byte[] toByteArray() {
+		if(cachedBa == null) //Since we are immutable it is safe to never update the cached ba after it has initially been generated
+			cachedBa = super.toByteArray();
+		return cachedBa;
+	}
 
-    private static void runModPowTest(int numRuns) {
-        System.out.println("DEBUG: Warming up the random number generator...");
-        SecureRandom rand = new SecureRandom();
-        rand.nextBoolean();
-        System.out.println("DEBUG: Random number generator warmed up");
+	public String toString(int radix) {
+		if(radix == 16)
+			return toHexString();
+		return super.toString(radix);
+	}
 
-        BigInteger jg = new BigInteger(_sampleGenerator);
-        BigInteger jp = new BigInteger(_samplePrime);
+	public String toHexString() {
+		byte[] buf = toByteArray();
+		return HexUtil.bytesToHex(buf);
+	}
 
-        long totalTime = 0;
-        long javaTime = 0;
+	public double doubleValue() {
+		if(_nativeOk)
+			return nativeDoubleValue(toByteArray());
+		else
+			return super.doubleValue();
+	}
 
-        int runsProcessed = 0;
-        for (runsProcessed = 0; runsProcessed < numRuns; runsProcessed++) {
-            BigInteger bi = new BigInteger(2048, rand);
-            NativeBigInteger g = new NativeBigInteger(_sampleGenerator);
-            NativeBigInteger p = new NativeBigInteger(_samplePrime);
-            NativeBigInteger k = new NativeBigInteger(1, bi.toByteArray());
-            long beforeModPow = System.currentTimeMillis();
-            BigInteger myValue = g.modPow(k, p);
-            long afterModPow = System.currentTimeMillis();
-            BigInteger jval = jg.modPow(bi, jp);
-            long afterJavaModPow = System.currentTimeMillis();
+	/**
+	 * 
+	 * @return True iff native methods will be used by this class
+	 */
+	public static boolean isNative() {
+		return _nativeOk;
+	}
 
-            totalTime += (afterModPow - beforeModPow);
-            javaTime += (afterJavaModPow - afterModPow);
-            if (!myValue.equals(jval)) {
-                System.err.println("ERROR: [" + runsProcessed + "]\tnative modPow != java modPow");
-                System.err.println("ERROR: native modPow value: " + myValue.toString());
-                System.err.println("ERROR: java modPow value: " + jval.toString());
-                System.err.println("ERROR: run time: " + totalTime + "ms (" + (totalTime / (runsProcessed + 1)) + "ms each)");
-                break;
-            } else {
-                System.out.println("DEBUG: current run time: " + (afterModPow - beforeModPow) + "ms (total: " 
-                                   + totalTime + "ms, " + (totalTime / (runsProcessed + 1)) + "ms each)");
-            }
-        }
-        System.out.println("INFO: run time: " + totalTime + "ms (" + (totalTime / (runsProcessed + 1)) + "ms each)");
-        if (numRuns == runsProcessed)
-            System.out.println("INFO: " + runsProcessed + " runs complete without any errors");
-        else
-            System.out.println("ERROR: " + runsProcessed + " runs until we got an error");
+	/**
+	 * <p>Compare the BigInteger.modPow/doubleValue vs the NativeBigInteger.modPow/doubleValue of some 
+	 * really big (2Kbit) numbers 100 different times and benchmark the 
+	 * performance (or shit a brick if they don't match).  </p>
+	 *
+	 */
+	public static void main(String args[]) {
+		runModPowTest(100);
+		runDoubleValueTest(100);
+	}
 
-        if (_nativeOk) {
-            System.out.println("native run time: \t" + totalTime + "ms (" + (totalTime / (runsProcessed + 1))
-                               + "ms each)");
-            System.out.println("java run time:   \t" + javaTime + "ms (" + (javaTime / (runsProcessed + 1)) + "ms each)");
-            System.out.println("native = " + ((totalTime * 100.0d) / (double) javaTime) + "% of pure java time");
-        } else {
-            System.out.println("java run time: \t" + javaTime + "ms (" + (javaTime / (runsProcessed + 1)) + "ms each)");
-            System.out.println("However, we couldn't load the native library, so this doesn't test much");
-        }
-    }
-    
-    private static void runDoubleValueTest(int numRuns) {
-        System.out.println("DEBUG: Warming up the random number generator...");
-        SecureRandom rand = new SecureRandom();
-        rand.nextBoolean();
-        System.out.println("DEBUG: Random number generator warmed up");
+	/* the sample numbers are elG generator/prime so we can test with reasonable numbers */
+	private final static byte[] _sampleGenerator = new BigInteger("2").toByteArray();
+	private final static byte[] _samplePrime = new BigInteger("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" + "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" + "83655D23DCA3AD961C62F356208552BB9ED529077096966D" + "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" + "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" + "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" + "15728E5A8AACAA68FFFFFFFFFFFFFFFF", 16).toByteArray();
 
-        BigInteger jg = new BigInteger(_sampleGenerator);
+	private static void runModPowTest(int numRuns) {
+		System.out.println("DEBUG: Warming up the random number generator...");
+		SecureRandom rand = new SecureRandom();
+		rand.nextBoolean();
+		System.out.println("DEBUG: Random number generator warmed up");
 
-        long totalTime = 0;
-        long javaTime = 0;
+		BigInteger jg = new BigInteger(_sampleGenerator);
+		BigInteger jp = new BigInteger(_samplePrime);
 
-        int MULTIPLICATOR = 50000; //Run the doubleValue() calls within a loop since they are pretty fast.. 
-        int runsProcessed = 0;
-        for (runsProcessed = 0; runsProcessed < numRuns; runsProcessed++) {
-            NativeBigInteger g = new NativeBigInteger(_sampleGenerator);
-            long beforeDoubleValue = System.currentTimeMillis();
-            double dNative=0;
-            for(int mult=0;mult<MULTIPLICATOR;mult++)
-            	dNative = g.doubleValue();
-            long afterDoubleValue = System.currentTimeMillis();
-            double jval=0;
-            for(int mult=0;mult<MULTIPLICATOR;mult++)
-            	jval = jg.doubleValue();
-            long afterJavaDoubleValue = System.currentTimeMillis();
+		long totalTime = 0;
+		long javaTime = 0;
 
-            totalTime += (afterDoubleValue - beforeDoubleValue);
-            javaTime += (afterJavaDoubleValue - afterDoubleValue);
-            if (dNative!=jval) {
-                System.err.println("ERROR: [" + runsProcessed + "]\tnative double != java double");
-                System.err.println("ERROR: native double value: " + dNative);
-                System.err.println("ERROR: java double value: " + jval);
-                System.err.println("ERROR: run time: " + totalTime + "ms (" + (totalTime / (runsProcessed + 1)) + "ms each)");
-                break;
-            } else {
-                System.out.println("DEBUG: current run time: " + (afterDoubleValue - beforeDoubleValue) + "ms (total: " 
-                                   + totalTime + "ms, " + (totalTime / (runsProcessed + 1)) + "ms each)");
-            }
-        }
-        System.out.println("INFO: run time: " + totalTime + "ms (" + (totalTime / (runsProcessed + 1)) + "ms each)");
-        if (numRuns == runsProcessed)
-            System.out.println("INFO: " + runsProcessed + " runs complete without any errors");
-        else
-            System.out.println("ERROR: " + runsProcessed + " runs until we got an error");
+		int runsProcessed = 0;
+		for(runsProcessed = 0; runsProcessed < numRuns; runsProcessed++) {
+			BigInteger bi = new BigInteger(2048, rand);
+			NativeBigInteger g = new NativeBigInteger(_sampleGenerator);
+			NativeBigInteger p = new NativeBigInteger(_samplePrime);
+			NativeBigInteger k = new NativeBigInteger(1, bi.toByteArray());
+			long beforeModPow = System.currentTimeMillis();
+			BigInteger myValue = g.modPow(k, p);
+			long afterModPow = System.currentTimeMillis();
+			BigInteger jval = jg.modPow(bi, jp);
+			long afterJavaModPow = System.currentTimeMillis();
 
-        if (_nativeOk) {
-            System.out.println("native run time: \t" + totalTime + "ms (" + (totalTime / (runsProcessed + 1))
-                               + "ms each)");
-            System.out.println("java run time:   \t" + javaTime + "ms (" + (javaTime / (runsProcessed + 1)) + "ms each)");
-            System.out.println("native = " + ((totalTime * 100.0d) / (double) javaTime) + "% of pure java time");
-        } else {
-            System.out.println("java run time: \t" + javaTime + "ms (" + (javaTime / (runsProcessed + 1)) + "ms each)");
-            System.out.println("However, we couldn't load the native library, so this doesn't test much");
-        }
-    }
-    
- 
-    /**
-     * <p>Do whatever we can to load up the native library backing this BigInteger's native methods.
-     * If it can find a custom built jbigi.dll / libjbigi.so, it'll use that.  Otherwise
-     * it'll try to look in the classpath for the correct library (see loadFromResource).
-     * If the user specifies -Djbigi.enable=false it'll skip all of this.</p>
-     *
-     */
-    private static final void loadNative() {
-    	try{
-        String wantedProp = System.getProperty("jbigi.enable", "true");
-        boolean wantNative = "true".equalsIgnoreCase(wantedProp);
-        if (wantNative) {
-            boolean loaded = loadFromResource(true);
-            if (loaded) {
-                _nativeOk = true;
-                if (_doLog)
-                    System.err.println("INFO: Optimized native BigInteger library '"+getResourceName(true)+"' loaded from resource");
-            } else {
-                loaded = loadGeneric(true);
-                if (loaded) {
-                    _nativeOk = true;
-                    if (_doLog)
-                        System.err.println("INFO: Optimized native BigInteger library '"+getMiddleName(true)+"' loaded from somewhere in the path");
-                } else {
-                	loaded = loadFromResource(false);
-                    if (loaded) {
-                        _nativeOk = true;
-                        if (_doLog)
-                            System.err.println("INFO: Non-optimized native BigInteger library '"+getResourceName(false)+"' loaded from resource");
-                    } else {
-                        loaded = loadGeneric(false);
-                        if (loaded) {
-                            _nativeOk = true;
-                            if (_doLog)
-                                System.err.println("INFO: Non-optimized native BigInteger library '"+getMiddleName(false)+"' loaded from somewhere in the path");
-                        } else {
-                            _nativeOk = false;          
-                        }
-                    }       
-                }
-            }
-        }
-        if (_doLog && !_nativeOk)
-        	System.err.println("INFO: Native BigInteger library jbigi not loaded - using pure java");
-    	}catch(Throwable e){
-            if (_doLog)
-            	System.err.println("INFO: Native BigInteger library jbigi not loaded, reason: '"+e.getMessage()+"' - using pure java");
-    	}
-    }
-    
-    /** 
-     * <p>Try loading it from an explictly build jbigi.dll / libjbigi.so first, before 
-     * looking into a jbigi.jar for any other libraries.</p>
-     *
-     * @return true if it was loaded successfully, else false
-     *
-     */
-    private static final boolean loadGeneric(boolean optimized) {
-        try {
-        	String name = getMiddleName(optimized);
-        	if(name == null)
-        		return false;
-            System.loadLibrary(name);
-            return true;
-        } catch (UnsatisfiedLinkError ule) {
-            return false;
-        }
-    }
-    
-    /**
-     * A helper function to make loading the native library easier.
-     * @param f The File to which to write the library
-     * @param URL The URL of the resource
-     * @return True is the library was loaded, false on error
-     * @throws FileNotFoundException If the library could not be read from the reference
-     * @throws UnsatisfiedLinkError If and only if the library is incompatible with this system
-     */
+			totalTime += (afterModPow - beforeModPow);
+			javaTime += (afterJavaModPow - afterModPow);
+			if(!myValue.equals(jval)) {
+				System.err.println("ERROR: [" + runsProcessed + "]\tnative modPow != java modPow");
+				System.err.println("ERROR: native modPow value: " + myValue.toString());
+				System.err.println("ERROR: java modPow value: " + jval.toString());
+				System.err.println("ERROR: run time: " + totalTime + "ms (" + (totalTime / (runsProcessed + 1)) + "ms each)");
+				break;
+			} else
+				System.out.println("DEBUG: current run time: " + (afterModPow - beforeModPow) + "ms (total: " + totalTime + "ms, " + (totalTime / (runsProcessed + 1)) + "ms each)");
+		}
+		System.out.println("INFO: run time: " + totalTime + "ms (" + (totalTime / (runsProcessed + 1)) + "ms each)");
+		if(numRuns == runsProcessed)
+			System.out.println("INFO: " + runsProcessed + " runs complete without any errors");
+		else
+			System.out.println("ERROR: " + runsProcessed + " runs until we got an error");
 
-    private static final boolean tryLoadResource(File f, URL resource)
-	throws FileNotFoundException, UnsatisfiedLinkError {
-	InputStream is;
-	try {
-	    is=resource.openStream();
-	} catch(IOException e) {
-		f.delete();
-	    throw new FileNotFoundException();
+		if(_nativeOk) {
+			System.out.println("native run time: \t" + totalTime + "ms (" + (totalTime / (runsProcessed + 1)) + "ms each)");
+			System.out.println("java run time:   \t" + javaTime + "ms (" + (javaTime / (runsProcessed + 1)) + "ms each)");
+			System.out.println("native = " + ((totalTime * 100.0d) / (double) javaTime) + "% of pure java time");
+		} else {
+			System.out.println("java run time: \t" + javaTime + "ms (" + (javaTime / (runsProcessed + 1)) + "ms each)");
+			System.out.println("However, we couldn't load the native library, so this doesn't test much");
+		}
 	}
-	
-	try {
-		f.deleteOnExit();
-	    FileOutputStream fos=new FileOutputStream(f);
-	    byte[] buf=new byte[4096*1024];
-	    int read;
-	    while((read=is.read(buf))>0)
-		fos.write(buf,0,read);
-	    fos.close();
-	    System.load(f.getAbsolutePath());
-	    return true;
-	} catch(IOException e) {
-	} catch(UnsatisfiedLinkError ule) {
-	    f.delete();
-	    // likely to be "noexec" 
-	    if(ule.toString().toLowerCase().indexOf("not permitted")==-1)
-	    	throw ule;
-	} finally {
-		f.delete();
+
+	private static void runDoubleValueTest(int numRuns) {
+		System.out.println("DEBUG: Warming up the random number generator...");
+		SecureRandom rand = new SecureRandom();
+		rand.nextBoolean();
+		System.out.println("DEBUG: Random number generator warmed up");
+
+		BigInteger jg = new BigInteger(_sampleGenerator);
+
+		long totalTime = 0;
+		long javaTime = 0;
+
+		int MULTIPLICATOR = 50000; //Run the doubleValue() calls within a loop since they are pretty fast.. 
+		int runsProcessed = 0;
+		for(runsProcessed = 0; runsProcessed < numRuns; runsProcessed++) {
+			NativeBigInteger g = new NativeBigInteger(_sampleGenerator);
+			long beforeDoubleValue = System.currentTimeMillis();
+			double dNative = 0;
+			for(int mult = 0; mult < MULTIPLICATOR; mult++)
+				dNative = g.doubleValue();
+			long afterDoubleValue = System.currentTimeMillis();
+			double jval = 0;
+			for(int mult = 0; mult < MULTIPLICATOR; mult++)
+				jval = jg.doubleValue();
+			long afterJavaDoubleValue = System.currentTimeMillis();
+
+			totalTime += (afterDoubleValue - beforeDoubleValue);
+			javaTime += (afterJavaDoubleValue - afterDoubleValue);
+			if(dNative != jval) {
+				System.err.println("ERROR: [" + runsProcessed + "]\tnative double != java double");
+				System.err.println("ERROR: native double value: " + dNative);
+				System.err.println("ERROR: java double value: " + jval);
+				System.err.println("ERROR: run time: " + totalTime + "ms (" + (totalTime / (runsProcessed + 1)) + "ms each)");
+				break;
+			} else
+				System.out.println("DEBUG: current run time: " + (afterDoubleValue - beforeDoubleValue) + "ms (total: " + totalTime + "ms, " + (totalTime / (runsProcessed + 1)) + "ms each)");
+		}
+		System.out.println("INFO: run time: " + totalTime + "ms (" + (totalTime / (runsProcessed + 1)) + "ms each)");
+		if(numRuns == runsProcessed)
+			System.out.println("INFO: " + runsProcessed + " runs complete without any errors");
+		else
+			System.out.println("ERROR: " + runsProcessed + " runs until we got an error");
+
+		if(_nativeOk) {
+			System.out.println("native run time: \t" + totalTime + "ms (" + (totalTime / (runsProcessed + 1)) + "ms each)");
+			System.out.println("java run time:   \t" + javaTime + "ms (" + (javaTime / (runsProcessed + 1)) + "ms each)");
+			System.out.println("native = " + ((totalTime * 100.0d) / (double) javaTime) + "% of pure java time");
+		} else {
+			System.out.println("java run time: \t" + javaTime + "ms (" + (javaTime / (runsProcessed + 1)) + "ms each)");
+			System.out.println("However, we couldn't load the native library, so this doesn't test much");
+		}
 	}
 
-	return false;	
-    }
+	/**
+	 * <p>Do whatever we can to load up the native library backing this BigInteger's native methods.
+	 * If it can find a custom built jbigi.dll / libjbigi.so, it'll use that.  Otherwise
+	 * it'll try to look in the classpath for the correct library (see loadFromResource).
+	 * If the user specifies -Djbigi.enable=false it'll skip all of this.</p>
+	 *
+	 */
+	private static final void loadNative() {
+		try {
+			String wantedProp = System.getProperty("jbigi.enable", "true");
+			boolean wantNative = "true".equalsIgnoreCase(wantedProp);
+			if(wantNative) {
+				boolean loaded = loadFromResource(true);
+				if(loaded) {
+					_nativeOk = true;
+					if(_doLog)
+						System.err.println("INFO: Optimized native BigInteger library '" + getResourceName(true) + "' loaded from resource");
+				} else {
+					loaded = loadGeneric(true);
+					if(loaded) {
+						_nativeOk = true;
+						if(_doLog)
+							System.err.println("INFO: Optimized native BigInteger library '" + getMiddleName(true) + "' loaded from somewhere in the path");
+					} else {
+						loaded = loadFromResource(false);
+						if(loaded) {
+							_nativeOk = true;
+							if(_doLog)
+								System.err.println("INFO: Non-optimized native BigInteger library '" + getResourceName(false) + "' loaded from resource");
+						} else {
+							loaded = loadGeneric(false);
+							if(loaded) {
+								_nativeOk = true;
+								if(_doLog)
+									System.err.println("INFO: Non-optimized native BigInteger library '" + getMiddleName(false) + "' loaded from somewhere in the path");
+							} else
+								_nativeOk = false;
+						}
+					}
+				}
+			}
+			if(_doLog && !_nativeOk)
+				System.err.println("INFO: Native BigInteger library jbigi not loaded - using pure java");
+		} catch(Throwable e) {
+			if(_doLog)
+				System.err.println("INFO: Native BigInteger library jbigi not loaded, reason: '" + e.getMessage() + "' - using pure java");
+		}
+	}
 
-    /**
-     * <p>Check all of the jars in the classpath for the file specified by the 
-     * environmental property "jbigi.impl" and load it as the native library 
-     * implementation.  For instance, a windows user on a p4 would define
-     * -Djbigi.impl=win-686 if there is a jbigi.jar in the classpath containing the 
-     * files "win-686", "win-athlon", "freebsd-p4", "linux-p3", where each 
-     * of those files contain the correct binary file for a native library (e.g.
-     * windows DLL, or a *nix .so).  </p>
-     * 
-     * <p>This is a pretty ugly hack, using the general technique illustrated by the
-     * onion FEC libraries.  It works by pulling the resource, writing out the 
-     * byte stream to a temporary file, loading the native library from that file,
-     * then deleting the file.</p>
-     *
-     * @return true if it was loaded successfully, else false
-     *
-     */
-    
-    private static final boolean loadFromResource(boolean optimized) {
-        String resourceName = getResourceName(optimized);
-        if (resourceName == null) return false;
-        URL resource = NativeBigInteger.class.getClassLoader().getResource(resourceName);
-        if (resource == null) {
-            if (_doLog)
-                System.err.println("NOTICE: Resource name [" + getResourceName(true) + "] was not found");
-            return false;
-        }
+	/** 
+	 * <p>Try loading it from an explictly build jbigi.dll / libjbigi.so first, before 
+	 * looking into a jbigi.jar for any other libraries.</p>
+	 *
+	 * @return true if it was loaded successfully, else false
+	 *
+	 */
+	private static final boolean loadGeneric(boolean optimized) {
+		try {
+			String name = getMiddleName(optimized);
+			if(name == null)
+				return false;
+			System.loadLibrary(name);
+			return true;
+		} catch(UnsatisfiedLinkError ule) {
+			return false;
+		}
+	}
 
-        try {
-        	try {
-        		if(tryLoadResource(File.createTempFile("jbigi", "lib.tmp"), resource))
-        			return true;
-        	} catch(IOException e) { }
-        	Logger.error(NativeBigInteger.class, "Can't load from " + System.getProperty("java.io.tmpdir"));
-        	System.err.println("Can't load from " + System.getProperty("java.io.tmpdir"));
-        	if(tryLoadResource(new File("jbigi-lib.tmp"), resource))
-        		return true;
-        } catch(Exception fnf) {
-        	Logger.error(NativeBigInteger.class, "Error reading jbigi resource");
-        	System.err.println("Error reading jbigi resource");
-        } catch(UnsatisfiedLinkError ule) {
-        	Logger.error(NativeBigInteger.class, "Library " + resourceName + " is not appropriate for this system.");
-        	System.err.println("Library " + resourceName + " is not appropriate for this system.");
-        }
+	/**
+	 * A helper function to make loading the native library easier.
+	 * @param f The File to which to write the library
+	 * @param URL The URL of the resource
+	 * @return True is the library was loaded, false on error
+	 * @throws FileNotFoundException If the library could not be read from the reference
+	 * @throws UnsatisfiedLinkError If and only if the library is incompatible with this system
+	 */
+	private static final boolean tryLoadResource(File f, URL resource)
+		throws FileNotFoundException, UnsatisfiedLinkError {
+		InputStream is;
+		try {
+			is = resource.openStream();
+		} catch(IOException e) {
+			f.delete();
+			throw new FileNotFoundException();
+		}
 
-        return false;
-    }
+		try {
+			f.deleteOnExit();
+			FileOutputStream fos = new FileOutputStream(f);
+			byte[] buf = new byte[4096 * 1024];
+			int read;
+			while((read = is.read(buf)) > 0) {
+				fos.write(buf, 0, read);
+			}
+			fos.close();
+			System.load(f.getAbsolutePath());
+			return true;
+		} catch(IOException e) {
+		} catch(UnsatisfiedLinkError ule) {
+			f.delete();
+			// likely to be "noexec" 
+			if(ule.toString().toLowerCase().indexOf("not permitted") == -1)
+				throw ule;
+		} finally {
+			f.delete();
+		}
 
-    private static final String getResourceName(boolean optimized) {
-    	String pname = NativeBigInteger.class.getPackage().getName().replace('.','/');
-    	String pref = getLibraryPrefix();
-    	String middle = getMiddleName(optimized);
-    	String suff = getLibrarySuffix();
-    	if((pref == null) || (middle == null) || (suff == null))
-    		return null;
-    	return pname+ '/' +pref+middle+ '.' +suff;
-    }
-    
-    private static final String getMiddleName(boolean optimized){
-    	
-    	String sAppend;
-    	if(optimized)
-    	{
-    		if(sCPUType == null)
-    			return null;
-    		else
-    			sAppend = '-' +sCPUType;
-    	}else
-       		sAppend = "-none";
+		return false;
+	}
 
-    	boolean isWindows =(System.getProperty("os.name").toLowerCase().indexOf("windows") != -1);
-    	boolean isLinux =(System.getProperty("os.name").toLowerCase().indexOf("linux") != -1);
-    	boolean isFreebsd =(System.getProperty("os.name").toLowerCase().indexOf("freebsd") != -1);
-    	boolean isMacOS =(System.getProperty("os.name").toLowerCase().indexOf("mac os x") != -1);
-    	if(isWindows)
-		 	return "jbigi-windows"+sAppend; // The convention on Windows
+	/**
+	 * <p>Check all of the jars in the classpath for the file specified by the 
+	 * environmental property "jbigi.impl" and load it as the native library 
+	 * implementation.  For instance, a windows user on a p4 would define
+	 * -Djbigi.impl=win-686 if there is a jbigi.jar in the classpath containing the 
+	 * files "win-686", "win-athlon", "freebsd-p4", "linux-p3", where each 
+	 * of those files contain the correct binary file for a native library (e.g.
+	 * windows DLL, or a *nix .so).  </p>
+	 * 
+	 * <p>This is a pretty ugly hack, using the general technique illustrated by the
+	 * onion FEC libraries.  It works by pulling the resource, writing out the 
+	 * byte stream to a temporary file, loading the native library from that file,
+	 * then deleting the file.</p>
+	 *
+	 * @return true if it was loaded successfully, else false
+	 *
+	 */
+	private static final boolean loadFromResource(boolean optimized) {
+		String resourceName = getResourceName(optimized);
+		if(resourceName == null)
+			return false;
+		URL resource = NativeBigInteger.class.getClassLoader().getResource(resourceName);
+		if(resource == null) {
+			if(_doLog)
+				System.err.println("NOTICE: Resource name [" + getResourceName(true) + "] was not found");
+			return false;
+		}
+
+		try {
+			try {
+				if(tryLoadResource(File.createTempFile("jbigi", "lib.tmp"), resource))
+					return true;
+			} catch(IOException e) {
+			}
+			Logger.error(NativeBigInteger.class, "Can't load from " + System.getProperty("java.io.tmpdir"));
+			System.err.println("Can't load from " + System.getProperty("java.io.tmpdir"));
+			if(tryLoadResource(new File("jbigi-lib.tmp"), resource))
+				return true;
+		} catch(Exception fnf) {
+			Logger.error(NativeBigInteger.class, "Error reading jbigi resource");
+			System.err.println("Error reading jbigi resource");
+		} catch(UnsatisfiedLinkError ule) {
+			Logger.error(NativeBigInteger.class, "Library " + resourceName + " is not appropriate for this system.");
+			System.err.println("Library " + resourceName + " is not appropriate for this system.");
+		}
+
+		return false;
+	}
+
+	private static final String getResourceName(boolean optimized) {
+		String pname = NativeBigInteger.class.getPackage().getName().replace('.', '/');
+		String pref = getLibraryPrefix();
+		String middle = getMiddleName(optimized);
+		String suff = getLibrarySuffix();
+		if((pref == null) || (middle == null) || (suff == null))
+			return null;
+		return pname + '/' + pref + middle + '.' + suff;
+	}
+
+	private static final String getMiddleName(boolean optimized) {
+
+		String sAppend;
+		if(optimized)
+			if(sCPUType == null)
+				return null;
+			else
+				sAppend = '-' + sCPUType;
+		else
+			sAppend = "-none";
+
+		boolean isWindows = (System.getProperty("os.name").toLowerCase().indexOf("windows") != -1);
+		boolean isLinux = (System.getProperty("os.name").toLowerCase().indexOf("linux") != -1);
+		boolean isFreebsd = (System.getProperty("os.name").toLowerCase().indexOf("freebsd") != -1);
+		boolean isMacOS = (System.getProperty("os.name").toLowerCase().indexOf("mac os x") != -1);
+		if(isWindows)
+			return "jbigi-windows" + sAppend; // The convention on Windows
 		if(isLinux)
-			return "jbigi-linux"+sAppend; // The convention on linux...
+			return "jbigi-linux" + sAppend; // The convention on linux...
 		if(isFreebsd)
-			return "jbigi-freebsd"+sAppend; // The convention on freebsd...
+			return "jbigi-freebsd" + sAppend; // The convention on freebsd...
 		if(isMacOS)
-			return "jbigi-osx"+sAppend; // The convention on Mac OS X...
-		throw new RuntimeException("Dont know jbigi library name for os type '"+System.getProperty("os.name")+ '\'');
-    }
-    private static final String getLibrarySuffix()
-    {
-    	boolean isWindows =System.getProperty("os.name").toLowerCase().indexOf("windows") != -1;
-    	boolean isMacOS =(System.getProperty("os.name").toLowerCase().indexOf("mac os x") != -1);
-    	if(isWindows)
-    		return "dll";
-    	else if(isMacOS)
-    		return "jnilib";
-	else
-    		return "so";
-    }
-    private static final String getLibraryPrefix()
-    {
-    	boolean isWindows =System.getProperty("os.name").toLowerCase().indexOf("windows") != -1;
-    	if(isWindows)
-    		return "";
+			return "jbigi-osx" + sAppend; // The convention on Mac OS X...
+		throw new RuntimeException("Dont know jbigi library name for os type '" + System.getProperty("os.name") + '\'');
+	}
+
+	private static final String getLibrarySuffix() {
+		boolean isWindows = System.getProperty("os.name").toLowerCase().indexOf("windows") != -1;
+		boolean isMacOS = (System.getProperty("os.name").toLowerCase().indexOf("mac os x") != -1);
+		if(isWindows)
+			return "dll";
+		else if(isMacOS)
+			return "jnilib";
 		else
-    		return "lib";
-    }
+			return "so";
+	}
+
+	private static final String getLibraryPrefix() {
+		boolean isWindows = System.getProperty("os.name").toLowerCase().indexOf("windows") != -1;
+		if(isWindows)
+			return "";
+		else
+			return "lib";
+	}
 }




More information about the cvs mailing list