package com.ctriposs.sdb.table; 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.sdb.table.AbstractMapTable; import com.ctriposs.sdb.table.GetResult; import com.ctriposs.sdb.table.HashMapTable; import com.ctriposs.sdb.utils.FileUtil; import com.ctriposs.sdb.utils.TestUtil; public class HashMapTablePerfTest { private static String testDir = TestUtil.TEST_BASE_DIR + "sdb/unit/hashmap_table_perf_test"; private HashMapTable map; static final int N_THREADS = 128; @Test public void testPut() throws IOException, ClassNotFoundException { int count = 40000; map = new HashMapTable(testDir, 0, System.nanoTime()); 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(), AbstractMapTable.NO_TIMEOUT, System.currentTimeMillis()); } assertTrue(map.getAppendedSize() == count); for(int i = 0; i < count; i++) { GetResult result = map.get(users(user, i).getBytes()); assertTrue(result.isFound() && !result.isDeleted() && !result.isExpired()); assertNotNull(result.getValue()); SampleValue value2 = SampleValue.fromBytes(result.getValue()); assertEquals(i, value2.ee); assertEquals(i, value2.gg, 0.0); assertEquals(i, value2.ii); } for(int i = 0; i < count; i++) { GetResult result = map.get(users(user, i).getBytes()); assertNotNull(result.getValue()); } for (int i = 0; i < count; i++) { map.delete(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"); map = new HashMapTable(testDir, 0, System.nanoTime()); final int COUNT = 50000; 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(), AbstractMapTable.NO_TIMEOUT, System.currentTimeMillis()); } for (int i = finalT; i < COUNT; i += N_THREADS) { GetResult result = map.get(users(user, i).getBytes()); assertTrue(result.isFound() && !result.isDeleted() && !result.isExpired()); assertNotNull(result.getValue()); SampleValue value2 = SampleValue.fromBytes(result.getValue()); assertEquals(i, value2.ee); assertEquals(i, value2.gg, 0.0); assertEquals(i, value2.ii); } for (int i = finalT; i < COUNT; i += N_THREADS) assertTrue(map.get(users(user, i).getBytes()).isFound()); for (int i = finalT; i < COUNT; i += N_THREADS) map.delete(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; public String aa = "aaaaaaaaaa"; public String bb = "bbbbbbbbbb"; public BuySell cc = BuySell.Buy; public BuySell dd = BuySell.Sell; public int ee = 123456; public int ff = 654321; public double gg = 1.23456789; public double hh = 9.87654321; public long ii = 987654321; public 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 } public static 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)); } }