Refactoring BTree tests to reduce duplicate code and improve readability.

git-svn-id: https://hyracks.googlecode.com/svn/branches/hyracks_btree_updates_next@594 123451ca-8445-de46-9d55-352943316053
diff --git a/hyracks-api/src/main/java/edu/uci/ics/hyracks/api/dataflow/value/ITypeTrait.java b/hyracks-api/src/main/java/edu/uci/ics/hyracks/api/dataflow/value/ITypeTrait.java
index 0f46f57..639617d 100644
--- a/hyracks-api/src/main/java/edu/uci/ics/hyracks/api/dataflow/value/ITypeTrait.java
+++ b/hyracks-api/src/main/java/edu/uci/ics/hyracks/api/dataflow/value/ITypeTrait.java
@@ -3,6 +3,13 @@
 import java.io.Serializable;
 
 public interface ITypeTrait extends Serializable {
-	public static final int VARIABLE_LENGTH = -1;	
+	public static final int VARIABLE_LENGTH = -1;
+	
+	public static final ITypeTrait INTEGER_TYPE_TRAIT = new TypeTrait(4);
+    public static final ITypeTrait INTEGER64_TYPE_TRAIT = new TypeTrait(8);
+    public static final ITypeTrait FLOAT_TYPE_TRAIT = new TypeTrait(4);
+    public static final ITypeTrait DOUBLE_TYPE_TRAIT = new TypeTrait(8);
+    public static final ITypeTrait BOOLEAN_TYPE_TRAIT = new TypeTrait(1);
+    public static final ITypeTrait VARLEN_TYPE_TRAIT = new TypeTrait(ITypeTrait.VARIABLE_LENGTH);	
 	int getStaticallyKnownDataLength();
 }
diff --git a/hyracks-dataflow-common/src/main/java/edu/uci/ics/hyracks/dataflow/common/comm/io/ArrayTupleReference.java b/hyracks-dataflow-common/src/main/java/edu/uci/ics/hyracks/dataflow/common/comm/io/ArrayTupleReference.java
new file mode 100644
index 0000000..b265283
--- /dev/null
+++ b/hyracks-dataflow-common/src/main/java/edu/uci/ics/hyracks/dataflow/common/comm/io/ArrayTupleReference.java
@@ -0,0 +1,41 @@
+package edu.uci.ics.hyracks.dataflow.common.comm.io;
+
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ITupleReference;
+
+/**
+ * An ArrayTupleReference provides access to a tuple that is not serialized into
+ * a frame. It is meant to be reset directly with the field slots and tuple data
+ * provided by ArrayTupleBuilder. The purpose is to avoid coping the built tuple
+ * into a frame before being able to use it as an ITupleReference.
+ * 
+ * @author alexander.behm
+ */
+public class ArrayTupleReference implements ITupleReference {
+	private int[] fEndOffsets;
+	private byte[] tupleData;
+
+	public void reset(int[] fEndOffsets, byte[] tupleData) {
+		this.fEndOffsets = fEndOffsets;
+		this.tupleData = tupleData;
+	}
+	
+	@Override
+	public int getFieldCount() {
+		return fEndOffsets.length;
+	}
+
+	@Override
+	public byte[] getFieldData(int fIdx) {
+		return tupleData;
+	}
+
+	@Override
+	public int getFieldStart(int fIdx) {
+		return (fIdx == 0) ? 0 : fEndOffsets[fIdx - 1]; 
+	}
+
+	@Override
+	public int getFieldLength(int fIdx) {
+		return (fIdx == 0) ? fEndOffsets[0] : fEndOffsets[fIdx] - fEndOffsets[fIdx - 1];
+	}
+}
diff --git a/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/btree/AbstractBTreeTest.java b/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/btree/AbstractBTreeTest.java
index 56ae6e9..c54a830 100644
--- a/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/btree/AbstractBTreeTest.java
+++ b/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/btree/AbstractBTreeTest.java
@@ -5,24 +5,68 @@
 import java.util.Date;
 import java.util.logging.Logger;
 
