/* * Copyright (c) 2008, Jan Stender, Bjoern Kolbeck, Mikael Hoegqvist, * Felix Hupfeld, Zuse Institute Berlin * * Licensed under the BSD License, see LICENSE file for details. * */ package de.mxro.thrd.babudb05.sandbox; import java.io.File; import java.util.Map.Entry; import de.mxro.thrd.babudb05.api.database.ResultSet; import de.mxro.thrd.babudb05.index.DefaultByteRangeComparator; import de.mxro.thrd.babudb05.index.LSMTree; import de.mxro.thrd.babudb05.index.writer.DiskIndexWriter; public class LSMTreePerformanceTest { public static void main(String[] args) throws Exception { if (args.length != 4) { System.out.println("usage: java " + LSMTreePerformanceTest.class.getCanonicalName() + " <db_file> <num_entries> <num_inserts> <num_lookups>"); System.exit(1); } final String path = args[0]; final int entriesPerBlock = 16; final int minStrLen = 1; final int maxStrLen = 8; final char minChar = 48; final char maxChar = 122; final int size = Integer.parseInt(args[1]); final int inserts = Integer.parseInt(args[2]); final int lookups = Integer.parseInt(args[3]); // TODO: make configurable final int blockFileSize = 1024 * 1024 * 1024; if (size != 0) { // delete old index file new File(path).delete(); System.out.println("creating new database with " + size + " random entries ..."); // write the map to a disk index DiskIndexWriter index = new DiskIndexWriter(path, entriesPerBlock, false, blockFileSize); index.writeIndex(new ResultSet<Object, Object>() { private int count; private String next = minChar + ""; @Override public boolean hasNext() { return count < size; } @Override public Entry<Object, Object> next() { count++; next = createNextString(next, minStrLen, maxStrLen, minChar, maxChar); return new Entry<Object, Object>() { @Override public Object getKey() { return next.getBytes(); } @Override public Object getValue() { return next.getBytes(); } @Override public Object setValue(Object value) { throw new UnsupportedOperationException(); } }; } @Override public void remove() { throw new UnsupportedOperationException(); } @Override public void free() { } }); } // read the LSM tree LSMTree tree = new LSMTree(path, new DefaultByteRangeComparator(), false, 16, 1024 * 1024 * 512, true, -1); System.out.println("inserting " + inserts + " random elements ..."); for (int i = 0; i < inserts; i++) { byte[] entry = createRandomString(minChar, maxChar, minStrLen, maxStrLen).getBytes(); tree.insert(entry, entry); } // Iterator<Entry<ReusableBuffer, ReusableBuffer>> it = // tree.prefixLookup(null); // while (it.hasNext()) // System.out.println(new String(it.next().getKey().array())); // System.out.println("performing " + lookups + " random lookups ..."); // look up each element int hits = 0; long t0 = System.currentTimeMillis(); for (int i = 0; i < lookups; i++) { byte[] key = createRandomString(minChar, maxChar, minStrLen, maxStrLen).getBytes(); byte[] result = tree.lookup(key); if (result != null) hits++; if (i % 100000 == 0) System.out.println(i); } long time = System.currentTimeMillis() - t0; System.out.println(time + " ms"); System.out.println((long) lookups * 1000 / time + " lookups/s"); System.out.println("hits: " + hits + " / " + lookups); } private static String createNextString(String st, int minStrLen, int maxStrLen, char minChar, char maxChar) { char[] chars = st.toCharArray(); for (;;) { double rnd = Math.random(); if (rnd < .1f + .8f / chars.length && chars.length < maxStrLen) { // append character char[] chars2 = new char[chars.length + 1]; System.arraycopy(chars, 0, chars2, 0, chars.length); chars2[chars2.length - 1] = createRandomChar(minChar, maxChar); return new String(chars2); } else if (rnd > .95f + .05f / chars.length && chars.length > minStrLen) { int i = chars.length - 2; for (; i >= 0; i--) if (chars[i] < maxChar) break; if (i == -1) continue; // increment character and truncate char[] chars2 = new char[i + 1]; System.arraycopy(chars, 0, chars2, 0, chars2.length); chars2[chars2.length - 1]++; return new String(chars2); } else if (chars[chars.length - 1] < maxChar) { // increment last character chars[chars.length - 1]++; return new String(chars); } } } private static String createRandomString(char minChar, char maxChar, int minLength, int maxLength) { char[] chars = new char[(int) (Math.random() * (maxLength + 1)) + minLength]; for (int i = 0; i < chars.length; i++) chars[i] = createRandomChar(minChar, maxChar); return new String(chars); } private static char createRandomChar(char minChar, char maxChar) { return (char) (Math.random() * (maxChar - minChar + 1) + minChar); } }