package jelectrum.db;
import jelectrum.Config;
import jelectrum.db.mongo.MongoDB;
import jelectrum.db.lobstack.LobstackDB;
import jelectrum.db.level.LevelDB;
import jelectrum.db.lmdb.LMDB;
import jelectrum.db.slopbucket.SlopbucketDB;
import jelectrum.db.jedis.JedisDB;
import java.util.Map;
import java.util.TreeMap;
import java.util.HashMap;
import com.google.protobuf.ByteString;
import java.util.Random;
import java.util.concurrent.Semaphore;
import java.util.concurrent.LinkedBlockingQueue;
import java.text.DecimalFormat;
import org.bitcoinj.core.Sha256Hash;
import jelectrum.EventLog;
import jelectrum.TimeRecord;
import java.util.concurrent.atomic.AtomicInteger;
import org.junit.Assert;
public class GrindTest
{
private static final long ITEMS_TO_ADD = 100L * 1000000L;
private static final int ITEMS_PER_PUT = 10000;
private static final int THREADS = 8;
private AtomicInteger items_saved= new AtomicInteger(0);
public static void main(String args[]) throws Exception
{
String name =args[0];
new GrindTest(name);
}
DBMap db_map;
Semaphore done_sem;
LinkedBlockingQueue<String> queue;
EventLog log;
public GrindTest(String name)
throws Exception
{
DB db = null;
Config conf = new Config("jelly-test.conf");
log =new EventLog(System.out);
if (name.equals("mongo"))
{
db = new MongoDB(conf);
}
if (name.equals("lobstack"))
{
db = new LobstackDB(null, conf);
}
if (name.equals("leveldb"))
{
db = new LevelDB(log, conf);
}
if (name.equals("lmdb"))
{
db = new LMDB(conf);
}
if (name.equals("slopbucket"))
{
db = new SlopbucketDB(conf, log);
}
if (name.equals("lmdbnet"))
{
conf = new Config("jelly-lmdbnet.conf");
db = new LevelDB(log, conf);
}
if (name.equals("redis"))
{
db = new JedisDB(conf);
}
if (name.equals("rocksdb"))
{
db = new jelectrum.db.rocksdb.JRocksDB(conf, log);
}
if (name.equals("cassandra"))
{
db = new jelectrum.db.cassandra.CassandraDB(conf);
}
Assert.assertNotNull("DB must not be null", db);
log.log("Selected DB: " + name);
db_map = db.openMap("grindtest");
new RateThread(15000).start();
performTest(name);
}
private void performTest(String name)
throws Exception
{
done_sem = new Semaphore(0);
queue = new LinkedBlockingQueue<>();
int runs = (int)ITEMS_TO_ADD / ITEMS_PER_PUT;
for(int i=0; i<runs; i++)
{
queue.put("" + i);
}
log.log("Adding " + ITEMS_TO_ADD + " in groups of " + ITEMS_PER_PUT);
long total_start = System.nanoTime();
for(int i=0; i<THREADS; i++) new GrindThread().start();
done_sem.acquire(runs);
System.out.println();
long total_end = System.nanoTime();
double sec = (total_end - total_start) / 1e9;
DecimalFormat df = new DecimalFormat("0.000");
log.log("Run "+ name +" done in " + df.format(sec));
}
public class GrindThread extends Thread
{
public GrindThread()
{
setName("GrindThread");
setDaemon(true);
}
public void run()
{
Random rnd = new Random();
while(true)
{
try
{
queue.take();
Map<String, ByteString> put_map = new HashMap<String, ByteString>(ITEMS_PER_PUT*2, 0.75f);
for(int i=0; i< ITEMS_PER_PUT; i++)
{
put_map.put(randomHash(rnd).toString(), randomByteString(rnd));
}
db_map.putAll(put_map);
done_sem.release();
items_saved.addAndGet(ITEMS_PER_PUT);
}
catch(Throwable e)
{
e.printStackTrace();
}
}
}
}
public static Sha256Hash randomHash(Random rnd)
{
byte[] b=new byte[32];
rnd.nextBytes(b);
return new Sha256Hash(b);
}
public static ByteString randomByteString(Random rnd)
{
byte[] b=new byte[100];
rnd.nextBytes(b);
return ByteString.copyFrom(b);
}
public class RateThread extends Thread
{
private long delay;
private String name;
public RateThread(long delay)
{
this.name = name;
this.delay = delay;
setDaemon(true);
setName("RateThread");
}
public void run()
{
long items = 0;
long last_run = System.currentTimeMillis();
DecimalFormat df =new DecimalFormat("0.000");
while(true)
{
TimeRecord tr = new TimeRecord();
TimeRecord.setSharedRecord(tr);
System.gc();
try{Thread.sleep(delay);}catch(Exception e){}
long now = System.currentTimeMillis();
long items_now = items_saved.get();
double sec = (now - last_run) / 1000.0;
double items_rate = (items_now - items) / sec;
String rate_log = "Rate: " + df.format(items_rate) + "/s";
log.log(rate_log);
tr.printReport(System.out);
items = items_now;
last_run= now;
}
}
}
}