More of LSM-RTree clean up and bug fixes.

git-svn-id: https://hyracks.googlecode.com/svn/branches/hyracks_lsm_tree@1057 123451ca-8445-de46-9d55-352943316053
diff --git a/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMBTreeOpContext.java b/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMBTreeOpContext.java
deleted file mode 100644
index 1b14d9f..0000000
--- a/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMBTreeOpContext.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package edu.uci.ics.hyracks.storage.am.lsm.rtree.impls;
-
-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.common.api.ITreeIndexFrameFactory;
-import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexMetaDataFrame;
-import edu.uci.ics.hyracks.storage.am.common.ophelpers.IndexOp;
-import edu.uci.ics.hyracks.storage.am.common.ophelpers.MultiComparator;
-
-public final class LSMBTreeOpContext extends BTreeOpContext {
-
-    public final BTree.BTreeAccessor memBTreeAccessor;
-
-    public LSMBTreeOpContext(BTree.BTreeAccessor memBtreeAccessor, ITreeIndexFrameFactory leafFrameFactory,
-            ITreeIndexFrameFactory interiorFrameFactory, ITreeIndexMetaDataFrame metaFrame, MultiComparator cmp) {
-        super(leafFrameFactory, interiorFrameFactory, metaFrame, cmp);
-
-        this.memBTreeAccessor = memBtreeAccessor;
-        // Overwrite the BTree accessor's op context with our LSMBTreeOpContext.
-        this.memBTreeAccessor.setOpContext(this);
-
-        reset(op);
-    }
-
-    @Override
-    public void reset(IndexOp newOp) {
-        super.reset(newOp);
-    }
-
-}
\ No newline at end of file
diff --git a/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMRTree.java b/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMRTree.java
index 32ec957..1c65cd2 100644
--- a/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMRTree.java
+++ b/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMRTree.java
@@ -2,6 +2,7 @@
 
 import java.io.File;
 import java.util.LinkedList;
+import java.util.ListIterator;
 
 import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
 import edu.uci.ics.hyracks.api.io.FileReference;
@@ -96,6 +97,8 @@
             onDiskDir += System.getProperty("file.separator");
         }
         this.onDiskDir = onDiskDir;
+        this.rtreeFileId = 0;
+        this.btreeFileId = 1;
     }
 
     @Override
@@ -213,10 +216,7 @@
 
         // Cursor setting -- almost the same as search, only difference is
         // "no cursor for in-memory tree"
-        int numberOfInDiskTrees;
-        synchronized (onDiskRTrees) {
-            numberOfInDiskTrees = onDiskRTrees.size();
-        }
+        int numberOfInDiskTrees = onDiskRTrees.size();
 
         RTreeSearchCursor[] rtreeCursors = new RTreeSearchCursor[numberOfInDiskTrees];
         BTreeRangeSearchCursor[] btreeCursors = new BTreeRangeSearchCursor[numberOfInDiskTrees];
@@ -363,7 +363,7 @@
         }
     }
 
-    private void insert(ITupleReference tuple, LSMTreeOpContext ctx) throws HyracksDataException, TreeIndexException {
+    private void insert(ITupleReference tuple, LSMRTreeOpContext ctx) throws HyracksDataException, TreeIndexException {
         boolean waitForFlush = false;
         do {
             synchronized (this) {
@@ -373,7 +373,7 @@
                 }
             }
         } while (waitForFlush == true);
-        ctx.LSMRTreeOpContext.memRTreeAccessor.insert(tuple);
+        ctx.memRTreeAccessor.insert(tuple);
         try {
             threadExit();
         } catch (Exception e) {
@@ -381,7 +381,7 @@
         }
     }
 
-    private void delete(ITupleReference tuple, LSMTreeOpContext ctx) throws HyracksDataException, TreeIndexException {
+    private void delete(ITupleReference tuple, LSMRTreeOpContext ctx) throws HyracksDataException, TreeIndexException {
         boolean waitForFlush = false;
         do {
             synchronized (this) {
@@ -391,7 +391,7 @@
                 }
             }
         } while (waitForFlush == true);
-        ctx.LSMBTreeOpContext.memBTreeAccessor.insert(tuple);
+        ctx.memBTreeAccessor.insert(tuple);
         try {
             threadExit();
         } catch (Exception e) {
@@ -399,12 +399,11 @@
         }
     }
 
