You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@asterixdb.apache.org by am...@apache.org on 2016/01/04 09:23:29 UTC

[2/2] incubator-asterixdb-hyracks git commit: Reduce Object Creation in Index Operations

Reduce Object Creation in Index Operations

Removed proportioanl object creation in btrees and rtrees during insert and
search operations. Instead, we re-use objects in OpContexts.

Change-Id: I7fab280372951522db02f8c2ff1d7d5b15529cd7
Reviewed-on: https://asterix-gerrit.ics.uci.edu/245
Tested-by: Jenkins <je...@fulliautomatix.ics.uci.edu>
Reviewed-by: Murtadha Hubail <hu...@gmail.com>


Project: http://git-wip-us.apache.org/repos/asf/incubator-asterixdb-hyracks/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-asterixdb-hyracks/commit/a17fa8a9
Tree: http://git-wip-us.apache.org/repos/asf/incubator-asterixdb-hyracks/tree/a17fa8a9
Diff: http://git-wip-us.apache.org/repos/asf/incubator-asterixdb-hyracks/diff/a17fa8a9

Branch: refs/heads/master
Commit: a17fa8a9df32ea9ea98599584c3eda6ec064f2e1
Parents: f6b9f1f
Author: Abdullah Alamoudi <ba...@gmail.com>
Authored: Mon Jan 4 09:26:39 2016 +0300
Committer: abdullah alamoudi <ba...@gmail.com>
Committed: Mon Jan 4 00:18:33 2016 -0800

----------------------------------------------------------------------
 .../hyracks/storage/am/btree/impls/BTree.java   |  14 +
 .../storage/am/btree/impls/BTreeOpContext.java  |   6 +
 .../am/btree/impls/BTreeRangeSearchCursor.java  |   4 +
 .../storage/am/btree/impls/RangePredicate.java  |  26 ++
 .../am/lsm/btree/impls/ExternalBTree.java       |  52 ++--
 .../lsm/btree/impls/ExternalBTreeOpContext.java |  10 +-
 .../lsm/btree/impls/ExternalBTreeWithBuddy.java |  11 +-
 .../impls/ExternalBTreeWithBuddyOpContext.java  |  12 +-
 .../storage/am/lsm/btree/impls/LSMBTree.java    | 104 +++----
 .../btree/impls/LSMBTreeCursorInitialState.java |  10 +-
 .../am/lsm/btree/impls/LSMBTreeOpContext.java   |  18 +-
 .../btree/impls/LSMBTreePointSearchCursor.java  |  51 +++-
 .../btree/impls/LSMBTreeRangeSearchCursor.java  |  41 ++-
 .../impls/LSMBTreeWithBuddyAbstractCursor.java  | 299 ++++++++++---------
 .../LSMBTreeWithBuddyCursorInitialState.java    | 169 ++++++-----
 .../impls/LSMBTreeWithBuddySortedCursor.java    |   3 +-
 .../BloomFilterAwareBTreePointSearchCursor.java |  11 +-
 .../lsm/common/impls/LSMIndexSearchCursor.java  |  29 +-
 .../am/lsm/rtree/impls/AbstractLSMRTree.java    |  52 ++--
 .../am/lsm/rtree/impls/ExternalRTree.java       |  43 ++-
 .../lsm/rtree/impls/ExternalRTreeOpContext.java |  12 +-
 .../storage/am/lsm/rtree/impls/LSMRTree.java    |  71 +++--
 .../lsm/rtree/impls/LSMRTreeAbstractCursor.java |  86 ++++--
 .../rtree/impls/LSMRTreeCursorInitialState.java |   8 +-
 .../am/lsm/rtree/impls/LSMRTreeOpContext.java   |  23 +-
 .../hyracks/storage/am/rtree/impls/RTree.java   |   6 +
 .../storage/am/rtree/impls/RTreeOpContext.java  |   6 +-
 27 files changed, 702 insertions(+), 475 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-asterixdb-hyracks/blob/a17fa8a9/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/BTree.java
