Fleshed out multi-threaded BTree tests a little more.
git-svn-id: https://hyracks.googlecode.com/svn/branches/hyracks_lsm_tree@1117 123451ca-8445-de46-9d55-352943316053
diff --git a/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/test/TreeIndexMultiThreadTestDriver.java b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/test/TreeIndexMultiThreadTestDriver.java
index e0b6b47..0e0d3c2 100644
--- a/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/test/TreeIndexMultiThreadTestDriver.java
+++ b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/test/TreeIndexMultiThreadTestDriver.java
@@ -16,6 +16,7 @@
package edu.uci.ics.hyracks.storage.am.common.test;
import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndex;
import edu.uci.ics.hyracks.storage.am.common.api.TreeIndexException;
import edu.uci.ics.hyracks.storage.am.common.datagen.DataGenThread;
@@ -38,9 +39,14 @@
this.workerFactory = workerFactory;
this.fieldSerdes = fieldSerdes;
this.opSelector = new TestOperationSelector(ops, opProbs);
+ }
+
+ public void init(int fileId) throws HyracksDataException {
+ index.create(fileId);
+ index.open(fileId);
}
- public void run(int numThreads, int numRepeats, int numTuples, int batchSize) throws InterruptedException, TreeIndexException {
+ public long[] run(int numThreads, int numRepeats, int numTuples, int batchSize) throws InterruptedException, TreeIndexException {
int numBatches = numTuples / batchSize;
int threadNumBatches = numBatches / numThreads;
if (threadNumBatches <= 0) {
@@ -69,6 +75,11 @@
long end = System.currentTimeMillis();
times[i] = end - start;
}
+ return times;
+ }
+
+ public void deinit() throws HyracksDataException {
+ index.close();
}
// To allow subclasses to override the data gen params.
diff --git a/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/btree/multithread/BTreeMultiThreadTest.java b/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/btree/multithread/BTreeMultiThreadTest.java
index c7e13f7..610df16 100644
--- a/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/btree/multithread/BTreeMultiThreadTest.java
+++ b/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/btree/multithread/BTreeMultiThreadTest.java
@@ -15,6 +15,9 @@
package edu.uci.ics.hyracks.storage.am.btree.multithread;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -36,15 +39,24 @@
@SuppressWarnings("rawtypes")
public class BTreeMultiThreadTest {
- private final int PAGE_SIZE = 8192;
- //private final int PAGE_SIZE = 64;
- private final int NUM_PAGES = 1000;
- private final int MAX_OPEN_FILES = 10;
- private final int HYRACKS_FRAME_SIZE = 32768;
+ protected final Logger LOGGER = Logger.getLogger(BTreeMultiThreadTest.class.getName());
+
+ //private final int PAGE_SIZE = 8192;
+ //private final int PAGE_SIZE = 8192;
+ //private final int NUM_PAGES = 100;
+ //private final int MAX_OPEN_FILES = 10;
+ //private final int HYRACKS_FRAME_SIZE = 32768;
private final BTreeTestWorkerFactory workerFactory = new BTreeTestWorkerFactory();
- private final BTreeTestHarness harness = new BTreeTestHarness(PAGE_SIZE, NUM_PAGES, MAX_OPEN_FILES, HYRACKS_FRAME_SIZE);
+ //private final BTreeTestHarness harness = new BTreeTestHarness(PAGE_SIZE, NUM_PAGES, MAX_OPEN_FILES, HYRACKS_FRAME_SIZE);
+ private final BTreeTestHarness harness = new BTreeTestHarness();
+ // Machine-specific number of threads to use for testing.
+ private final int REGULAR_NUM_THREADS = Runtime.getRuntime().availableProcessors();
+ // Excessive number of threads for testing.
+ private final int EXCESSIVE_NUM_THREADS = Runtime.getRuntime().availableProcessors() * 4;
+ private final int NUM_TUPLES = 1000000;
+
@Before
public void setUp() throws HyracksDataException {
harness.setUp();
@@ -55,8 +67,11 @@
harness.tearDown();
}
- @Test
- public void firstTest() throws InterruptedException, HyracksDataException, TreeIndexException {
+ private void runOneIntKeyAndValueTest(int numThreads) throws HyracksDataException, InterruptedException, TreeIndexException {
+ if (LOGGER.isLoggable(Level.INFO)) {
+ LOGGER.info("BTree MultiThread Test With One Int Key And Value Using " + numThreads + " Threads.");
+ }
+
ISerializerDeserializer[] fieldSerdes = new ISerializerDeserializer[] { IntegerSerializerDeserializer.INSTANCE, IntegerSerializerDeserializer.INSTANCE };
ITypeTraits[] typeTraits = SerdeUtils.serdesToTypeTraits(fieldSerdes);
int numKeyFields = 1;
@@ -70,10 +85,26 @@
TestOperation[] ops = new TestOperation[] { TestOperation.INSERT };
float[] opProbs = new float[] { 1.0f };
+ // 4 batches per thread.
+ int batchSize = (NUM_TUPLES / numThreads) / 4;
+
TreeIndexMultiThreadTestDriver driver = new TreeIndexMultiThreadTestDriver(btree, workerFactory, fieldSerdes, ops, opProbs);
+ driver.init(harness.getBTreeFileId());
+ long[] times = driver.run(REGULAR_NUM_THREADS, 1, NUM_TUPLES, batchSize);
+ driver.deinit();
- driver.run(10, 1, 10000000, 1000);
-
- btree.close();
+ for (int i = 0; i < times.length; i++) {
+ System.out.println("TIME: " + times[i]);
+ }
+ }
+
+ @Test
+ public void oneIntKeyAndValueRegular() throws InterruptedException, HyracksDataException, TreeIndexException {
+ runOneIntKeyAndValueTest(REGULAR_NUM_THREADS);
+ }
+
+ @Test
+ public void oneIntKeyAndValueExcessive() throws InterruptedException, HyracksDataException, TreeIndexException {
+ runOneIntKeyAndValueTest(EXCESSIVE_NUM_THREADS);
}
}
diff --git a/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/btree/multithread/BTreeTestWorker.java b/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/btree/multithread/BTreeTestWorker.java
index 7896394..ce2592c 100644
--- a/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/btree/multithread/BTreeTestWorker.java
+++ b/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/btree/multithread/BTreeTestWorker.java
@@ -18,9 +18,15 @@
import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
import edu.uci.ics.hyracks.dataflow.common.data.accessors.ITupleReference;
import edu.uci.ics.hyracks.storage.am.btree.exceptions.BTreeDuplicateKeyException;
+import edu.uci.ics.hyracks.storage.am.btree.exceptions.BTreeNonExistentKeyException;
+import edu.uci.ics.hyracks.storage.am.btree.exceptions.BTreeNotUpdateableException;
+import edu.uci.ics.hyracks.storage.am.btree.impls.BTree;
+import edu.uci.ics.hyracks.storage.am.btree.impls.RangePredicate;
import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndex;
+import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexCursor;
import edu.uci.ics.hyracks.storage.am.common.api.TreeIndexException;
import edu.uci.ics.hyracks.storage.am.common.datagen.DataGenThread;
+import edu.uci.ics.hyracks.storage.am.common.ophelpers.MultiComparator;
import edu.uci.ics.hyracks.storage.am.common.test.AbstractTreeIndexTestWorker;
import edu.uci.ics.hyracks.storage.am.common.test.TestOperationSelector;
import edu.uci.ics.hyracks.storage.am.common.test.TestOperationSelector.TestOperation;
@@ -32,19 +38,72 @@
}
@Override
- public void performOp(ITupleReference tuple, TestOperation op) throws HyracksDataException, TreeIndexException {
+ public void performOp(ITupleReference tuple, TestOperation op) throws HyracksDataException, TreeIndexException {
+ BTree.BTreeAccessor accessor = (BTree.BTreeAccessor) indexAccessor;
+ ITreeIndexCursor searchCursor = accessor.createSearchCursor();
+ ITreeIndexCursor diskOrderScanCursor = accessor.createDiskOrderScanCursor();
+ MultiComparator cmp = accessor.getOpContext().cmp;
+ RangePredicate rangePred = new RangePredicate(tuple, tuple, true, true, cmp, cmp);
+
switch (op) {
case INSERT:
try {
- indexAccessor.insert(tuple);
+ accessor.insert(tuple);
} catch (BTreeDuplicateKeyException e) {
- // Ignore duplicate keys.
+ // Ignore duplicate keys, since we get random tuples.
}
break;
+ case DELETE:
+ try {
+ accessor.delete(tuple);
+ } catch (BTreeNonExistentKeyException e) {
+ // Ignore non-existant keys, since we get random tuples.
+ }
+ break;
+
+ case UPDATE:
+ try {
+ accessor.update(tuple);
+ } catch (BTreeNotUpdateableException e) {
+ // Ignore not updateable exception due to numKeys == numFields.
+ }
+ break;
+
+ case POINT_SEARCH:
+ searchCursor.reset();
+ rangePred.setLowKey(tuple, true);
+ rangePred.setHighKey(tuple, true);
+ accessor.search(searchCursor, rangePred);
+ consumeCursorTuples(searchCursor);
+ break;
+
+ case ORDERED_SCAN:
+ searchCursor.reset();
+ rangePred.setLowKey(null, true);
+ rangePred.setHighKey(null, true);
+ accessor.search(searchCursor, rangePred);
+ consumeCursorTuples(searchCursor);
+ break;
+
+ case DISKORDER_SCAN:
+ diskOrderScanCursor.reset();
+ accessor.diskOrderScan(diskOrderScanCursor);
+ consumeCursorTuples(diskOrderScanCursor);
+ break;
default:
throw new HyracksDataException("Op " + op.toString() + " not supported.");
}
}
+
+ private void consumeCursorTuples(ITreeIndexCursor cursor) throws HyracksDataException {
+ try {
+ while(cursor.hasNext()) {
+
+ }
+ } finally {
+ cursor.close();
+ }
+ }
}