Skip to content

Commit

Permalink
This is an attempt to optimize our YCSB implementation. We now have a…
Browse files Browse the repository at this point in the history
… faster random string generator where we don't have to allocate the char array each time. We also don't have to create HashMap to store results anymore. I haven't tested this for real on a DBMS but it passes the tests.
  • Loading branch information
apavlo committed Oct 28, 2016
1 parent f98d761 commit 53b5529
Show file tree
Hide file tree
Showing 9 changed files with 87 additions and 65 deletions.
2 changes: 2 additions & 0 deletions src/com/oltpbenchmark/benchmarks/ycsb/YCSBConstants.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ public abstract class YCSBConstants {

public static final int NUN_FIELDS = 10;

public static final int FIELD_SIZE = 100; // chars

public static final int configCommitCount = 100;

static final int MAX_SCAN=1000;
Expand Down
46 changes: 23 additions & 23 deletions src/com/oltpbenchmark/benchmarks/ycsb/YCSBWorker.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

import com.oltpbenchmark.api.BenchmarkModule;
import com.oltpbenchmark.api.Procedure;
Expand All @@ -37,13 +37,21 @@
import com.oltpbenchmark.types.TransactionStatus;
import com.oltpbenchmark.util.TextGenerator;

/**
* YCSBWorker Implementation
* I forget who really wrote this but I fixed it up in 2016...
* @author pavlo
*
*/
public class YCSBWorker extends Worker {

private ZipfianGenerator readRecord;
private static CounterGenerator insertRecord;
private ZipfianGenerator randScan;

private final Map<Integer, String> m = new HashMap<Integer, String>();
private final char data[] = new char[YCSBConstants.FIELD_SIZE];
private final String params[] = new String[YCSBConstants.NUN_FIELDS];
private final String results[] = new String[YCSBConstants.NUN_FIELDS];

public YCSBWorker(int id, BenchmarkModule benchmarkModule, int init_record_count) {
super(benchmarkModule, id);
Expand Down Expand Up @@ -83,46 +91,39 @@ private void updateRecord() throws SQLException {
UpdateRecord proc = this.getProcedure(UpdateRecord.class);
assert (proc != null);
int keyname = readRecord.nextInt();
Map<Integer, String> values = buildValues(10);
proc.run(conn, keyname, values);
this.buildParameters();
proc.run(conn, keyname, this.params);
}

private void scanRecord() throws SQLException {
ScanRecord proc = this.getProcedure(ScanRecord.class);
assert (proc != null);
int keyname = readRecord.nextInt();
int count = randScan.nextInt();
proc.run(conn, keyname, count, new ArrayList<Map<Integer, String>>());
proc.run(conn, keyname, count, new ArrayList<String[]>());
}

private void readRecord() throws SQLException {
ReadRecord proc = this.getProcedure(ReadRecord.class);
assert (proc != null);
int keyname = readRecord.nextInt();
proc.run(conn, keyname, new HashMap<Integer, String>());
proc.run(conn, keyname, this.results);
}

private void readModifyWriteRecord() throws SQLException {
ReadModifyWriteRecord proc = this.getProcedure(ReadModifyWriteRecord.class);
assert (proc != null);
int keyname = readRecord.nextInt();

String fields[] = new String[10];
for (int i = 0; i < fields.length; i++) {
fields[i] = TextGenerator.randomStr(rng(), 100);
} // FOR

this.m.clear();
proc.run(conn, keyname, fields, this.m);
this.buildParameters();
proc.run(conn, keyname, this.params, this.results);
}

private void insertRecord() throws SQLException {
InsertRecord proc = this.getProcedure(InsertRecord.class);
assert (proc != null);
int keyname = insertRecord.nextInt();
// System.out.println("[Thread " + this.id+"] insert this: "+ keyname);
Map<Integer, String> values = buildValues(10);
proc.run(conn, keyname, values);
this.buildParameters();
proc.run(conn, keyname, this.params);
}

private void deleteRecord() throws SQLException {
Expand All @@ -132,11 +133,10 @@ private void deleteRecord() throws SQLException {
proc.run(conn, keyname);
}

private Map<Integer, String> buildValues(int numVals) {
this.m.clear();
for (int i = 1; i <= numVals; i++) {
this.m.put(i, TextGenerator.randomStr(rng(), 100));
}
return this.m;
private void buildParameters() {
Random rng = rng();
for (int i = 0; i < this.params.length; i++) {
this.params[i] = new String(TextGenerator.randomChars(rng, this.data));
} // FOR
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Map;
import java.util.Map.Entry;
import com.oltpbenchmark.api.Procedure;
import com.oltpbenchmark.api.SQLStmt;

Expand All @@ -30,12 +28,11 @@ public class InsertRecord extends Procedure{
);

//FIXME: The value in ysqb is a byteiterator
public void run(Connection conn, int keyname, Map<Integer,String> vals) throws SQLException {
public void run(Connection conn, int keyname, String vals[]) throws SQLException {
PreparedStatement stmt = this.getPreparedStatement(conn, insertStmt);
stmt.setInt(1, keyname);
for(Entry<Integer,String> s:vals.entrySet())
{
stmt.setString(s.getKey()+1, s.getValue());
for (int i = 0; i < vals.length; i++) {
stmt.setString(i+1, vals[i]);
}
stmt.executeUpdate();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,30 +20,34 @@
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Map;

import com.oltpbenchmark.api.Procedure;
import com.oltpbenchmark.api.SQLStmt;
import com.oltpbenchmark.benchmarks.ycsb.YCSBConstants;

public class ReadModifyWriteRecord extends Procedure {
public final SQLStmt selectStmt = new SQLStmt(
"Select * from USERTABLE where YCSB_KEY=? for update"
"SELECT * FROM USERTABLE where YCSB_KEY=? FOR UPDATE"
);
public final SQLStmt updateAllStmt = new SQLStmt(
"UPDATE USERTABLE SET FIELD1=?,FIELD2=?,FIELD3=?,FIELD4=?,FIELD5=?," +
"FIELD6=?,FIELD7=?,FIELD8=?,FIELD9=?,FIELD10=? WHERE YCSB_KEY=?"
);
//FIXME: The value in ysqb is a byteiterator
public void run(Connection conn, int keyname, String fields[], Map<Integer,String> results) throws SQLException {
public void run(Connection conn, int keyname, String fields[], String results[]) throws SQLException {

// Fetch it!
PreparedStatement stmt = this.getPreparedStatement(conn, selectStmt);
stmt.setInt(1, keyname);
ResultSet r = stmt.executeQuery();
while (r.next()) {
for (int i = 1; i < 11; i++)
results.put(i, r.getString(i));
for (int i = 0; i < YCSBConstants.NUN_FIELDS; i++)
results[i] = r.getString(i+1);
}
r.close();
stmt= this.getPreparedStatement(conn, updateAllStmt);

// Update that mofo
stmt = this.getPreparedStatement(conn, updateAllStmt);
stmt.setInt(11, keyname);

for (int i = 0; i < fields.length; i++) {
Expand Down
15 changes: 7 additions & 8 deletions src/com/oltpbenchmark/benchmarks/ycsb/procedures/ReadRecord.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,26 +20,25 @@
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Map;

import com.oltpbenchmark.api.Procedure;
import com.oltpbenchmark.api.SQLStmt;
import com.oltpbenchmark.benchmarks.ycsb.YCSBConstants;

public class ReadRecord extends Procedure{
public final SQLStmt readStmt = new SQLStmt(
"SELECT * FROM USERTABLE WHERE YCSB_KEY=?"
);

//FIXME: The value in ysqb is a byteiterator
public void run(Connection conn, int keyname, Map<Integer,String> results) throws SQLException {
public void run(Connection conn, int keyname, String results[]) throws SQLException {
PreparedStatement stmt = this.getPreparedStatement(conn, readStmt);
stmt.setInt(1, keyname);
ResultSet r=stmt.executeQuery();
while(r.next())
{
for(int i=1;i<11;i++)
results.put(i, r.getString(i));
}
ResultSet r = stmt.executeQuery();
while(r.next()) {
for (int i = 0; i < YCSBConstants.NUN_FIELDS; i++)
results[i] = r.getString(i+1);
} // WHILE
r.close();
}

Expand Down
16 changes: 7 additions & 9 deletions src/com/oltpbenchmark/benchmarks/ycsb/procedures/ScanRecord.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,30 +20,28 @@
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.oltpbenchmark.api.Procedure;
import com.oltpbenchmark.api.SQLStmt;
import com.oltpbenchmark.benchmarks.ycsb.YCSBConstants;

public class ScanRecord extends Procedure{
public final SQLStmt scanStmt = new SQLStmt(
"SELECT * FROM USERTABLE WHERE YCSB_KEY>? AND YCSB_KEY<?"
);

//FIXME: The value in ysqb is a byteiterator
public void run(Connection conn, int start, int count, List<Map<Integer,String>> results) throws SQLException {
public void run(Connection conn, int start, int count, List<String[]> results) throws SQLException {
PreparedStatement stmt = this.getPreparedStatement(conn, scanStmt);
stmt.setInt(1, start);
stmt.setInt(2, start+count);
ResultSet r=stmt.executeQuery();
while(r.next())
{
HashMap<Integer,String> m=new HashMap<Integer,String>();
for(int i=1;i<11;i++)
m.put(i, r.getString(i));
results.add(m);
while(r.next()) {
String data[] = new String[YCSBConstants.NUN_FIELDS];
for(int i = 0; i < data.length; i++)
data[i] = r.getString(i+1);
results.add(data);
}
r.close();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,10 @@
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Map;
import java.util.Map.Entry;

import com.oltpbenchmark.api.Procedure;
import com.oltpbenchmark.api.SQLStmt;
import com.oltpbenchmark.benchmarks.ycsb.YCSBConstants;

public class UpdateRecord extends Procedure {

Expand All @@ -32,13 +31,12 @@ public class UpdateRecord extends Procedure {
"FIELD6=?,FIELD7=?,FIELD8=?,FIELD9=?,FIELD10=? WHERE YCSB_KEY=?"
);

public void run(Connection conn, int keyname, Map<Integer,String> vals) throws SQLException {
public void run(Connection conn, int keyname, String vals[]) throws SQLException {
PreparedStatement stmt = this.getPreparedStatement(conn, updateAllStmt);
assert(vals.size()==10);
assert(vals.length == YCSBConstants.NUN_FIELDS);
stmt.setInt(11,keyname);
for(Entry<Integer, String> s:vals.entrySet())
{
stmt.setString(s.getKey(), s.getValue());
for (int i = 0; i < vals.length; i++) {
stmt.setString(i+1, vals[i]);
}
stmt.executeUpdate();
}
Expand Down
7 changes: 6 additions & 1 deletion src/com/oltpbenchmark/util/TextGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,16 @@ public abstract class TextGenerator {
*/
public static char[] randomChars(Random rng, int strLen) {
char chars[] = new char[strLen];
return randomChars(rng, chars);
}

public static char[] randomChars(Random rng, char chars[]) {
for (int i = 0; i < chars.length; i++) {
chars[i] = (char)CHAR_SYMBOLS[rng.nextInt(CHAR_SYMBOLS.length)];
chars[i] = CHAR_SYMBOLS[rng.nextInt(CHAR_SYMBOLS.length)];
} // FOR
return (chars);
}


public static char[] randomChars(Random rng, char chars[], int start, int stop) {
for (int i = start; i < stop; i++) {
Expand Down
29 changes: 24 additions & 5 deletions tests/com/oltpbenchmark/util/TestTextGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,37 @@ public class TestTextGenerator extends TestCase {
* testRandomChars
*/
public void testRandomChars() throws Exception {
long start = System.nanoTime();
for (int i = 0; i < 1000; i++) {
int strLen = rng.nextInt(2048);
char text[] = TextGenerator.randomChars(rng, strLen);
assertNotNull(text);
assertEquals(strLen, text.length);

for (int idx = 0; idx < strLen; idx++) {
assertFalse(Integer.toString(idx), text[idx] == 0);
} // FOR
} // FOR

// System.err.println(new String(text));
long stop = System.nanoTime();
System.err.println("Chars Elapsed Time: " + ((stop - start) / 1000000d) + " ms");
}

/**
* testRandomChars
*/
public void testRandomCharsPrealloc() throws Exception {
long start = System.nanoTime();
int strLen = rng.nextInt(2048);
char text[] = new char[strLen];
for (int i = 0; i < 1000; i++) {
TextGenerator.randomChars(rng, text);
assertNotNull(text);
assertEquals(strLen, text.length);
for (int idx = 0; idx < strLen; idx++) {
assertFalse(Integer.toString(idx), text[idx] == 0);
} // FOR
} // FOR
long stop = System.nanoTime();
System.err.println("Pre-allocated Chars Elapsed Time: " + ((stop - start) / 1000000d) + " ms");
}

/**
Expand Down Expand Up @@ -95,8 +114,8 @@ public void testPermuteText() throws Exception {
break;
}
} // FOR
System.err.println(new String(orig));
System.err.println(new String(newText));
// System.err.println(new String(orig));
// System.err.println(new String(newText));
assertTrue(valid);

}
Expand Down

0 comments on commit 53b5529

Please sign in to comment.