package com.ctriposs.bigmap;
import static org.junit.Assert.*;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import org.junit.After;
import org.junit.Test;
import com.ctriposs.bigmap.utils.FileUtil;
public class PerfTest {
private static String testDir = TestUtil.TEST_BASE_DIR + "bigmap/unit/perf_test";
private BigConcurrentHashMapImpl map;
static final int N_THREADS = 128;
static final int COUNT = 8 * 10000000;
static final long stride;
static {
long _stride = Long.MAX_VALUE / COUNT;
while(_stride % 2 == 0)
_stride--;
stride = _stride;
}
@Test
public void testPut() throws IOException, ClassNotFoundException {
int count = 4000000;
BigConfig config = new BigConfig().setInitialCapacity(count).setConcurrencyLevel(128);
map = new BigConcurrentHashMapImpl(testDir, "testPut", config);
long start = System.nanoTime();
final SampleValue value = new SampleValue();
StringBuilder user = new StringBuilder();
System.out.println(value.toBytes().length);
for(int i = 0; i < count; i++) {
value.ee = i;
value.gg = i;
value.ii = i;
map.put(users(user, i).getBytes(), value.toBytes());
}
assertTrue(map.size() == count);
for(int i = 0; i < count; i++) {
byte[] bytes = map.get(users(user, i).getBytes());
assertNotNull(bytes);
SampleValue value2 = SampleValue.fromBytes(bytes);
assertEquals(i, value2.ee);
assertEquals(i, value2.gg, 0.0);
assertEquals(i, value2.ii);
}
for(int i = 0; i < count; i++) {
byte[] bytes = map.get(users(user, i).getBytes());
assertNotNull(bytes);
}
for (int i = 0; i < count; i++) {
map.remove(users(user, i).getBytes());
}
long time = System.nanoTime() - start;
System.out.printf("Put/get %,d K operations per second%n",
(int) (count * 4 * 1e6 / time));
}
@Test
public void testPutPerf() throws ExecutionException, InterruptedException, IOException {
ExecutorService es = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
// use a simple pseudo-random distribution over 64-bits
System.out.println("Starting test");
BigConfig config = new BigConfig().setInitialCapacity(COUNT).setConcurrencyLevel(64);
map = new BigConcurrentHashMapImpl(testDir, "testPutPerf", config);
final int COUNT = 5000000;
final String[] users = new String[COUNT];
for(int i = 0; i < COUNT; i++) users[i] = "user:" + i;
long start = System.nanoTime();
List<Future<?>> futures = new ArrayList<Future<?>>();
for(int t = 0; t < N_THREADS; t++) {
final int finalT = t;
futures.add(es.submit(new Runnable() {
@Override
public void run() {
try {
final SampleValue value = new SampleValue();
StringBuilder user = new StringBuilder();
for (int i = finalT; i < COUNT; i += N_THREADS) {
value.ee = i;
value.gg = i;
value.ii = i;
map.put(users(user, i).getBytes(), value.toBytes());
}
for (int i = finalT; i < COUNT; i += N_THREADS) {
byte[] bytes = map.get(users(user, i).getBytes());
assertNotNull(bytes);
SampleValue value2 = SampleValue.fromBytes(bytes);
assertEquals(i, value2.ee);
assertEquals(i, value2.gg, 0.0);
assertEquals(i, value2.ii);
}
for (int i = finalT; i < COUNT; i += N_THREADS)
if (map.get(users(user,i).getBytes()) == null) {
System.out.println(users(user, i));
}
//assertNotNull(map.get(users(user, i).getBytes()));
for (int i = finalT; i < COUNT; i += N_THREADS)
map.remove(users(user, i).getBytes());
} catch (Exception ex) {
ex.printStackTrace();
}
}
}));
}
for (Future<?> future : futures)
future.get();
long time = System.nanoTime() - start;
System.out.printf("Put/get %,d K operations per second%n",
(int) (COUNT * 4 * 1e6 / time));
es.shutdown();
}
public static class SampleValue implements Serializable {
private static final long serialVersionUID = 1L;
String aa = "aaaaaaaaaa";
String bb = "bbbbbbbbbb";
BuySell cc = BuySell.Buy;
BuySell dd = BuySell.Sell;
int ee = 123456;
int ff = 654321;
double gg = 1.23456789;
double hh = 9.87654321;
long ii = 987654321;
long jj = 123456789;
public byte[] toBytes() throws IOException {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutput out = null;
try {
out = new ObjectOutputStream(bos);
out.writeObject(this);
byte[] yourBytes = bos.toByteArray();
return yourBytes;
} finally {
try {
if (out != null) {
out.close();
}
} catch (IOException ex) {
// ignore close exception
}
try {
bos.close();
} catch (IOException ex) {
// ignore close exception
}
}
}
public static SampleValue fromBytes(byte[] bytes) throws ClassNotFoundException, IOException {
ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
ObjectInput in = null;
try {
in = new ObjectInputStream(bis);
Object o = in.readObject();
return (SampleValue)o;
} finally {
try {
bis.close();
} catch (IOException ex) {
// ignore close exception
}
try {
if (in != null) {
in.close();
}
} catch (IOException ex) {
// ignore close exception
}
}
}
}
enum BuySell {
Buy, Sell
}
String users(StringBuilder user, int i) {
user.setLength(0);
user.append("user:");
user.append(i);
return user.toString();
}
@After
public void clear() throws IOException {
if (map != null) {
map.close();
}
FileUtil.deleteDirectory(new File(testDir));
}
}