Skip to content

Commit

Permalink
Merge pull request #551 from vfunshteyn/master
Browse files Browse the repository at this point in the history
[core] Generator refactoring
  • Loading branch information
busbey committed Feb 3, 2016
2 parents 779a703 + 0a33074 commit 1363f83
Show file tree
Hide file tree
Showing 20 changed files with 234 additions and 319 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public AcknowledgedCounterGenerator(int countstart)
* (as opposed to the highest generated counter value).
*/
@Override
public int lastInt()
public Integer lastValue()
{
return limit;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
* @author sears
*
*/
public class ConstantIntegerGenerator extends IntegerGenerator {
public class ConstantIntegerGenerator extends NumberGenerator {
private final int i;
/**
* @param i The integer that this generator will always return.
Expand All @@ -32,7 +32,7 @@ public ConstantIntegerGenerator(int i) {
}

@Override
public int nextInt() {
public Integer nextValue() {
return i;
}

Expand Down
21 changes: 8 additions & 13 deletions core/src/main/java/com/yahoo/ycsb/generator/CounterGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,33 +22,28 @@
/**
* Generates a sequence of integers 0, 1, ...
*/
public class CounterGenerator extends IntegerGenerator
public class CounterGenerator extends NumberGenerator
{
final AtomicInteger counter;
private final AtomicInteger counter;

/**
* Create a counter that starts at countstart
*/
public CounterGenerator(int countstart)
{
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 int nextInt()
@Override
public Integer nextValue()
{
int ret = counter.getAndIncrement();
setLastInt(ret);
return ret;
return counter.getAndIncrement();
}

@Override
public int lastInt()
public Integer lastValue()
{
return counter.get() - 1;
return counter.get() - 1;
}
@Override
public double mean() {
Expand Down
51 changes: 19 additions & 32 deletions core/src/main/java/com/yahoo/ycsb/generator/DiscreteGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,42 +17,42 @@

package com.yahoo.ycsb.generator;

import java.util.Vector;
import java.util.Random;
import java.util.ArrayList;
import java.util.Collection;
import static java.util.Objects.requireNonNull;

import com.yahoo.ycsb.Utils;
import com.yahoo.ycsb.WorkloadException;

/**
* Generates a distribution by choosing from a discrete set of values.
*/
public class DiscreteGenerator extends Generator
public class DiscreteGenerator extends Generator<String>
{
class Pair
private static class Pair
{
public double _weight;
public String _value;
private double _weight;
private String _value;

Pair(double weight, String value)
{
_weight=weight;
_value=value;
_value = requireNonNull(value);
}
}

Vector<Pair> _values;
String _lastvalue;
private final Collection<Pair> _values = new ArrayList<>();
private String _lastvalue;

public DiscreteGenerator()
{
_values=new Vector<Pair>();
_lastvalue=null;
}

/**
* Generate the next string in the distribution.
*/
public String nextString()
@Override
public String nextValue()
{
double sum=0;

Expand All @@ -65,43 +65,30 @@ public String nextString()

for (Pair p : _values)
{
if (val<p._weight/sum)
double pw = p._weight / sum;
if (val < pw)
{
return p._value;
}

val-=p._weight/sum;
val -= pw;
}

//should never get here.
System.out.println("oops. should not get here.");
throw new AssertionError("oops. should not get here.");

System.exit(0);

return null;
}

/**
* 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.
*
* @throws WorkloadException if this generator does not support integer values
*/
public int nextInt() throws WorkloadException
{
throw new WorkloadException("DiscreteGenerator does not support nextInt()");
}

/**
* Return the previous string generated by the distribution; e.g., returned from the last nextString() call.
* Calling lastString() should not advance the distribution or have any side effects. If nextString() has not yet
* been called, lastString() should return something reasonable.
*/
public String lastString()
@Override
public String lastValue()
{
if (_lastvalue==null)
{
_lastvalue=nextString();
_lastvalue=nextValue();
}
return _lastvalue;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,18 @@

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
* of time intervals 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
public class ExponentialGenerator extends NumberGenerator
{
// 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";
Expand All @@ -43,7 +41,7 @@ public class ExponentialGenerator extends IntegerGenerator
/**
* The exponential constant to use.
*/
double _gamma;
private double _gamma;

/******************************* Constructors **************************************/

Expand All @@ -62,27 +60,16 @@ public ExponentialGenerator(double percentile, double range)

/****************************************************************************************/

/**
* 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()
* Generate the next item as a long. This distribution will be skewed toward lower values; e.g. 0 will
* be the most popular, 1 the next most popular, etc.
* @return The next item in the sequence.
*/
@Override
public Double nextValue()
{
return (long) (-Math.log(Utils.random().nextDouble()) / _gamma);
return -Math.log(Utils.random().nextDouble()) / _gamma;
}

@Override
Expand All @@ -93,7 +80,7 @@ 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) {
if(e.nextValue() < 100) {
j++;
}
}
Expand Down
53 changes: 20 additions & 33 deletions core/src/main/java/com/yahoo/ycsb/generator/FileGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,74 +15,61 @@

package com.yahoo.ycsb.generator;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.FileReader;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;

/**
* A generator, whose sequence is the lines of a file.
*/
public class FileGenerator extends Generator
public class FileGenerator extends Generator<String>
{
String filename;
String current;
BufferedReader reader;
private final String filename;
private String current;
private BufferedReader reader;

/**
* Create a FileGenerator with the given file.
* @param _filename The file to read lines from.
*/
public FileGenerator(String _filename)
public FileGenerator(String _filename)
{
try {
filename = _filename;
File file = new File(filename);
FileInputStream in = new FileInputStream(file);
reader = new BufferedReader(new InputStreamReader(in));
} catch(IOException e) {
System.err.println("Exception: " + e);
}
filename = _filename;
reloadFile();
}

/**
* Return the next string of the sequence, ie the next line of the file.
*/
public synchronized String nextString()
@Override
public synchronized String nextValue()
{
try {
return current = reader.readLine();
} catch(NullPointerException e) {
System.err.println("NullPointerException: " + filename + ':' + current);
throw e;
} catch(IOException e) {
System.err.println("Exception: " + e);
return null;
throw new RuntimeException(e);
}
}

/**
* Return the previous read line.
*/
public String lastString()
@Override
public String lastValue()
{
return current;
}

/**
* Reopen the file to reuse values.
*/
public synchronized void reloadFile()
{
try {
public synchronized void reloadFile() {
try (Reader r = reader) {
System.err.println("Reload " + filename);
reader.close();
File file = new File(filename);
FileInputStream in = new FileInputStream(file);
reader = new BufferedReader(new InputStreamReader(in));
} catch(IOException e) {
System.err.println("Exception: " + e);
}
reader = new BufferedReader(new FileReader(filename));
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
26 changes: 18 additions & 8 deletions core/src/main/java/com/yahoo/ycsb/generator/Generator.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,30 @@
package com.yahoo.ycsb.generator;

/**
* An expression that generates a sequence of string values, following some distribution (Uniform, Zipfian, Sequential, etc.)
* An expression that generates a sequence of values, following some distribution (Uniform, Zipfian, Sequential, etc.)
*/
public abstract class Generator
public abstract class Generator<V>
{
/**
* Generate the next string in the distribution.
* Generate the next value in the distribution.
*/
public abstract String nextString();
public abstract V nextValue();

/**
* Return the previous string generated by the distribution; e.g., returned from the last nextString() call.
* Calling lastString() should not advance the distribution or have any side effects. If nextString() has not yet
* been called, lastString() should return something reasonable.
* Return the previous value generated by the distribution; e.g., returned from the last {@link Generator#nextValue()} call.
* Calling {@link #lastValue()} should not advance the distribution or have any side effects. If {@link #nextValue()} has not yet
* been called, {@link #lastValue()} should return something reasonable.
*/
public abstract String lastString();
public abstract V lastValue();

public final String nextString() {
V ret = nextValue();
return ret == null ? null : ret.toString();
}

public final String lastString() {
V ret = lastValue();
return ret == null ? null : ret.toString();
}
}

Loading

0 comments on commit 1363f83

Please sign in to comment.