Permalink
Browse files

Merge branch 'master' of github.com:sears/YCSB into ImprovedToplevel

With this merge, the performance of ImprovedTopLevel tracks that of master.

Conflicts:
	src/com/yahoo/ycsb/Client.java
	src/com/yahoo/ycsb/Utils.java
  • Loading branch information...
Russell Sears
Russell Sears committed Nov 23, 2011
2 parents 41c2f75 + 2227eeb commit bc5ae537d949e90b2270f901668d62290b51555c
View
@@ -18,6 +18,10 @@
* gh-44 Constant occupancy workload (sears)
* gh-45 Modify DB API for efficient large object support (sears)
* gh-46 Fixed typo in RedisClient (Zlender)
+ * gh-49 Build fix (sears)
+ * gh-50 Switch unordered key generation from FNV32 to FNV64 (sears)
+ * gh-51 Improved Random Number Generation Performance and add Exponential distribution support (sears)
+ * gh-52 Mongo db fix (sears)
0.1.3
* Voldemort binding (rsumbaly)
@@ -148,8 +148,9 @@ public int insert(String table, String key, HashMap<String, ByteIterator> values
DBCollection collection = db.getCollection(table);
DBObject r = new BasicDBObject().append("_id", key);
- r.putAll(values);
-
+ for(String k: values.keySet()) {
+ r.put(k, values.get(k).toString());
+ }
collection.setWriteConcern(writeConcern);
collection.insert(r);
@@ -21,7 +21,6 @@
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 static final String SIMULATE_DELAY_DEFAULT="0";
- Random random;
boolean verbose;
int todelay;
public BasicDB()
{
- random=new Random();
todelay=0;
}
@@ -54,7 +51,7 @@ void delay()
{
try
{
- Thread.sleep((long)random.nextInt(todelay));
+ Thread.sleep((long)Utils.random().nextInt(todelay));
}
catch (InterruptedException e)
{
@@ -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 boolean hasNext() {
}
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) + ' ');
@@ -26,7 +26,16 @@
*/
public class Utils
{
- static Random random=new Random();
+ private static 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;
+ }
private static String stars(int n) {
StringBuffer ret = new StringBuffer();
@@ -57,7 +66,7 @@ public static String ASCIIString(int length)
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) + ' ');
@@ -5,7 +5,6 @@
import java.io.PrintWriter;
import java.text.DecimalFormat;
import java.util.Properties;
-import java.util.Random;
import java.util.Vector;
import com.yahoo.ycsb.measurements.Measurements;
@@ -118,8 +117,6 @@ public void run() {
*
*/
class ClientThread extends Thread {
- static Random random = new Random();
-
DB _db;
boolean _dotransactions;
Workload _workload;
@@ -198,7 +195,7 @@ public void run() {
// 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) {
// do nothing.
@@ -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!");
@@ -20,6 +20,7 @@
import java.util.Vector;
import java.util.Random;
+import com.yahoo.ycsb.Utils;
import com.yahoo.ycsb.WorkloadException;
/**
@@ -40,13 +41,11 @@
}
Vector<Pair> _values;
- Random _random;
String _lastvalue;
public DiscreteGenerator()
{
_values=new Vector<Pair>();
- _random=new Random();
_lastvalue=null;
}
@@ -62,7 +61,7 @@ public String nextString()
sum+=p._weight;
}
- double val=_random.nextDouble();
+ double val=Utils.random().nextDouble();
for (Pair p : _values)
{
@@ -0,0 +1,102 @@
+/**
+ * Copyright (c) 2011 Yahoo! Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you
+ * may not use this file except in compliance with the License. You
+ * may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * permissions and limitations under the License. See accompanying
+ * LICENSE file.
+ */
+
+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
+ * distribution. Smaller intervals are more frequent than larger
+ * ones, and there is no bound on the length of an interval. When you
+ * construct an instance of this class, you specify a parameter gamma,
+ * which corresponds to the rate at which events occur.
+ * Alternatively, 1/gamma is the average length of an interval.
+ */
+public class ExponentialGenerator extends IntegerGenerator
+{
+ // What percentage of the readings should be within the most recent exponential.frac portion of the dataset?
+ public static final String EXPONENTIAL_PERCENTILE_PROPERTY="exponential.percentile";
+ public static final String EXPONENTIAL_PERCENTILE_DEFAULT="95";
+
+ // What fraction of the dataset should be accessed exponential.percentile of the time?
+ public static final String EXPONENTIAL_FRAC_PROPERTY = "exponential.frac";
+ public static final String EXPONENTIAL_FRAC_DEFAULT = "0.8571428571"; // 1/7
+
+ /**
+ * The exponential constant to use.
+ */
+ double _gamma;
+
+ /******************************* Constructors **************************************/
+
+ /**
+ * Create an exponential generator with a mean arrival rate of
+ * gamma. (And half life of 1/gamma).
+ */
+ public ExponentialGenerator(double mean)
+ {
+ _gamma = 1.0/mean;
+ }
+ public ExponentialGenerator(double percentile, double range)
+ {
+ _gamma = -Math.log(1.0-percentile/100.0) / range; //1.0/mean;
+ }
+
+ /****************************************************************************************/
+
+ /**
+ * Generate the next item. this distribution will be skewed toward lower integers; e.g. 0 will
+ * be the most popular, 1 the next most popular, etc.
+ * @param itemcount The number of items in the distribution.
+ * @return The next item in the sequence.
+ */
+ @Override
+ public int nextInt()
+ {
+ return (int)nextLong();
+ }
+
+ /**
+ * Generate the next item as a long.
+ *
+ * @param itemcount The number of items in the distribution.
+ * @return The next item in the sequence.
+ */
+ public long nextLong()
+ {
+ return (long) (-Math.log(Utils.random().nextDouble()) / _gamma);
+ }
+
+ @Override
+ public double mean() {
+ return 1.0/_gamma;
+ }
+ public static void main(String args[]) {
+ ExponentialGenerator e = new ExponentialGenerator(90, 100);
+ int j = 0;
+ for(int i = 0; i < 1000; i++) {
+ if(e.nextInt() < 100) {
+ j++;
+ }
+ }
+ System.out.println("Got " + j + " hits. Expect 900");
+ }
+}
@@ -20,6 +20,8 @@
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 @@
long block_size;
long[] buckets;
long area;
- Random rand = new Random();
long weighted_area = 0;
double mean_size = 0;
@@ -93,7 +94,7 @@ private void init() {
@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++){
@@ -18,6 +18,8 @@
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 @@
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 HotspotIntegerGenerator(int lowerBound, int upperBound,
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);
@@ -31,7 +31,7 @@
* 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 String nextString()
* 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();
}
/**
Oops, something went wrong.

0 comments on commit bc5ae53

Please sign in to comment.