Added latches to the tree

git-svn-id: https://hyracks.googlecode.com/svn/branches/hyracks_indexes@377 123451ca-8445-de46-9d55-352943316053
diff --git a/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/api/IRTreeFrame.java b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/api/IRTreeFrame.java
index 6cfa40e..c8f5231 100644
--- a/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/api/IRTreeFrame.java
+++ b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/api/IRTreeFrame.java
@@ -9,10 +9,7 @@
 public interface IRTreeFrame extends ITreeIndexFrame {
 
     public int getChildPageId(ITupleReference tuple, MultiComparator cmp);
-    
-    public int split(IRTreeFrame rightFrame, ITupleReference tuple, MultiComparator cmp, RTreeSplitKey leftSplitKey,
-            RTreeSplitKey rightSplitKey) throws Exception;
-    
+
     public void adjustNode(ITreeIndexTupleReference[] tuples, MultiComparator cmp);
 
     public void adjustTuple(ITupleReference tuple, MultiComparator cmp);
diff --git a/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/NSMRTreeFrame.java b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/NSMRTreeFrame.java
index 61af92b..9c37434 100644
--- a/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/NSMRTreeFrame.java
+++ b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/frames/NSMRTreeFrame.java
@@ -33,7 +33,7 @@
             this.tuples[i] = tupleWriter.createTupleReference();
         }
     }
-    
+
     public ITreeIndexTupleReference[] getTuples() {
         return tuples;
     }
@@ -61,9 +61,10 @@
     }
 
     @Override
-    public int split(IRTreeFrame rightFrame, ITupleReference tuple, MultiComparator cmp, RTreeSplitKey leftSplitKey,
-            RTreeSplitKey rightSplitKey) throws Exception {
+    public int split(ITreeIndexFrame rightFrame, ITupleReference tuple, MultiComparator cmp, ISplitKey splitKey)
+            throws Exception {
 
+        RTreeSplitKey rTreeSplitKey = ((RTreeSplitKey) splitKey);
         RTreeTypeAwareTupleWriter rTreeTupleWriterLeftFrame = ((RTreeTypeAwareTupleWriter) tupleWriter);
         RTreeTypeAwareTupleWriter rTreeTupleWriterRightFrame = ((RTreeTypeAwareTupleWriter) rightFrame.getTupleWriter());
         frameTuple.setFieldCount(cmp.getFieldCount());
@@ -74,7 +75,7 @@
 
         int tuplesToLeft;
         int mid = tupleCount / 2;
-        IRTreeFrame targetFrame = null;
+        ITreeIndexFrame targetFrame = null;
         int tupleOff = slotManager.getTupleOff(slotManager.getSlotOff(mid));
         frameTuple.resetByTupleOffset(buf, tupleOff);
         if (cmp.compare(tuple, frameTuple) >= 0) {
@@ -113,15 +114,15 @@
         frameTuple.resetByTupleOffset(buf, tupleOff);
 
         int splitKeySize = tupleWriter.bytesRequired(frameTuple, 0, cmp.getKeyFieldCount());
-        leftSplitKey.initData(splitKeySize);
+        splitKey.initData(splitKeySize);
         this.adjustNode(tuples, cmp);
-        rTreeTupleWriterLeftFrame.writeTupleFields(tuples, 0, leftSplitKey.getBuffer(), 0);
-        leftSplitKey.getTuple().resetByTupleOffset(leftSplitKey.getBuffer(), 0);
+        rTreeTupleWriterLeftFrame.writeTupleFields(tuples, 0, rTreeSplitKey.getLeftPageBuffer(), 0);
+        rTreeSplitKey.getLeftTuple().resetByTupleOffset(rTreeSplitKey.getLeftPageBuffer(), 0);
 
-        rightSplitKey.initData(splitKeySize);
-        rightFrame.adjustNode(((NSMRTreeFrame) rightFrame).getTuples(), cmp);
-        rTreeTupleWriterRightFrame.writeTupleFields(((NSMRTreeFrame) rightFrame).getTuples(), 0, rightSplitKey.getBuffer(), 0);
-        rightSplitKey.getTuple().resetByTupleOffset(rightSplitKey.getBuffer(), 0);
+        ((IRTreeFrame) rightFrame).adjustNode(((NSMRTreeFrame) rightFrame).getTuples(), cmp);
+        rTreeTupleWriterRightFrame.writeTupleFields(((NSMRTreeFrame) rightFrame).getTuples(), 0,
+                rTreeSplitKey.getRightPageBuffer(), 0);
+        rTreeSplitKey.getRightTuple().resetByTupleOffset(rTreeSplitKey.getRightPageBuffer(), 0);
 
         return 0;
     }
@@ -282,11 +283,4 @@
             }
         }
     }
-
-    @Override
-    public int split(ITreeIndexFrame rightFrame, ITupleReference tuple, MultiComparator cmp, ISplitKey splitKey)
-            throws Exception {
-        // TODO Auto-generated method stub
-        return 0;
-    }
 }
diff --git a/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/impls/RTree.java b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/impls/RTree.java
index ca7404a..573aea2 100644
--- a/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/impls/RTree.java
+++ b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/impls/RTree.java
@@ -5,6 +5,7 @@
 import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
 import edu.uci.ics.hyracks.dataflow.common.data.accessors.ITupleReference;
 import edu.uci.ics.hyracks.dataflow.common.data.marshalling.DoubleSerializerDeserializer;
+import edu.uci.ics.hyracks.storage.am.btree.api.IBTreeLeafFrame;
 import edu.uci.ics.hyracks.storage.am.common.api.IFreePageManager;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexMetaDataFrame;
 import edu.uci.ics.hyracks.storage.am.common.frames.FrameOpSpaceStatus;
@@ -33,6 +34,12 @@
     private final MultiComparator interiorCmp;
     private final MultiComparator leafCmp;
 
+    public int rootSplits = 0;
+    public int[] splitsByLevel = new int[500];
+    public long readLatchesAcquired = 0;
+    public long readLatchesReleased = 0;
+    public long writeLatchesAcquired = 0;
+    public long writeLatchesReleased = 0;
     public long pins = 0;
     public long unpins = 0;
     public byte currentLevel = 0;
@@ -47,6 +54,20 @@
         this.leafCmp = leafCmp;
     }
 