-import org.junit.AfterClass;
+import org.junit.After;
+import org.junit.Before;
+
+import edu.uci.ics.hyracks.api.context.IHyracksTaskContext;
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.api.io.FileReference;
+import edu.uci.ics.hyracks.storage.common.buffercache.IBufferCache;
+import edu.uci.ics.hyracks.storage.common.file.IFileMapProvider;
+import edu.uci.ics.hyracks.test.support.TestStorageManagerComponentHolder;
+import edu.uci.ics.hyracks.test.support.TestUtils;
 
 public abstract class AbstractBTreeTest {
-
     protected static final Logger LOGGER = Logger.getLogger(AbstractBTreeTest.class.getName());
 
+    private static final int PAGE_SIZE = 256;
+    private static final int NUM_PAGES = 10;
+    private static final int MAX_OPEN_FILES = 10;
+    private static final int HYRACKS_FRAME_SIZE = 128;
+    
+    protected IHyracksTaskContext ctx; 
+    protected IBufferCache bufferCache;
+    protected int btreeFileId;
+    
     protected final static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("ddMMyy-hhmmssSS");
     protected final static String tmpDir = System.getProperty("java.io.tmpdir");
     protected final static String sep = System.getProperty("file.separator");
-    protected final static String fileName = tmpDir + sep + simpleDateFormat.format(new Date());
-
-    protected void print(String str) {
-        System.out.print(str);
+    protected String fileName;
+    
+    @Before
+    public void setUp() throws HyracksDataException {
+        fileName = tmpDir + sep + simpleDateFormat.format(new Date());
+        ctx = TestUtils.create(HYRACKS_FRAME_SIZE);
+        TestStorageManagerComponentHolder.init(PAGE_SIZE, NUM_PAGES, MAX_OPEN_FILES);
+        bufferCache = TestStorageManagerComponentHolder.getBufferCache(ctx);
+        IFileMapProvider fmp = TestStorageManagerComponentHolder.getFileMapProvider(ctx);
+        FileReference file = new FileReference(new File(fileName));
+        bufferCache.createFile(file);
+        btreeFileId = fmp.lookupFileId(file);
+        bufferCache.openFile(btreeFileId);
     }
-
-    @AfterClass
-    public static void cleanup() throws Exception {
+    
+    @After
+    public void tearDown() throws HyracksDataException {
+        bufferCache.closeFile(btreeFileId);
+        bufferCache.close();
         File f = new File(fileName);
         f.deleteOnExit();
     }
+    
+    public int getPageSize() {
+        return PAGE_SIZE;
+    }
+    
+    public int getNumPages() {
+        return NUM_PAGES;
+    }
+    
+    public int getHyracksFrameSize() {
+        return HYRACKS_FRAME_SIZE;
+    }
+    
+    public int getMaxOpenFiles() {
+        return MAX_OPEN_FILES;
+    }
 }
diff --git a/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/btree/BTreeTest.java b/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/btree/BTreeTest.java
index 7240d9f..23eb0b2 100644
--- a/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/btree/BTreeTest.java
+++ b/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/btree/BTreeTest.java
@@ -36,6 +36,7 @@
 import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
 import edu.uci.ics.hyracks.api.io.FileReference;
 import edu.uci.ics.hyracks.dataflow.common.comm.io.ArrayTupleBuilder;
+import edu.uci.ics.hyracks.dataflow.common.comm.io.ArrayTupleReference;
 import edu.uci.ics.hyracks.dataflow.common.comm.io.FrameTupleAccessor;
 import edu.uci.ics.hyracks.dataflow.common.comm.io.FrameTupleAppender;
 import edu.uci.ics.hyracks.dataflow.common.data.accessors.FrameTupleReference;
@@ -84,7 +85,7 @@
     // "value" field
     // fill B-tree with random values using insertions (not bulk load)
     // perform ordered scan and range search
-    //@Test
+    @Test
     public void test01() throws Exception {
 
         LOGGER.info("FIXED-LENGTH KEY TEST");
@@ -163,13 +164,16 @@
 
             tuple.reset(accessor, 0);
 
+            ArrayTupleReference t = new ArrayTupleReference();
+            t.reset(tb.getFieldEndOffsets(), tb.getByteArray());
+            
             if (i % 1000 == 0) {
                 long end = System.currentTimeMillis();
                 LOGGER.info("INSERTING " + i + " : " + f0 + " " + f1 + " " + (end - start));
             }
 
             try {
-                btree.insert(tuple, insertOpCtx);
+                btree.insert(t, insertOpCtx);
             } catch (TreeIndexException e) {
             } catch (Exception e) {
                 e.printStackTrace();
@@ -288,7 +292,7 @@
     // fixed-length "value" field
     // fill B-tree with random values using insertions (not bulk load)
     // perform ordered scan and range search
-    @Test
+    //@Test
     public void test02() throws Exception {
 
         LOGGER.info("COMPOSITE KEY TEST");
@@ -366,7 +370,7 @@
             tb.addFieldEndOffset();
             IntegerSerializerDeserializer.INSTANCE.serialize(f2, dos);
             tb.addFieldEndOffset();
-
+            
             appender.reset(frame, true);
             appender.append(tb.getFieldEndOffsets(), tb.getByteArray(), 0, tb.getSize());
 
@@ -859,7 +863,7 @@
     // fill B-tree with random values using insertions, then update entries
     // one-by-one
     // repeat procedure a few times on same B-tree
-    //@Test
+    @Test
     public void test05() throws Exception {
 
         LOGGER.info("DELETION TEST");
@@ -937,6 +941,9 @@
             UTF8StringSerializerDeserializer.INSTANCE.serialize(f1, dos);
             tb.addFieldEndOffset();
 
+            ArrayTupleReference t = new ArrayTupleReference();
+            t.reset(tb.getFieldEndOffsets(), tb.getByteArray());
+            
             appender.reset(frame, true);
             appender.append(tb.getFieldEndOffsets(), tb.getByteArray(), 0, tb.getSize());
 
@@ -946,7 +953,7 @@
                 LOGGER.info("INSERTING " + i);
             }
             try {
-                btree.insert(tuple, insertOpCtx);
+                btree.insert(t, insertOpCtx);
                 expectedValues.put(f0, f1);
             } catch (TreeIndexException e) {
                 // e.printStackTrace();
@@ -989,8 +996,11 @@
                     LOGGER.info("UPDATING " + i);
                 }
 
+                ArrayTupleReference t = new ArrayTupleReference();
+                t.reset(tb.getFieldEndOffsets(), tb.getByteArray());
+                
                 try {
-                    btree.update(tuple, updateOpCtx);
+                    btree.update(t, updateOpCtx);
                     expectedValues.put(f0s[i], f1);
                 } catch (TreeIndexException e) {
                     e.printStackTrace();
@@ -1311,7 +1321,8 @@
                 scanCursor.next();
                 ITupleReference frameTuple = scanCursor.getTuple();
                 String rec = cmp.printTuple(frameTuple, recDescSers);
-                print(rec + "\n");
+                // TODO: fix me.
+                //print(rec + "\n");
             }
         } catch (Exception e) {
             e.printStackTrace();
diff --git a/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/btree/BTreeTestUtils.java b/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/btree/BTreeTestUtils.java
new file mode 100644
index 0000000..2e33eaf
--- /dev/null
+++ b/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/btree/BTreeTestUtils.java
@@ -0,0 +1,92 @@
+package edu.uci.ics.hyracks.storage.am.btree;
+
+import java.io.DataOutput;
+
+import edu.uci.ics.hyracks.api.dataflow.value.IBinaryComparator;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.api.dataflow.value.ITypeTrait;
+import edu.uci.ics.hyracks.api.dataflow.value.TypeTrait;
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.dataflow.common.comm.io.ArrayTupleBuilder;
+import edu.uci.ics.hyracks.dataflow.common.comm.io.ArrayTupleReference;
+import edu.uci.ics.hyracks.dataflow.common.data.marshalling.BooleanSerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.data.marshalling.DoubleSerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.data.marshalling.FloatSerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.data.marshalling.Integer64SerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.data.marshalling.IntegerSerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.data.marshalling.UTF8StringSerializerDeserializer;
+import edu.uci.ics.hyracks.storage.am.btree.frames.BTreeNSMInteriorFrameFactory;
+import edu.uci.ics.hyracks.storage.am.btree.frames.BTreeNSMLeafFrameFactory;
+import edu.uci.ics.hyracks.storage.am.btree.impls.BTree;
+import edu.uci.ics.hyracks.storage.am.common.api.IFreePageManager;
+import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexFrameFactory;
+import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexMetaDataFrameFactory;
+import edu.uci.ics.hyracks.storage.am.common.frames.LIFOMetaDataFrameFactory;
+import edu.uci.ics.hyracks.storage.am.common.freepage.LinkedListFreePageManager;
+import edu.uci.ics.hyracks.storage.am.common.ophelpers.MultiComparator;
+import edu.uci.ics.hyracks.storage.am.common.tuples.TypeAwareTupleWriterFactory;
+import edu.uci.ics.hyracks.storage.common.buffercache.IBufferCache;
+
+public class BTreeTestUtils {
+    public static void createIntTuple(ArrayTupleBuilder tupleBuilder, ArrayTupleReference tuple, final int... fields)
+            throws HyracksDataException {
+        DataOutput dos = tupleBuilder.getDataOutput();
+        tupleBuilder.reset();
+        for (final int i : fields) {
+            IntegerSerializerDeserializer.INSTANCE.serialize(i, dos);
+            tupleBuilder.addFieldEndOffset();
+        }
+        tuple.reset(tupleBuilder.getFieldEndOffsets(), tupleBuilder.getByteArray());
+    }
+    public static void createStringTuple(ArrayTupleBuilder tupleBuilder, ArrayTupleReference tuple, final String... fields)
+            throws HyracksDataException {
+        DataOutput dos = tupleBuilder.getDataOutput();
+        tupleBuilder.reset();
+        for (final String s : fields) {
+            UTF8StringSerializerDeserializer.INSTANCE.serialize(s, dos);
+            tupleBuilder.addFieldEndOffset();
+        }
+        tuple.reset(tupleBuilder.getFieldEndOffsets(), tupleBuilder.getByteArray());
+    }
+    
+    public static BTree createBTree(IBufferCache bufferCache, int btreeFileId, ITypeTrait[] typeTraits, IBinaryComparator[] cmps) {
+        MultiComparator cmp = new MultiComparator(typeTraits, cmps);
+        TypeAwareTupleWriterFactory tupleWriterFactory = new TypeAwareTupleWriterFactory(typeTraits);
+        ITreeIndexFrameFactory leafFrameFactory = new BTreeNSMLeafFrameFactory(tupleWriterFactory);        
+        ITreeIndexFrameFactory interiorFrameFactory = new BTreeNSMInteriorFrameFactory(tupleWriterFactory);
+        ITreeIndexMetaDataFrameFactory metaFrameFactory = new LIFOMetaDataFrameFactory();
+        IFreePageManager freePageManager = new LinkedListFreePageManager(bufferCache, btreeFileId, 0, metaFrameFactory);
+        BTree btree = new BTree(bufferCache, freePageManager, interiorFrameFactory, leafFrameFactory, cmp);
+        return btree;
+    }
+    
+    @SuppressWarnings("rawtypes") 
+    public static ITypeTrait[] serdesToTypeTraits(ISerializerDeserializer[] serdes) {
+        ITypeTrait[] typeTraits = new ITypeTrait[serdes.length];
+        for (int i = 0; i < serdes.length; i++) {
+            ISerializerDeserializer serde = serdes[i];
+            if (serde instanceof IntegerSerializerDeserializer) {
+                typeTraits[i] = ITypeTrait.INTEGER_TYPE_TRAIT;
+                continue;
+            }
+            if (serde instanceof Integer64SerializerDeserializer) {
+                typeTraits[i] = ITypeTrait.INTEGER64_TYPE_TRAIT;
+                continue;
+            }
+            if (serde instanceof FloatSerializerDeserializer) {
+                typeTraits[i] = ITypeTrait.FLOAT_TYPE_TRAIT;
+                continue;
+            }
+            if (serde instanceof DoubleSerializerDeserializer) {
+                typeTraits[i] = ITypeTrait.DOUBLE_TYPE_TRAIT;
+                continue;
+            }
+            if (serde instanceof BooleanSerializerDeserializer) {
+                typeTraits[i] = ITypeTrait.BOOLEAN_TYPE_TRAIT;
+                continue;
+            }
+            typeTraits[i] = ITypeTrait.VARLEN_TYPE_TRAIT;
+        }
+        return typeTraits;
+    }
+}
diff --git a/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/btree/InsertTest.java b/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/btree/InsertTest.java
index 634a057..205527e 100644
--- a/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/btree/InsertTest.java
+++ b/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/btree/InsertTest.java
@@ -1,28 +1,199 @@
 package edu.uci.ics.hyracks.storage.am.btree;
 
-import org.junit.After;
-import org.junit.Before;
+import java.util.Random;
+
 import org.junit.Test;
 
-public class InsertTest {
+import edu.uci.ics.hyracks.api.dataflow.value.IBinaryComparator;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.api.dataflow.value.ITypeTrait;
+import edu.uci.ics.hyracks.dataflow.common.comm.io.ArrayTupleBuilder;
+import edu.uci.ics.hyracks.dataflow.common.comm.io.ArrayTupleReference;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ITupleReference;
+import edu.uci.ics.hyracks.dataflow.common.data.comparators.IntegerBinaryComparatorFactory;
+import edu.uci.ics.hyracks.dataflow.common.data.marshalling.IntegerSerializerDeserializer;
+import edu.uci.ics.hyracks.storage.am.btree.api.IBTreeInteriorFrame;
+import edu.uci.ics.hyracks.storage.am.btree.api.IBTreeLeafFrame;
+import edu.uci.ics.hyracks.storage.am.btree.impls.BTree;
+import edu.uci.ics.hyracks.storage.am.btree.impls.BTreeOpContext;
+import edu.uci.ics.hyracks.storage.am.btree.impls.BTreeRangeSearchCursor;
+import edu.uci.ics.hyracks.storage.am.btree.impls.RangePredicate;
+import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexCursor;
+import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexMetaDataFrame;
+import edu.uci.ics.hyracks.storage.am.common.api.TreeIndexException;
+import edu.uci.ics.hyracks.storage.am.common.impls.TreeDiskOrderScanCursor;
+import edu.uci.ics.hyracks.storage.am.common.ophelpers.IndexOp;
 
-    @Before
-    public void setUp() {
-        System.out.println("Setup");
-    }
-
-    @After
-    public void tearDown() {
-        System.out.println("Teardown");
-    }
+public class InsertTest extends AbstractBTreeTest {
     
     @Test
-    public void test() {
-        System.out.println("Test");
+    public void test() throws Exception {
+        LOGGER.info("FIXED-LENGTH KEY TEST");
+
+        // declare fields
+        ISerializerDeserializer[] fieldSerdes = { IntegerSerializerDeserializer.INSTANCE, IntegerSerializerDeserializer.INSTANCE };
+        int fieldCount = fieldSerdes.length;
+        ITypeTrait[] typeTraits = BTreeTestUtils.serdesToTypeTraits(fieldSerdes);
+
+        // declare keys
+        int keyFieldCount = 1;
+        IBinaryComparator[] cmps = new IBinaryComparator[keyFieldCount];
+        cmps[0] = IntegerBinaryComparatorFactory.INSTANCE.createBinaryComparator();
+
+        BTree btree = BTreeTestUtils.createBTree(bufferCache, btreeFileId, typeTraits, cmps);
+        
+        IBTreeLeafFrame leafFrame = (IBTreeLeafFrame) btree.getLeafFrameFactory().createFrame();
+        IBTreeInteriorFrame interiorFrame = (IBTreeInteriorFrame) btree.getInteriorFrameFactory().createFrame();
+        ITreeIndexMetaDataFrame metaFrame = btree.getFreePageManager().getMetaDataFrameFactory().createFrame();
+        
+        btree.create(btreeFileId, leafFrame, metaFrame);
+        btree.open(btreeFileId);
+        
+        Random rnd = new Random();
+        rnd.setSeed(50);
+
+        long start = System.currentTimeMillis();
+
+        LOGGER.info("INSERTING INTO TREE");
+
+        ArrayTupleBuilder tupleBuilder = new ArrayTupleBuilder(fieldCount);
+        ArrayTupleReference tuple = new ArrayTupleReference();
+
+        BTreeOpContext insertOpCtx = btree.createOpContext(IndexOp.INSERT, leafFrame, interiorFrame, metaFrame);
+
+        // 10000
+        for (int i = 0; i < 10000; i++) {
+            int f0 = rnd.nextInt() % 10000;
+            int f1 = 5;
+
+            BTreeTestUtils.createIntTuple(tupleBuilder, tuple, f0, f1);
+            
+            if (i % 1000 == 0) {
+                long end = System.currentTimeMillis();
+                LOGGER.info("INSERTING " + i + " : " + f0 + " " + f1 + " " + (end - start));
+            }
+
+            try {
+                btree.insert(tuple, insertOpCtx);
+            } catch (TreeIndexException e) {
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+        // btree.printTree(leafFrame, interiorFrame);
+
+        int maxPage = btree.getFreePageManager().getMaxPage(metaFrame);
+        LOGGER.info("MAXPAGE: " + maxPage);
+        LOGGER.info(btree.printStats());
+
+        long end = System.currentTimeMillis();
+        long duration = end - start;
+        LOGGER.info("DURATION: " + duration);
+
+        // ordered scan
+
+        LOGGER.info("ORDERED SCAN:");
+        ITreeIndexCursor scanCursor = new BTreeRangeSearchCursor(leafFrame);
+        RangePredicate nullPred = new RangePredicate(true, null, null, true, true, null, null);
+        BTreeOpContext searchOpCtx = btree.createOpContext(IndexOp.SEARCH, leafFrame, interiorFrame, null);
+        btree.search(scanCursor, nullPred, searchOpCtx);
+        try {
+            while (scanCursor.hasNext()) {
+                scanCursor.next();
+                ITupleReference frameTuple = scanCursor.getTuple();
+                String rec = btree.getMultiComparator().printTuple(frameTuple, fieldSerdes);
+                LOGGER.info(rec);
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            scanCursor.close();
+        }
+
+        // disk-order scan
+        LOGGER.info("DISK-ORDER SCAN:");
+        TreeDiskOrderScanCursor diskOrderCursor = new TreeDiskOrderScanCursor(leafFrame);
+        BTreeOpContext diskOrderScanOpCtx = btree.createOpContext(IndexOp.DISKORDERSCAN, leafFrame, null, null);
+        btree.diskOrderScan(diskOrderCursor, leafFrame, metaFrame, diskOrderScanOpCtx);
+        try {
+            while (diskOrderCursor.hasNext()) {
+                diskOrderCursor.next();
+                ITupleReference frameTuple = diskOrderCursor.getTuple();
+                String rec = btree.getMultiComparator().printTuple(frameTuple, fieldSerdes);
+                LOGGER.info(rec);
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            diskOrderCursor.close();
+        }
+
+        /*
+        // range search in [-1000, 1000]
+        LOGGER.info("RANGE SEARCH:");
+
+        ITreeIndexCursor rangeCursor = new BTreeRangeSearchCursor(leafFrame);
+
+        // build low and high keys
+        ArrayTupleBuilder ktb = new ArrayTupleBuilder(cmp.getKeyFieldCount());
+        DataOutput kdos = ktb.getDataOutput();
+
+        ISerializerDeserializer[] keyDescSers = { IntegerSerializerDeserializer.INSTANCE };
+        RecordDescriptor keyDesc = new RecordDescriptor(keyDescSers);
+        IFrameTupleAccessor keyAccessor = new FrameTupleAccessor(ctx.getFrameSize(), keyDesc);
+        keyAccessor.reset(frame);
+
+        appender.reset(frame, true);
+
+        // build and append low key
+        ktb.reset();
+        IntegerSerializerDeserializer.INSTANCE.serialize(-1000, kdos);
+        ktb.addFieldEndOffset();
+        appender.append(ktb.getFieldEndOffsets(), ktb.getByteArray(), 0, ktb.getSize());
+
+        // build and append high key
+        ktb.reset();
+        IntegerSerializerDeserializer.INSTANCE.serialize(1000, kdos);
+        ktb.addFieldEndOffset();
+        appender.append(ktb.getFieldEndOffsets(), ktb.getByteArray(), 0, ktb.getSize());
+
+        // create tuplereferences for search keys
+        FrameTupleReference lowKey = new FrameTupleReference();
+        lowKey.reset(keyAccessor, 0);
+
+        FrameTupleReference highKey = new FrameTupleReference();
+        highKey.reset(keyAccessor, 1);
+
+        IBinaryComparator[] searchCmps = new IBinaryComparator[1];
+        searchCmps[0] = IntegerBinaryComparatorFactory.INSTANCE.createBinaryComparator();
+        MultiComparator searchCmp = new MultiComparator(typeTraits, searchCmps);
+
+        RangePredicate rangePred = new RangePredicate(true, lowKey, highKey, true, true, searchCmp, searchCmp);
+        btree.search(rangeCursor, rangePred, searchOpCtx);
+
+        try {
+            while (rangeCursor.hasNext()) {
+                rangeCursor.next();
+                ITupleReference frameTuple = rangeCursor.getTuple();
+                String rec = cmp.printTuple(frameTuple, recDescSers);
+                LOGGER.info(rec);
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            rangeCursor.close();
+        }
+
+        btree.close();
+        bufferCache.closeFile(fileId);
+        bufferCache.close();
+        */
+        
+        btree.close();
     }
     
     @Test
     public void test2() {
         System.out.println("Test 2");
-    }
+    }       
 }