-    private void search(ITreeIndexCursor cursor, ISearchPredicate rtreeSearchPred, LSMTreeOpContext ctx)
-            throws Exception {
+    private void search(ITreeIndexCursor cursor, ISearchPredicate rtreeSearchPred, LSMRTreeOpContext ctx,
+            boolean includeMemTree) throws Exception {
 
         boolean continuePerformOp = false;
         ctx.reset(IndexOp.SEARCH);
-
         while (continuePerformOp == false) {
             synchronized (this) {
                 if (!flushFlag) {
@@ -414,45 +413,70 @@
             }
         }
 
-        int numberOfInDiskTrees;
-        synchronized (onDiskRTrees) {
-            numberOfInDiskTrees = onDiskRTrees.size();
+        int numDiskTrees = onDiskRTrees.size();
+
+        ITreeIndexAccessor[] bTreeAccessors;
+        int diskBTreeIx = 0;
+        if (includeMemTree) {
+            bTreeAccessors = new ITreeIndexAccessor[numDiskTrees + 1];
+            bTreeAccessors[0] = ctx.memBTreeAccessor;
+            diskBTreeIx++;
+        } else {
+            bTreeAccessors = new ITreeIndexAccessor[numDiskTrees];
         }
 
-        LSMRTreeCursorInitialState initialState = new LSMRTreeCursorInitialState(numberOfInDiskTrees + 1,
-                rtreeLeafFrameFactory, rtreeInteriorFrameFactory, btreeLeafFrameFactory, btreeCmp,
-                ctx.LSMBTreeOpContext.memBTreeAccessor, this);
-        cursor.open(initialState, rtreeSearchPred);
-
-        ITreeIndexAccessor[] onDiskRTreeAccessors = new ITreeIndexAccessor[numberOfInDiskTrees];
-
-        for (int i = 0; i < numberOfInDiskTrees; i++) {
-            onDiskRTreeAccessors[i] = onDiskRTrees.get(i).createAccessor();
-            onDiskRTreeAccessors[i].search(((LSMRTreeSearchCursor) cursor).getRTreeCursor(i + 1), rtreeSearchPred);
+        ListIterator<BTree> diskBTreesIter = onDiskBTrees.listIterator();
+        while (diskBTreesIter.hasNext()) {
+            BTree diskBTree = diskBTreesIter.next();
+            bTreeAccessors[diskBTreeIx] = diskBTree.createAccessor();
+            diskBTreeIx++;
         }
 
-        // in-memory
-        ctx.LSMRTreeOpContext.memRTreeAccessor.search(((LSMRTreeSearchCursor) cursor).getRTreeCursor(0),
-                rtreeSearchPred);
+        LSMRTreeSearchCursor lsmRTreeCursor = (LSMRTreeSearchCursor) cursor;
+        LSMRTreeCursorInitialState initialState = new LSMRTreeCursorInitialState(numDiskTrees + 1,
+                rtreeLeafFrameFactory, rtreeInteriorFrameFactory, btreeLeafFrameFactory, btreeCmp, bTreeAccessors, this);
+        lsmRTreeCursor.open(initialState, rtreeSearchPred);
+
+        int cursorIx = 1;
+        if (includeMemTree) {
+            ctx.memRTreeAccessor.search(((LSMRTreeSearchCursor) lsmRTreeCursor).getCursor(0), rtreeSearchPred);
+            cursorIx = 1;
+        } else {
+            cursorIx = 0;
+        }
+
+        // Open cursors of on-disk RTrees
+        ITreeIndexAccessor[] diskRTreeAccessors = new ITreeIndexAccessor[numDiskTrees];
+        ListIterator<RTree> diskRTreesIter = onDiskRTrees.listIterator();
+
+        int diskRTreeIx = 0;
+        while (diskRTreesIter.hasNext()) {
+            RTree diskRTree = diskRTreesIter.next();
+            diskRTreeAccessors[diskRTreeIx] = diskRTree.createAccessor();
+            diskRTreeAccessors[diskRTreeIx].search(lsmRTreeCursor.getCursor(cursorIx), rtreeSearchPred);
+            cursorIx++;
+            diskRTreeIx++;
+        }
+
     }
 
     public LinkedList<BTree> getOnDiskBTrees() {
         return onDiskBTrees;
     }
 
-    private LSMTreeOpContext createOpContext() {
+    private LSMRTreeOpContext createOpContext() {
 
-        return new LSMTreeOpContext(new LSMRTreeOpContext((RTree.RTreeAccessor) memRTree.createAccessor(),
+        return new LSMRTreeOpContext((RTree.RTreeAccessor) memRTree.createAccessor(),
                 (IRTreeLeafFrame) rtreeLeafFrameFactory.createFrame(),
                 (IRTreeInteriorFrame) rtreeInteriorFrameFactory.createFrame(), memFreePageManager
-                        .getMetaDataFrameFactory().createFrame(), 8), new LSMBTreeOpContext(
-                (BTree.BTreeAccessor) memBTree.createAccessor(), btreeLeafFrameFactory, btreeInteriorFrameFactory,
-                memFreePageManager.getMetaDataFrameFactory().createFrame(), btreeCmp));
+                        .getMetaDataFrameFactory().createFrame(), 8, (BTree.BTreeAccessor) memBTree.createAccessor(),
+                btreeLeafFrameFactory, btreeInteriorFrameFactory, memFreePageManager.getMetaDataFrameFactory()
+                        .createFrame(), btreeCmp);
     }
 
     private class LSMRTreeAccessor implements ITreeIndexAccessor {
         private LSMRTree lsmRTree;
-        private LSMTreeOpContext ctx;
+        private LSMRTreeOpContext ctx;
 
         public LSMRTreeAccessor(LSMRTree lsmRTree) {
             this.lsmRTree = lsmRTree;
@@ -462,7 +486,7 @@
 
         @Override
         public void insert(ITupleReference tuple) throws HyracksDataException, TreeIndexException {
-            ctx.LSMRTreeOpContext.reset(IndexOp.INSERT);
+            ctx.reset(IndexOp.INSERT);
             lsmRTree.insert(tuple, ctx);
         }
 
@@ -473,33 +497,33 @@
 
         @Override
         public void delete(ITupleReference tuple) throws HyracksDataException, TreeIndexException {
-            ctx.LSMBTreeOpContext.reset(IndexOp.INSERT);
+            ctx.reset(IndexOp.DELETE);
             lsmRTree.delete(tuple, ctx);
         }
 
         @Override
-		public ITreeIndexCursor createSearchCursor() {			
-			return new LSMRTreeSearchCursor();
-		}
-        
+        public ITreeIndexCursor createSearchCursor() {
+            return new LSMRTreeSearchCursor();
+        }
+
         @Override
         public void search(ITreeIndexCursor cursor, ISearchPredicate searchPred) throws HyracksDataException,
                 TreeIndexException {
             ctx.reset(IndexOp.SEARCH);
             // TODO: fix exception handling throughout LSM tree.
             try {
-                lsmRTree.search(cursor, searchPred, ctx);
+                lsmRTree.search(cursor, searchPred, ctx, true);
             } catch (Exception e) {
                 throw new HyracksDataException(e);
             }
         }
 
         @Override
-		public ITreeIndexCursor createDiskOrderScanCursor() {
-			// TODO: Not implemented yet.
-			return null;
-		}
-        
+        public ITreeIndexCursor createDiskOrderScanCursor() {
+            // TODO: Not implemented yet.
+            return null;
+        }
+
         @Override
         public void diskOrderScan(ITreeIndexCursor cursor) throws HyracksDataException {
             throw new UnsupportedOperationException("DiskOrderScan not supported by LSMRTree");
diff --git a/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMRTreeCursorInitialState.java b/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMRTreeCursorInitialState.java
index 3669f87..7239f3a 100644
--- a/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMRTreeCursorInitialState.java
+++ b/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMRTreeCursorInitialState.java
@@ -1,7 +1,7 @@
 package edu.uci.ics.hyracks.storage.am.lsm.rtree.impls;
 
-import edu.uci.ics.hyracks.storage.am.btree.impls.BTree;
 import edu.uci.ics.hyracks.storage.am.common.api.ICursorInitialState;
+import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexAccessor;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexFrameFactory;
 import edu.uci.ics.hyracks.storage.am.common.ophelpers.MultiComparator;
 import edu.uci.ics.hyracks.storage.common.buffercache.ICachedPage;
@@ -14,18 +14,18 @@
     private ITreeIndexFrameFactory btreeLeafFrameFactory;
     private MultiComparator btreeCmp;
     private LSMRTree lsmRTree;
-    private BTree.BTreeAccessor memBtreeAccessor;
+    private ITreeIndexAccessor[] bTreeAccessors;
 
     public LSMRTreeCursorInitialState(int numberOfTrees, ITreeIndexFrameFactory rtreeLeafFrameFactory,
             ITreeIndexFrameFactory rtreeInteriorFrameFactory, ITreeIndexFrameFactory btreeLeafFrameFactory,
-            MultiComparator btreeCmp, BTree.BTreeAccessor memBtreeAccessor, LSMRTree lsmRTree) {
+            MultiComparator btreeCmp, ITreeIndexAccessor[] bTreeAccessors, LSMRTree lsmRTree) {
         this.numberOfTrees = numberOfTrees;
         this.rtreeLeafFrameFactory = rtreeLeafFrameFactory;
         this.rtreeInteriorFrameFactory = rtreeInteriorFrameFactory;
         this.btreeLeafFrameFactory = btreeLeafFrameFactory;
         this.btreeCmp = btreeCmp;
         this.lsmRTree = lsmRTree;
-        this.memBtreeAccessor = memBtreeAccessor;
+        this.bTreeAccessors = bTreeAccessors;
     }
 
     public int getNumberOfTrees() {
@@ -57,8 +57,8 @@
     public void setPage(ICachedPage page) {
     }
 
-    public BTree.BTreeAccessor getMemBtreeAccessor() {
-        return memBtreeAccessor;
+    public ITreeIndexAccessor[] getBTreeAccessors() {
+        return bTreeAccessors;
     }
 
     public LSMRTree getLsmRTree() {
diff --git a/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMRTreeFileNameManager.java b/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMRTreeFileNameManager.java
new file mode 100644
index 0000000..86cbf78
--- /dev/null
+++ b/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMRTreeFileNameManager.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package edu.uci.ics.hyracks.storage.am.lsm.rtree.impls;
+
+import java.text.Format;
+import java.text.SimpleDateFormat;
+import java.util.Comparator;
+import java.util.Date;
+
+import edu.uci.ics.hyracks.storage.am.lsm.common.api.ILSMFileNameManager;
+
+public class LSMRTreeFileNameManager implements ILSMFileNameManager {
+
+    private final String baseDir;
+    private final Format formatter = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss_SSS");
+    private final Comparator<String> cmp = new FileNameComparator();
+    
+    public LSMRTreeFileNameManager(String baseDir) {
+        if (!baseDir.endsWith(System.getProperty("file.separator"))) {
+            baseDir += System.getProperty("file.separator");
+        }
+        this.baseDir = baseDir;
+    }
+    
+    @Override
+    public String getFlushFileName() {
+        Date date = new Date();        
+        // "Z" prefix to indicate flush. Relies on "Z" sorting higher than "A".
+        return baseDir + "Z" + formatter.format(date);
+    }
+
+    @Override
+    public String getMergeFileName() {
+        Date date = new Date();
+        // "A" prefix to indicate merge. Relies on "A" sorting lower than "Z".
+        return baseDir + "A" + formatter.format(date);
+    }
+
+    @Override
+    public Comparator<String> getFileNameComparator() {
+        return cmp;
+    }
+
+    /**
+     * Sorts strings in reverse lexicographical order. The way we construct the
+     * file names above guarantees that:
+     * 
+     * 1. Flushed files ("Z" prefix) sort lower than merged files ("A" prefix)
+     * 
+     * 2. Flushed files are sorted from newest to oldest (based on the timestamp
+     * string)
+     * 
+     */
+    private class FileNameComparator implements Comparator<String> {
+        @Override
+        public int compare(String a, String b) {
+            // Consciously ignoring locale.
+            return -a.compareTo(b);
+        }
+    }
+
+    @Override
+    public String getBaseDir() {
+        return baseDir;
+    }
+}
diff --git a/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMRTreeOpContext.java b/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMRTreeOpContext.java
index 1ee238f..4cf18c4 100644
--- a/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMRTreeOpContext.java
+++ b/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMRTreeOpContext.java
@@ -1,31 +1,42 @@
 package edu.uci.ics.hyracks.storage.am.lsm.rtree.impls;
 
+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.common.api.ITreeIndexFrameFactory;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexMetaDataFrame;
 import edu.uci.ics.hyracks.storage.am.common.ophelpers.IndexOp;
+import edu.uci.ics.hyracks.storage.am.common.ophelpers.MultiComparator;
 import edu.uci.ics.hyracks.storage.am.rtree.api.IRTreeInteriorFrame;
 import edu.uci.ics.hyracks.storage.am.rtree.api.IRTreeLeafFrame;
 import edu.uci.ics.hyracks.storage.am.rtree.impls.RTree;
 import edu.uci.ics.hyracks.storage.am.rtree.impls.RTreeOpContext;
 
-public final class LSMRTreeOpContext extends RTreeOpContext {
-    
+public final class LSMRTreeOpContext {
+
+    private RTreeOpContext rtreeOpContext;
+    private BTreeOpContext btreeOpContext;
     public final RTree.RTreeAccessor memRTreeAccessor;
+    public final BTree.BTreeAccessor memBTreeAccessor;
 
-    public LSMRTreeOpContext(RTree.RTreeAccessor memRtreeAccessor, IRTreeLeafFrame leafFrame,
-            IRTreeInteriorFrame interiorFrame, ITreeIndexMetaDataFrame metaFrame, int treeHeightHint) {
-
-        super(leafFrame, interiorFrame, metaFrame, treeHeightHint);
+    public LSMRTreeOpContext(RTree.RTreeAccessor memRtreeAccessor, IRTreeLeafFrame rtreeLeafFrame,
+            IRTreeInteriorFrame rtreeInteriorFrame, ITreeIndexMetaDataFrame rtreeMetaFrame, int rTreeHeightHint,
+            BTree.BTreeAccessor memBtreeAccessor, ITreeIndexFrameFactory btreeLeafFrameFactory,
+            ITreeIndexFrameFactory btreeInteriorFrameFactory, ITreeIndexMetaDataFrame btreeMetaFrame,
+            MultiComparator btreeCmp) {
 
         this.memRTreeAccessor = memRtreeAccessor;
-        // Overwrite the RTree accessor's op context with our LSMRTreeOpContext.
-        this.memRTreeAccessor.setOpContext(this);
-
-        reset(op);
+        this.memBTreeAccessor = memBtreeAccessor;
+        this.rtreeOpContext = new RTreeOpContext(rtreeLeafFrame, rtreeInteriorFrame, rtreeMetaFrame, rTreeHeightHint);
+        this.btreeOpContext = new BTreeOpContext(btreeLeafFrameFactory, btreeInteriorFrameFactory, btreeMetaFrame,
+                btreeCmp);
     }
 
-    @Override
     public void reset(IndexOp newOp) {
-        super.reset(newOp);
+        if (newOp == IndexOp.INSERT) {
+            rtreeOpContext.reset(newOp);
+        } else if (newOp == IndexOp.DELETE) {
+            btreeOpContext.reset(IndexOp.INSERT);
+        }
     }
 
 }
\ No newline at end of file
diff --git a/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMRTreeSearchCursor.java b/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMRTreeSearchCursor.java
index b3a909c..98de361 100644
--- a/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMRTreeSearchCursor.java
+++ b/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMRTreeSearchCursor.java
@@ -3,7 +3,6 @@
 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.api.IBTreeLeafFrame;
-import edu.uci.ics.hyracks.storage.am.btree.impls.BTree;
 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.ICursorInitialState;
@@ -22,8 +21,7 @@
 
     private RTreeSearchCursor[] rtreeCursors;
     private BTreeRangeSearchCursor[] btreeCursors;
-    private BTree.BTreeAccessor memBtreeAccessor;
-    private ITreeIndexAccessor[] onDiskBTreeAccessors;
+    private ITreeIndexAccessor[] diskBTreeAccessors;
     private int currentCursror;
     private MultiComparator btreeCmp;
     private int numberOfTrees;
@@ -35,7 +33,7 @@
         currentCursror = 0;
     }
 
-    public RTreeSearchCursor getRTreeCursor(int cursorIndex) {
+    public RTreeSearchCursor getCursor(int cursorIndex) {
         return rtreeCursors[cursorIndex];
     }
 
@@ -55,17 +53,11 @@
                     btreeRangePredicate.setHighKey(currentTuple, true);
                     btreeRangePredicate.setLowKey(currentTuple, true);
 
-					try {
-						if (j == 0) {
-							memBtreeAccessor.search(btreeCursors[j],
-									btreeRangePredicate);
-						} else {
-							onDiskBTreeAccessors[j - 1].search(btreeCursors[j],
-									btreeRangePredicate);
-						}
-					} catch (TreeIndexException e) {
-						throw new HyracksDataException(e);
-					}
+                    try {
+                        diskBTreeAccessors[j].search(btreeCursors[j], btreeRangePredicate);
+                    } catch (TreeIndexException e) {
+                        throw new HyracksDataException(e);
+                    }
 
                     if (btreeCursors[j].hasNext()) {
                         killerTupleFound = true;
@@ -97,21 +89,15 @@
 
         lsmRTree = ((LSMRTreeCursorInitialState) initialState).getLsmRTree();
         btreeCmp = ((LSMRTreeCursorInitialState) initialState).getBTreeCmp();
-        memBtreeAccessor = ((LSMRTreeCursorInitialState) initialState).getMemBtreeAccessor();
 
         numberOfTrees = ((LSMRTreeCursorInitialState) initialState).getNumberOfTrees();
 
+        diskBTreeAccessors = ((LSMRTreeCursorInitialState) initialState).getBTreeAccessors();
+
         rtreeCursors = new RTreeSearchCursor[numberOfTrees];
         btreeCursors = new BTreeRangeSearchCursor[numberOfTrees];
 
-        onDiskBTreeAccessors = new ITreeIndexAccessor[numberOfTrees - 1];
-
         for (int i = 0; i < numberOfTrees; i++) {
-            // we already have an accessor for the in-memory b-tree
-            if (i < numberOfTrees - 1) {
-                onDiskBTreeAccessors[i] = lsmRTree.getOnDiskBTrees().get(i).createAccessor();
-            }
-
             rtreeCursors[i] = new RTreeSearchCursor((IRTreeInteriorFrame) ((LSMRTreeCursorInitialState) initialState)
                     .getRTreeInteriorFrameFactory().createFrame(),
                     (IRTreeLeafFrame) ((LSMRTreeCursorInitialState) initialState).getRTreeLeafFrameFactory()
@@ -129,20 +115,21 @@
         return null;
     }
 
-	@Override
-	public void close() throws HyracksDataException {
-		try {
-			lsmRTree.threadExit();
-		} catch (TreeIndexException e) {
-			throw new HyracksDataException(e);
-		}
-		for (int i = 0; i < numberOfTrees; i++) {
-			rtreeCursors[i].close();
-			btreeCursors[i].close();
-		}
-		rtreeCursors = null;
-		btreeCursors = null;
-	}
+    @Override
+    public void close() throws HyracksDataException {
+        for (int i = 0; i < numberOfTrees; i++) {
+            rtreeCursors[i].close();
+            btreeCursors[i].close();
+        }
+        rtreeCursors = null;
+        btreeCursors = null;
+
+        try {
+            lsmRTree.threadExit();
+        } catch (TreeIndexException e) {
+            throw new HyracksDataException(e);
+        }
+    }
 
     @Override
     public void setBufferCache(IBufferCache bufferCache) {
diff --git a/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMTreeOpContext.java b/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMTreeOpContext.java
deleted file mode 100644
index b3b6e69..0000000
--- a/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMTreeOpContext.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package edu.uci.ics.hyracks.storage.am.lsm.rtree.impls;
-
-import edu.uci.ics.hyracks.storage.am.common.ophelpers.IndexOp;
-
-public final class LSMTreeOpContext {
-
-    public LSMRTreeOpContext LSMRTreeOpContext;
-    public LSMBTreeOpContext LSMBTreeOpContext;
-
-    public LSMTreeOpContext(LSMRTreeOpContext LSMRTreeOpContext, LSMBTreeOpContext LSMBTreeOpContext) {
-        this.LSMRTreeOpContext = LSMRTreeOpContext;
-        this.LSMBTreeOpContext = LSMBTreeOpContext;
-    }
-    
-    public void reset(IndexOp newOp) {
-        LSMRTreeOpContext.reset(newOp);
-        LSMBTreeOpContext.reset(newOp);
-    }
-
-}
\ No newline at end of file
diff --git a/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMTypeAwareTupleWriterFactory.java b/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/tuples/LSMTypeAwareTupleWriterFactory.java
similarity index 94%
rename from hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMTypeAwareTupleWriterFactory.java
rename to hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/tuples/LSMTypeAwareTupleWriterFactory.java
index 811b68b..876df56 100644
--- a/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMTypeAwareTupleWriterFactory.java
+++ b/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/tuples/LSMTypeAwareTupleWriterFactory.java
@@ -1,4 +1,4 @@
-package edu.uci.ics.hyracks.storage.am.lsm.rtree.impls;
+package edu.uci.ics.hyracks.storage.am.lsm.rtree.tuples;
 
 import edu.uci.ics.hyracks.api.dataflow.value.ITypeTraits;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexTupleWriter;
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 96f3439..71bbda9 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
@@ -1104,13 +1104,5 @@
             ctx.reset(IndexOp.DISKORDERSCAN);
             rtree.diskOrderScan(cursor, ctx);
         }
-
-        // TODO: Ideally, this method should not exist. But we need it for
-        // the LSM tree to work correctly, so we can use the LSMOpContext inside
-        // a BTreeAccessor.
-        // Making the appropriate change will involve changing lots of code.
-        public void setOpContext(RTreeOpContext ctx) {
-            this.ctx = ctx;
-        }
     }
 }
\ No newline at end of file
diff --git a/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/LSMRTreeTest.java b/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/LSMRTreeTest.java
index 12033b6..7755f21 100644
--- a/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/LSMRTreeTest.java
+++ b/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/LSMRTreeTest.java
@@ -46,8 +46,8 @@
 import edu.uci.ics.hyracks.storage.am.lsm.rtree.impls.LSMRTreeInMemoryBufferCacheFactory;
 import edu.uci.ics.hyracks.storage.am.lsm.rtree.impls.LSMRTreeInMemoryFreePageManager;
 import edu.uci.ics.hyracks.storage.am.lsm.rtree.impls.LSMRTreeSearchCursor;
-import edu.uci.ics.hyracks.storage.am.lsm.rtree.impls.LSMTypeAwareTupleWriterFactory;
 import edu.uci.ics.hyracks.storage.am.lsm.rtree.impls.RTreeFactory;
+import edu.uci.ics.hyracks.storage.am.lsm.rtree.tuples.LSMTypeAwareTupleWriterFactory;
 import edu.uci.ics.hyracks.storage.am.rtree.frames.RTreeNSMInteriorFrameFactory;
 import edu.uci.ics.hyracks.storage.am.rtree.frames.RTreeNSMLeafFrameFactory;
 import edu.uci.ics.hyracks.storage.am.rtree.impls.SearchPredicate;
@@ -91,26 +91,22 @@
         rtreeCmps[3] = rtreeCmps[0];
 
         // declare b-tree keys
-        int btreeKeyFieldCount = 7;
+        int btreeKeyFieldCount = 5;
         IBinaryComparator[] btreeCmps = new IBinaryComparator[btreeKeyFieldCount];
         btreeCmps[0] = PointableBinaryComparatorFactory.of(DoublePointable.FACTORY).createBinaryComparator();
         btreeCmps[1] = btreeCmps[0];
         btreeCmps[2] = btreeCmps[0];
         btreeCmps[3] = btreeCmps[0];
-        btreeCmps[4] = btreeCmps[0];
-        btreeCmps[5] = PointableBinaryComparatorFactory.of(IntegerPointable.FACTORY).createBinaryComparator();
-        btreeCmps[6] = btreeCmps[0];
+        btreeCmps[4] = PointableBinaryComparatorFactory.of(IntegerPointable.FACTORY).createBinaryComparator();
 
         // declare tuple fields
-        int fieldCount = 7;
+        int fieldCount = 5;
         ITypeTraits[] typeTraits = new ITypeTraits[fieldCount];
         typeTraits[0] = DoublePointable.TYPE_TRAITS;
         typeTraits[1] = DoublePointable.TYPE_TRAITS;
         typeTraits[2] = DoublePointable.TYPE_TRAITS;
         typeTraits[3] = DoublePointable.TYPE_TRAITS;
-        typeTraits[4] = DoublePointable.TYPE_TRAITS;
-        typeTraits[5] = IntegerPointable.TYPE_TRAITS;
-        typeTraits[6] = DoublePointable.TYPE_TRAITS;
+        typeTraits[4] = IntegerPointable.TYPE_TRAITS;
 
         MultiComparator rtreeCmp = new MultiComparator(rtreeCmps);
         MultiComparator btreeCmp = new MultiComparator(btreeCmps);
@@ -158,8 +154,7 @@
         @SuppressWarnings("rawtypes")
         ISerializerDeserializer[] recDescSers = { DoubleSerializerDeserializer.INSTANCE,
                 DoubleSerializerDeserializer.INSTANCE, DoubleSerializerDeserializer.INSTANCE,
-                DoubleSerializerDeserializer.INSTANCE, DoubleSerializerDeserializer.INSTANCE,
-                IntegerSerializerDeserializer.INSTANCE, DoubleSerializerDeserializer.INSTANCE };
+                DoubleSerializerDeserializer.INSTANCE, IntegerSerializerDeserializer.INSTANCE };
         RecordDescriptor recDesc = new RecordDescriptor(recDescSers);
 
         IFrameTupleAccessor accessor = new FrameTupleAccessor(ctx.getFrameSize(), recDesc);
@@ -172,8 +167,6 @@
         Random rnd = new Random();
         rnd.setSeed(50);
 
-        Random rnd2 = new Random();
-        rnd2.setSeed(50);
         for (int i = 0; i < 5000; i++) {
 
             double p1x = rnd.nextDouble();
@@ -181,9 +174,7 @@
             double p2x = rnd.nextDouble();
             double p2y = rnd.nextDouble();
 
-            double pk1 = rnd2.nextDouble();
-            int pk2 = rnd2.nextInt();
-            double pk3 = rnd2.nextDouble();
+            int pk = rnd.nextInt();
 
             tb.reset();
             DoubleSerializerDeserializer.INSTANCE.serialize(Math.min(p1x, p2x), dos);
@@ -194,11 +185,7 @@
             tb.addFieldEndOffset();
             DoubleSerializerDeserializer.INSTANCE.serialize(Math.max(p1y, p2y), dos);
             tb.addFieldEndOffset();
-            DoubleSerializerDeserializer.INSTANCE.serialize(pk1, dos);
-            tb.addFieldEndOffset();
-            IntegerSerializerDeserializer.INSTANCE.serialize(pk2, dos);
-            tb.addFieldEndOffset();
-            DoubleSerializerDeserializer.INSTANCE.serialize(pk3, dos);
+            IntegerSerializerDeserializer.INSTANCE.serialize(pk, dos);
             tb.addFieldEndOffset();
 
             appender.reset(frame, true);
@@ -291,9 +278,7 @@
             double p2x = rnd.nextDouble();
             double p2y = rnd.nextDouble();
 
-            double pk1 = rnd.nextDouble();
-            int pk2 = rnd.nextInt();
-            double pk3 = rnd.nextDouble();
+            int pk = rnd.nextInt();
 
             tb.reset();
             DoubleSerializerDeserializer.INSTANCE.serialize(Math.min(p1x, p2x), dos);
@@ -304,11 +289,7 @@
             tb.addFieldEndOffset();
             DoubleSerializerDeserializer.INSTANCE.serialize(Math.max(p1y, p2y), dos);
             tb.addFieldEndOffset();
-            DoubleSerializerDeserializer.INSTANCE.serialize(pk1, dos);
-            tb.addFieldEndOffset();
-            IntegerSerializerDeserializer.INSTANCE.serialize(pk2, dos);
-            tb.addFieldEndOffset();
-            DoubleSerializerDeserializer.INSTANCE.serialize(pk3, dos);
+            IntegerSerializerDeserializer.INSTANCE.serialize(pk, dos);
             tb.addFieldEndOffset();
 
             appender.reset(frame, true);
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 e24a086..bb744c9 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
@@ -102,7 +102,7 @@
         typeTraits[2] = DoublePointable.TYPE_TRAITS;
         typeTraits[3] = DoublePointable.TYPE_TRAITS;
         typeTraits[4] = DoublePointable.TYPE_TRAITS;
-        typeTraits[5] = DoublePointable.TYPE_TRAITS;
+        typeTraits[5] = IntegerPointable.TYPE_TRAITS;
         typeTraits[6] = DoublePointable.TYPE_TRAITS;
 
         // create value providers
diff --git a/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/rtree/SearchCursorTest.java b/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/rtree/SearchCursorTest.java
index a232e37..2eac485 100644
--- a/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/rtree/SearchCursorTest.java
+++ b/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/rtree/SearchCursorTest.java
@@ -120,7 +120,6 @@
         ITreeIndexFrameFactory leafFrameFactory = new RTreeNSMLeafFrameFactory(tupleWriterFactory,
                 valueProviderFactories);
         ITreeIndexMetaDataFrameFactory metaFrameFactory = new LIFOMetaDataFrameFactory();
-        ITreeIndexMetaDataFrame metaFrame = metaFrameFactory.createFrame();
 
         IRTreeInteriorFrame interiorFrame = (IRTreeInteriorFrame) interiorFrameFactory.createFrame();
         IRTreeLeafFrame leafFrame = (IRTreeLeafFrame) leafFrameFactory.createFrame();