+    public String printStats() {
+        StringBuilder strBuilder = new StringBuilder();
+        strBuilder.append("\n");
+        strBuilder.append("ROOTSPLITS: " + rootSplits + "\n");
+        strBuilder.append("SPLITS BY LEVEL\n");
+        for (int i = 0; i < currentLevel; i++) {
+            strBuilder.append(String.format("%3d ", i) + String.format("%8d ", splitsByLevel[i]) + "\n");
+        }
+        strBuilder.append(String.format("READ LATCHES:  %10d %10d\n", readLatchesAcquired, readLatchesReleased));
+        strBuilder.append(String.format("WRITE LATCHES: %10d %10d\n", writeLatchesAcquired, writeLatchesReleased));
+        strBuilder.append(String.format("PINS:          %10d %10d\n", pins, unpins));
+        return strBuilder.toString();
+    }
+
     public void printTree(IRTreeFrame leafFrame, IRTreeFrame interiorFrame, ISerializerDeserializer[] fields)
             throws Exception {
         printTree(rootPage, null, false, leafFrame, interiorFrame, fields);
@@ -57,9 +78,13 @@
 
         ICachedPage node = bufferCache.pin(BufferedFileHandle.getDiskPageId(fileId, pageId), false);
         pins++;
+        node.acquireReadLatch();
+        readLatchesAcquired++;
 
         try {
             if (parent != null && unpin == true) {
+                parent.releaseReadLatch();
+                readLatchesReleased++;
                 bufferCache.unpin(parent);
                 unpins++;
             }
@@ -83,17 +108,18 @@
             System.out.format(keyString);
             if (!interiorFrame.isLeaf()) {
                 ArrayList<Integer> children = ((NSMRTreeFrame) (interiorFrame)).getChildren(interiorCmp);
-
-                //System.out.println("num of children for page id " + pageId + " is: "+ children.size());
                 for (int i = 0; i < children.size(); i++) {
                     printTree(children.get(i), node, i == children.size() - 1, leafFrame, interiorFrame, fields);
                 }
-                //System.out.println();
             } else {
+                node.releaseReadLatch();
+                readLatchesReleased++;
                 bufferCache.unpin(node);
                 unpins++;
             }
         } catch (Exception e) {
+            node.releaseReadLatch();
+            readLatchesReleased++;
             bufferCache.unpin(node);
             unpins++;
             e.printStackTrace();
@@ -101,35 +127,33 @@
     }
 
     public void create(int fileId, IRTreeFrame leafFrame, ITreeIndexMetaDataFrame metaFrame) throws Exception {
+
         if (created)
             return;
 
-        // initialize meta data page
-        ICachedPage metaNode = bufferCache.pin(BufferedFileHandle.getDiskPageId(fileId, metaDataPage), false);
-        pins++;
+        // check if another thread beat us to it
+        if (created)
+            return;
 
-        metaNode.acquireWriteLatch();
-        try {
-            metaFrame.setPage(metaNode);
-            metaFrame.initBuffer((byte) -1);
-            metaFrame.setMaxPage(rootPage);
-        } finally {
-            bufferCache.unpin(metaNode);
-            unpins++;
-        }
+        freePageManager.init(metaFrame, rootPage);
 
         // initialize root page
         ICachedPage rootNode = bufferCache.pin(BufferedFileHandle.getDiskPageId(fileId, rootPage), true);
         pins++;
 
+        rootNode.acquireWriteLatch();
+        writeLatchesAcquired++;
         try {
             leafFrame.setPage(rootNode);
             leafFrame.initBuffer((byte) 0);
         } finally {
+            rootNode.releaseWriteLatch();
+            writeLatchesReleased++;
             bufferCache.unpin(rootNode);
             unpins++;
         }
         currentLevel = 0;
+
         created = true;
     }
 
@@ -148,20 +172,31 @@
     }
 
     private void createNewRoot(RTreeOpContext ctx) throws Exception {
+        rootSplits++; // debug
+        splitsByLevel[currentLevel]++;
         currentLevel++;
 
         // make sure the root is always at the same level
-        ICachedPage leftNode = bufferCache.pin(BufferedFileHandle.getDiskPageId(fileId, ctx.leftSplitKey.getPage()),
+        ICachedPage leftNode = bufferCache.pin(BufferedFileHandle.getDiskPageId(fileId, ctx.splitKey.getLeftPage()),
                 false);
         pins++;
+        leftNode.acquireWriteLatch(); // TODO: think about whether latching is
+                                      // really required
+        writeLatchesAcquired++;
         try {
             ICachedPage rightNode = bufferCache.pin(
-                    BufferedFileHandle.getDiskPageId(fileId, ctx.rightSplitKey.getPage()), false);
+                    BufferedFileHandle.getDiskPageId(fileId, ctx.splitKey.getRightPage()), false);
             pins++;
+            rightNode.acquireWriteLatch(); // TODO: think about whether latching
+                                           // is really required
+            writeLatchesAcquired++;
             try {
                 int newLeftId = freePageManager.getFreePage(ctx.metaFrame);
                 ICachedPage newLeftNode = bufferCache.pin(BufferedFileHandle.getDiskPageId(fileId, newLeftId), true);
                 pins++;
+                newLeftNode.acquireWriteLatch(); // TODO: think about whether
+                                                 // latching is really required
+                writeLatchesAcquired++;
                 try {
                     // copy left child to new left child
                     System.arraycopy(leftNode.getBuffer().array(), 0, newLeftNode.getBuffer().array(), 0, newLeftNode
@@ -171,44 +206,51 @@
                     ctx.interiorFrame.setPage(leftNode);
                     ctx.interiorFrame.initBuffer((byte) (ctx.interiorFrame.getLevel() + 1));
 
-                    ctx.leftSplitKey.setPage(newLeftId);
-                    
-                    ctx.interiorFrame.insert(ctx.leftSplitKey.getTuple(), interiorCmp);
-                    ctx.interiorFrame.insert(ctx.rightSplitKey.getTuple(), interiorCmp);
+                    ctx.splitKey.setLeftPage(newLeftId);
 
-                    //System.out.println("R Created page id: " + newLeftId + "level: " + ctx.interiorFrame.getLevel());
-                    
-                    System.out.println("Created new root");
-
+                    ctx.interiorFrame.insert(ctx.splitKey.getLeftTuple(), interiorCmp);
+                    ctx.interiorFrame.insert(ctx.splitKey.getRightTuple(), interiorCmp);
                 } finally {
+                    newLeftNode.releaseWriteLatch();
+                    writeLatchesReleased++;
                     bufferCache.unpin(newLeftNode);
                     unpins++;
                 }
             } finally {
+                rightNode.releaseWriteLatch();
+                writeLatchesReleased++;
                 bufferCache.unpin(rightNode);
                 unpins++;
             }
         } finally {
+            leftNode.releaseWriteLatch();
+            writeLatchesReleased++;
             bufferCache.unpin(leftNode);
             unpins++;
         }
     }
 
-    public int temp = 0;
+    private final void acquireLatch(ICachedPage node, TreeIndexOp op, boolean isLeaf) {
+        if (isLeaf && (op.equals(TreeIndexOp.TI_INSERT) || op.equals(TreeIndexOp.TI_DELETE))) {
+            node.acquireWriteLatch();
+            writeLatchesAcquired++;
+        } else {
+            node.acquireReadLatch();
+            readLatchesAcquired++;
+        }
+    }
 
     public void insert(ITupleReference tuple, RTreeOpContext ctx) throws Exception {
         ctx.reset();
         ctx.setTuple(tuple);
-        ctx.leftSplitKey.reset();
-        ctx.rightSplitKey.reset();
-        ctx.leftSplitKey.getTuple().setFieldCount(interiorCmp.getFieldCount());
-        ctx.rightSplitKey.getTuple().setFieldCount(interiorCmp.getFieldCount());
+        ctx.splitKey.reset();
+        ctx.splitKey.getLeftTuple().setFieldCount(interiorCmp.getFieldCount());
+        ctx.splitKey.getRightTuple().setFieldCount(interiorCmp.getFieldCount());
         ctx.interiorFrame.setPageTupleFieldCount(interiorCmp.getFieldCount());
-        temp++;
         insertImpl(rootPage, null, (byte) 0, ctx);
 
         // we split the root, here is the key for a new root
-        if (ctx.leftSplitKey.getBuffer() != null && ctx.rightSplitKey.getBuffer() != null) {
+        if (ctx.splitKey.getLeftPageBuffer() != null) {
             createNewRoot(ctx);
         }
     }
@@ -217,38 +259,37 @@
         ICachedPage node = bufferCache.pin(BufferedFileHandle.getDiskPageId(fileId, pageId), false);
         pins++;
         ctx.interiorFrame.setPage(node);
+        boolean isLeaf = ctx.interiorFrame.isLeaf();
+        acquireLatch(node, ctx.op, isLeaf);
 
         // latch coupling TODO: check the correctness of this
         if (parent != null) {
+            parent.releaseReadLatch();
+            readLatchesReleased++;
             bufferCache.unpin(parent);
             unpins++;
         }
-        if (temp >= 36) {
-            //System.out.println("HHHHHHHHHHHHHH");
-        }
-        boolean isLeaf = ctx.interiorFrame.isLeaf();
-        //System.out.println("level: " + ctx.interiorFrame.getLevel());
+
         // the children pointers in the node point to leaves
         if (ctx.interiorFrame.getLevel() > desiredLevel) {
             int childPageId = ctx.interiorFrame.getChildPageId(ctx.getTuple(), interiorCmp);
-            //System.out.println("PAGE ID: " + childPageId);
             insertImpl(childPageId, node, desiredLevel, ctx);
 
-            if (ctx.leftSplitKey.getBuffer() != null && ctx.rightSplitKey.getBuffer() != null) { // TODO:
-                                                                                                 // checking
-                                                                                                 // one
-                                                                                                 // is
-                                                                                                 // enough?
+            if (ctx.splitKey.getLeftPageBuffer() != null) {
                 node = bufferCache.pin(BufferedFileHandle.getDiskPageId(fileId, pageId), false);
                 pins++;
+                node.acquireWriteLatch();
+                writeLatchesAcquired++;
                 try {
                     ctx.interiorFrame.setPage(node);
-                    ctx.interiorFrame.adjustTuple(ctx.leftSplitKey.getTuple(), interiorCmp);
-                    insertTuple(pageId, ctx.rightSplitKey.getTuple(), ctx, isLeaf);
+                    ctx.interiorFrame.adjustTuple(ctx.splitKey.getLeftTuple(), interiorCmp);
+                    insertTuple(pageId, ctx.splitKey.getRightTuple(), ctx, isLeaf);
                     // RTreeSplitKey splitKey =
                     // ctx.rightSplitKey.duplicate(ctx.interiorFrame.getTupleWriter().createTupleReference());
                     // insertTuple(pageId, splitKey.getTuple(), ctx, isLeaf);
                 } finally {
+                    node.releaseWriteLatch();
+                    writeLatchesReleased++;
                     bufferCache.unpin(node);
                     unpins++;
                 }
@@ -261,6 +302,8 @@
                 }
                 insertTuple(pageId, ctx.getTuple(), ctx, isLeaf);
             } finally {
+                node.releaseWriteLatch();
+                writeLatchesReleased++;
                 bufferCache.unpin(node);
                 unpins++;
             }
@@ -282,8 +325,7 @@
                 } else {
                     ctx.leafFrame.insert(tuple, leafCmp);
                 }
-                ctx.leftSplitKey.reset();
-                ctx.rightSplitKey.reset();
+                ctx.splitKey.reset();
                 break;
             }
 
@@ -295,8 +337,7 @@
                     ctx.leafFrame.compact(leafCmp);
                     ctx.leafFrame.insert(tuple, leafCmp);
                 }
