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";
+ }
}