/*
* Copyright 2004-2014 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.test.store;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.Statement;
import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import org.h2.mvstore.MVMap;
import org.h2.mvstore.MVStore;
import org.h2.store.FileLister;
import org.h2.store.fs.FileUtils;
import org.h2.test.TestBase;
import org.h2.util.Task;
/**
* Tests performance and helps analyze bottlenecks.
*/
public class TestBenchmark extends TestBase {
/**
* Run just this test.
*
* @param a ignored
*/
public static void main(String... a) throws Exception {
TestBase.createCaller().init().test();
}
@Override
public void test() throws Exception {
testConcurrency();
// TODO this test is currently disabled
test(true);
test(false);
test(true);
test(false);
test(true);
test(false);
}
private void testConcurrency() throws Exception {
// String fileName = getBaseDir() + "/" + getTestName();
String fileName = "nioMemFS:/" + getTestName();
FileUtils.delete(fileName);
MVStore store = new MVStore.Builder().cacheSize(16).
fileName(fileName).open();
MVMap<Integer, byte[]> map = store.openMap("test");
byte[] data = new byte[1024];
int count = 1000000;
for (int i = 0; i < count; i++) {
map.put(i, data);
}
store.close();
for (int concurrency = 1024; concurrency > 0; concurrency /= 2) {
testConcurrency(fileName, concurrency, count);
testConcurrency(fileName, concurrency, count);
testConcurrency(fileName, concurrency, count);
}
FileUtils.delete(fileName);
}
private void testConcurrency(String fileName,
int concurrency, final int count) throws Exception {
Thread.sleep(1000);
final MVStore store = new MVStore.Builder().cacheSize(256).
cacheConcurrency(concurrency).
fileName(fileName).open();
int threadCount = 128;
final CountDownLatch wait = new CountDownLatch(1);
final AtomicInteger counter = new AtomicInteger();
final AtomicBoolean stopped = new AtomicBoolean();
Task[] tasks = new Task[threadCount];
// Profiler prof = new Profiler().startCollecting();
for (int i = 0; i < threadCount; i++) {
final int x = i;
Task t = new Task() {
@Override
public void call() throws Exception {
MVMap<Integer, byte[]> map = store.openMap("test");
Random random = new Random(x);
wait.await();
while (!stopped.get()) {
int key = random.nextInt(count);
byte[] data = map.get(key);
if (data.length > 1) {
counter.incrementAndGet();
}
}
}
};
t.execute("t" + i);
tasks[i] = t;
}
wait.countDown();
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
stopped.set(true);
for (Task t : tasks) {
t.get();
}
// System.out.println(prof.getTop(5));
String msg = "concurrency " + concurrency +
" threads " + threadCount + " requests: " + counter;
System.out.println(msg);
trace(msg);
store.close();
}
private void test(boolean mvStore) throws Exception {
// testInsertSelect(mvStore);
// testBinary(mvStore);
testCreateIndex(mvStore);
}
private void testCreateIndex(boolean mvStore) throws Exception {
FileUtils.deleteRecursive(getBaseDir(), true);
Connection conn;
Statement stat;
String url = "mvstore";
if (mvStore) {
// ;COMPRESS=TRUE";
url += ";MV_STORE=TRUE";
}
url = getURL(url, true);
conn = getConnection(url);
stat = conn.createStatement();
stat.execute("create table test(id bigint primary key, data bigint)");
conn.setAutoCommit(false);
PreparedStatement prep = conn
.prepareStatement("insert into test values(?, ?)");
// int rowCount = 10000000;
int rowCount = 1000000;
Random r = new Random(1);
for (int i = 0; i < rowCount; i++) {
prep.setInt(1, i);
// prep.setInt(2, i);
prep.setInt(2, r.nextInt());
prep.execute();
if (i % 10000 == 0) {
conn.commit();
}
}
long start = System.nanoTime();
// Profiler prof = new Profiler().startCollecting();
stat.execute("create index on test(data)");
// System.out.println(prof.getTop(5));
System.out.println(TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start) + " "
+ (mvStore ? "mvstore" : "default"));
conn.createStatement().execute("shutdown compact");
conn.close();
for (String f : FileLister.getDatabaseFiles(getBaseDir(), "mvstore", true)) {
System.out.println(" " + f + " " + FileUtils.size(f));
}
}
private void testBinary(boolean mvStore) throws Exception {
FileUtils.deleteRecursive(getBaseDir(), true);
Connection conn;
Statement stat;
String url = "mvstore";
if (mvStore) {
url += ";MV_STORE=TRUE";
}
url = getURL(url, true);
conn = getConnection(url);
stat = conn.createStatement();
stat.execute("create table test(id bigint primary key, data blob)");
conn.setAutoCommit(false);
PreparedStatement prep = conn
.prepareStatement("insert into test values(?, ?)");
byte[] data = new byte[1024 * 1024];
int rowCount = 100;
int readCount = 20 * rowCount;
long start = System.nanoTime();
for (int i = 0; i < rowCount; i++) {
prep.setInt(1, i);
randomize(data, i);
prep.setBytes(2, data);
prep.execute();
if (i % 100 == 0) {
conn.commit();
}
}
prep = conn.prepareStatement("select * from test where id = ?");
for (int i = 0; i < readCount; i++) {
prep.setInt(1, i % rowCount);
prep.executeQuery();
}
System.out.println(TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start) + " "
+ (mvStore ? "mvstore" : "default"));
conn.close();
}
private static void randomize(byte[] data, int i) {
Random r = new Random(i);
r.nextBytes(data);
}
private void testInsertSelect(boolean mvStore) throws Exception {
FileUtils.deleteRecursive(getBaseDir(), true);
Connection conn;
Statement stat;
String url = "mvstore";
if (mvStore) {
url += ";MV_STORE=TRUE;LOG=0;COMPRESS=TRUE";
}
url = getURL(url, true);
conn = getConnection(url);
stat = conn.createStatement();
stat.execute("create table test(id bigint primary key, name varchar)");
conn.setAutoCommit(false);
PreparedStatement prep = conn
.prepareStatement("insert into test values(?, ?)");
String data = "Hello World";
int rowCount = 100000;
int readCount = 20 * rowCount;
for (int i = 0; i < rowCount; i++) {
prep.setInt(1, i);
prep.setString(2, data);
prep.execute();
if (i % 100 == 0) {
conn.commit();
}
}
long start = System.nanoTime();
prep = conn.prepareStatement("select * from test where id = ?");
for (int i = 0; i < readCount; i++) {
prep.setInt(1, i % rowCount);
prep.executeQuery();
}
System.out.println(TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start) + " "
+ (mvStore ? "mvstore" : "default"));
conn.createStatement().execute("shutdown compact");
conn.close();
for (String f : FileLister.getDatabaseFiles(getBaseDir(), "mvstore", true)) {
System.out.println(" " + f + " " + FileUtils.size(f));
}
}
}