-                ctx.leftSplitKey.reset();
-                ctx.rightSplitKey.reset();
+                ctx.splitKey.reset();
                 break;
             }
 
@@ -304,49 +345,44 @@
                 int rightPageId = freePageManager.getFreePage(ctx.metaFrame);
                 ICachedPage rightNode = bufferCache.pin(BufferedFileHandle.getDiskPageId(fileId, rightPageId), true);
                 pins++;
+                rightNode.acquireWriteLatch();
+                writeLatchesAcquired++;
 
                 try {
                     IRTreeFrame rightFrame;
                     int ret;
                     if (!isLeaf) {
+                        splitsByLevel[ctx.interiorFrame.getLevel()]++; // debug
                         rightFrame = interiorFrameFactory.getFrame();
                         rightFrame.setPage(rightNode);
                         rightFrame.initBuffer((byte) ctx.interiorFrame.getLevel());
                         rightFrame.setPageTupleFieldCount(interiorCmp.getFieldCount());
-                        ret = ctx.interiorFrame.split(rightFrame, tuple, interiorCmp, ctx.leftSplitKey,
-                                ctx.rightSplitKey);
+                        ret = ctx.interiorFrame.split(rightFrame, tuple, interiorCmp, ctx.splitKey);
                         rightFrame.setPageLsn(rightFrame.getPageLsn() + 1);
                         ctx.interiorFrame.setPageLsn(ctx.interiorFrame.getPageLsn() + 1);
-
-//                         System.out.println("I Created page id: " +
-//                         rightPageId + "level: "
-//                         + ctx.interiorFrame.getLevel());
                     } else {
+                        splitsByLevel[0]++; // debug
                         rightFrame = leafFrameFactory.getFrame();
                         rightFrame.setPage(rightNode);
                         rightFrame.initBuffer((byte) 0);
                         rightFrame.setPageTupleFieldCount(leafCmp.getFieldCount());
-                        ret = ctx.leafFrame.split(rightFrame, tuple, leafCmp, ctx.leftSplitKey, ctx.rightSplitKey);
+                        ret = ctx.leafFrame.split(rightFrame, tuple, leafCmp, ctx.splitKey);
                         rightFrame.setPageLsn(rightFrame.getPageLsn() + 1);
                         ctx.leafFrame.setPageLsn(ctx.leafFrame.getPageLsn() + 1);
-
-//                         System.out.println("L Created page id: " +
-//                         rightPageId + "level: " + 0);
                     }
 
                     if (ret != 0) {
-                        ctx.leftSplitKey.reset();
-                        ctx.rightSplitKey.reset();
+                        ctx.splitKey.reset();
                     } else {
-                        ctx.leftSplitKey.setPage(pageId);
-                        ctx.rightSplitKey.setPage(rightPageId);
+                        ctx.splitKey.setPages(pageId, rightPageId);
                     }
 
                 } finally {
+                    rightNode.releaseWriteLatch();
+                    writeLatchesReleased++;
                     bufferCache.unpin(rightNode);
                     unpins++;
                 }
