diff --git a/src/com/yahoo/ycsb/BasicDB.java b/src/com/yahoo/ycsb/BasicDB.java index 3b4adf63c4712c5704226990563676428d514490..9490451eff7e3be3d22ad30cbb1392d0712d8d6d 100644 --- a/src/com/yahoo/ycsb/BasicDB.java +++ b/src/com/yahoo/ycsb/BasicDB.java @@ -21,7 +21,6 @@ import java.util.HashMap; import java.util.Properties; import java.util.Set; import java.util.Enumeration; -import java.util.Random; import java.util.Vector; @@ -37,13 +36,11 @@ public class BasicDB extends DB public static final String SIMULATE_DELAY_DEFAULT="0"; - Random random; boolean verbose; int todelay; public BasicDB() { - random=new Random(); todelay=0; } @@ -54,7 +51,7 @@ public class BasicDB extends DB { try { - Thread.sleep((long)random.nextInt(todelay)); + Thread.sleep((long)Utils.random().nextInt(todelay)); } catch (InterruptedException e) { diff --git a/src/com/yahoo/ycsb/Client.java b/src/com/yahoo/ycsb/Client.java index 9da86041a6c2c601737b9681fb5e53bca2ed0894..64585f81a02276d04f0ba9142a9d7bf7375889f3 100644 --- a/src/com/yahoo/ycsb/Client.java +++ b/src/com/yahoo/ycsb/Client.java @@ -137,8 +137,6 @@ class StatusThread extends Thread */ class ClientThread extends Thread { - static Random random=new Random(); - DB _db; boolean _dotransactions; Workload _workload; @@ -215,7 +213,7 @@ class ClientThread extends Thread //and the sleep() doesn't make sense for granularities < 1 ms anyway if ( (_target>0) && (_target<=1.0) ) { - sleep(random.nextInt((int)(1.0/_target))); + sleep(Utils.random().nextInt((int)(1.0/_target))); } } catch (InterruptedException e) diff --git a/src/com/yahoo/ycsb/RandomByteIterator.java b/src/com/yahoo/ycsb/RandomByteIterator.java index 3e6cba18f95a336ea37364d5ff0f6820d040a7a2..99239f859fb8011e663af50acaa985b09a6d0586 100644 --- a/src/com/yahoo/ycsb/RandomByteIterator.java +++ b/src/com/yahoo/ycsb/RandomByteIterator.java @@ -16,10 +16,7 @@ */ package com.yahoo.ycsb; -import java.util.Random; - public class RandomByteIterator extends ByteIterator { - static Random random=new Random(); long len; long off; int buf_off; @@ -31,7 +28,7 @@ public class RandomByteIterator extends ByteIterator { } private void fillBytesImpl(byte[] buf, int base) { - int bytes = random.nextInt(); + int bytes = Utils.random().nextInt(); try { buf[base+0] = (byte)(((bytes ) & 31) + ' '); buf[base+1] = (byte)(((bytes >> 5 ) & 31) + ' '); diff --git a/src/com/yahoo/ycsb/Utils.java b/src/com/yahoo/ycsb/Utils.java index 57dd141a066bd0145d1f2f617d4c9045e71ec36a..f49bc0f5c03cd1b3cd7993d9d97ba619cc5cde37 100644 --- a/src/com/yahoo/ycsb/Utils.java +++ b/src/com/yahoo/ycsb/Utils.java @@ -24,8 +24,17 @@ import java.util.Random; */ public class Utils { - static Random random=new Random(); - + private static final Random rand = new Random(); + private static final ThreadLocal<Random> rng = new ThreadLocal<Random>(); + + public static Random random() { + Random ret = rng.get(); + if(ret == null) { + ret = new Random(rand.nextLong()); + rng.set(ret); + } + return ret; + } /** * Generate a random ASCII string of a given length. */ @@ -34,7 +43,7 @@ public class Utils int interval='~'-' '+1; byte []buf = new byte[length]; - random.nextBytes(buf); + random().nextBytes(buf); for (int i = 0; i < length; i++) { if (buf[i] < 0) { buf[i] = (byte)((-buf[i] % interval) + ' '); diff --git a/src/com/yahoo/ycsb/generator/CounterGenerator.java b/src/com/yahoo/ycsb/generator/CounterGenerator.java index 11db1cf1307404ee87f9caf1e03e6d56af41aa37..df37b2398c5f0f46e886d7df7367398f68d86b90 100644 --- a/src/com/yahoo/ycsb/generator/CounterGenerator.java +++ b/src/com/yahoo/ycsb/generator/CounterGenerator.java @@ -17,34 +17,39 @@ package com.yahoo.ycsb.generator; +import java.util.concurrent.atomic.AtomicInteger; + /** * Generates a sequence of integers 0, 1, ... */ public class CounterGenerator extends IntegerGenerator { - int counter; + final AtomicInteger counter; /** * Create a counter that starts at countstart */ public CounterGenerator(int countstart) { - counter=countstart; - setLastInt(countstart-1); + counter=new AtomicInteger(countstart); + setLastInt(counter.get()-1); } /** * If the generator returns numeric (integer) values, return the next value as an int. Default is to return -1, which * is appropriate for generators that do not return numeric values. */ - public synchronized int nextInt() + public int nextInt() { - int lastint=counter; - counter++; - setLastInt(lastint); - return lastint; + int ret = counter.getAndIncrement(); + setLastInt(ret); + return ret; + } + @Override + public int lastInt() + { + return counter.get() - 1; } - @Override public double mean() { throw new UnsupportedOperationException("Can't compute mean of non-stationary distribution!"); diff --git a/src/com/yahoo/ycsb/generator/DiscreteGenerator.java b/src/com/yahoo/ycsb/generator/DiscreteGenerator.java index 087312c03519bbc50ef69f04f63288125c3c0b97..c28f3ae771e1bbe667902e925bf0a16f0bdf8fe3 100644 --- a/src/com/yahoo/ycsb/generator/DiscreteGenerator.java +++ b/src/com/yahoo/ycsb/generator/DiscreteGenerator.java @@ -20,6 +20,7 @@ package com.yahoo.ycsb.generator; import java.util.Vector; import java.util.Random; +import com.yahoo.ycsb.Utils; import com.yahoo.ycsb.WorkloadException; /** @@ -40,13 +41,11 @@ public class DiscreteGenerator extends Generator } Vector<Pair> _values; - Random _random; String _lastvalue; public DiscreteGenerator() { _values=new Vector<Pair>(); - _random=new Random(); _lastvalue=null; } @@ -62,7 +61,7 @@ public class DiscreteGenerator extends Generator sum+=p._weight; } - double val=_random.nextDouble(); + double val=Utils.random().nextDouble(); for (Pair p : _values) { diff --git a/src/com/yahoo/ycsb/generator/ExponentialGenerator.java b/src/com/yahoo/ycsb/generator/ExponentialGenerator.java index 7a9187e1083783236b3c83c475873c8e046a4699..de1a2760c4b02b308666dbc7ceaefb9cc8805cfd 100644 --- a/src/com/yahoo/ycsb/generator/ExponentialGenerator.java +++ b/src/com/yahoo/ycsb/generator/ExponentialGenerator.java @@ -19,6 +19,8 @@ package com.yahoo.ycsb.generator; import java.util.Random; +import com.yahoo.ycsb.Utils; + /** * A generator of an exponential distribution. It produces a sequence * of time intervals (integers) according to an exponential @@ -43,8 +45,6 @@ public class ExponentialGenerator extends IntegerGenerator */ double _gamma; - Random _random; - /******************************* Constructors **************************************/ /** @@ -54,12 +54,10 @@ public class ExponentialGenerator extends IntegerGenerator public ExponentialGenerator(double mean) { _gamma = 1.0/mean; - _random = new Random(); } public ExponentialGenerator(double percentile, double range) { _gamma = -Math.log(1.0-percentile/100.0) / range; //1.0/mean; - _random = new Random(); } /****************************************************************************************/ @@ -84,7 +82,7 @@ public class ExponentialGenerator extends IntegerGenerator */ public long nextLong() { - return (long) (-Math.log(_random.nextDouble()) / _gamma); + return (long) (-Math.log(Utils.random().nextDouble()) / _gamma); } @Override diff --git a/src/com/yahoo/ycsb/generator/HistogramGenerator.java b/src/com/yahoo/ycsb/generator/HistogramGenerator.java index baaf358851d14caf7d1d6f3e5f20fe3c1ea84496..aba42c47b0c060a92b667c7d6808f3b608c37dac 100644 --- a/src/com/yahoo/ycsb/generator/HistogramGenerator.java +++ b/src/com/yahoo/ycsb/generator/HistogramGenerator.java @@ -20,6 +20,8 @@ import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; import java.util.Random; + +import com.yahoo.ycsb.Utils; import com.yahoo.ycsb.generator.IntegerGenerator; /** @@ -41,7 +43,6 @@ public class HistogramGenerator extends IntegerGenerator { long block_size; long[] buckets; long area; - Random rand = new Random(); long weighted_area = 0; double mean_size = 0; @@ -93,7 +94,7 @@ public class HistogramGenerator extends IntegerGenerator { @Override public int nextInt() { - int number = rand.nextInt((int)area); + int number = Utils.random().nextInt((int)area); int i; for(i = 0; i < (buckets.length - 1); i++){ diff --git a/src/com/yahoo/ycsb/generator/HotspotIntegerGenerator.java b/src/com/yahoo/ycsb/generator/HotspotIntegerGenerator.java index 2ede01b9ebad58a560074942a30c10b18b4562cf..969ae7706d781b48e50f2289db602eb666a761d9 100644 --- a/src/com/yahoo/ycsb/generator/HotspotIntegerGenerator.java +++ b/src/com/yahoo/ycsb/generator/HotspotIntegerGenerator.java @@ -18,6 +18,8 @@ package com.yahoo.ycsb.generator; import java.util.Random; +import com.yahoo.ycsb.Utils; + /** * Generate integers resembling a hotspot distribution where x% of operations * access y% of data items. The parameters specify the bounds for the numbers, @@ -37,7 +39,6 @@ public class HotspotIntegerGenerator extends IntegerGenerator { private final int coldInterval; private final double hotsetFraction; private final double hotOpnFraction; - private final Random random; /** * Create a generator for Hotspot distributions. @@ -71,12 +72,12 @@ public class HotspotIntegerGenerator extends IntegerGenerator { this.hotInterval = (int)(interval * hotsetFraction); this.coldInterval = interval - hotInterval; this.hotOpnFraction = hotOpnFraction; - random = new Random(); } @Override public int nextInt() { int value = 0; + Random random = Utils.random(); if (random.nextDouble() < hotOpnFraction) { // Choose a value from the hot set. value = lowerBound + random.nextInt(hotInterval); diff --git a/src/com/yahoo/ycsb/generator/IntegerGenerator.java b/src/com/yahoo/ycsb/generator/IntegerGenerator.java index a49d9b4765729aa83200a55420d205d7383845bb..13d36cd1f1f423e7cd97b36789e2e02152d1ef09 100644 --- a/src/com/yahoo/ycsb/generator/IntegerGenerator.java +++ b/src/com/yahoo/ycsb/generator/IntegerGenerator.java @@ -31,7 +31,7 @@ public abstract class IntegerGenerator extends Generator * Set the last value generated. IntegerGenerator subclasses must use this call * to properly set the last string value, or the lastString() and lastInt() calls won't work. */ - public void setLastInt(int last) + protected void setLastInt(int last) { lastint=last; } @@ -54,9 +54,10 @@ public abstract class IntegerGenerator extends Generator * Calling lastString() should not advance the distribution or have any side effects. If nextString() has not yet * been called, lastString() should return something reasonable. */ + @Override public String lastString() { - return ""+lastint; + return ""+lastInt(); } /** diff --git a/src/com/yahoo/ycsb/generator/SkewedLatestGenerator.java b/src/com/yahoo/ycsb/generator/SkewedLatestGenerator.java index 6d07c5fc9e129ef204ec757fdbc211718382612b..376eb7775c6b7cf6c44549728d4a03a4d47916b6 100644 --- a/src/com/yahoo/ycsb/generator/SkewedLatestGenerator.java +++ b/src/com/yahoo/ycsb/generator/SkewedLatestGenerator.java @@ -28,7 +28,7 @@ public class SkewedLatestGenerator extends IntegerGenerator public SkewedLatestGenerator(CounterGenerator basis) { _basis=basis; - _zipfian=new ZipfianGenerator(Integer.parseInt(_basis.lastString())); + _zipfian=new ZipfianGenerator(_basis.lastInt()); nextInt(); } @@ -37,7 +37,7 @@ public class SkewedLatestGenerator extends IntegerGenerator */ public int nextInt() { - int max=Integer.parseInt(_basis.lastString()); + int max=_basis.lastInt(); int nextint=max-_zipfian.nextInt(max); setLastInt(nextint); return nextint; diff --git a/src/com/yahoo/ycsb/generator/UniformIntegerGenerator.java b/src/com/yahoo/ycsb/generator/UniformIntegerGenerator.java index a6ae08a6de87b49c43566c941e30e96a367d9eff..fa6af1316ca3d156653d9b362f1f59debd451a97 100644 --- a/src/com/yahoo/ycsb/generator/UniformIntegerGenerator.java +++ b/src/com/yahoo/ycsb/generator/UniformIntegerGenerator.java @@ -19,12 +19,13 @@ package com.yahoo.ycsb.generator; import java.util.Random; +import com.yahoo.ycsb.Utils; + /** * Generates integers randomly uniform from an interval. */ public class UniformIntegerGenerator extends IntegerGenerator { - Random _random; int _lb,_ub,_interval; /** @@ -35,7 +36,6 @@ public class UniformIntegerGenerator extends IntegerGenerator */ public UniformIntegerGenerator(int lb, int ub) { - _random=new Random(); _lb=lb; _ub=ub; _interval=_ub-_lb+1; @@ -44,7 +44,7 @@ public class UniformIntegerGenerator extends IntegerGenerator @Override public int nextInt() { - int ret=_random.nextInt(_interval)+_lb; + int ret=Utils.random().nextInt(_interval)+_lb; setLastInt(ret); return ret; diff --git a/src/com/yahoo/ycsb/generator/ZipfianGenerator.java b/src/com/yahoo/ycsb/generator/ZipfianGenerator.java index 5a4c0198dedd75cbce17620051990fb19d8d5051..8a70f0869a16c7d2776072c1b6c4ed2e94e38e27 100644 --- a/src/com/yahoo/ycsb/generator/ZipfianGenerator.java +++ b/src/com/yahoo/ycsb/generator/ZipfianGenerator.java @@ -19,6 +19,8 @@ package com.yahoo.ycsb.generator; import java.util.Random; +import com.yahoo.ycsb.Utils; + /** * A generator of a zipfian distribution. It produces a sequence of items, such that some items are more popular than others, according * to a zipfian distribution. When you construct an instance of this class, you specify the number of items in the set to draw from, either @@ -61,8 +63,6 @@ public class ZipfianGenerator extends IntegerGenerator */ double alpha,zetan,eta,theta,zeta2theta; - Random random; - /** * The number of items used to compute zetan the last time. */ @@ -136,8 +136,6 @@ public class ZipfianGenerator extends IntegerGenerator base=min; zipfianconstant=_zipfianconstant; - random=new Random(); - theta=zipfianconstant; zeta2theta=zeta(2,theta); @@ -273,7 +271,7 @@ public class ZipfianGenerator extends IntegerGenerator } } - double u=random.nextDouble(); + double u=Utils.random().nextDouble(); double uz=u*zetan; if (uz<1.0)