ITBLL: use a faster PRNG

The SecureRandom PRNG is very very slow. Since we don't need
cryptographic random numbers, we can use a simpler random. This switches
to Xoroshiro128+, which is much faster but still has a long period
(2^128) necessary to avoid collisions.

The implementation is from Squidlib[1] which is Apache licensed. The
file itself has a license header indicating it is public domain. The
original C implementation is also in the public domain[2]. Given that, I
didn't reference this in LICENSE.txt or NOTICE.

It's copy-pasted rather than introduced as a dependency because SquidLib
is a library for writing turn-based games in Swing -- it just happens to
have a good RNG in it.

[1] 
https://github.com/SquidPony/SquidLib/blob/master/squidlib-util/src/main/java/squidpony/squidmath/XoRoRNG.java
    at revision b4fb31efe527d3298b8f37f3cc72e957579ad6e3
[2] http://xoroshiro.di.unimi.it/xoroshiro128plus.c

Change-Id: I2f51664af25b9fb4309dd78556e954bf483d22c0
Reviewed-on: http://gerrit.cloudera.org:8080/4731
Tested-by: Kudu Jenkins
Reviewed-by: Jean-Daniel Cryans <jdcry...@apache.org>


Project: http://git-wip-us.apache.org/repos/asf/kudu/repo
Commit: http://git-wip-us.apache.org/repos/asf/kudu/commit/0c44223e
Tree: http://git-wip-us.apache.org/repos/asf/kudu/tree/0c44223e
Diff: http://git-wip-us.apache.org/repos/asf/kudu/diff/0c44223e

Branch: refs/heads/master
Commit: 0c44223ea9e8561d9c48299007094f6f0d3f495f
Parents: e5b7ebf
Author: Todd Lipcon <t...@apache.org>
Authored: Thu Oct 13 22:24:51 2016 -0700
Committer: Todd Lipcon <t...@apache.org>
Committed: Mon Oct 17 17:13:25 2016 +0000

----------------------------------------------------------------------
 .../tools/IntegrationTestBigLinkedList.java     | 47 +++++++++++++++++++-
 1 file changed, 45 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/kudu/blob/0c44223e/java/kudu-client-tools/src/main/java/org/apache/kudu/mapreduce/tools/IntegrationTestBigLinkedList.java
----------------------------------------------------------------------
diff --git 
a/java/kudu-client-tools/src/main/java/org/apache/kudu/mapreduce/tools/IntegrationTestBigLinkedList.java
 
b/java/kudu-client-tools/src/main/java/org/apache/kudu/mapreduce/tools/IntegrationTestBigLinkedList.java
index 7a2d6ac..5a0c0ea 100644
--- 
a/java/kudu-client-tools/src/main/java/org/apache/kudu/mapreduce/tools/IntegrationTestBigLinkedList.java
+++ 
b/java/kudu-client-tools/src/main/java/org/apache/kudu/mapreduce/tools/IntegrationTestBigLinkedList.java
@@ -304,6 +304,49 @@ public class IntegrationTestBigLinkedList extends 
Configured implements Tool {
   }
 
   /**
+   * Implementation of the Xoroshiro128+ PRNG.
+   * Copied under the public domain from SquidLib.
+   */
+  private static class Xoroshiro128PlusRandom {
+    private long state0, state1;
+    public Xoroshiro128PlusRandom() {
+      this((long) (Math.random() * Long.MAX_VALUE));
+    }
+    public Xoroshiro128PlusRandom(long seed) {
+      long state = seed + 0x9E3779B97F4A7C15L,
+           z = state;
+      z = (z ^ (z >>> 30)) * 0xBF58476D1CE4E5B9L;
+      z = (z ^ (z >>> 27)) * 0x94D049BB133111EBL;
+      state0 = z ^ (z >>> 31);
+      state += state0 + 0x9E3779B97F4A7C15L;
+      z = state;
+      z = (z ^ (z >>> 30)) * 0xBF58476D1CE4E5B9L;
+      z = (z ^ (z >>> 27)) * 0x94D049BB133111EBL;
+      state1 = z ^ (z >>> 31);
+    }
+    public long nextLong() {
+      final long s0 = state0;
+      long s1 = state1;
+      final long result = s0 + s1;
+
+      s1 ^= s0;
+      state0 = Long.rotateLeft(s0, 55) ^ s1 ^ (s1 << 14); // a, b
+      state1 = Long.rotateLeft(s1, 36); // c
+
+      return result;
+    }
+    public void nextBytes(final byte[] bytes) {
+      int i = bytes.length, n = 0;
+      while (i != 0) {
+        n = Math.min(i, 8);
+        for (long bits = nextLong(); n-- != 0; bits >>>= 8) {
+          bytes[--i] = (byte) bits;
+        }
+      }
+    }
+  }
+
+  /**
    * A Map only job that generates random linked list and stores them.
    */
   static class Generator extends Configured implements Tool {
@@ -331,7 +374,7 @@ public class IntegrationTestBigLinkedList extends 
Configured implements Tool {
       static class GeneratorRecordReader extends 
RecordReader<BytesWritable,NullWritable> {
         private long count;
         private long numNodes;
-        private Random rand;
+        private Xoroshiro128PlusRandom rand;
 
         @Override
         public void close() throws IOException {
@@ -359,7 +402,7 @@ public class IntegrationTestBigLinkedList extends 
Configured implements Tool {
             throws IOException, InterruptedException {
           numNodes = 
context.getConfiguration().getLong(GENERATOR_NUM_ROWS_PER_MAP_KEY, 25000000);
           // Use SecureRandom to avoid issue described in HBASE-13382.
-          rand = new SecureRandom();
+          rand = new Xoroshiro128PlusRandom();
         }
 
         @Override

Reply via email to