-                // System.out.println("Splitted");
                 break;
             }
         }
diff --git a/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/impls/RTreeOpContext.java b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/impls/RTreeOpContext.java
index 94e16d2..f23eb48 100644
--- a/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/impls/RTreeOpContext.java
+++ b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/impls/RTreeOpContext.java
@@ -11,8 +11,7 @@
     public final IRTreeFrame leafFrame;
     public final ITreeIndexMetaDataFrame metaFrame;
     public final ByteArrayList overflowArray;
-    public final RTreeSplitKey leftSplitKey;
-    public final RTreeSplitKey rightSplitKey;
+    public final RTreeSplitKey splitKey;
     public int insertLevel;
     public ITupleReference tuple;
 
@@ -22,8 +21,8 @@
         this.interiorFrame = interiorFrame;
         this.leafFrame = leafFrame;
         this.metaFrame = metaFrame;
-        leftSplitKey = new RTreeSplitKey(leafFrame.getTupleWriter().createTupleReference());
-        rightSplitKey = new RTreeSplitKey(leafFrame.getTupleWriter().createTupleReference());
+        splitKey = new RTreeSplitKey(leafFrame.getTupleWriter().createTupleReference(), leafFrame.getTupleWriter()
+                .createTupleReference());
         overflowArray = new ByteArrayList(treeHeightHint, treeHeightHint);
     }
 
diff --git a/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/impls/RTreeSplitKey.java b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/impls/RTreeSplitKey.java
index 7c33a9a..b130e18 100644
--- a/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/impls/RTreeSplitKey.java
+++ b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/impls/RTreeSplitKey.java
@@ -2,61 +2,136 @@
 
 import java.nio.ByteBuffer;
 
+import edu.uci.ics.hyracks.storage.am.common.api.ISplitKey;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexTupleReference;
 