----------------------------------------------------------------------
diff --git a/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/BTree.java b/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/BTree.java
index 8c192a1..7099041 100644
--- a/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/BTree.java
+++ b/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/BTree.java
@@ -849,6 +849,13 @@ public class BTree extends AbstractTreeIndex {
 
     // TODO: Class should be private. But currently we need to expose the
     // setOpContext() API to the LSM Tree for it to work correctly.
+
+    /* TODO: Class should be re-usable to avoid massive object creation on a per tuple basis. two solutions for this:
+     * 1. have an accessor pool as part of the btree class (cleaner but introduce additional synchronization)
+     * 2. don't make it an inner class (no synchronization overhead)
+     *
+     * for now, we are reusing it while it is an inner class !!!!
+     */
     public class BTreeAccessor implements ITreeIndexAccessor {
         private BTree btree;
         private BTreeOpContext ctx;
@@ -859,6 +866,13 @@ public class BTree extends AbstractTreeIndex {
             this.ctx = btree.createOpContext(this, modificationCalback, searchCallback);
         }
 
+        public void reset(BTree btree, IModificationOperationCallback modificationCallback,
+                ISearchOperationCallback searchCallback) {
+            this.btree = btree;
+            ctx.setCallbacks(modificationCallback, searchCallback);
+            ctx.reset();
+        }
+
         @Override
         public void insert(ITupleReference tuple) throws HyracksDataException, TreeIndexException {
             ctx.setOperation(IndexOperation.INSERT);

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb-hyracks/blob/a17fa8a9/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/BTreeOpContext.java
----------------------------------------------------------------------
diff --git a/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/BTreeOpContext.java b/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/BTreeOpContext.java
index b3aeef5..8513368 100644
--- a/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/BTreeOpContext.java
+++ b/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/BTreeOpContext.java
@@ -227,4 +227,10 @@ public class BTreeOpContext implements IIndexOperationContext {
     public IndexOperation getOperation() {
         return op;
     }
+
+    public void setCallbacks(IModificationOperationCallback modificationCallback,
+            ISearchOperationCallback searchCallback) {
+        this.modificationCallback = modificationCallback;
+        this.searchCallback = searchCallback;
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb-hyracks/blob/a17fa8a9/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/BTreeRangeSearchCursor.java
----------------------------------------------------------------------
diff --git a/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/BTreeRangeSearchCursor.java b/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/BTreeRangeSearchCursor.java
index 18207b7..ba49ece 100644
--- a/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/BTreeRangeSearchCursor.java
+++ b/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/BTreeRangeSearchCursor.java
@@ -318,4 +318,8 @@ public class BTreeRangeSearchCursor implements ITreeIndexCursor {
             throw new HyracksDataException("This cursor has not been created with the intention to allow updates.");
         }
     }
+
+    public boolean isBloomFilterAware(){
+        return false;
+    }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb-hyracks/blob/a17fa8a9/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/RangePredicate.java
----------------------------------------------------------------------
diff --git a/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/RangePredicate.java b/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/RangePredicate.java
index 2de5ac0..0399ede 100644
--- a/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/RangePredicate.java
+++ b/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/RangePredicate.java
@@ -60,6 +60,16 @@ public class RangePredicate extends AbstractSearchPredicate {
         this.highKeyCmp = highKeyCmp;
     }
 
+    public void reset(ITupleReference lowKey, ITupleReference highKey, boolean lowKeyInclusive,
+            boolean highKeyInclusive, MultiComparator lowKeyCmp, MultiComparator highKeyCmp) {
+        this.lowKey = lowKey;
+        this.highKey = highKey;
+        this.lowKeyInclusive = lowKeyInclusive;
+        this.highKeyInclusive = highKeyInclusive;
+        this.lowKeyCmp = lowKeyCmp;
+        this.highKeyCmp = highKeyCmp;
+    }
+
     public MultiComparator getLowKeyComparator() {
         return lowKeyCmp;
     }
@@ -101,4 +111,20 @@ public class RangePredicate extends AbstractSearchPredicate {
     public boolean isHighKeyInclusive() {
         return highKeyInclusive;
     }
+
+    public void setLowKey(ITupleReference lowKey) {
+        this.lowKey = lowKey;
+    }
+
+    public void setHighKey(ITupleReference highKey) {
+        this.highKey = highKey;
+    }
+
+    public void setLowKeyCmp(MultiComparator lowKeyCmp) {
+        this.lowKeyCmp = lowKeyCmp;
+    }
+
+    public void setHighKeyCmp(MultiComparator highKeyCmp) {
+        this.highKeyCmp = highKeyCmp;
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb-hyracks/blob/a17fa8a9/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/ExternalBTree.java
----------------------------------------------------------------------
diff --git a/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/ExternalBTree.java b/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/ExternalBTree.java
index 7861730..1942623 100644
--- a/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/ExternalBTree.java
+++ b/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/ExternalBTree.java
@@ -32,8 +32,19 @@ import org.apache.hyracks.storage.am.bloomfilter.impls.BloomFilterFactory;
 import org.apache.hyracks.storage.am.bloomfilter.impls.BloomFilterSpecification;
 import org.apache.hyracks.storage.am.btree.impls.BTree;
 import org.apache.hyracks.storage.am.btree.impls.BTree.BTreeBulkLoader;
-import org.apache.hyracks.storage.am.common.api.*;
+import org.apache.hyracks.storage.am.common.api.IIndexBulkLoader;
+import org.apache.hyracks.storage.am.common.api.IIndexCursor;
+import org.apache.hyracks.storage.am.common.api.IIndexOperationContext;
 import org.apache.hyracks.storage.am.common.api.IMetaDataPageManager;
+import org.apache.hyracks.storage.am.common.api.IModificationOperationCallback;
+import org.apache.hyracks.storage.am.common.api.ISearchOperationCallback;
+import org.apache.hyracks.storage.am.common.api.ISearchPredicate;
+import org.apache.hyracks.storage.am.common.api.ITreeIndexCursor;
+import org.apache.hyracks.storage.am.common.api.ITreeIndexFrameFactory;
+import org.apache.hyracks.storage.am.common.api.ITreeIndexTupleWriterFactory;
+import org.apache.hyracks.storage.am.common.api.ITwoPCIndexBulkLoader;
+import org.apache.hyracks.storage.am.common.api.IndexException;
+import org.apache.hyracks.storage.am.common.api.TreeIndexException;
 import org.apache.hyracks.storage.am.common.impls.NoOpOperationCallback;
 import org.apache.hyracks.storage.am.common.ophelpers.IndexOperation;
 import org.apache.hyracks.storage.am.lsm.btree.tuples.LSMBTreeRefrencingTupleWriterFactory;
@@ -86,10 +97,10 @@ public class ExternalBTree extends LSMBTree implements ITwoPCIndex {
             ILSMIOOperationCallback ioOpCallback, TreeIndexFactory<BTree> transactionBTreeFactory, int version,
             boolean durable) {
         super(interiorFrameFactory, insertLeafFrameFactory, deleteLeafFrameFactory, fileManager, diskBTreeFactory,
-                bulkLoadBTreeFactory, bloomFilterFactory, bloomFilterFalsePositiveRate, diskFileMapProvider,
-                fieldCount, cmpFactories, mergePolicy, opTracker, ioScheduler, ioOpCallback, false, durable);
-        this.transactionComponentFactory = new LSMBTreeDiskComponentFactory(transactionBTreeFactory,
-                bloomFilterFactory, null);
+                bulkLoadBTreeFactory, bloomFilterFactory, bloomFilterFalsePositiveRate, diskFileMapProvider, fieldCount,
+                cmpFactories, mergePolicy, opTracker, ioScheduler, ioOpCallback, false, durable);
+        this.transactionComponentFactory = new LSMBTreeDiskComponentFactory(transactionBTreeFactory, bloomFilterFactory,
+                null);
         this.secondDiskComponents = new LinkedList<ILSMComponent>();
         this.interiorFrameFactory = interiorFrameFactory;
         this.version = version;
@@ -154,9 +165,14 @@ public class ExternalBTree extends LSMBTree implements ITwoPCIndex {
             throws HyracksDataException, IndexException {
         ExternalBTreeOpContext ctx = (ExternalBTreeOpContext) ictx;
         List<ILSMComponent> operationalComponents = ctx.getComponentHolder();
-        LSMBTreeCursorInitialState initialState = new LSMBTreeCursorInitialState(insertLeafFrameFactory, ctx.cmp,
-                ctx.bloomFilterCmp, lsmHarness, pred, ctx.searchCallback, operationalComponents);
-        cursor.open(initialState, pred);
+        ctx.searchInitialState.reset(pred, operationalComponents);
+        cursor.open(ctx.searchInitialState, pred);
+    }
+
+    // This method creates the appropriate opContext for the targeted version
+    public ExternalBTreeOpContext createOpContext(ISearchOperationCallback searchCallback, int targetVersion) {
+        return new ExternalBTreeOpContext(insertLeafFrameFactory, deleteLeafFrameFactory, searchCallback,
+                componentFactory.getBloomFilterKeyFields().length, cmpFactories, targetVersion, lsmHarness);
     }
 
     // The only reason to override the following method is that it uses a different context object
@@ -169,8 +185,8 @@ public class ExternalBTree extends LSMBTree implements ITwoPCIndex {
         List<ILSMComponent> mergingComponents = ctx.getComponentHolder();
         boolean returnDeletedTuples = false;
         if (version == 0) {
-            if (ctx.getComponentHolder().get(ctx.getComponentHolder().size() - 1) != diskComponents.get(diskComponents
-                    .size() - 1)) {
+            if (ctx.getComponentHolder().get(ctx.getComponentHolder().size() - 1) != diskComponents
+                    .get(diskComponents.size() - 1)) {
                 returnDeletedTuples = true;
             }
         } else {
@@ -184,12 +200,12 @@ public class ExternalBTree extends LSMBTree implements ITwoPCIndex {
         BTree lastBTree = ((LSMBTreeDiskComponent) mergingComponents.get(mergingComponents.size() - 1)).getBTree();
         FileReference firstFile = diskFileMapProvider.lookupFileName(firstBTree.getFileId());
         FileReference lastFile = diskFileMapProvider.lookupFileName(lastBTree.getFileId());
-        LSMComponentFileReferences relMergeFileRefs = fileManager.getRelMergeFileReference(firstFile.getFile()
-                .getName(), lastFile.getFile().getName());
+        LSMComponentFileReferences relMergeFileRefs = fileManager
+                .getRelMergeFileReference(firstFile.getFile().getName(), lastFile.getFile().getName());
         ILSMIndexAccessorInternal accessor = new LSMBTreeAccessor(lsmHarness, opCtx);
-        ioScheduler.scheduleOperation(new LSMBTreeMergeOperation(accessor, mergingComponents, cursor, relMergeFileRefs
-                .getInsertIndexFileReference(), relMergeFileRefs.getBloomFilterFileReference(), callback, fileManager
-                .getBaseDir()));
+        ioScheduler.scheduleOperation(new LSMBTreeMergeOperation(accessor, mergingComponents, cursor,
+                relMergeFileRefs.getInsertIndexFileReference(), relMergeFileRefs.getBloomFilterFileReference(),
+                callback, fileManager.getBaseDir()));
     }
 
     // This function should only be used when a transaction fail. it doesn't
@@ -613,12 +629,6 @@ public class ExternalBTree extends LSMBTree implements ITwoPCIndex {
         return new LSMBTreeAccessor(lsmHarness, createOpContext(searchCallback, version));
     }
 
-    // This method creates the appropriate opContext for the targeted version
-    public ExternalBTreeOpContext createOpContext(ISearchOperationCallback searchCallback, int targetVersion) {
-        return new ExternalBTreeOpContext(insertLeafFrameFactory, deleteLeafFrameFactory, searchCallback,
-                componentFactory.getBloomFilterKeyFields().length, cmpFactories, targetVersion);
-    }
-
     @Override
     public ILSMIndexAccessorInternal createAccessor(ISearchOperationCallback searchCallback, int targetIndexVersion)
             throws HyracksDataException {

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb-hyracks/blob/a17fa8a9/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/ExternalBTreeOpContext.java
----------------------------------------------------------------------
diff --git a/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/ExternalBTreeOpContext.java b/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/ExternalBTreeOpContext.java
index e8face1..d441df5 100644
--- a/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/ExternalBTreeOpContext.java
+++ b/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/ExternalBTreeOpContext.java
@@ -30,6 +30,7 @@ import org.apache.hyracks.storage.am.common.api.ITreeIndexFrameFactory;
 import org.apache.hyracks.storage.am.common.ophelpers.IndexOperation;
 import org.apache.hyracks.storage.am.common.ophelpers.MultiComparator;
 import org.apache.hyracks.storage.am.lsm.common.api.ILSMComponent;
+import org.apache.hyracks.storage.am.lsm.common.api.ILSMHarness;
 import org.apache.hyracks.storage.am.lsm.common.api.ILSMIndexOperationContext;
 
 public class ExternalBTreeOpContext implements ILSMIndexOperationContext {
@@ -46,10 +47,12 @@ public class ExternalBTreeOpContext implements ILSMIndexOperationContext {
     private final List<ILSMComponent> componentsToBeReplicated;
     private final int targetIndexVersion;
     public ISearchPredicate searchPredicate;
+    public LSMBTreeCursorInitialState searchInitialState;
 
     public ExternalBTreeOpContext(ITreeIndexFrameFactory insertLeafFrameFactory,
             ITreeIndexFrameFactory deleteLeafFrameFactory, ISearchOperationCallback searchCallback,
-            int numBloomFilterKeyFields, IBinaryComparatorFactory[] cmpFactories, int targetIndexVersion) {
+            int numBloomFilterKeyFields, IBinaryComparatorFactory[] cmpFactories, int targetIndexVersion,
+            ILSMHarness lsmHarness) {
         if (cmpFactories != null) {
             this.cmp = MultiComparator.create(cmpFactories);
         } else {
@@ -71,6 +74,8 @@ public class ExternalBTreeOpContext implements ILSMIndexOperationContext {
         this.componentsToBeReplicated = new LinkedList<ILSMComponent>();
         this.searchCallback = searchCallback;
         this.targetIndexVersion = targetIndexVersion;
+        searchInitialState = new LSMBTreeCursorInitialState(insertLeafFrameFactory, cmp, bloomFilterCmp, lsmHarness,
+                null, searchCallback, null);
     }
 
     @Override
@@ -86,6 +91,7 @@ public class ExternalBTreeOpContext implements ILSMIndexOperationContext {
         componentsToBeReplicated.clear();
     }
 
+    @Override
     public IndexOperation getOperation() {
         return op;
     }
@@ -130,7 +136,7 @@ public class ExternalBTreeOpContext implements ILSMIndexOperationContext {
     public ISearchPredicate getSearchPredicate() {
         return searchPredicate;
     }
-    
+
     @Override
     public List<ILSMComponent> getComponentsToBeReplicated() {
         return componentsToBeReplicated;

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb-hyracks/blob/a17fa8a9/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/ExternalBTreeWithBuddy.java
----------------------------------------------------------------------
diff --git a/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/ExternalBTreeWithBuddy.java b/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/ExternalBTreeWithBuddy.java
index 4b5e5c8..cdd797b 100644
--- a/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/ExternalBTreeWithBuddy.java
+++ b/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/ExternalBTreeWithBuddy.java
@@ -316,13 +316,8 @@ public class ExternalBTreeWithBuddy extends AbstractLSMIndex implements ITreeInd
             throws HyracksDataException, IndexException {
         ExternalBTreeWithBuddyOpContext ctx = (ExternalBTreeWithBuddyOpContext) ictx;
         List<ILSMComponent> operationalComponents = ictx.getComponentHolder();
-
-        LSMBTreeWithBuddyCursorInitialState initialState = new LSMBTreeWithBuddyCursorInitialState(
-                btreeInteriorFrameFactory, btreeLeafFrameFactory, buddyBtreeLeafFrameFactory, lsmHarness,
-                MultiComparator.create(btreeCmpFactories), MultiComparator.create(buddyBtreeCmpFactories),
-                ctx.searchCallback, operationalComponents);
-
-        cursor.open(initialState, pred);
+        ctx.searchInitialState.setOperationalComponents(operationalComponents);
+        cursor.open(ctx.searchInitialState, pred);
     }
 
     @Override
@@ -378,7 +373,7 @@ public class ExternalBTreeWithBuddy extends AbstractLSMIndex implements ITreeInd
     // This method creates the appropriate opContext for the targeted version
     public ExternalBTreeWithBuddyOpContext createOpContext(ISearchOperationCallback searchCallback, int targetVersion) {
         return new ExternalBTreeWithBuddyOpContext(btreeCmpFactories, buddyBtreeCmpFactories, searchCallback,
-                targetVersion);
+                targetVersion, lsmHarness, btreeInteriorFrameFactory, btreeLeafFrameFactory, buddyBtreeLeafFrameFactory);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb-hyracks/blob/a17fa8a9/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/ExternalBTreeWithBuddyOpContext.java
----------------------------------------------------------------------
diff --git a/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/ExternalBTreeWithBuddyOpContext.java b/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/ExternalBTreeWithBuddyOpContext.java
index 42b37c3..654fd0c 100644
--- a/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/ExternalBTreeWithBuddyOpContext.java
+++ b/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/ExternalBTreeWithBuddyOpContext.java
@@ -25,9 +25,12 @@ import org.apache.hyracks.api.dataflow.value.IBinaryComparatorFactory;
 import org.apache.hyracks.storage.am.common.api.IModificationOperationCallback;
 import org.apache.hyracks.storage.am.common.api.ISearchOperationCallback;
 import org.apache.hyracks.storage.am.common.api.ISearchPredicate;
+import org.apache.hyracks.storage.am.common.api.ITreeIndexFrameFactory;
+import org.apache.hyracks.storage.am.common.impls.NoOpOperationCallback;
 import org.apache.hyracks.storage.am.common.ophelpers.IndexOperation;
 import org.apache.hyracks.storage.am.common.ophelpers.MultiComparator;
 import org.apache.hyracks.storage.am.lsm.common.api.ILSMComponent;
+import org.apache.hyracks.storage.am.lsm.common.api.ILSMHarness;
 import org.apache.hyracks.storage.am.lsm.common.api.ILSMIndexOperationContext;
 
 public class ExternalBTreeWithBuddyOpContext implements ILSMIndexOperationContext {
@@ -40,11 +43,12 @@ public class ExternalBTreeWithBuddyOpContext implements ILSMIndexOperationContex
     public final ISearchOperationCallback searchCallback;
     private final int targetIndexVersion;
     public ISearchPredicate searchPredicate;
+    public LSMBTreeWithBuddyCursorInitialState searchInitialState;
 
     public ExternalBTreeWithBuddyOpContext(IBinaryComparatorFactory[] btreeCmpFactories,
             IBinaryComparatorFactory[] buddyBtreeCmpFactories, ISearchOperationCallback searchCallback,
-            int targetIndexVersion) {
-
+            int targetIndexVersion, ILSMHarness lsmHarness, ITreeIndexFrameFactory btreeInteriorFrameFactory,
+            ITreeIndexFrameFactory btreeLeafFrameFactory, ITreeIndexFrameFactory buddyBtreeLeafFrameFactory) {
         this.componentHolder = new LinkedList<ILSMComponent>();
         this.componentsToBeMerged = new LinkedList<ILSMComponent>();
         this.componentsToBeReplicated = new LinkedList<ILSMComponent>();
@@ -52,8 +56,12 @@ public class ExternalBTreeWithBuddyOpContext implements ILSMIndexOperationContex
         this.targetIndexVersion = targetIndexVersion;
         this.bTreeCmp = MultiComparator.create(btreeCmpFactories);
         this.buddyBTreeCmp = MultiComparator.create(buddyBtreeCmpFactories);
+        searchInitialState = new LSMBTreeWithBuddyCursorInitialState(btreeInteriorFrameFactory, btreeLeafFrameFactory,
+                buddyBtreeLeafFrameFactory, lsmHarness, MultiComparator.create(btreeCmpFactories),
+                MultiComparator.create(buddyBtreeCmpFactories), NoOpOperationCallback.INSTANCE, null);
     }
 
+    @Override
     public void setOperation(IndexOperation newOp) {
         reset();
         this.op = newOp;

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb-hyracks/blob/a17fa8a9/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTree.java
----------------------------------------------------------------------
diff --git a/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTree.java b/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTree.java
index 04f76d5..841dbc4 100644
--- a/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTree.java
+++ b/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTree.java
@@ -37,10 +37,20 @@ import org.apache.hyracks.storage.am.bloomfilter.impls.BloomFilterSpecification;
 import org.apache.hyracks.storage.am.btree.impls.BTree;
 import org.apache.hyracks.storage.am.btree.impls.BTree.BTreeAccessor;
 import org.apache.hyracks.storage.am.btree.impls.BTree.BTreeBulkLoader;
-import org.apache.hyracks.storage.am.btree.impls.BTreeRangeSearchCursor;
 import org.apache.hyracks.storage.am.btree.impls.RangePredicate;
-import org.apache.hyracks.storage.am.common.api.*;
+import org.apache.hyracks.storage.am.common.api.IIndexAccessor;
+import org.apache.hyracks.storage.am.common.api.IIndexBulkLoader;
+import org.apache.hyracks.storage.am.common.api.IIndexCursor;
+import org.apache.hyracks.storage.am.common.api.IIndexOperationContext;
 import org.apache.hyracks.storage.am.common.api.IMetaDataPageManager;
+import org.apache.hyracks.storage.am.common.api.IModificationOperationCallback;
+import org.apache.hyracks.storage.am.common.api.ISearchOperationCallback;
+import org.apache.hyracks.storage.am.common.api.ISearchPredicate;
+import org.apache.hyracks.storage.am.common.api.ITreeIndex;
+import org.apache.hyracks.storage.am.common.api.ITreeIndexCursor;
+import org.apache.hyracks.storage.am.common.api.ITreeIndexFrameFactory;
+import org.apache.hyracks.storage.am.common.api.IndexException;
+import org.apache.hyracks.storage.am.common.api.TreeIndexException;
 import org.apache.hyracks.storage.am.common.exceptions.TreeIndexDuplicateKeyException;
 import org.apache.hyracks.storage.am.common.impls.AbstractSearchPredicate;
 import org.apache.hyracks.storage.am.common.impls.NoOpOperationCallback;
@@ -107,12 +117,13 @@ public class LSMBTree extends AbstractLSMIndex implements ITreeIndex {
         this.cmpFactories = cmpFactories;
         int i = 0;
         for (IVirtualBufferCache virtualBufferCache : virtualBufferCaches) {
-            LSMBTreeMemoryComponent mutableComponent = new LSMBTreeMemoryComponent(new BTree(virtualBufferCache,
-                    virtualBufferCache.getFileMapProvider(), new VirtualMetaDataPageManager(
-                            virtualBufferCache.getNumPages()), interiorFrameFactory, insertLeafFrameFactory,
-                    cmpFactories, fieldCount, new FileReference(new File(fileManager.getBaseDir() + "_virtual_" + i))),
-                    virtualBufferCache, i == 0 ? true : false, filterFactory == null ? null
-                            : filterFactory.createLSMComponentFilter());
+            LSMBTreeMemoryComponent mutableComponent = new LSMBTreeMemoryComponent(
+                    new BTree(virtualBufferCache, virtualBufferCache.getFileMapProvider(),
+                            new VirtualMetaDataPageManager(virtualBufferCache.getNumPages()), interiorFrameFactory,
+                            insertLeafFrameFactory, cmpFactories, fieldCount,
+                            new FileReference(new File(fileManager.getBaseDir() + "_virtual_" + i))),
+                    virtualBufferCache, i == 0 ? true : false,
+                    filterFactory == null ? null : filterFactory.createLSMComponentFilter());
             memoryComponents.add(mutableComponent);
             ++i;
         }
@@ -327,19 +338,17 @@ public class LSMBTree extends AbstractLSMIndex implements ITreeIndex {
         }
         if (ctx.filterTuple != null) {
             ctx.filterTuple.reset(tuple);
-            memoryComponents.get(currentMutableComponentId.get()).getLSMComponentFilter()
-                    .update(ctx.filterTuple, ctx.filterCmp);
+            memoryComponents.get(currentMutableComponentId.get()).getLSMComponentFilter().update(ctx.filterTuple,
+                    ctx.filterCmp);
         }
     }
 
     private boolean insert(ITupleReference tuple, LSMBTreeOpContext ctx) throws HyracksDataException, IndexException {
-        ILSMComponent c = ctx.getComponentHolder().get(0);
-        LSMBTreeMemoryComponent mutableComponent = (LSMBTreeMemoryComponent) c;
-        MultiComparator comparator = MultiComparator.create(mutableComponent.getBTree().getComparatorFactories());
-        LSMBTreePointSearchCursor searchCursor = new LSMBTreePointSearchCursor(ctx);
-        IIndexCursor memCursor = new BTreeRangeSearchCursor(ctx.currentMutableBTreeOpCtx.leafFrame, false);
-        RangePredicate predicate = new RangePredicate(tuple, tuple, true, true, comparator, comparator);
-
+        LSMBTreePointSearchCursor searchCursor = ctx.insertSearchCursor;
+        IIndexCursor memCursor = ctx.memCursor;
+        RangePredicate predicate = (RangePredicate) ctx.getSearchPredicate();
+        predicate.setHighKey(tuple);
+        predicate.setLowKey(tuple);
         if (needKeyDupCheck) {
             // first check the inmemory component
             ctx.currentMutableBTreeAccessor.search(memCursor, predicate);
@@ -380,7 +389,6 @@ public class LSMBTree extends AbstractLSMIndex implements ITreeIndex {
                 ctx.getComponentHolder().add(0, firstComponent);
             }
         }
-
         ctx.currentMutableBTreeAccessor.upsertIfConditionElseInsert(tuple, AntimatterAwareTupleAcceptor.INSTANCE);
         return true;
     }
@@ -390,10 +398,8 @@ public class LSMBTree extends AbstractLSMIndex implements ITreeIndex {
             throws HyracksDataException, IndexException {
         LSMBTreeOpContext ctx = (LSMBTreeOpContext) ictx;
         List<ILSMComponent> operationalComponents = ctx.getComponentHolder();
-
-        LSMBTreeCursorInitialState initialState = new LSMBTreeCursorInitialState(insertLeafFrameFactory, ctx.cmp,
-                ctx.bloomFilterCmp, lsmHarness, pred, ctx.searchCallback, operationalComponents);
-        cursor.open(initialState, pred);
+        ctx.searchInitialState.reset(pred, operationalComponents);
+        cursor.open(ctx.searchInitialState, pred);
     }
 
     @Override
@@ -406,9 +412,9 @@ public class LSMBTree extends AbstractLSMIndex implements ITreeIndex {
         opCtx.setOperation(IndexOperation.FLUSH);
         opCtx.getComponentHolder().add(flushingComponent);
         ILSMIndexAccessorInternal flushAccessor = new LSMBTreeAccessor(lsmHarness, opCtx);
-        ioScheduler.scheduleOperation(new LSMBTreeFlushOperation(flushAccessor, flushingComponent, componentFileRefs
-                .getInsertIndexFileReference(), componentFileRefs.getBloomFilterFileReference(), callback, fileManager
-                .getBaseDir()));
+        ioScheduler.scheduleOperation(new LSMBTreeFlushOperation(flushAccessor, flushingComponent,
+                componentFileRefs.getInsertIndexFileReference(), componentFileRefs.getBloomFilterFileReference(),
+                callback, fileManager.getBaseDir()));
     }
 
     @Override
@@ -439,8 +445,8 @@ public class LSMBTree extends AbstractLSMIndex implements ITreeIndex {
         LSMBTreeDiskComponent component = createDiskComponent(componentFactory, flushOp.getBTreeFlushTarget(),
                 flushOp.getBloomFilterFlushTarget(), true);
         IIndexBulkLoader bulkLoader = component.getBTree().createBulkLoader(1.0f, false, numElements, false, true);
-        IIndexBulkLoader builder = component.getBloomFilter().createBuilder(numElements,
-                bloomFilterSpec.getNumHashes(), bloomFilterSpec.getNumBucketsPerElements());
+        IIndexBulkLoader builder = component.getBloomFilter().createBuilder(numElements, bloomFilterSpec.getNumHashes(),
+                bloomFilterSpec.getNumBucketsPerElements());
 
         IIndexCursor scanCursor = accessor.createSearchCursor(false);
         accessor.search(scanCursor, nullPred);
@@ -460,8 +466,7 @@ public class LSMBTree extends AbstractLSMIndex implements ITreeIndex {
             filterTuples.add(flushingComponent.getLSMComponentFilter().getMinTuple());
             filterTuples.add(flushingComponent.getLSMComponentFilter().getMaxTuple());
             filterManager.updateFilterInfo(component.getLSMComponentFilter(), filterTuples);
-            filterManager.writeFilterInfo(component.getLSMComponentFilter(), component.getBTree()
-            );
+            filterManager.writeFilterInfo(component.getLSMComponentFilter(), component.getBTree());
         }
 
         bulkLoader.end();
@@ -476,8 +481,8 @@ public class LSMBTree extends AbstractLSMIndex implements ITreeIndex {
         opCtx.setOperation(IndexOperation.MERGE);
         List<ILSMComponent> mergingComponents = ctx.getComponentHolder();
         boolean returnDeletedTuples = false;
-        if (ctx.getComponentHolder().get(ctx.getComponentHolder().size() - 1) != diskComponents.get(diskComponents
-                .size() - 1)) {
+        if (ctx.getComponentHolder().get(ctx.getComponentHolder().size() - 1) != diskComponents
+                .get(diskComponents.size() - 1)) {
             returnDeletedTuples = true;
         }
         ITreeIndexCursor cursor = new LSMBTreeRangeSearchCursor(opCtx, returnDeletedTuples);
@@ -485,12 +490,12 @@ public class LSMBTree extends AbstractLSMIndex implements ITreeIndex {
         BTree lastBTree = ((LSMBTreeDiskComponent) mergingComponents.get(mergingComponents.size() - 1)).getBTree();
         FileReference firstFile = diskFileMapProvider.lookupFileName(firstBTree.getFileId());
         FileReference lastFile = diskFileMapProvider.lookupFileName(lastBTree.getFileId());
-        LSMComponentFileReferences relMergeFileRefs = fileManager.getRelMergeFileReference(firstFile.getFile()
-                .getName(), lastFile.getFile().getName());
+        LSMComponentFileReferences relMergeFileRefs = fileManager
+                .getRelMergeFileReference(firstFile.getFile().getName(), lastFile.getFile().getName());
         ILSMIndexAccessorInternal accessor = new LSMBTreeAccessor(lsmHarness, opCtx);
-        ioScheduler.scheduleOperation(new LSMBTreeMergeOperation(accessor, mergingComponents, cursor, relMergeFileRefs
-                .getInsertIndexFileReference(), relMergeFileRefs.getBloomFilterFileReference(), callback, fileManager
-                .getBaseDir()));
+        ioScheduler.scheduleOperation(new LSMBTreeMergeOperation(accessor, mergingComponents, cursor,
+                relMergeFileRefs.getInsertIndexFileReference(), relMergeFileRefs.getBloomFilterFileReference(),
+                callback, fileManager.getBaseDir()));
     }
 
     @Override
@@ -514,8 +519,8 @@ public class LSMBTree extends AbstractLSMIndex implements ITreeIndex {
         LSMBTreeDiskComponent mergedComponent = createDiskComponent(componentFactory, mergeOp.getBTreeMergeTarget(),
                 mergeOp.getBloomFilterMergeTarget(), true);
 
-        IIndexBulkLoader bulkLoader = mergedComponent.getBTree()
-                .createBulkLoader(1.0f, false, numElements, false, true);
+        IIndexBulkLoader bulkLoader = mergedComponent.getBTree().createBulkLoader(1.0f, false, numElements, false,
+                true);
         IIndexBulkLoader builder = mergedComponent.getBloomFilter().createBuilder(numElements,
                 bloomFilterSpec.getNumHashes(), bloomFilterSpec.getNumBucketsPerElements());
         try {
@@ -536,8 +541,7 @@ public class LSMBTree extends AbstractLSMIndex implements ITreeIndex {
                 filterTuples.add(mergeOp.getMergingComponents().get(i).getLSMComponentFilter().getMaxTuple());
             }
             filterManager.updateFilterInfo(mergedComponent.getLSMComponentFilter(), filterTuples);
-            filterManager.writeFilterInfo(mergedComponent.getLSMComponentFilter(), mergedComponent.getBTree()
-            );
+            filterManager.writeFilterInfo(mergedComponent.getLSMComponentFilter(), mergedComponent.getBTree());
         }
 
         bulkLoader.end();
@@ -547,7 +551,7 @@ public class LSMBTree extends AbstractLSMIndex implements ITreeIndex {
 
     protected LSMBTreeDiskComponent createDiskComponent(LSMBTreeDiskComponentFactory factory,
             FileReference btreeFileRef, FileReference bloomFilterFileRef, boolean createComponent)
-            throws HyracksDataException, IndexException {
+                    throws HyracksDataException, IndexException {
         // Create new BTree instance.
         LSMBTreeDiskComponent component = (LSMBTreeDiskComponent) factory
                 .createLSMComponentInstance(new LSMComponentFileReferences(btreeFileRef, null, bloomFilterFileRef));
@@ -583,7 +587,7 @@ public class LSMBTree extends AbstractLSMIndex implements ITreeIndex {
         // The order of forcing the dirty page to be flushed is critical. The
         // bloom filter must be always done first.
         LSMBTreeDiskComponent component = (LSMBTreeDiskComponent) lsmComponent;
-        markAsValidInternal(component.getBTree().getBufferCache(),component.getBloomFilter());
+        markAsValidInternal(component.getBTree().getBufferCache(), component.getBloomFilter());
         markAsValidInternal(component.getBTree());
     }
 
@@ -598,8 +602,8 @@ public class LSMBTree extends AbstractLSMIndex implements ITreeIndex {
         public final PermutingTupleReference filterTuple;
         public final MultiComparator filterCmp;
 
-        public LSMBTreeBulkLoader(float fillFactor, boolean verifyInput, long numElementsHint, boolean checkIfEmptyIndex)
-                throws TreeIndexException, HyracksDataException {
+        public LSMBTreeBulkLoader(float fillFactor, boolean verifyInput, long numElementsHint,
+                boolean checkIfEmptyIndex) throws TreeIndexException, HyracksDataException {
             if (checkIfEmptyIndex && !isEmptyIndex()) {
                 throw new TreeIndexException("Cannot load an index that is not empty");
             }
@@ -659,8 +663,8 @@ public class LSMBTree extends AbstractLSMIndex implements ITreeIndex {
             if (!cleanedUpArtifacts) {
                 cleanedUpArtifacts = true;
                 if (!endedBloomFilterLoad) {
-                        builder.abort();
-	                    endedBloomFilterLoad = true;
+                    builder.abort();
+                    endedBloomFilterLoad = true;
                 }
                 ((LSMBTreeDiskComponent) component).getBTree().deactivate();
                 ((LSMBTreeDiskComponent) component).getBTree().destroy();
@@ -694,11 +698,11 @@ public class LSMBTree extends AbstractLSMIndex implements ITreeIndex {
 
         @Override
         public void abort() throws HyracksDataException {
-            if(bulkLoader != null){
+            if (bulkLoader != null) {
                 bulkLoader.abort();
             }
 
-            if(builder != null){
+            if (builder != null) {
                 builder.abort();
             }
 
@@ -709,7 +713,7 @@ public class LSMBTree extends AbstractLSMIndex implements ITreeIndex {
             ISearchOperationCallback searchCallback) {
         return new LSMBTreeOpContext(memoryComponents, insertLeafFrameFactory, deleteLeafFrameFactory,
                 modificationCallback, searchCallback, componentFactory.getBloomFilterKeyFields().length, btreeFields,
-                filterFields);
+                filterFields, lsmHarness);
     }
 
     @Override
@@ -900,4 +904,4 @@ public class LSMBTree extends AbstractLSMIndex implements ITreeIndex {
             memoryComponentsAllocated = false;
         }
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb-hyracks/blob/a17fa8a9/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreeCursorInitialState.java
----------------------------------------------------------------------
diff --git a/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreeCursorInitialState.java b/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreeCursorInitialState.java
index c91bc1c..5d8065f 100644
--- a/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreeCursorInitialState.java
+++ b/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreeCursorInitialState.java
@@ -37,10 +37,10 @@ public class LSMBTreeCursorInitialState implements ICursorInitialState {
     private final MultiComparator bloomFilterCmp;
     private final ILSMHarness lsmHarness;
 
-    private final ISearchPredicate predicate;
+    private ISearchPredicate predicate;
     private ISearchOperationCallback searchCallback;
 
-    private final List<ILSMComponent> operationalComponents;
+    private List<ILSMComponent> operationalComponents;
 
     public LSMBTreeCursorInitialState(ITreeIndexFrameFactory leafFrameFactory, MultiComparator cmp,
             MultiComparator bloomFilterCmp, ILSMHarness lsmHarness, ISearchPredicate predicate,
@@ -102,4 +102,10 @@ public class LSMBTreeCursorInitialState implements ICursorInitialState {
     public void setOriginialKeyComparator(MultiComparator originalCmp) {
         this.cmp = originalCmp;
     }
+
+    // make the cursor initial state re-usable
+    public void reset(ISearchPredicate predicate, List<ILSMComponent> operationalComponents) {
+        this.predicate = predicate;
+        this.operationalComponents = operationalComponents;
+    }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb-hyracks/blob/a17fa8a9/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreeOpContext.java
----------------------------------------------------------------------
diff --git a/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreeOpContext.java b/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreeOpContext.java
index 1f56d55..08891c2 100644
--- a/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreeOpContext.java
+++ b/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreeOpContext.java
@@ -26,6 +26,8 @@ import org.apache.hyracks.api.dataflow.value.IBinaryComparatorFactory;
 import org.apache.hyracks.storage.am.btree.api.IBTreeLeafFrame;
 import org.apache.hyracks.storage.am.btree.impls.BTree;
 import org.apache.hyracks.storage.am.btree.impls.BTreeOpContext;
+import org.apache.hyracks.storage.am.btree.impls.BTreeRangeSearchCursor;
+import org.apache.hyracks.storage.am.btree.impls.RangePredicate;
 import org.apache.hyracks.storage.am.common.api.IModificationOperationCallback;
 import org.apache.hyracks.storage.am.common.api.ISearchOperationCallback;
 import org.apache.hyracks.storage.am.common.api.ISearchPredicate;
@@ -35,6 +37,7 @@ import org.apache.hyracks.storage.am.common.ophelpers.IndexOperation;
 import org.apache.hyracks.storage.am.common.ophelpers.MultiComparator;
 import org.apache.hyracks.storage.am.common.tuples.PermutingTupleReference;
 import org.apache.hyracks.storage.am.lsm.common.api.ILSMComponent;
+import org.apache.hyracks.storage.am.lsm.common.api.ILSMHarness;
 import org.apache.hyracks.storage.am.lsm.common.api.ILSMIndexOperationContext;
 
 public final class LSMBTreeOpContext implements ILSMIndexOperationContext {
@@ -60,10 +63,14 @@ public final class LSMBTreeOpContext implements ILSMIndexOperationContext {
     public final MultiComparator filterCmp;
     public final PermutingTupleReference filterTuple;
     public ISearchPredicate searchPredicate;
+    public BTreeRangeSearchCursor memCursor;
+    public LSMBTreeCursorInitialState searchInitialState;
+    public LSMBTreePointSearchCursor insertSearchCursor;
 
     public LSMBTreeOpContext(List<ILSMComponent> mutableComponents, ITreeIndexFrameFactory insertLeafFrameFactory,
             ITreeIndexFrameFactory deleteLeafFrameFactory, IModificationOperationCallback modificationCallback,
-            ISearchOperationCallback searchCallback, int numBloomFilterKeyFields, int[] btreeFields, int[] filterFields) {
+            ISearchOperationCallback searchCallback, int numBloomFilterKeyFields, int[] btreeFields, int[] filterFields,
+            ILSMHarness lsmHarness) {
         LSMBTreeMemoryComponent c = (LSMBTreeMemoryComponent) mutableComponents.get(0);
         IBinaryComparatorFactory cmpFactories[] = c.getBTree().getComparatorFactories();
         if (cmpFactories[0] != null) {
@@ -110,6 +117,14 @@ public final class LSMBTreeOpContext implements ILSMIndexOperationContext {
             filterCmp = null;
             filterTuple = null;
         }
+        searchPredicate = new RangePredicate(null, null, true, true, cmp, cmp);
+        if (insertLeafFrame != null) {
+            memCursor = new BTreeRangeSearchCursor(insertLeafFrame, false);
+        }
+
+        searchInitialState = new LSMBTreeCursorInitialState(insertLeafFrameFactory, cmp, bloomFilterCmp, lsmHarness,
+                null, searchCallback, null);
+        insertSearchCursor = new LSMBTreePointSearchCursor(this);
     }
 
     @Override
@@ -135,6 +150,7 @@ public final class LSMBTreeOpContext implements ILSMIndexOperationContext {
         componentsToBeReplicated.clear();
     }
 
+    @Override
     public IndexOperation getOperation() {
         return op;
     }

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb-hyracks/blob/a17fa8a9/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreePointSearchCursor.java
----------------------------------------------------------------------
diff --git a/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreePointSearchCursor.java b/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreePointSearchCursor.java
index 8d442d6..2e0b06a 100644
--- a/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreePointSearchCursor.java
+++ b/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreePointSearchCursor.java
@@ -25,11 +25,10 @@ import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.dataflow.common.data.accessors.ITupleReference;
 import org.apache.hyracks.storage.am.btree.api.IBTreeLeafFrame;
 import org.apache.hyracks.storage.am.btree.impls.BTree;
+import org.apache.hyracks.storage.am.btree.impls.BTree.BTreeAccessor;
 import org.apache.hyracks.storage.am.btree.impls.BTreeRangeSearchCursor;
 import org.apache.hyracks.storage.am.btree.impls.RangePredicate;
 import org.apache.hyracks.storage.am.common.api.ICursorInitialState;
-import org.apache.hyracks.storage.am.common.api.IIndexAccessor;
-import org.apache.hyracks.storage.am.common.api.IIndexCursor;
 import org.apache.hyracks.storage.am.common.api.ISearchOperationCallback;
 import org.apache.hyracks.storage.am.common.api.ISearchPredicate;
 import org.apache.hyracks.storage.am.common.api.ITreeIndexCursor;
@@ -46,13 +45,13 @@ import org.apache.hyracks.storage.common.buffercache.ICachedPage;
 
 public class LSMBTreePointSearchCursor implements ITreeIndexCursor {
 
-    private IIndexCursor[] rangeCursors;
+    private BTreeRangeSearchCursor[] rangeCursors;
     private final ILSMIndexOperationContext opCtx;
     private ISearchOperationCallback searchCallback;
     private RangePredicate predicate;
     private boolean includeMutableComponent;
     private int numBTrees;
-    private IIndexAccessor[] btreeAccessors;
+    private BTreeAccessor[] btreeAccessors;
     private ILSMHarness lsmHarness;
     private boolean nextHasBeenCalled;
     private boolean foundTuple;
@@ -151,25 +150,49 @@ public class LSMBTreePointSearchCursor implements ITreeIndexCursor {
         searchCallback = lsmInitialState.getSearchOperationCallback();
         predicate = (RangePredicate) lsmInitialState.getSearchPredicate();
         numBTrees = operationalComponents.size();
-        rangeCursors = new IIndexCursor[numBTrees];
-        btreeAccessors = new IIndexAccessor[numBTrees];
+        if (rangeCursors == null || rangeCursors.length != numBTrees) {
+            // object creation: should be relatively low
+            rangeCursors = new BTreeRangeSearchCursor[numBTrees];
+            btreeAccessors = new BTreeAccessor[numBTrees];
+        }
         includeMutableComponent = false;
 
         for (int i = 0; i < numBTrees; i++) {
             ILSMComponent component = operationalComponents.get(i);
             BTree btree;
-            IBTreeLeafFrame leafFrame = (IBTreeLeafFrame) lsmInitialState.getLeafFrameFactory().createFrame();
             if (component.getType() == LSMComponentType.MEMORY) {
                 includeMutableComponent = true;
                 // No need for a bloom filter for the in-memory BTree.
-                rangeCursors[i] = new BTreeRangeSearchCursor(leafFrame, false);
-                btree = (BTree) ((LSMBTreeMemoryComponent) component).getBTree();
+                if (rangeCursors[i] == null || rangeCursors[i].isBloomFilterAware()) {
+                    // create a new one
+                    IBTreeLeafFrame leafFrame = (IBTreeLeafFrame) lsmInitialState.getLeafFrameFactory().createFrame();
+                    rangeCursors[i] = new BTreeRangeSearchCursor(leafFrame, false);
+                } else {
+                    // reset
+                    rangeCursors[i].reset();
+                }
+                btree = ((LSMBTreeMemoryComponent) component).getBTree();
             } else {
-                rangeCursors[i] = new BloomFilterAwareBTreePointSearchCursor(leafFrame, false,
-                        ((LSMBTreeDiskComponent) component).getBloomFilter());
-                btree = (BTree) ((LSMBTreeDiskComponent) component).getBTree();
+                if (rangeCursors[i] != null && rangeCursors[i].isBloomFilterAware()) {
+                    // can re-use cursor
+                    ((BloomFilterAwareBTreePointSearchCursor) rangeCursors[i])
+                            .resetBloomFilter(((LSMBTreeDiskComponent) component).getBloomFilter());
+                    rangeCursors[i].reset();
+                } else {
+                    // create new cursor <should be relatively rare>
+                    IBTreeLeafFrame leafFrame = (IBTreeLeafFrame) lsmInitialState.getLeafFrameFactory().createFrame();
+                    rangeCursors[i] = new BloomFilterAwareBTreePointSearchCursor(leafFrame, false,
+                            ((LSMBTreeDiskComponent) component).getBloomFilter());
+                }
+                btree = ((LSMBTreeDiskComponent) component).getBTree();
+            }
+            if (btreeAccessors[i] == null) {
+                btreeAccessors[i] = (BTreeAccessor) btree.createAccessor(NoOpOperationCallback.INSTANCE,
+                        NoOpOperationCallback.INSTANCE);
+            } else {
+                // re-use
+                btreeAccessors[i].reset(btree, NoOpOperationCallback.INSTANCE, NoOpOperationCallback.INSTANCE);
             }
-            btreeAccessors[i] = btree.createAccessor(NoOpOperationCallback.INSTANCE, NoOpOperationCallback.INSTANCE);
         }
         nextHasBeenCalled = false;
         foundTuple = false;
@@ -210,13 +233,11 @@ public class LSMBTreePointSearchCursor implements ITreeIndexCursor {
     @Override
     public void setBufferCache(IBufferCache bufferCache) {
         // do nothing
-
     }
 
     @Override
     public void setFileId(int fileId) {
         // do nothing
-
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb-hyracks/blob/a17fa8a9/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreeRangeSearchCursor.java
----------------------------------------------------------------------
diff --git a/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreeRangeSearchCursor.java b/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreeRangeSearchCursor.java
index a148eac..2e85fe9 100644
--- a/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreeRangeSearchCursor.java
+++ b/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreeRangeSearchCursor.java
@@ -27,14 +27,13 @@ import org.apache.hyracks.dataflow.common.comm.io.ArrayTupleReference;
 import org.apache.hyracks.dataflow.common.util.TupleUtils;
 import org.apache.hyracks.storage.am.btree.api.IBTreeLeafFrame;
 import org.apache.hyracks.storage.am.btree.impls.BTree;
+import org.apache.hyracks.storage.am.btree.impls.BTree.BTreeAccessor;
 import org.apache.hyracks.storage.am.btree.impls.BTreeRangeSearchCursor;
 import org.apache.hyracks.storage.am.btree.impls.RangePredicate;
 import org.apache.hyracks.storage.am.common.api.ICursorInitialState;
-import org.apache.hyracks.storage.am.common.api.IIndexAccessor;
 import org.apache.hyracks.storage.am.common.api.IIndexCursor;
 import org.apache.hyracks.storage.am.common.api.ISearchOperationCallback;
 import org.apache.hyracks.storage.am.common.api.ISearchPredicate;
-import org.apache.hyracks.storage.am.common.api.ITreeIndexAccessor;
 import org.apache.hyracks.storage.am.common.api.IndexException;
 import org.apache.hyracks.storage.am.common.impls.NoOpOperationCallback;
 import org.apache.hyracks.storage.am.lsm.common.api.ILSMComponent;
@@ -48,7 +47,7 @@ public class LSMBTreeRangeSearchCursor extends LSMIndexSearchCursor {
 
     private ISearchOperationCallback searchCallback;
     private RangePredicate predicate;
-    private IIndexAccessor[] btreeAccessors;
+    private BTreeAccessor[] btreeAccessors;
     private ArrayTupleBuilder tupleBuilder;
     private boolean proceed = true;
 
@@ -75,6 +74,7 @@ public class LSMBTreeRangeSearchCursor extends LSMIndexSearchCursor {
         proceed = false;
     }
 
+    @Override
     protected void checkPriorityQueue() throws HyracksDataException, IndexException {
         while (!outputPriorityQueue.isEmpty() || needPush == true) {
             if (!outputPriorityQueue.isEmpty()) {
@@ -178,8 +178,8 @@ public class LSMBTreeRangeSearchCursor extends LSMIndexSearchCursor {
     }
 
     @Override
-    public void open(ICursorInitialState initialState, ISearchPredicate searchPred) throws HyracksDataException,
-            IndexException {
+    public void open(ICursorInitialState initialState, ISearchPredicate searchPred)
+            throws HyracksDataException, IndexException {
         LSMBTreeCursorInitialState lsmInitialState = (LSMBTreeCursorInitialState) initialState;
         cmp = lsmInitialState.getOriginalKeyComparator();
         operationalComponents = lsmInitialState.getOperationalComponents();
@@ -192,21 +192,36 @@ public class LSMBTreeRangeSearchCursor extends LSMIndexSearchCursor {
         includeMutableComponent = false;
 
         int numBTrees = operationalComponents.size();
-        rangeCursors = new IIndexCursor[numBTrees];
-
-        btreeAccessors = new ITreeIndexAccessor[numBTrees];
+        if (rangeCursors == null || rangeCursors.length != numBTrees) {
+            // object creation: should be relatively low
+            rangeCursors = new IIndexCursor[numBTrees];
+            btreeAccessors = new BTreeAccessor[numBTrees];
+        }
         for (int i = 0; i < numBTrees; i++) {
             ILSMComponent component = operationalComponents.get(i);
             BTree btree;
-            IBTreeLeafFrame leafFrame = (IBTreeLeafFrame) lsmInitialState.getLeafFrameFactory().createFrame();
-            rangeCursors[i] = new BTreeRangeSearchCursor(leafFrame, false);
+            if (rangeCursors[i] == null) {
+                // create, should be relatively rare
+                IBTreeLeafFrame leafFrame = (IBTreeLeafFrame) lsmInitialState.getLeafFrameFactory().createFrame();
+                rangeCursors[i] = new BTreeRangeSearchCursor(leafFrame, false);
+            } else {
+                // re-use
+                rangeCursors[i].reset();
+            }
             if (component.getType() == LSMComponentType.MEMORY) {
                 includeMutableComponent = true;
-                btree = (BTree) ((LSMBTreeMemoryComponent) component).getBTree();
+                btree = ((LSMBTreeMemoryComponent) component).getBTree();
+            } else {
+                btree = ((LSMBTreeDiskComponent) component).getBTree();
+            }
+
+            if (btreeAccessors[i] == null) {
+                btreeAccessors[i] = (BTreeAccessor) btree.createAccessor(NoOpOperationCallback.INSTANCE,
+                        NoOpOperationCallback.INSTANCE);
             } else {
-                btree = (BTree) ((LSMBTreeDiskComponent) component).getBTree();
+                // re-use
+                btreeAccessors[i].reset(btree, NoOpOperationCallback.INSTANCE, NoOpOperationCallback.INSTANCE);
             }
-            btreeAccessors[i] = btree.createAccessor(NoOpOperationCallback.INSTANCE, NoOpOperationCallback.INSTANCE);
             btreeAccessors[i].search(rangeCursors[i], searchPred);
         }
         setPriorityQueueComparator();

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb-hyracks/blob/a17fa8a9/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreeWithBuddyAbstractCursor.java
----------------------------------------------------------------------
diff --git a/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreeWithBuddyAbstractCursor.java b/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreeWithBuddyAbstractCursor.java
index d8c07fa..dab48f7 100644
--- a/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreeWithBuddyAbstractCursor.java
+++ b/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreeWithBuddyAbstractCursor.java
@@ -24,168 +24,171 @@ import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.dataflow.common.data.accessors.ITupleReference;
 import org.apache.hyracks.storage.am.btree.api.IBTreeLeafFrame;
 import org.apache.hyracks.storage.am.btree.impls.BTree;
+import org.apache.hyracks.storage.am.btree.impls.BTree.BTreeAccessor;
 import org.apache.hyracks.storage.am.btree.impls.BTreeRangeSearchCursor;
 import org.apache.hyracks.storage.am.btree.impls.RangePredicate;
 import org.apache.hyracks.storage.am.common.api.ICursorInitialState;
 import org.apache.hyracks.storage.am.common.api.ISearchPredicate;
-import org.apache.hyracks.storage.am.common.api.ITreeIndexAccessor;
 import org.apache.hyracks.storage.am.common.api.ITreeIndexCursor;
 import org.apache.hyracks.storage.am.common.api.IndexException;
 import org.apache.hyracks.storage.am.common.impls.NoOpOperationCallback;
 import org.apache.hyracks.storage.am.common.ophelpers.MultiComparator;
 import org.apache.hyracks.storage.am.lsm.common.api.ILSMComponent;
+import org.apache.hyracks.storage.am.lsm.common.api.ILSMComponent.LSMComponentType;
 import org.apache.hyracks.storage.am.lsm.common.api.ILSMHarness;
 import org.apache.hyracks.storage.am.lsm.common.api.ILSMIndexOperationContext;
-import org.apache.hyracks.storage.am.lsm.common.api.ILSMComponent.LSMComponentType;
 import org.apache.hyracks.storage.am.lsm.common.impls.BloomFilterAwareBTreePointSearchCursor;
 import org.apache.hyracks.storage.common.buffercache.IBufferCache;
 import org.apache.hyracks.storage.common.buffercache.ICachedPage;
 
-public abstract class LSMBTreeWithBuddyAbstractCursor implements
-		ITreeIndexCursor {
-
-	protected boolean open;
-	protected ITreeIndexCursor[] btreeCursors;
-	protected ITreeIndexCursor[] buddyBtreeCursors;
-	protected ITreeIndexAccessor[] btreeAccessors;
-	protected ITreeIndexAccessor[] buddyBtreeAccessors;
-	protected MultiComparator btreeCmp;
-	protected MultiComparator buddyBtreeCmp;
-	protected int numberOfTrees;
-	protected RangePredicate btreeRangePredicate;
-	protected RangePredicate buddyBtreeRangePredicate;
-	protected ITupleReference frameTuple;
-	protected boolean includeMutableComponent;
-	protected ILSMHarness lsmHarness;
-	protected boolean foundNext;
-	protected final ILSMIndexOperationContext opCtx;
-
-	protected List<ILSMComponent> operationalComponents;
-
-	public LSMBTreeWithBuddyAbstractCursor(ILSMIndexOperationContext opCtx) {
-		super();
-		this.opCtx = opCtx;
-	}
-
-	public ITreeIndexCursor getCursor(int cursorIndex) {
-		return btreeCursors[cursorIndex];
-	}
-
-	@Override
-	public void open(ICursorInitialState initialState,
-			ISearchPredicate searchPred) throws IndexException,
-			HyracksDataException {
-
-		LSMBTreeWithBuddyCursorInitialState lsmInitialState = (LSMBTreeWithBuddyCursorInitialState) initialState;
-		btreeCmp = lsmInitialState.getBTreeCmp();
-		buddyBtreeCmp = lsmInitialState.getBuddyBTreeCmp();
-
-		operationalComponents = lsmInitialState.getOperationalComponents();
-		lsmHarness = lsmInitialState.getLSMHarness();
-		numberOfTrees = operationalComponents.size();
-
-		btreeCursors = new ITreeIndexCursor[numberOfTrees];
-		buddyBtreeCursors = new ITreeIndexCursor[numberOfTrees];
-		btreeAccessors = new ITreeIndexAccessor[numberOfTrees];
-		buddyBtreeAccessors = new ITreeIndexAccessor[numberOfTrees];
-
-		includeMutableComponent = false;
-
-		for (int i = 0; i < numberOfTrees; i++) {
-			ILSMComponent component = operationalComponents.get(i);
-			BTree btree;
-			BTree buddyBtree;
-			if (component.getType() == LSMComponentType.MEMORY) {
-				// This is not needed at the moment but is implemented anyway
-				includeMutableComponent = true;
-				// No need for a bloom filter for the in-memory BTree.
-				buddyBtreeCursors[i] = new BTreeRangeSearchCursor(
-						(IBTreeLeafFrame) lsmInitialState
-								.getBuddyBTreeLeafFrameFactory().createFrame(),
-						false);
-				btree = ((LSMBTreeWithBuddyMemoryComponent) component)
-						.getBTree();
-				buddyBtree = ((LSMBTreeWithBuddyMemoryComponent) component)
-						.getBuddyBTree();
-			} else {
-				buddyBtreeCursors[i] = new BloomFilterAwareBTreePointSearchCursor(
-						(IBTreeLeafFrame) lsmInitialState
-								.getBuddyBTreeLeafFrameFactory().createFrame(),
-						false,
-						((LSMBTreeWithBuddyDiskComponent) operationalComponents
-								.get(i)).getBloomFilter());
-				btree = ((LSMBTreeWithBuddyDiskComponent) component).getBTree();
-				buddyBtree = (BTree) ((LSMBTreeWithBuddyDiskComponent) component)
-						.getBuddyBTree();
-			}
-			IBTreeLeafFrame leafFrame = (IBTreeLeafFrame) lsmInitialState
-					.getBTreeLeafFrameFactory().createFrame();
-			btreeCursors[i] = new BTreeRangeSearchCursor(leafFrame, false);
-			btreeAccessors[i] = btree.createAccessor(
-					NoOpOperationCallback.INSTANCE,
-					NoOpOperationCallback.INSTANCE);
-			buddyBtreeAccessors[i] = buddyBtree.createAccessor(
-					NoOpOperationCallback.INSTANCE,
-					NoOpOperationCallback.INSTANCE);
-		}
-		btreeRangePredicate = (RangePredicate) searchPred;
-		buddyBtreeRangePredicate = new RangePredicate(null, null, true, true,
-				buddyBtreeCmp, buddyBtreeCmp);
-
-		open = true;
-	}
-
-	@Override
-	public void close() throws HyracksDataException {
-		if (!open) {
-			return;
-		}
-		try {
-			if (btreeCursors != null && buddyBtreeCursors != null) {
-				for (int i = 0; i < numberOfTrees; i++) {
-					btreeCursors[i].close();
-					buddyBtreeCursors[i].close();
-				}
-			}
-			btreeCursors = null;
-			buddyBtreeCursors = null;
-		} finally {
-			lsmHarness.endSearch(opCtx);
-		}
-		foundNext = false;
-		open = false;
-	}
-
-	@Override
-	public ITupleReference getTuple() {
-		return frameTuple;
-	}
-
-	@Override
-	public ICachedPage getPage() {
-		// Do nothing
-		return null;
-	}
-
-	@Override
-	public void setBufferCache(IBufferCache bufferCache) {
-		// Do nothing
-	}
-
-	@Override
-	public void setFileId(int fileId) {
-		// Do nothing
-	}
-
-	@Override
-	public boolean exclusiveLatchNodes() {
-		return false;
-	}
-
-	@Override
-	public void markCurrentTupleAsUpdated() throws HyracksDataException {
-		throw new HyracksDataException(
-				"Updating tuples is not supported with this cursor.");
-	}
+public abstract class LSMBTreeWithBuddyAbstractCursor implements ITreeIndexCursor {
+
+    protected boolean open;
+    protected BTreeRangeSearchCursor[] btreeCursors;
+    protected BTreeRangeSearchCursor[] buddyBtreeCursors;
+    protected BTreeAccessor[] btreeAccessors;
+    protected BTreeAccessor[] buddyBtreeAccessors;
+    protected MultiComparator btreeCmp;
+    protected MultiComparator buddyBtreeCmp;
+    protected int numberOfTrees;
+    protected RangePredicate btreeRangePredicate;
+    protected RangePredicate buddyBtreeRangePredicate;
+    protected ITupleReference frameTuple;
+    protected boolean includeMutableComponent;
+    protected ILSMHarness lsmHarness;
+    protected boolean foundNext;
+    protected final ILSMIndexOperationContext opCtx;
+
+    protected List<ILSMComponent> operationalComponents;
+
+    public LSMBTreeWithBuddyAbstractCursor(ILSMIndexOperationContext opCtx) {
+        super();
+        this.opCtx = opCtx;
+        buddyBtreeRangePredicate = new RangePredicate(null, null, true, true, null, null);
+    }
+
+    public ITreeIndexCursor getCursor(int cursorIndex) {
+        return btreeCursors[cursorIndex];
+    }
+
+    @Override
+    public void open(ICursorInitialState initialState, ISearchPredicate searchPred)
+            throws IndexException, HyracksDataException {
+
+        LSMBTreeWithBuddyCursorInitialState lsmInitialState = (LSMBTreeWithBuddyCursorInitialState) initialState;
+        btreeCmp = lsmInitialState.getBTreeCmp();
+        buddyBtreeCmp = lsmInitialState.getBuddyBTreeCmp();
+
+        operationalComponents = lsmInitialState.getOperationalComponents();
+        lsmHarness = lsmInitialState.getLSMHarness();
+        numberOfTrees = operationalComponents.size();
+
+        if (btreeCursors == null || btreeCursors.length != numberOfTrees) {
+            // need to re-use the following four instead of re-creating
+            btreeCursors = new BTreeRangeSearchCursor[numberOfTrees];
+            buddyBtreeCursors = new BTreeRangeSearchCursor[numberOfTrees];
+            btreeAccessors = new BTreeAccessor[numberOfTrees];
+            buddyBtreeAccessors = new BTreeAccessor[numberOfTrees];
+        }
+
+        includeMutableComponent = false;
+
+        for (int i = 0; i < numberOfTrees; i++) {
+            ILSMComponent component = operationalComponents.get(i);
+            BTree btree;
+            BTree buddyBtree;
+            if (component.getType() == LSMComponentType.MEMORY) {
+                // This is not needed at the moment but is implemented anyway
+                includeMutableComponent = true;
+                // No need for a bloom filter for the in-memory BTree.
+                if (buddyBtreeCursors[i] == null || buddyBtreeCursors[i].isBloomFilterAware()) {
+                    buddyBtreeCursors[i] = new BTreeRangeSearchCursor(
+                            (IBTreeLeafFrame) lsmInitialState.getBuddyBTreeLeafFrameFactory().createFrame(), false);
+                } else {
+                    buddyBtreeCursors[i].reset();
+                }
+                btree = ((LSMBTreeWithBuddyMemoryComponent) component).getBTree();
+                buddyBtree = ((LSMBTreeWithBuddyMemoryComponent) component).getBuddyBTree();
+            } else {
+                if (buddyBtreeCursors[i] == null || !buddyBtreeCursors[i].isBloomFilterAware()) {
+                    buddyBtreeCursors[i] = new BloomFilterAwareBTreePointSearchCursor(
+                            (IBTreeLeafFrame) lsmInitialState.getBuddyBTreeLeafFrameFactory().createFrame(), false,
+                            ((LSMBTreeWithBuddyDiskComponent) operationalComponents.get(i)).getBloomFilter());
+                } else {
+                    buddyBtreeCursors[i].reset();
+                }
+                btree = ((LSMBTreeWithBuddyDiskComponent) component).getBTree();
+                buddyBtree = ((LSMBTreeWithBuddyDiskComponent) component).getBuddyBTree();
+            }
+            IBTreeLeafFrame leafFrame = (IBTreeLeafFrame) lsmInitialState.getBTreeLeafFrameFactory().createFrame();
+            if (btreeAccessors[i] == null) {
+                btreeCursors[i] = new BTreeRangeSearchCursor(leafFrame, false);
+                btreeAccessors[i] = (BTreeAccessor) btree.createAccessor(NoOpOperationCallback.INSTANCE,
+                        NoOpOperationCallback.INSTANCE);
+                buddyBtreeAccessors[i] = (BTreeAccessor) buddyBtree.createAccessor(NoOpOperationCallback.INSTANCE,
+                        NoOpOperationCallback.INSTANCE);
+            } else {
+                btreeCursors[i].reset();
+                btreeAccessors[i].reset(btree, NoOpOperationCallback.INSTANCE, NoOpOperationCallback.INSTANCE);
+                buddyBtreeAccessors[i].reset(buddyBtree, NoOpOperationCallback.INSTANCE,
+                        NoOpOperationCallback.INSTANCE);
+            }
+        }
+        btreeRangePredicate = (RangePredicate) searchPred;
+        buddyBtreeRangePredicate.reset(null, null, true, true, buddyBtreeCmp, buddyBtreeCmp);
+        open = true;
+    }
+
+    @Override
+    public void close() throws HyracksDataException {
+        if (!open) {
+            return;
+        }
+        try {
+            if (btreeCursors != null && buddyBtreeCursors != null) {
+                for (int i = 0; i < numberOfTrees; i++) {
+                    btreeCursors[i].close();
+                    buddyBtreeCursors[i].close();
+                }
+            }
+            btreeCursors = null;
+            buddyBtreeCursors = null;
+        } finally {
+            lsmHarness.endSearch(opCtx);
+        }
+        foundNext = false;
+        open = false;
+    }
+
+    @Override
+    public ITupleReference getTuple() {
+        return frameTuple;
+    }
+
+    @Override
+    public ICachedPage getPage() {
+        // Do nothing
+        return null;
+    }
+
+    @Override
+    public void setBufferCache(IBufferCache bufferCache) {
+        // Do nothing
+    }
+
+    @Override
+    public void setFileId(int fileId) {
+        // Do nothing
+    }
+
+    @Override
+    public boolean exclusiveLatchNodes() {
+        return false;
+    }
+
+    @Override
+    public void markCurrentTupleAsUpdated() throws HyracksDataException {
+        throw new HyracksDataException("Updating tuples is not supported with this cursor.");
+    }
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb-hyracks/blob/a17fa8a9/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreeWithBuddyCursorInitialState.java
----------------------------------------------------------------------
diff --git a/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreeWithBuddyCursorInitialState.java b/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreeWithBuddyCursorInitialState.java
index 0c8e7a4..a2fe232 100644
--- a/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreeWithBuddyCursorInitialState.java
+++ b/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreeWithBuddyCursorInitialState.java
@@ -29,89 +29,88 @@ import org.apache.hyracks.storage.am.lsm.common.api.ILSMHarness;
 import org.apache.hyracks.storage.common.buffercache.ICachedPage;
 
 public class LSMBTreeWithBuddyCursorInitialState implements ICursorInitialState {
-	private final ITreeIndexFrameFactory btreeInteriorFrameFactory;
-	private final ITreeIndexFrameFactory btreeLeafFrameFactory;
-	private final ITreeIndexFrameFactory buddyBtreeLeafFrameFactory;
-	private MultiComparator btreeCmp;
-	private MultiComparator buddyBtreeCmp;
-	private final ILSMHarness lsmHarness;
-
-	private ISearchOperationCallback searchCallback;
-	private final List<ILSMComponent> operationalComponents;
-
-	public LSMBTreeWithBuddyCursorInitialState(
-			ITreeIndexFrameFactory btreeInteriorFrameFactory,
-			ITreeIndexFrameFactory btreeLeafFrameFactory,
-			ITreeIndexFrameFactory buddyBtreeLeafFrameFactory,
-			ILSMHarness lsmHarness,
-			MultiComparator btreeCmp, MultiComparator buddyBtreeCmp,
-			ISearchOperationCallback searchCallback,
-			List<ILSMComponent> operationalComponents) {
-		this.btreeLeafFrameFactory = btreeLeafFrameFactory;
-		this.btreeInteriorFrameFactory = btreeInteriorFrameFactory;
-		this.buddyBtreeLeafFrameFactory = buddyBtreeLeafFrameFactory;
-		this.btreeCmp = btreeCmp;
-		this.buddyBtreeCmp = buddyBtreeCmp;
-		this.lsmHarness = lsmHarness;
-		this.searchCallback = searchCallback;
-		this.operationalComponents = operationalComponents;
-	}
-
-	public ITreeIndexFrameFactory getBTreeInteriorFrameFactory() {
-		return btreeInteriorFrameFactory;
-	}
-
-	public ITreeIndexFrameFactory getBTreeLeafFrameFactory() {
-		return btreeLeafFrameFactory;
-	}
-
-	public ITreeIndexFrameFactory getBuddyBTreeLeafFrameFactory() {
-		return buddyBtreeLeafFrameFactory;
-	}
-
-	public MultiComparator getBTreeCmp() {
-		return btreeCmp;
-	}
-
-	public MultiComparator getBuddyBTreeCmp() {
-		return buddyBtreeCmp;
-	}
-
-	public List<ILSMComponent> getOperationalComponents() {
-		return operationalComponents;
-	}
-
-	public ILSMHarness getLSMHarness() {
-		return lsmHarness;
-	}
-
-	@Override
-	public ICachedPage getPage() {
-		return null;
-	}
-
-	@Override
-	public void setPage(ICachedPage page) {
-	}
-
-	@Override
-	public ISearchOperationCallback getSearchOperationCallback() {
-		return searchCallback;
-	}
-
-	@Override
-	public void setSearchOperationCallback(
-			ISearchOperationCallback searchCallback) {
-		this.searchCallback = searchCallback;
-	}
-
-	@Override
-	public MultiComparator getOriginalKeyComparator() {
-		return btreeCmp;
-	}
-
-	@Override
-	public void setOriginialKeyComparator(MultiComparator originalCmp) {
-		this.btreeCmp = originalCmp;
-	}
+    private final ITreeIndexFrameFactory btreeInteriorFrameFactory;
+    private final ITreeIndexFrameFactory btreeLeafFrameFactory;
+    private final ITreeIndexFrameFactory buddyBtreeLeafFrameFactory;
+    private MultiComparator btreeCmp;
+    private MultiComparator buddyBtreeCmp;
+    private final ILSMHarness lsmHarness;
+
+    private ISearchOperationCallback searchCallback;
+    private List<ILSMComponent> operationalComponents;
+
+    public LSMBTreeWithBuddyCursorInitialState(ITreeIndexFrameFactory btreeInteriorFrameFactory,
+            ITreeIndexFrameFactory btreeLeafFrameFactory, ITreeIndexFrameFactory buddyBtreeLeafFrameFactory,
+            ILSMHarness lsmHarness, MultiComparator btreeCmp, MultiComparator buddyBtreeCmp,
+            ISearchOperationCallback searchCallback, List<ILSMComponent> operationalComponents) {
+        this.btreeLeafFrameFactory = btreeLeafFrameFactory;
+        this.btreeInteriorFrameFactory = btreeInteriorFrameFactory;
+        this.buddyBtreeLeafFrameFactory = buddyBtreeLeafFrameFactory;
+        this.btreeCmp = btreeCmp;
+        this.buddyBtreeCmp = buddyBtreeCmp;
+        this.lsmHarness = lsmHarness;
+        this.searchCallback = searchCallback;
+        this.operationalComponents = operationalComponents;
+    }
+
+    public ITreeIndexFrameFactory getBTreeInteriorFrameFactory() {
+        return btreeInteriorFrameFactory;
+    }
+
+    public ITreeIndexFrameFactory getBTreeLeafFrameFactory() {
+        return btreeLeafFrameFactory;
+    }
+
+    public ITreeIndexFrameFactory getBuddyBTreeLeafFrameFactory() {
+        return buddyBtreeLeafFrameFactory;
+    }
+
+    public MultiComparator getBTreeCmp() {
+        return btreeCmp;
+    }
+
+    public MultiComparator getBuddyBTreeCmp() {
+        return buddyBtreeCmp;
+    }
+
+    public List<ILSMComponent> getOperationalComponents() {
+        return operationalComponents;
+    }
+
+    public ILSMHarness getLSMHarness() {
+        return lsmHarness;
+    }
+
+    @Override
+    public ICachedPage getPage() {
+        return null;
+    }
+
+    @Override
+    public void setPage(ICachedPage page) {
+    }
+
+    @Override
+    public ISearchOperationCallback getSearchOperationCallback() {
+        return searchCallback;
+    }
+
+    @Override
+    public void setSearchOperationCallback(ISearchOperationCallback searchCallback) {
+        this.searchCallback = searchCallback;
+    }
+
+    @Override
+    public MultiComparator getOriginalKeyComparator() {
+        return btreeCmp;
+    }
+
+    @Override
+    public void setOriginialKeyComparator(MultiComparator originalCmp) {
+        this.btreeCmp = originalCmp;
+    }
+
+    public void setOperationalComponents(List<ILSMComponent> operationalComponents) {
+        this.operationalComponents = operationalComponents;
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb-hyracks/blob/a17fa8a9/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreeWithBuddySortedCursor.java
----------------------------------------------------------------------
diff --git a/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreeWithBuddySortedCursor.java b/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreeWithBuddySortedCursor.java
index 030f3d4..42ec6e8 100644
--- a/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreeWithBuddySortedCursor.java
+++ b/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreeWithBuddySortedCursor.java
@@ -30,6 +30,7 @@ public class LSMBTreeWithBuddySortedCursor extends
 	// TODO: This class can be removed and instead use a search cursor that uses
 	// a logic similar
 	// to the one in LSMRTreeWithAntiMatterTuplesSearchCursor
+    // currently, this cursor is only used when doing merge operations.
 	private boolean[] depletedBtreeCursors;
 	private int foundIn = -1;
 	private PermutingTupleReference buddyBtreeTuple;
@@ -64,7 +65,7 @@ public class LSMBTreeWithBuddySortedCursor extends
 					depletedBtreeCursors[i] = true;
 				}
 			}
-		} catch (IndexException e) {
+		} catch (Exception e) {
 			e.printStackTrace();
 			throw new HyracksDataException(
 					"error while reseting the btrees of the lsm btree with buddy btree",

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb-hyracks/blob/a17fa8a9/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/BloomFilterAwareBTreePointSearchCursor.java
----------------------------------------------------------------------
diff --git a/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/BloomFilterAwareBTreePointSearchCursor.java b/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/BloomFilterAwareBTreePointSearchCursor.java
index 9c484cd..34b4904 100644
--- a/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/BloomFilterAwareBTreePointSearchCursor.java
+++ b/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/BloomFilterAwareBTreePointSearchCursor.java
@@ -25,7 +25,7 @@ import org.apache.hyracks.storage.am.btree.api.IBTreeLeafFrame;
 import org.apache.hyracks.storage.am.btree.impls.BTreeRangeSearchCursor;
 
 public class BloomFilterAwareBTreePointSearchCursor extends BTreeRangeSearchCursor {
-    private final BloomFilter bloomFilter;
+    private BloomFilter bloomFilter;
     private long[] hashes = new long[2];
 
     public BloomFilterAwareBTreePointSearchCursor(IBTreeLeafFrame frame, boolean exclusiveLatchNodes,
@@ -41,4 +41,13 @@ public class BloomFilterAwareBTreePointSearchCursor extends BTreeRangeSearchCurs
         }
         return false;
     }
+
+    @Override
+    public boolean isBloomFilterAware() {
+        return true;
+    }
+
+    public void resetBloomFilter(BloomFilter bloomFilter) {
+        this.bloomFilter = bloomFilter;
+    }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb-hyracks/blob/a17fa8a9/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/LSMIndexSearchCursor.java
----------------------------------------------------------------------
diff --git a/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/LSMIndexSearchCursor.java b/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/LSMIndexSearchCursor.java
index 6273ea3..33938fa 100644
--- a/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/LSMIndexSearchCursor.java
+++ b/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/LSMIndexSearchCursor.java
@@ -39,6 +39,7 @@ import org.apache.hyracks.storage.common.buffercache.ICachedPage;
 public abstract class LSMIndexSearchCursor implements ITreeIndexCursor {
     protected PriorityQueueElement outputElement;
     protected IIndexCursor[] rangeCursors;
+    protected PriorityQueueElement[] pqes;
     protected PriorityQueue<PriorityQueueElement> outputPriorityQueue;
     protected PriorityQueueComparator pqCmp;
     protected MultiComparator cmp;
@@ -63,9 +64,30 @@ public abstract class LSMIndexSearchCursor implements ITreeIndexCursor {
 
     public void initPriorityQueue() throws HyracksDataException, IndexException {
         int pqInitSize = (rangeCursors.length > 0) ? rangeCursors.length : 1;
-        outputPriorityQueue = new PriorityQueue<PriorityQueueElement>(pqInitSize, pqCmp);
-        for (int i = 0; i < rangeCursors.length; i++) {
-            pushIntoPriorityQueue(new PriorityQueueElement(i));
+        if (outputPriorityQueue == null) {
+            outputPriorityQueue = new PriorityQueue<PriorityQueueElement>(pqInitSize, pqCmp);
+            pqes = new PriorityQueueElement[pqInitSize];
+            for (int i = 0; i < rangeCursors.length; i++) {
+                pqes[i] = new PriorityQueueElement(i);
+                pushIntoPriorityQueue(pqes[i]);
+            }
+        } else {
+            outputPriorityQueue.clear();
+            // did size change?
+            if (pqInitSize == pqes.length) {
+                // size is the same -> re-use
+                for (int i = 0; i < rangeCursors.length; i++) {
+                    pqes[i].reset(null);
+                    pushIntoPriorityQueue(pqes[i]);
+                }
+            } else {
+                // size changed (due to flushes, merges, etc) -> re-create
+                pqes = new PriorityQueueElement[pqInitSize];
+                for (int i = 0; i < rangeCursors.length; i++) {
+                    pqes[i] = new PriorityQueueElement(i);
+                    pushIntoPriorityQueue(pqes[i]);
+                }
+            }
         }
     }
 
@@ -265,6 +287,7 @@ public abstract class LSMIndexSearchCursor implements ITreeIndexCursor {
     }
 
     protected void setPriorityQueueComparator() {
+        // is there a case where cmp != pqCmp ??
         if (pqCmp == null || cmp != pqCmp.getMultiComparator()) {
             pqCmp = new PriorityQueueComparator(cmp);
         }