-public class RTreeSplitKey {
-    public byte[] data = null;
-    public ByteBuffer buf = null;
-    public ITreeIndexTupleReference tuple;
+public class RTreeSplitKey implements ISplitKey {
+    public byte[] leftPageData = null;
+    public ByteBuffer leftPageBuf = null;
+    public ITreeIndexTupleReference leftTuple;
+
+    public byte[] rightPageData = null;
+    public ByteBuffer rightPageBuf = null;
+    public ITreeIndexTupleReference rightTuple;
+
     public int keySize = 0;
 
-    public RTreeSplitKey(ITreeIndexTupleReference tuple) {
-        this.tuple = tuple;
+    public RTreeSplitKey(ITreeIndexTupleReference leftTuple, ITreeIndexTupleReference rightTuple) {
+        this.leftTuple = leftTuple;
+        this.rightTuple = rightTuple;
     }
 
     public void initData(int keySize) {
         // try to reuse existing memory from a lower-level split if possible
         this.keySize = keySize;
-        if (data != null) {
-            if (data.length < keySize + 4) {
-                data = new byte[keySize + 4]; // add 4 for the page
-                buf = ByteBuffer.wrap(data);
+        if (leftPageData != null) {
+            if (leftPageData.length < keySize + 4) {
+                leftPageData = new byte[keySize + 4]; // add 4 for the page
+                leftPageBuf = ByteBuffer.wrap(leftPageData);
             }
         } else {
-            data = new byte[keySize + 4]; // add 4 for the page
-            buf = ByteBuffer.wrap(data);
+            leftPageData = new byte[keySize + 4]; // add 4 for the page
+            leftPageBuf = ByteBuffer.wrap(leftPageData);
+        }
+        if (rightPageData != null) {
+            if (rightPageData.length < keySize + 4) {
+                rightPageData = new byte[keySize + 4]; // add 4 for the page
+                rightPageBuf = ByteBuffer.wrap(rightPageData);
+            }
+        } else {
+            rightPageData = new byte[keySize + 4]; // add 4 for the page
+            rightPageBuf = ByteBuffer.wrap(rightPageData);
         }
 
-        tuple.resetByTupleOffset(buf, 0);
+        leftTuple.resetByTupleOffset(leftPageBuf, 0);
+        rightTuple.resetByTupleOffset(rightPageBuf, 0);
     }
 
-    public void reset() {
-        data = null;
-        buf = null;
+    public void resetLeftPage() {
+        leftPageData = null;
+        leftPageBuf = null;
     }
 
-    public ByteBuffer getBuffer() {
-        return buf;
+    public void resetRightPage() {
+        rightPageData = null;
+        rightPageBuf = null;
     }
 
-    public ITreeIndexTupleReference getTuple() {
-        return tuple;
+    public ByteBuffer getLeftPageBuffer() {
+        return leftPageBuf;
     }
 
-    public int getPage() {
-        return buf.getInt(keySize);
+    public ByteBuffer getRightPageBuffer() {
+        return rightPageBuf;
     }
 
-    public void setPage(int Page) {
-        buf.putInt(keySize, Page);
+    public ITreeIndexTupleReference getLeftTuple() {
+        return leftTuple;
     }
 
-    public RTreeSplitKey duplicate(ITreeIndexTupleReference copyTuple) {
-        RTreeSplitKey copy = new RTreeSplitKey(copyTuple);
-        copy.data = data.clone();
-        copy.buf = ByteBuffer.wrap(copy.data);
-        copy.tuple.setFieldCount(tuple.getFieldCount());
-        copy.tuple.resetByTupleOffset(copy.buf, 0);
+    public ITreeIndexTupleReference getRightTuple() {
+        return rightTuple;
+    }
+
+    public int getLeftPage() {
+        return leftPageBuf.getInt(keySize);
+    }
+
+    public int getRightPage() {
+        return rightPageBuf.getInt(keySize);
+    }
+
+    public void setLeftPage(int page) {
+        leftPageBuf.putInt(keySize, page);
+    }
+
+    public void setRightPage(int page) {
+        rightPageBuf.putInt(keySize, page);
+    }
+
+    public ISplitKey duplicate(ITreeIndexTupleReference copyLeftTuple, ITreeIndexTupleReference copyRightTuple) {
+        RTreeSplitKey copy = new RTreeSplitKey(copyLeftTuple, copyRightTuple);
+        copy.leftPageData = leftPageData.clone();
+        copy.leftPageBuf = ByteBuffer.wrap(copy.leftPageData);
+        copy.leftTuple.setFieldCount(leftTuple.getFieldCount());
+        copy.leftTuple.resetByTupleOffset(copy.leftPageBuf, 0);
+
+        copy.rightPageData = rightPageData.clone();
+        copy.rightPageBuf = ByteBuffer.wrap(copy.rightPageData);
+        copy.rightTuple.setFieldCount(rightTuple.getFieldCount());
+        copy.rightTuple.resetByTupleOffset(copy.rightPageBuf, 0);
         return copy;
     }
+
+    @Override
+    public void reset() {
+        leftPageData = null;
+        leftPageBuf = null;
+        rightPageData = null;
+        rightPageBuf = null;
+    }
+
+    @Override
+    public ByteBuffer getBuffer() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public ITreeIndexTupleReference getTuple() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public void setPages(int leftPage, int rightPage) {
+        leftPageBuf.putInt(keySize, leftPage);
+        rightPageBuf.putInt(keySize, rightPage);
+    }
+
+    @Override
+    public ISplitKey duplicate(ITreeIndexTupleReference copyTuple) {
+        // TODO Auto-generated method stub
+        return null;
+    }
 }
\ No newline at end of file
diff --git a/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/tuples/RTreeTypeAwareTupleWriter.java b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/tuples/RTreeTypeAwareTupleWriter.java
index f512cc8..e932624 100644
--- a/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/tuples/RTreeTypeAwareTupleWriter.java
+++ b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/tuples/RTreeTypeAwareTupleWriter.java
@@ -34,7 +34,7 @@
         // write data
         for (int i = 0; i < refs.length; i++) {
             double d3 = DoubleSerializerDeserializer.getDouble(refs[i].getFieldData(i), refs[i].getFieldStart(i));
-            
+
             System.arraycopy(refs[i].getFieldData(i), refs[i].getFieldStart(i), targetBuf.array(), runner,
                     refs[i].getFieldLength(i));
             runner += refs[i].getFieldLength(i);
diff --git a/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/rtree/RTreeFrameTest.java b/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/rtree/RTreeFrameTest.java
index 01a3989..f93a6b6 100644
--- a/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/rtree/RTreeFrameTest.java
+++ b/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/rtree/RTreeFrameTest.java
@@ -1,166 +1,133 @@
-/*package edu.uci.ics.hyracks.storage.am.rtree;
-
-import java.io.DataOutput;
-import java.io.File;
-import java.nio.ByteBuffer;
-import java.util.Random;
-
-import org.junit.Test;
-
-import edu.uci.ics.hyracks.api.comm.IFrameTupleAccessor;
-import edu.uci.ics.hyracks.api.context.IHyracksStageletContext;
-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.RecordDescriptor;
-import edu.uci.ics.hyracks.api.dataflow.value.TypeTrait;
-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.FrameTupleAccessor;
-import edu.uci.ics.hyracks.dataflow.common.comm.io.FrameTupleAppender;
-import edu.uci.ics.hyracks.dataflow.common.data.accessors.FrameTupleReference;
-import edu.uci.ics.hyracks.dataflow.common.data.comparators.DoubleBinaryComparatorFactory;
-import edu.uci.ics.hyracks.dataflow.common.data.marshalling.DoubleSerializerDeserializer;
-import edu.uci.ics.hyracks.dataflow.common.data.marshalling.IntegerSerializerDeserializer;
-import edu.uci.ics.hyracks.storage.am.btree.impls.MultiComparator;
-import edu.uci.ics.hyracks.storage.am.btree.impls.SpaceStatus;
-import edu.uci.ics.hyracks.storage.am.btree.tuples.TypeAwareTupleWriter;
-import edu.uci.ics.hyracks.storage.am.rtree.frames.NSMRTreeFrame;
-import edu.uci.ics.hyracks.storage.common.buffercache.IBufferCache;
-import edu.uci.ics.hyracks.storage.common.buffercache.ICachedPage;
-import edu.uci.ics.hyracks.storage.common.file.BufferedFileHandle;
-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 class RTreeFrameTest extends AbstractRTreeTest {
-
-    private static final int PAGE_SIZE = 256;
-    private static final int NUM_PAGES = 10;
-    private static final int HYRACKS_FRAME_SIZE = 128;
-    private IHyracksStageletContext ctx = TestUtils.create(HYRACKS_FRAME_SIZE);
-
-    private String tmpDir = System.getProperty("java.io.tmpdir");
-
-    @Test
-    public void frameInsertTest() throws Exception {
-
-        TestStorageManagerComponentHolder.init(PAGE_SIZE, NUM_PAGES);
-        IBufferCache bufferCache = TestStorageManagerComponentHolder
-                .getBufferCache(ctx);
-        IFileMapProvider fmp = TestStorageManagerComponentHolder
-                .getFileMapProvider(ctx);
-        FileReference file = new FileReference(new File(fileName));
-        bufferCache.createFile(file);
-        int fileId = fmp.lookupFileId(file);
-        bufferCache.openFile(fileId);
-
-        // declare fields
-        int fieldCount = 5;
-        ITypeTrait[] typeTraits = new ITypeTrait[fieldCount];
-        typeTraits[0] = new TypeTrait(8);
-        typeTraits[1] = new TypeTrait(8);
-        typeTraits[2] = new TypeTrait(8);
-        typeTraits[3] = new TypeTrait(8);
-        typeTraits[4] = new TypeTrait(4);
-
-        // declare keys
-        int keyFieldCount = 4;
-        IBinaryComparator[] cmps = new IBinaryComparator[keyFieldCount];
-        cmps[0] = DoubleBinaryComparatorFactory.INSTANCE.createBinaryComparator();
-        cmps[1] = cmps[0];
-        cmps[2] = cmps[0];
-        cmps[3] = cmps[0];
-
-        MultiComparator cmp = new MultiComparator(typeTraits, cmps);
-
-        TypeAwareTupleWriter tupleWriter = new TypeAwareTupleWriter(typeTraits);
-        //SimpleTupleWriter tupleWriter = new SimpleTupleWriter();
-        NSMRTreeFrame rtreeFrame = new NSMRTreeFrame(tupleWriter);
-
-        ByteBuffer hyracksFrame = ctx.allocateFrame();
-        FrameTupleAppender appender = new FrameTupleAppender(ctx.getFrameSize());
-        ArrayTupleBuilder tb = new ArrayTupleBuilder(cmp.getFieldCount());
-        DataOutput dos = tb.getDataOutput();
-
-        ISerializerDeserializer[] recDescSers = { DoubleSerializerDeserializer.INSTANCE,
-                DoubleSerializerDeserializer.INSTANCE, DoubleSerializerDeserializer.INSTANCE,
-                DoubleSerializerDeserializer.INSTANCE, DoubleSerializerDeserializer.INSTANCE };
-        RecordDescriptor recDesc = new RecordDescriptor(recDescSers);
-        IFrameTupleAccessor accessor = new FrameTupleAccessor(ctx
-                .getFrameSize(), recDesc);
-        FrameTupleReference tuple = new FrameTupleReference();
-
-        ICachedPage page = bufferCache.pin(BufferedFileHandle.getDiskPageId(fileId, 0), true);
-        try {
-
-            rtreeFrame.setPage(page);
-            rtreeFrame.initBuffer((byte)0);
-
-            // insert some random stuff...
-
-            Random rnd = new Random(50);
-
-            int numInserts = 10;
-            for (int i = 0; i < numInserts; i++) {
-                double p1x = rnd.nextDouble();
-                double p1y = rnd.nextDouble();
-                double p2x = rnd.nextDouble();
-                double p2y = rnd.nextDouble();
-
-                int pk = rnd.nextInt();
-
-                tb.reset();
-                DoubleSerializerDeserializer.INSTANCE.serialize(p1x, dos);
-                tb.addFieldEndOffset();
-                DoubleSerializerDeserializer.INSTANCE.serialize(p1y, dos);
-                tb.addFieldEndOffset();
-                DoubleSerializerDeserializer.INSTANCE.serialize(p2x, dos);
-                tb.addFieldEndOffset();
-                DoubleSerializerDeserializer.INSTANCE.serialize(p2y, dos);
-                tb.addFieldEndOffset();
-                IntegerSerializerDeserializer.INSTANCE.serialize(pk, dos);
-                tb.addFieldEndOffset();
-
-                appender.reset(hyracksFrame, true);
-                appender.append(tb.getFieldEndOffsets(), tb.getByteArray(), 0, tb.getSize());
-
-                tuple.reset(accessor, 0);
-
-                SpaceStatus status = rtreeFrame.hasSpaceInsert(tuple, cmp);
-                switch(status) {
-                    case SUFFICIENT_CONTIGUOUS_SPACE: {
-                        rtreeFrame.insert(tuple, cmp);
-                        break;
-                    }
-                
-                    case SUFFICIENT_SPACE: {
-                        rtreeFrame.compact(cmp);
-                        rtreeFrame.insert(tuple, cmp);
-                        break;
-                    }
-                    
-                    case INSUFFICIENT_SPACE: {
-                        // split
-                        System.out.println("PLEASE STOP, NO MORE SPACE");
-                        break;
-                    }
-                }
-                
-                
-
-                String contents = rtreeFrame.printKeys(cmp, recDescSers);
-                System.out.println(contents);
-
-            }
-        } finally {
-            bufferCache.unpin(page);
-        }
-
-        bufferCache.closeFile(fileId);
-        bufferCache.close();
-
-    }
-
-}
-*/
\ No newline at end of file
+/*
+ * package edu.uci.ics.hyracks.storage.am.rtree;
+ * 
+ * import java.io.DataOutput; import java.io.File; import java.nio.ByteBuffer;
+ * import java.util.Random;
+ * 
+ * import org.junit.Test;
+ * 
+ * import edu.uci.ics.hyracks.api.comm.IFrameTupleAccessor; import
+ * edu.uci.ics.hyracks.api.context.IHyracksStageletContext; 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.RecordDescriptor; import
+ * edu.uci.ics.hyracks.api.dataflow.value.TypeTrait; 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.FrameTupleAccessor; import
+ * edu.uci.ics.hyracks.dataflow.common.comm.io.FrameTupleAppender; import
+ * edu.uci.ics.hyracks.dataflow.common.data.accessors.FrameTupleReference;
+ * import edu.uci.ics.hyracks.dataflow.common.data.comparators.
+ * DoubleBinaryComparatorFactory; import
+ * edu.uci.ics.hyracks.dataflow.common.data
+ * .marshalling.DoubleSerializerDeserializer; import
+ * edu.uci.ics.hyracks.dataflow
+ * .common.data.marshalling.IntegerSerializerDeserializer; import
+ * edu.uci.ics.hyracks.storage.am.btree.impls.MultiComparator; import
+ * edu.uci.ics.hyracks.storage.am.btree.impls.SpaceStatus; import
+ * edu.uci.ics.hyracks.storage.am.btree.tuples.TypeAwareTupleWriter; import
+ * edu.uci.ics.hyracks.storage.am.rtree.frames.NSMRTreeFrame; import
+ * edu.uci.ics.hyracks.storage.common.buffercache.IBufferCache; import
+ * edu.uci.ics.hyracks.storage.common.buffercache.ICachedPage; import
+ * edu.uci.ics.hyracks.storage.common.file.BufferedFileHandle; 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 class RTreeFrameTest extends AbstractRTreeTest {
+ * 
+ * private static final int PAGE_SIZE = 256; private static final int NUM_PAGES
+ * = 10; private static final int HYRACKS_FRAME_SIZE = 128; private
+ * IHyracksStageletContext ctx = TestUtils.create(HYRACKS_FRAME_SIZE);
+ * 
+ * private String tmpDir = System.getProperty("java.io.tmpdir");
+ * 
+ * @Test public void frameInsertTest() throws Exception {
+ * 
+ * TestStorageManagerComponentHolder.init(PAGE_SIZE, NUM_PAGES); IBufferCache
+ * bufferCache = TestStorageManagerComponentHolder .getBufferCache(ctx);
+ * IFileMapProvider fmp = TestStorageManagerComponentHolder
+ * .getFileMapProvider(ctx); FileReference file = new FileReference(new
+ * File(fileName)); bufferCache.createFile(file); int fileId =
+ * fmp.lookupFileId(file); bufferCache.openFile(fileId);
+ * 
+ * // declare fields int fieldCount = 5; ITypeTrait[] typeTraits = new
+ * ITypeTrait[fieldCount]; typeTraits[0] = new TypeTrait(8); typeTraits[1] = new
+ * TypeTrait(8); typeTraits[2] = new TypeTrait(8); typeTraits[3] = new
+ * TypeTrait(8); typeTraits[4] = new TypeTrait(4);
+ * 
+ * // declare keys int keyFieldCount = 4; IBinaryComparator[] cmps = new
+ * IBinaryComparator[keyFieldCount]; cmps[0] =
+ * DoubleBinaryComparatorFactory.INSTANCE.createBinaryComparator(); cmps[1] =
+ * cmps[0]; cmps[2] = cmps[0]; cmps[3] = cmps[0];
+ * 
+ * MultiComparator cmp = new MultiComparator(typeTraits, cmps);
+ * 
+ * TypeAwareTupleWriter tupleWriter = new TypeAwareTupleWriter(typeTraits);
+ * //SimpleTupleWriter tupleWriter = new SimpleTupleWriter(); NSMRTreeFrame
+ * rtreeFrame = new NSMRTreeFrame(tupleWriter);
+ * 
+ * ByteBuffer hyracksFrame = ctx.allocateFrame(); FrameTupleAppender appender =
+ * new FrameTupleAppender(ctx.getFrameSize()); ArrayTupleBuilder tb = new
+ * ArrayTupleBuilder(cmp.getFieldCount()); DataOutput dos = tb.getDataOutput();
+ * 
+ * ISerializerDeserializer[] recDescSers = {
+ * DoubleSerializerDeserializer.INSTANCE, DoubleSerializerDeserializer.INSTANCE,
+ * DoubleSerializerDeserializer.INSTANCE, DoubleSerializerDeserializer.INSTANCE,
+ * DoubleSerializerDeserializer.INSTANCE }; RecordDescriptor recDesc = new
+ * RecordDescriptor(recDescSers); IFrameTupleAccessor accessor = new
+ * FrameTupleAccessor(ctx .getFrameSize(), recDesc); FrameTupleReference tuple =
+ * new FrameTupleReference();
+ * 
+ * ICachedPage page = bufferCache.pin(BufferedFileHandle.getDiskPageId(fileId,
+ * 0), true); try {
+ * 
+ * rtreeFrame.setPage(page); rtreeFrame.initBuffer((byte)0);
+ * 
+ * // insert some random stuff...
+ * 
+ * Random rnd = new Random(50);
+ * 
+ * int numInserts = 10; for (int i = 0; i < numInserts; i++) { double p1x =
+ * rnd.nextDouble(); double p1y = rnd.nextDouble(); double p2x =
+ * rnd.nextDouble(); double p2y = rnd.nextDouble();
+ * 
+ * int pk = rnd.nextInt();
+ * 
+ * tb.reset(); DoubleSerializerDeserializer.INSTANCE.serialize(p1x, dos);
+ * tb.addFieldEndOffset(); DoubleSerializerDeserializer.INSTANCE.serialize(p1y,
+ * dos); tb.addFieldEndOffset();
+ * DoubleSerializerDeserializer.INSTANCE.serialize(p2x, dos);
+ * tb.addFieldEndOffset(); DoubleSerializerDeserializer.INSTANCE.serialize(p2y,
+ * dos); tb.addFieldEndOffset();
+ * IntegerSerializerDeserializer.INSTANCE.serialize(pk, dos);
+ * tb.addFieldEndOffset();
+ * 
+ * appender.reset(hyracksFrame, true); appender.append(tb.getFieldEndOffsets(),
+ * tb.getByteArray(), 0, tb.getSize());
+ * 
+ * tuple.reset(accessor, 0);
+ * 
+ * SpaceStatus status = rtreeFrame.hasSpaceInsert(tuple, cmp); switch(status) {
+ * case SUFFICIENT_CONTIGUOUS_SPACE: { rtreeFrame.insert(tuple, cmp); break; }
+ * 
+ * case SUFFICIENT_SPACE: { rtreeFrame.compact(cmp); rtreeFrame.insert(tuple,
+ * cmp); break; }
+ * 
+ * case INSUFFICIENT_SPACE: { // split
+ * System.out.println("PLEASE STOP, NO MORE SPACE"); break; } }
+ * 
+ * 
+ * 
+ * String contents = rtreeFrame.printKeys(cmp, recDescSers);
+ * System.out.println(contents);
+ * 
+ * } } finally { bufferCache.unpin(page); }
+ * 
+ * bufferCache.closeFile(fileId); bufferCache.close();
+ * 
+ * }
+ * 
+ * }
+ */
\ No newline at end of file
diff --git a/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/rtree/RTreeTest.java b/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/rtree/RTreeTest.java
index f92855c..0e561fa 100644
--- a/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/rtree/RTreeTest.java
+++ b/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/rtree/RTreeTest.java
@@ -52,10 +52,8 @@
     public void test01() throws Exception {
 
         TestStorageManagerComponentHolder.init(PAGE_SIZE, NUM_PAGES);
-        IBufferCache bufferCache = TestStorageManagerComponentHolder
-                .getBufferCache(ctx);
-        IFileMapProvider fmp = TestStorageManagerComponentHolder
-                .getFileMapProvider(ctx);
+        IBufferCache bufferCache = TestStorageManagerComponentHolder.getBufferCache(ctx);
+        IFileMapProvider fmp = TestStorageManagerComponentHolder.getFileMapProvider(ctx);
         FileReference file = new FileReference(new File(fileName));
         bufferCache.createFile(file);
         int fileId = fmp.lookupFileId(file);
@@ -78,7 +76,6 @@
         cmps[2] = cmps[0];
         cmps[3] = cmps[0];
 
-
         // declare leaf-frame-tuple fields
         int leafFieldCount = 5;
         ITypeTrait[] leafTypeTraits = new ITypeTrait[leafFieldCount];
@@ -90,11 +87,11 @@
 
         MultiComparator interiorCmp = new MultiComparator(interiorTypeTraits, cmps);
         MultiComparator leafCmp = new MultiComparator(leafTypeTraits, cmps);
-        
-        
-        RTreeTypeAwareTupleWriterFactory interiorTupleWriterFactory = new RTreeTypeAwareTupleWriterFactory(interiorTypeTraits);
+
+        RTreeTypeAwareTupleWriterFactory interiorTupleWriterFactory = new RTreeTypeAwareTupleWriterFactory(
+                interiorTypeTraits);
         RTreeTypeAwareTupleWriterFactory leafTupleWriterFactory = new RTreeTypeAwareTupleWriterFactory(leafTypeTraits);
-        
+
         IRTreeFrameFactory interiorFrameFactory = new NSMRTreeFrameFactory(interiorTupleWriterFactory);
         IRTreeFrameFactory leafFrameFactory = new NSMRTreeFrameFactory(leafTupleWriterFactory);
         ITreeIndexMetaDataFrameFactory metaFrameFactory = new LIFOMetaDataFrameFactory();
@@ -103,8 +100,9 @@
         IRTreeFrame interiorFrame = interiorFrameFactory.getFrame();
         IRTreeFrame leafFrame = leafFrameFactory.getFrame();
         IFreePageManager freePageManager = new LinkedListFreePageManager(bufferCache, fileId, 0);
-        
-        RTree rtree = new RTree(bufferCache, freePageManager, interiorFrameFactory, leafFrameFactory, interiorCmp, leafCmp);
+
+        RTree rtree = new RTree(bufferCache, freePageManager, interiorFrameFactory, leafFrameFactory, interiorCmp,
+                leafCmp);
         rtree.create(fileId, leafFrame, metaFrame);
         rtree.open(fileId);
 
@@ -118,31 +116,22 @@
                 DoubleSerializerDeserializer.INSTANCE, DoubleSerializerDeserializer.INSTANCE,
                 DoubleSerializerDeserializer.INSTANCE, IntegerSerializerDeserializer.INSTANCE };
         RecordDescriptor recDesc = new RecordDescriptor(recDescSers);
-        IFrameTupleAccessor accessor = new FrameTupleAccessor(ctx
-                .getFrameSize(), recDesc);
+        IFrameTupleAccessor accessor = new FrameTupleAccessor(ctx.getFrameSize(), recDesc);
         accessor.reset(hyracksFrame);
         FrameTupleReference tuple = new FrameTupleReference();
 
-        
         RTreeOpContext insertOpCtx = rtree.createOpContext(TreeIndexOp.TI_INSERT, interiorFrame, leafFrame, metaFrame);
-        
+
         Random rnd = new Random();
         rnd.setSeed(50);
-        
-        for (int i = 0; i < 33; i++) {
+
+        for (int i = 0; i < 10000; i++) {
 
             double p1x = rnd.nextDouble();
             double p1y = rnd.nextDouble();
             double p2x = rnd.nextDouble();
             double p2y = rnd.nextDouble();
-            
-//            System.out.println(p1x);
-//            System.out.println(p1y);
-//            System.out.println(p2x);
-//            System.out.println(p2y);
-//            
-           System.out.println("=================================");
-            
+
             int pk = rnd.nextInt();
 
             tb.reset();
@@ -162,25 +151,26 @@
 
             tuple.reset(accessor, 0);
 
-            //if (i % 1000 == 0) {
-                long end = System.currentTimeMillis();
-                print("INSERTING " + i + " " + Math.min(p1x, p2x) + " " + Math.min(p1y, p2y) + " " + Math.max(p1x, p2x) + " " + Math.max(p1y, p2y) + "\n");
-            //}
+            // if (i % 1000 == 0) {
+            long end = System.currentTimeMillis();
+            print("INSERTING " + i + " " + Math.min(p1x, p2x) + " " + Math.min(p1y, p2y) + " " + Math.max(p1x, p2x)
+                    + " " + Math.max(p1y, p2y) + "\n");
+            // }
 
             try {
-                if(i == 22)
-                    System.out.print("");
                 rtree.insert(tuple, insertOpCtx);
             } catch (TreeIndexException e) {
             } catch (Exception e) {
                 e.printStackTrace();
             }
-            rtree.printTree(leafFrame, interiorFrame, recDescSers);
-            System.out.println();
         }
 
-//        rtree.printTree(leafFrame, interiorFrame, recDescSers);
-//        System.out.println();
+        rtree.printTree(leafFrame, interiorFrame, recDescSers);
+        System.out.println();
+
+        String stats = rtree.printStats();
+        print(stats);
+
         rtree.close();
         bufferCache.closeFile(fileId);
         bufferCache.close();