asterixdb-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From amo...@apache.org
Subject [6/6] asterixdb git commit: Fix upsert deadlock and upsert with filtered primary only
Date Thu, 25 May 2017 06:04:13 GMT
Fix upsert deadlock and upsert with filtered primary only

This change fixes a deadlock that happens when 3 operations
an upsert, a search and a flush happen simulteniously.
If all the memory components are full, the upsert
gets blocked, the upsert could've obtained a lock on the
search key which would block the search not allowing it
to exit the components and not allowing the components
to be cleared and reused.

In addition, the change refactors common LSM index code.

Change-Id: I93fac0f27ab0b3cc071ff38aef90d850cbbce488
Reviewed-on: https://asterix-gerrit.ics.uci.edu/1762
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
BAD: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Integration-Tests: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Reviewed-by: Murtadha Hubail <hubailmor@gmail.com>


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

Branch: refs/heads/master
Commit: 639fe8cb30a29b65cac583109b51f679d0a45871
Parents: d9b36ff
Author: Abdullah Alamoudi <bamousaa@gmail.com>
Authored: Wed May 24 21:40:23 2017 -0700
Committer: abdullah alamoudi <bamousaa@gmail.com>
Committed: Wed May 24 23:03:52 2017 -0700

----------------------------------------------------------------------
 .../NoOpFrameOperationCallbackFactory.java      |   2 +-
 .../AbstractLSMIOOperationCallback.java         |  43 +-
 .../LSMBTreeIOOperationCallback.java            |  43 --
 .../LSMBTreeWithBuddyIOOperationCallback.java   |  31 --
 .../LSMInvertedIndexIOOperationCallback.java    |  32 --
 .../LSMRTreeIOOperationCallback.java            |  31 --
 ...ilesIndexModificationOperatorDescriptor.java |   2 +-
 ...ternalIndexBulkModifyOperatorDescriptor.java |   7 +-
 ...rnalIndexBulkModifyOperatorNodePushable.java |  11 +-
 .../utils/SecondaryIndexOperationsHelper.java   |   2 +-
 .../LSMPrimaryUpsertOperatorNodePushable.java   |  26 +-
 .../hyracks/api/exceptions/ErrorCode.java       |   6 +
 .../src/main/resources/errormsg/en.properties   |   6 +
 .../hyracks/storage/am/btree/impls/BTree.java   |   2 +-
 .../btree/impls/BTreeCountingSearchCursor.java  |  17 +-
 .../am/btree/impls/BTreeRangeSearchCursor.java  |  16 +-
 .../storage/am/common/api/ITreeIndexCursor.java |  12 +-
 .../am/common/impls/AbstractTreeIndex.java      |  49 +-
 .../impls/TreeIndexDiskOrderScanCursor.java     |  12 +-
 .../am/common/tuples/DualTupleReference.java    |   2 +-
 .../am/lsm/btree/impls/ExternalBTree.java       |  70 ++-
 .../lsm/btree/impls/ExternalBTreeOpContext.java |  74 +--
 .../lsm/btree/impls/ExternalBTreeWithBuddy.java | 244 ++++----
 .../impls/ExternalBTreeWithBuddyOpContext.java  |  67 +--
 .../storage/am/lsm/btree/impls/LSMBTree.java    | 551 ++++---------------
 .../am/lsm/btree/impls/LSMBTreeBulkLoader.java  | 154 ++++++
 .../lsm/btree/impls/LSMBTreeFlushOperation.java |  83 +--
 .../lsm/btree/impls/LSMBTreeMergeOperation.java |  81 +--
 .../am/lsm/btree/impls/LSMBTreeOpContext.java   |  94 +---
 .../btree/impls/LSMBTreePointSearchCursor.java  |  19 +-
 .../lsm/btree/impls/LSMBTreeSearchCursor.java   |  14 +-
 .../impls/LSMBTreeWithBuddyAbstractCursor.java  |  14 +-
 .../impls/LSMBTreeWithBuddyMergeOperation.java  |  85 +--
 .../lsm/common/api/IFrameOperationCallback.java |   4 +-
 .../common/api/ILSMComponentFilterFactory.java  |  11 +-
 .../storage/am/lsm/common/api/ILSMHarness.java  |  33 +-
 .../am/lsm/common/api/ILSMIOOperation.java      |  28 +-
 .../storage/am/lsm/common/api/ILSMIndex.java    |  11 +-
 .../am/lsm/common/api/ILSMIndexAccessor.java    |  11 +
 .../common/api/ILSMIndexOperationContext.java   |   8 +
 .../storage/am/lsm/common/api/ITwoPCIndex.java  |   4 +-
 .../lsm/common/impls/AbstractIoOperation.java   |  64 +++
 .../am/lsm/common/impls/AbstractLSMIndex.java   | 368 ++++++++++++-
 .../impls/AbstractLSMIndexOperationContext.java | 108 +++-
 .../lsm/common/impls/AsynchronousScheduler.java |   4 +-
 .../lsm/common/impls/DiskComponentMetadata.java |   4 +
 .../am/lsm/common/impls/FlushOperation.java     |  92 ++++
 .../common/impls/LSMComponentFilterFactory.java |   5 +
 .../storage/am/lsm/common/impls/LSMHarness.java |  31 ++
 .../common/impls/LSMIndexReplicationJob.java    |   2 +-
 .../lsm/common/impls/LSMIndexSearchCursor.java  |  13 +-
 .../lsm/common/impls/LSMTreeIndexAccessor.java  |  48 +-
 .../am/lsm/common/impls/MergeOperation.java     |  60 ++
 .../invertedindex/impls/LSMInvertedIndex.java   | 436 +++++----------
 .../impls/LSMInvertedIndexAccessor.java         |  18 +
 .../impls/LSMInvertedIndexFlushOperation.java   |  82 +--
 .../impls/LSMInvertedIndexMergeOperation.java   |  83 +--
 .../impls/LSMInvertedIndexOpContext.java        | 114 +---
 .../am/lsm/rtree/impls/AbstractLSMRTree.java    | 238 ++------
 .../am/lsm/rtree/impls/ExternalRTree.java       |  85 +--
 .../lsm/rtree/impls/ExternalRTreeOpContext.java |  74 +--
 .../storage/am/lsm/rtree/impls/LSMRTree.java    | 322 +++--------
 .../lsm/rtree/impls/LSMRTreeAbstractCursor.java |  13 +-
 .../am/lsm/rtree/impls/LSMRTreeAccessor.java    |  57 ++
 .../am/lsm/rtree/impls/LSMRTreeBulkLoader.java  | 129 +++++
 .../lsm/rtree/impls/LSMRTreeFlushOperation.java |  81 +--
 .../lsm/rtree/impls/LSMRTreeMergeOperation.java |  94 +---
 .../am/lsm/rtree/impls/LSMRTreeOpContext.java   |  96 +---
 .../impls/LSMRTreeWithAntiMatterTuples.java     | 178 ++----
 ...LSMRTreeWithAntiMatterTuplesFlushCursor.java |  13 +-
 .../am/lsm/rtree/impls/TreeTupleSorter.java     |  16 +-
 .../am/rtree/impls/RTreeSearchCursor.java       |  20 +-
 .../apache/hyracks/storage/common/IIndex.java   |   6 +-
 .../btree/multithread/LSMBTreeTestWorker.java   |   8 +-
 .../am/lsm/common/DummyLSMIndexFileManager.java |  53 --
 .../storage/am/lsm/common/DummyTreeFactory.java |  37 --
 .../common/LSMComponentFilterReferenceTest.java |  63 ---
 .../am/lsm/common/LSMIndexFileManagerTest.java  | 268 ---------
 .../am/lsm/common/VirtualBufferCacheTest.java   | 139 -----
 .../lsm/common/VirtualFreePageManagerTest.java  |  73 ---
 .../component/TestLsmIndexFileManager.java      |  52 ++
 .../test/LSMComponentFilterReferenceTest.java   |  63 +++
 .../common/test/LSMIndexFileManagerTest.java    | 267 +++++++++
 .../lsm/common/test/VirtualBufferCacheTest.java | 139 +++++
 .../common/test/VirtualFreePageManagerTest.java |  73 +++
 .../rtree/multithread/LSMRTreeTestWorker.java   |   6 +-
 .../LSMRTreeWithAntiMatterTuplesTestWorker.java |   8 +-
 87 files changed, 2646 insertions(+), 3569 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/asterixdb/blob/639fe8cb/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/dataflow/NoOpFrameOperationCallbackFactory.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/dataflow/NoOpFrameOperationCallbackFactory.java b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/dataflow/NoOpFrameOperationCallbackFactory.java
index 3952b11..5e3879f 100644
--- a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/dataflow/NoOpFrameOperationCallbackFactory.java
+++ b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/dataflow/NoOpFrameOperationCallbackFactory.java
@@ -40,7 +40,7 @@ public class NoOpFrameOperationCallbackFactory implements IFrameOperationCallbac
 
     private static class NoOpFrameOperationCallback implements IFrameOperationCallback {
         @Override
-        public void frameCompleted(boolean modified) throws HyracksDataException {
+        public void frameCompleted() throws HyracksDataException {
             // No Op
         }
     }

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/639fe8cb/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/ioopcallbacks/AbstractLSMIOOperationCallback.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/ioopcallbacks/AbstractLSMIOOperationCallback.java b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/ioopcallbacks/AbstractLSMIOOperationCallback.java
index d04443a..ec7df85 100644
--- a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/ioopcallbacks/AbstractLSMIOOperationCallback.java
+++ b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/ioopcallbacks/AbstractLSMIOOperationCallback.java
@@ -24,12 +24,13 @@ import java.util.List;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.data.std.primitive.LongPointable;
 import org.apache.hyracks.storage.am.common.api.IMetadataPageManager;
-import org.apache.hyracks.storage.am.common.api.ITreeIndex;
 import org.apache.hyracks.storage.am.common.freepage.MutableArrayValueReference;
 import org.apache.hyracks.storage.am.lsm.common.api.ILSMComponent;
 import org.apache.hyracks.storage.am.lsm.common.api.ILSMDiskComponent;
 import org.apache.hyracks.storage.am.lsm.common.api.ILSMIOOperationCallback;
 import org.apache.hyracks.storage.am.lsm.common.api.LSMOperationType;
+import org.apache.hyracks.storage.am.lsm.common.impls.DiskComponentMetadata;
+import org.apache.hyracks.storage.am.lsm.common.utils.ComponentMetadataUtil;
 
 // A single LSMIOOperationCallback per LSM index used to perform actions around Flush and Merge operations
 public abstract class AbstractLSMIOOperationCallback implements ILSMIOOperationCallback {
@@ -93,16 +94,14 @@ public abstract class AbstractLSMIOOperationCallback implements ILSMIOOperationC
         }
     }
 
-    public abstract long getComponentLSN(List<? extends ILSMComponent> oldComponents) throws HyracksDataException;
-
     public void putLSNIntoMetadata(ILSMDiskComponent index, List<ILSMComponent> oldComponents)
             throws HyracksDataException {
         index.getMetadata().put(LSN_KEY, LongPointable.FACTORY.createPointable(getComponentLSN(oldComponents)));
     }
 
-    public static long getTreeIndexLSN(ITreeIndex treeIndex) throws HyracksDataException {
+    public static long getTreeIndexLSN(DiskComponentMetadata md) throws HyracksDataException {
         LongPointable pointable = new LongPointable();
-        IMetadataPageManager metadataPageManager = (IMetadataPageManager) treeIndex.getPageManager();
+        IMetadataPageManager metadataPageManager = md.getMetadataPageManager();
         metadataPageManager.get(metadataPageManager.createMetadataFrame(), LSN_KEY, pointable);
         return pointable.getLength() == 0 ? INVALID : pointable.longValue();
     }
@@ -139,6 +138,40 @@ public abstract class AbstractLSMIOOperationCallback implements ILSMIOOperationC
         return false;
     }
 
+    @Override
+    public final void afterOperation(LSMOperationType opType, List<ILSMComponent> oldComponents,
+            ILSMDiskComponent newComponent) throws HyracksDataException {
+        //TODO: Copying Filters and all content of the metadata pages for flush operation should be done here
+        if (newComponent != null) {
+            putLSNIntoMetadata(newComponent, oldComponents);
+            if (opType == LSMOperationType.MERGE) {
+                LongPointable markerLsn = LongPointable.FACTORY
+                        .createPointable(ComponentMetadataUtil.getLong(oldComponents.get(0).getMetadata(),
+                                ComponentMetadataUtil.MARKER_LSN_KEY, ComponentMetadataUtil.NOT_FOUND));
+                newComponent.getMetadata().put(ComponentMetadataUtil.MARKER_LSN_KEY, markerLsn);
+            }
+
+        }
+    }
+
+    public long getComponentLSN(List<? extends ILSMComponent> diskComponents) throws HyracksDataException {
+        if (diskComponents == null) {
+            // Implies a flush IO operation. --> moves the flush pointer
+            // Flush operation of an LSM index are executed sequentially.
+            synchronized (this) {
+                long lsn = mutableLastLSNs[readIndex];
+                return lsn;
+            }
+        }
+        // Get max LSN from the diskComponents. Implies a merge IO operation or Recovery operation.
+        long maxLSN = -1L;
+        for (ILSMComponent c : diskComponents) {
+            DiskComponentMetadata md = ((ILSMDiskComponent) c).getMetadata();
+            maxLSN = Math.max(getTreeIndexLSN(md), maxLSN);
+        }
+        return maxLSN;
+    }
+
     /**
      * @param component
      * @param componentFilePath

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/639fe8cb/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/ioopcallbacks/LSMBTreeIOOperationCallback.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/ioopcallbacks/LSMBTreeIOOperationCallback.java b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/ioopcallbacks/LSMBTreeIOOperationCallback.java
index 173c962..b9442dc 100644
--- a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/ioopcallbacks/LSMBTreeIOOperationCallback.java
+++ b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/ioopcallbacks/LSMBTreeIOOperationCallback.java
@@ -19,18 +19,11 @@
 
 package org.apache.asterix.common.ioopcallbacks;
 
-import java.util.List;
-
 import org.apache.hyracks.api.exceptions.HyracksDataException;
-import org.apache.hyracks.data.std.primitive.LongPointable;
-import org.apache.hyracks.storage.am.btree.impls.BTree;
 import org.apache.hyracks.storage.am.common.api.IMetadataPageManager;
 import org.apache.hyracks.storage.am.lsm.btree.impls.LSMBTreeDiskComponent;
 import org.apache.hyracks.storage.am.lsm.btree.impls.LSMBTreeFileManager;
-import org.apache.hyracks.storage.am.lsm.common.api.ILSMComponent;
 import org.apache.hyracks.storage.am.lsm.common.api.ILSMDiskComponent;
-import org.apache.hyracks.storage.am.lsm.common.api.LSMOperationType;
-import org.apache.hyracks.storage.am.lsm.common.utils.ComponentMetadataUtil;
 
 public class LSMBTreeIOOperationCallback extends AbstractLSMIOOperationCallback {
 
@@ -39,42 +32,6 @@ public class LSMBTreeIOOperationCallback extends AbstractLSMIOOperationCallback
     }
 
     @Override
-    public void afterOperation(LSMOperationType opType, List<ILSMComponent> oldComponents,
-            ILSMDiskComponent newComponent) throws HyracksDataException {
-        //TODO: Copying Filters and all content of the metadata pages for flush operation should be done here
-        if (newComponent != null) {
-            LSMBTreeDiskComponent btreeComponent = (LSMBTreeDiskComponent) newComponent;
-            putLSNIntoMetadata(btreeComponent, oldComponents);
-            if (opType == LSMOperationType.MERGE) {
-                LongPointable markerLsn = LongPointable.FACTORY
-                        .createPointable(ComponentMetadataUtil.getLong(oldComponents.get(0).getMetadata(),
-                                ComponentMetadataUtil.MARKER_LSN_KEY, ComponentMetadataUtil.NOT_FOUND));
-                btreeComponent.getMetadata().put(ComponentMetadataUtil.MARKER_LSN_KEY, markerLsn);
-            }
-
-        }
-    }
-
-    @Override
-    public long getComponentLSN(List<? extends ILSMComponent> diskComponents) throws HyracksDataException {
-        if (diskComponents == null) {
-            // Implies a flush IO operation. --> moves the flush pointer
-            // Flush operation of an LSM index are executed sequentially.
-            synchronized (this) {
-                long lsn = mutableLastLSNs[readIndex];
-                return lsn;
-            }
-        }
-        // Get max LSN from the diskComponents. Implies a merge IO operation or Recovery operation.
-        long maxLSN = -1L;
-        for (ILSMComponent c : diskComponents) {
-            BTree btree = ((LSMBTreeDiskComponent) c).getBTree();
-            maxLSN = Math.max(AbstractLSMIOOperationCallback.getTreeIndexLSN(btree), maxLSN);
-        }
-        return maxLSN;
-    }
-
-    @Override
     public long getComponentFileLSNOffset(ILSMDiskComponent diskComponent, String diskComponentFilePath)
             throws HyracksDataException {
         if (diskComponentFilePath.endsWith(LSMBTreeFileManager.BTREE_STRING)) {

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/639fe8cb/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/ioopcallbacks/LSMBTreeWithBuddyIOOperationCallback.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/ioopcallbacks/LSMBTreeWithBuddyIOOperationCallback.java b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/ioopcallbacks/LSMBTreeWithBuddyIOOperationCallback.java
index 6c987d6..0e80397 100644
--- a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/ioopcallbacks/LSMBTreeWithBuddyIOOperationCallback.java
+++ b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/ioopcallbacks/LSMBTreeWithBuddyIOOperationCallback.java
@@ -18,46 +18,15 @@
  */
 package org.apache.asterix.common.ioopcallbacks;
 
-import java.util.List;
-
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.storage.am.common.api.IMetadataPageManager;
 import org.apache.hyracks.storage.am.lsm.btree.impls.LSMBTreeWithBuddyDiskComponent;
 import org.apache.hyracks.storage.am.lsm.btree.impls.LSMBTreeWithBuddyFileManager;
-import org.apache.hyracks.storage.am.lsm.common.api.ILSMComponent;
 import org.apache.hyracks.storage.am.lsm.common.api.ILSMDiskComponent;
-import org.apache.hyracks.storage.am.lsm.common.api.LSMOperationType;
 
 public class LSMBTreeWithBuddyIOOperationCallback extends AbstractLSMIOOperationCallback {
 
     @Override
-    public void afterOperation(LSMOperationType opType, List<ILSMComponent> oldComponents,
-            ILSMDiskComponent newComponent) throws HyracksDataException {
-        if (newComponent != null) {
-            LSMBTreeWithBuddyDiskComponent btreeComponent = (LSMBTreeWithBuddyDiskComponent) newComponent;
-            putLSNIntoMetadata(btreeComponent, oldComponents);
-        }
-    }
-
-    @Override
-    public long getComponentLSN(List<? extends ILSMComponent> diskComponents) throws HyracksDataException {
-        if (diskComponents == null) {
-            // Implies a flush IO operation <Will never happen currently as Btree with buddy btree is only used with external datasets>
-            synchronized (this) {
-                long lsn = mutableLastLSNs[readIndex];
-                return lsn;
-            }
-        }
-        // Get max LSN from the diskComponents. Implies a merge IO operation or Recovery operation.
-        long maxLSN = -1;
-        for (Object o : diskComponents) {
-            LSMBTreeWithBuddyDiskComponent btreeComponent = (LSMBTreeWithBuddyDiskComponent) o;
-            maxLSN = Math.max(AbstractLSMIOOperationCallback.getTreeIndexLSN(btreeComponent.getBTree()), maxLSN);
-        }
-        return maxLSN;
-    }
-
-    @Override
     public long getComponentFileLSNOffset(ILSMDiskComponent diskComponent, String diskComponentFilePath)
             throws HyracksDataException {
         if (diskComponentFilePath.endsWith(LSMBTreeWithBuddyFileManager.BTREE_STRING)) {

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/639fe8cb/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/ioopcallbacks/LSMInvertedIndexIOOperationCallback.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/ioopcallbacks/LSMInvertedIndexIOOperationCallback.java b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/ioopcallbacks/LSMInvertedIndexIOOperationCallback.java
index 657d908..69286d5 100644
--- a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/ioopcallbacks/LSMInvertedIndexIOOperationCallback.java
+++ b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/ioopcallbacks/LSMInvertedIndexIOOperationCallback.java
@@ -19,13 +19,9 @@
 
 package org.apache.asterix.common.ioopcallbacks;
 
-import java.util.List;
-
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.storage.am.common.api.IMetadataPageManager;
-import org.apache.hyracks.storage.am.lsm.common.api.ILSMComponent;
 import org.apache.hyracks.storage.am.lsm.common.api.ILSMDiskComponent;
-import org.apache.hyracks.storage.am.lsm.common.api.LSMOperationType;
 import org.apache.hyracks.storage.am.lsm.invertedindex.impls.LSMInvertedIndexDiskComponent;
 import org.apache.hyracks.storage.am.lsm.invertedindex.impls.LSMInvertedIndexFileManager;
 
@@ -36,34 +32,6 @@ public class LSMInvertedIndexIOOperationCallback extends AbstractLSMIOOperationC
     }
 
     @Override
-    public void afterOperation(LSMOperationType opType, List<ILSMComponent> oldComponents,
-            ILSMDiskComponent newComponent) throws HyracksDataException {
-        if (newComponent != null) {
-            LSMInvertedIndexDiskComponent invIndexComponent = (LSMInvertedIndexDiskComponent) newComponent;
-            putLSNIntoMetadata(invIndexComponent, oldComponents);
-        }
-    }
-
-    @Override
-    public long getComponentLSN(List<? extends ILSMComponent> diskComponents) throws HyracksDataException {
-        if (diskComponents == null) {
-            // Implies a flush IO operation.
-            synchronized (this) {
-                long lsn = mutableLastLSNs[readIndex];
-                return lsn;
-            }
-        }
-        // Get max LSN from the diskComponents. Implies a merge IO operation or Recovery operation.
-        long maxLSN = -1;
-        for (Object o : diskComponents) {
-            LSMInvertedIndexDiskComponent invIndexComponent = (LSMInvertedIndexDiskComponent) o;
-            maxLSN = Math.max(AbstractLSMIOOperationCallback.getTreeIndexLSN(invIndexComponent.getDeletedKeysBTree()),
-                    maxLSN);
-        }
-        return maxLSN;
-    }
-
-    @Override
     public long getComponentFileLSNOffset(ILSMDiskComponent diskComponent, String diskComponentFilePath)
             throws HyracksDataException {
         if (diskComponentFilePath.endsWith(LSMInvertedIndexFileManager.DELETED_KEYS_BTREE_SUFFIX)) {

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/639fe8cb/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/ioopcallbacks/LSMRTreeIOOperationCallback.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/ioopcallbacks/LSMRTreeIOOperationCallback.java b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/ioopcallbacks/LSMRTreeIOOperationCallback.java
index 2dc06f7..4908c08 100644
--- a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/ioopcallbacks/LSMRTreeIOOperationCallback.java
+++ b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/ioopcallbacks/LSMRTreeIOOperationCallback.java
@@ -19,13 +19,9 @@
 
 package org.apache.asterix.common.ioopcallbacks;
 
-import java.util.List;
-
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.storage.am.common.api.IMetadataPageManager;
-import org.apache.hyracks.storage.am.lsm.common.api.ILSMComponent;
 import org.apache.hyracks.storage.am.lsm.common.api.ILSMDiskComponent;
-import org.apache.hyracks.storage.am.lsm.common.api.LSMOperationType;
 import org.apache.hyracks.storage.am.lsm.rtree.impls.LSMRTreeDiskComponent;
 import org.apache.hyracks.storage.am.lsm.rtree.impls.LSMRTreeFileManager;
 
@@ -36,33 +32,6 @@ public class LSMRTreeIOOperationCallback extends AbstractLSMIOOperationCallback
     }
 
     @Override
-    public void afterOperation(LSMOperationType opType, List<ILSMComponent> oldComponents,
-            ILSMDiskComponent newComponent) throws HyracksDataException {
-        if (newComponent != null) {
-            LSMRTreeDiskComponent rtreeComponent = (LSMRTreeDiskComponent) newComponent;
-            putLSNIntoMetadata(rtreeComponent, oldComponents);
-        }
-    }
-
-    @Override
-    public long getComponentLSN(List<? extends ILSMComponent> diskComponents) throws HyracksDataException {
-        if (diskComponents == null) {
-            // Implies a flush IO operation.
-            synchronized (this) {
-                long lsn = mutableLastLSNs[readIndex];
-                return lsn;
-            }
-        }
-        // Get max LSN from the diskComponents. Implies a merge IO operation or Recovery operation.
-        long maxLSN = INVALID;
-        for (Object o : diskComponents) {
-            LSMRTreeDiskComponent rtreeComponent = (LSMRTreeDiskComponent) o;
-            maxLSN = Math.max(AbstractLSMIOOperationCallback.getTreeIndexLSN(rtreeComponent.getRTree()), maxLSN);
-        }
-        return maxLSN;
-    }
-
-    @Override
     public long getComponentFileLSNOffset(ILSMDiskComponent diskComponent, String diskComponentFilePath)
             throws HyracksDataException {
         if (diskComponentFilePath.endsWith(LSMRTreeFileManager.RTREE_STRING)) {

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/639fe8cb/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/operators/ExternalFilesIndexModificationOperatorDescriptor.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/operators/ExternalFilesIndexModificationOperatorDescriptor.java b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/operators/ExternalFilesIndexModificationOperatorDescriptor.java
index f4fb455..94ef285 100644
--- a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/operators/ExternalFilesIndexModificationOperatorDescriptor.java
+++ b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/operators/ExternalFilesIndexModificationOperatorDescriptor.java
@@ -70,7 +70,7 @@ public class ExternalFilesIndexModificationOperatorDescriptor extends AbstractSi
                 LSMTwoPCBTreeBulkLoader bulkLoader = null;
                 try {
                     bulkLoader = (LSMTwoPCBTreeBulkLoader) ((ExternalBTree) index)
-                            .createTransactionBulkLoader(BTree.DEFAULT_FILL_FACTOR, false, files.size(), false);
+                            .createTransactionBulkLoader(BTree.DEFAULT_FILL_FACTOR, false, files.size());
                     // Load files
                     // The files must be ordered according to their numbers
                     for (ExternalFile file : files) {

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/639fe8cb/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/operators/ExternalIndexBulkModifyOperatorDescriptor.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/operators/ExternalIndexBulkModifyOperatorDescriptor.java b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/operators/ExternalIndexBulkModifyOperatorDescriptor.java
index 52230e0..60f1721 100644
--- a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/operators/ExternalIndexBulkModifyOperatorDescriptor.java
+++ b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/operators/ExternalIndexBulkModifyOperatorDescriptor.java
@@ -33,9 +33,8 @@ public class ExternalIndexBulkModifyOperatorDescriptor extends TreeIndexBulkLoad
 
     public ExternalIndexBulkModifyOperatorDescriptor(IOperatorDescriptorRegistry spec,
             IIndexDataflowHelperFactory dataflowHelperFactory, int[] deletedFiles, int[] fieldPermutation,
-            float fillFactor, boolean verifyInput, long numElementsHint, boolean checkIfEmpty) {
-        super(spec, null, fieldPermutation, fillFactor, verifyInput, numElementsHint, checkIfEmpty,
-                dataflowHelperFactory);
+            float fillFactor, boolean verifyInput, long numElementsHint) {
+        super(spec, null, fieldPermutation, fillFactor, verifyInput, numElementsHint, false, dataflowHelperFactory);
         this.deletedFiles = deletedFiles;
     }
 
@@ -43,7 +42,7 @@ public class ExternalIndexBulkModifyOperatorDescriptor extends TreeIndexBulkLoad
     public IOperatorNodePushable createPushRuntime(IHyracksTaskContext ctx,
             IRecordDescriptorProvider recordDescProvider, int partition, int nPartitions) throws HyracksDataException {
         return new ExternalIndexBulkModifyOperatorNodePushable(indexHelperFactory, ctx, partition, fieldPermutation,
-                fillFactor, verifyInput, numElementsHint, checkIfEmptyIndex,
+                fillFactor, verifyInput, numElementsHint,
                 recordDescProvider.getInputRecordDescriptor(getActivityId(), 0), deletedFiles);
     }
 

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/639fe8cb/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/operators/ExternalIndexBulkModifyOperatorNodePushable.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/operators/ExternalIndexBulkModifyOperatorNodePushable.java b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/operators/ExternalIndexBulkModifyOperatorNodePushable.java
index e47bb07..45d424e 100644
--- a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/operators/ExternalIndexBulkModifyOperatorNodePushable.java
+++ b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/operators/ExternalIndexBulkModifyOperatorNodePushable.java
@@ -43,10 +43,9 @@ public class ExternalIndexBulkModifyOperatorNodePushable extends IndexBulkLoadOp
 
     public ExternalIndexBulkModifyOperatorNodePushable(IIndexDataflowHelperFactory indexHelperFactory,
             IHyracksTaskContext ctx, int partition, int[] fieldPermutation, float fillFactor, boolean verifyInput,
-            long numElementsHint, boolean checkIfEmpty, RecordDescriptor inputRecDesc, int[] deletedFiles)
-            throws HyracksDataException {
-        super(indexHelperFactory, ctx, partition, fieldPermutation, fillFactor, verifyInput, numElementsHint,
-                checkIfEmpty, inputRecDesc);
+            long numElementsHint, RecordDescriptor inputRecDesc, int[] deletedFiles) throws HyracksDataException {
+        super(indexHelperFactory, ctx, partition, fieldPermutation, fillFactor, verifyInput, numElementsHint, false,
+                inputRecDesc);
         this.deletedFiles = deletedFiles;
     }
 
@@ -61,8 +60,8 @@ public class ExternalIndexBulkModifyOperatorNodePushable extends IndexBulkLoadOp
         try {
             writer.open();
             // Transactional BulkLoader
-            bulkLoader = ((ITwoPCIndex) index).createTransactionBulkLoader(fillFactor, verifyInput, deletedFiles.length,
-                    checkIfEmptyIndex);
+            bulkLoader =
+                    ((ITwoPCIndex) index).createTransactionBulkLoader(fillFactor, verifyInput, deletedFiles.length);
             // Delete files
             for (int i = 0; i < deletedFiles.length; i++) {
                 fileNumber.setValue(deletedFiles[i]);

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/639fe8cb/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/utils/SecondaryIndexOperationsHelper.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/utils/SecondaryIndexOperationsHelper.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/utils/SecondaryIndexOperationsHelper.java
index fa519e1..86e3911 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/utils/SecondaryIndexOperationsHelper.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/utils/SecondaryIndexOperationsHelper.java
@@ -515,7 +515,7 @@ public abstract class SecondaryIndexOperationsHelper {
             }
         }
         ExternalIndexBulkModifyOperatorDescriptor treeIndexBulkLoadOp = new ExternalIndexBulkModifyOperatorDescriptor(
-                spec, dataflowHelperFactory, deletedFiles, fieldPermutation, fillFactor, false, numElementsHint, false);
+                spec, dataflowHelperFactory, deletedFiles, fieldPermutation, fillFactor, false, numElementsHint);
         AlgebricksPartitionConstraintHelper.setPartitionConstraintInJobSpec(spec, treeIndexBulkLoadOp,
                 secondaryPartitionConstraint);
         return treeIndexBulkLoadOp;

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/639fe8cb/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/operators/LSMPrimaryUpsertOperatorNodePushable.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/operators/LSMPrimaryUpsertOperatorNodePushable.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/operators/LSMPrimaryUpsertOperatorNodePushable.java
index bff3ca6..40635c8 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/operators/LSMPrimaryUpsertOperatorNodePushable.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/operators/LSMPrimaryUpsertOperatorNodePushable.java
@@ -214,8 +214,8 @@ public class LSMPrimaryUpsertOperatorNodePushable extends LSMIndexInsertUpdateDe
         accessor.reset(buffer);
         LSMTreeIndexAccessor lsmAccessor = (LSMTreeIndexAccessor) indexAccessor;
         int tupleCount = accessor.getTupleCount();
-        boolean firstModification = true;
         int i = 0;
+        lsmAccessor.enter();
         try {
             while (i < tupleCount) {
                 tb.reset();
@@ -223,7 +223,7 @@ public class LSMPrimaryUpsertOperatorNodePushable extends LSMIndexInsertUpdateDe
                 boolean recordWasDeleted = false;
                 tuple.reset(accessor, i);
                 resetSearchPredicate(i);
-                if (hasSecondaries) {
+                if (isFiltered || hasSecondaries) {
                     lsmAccessor.search(cursor, searchPred);
                     if (cursor.hasNext()) {
                         cursor.next();
@@ -243,31 +243,27 @@ public class LSMPrimaryUpsertOperatorNodePushable extends LSMIndexInsertUpdateDe
                 if (isDeleteOperation(tuple, numOfPrimaryKeys)) {
                     // Only delete if it is a delete and not upsert
                     abstractModCallback.setOp(Operation.DELETE);
-                    if (firstModification) {
-                        lsmAccessor.delete(tuple);
-                        firstModification = false;
-                    } else {
-                        lsmAccessor.forceDelete(tuple);
-                    }
+                    lsmAccessor.forceDelete(tuple);
                     recordWasDeleted = true;
                 } else {
                     abstractModCallback.setOp(Operation.UPSERT);
-                    if (firstModification) {
-                        lsmAccessor.upsert(tuple);
-                        firstModification = false;
-                    } else {
-                        lsmAccessor.forceUpsert(tuple);
-                    }
+                    lsmAccessor.forceUpsert(tuple);
                     recordWasInserted = true;
                 }
+                if (isFiltered && prevTuple != null) {
+                    // need to update the filter of the new component with the previous value
+                    lsmAccessor.updateFilter(prevTuple);
+                }
                 writeOutput(i, recordWasInserted, recordWasDeleted);
                 i++;
             }
             // callback here before calling nextFrame on the next operator
-            frameOpCallback.frameCompleted(!firstModification);
+            frameOpCallback.frameCompleted();
             appender.write(writer, true);
         } catch (Exception e) {
             throw HyracksDataException.create(e);
+        } finally {
+            lsmAccessor.exit();
         }
     }
 

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/639fe8cb/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/exceptions/ErrorCode.java
----------------------------------------------------------------------
diff --git a/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/exceptions/ErrorCode.java b/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/exceptions/ErrorCode.java
index e321a1d..7eaeafb 100644
--- a/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/exceptions/ErrorCode.java
+++ b/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/exceptions/ErrorCode.java
@@ -82,6 +82,12 @@ public class ErrorCode {
     public static final int UNSORTED_LOAD_INPUT = 46;
     public static final int OPERATION_EXCEEDED_MAX_RESTARTS = 47;
     public static final int DUPLICATE_LOAD_INPUT = 48;
+    public static final int CANNOT_CREATE_ACTIVE_INDEX = 49;
+    public static final int CANNOT_ACTIVATE_ACTIVE_INDEX = 50;
+    public static final int CANNOT_DEACTIVATE_INACTIVE_INDEX = 51;
+    public static final int CANNOT_DESTROY_ACTIVE_INDEX = 52;
+    public static final int CANNOT_CLEAR_INACTIVE_INDEX = 53;
+    public static final int CANNOT_ALLOCATE_MEMORY_FOR_INACTIVE_INDEX = 54;
 
     // Compilation error codes.
     public static final int RULECOLLECTION_NOT_INSTANCE_OF_LIST = 10000;

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/639fe8cb/hyracks-fullstack/hyracks/hyracks-api/src/main/resources/errormsg/en.properties
----------------------------------------------------------------------
diff --git a/hyracks-fullstack/hyracks/hyracks-api/src/main/resources/errormsg/en.properties b/hyracks-fullstack/hyracks/hyracks-api/src/main/resources/errormsg/en.properties
index c3c2596..e95e7f4 100644
--- a/hyracks-fullstack/hyracks/hyracks-api/src/main/resources/errormsg/en.properties
+++ b/hyracks-fullstack/hyracks/hyracks-api/src/main/resources/errormsg/en.properties
@@ -67,5 +67,11 @@
 46 = Unsorted load input
 47 = Operation exceeded the maximum number of restarts %1$s
 48 = Loading duplicate keys into the primary storage
+49 = Failed to create the index since it is active
+50 = Failed to activate the index since it is active
+51 = Failed to deactivate the index since it is inactive
+52 = Failed to destroy the index since it is active
+53 = Failed to clear the index since it is inactive
+54 = Failed to allocate memory components for the index since it is inactive
 
 10000 = The given rule collection %1$s is not an instance of the List class.

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/639fe8cb/hyracks-fullstack/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/BTree.java
----------------------------------------------------------------------
diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/BTree.java b/hyracks-fullstack/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/BTree.java
index e98db9b..7f57524 100644
--- a/hyracks-fullstack/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/BTree.java
+++ b/hyracks-fullstack/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/BTree.java
@@ -535,7 +535,7 @@ public class BTree extends AbstractTreeIndex {
     }
 
     private final boolean acquireLatch(ICachedPage node, BTreeOpContext ctx, boolean isLeaf) {
-        if (!isLeaf || (ctx.getOperation() == IndexOperation.SEARCH && !ctx.getCursor().exclusiveLatchNodes())) {
+        if (!isLeaf || (ctx.getOperation() == IndexOperation.SEARCH && !ctx.getCursor().isExclusiveLatchNodes())) {
             node.acquireReadLatch();
             return true;
         } else {

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/639fe8cb/hyracks-fullstack/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/BTreeCountingSearchCursor.java
----------------------------------------------------------------------
diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/BTreeCountingSearchCursor.java b/hyracks-fullstack/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/BTreeCountingSearchCursor.java
index 92f1ae9..d7084bb 100644
--- a/hyracks-fullstack/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/BTreeCountingSearchCursor.java
+++ b/hyracks-fullstack/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/BTreeCountingSearchCursor.java
@@ -244,11 +244,6 @@ public class BTreeCountingSearchCursor implements ITreeIndexCursor {
     }
 
     @Override
-    public ICachedPage getPage() {
-        return page;
-    }
-
-    @Override
     public void setBufferCache(IBufferCache bufferCache) {
         this.bufferCache = bufferCache;
     }
@@ -259,17 +254,7 @@ public class BTreeCountingSearchCursor implements ITreeIndexCursor {
     }
 
     @Override
-    public boolean exclusiveLatchNodes() {
+    public boolean isExclusiveLatchNodes() {
         return exclusiveLatchNodes;
     }
-
-    @Override
-    public void markCurrentTupleAsUpdated() throws HyracksDataException {
-        if (exclusiveLatchNodes) {
-            isPageDirty = true;
-        } else {
-            throw new HyracksDataException("This cursor has not been created with the intention to allow updates.");
-        }
-    }
-
 }

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/639fe8cb/hyracks-fullstack/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/BTreeRangeSearchCursor.java
----------------------------------------------------------------------
diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/BTreeRangeSearchCursor.java b/hyracks-fullstack/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/BTreeRangeSearchCursor.java
index 64e7399..32cc7ee 100644
--- a/hyracks-fullstack/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/BTreeRangeSearchCursor.java
+++ b/hyracks-fullstack/hyracks/hyracks-storage-am-btree/src/main/java/org/apache/hyracks/storage/am/btree/impls/BTreeRangeSearchCursor.java
@@ -112,11 +112,6 @@ public class BTreeRangeSearchCursor implements ITreeIndexCursor {
         return null;
     }
 
-    @Override
-    public ICachedPage getPage() {
-        return page;
-    }
-
     public int getTupleOffset() {
         return frame.getTupleOffset(tupleIndex - 1);
     }
@@ -312,19 +307,10 @@ public class BTreeRangeSearchCursor implements ITreeIndexCursor {
     }
 
     @Override
-    public boolean exclusiveLatchNodes() {
+    public boolean isExclusiveLatchNodes() {
         return exclusiveLatchNodes;
     }
 
-    @Override
-    public void markCurrentTupleAsUpdated() throws HyracksDataException {
-        if (exclusiveLatchNodes) {
-            isPageDirty = true;
-        } else {
-            throw new HyracksDataException("This cursor has not been created with the intention to allow updates.");
-        }
-    }
-
     public boolean isBloomFilterAware() {
         return false;
     }

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/639fe8cb/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/api/ITreeIndexCursor.java
----------------------------------------------------------------------
diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/api/ITreeIndexCursor.java b/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/api/ITreeIndexCursor.java
index d0771bb..bdaf3aa 100644
--- a/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/api/ITreeIndexCursor.java
+++ b/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/api/ITreeIndexCursor.java
@@ -19,21 +19,15 @@
 
 package org.apache.hyracks.storage.am.common.api;
 
-import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.storage.common.IIndexCursor;
 import org.apache.hyracks.storage.common.buffercache.IBufferCache;
-import org.apache.hyracks.storage.common.buffercache.ICachedPage;
 
 public interface ITreeIndexCursor extends IIndexCursor {
 
-    public ICachedPage getPage();
+    void setBufferCache(IBufferCache bufferCache);
 
-    public void setBufferCache(IBufferCache bufferCache);
-
-    public void setFileId(int fileId);
+    void setFileId(int fileId);
 
     // For allowing updates.
-    public boolean exclusiveLatchNodes();
-
-    public void markCurrentTupleAsUpdated() throws HyracksDataException;
+    boolean isExclusiveLatchNodes();
 }

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/639fe8cb/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/impls/AbstractTreeIndex.java
----------------------------------------------------------------------
diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/impls/AbstractTreeIndex.java b/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/impls/AbstractTreeIndex.java
index 0ed5f19..163a3d1 100644
--- a/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/impls/AbstractTreeIndex.java
+++ b/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/impls/AbstractTreeIndex.java
@@ -23,6 +23,7 @@ import java.util.ArrayList;
 import java.util.List;
 
 import org.apache.hyracks.api.dataflow.value.IBinaryComparatorFactory;
+import org.apache.hyracks.api.exceptions.ErrorCode;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.api.io.FileReference;
 import org.apache.hyracks.dataflow.common.data.accessors.ITupleReference;
@@ -84,26 +85,11 @@ public abstract class AbstractTreeIndex implements ITreeIndex {
     @Override
     public synchronized void create() throws HyracksDataException {
         if (isActive) {
-            throw new HyracksDataException("Failed to create the index since it is activated.");
+            throw HyracksDataException.create(ErrorCode.CANNOT_CREATE_ACTIVE_INDEX);
         }
         synchronized (fileMapProvider) {
-            boolean fileIsMapped = fileMapProvider.isMapped(file);
-            if (!fileIsMapped) {
-                bufferCache.createFile(file);
-            }
-            fileId = fileMapProvider.lookupFileId(file);
-            try {
-                // Also creates the file if it doesn't exist yet.
-                bufferCache.openFile(fileId);
-            } catch (HyracksDataException e) {
-                // Revert state of buffer cache since file failed to open.
-                if (!fileIsMapped) {
-                    bufferCache.deleteFile(fileId, false);
-                }
-                throw e;
-            }
+            fileId = createAndOpen(bufferCache, fileMapProvider, file);
         }
-
         freePageManager.open(fileId);
         freePageManager.init(interiorFrameFactory, leafFrameFactory);
         setRootPage();
@@ -111,6 +97,27 @@ public abstract class AbstractTreeIndex implements ITreeIndex {
         bufferCache.closeFile(fileId);
     }
 
+    public static int createAndOpen(IBufferCache bufferCache, IFileMapProvider fileMapProvider, FileReference file)
+            throws HyracksDataException {
+        int fileId;
+        boolean fileIsMapped = fileMapProvider.isMapped(file);
+        if (!fileIsMapped) {
+            bufferCache.createFile(file);
+        }
+        fileId = fileMapProvider.lookupFileId(file);
+        try {
+            // Also creates the file if it doesn't exist yet.
+            bufferCache.openFile(fileId);
+        } catch (HyracksDataException e) {
+            // Revert state of buffer cache since file failed to open.
+            if (!fileIsMapped) {
+                bufferCache.deleteFile(fileId, false);
+            }
+            throw e;
+        }
+        return fileId;
+    }
+
     private void setRootPage() throws HyracksDataException {
         rootPage = freePageManager.getRootPageId();
         bulkloadLeafStart = freePageManager.getBulkLoadLeaf();
@@ -119,7 +126,7 @@ public abstract class AbstractTreeIndex implements ITreeIndex {
     @Override
     public synchronized void activate() throws HyracksDataException {
         if (isActive) {
-            throw new HyracksDataException("Failed to activate the index since it is already activated.");
+            throw HyracksDataException.create(ErrorCode.CANNOT_ACTIVATE_ACTIVE_INDEX);
         }
         boolean fileIsMapped = false;
         synchronized (fileMapProvider) {
@@ -150,7 +157,7 @@ public abstract class AbstractTreeIndex implements ITreeIndex {
     @Override
     public synchronized void deactivate() throws HyracksDataException {
         if (!isActive && hasEverBeenActivated) {
-            throw new HyracksDataException("Failed to deactivate the index since it is already deactivated.");
+            throw HyracksDataException.create(ErrorCode.CANNOT_DEACTIVATE_INACTIVE_INDEX);
         }
         if (isActive) {
             freePageManager.close();
@@ -169,7 +176,7 @@ public abstract class AbstractTreeIndex implements ITreeIndex {
     @Override
     public synchronized void destroy() throws HyracksDataException {
         if (isActive) {
-            throw new HyracksDataException("Failed to destroy the index since it is activated.");
+            throw HyracksDataException.create(ErrorCode.CANNOT_DESTROY_ACTIVE_INDEX);
         }
 
         if (fileId == -1) {
@@ -183,7 +190,7 @@ public abstract class AbstractTreeIndex implements ITreeIndex {
     @Override
     public synchronized void clear() throws HyracksDataException {
         if (!isActive) {
-            throw new HyracksDataException("Failed to clear the index since it is not activated.");
+            throw HyracksDataException.create(ErrorCode.CANNOT_CLEAR_INACTIVE_INDEX);
         }
         freePageManager.init(interiorFrameFactory, leafFrameFactory);
         setRootPage();

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/639fe8cb/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/impls/TreeIndexDiskOrderScanCursor.java
----------------------------------------------------------------------
diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/impls/TreeIndexDiskOrderScanCursor.java b/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/impls/TreeIndexDiskOrderScanCursor.java
index 88c9e51..0b8b64c 100644
--- a/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/impls/TreeIndexDiskOrderScanCursor.java
+++ b/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/impls/TreeIndexDiskOrderScanCursor.java
@@ -69,11 +69,6 @@ public class TreeIndexDiskOrderScanCursor implements ITreeIndexCursor {
         return null;
     }
 
-    @Override
-    public ICachedPage getPage() {
-        return page;
-    }
-
     private boolean positionToNextLeaf(boolean skipCurrent) throws HyracksDataException {
         while (frame.getLevel() != 0 || skipCurrent || frame.getTupleCount() == 0) {
             if (++currentPageId > maxPageId) {
@@ -161,12 +156,7 @@ public class TreeIndexDiskOrderScanCursor implements ITreeIndexCursor {
     }
 
     @Override
-    public boolean exclusiveLatchNodes() {
+    public boolean isExclusiveLatchNodes() {
         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/asterixdb/blob/639fe8cb/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/tuples/DualTupleReference.java
----------------------------------------------------------------------
diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/tuples/DualTupleReference.java b/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/tuples/DualTupleReference.java
index f6ae8c1..ca38853 100644
--- a/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/tuples/DualTupleReference.java
+++ b/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/tuples/DualTupleReference.java
@@ -54,7 +54,7 @@ public class DualTupleReference implements ITupleReference {
         permutingTuple.reset(tuple);
     }
 
-    public ITupleReference getPermutingTuple() {
+    public PermutingTupleReference getPermutingTuple() {
         return permutingTuple;
     }
 }

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/639fe8cb/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/ExternalBTree.java
----------------------------------------------------------------------
diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/ExternalBTree.java b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/ExternalBTree.java
index 1025cf9..1d8de79 100644
--- a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/ExternalBTree.java
+++ b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/ExternalBTree.java
@@ -24,7 +24,6 @@ import java.util.LinkedList;
 import java.util.List;
 
 import org.apache.hyracks.api.dataflow.value.IBinaryComparatorFactory;
-import org.apache.hyracks.api.exceptions.ErrorCode;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.api.io.FileReference;
 import org.apache.hyracks.api.io.IIOManager;
@@ -59,6 +58,8 @@ import org.apache.hyracks.storage.am.lsm.common.api.LSMOperationType;
 import org.apache.hyracks.storage.am.lsm.common.impls.BlockingIOOperationCallbackWrapper;
 import org.apache.hyracks.storage.am.lsm.common.impls.ExternalIndexHarness;
 import org.apache.hyracks.storage.am.lsm.common.impls.LSMComponentFileReferences;
+import org.apache.hyracks.storage.am.lsm.common.impls.LSMTreeIndexAccessor;
+import org.apache.hyracks.storage.am.lsm.common.impls.LSMTreeIndexAccessor.ICursorFactory;
 import org.apache.hyracks.storage.am.lsm.common.impls.TreeIndexFactory;
 import org.apache.hyracks.storage.common.IIndexBulkLoader;
 import org.apache.hyracks.storage.common.IIndexCursor;
@@ -76,6 +77,7 @@ import org.apache.hyracks.storage.common.file.IFileMapProvider;
  */
 public class ExternalBTree extends LSMBTree implements ITwoPCIndex {
 
+    private static final ICursorFactory cursorFactory = opCtx -> new LSMBTreeSearchCursor(opCtx);
     // This component factory has to be different since it uses different tuple
     // writer in it's leaf frames to support inserting both
     // regular and delete tuples
@@ -108,6 +110,11 @@ public class ExternalBTree extends LSMBTree implements ITwoPCIndex {
         this.interiorFrameFactory = interiorFrameFactory;
     }
 
+    @Override
+    public ExternalIndexHarness getLsmHarness() {
+        return (ExternalIndexHarness) super.getLsmHarness();
+    }
+
     // The subsume merged components is overridden to account for:
     // Maintaining two versions of the index
     @Override
@@ -163,7 +170,7 @@ public class ExternalBTree extends LSMBTree implements ITwoPCIndex {
     // 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);
+                componentFactory.getBloomFilterKeyFields().length, cmpFactories, targetVersion, getLsmHarness());
     }
 
     // The only reason to override the following method is that it uses a different context object
@@ -193,7 +200,7 @@ public class ExternalBTree extends LSMBTree implements ITwoPCIndex {
         FileReference lastFile = lastBTree.getFileReference();
         LSMComponentFileReferences relMergeFileRefs =
                 fileManager.getRelMergeFileReference(firstFile.getFile().getName(), lastFile.getFile().getName());
-        ILSMIndexAccessor accessor = new LSMBTreeAccessor(lsmHarness, opCtx);
+        ILSMIndexAccessor accessor = new LSMTreeIndexAccessor(getLsmHarness(), opCtx, cursorFactory);
         ioScheduler.scheduleOperation(new LSMBTreeMergeOperation(accessor, mergingComponents, cursor,
                 relMergeFileRefs.getInsertIndexFileReference(), relMergeFileRefs.getBloomFilterFileReference(),
                 callback, fileManager.getBaseDir()));
@@ -244,7 +251,7 @@ public class ExternalBTree extends LSMBTree implements ITwoPCIndex {
 
     @Override
     public synchronized void activate() throws HyracksDataException {
-        if (isActivated) {
+        if (isActive) {
             throw new HyracksDataException("Failed to activate the index since it is already activated.");
         }
         if (diskComponents.size() == 0 && secondDiskComponents.size() == 0) {
@@ -259,7 +266,7 @@ public class ExternalBTree extends LSMBTree implements ITwoPCIndex {
                 diskComponents.add(component);
                 secondDiskComponents.add(component);
             }
-            ((ExternalIndexHarness) lsmHarness).indexFirstTimeActivated();
+            getLsmHarness().indexFirstTimeActivated();
         } else {
             // This index has been opened before
             for (ILSMComponent c : diskComponents) {
@@ -280,7 +287,7 @@ public class ExternalBTree extends LSMBTree implements ITwoPCIndex {
                 }
             }
         }
-        isActivated = true;
+        isActive = true;
     }
 
     @Override
@@ -291,7 +298,7 @@ public class ExternalBTree extends LSMBTree implements ITwoPCIndex {
 
     @Override
     public void deactivate(boolean flushOnExit) throws HyracksDataException {
-        if (!isActivated) {
+        if (!isActive) {
             throw new HyracksDataException("Failed to deactivate the index since it is already deactivated.");
         }
         if (flushOnExit) {
@@ -315,17 +322,17 @@ public class ExternalBTree extends LSMBTree implements ITwoPCIndex {
                 bloomFilter.deactivate();
             }
         }
-        isActivated = false;
+        isActive = false;
     }
 
     // The clear method is not used anywhere in AsterixDB! we override it anyway
     // to exit components first and deal with the two lists
     @Override
     public void clear() throws HyracksDataException {
-        if (!isActivated) {
+        if (!isActive) {
             throw new HyracksDataException("Failed to clear the index since it is not activated.");
         }
-        ((ExternalIndexHarness) lsmHarness).indexClear();
+        getLsmHarness().indexClear();
 
         for (ILSMComponent c : diskComponents) {
             LSMBTreeDiskComponent component = (LSMBTreeDiskComponent) c;
@@ -351,7 +358,7 @@ public class ExternalBTree extends LSMBTree implements ITwoPCIndex {
 
     @Override
     public void destroy() throws HyracksDataException {
-        if (isActivated) {
+        if (isActive) {
             throw new HyracksDataException("Failed to destroy the index since it is activated.");
         }
         for (ILSMComponent c : diskComponents) {
@@ -372,20 +379,6 @@ public class ExternalBTree extends LSMBTree implements ITwoPCIndex {
         version = 0;
     }
 
-    @Override
-    public void validate() throws HyracksDataException {
-        for (ILSMComponent c : diskComponents) {
-            BTree btree = ((LSMBTreeDiskComponent) c).getBTree();
-            btree.validate();
-        }
-        for (ILSMComponent c : secondDiskComponents) {
-            if (!diskComponents.contains(c)) {
-                BTree btree = ((LSMBTreeDiskComponent) c).getBTree();
-                btree.validate();
-            }
-        }
-    }
-
     // Not supported
     @Override
     public void modify(IIndexOperationContext ictx, ITupleReference tuple) throws HyracksDataException {
@@ -442,16 +435,16 @@ public class ExternalBTree extends LSMBTree implements ITwoPCIndex {
 
     // For initial load
     @Override
-    public IIndexBulkLoader createBulkLoader(float fillLevel, boolean verifyInput, long numElementsHint,
-            boolean checkIfEmptyIndex) throws HyracksDataException {
-        return new LSMTwoPCBTreeBulkLoader(fillLevel, verifyInput, numElementsHint, checkIfEmptyIndex, false);
+    public IIndexBulkLoader createBulkLoader(float fillLevel, boolean verifyInput, long numElementsHint)
+            throws HyracksDataException {
+        return new LSMTwoPCBTreeBulkLoader(fillLevel, verifyInput, numElementsHint, false);
     }
 
     // For transaction bulk load <- could consolidate with the above method ->
     @Override
-    public IIndexBulkLoader createTransactionBulkLoader(float fillLevel, boolean verifyInput, long numElementsHint,
-            boolean checkIfEmptyIndex) throws HyracksDataException {
-        return new LSMTwoPCBTreeBulkLoader(fillLevel, verifyInput, numElementsHint, checkIfEmptyIndex, true);
+    public IIndexBulkLoader createTransactionBulkLoader(float fillLevel, boolean verifyInput, long numElementsHint)
+            throws HyracksDataException {
+        return new LSMTwoPCBTreeBulkLoader(fillLevel, verifyInput, numElementsHint, true);
     }
 
     // The bulk loader used for both initial loading and transaction
@@ -467,15 +460,12 @@ public class ExternalBTree extends LSMBTree implements ITwoPCIndex {
         private final ITreeIndexTupleWriterFactory frameTupleWriterFactory;
 
         public LSMTwoPCBTreeBulkLoader(float fillFactor, boolean verifyInput, long numElementsHint,
-                boolean checkIfEmptyIndex, boolean isTransaction) throws HyracksDataException {
+                boolean isTransaction) throws HyracksDataException {
             this.isTransaction = isTransaction;
             // Create the appropriate target
             if (isTransaction) {
                 component = createTransactionTarget();
             } else {
-                if (checkIfEmptyIndex && !isEmptyIndex()) {
-                    throw HyracksDataException.create(ErrorCode.LOAD_NON_EMPTY_INDEX);
-                }
                 component = createBulkLoadTarget();
             }
 
@@ -551,7 +541,7 @@ public class ExternalBTree extends LSMBTree implements ITwoPCIndex {
                     btree.deactivate();
                     bloomFilter.deactivate();
                 } else {
-                    lsmHarness.addBulkLoadedComponent(component);
+                    getLsmHarness().addBulkLoadedComponent(component);
                 }
             }
         }
@@ -606,13 +596,15 @@ public class ExternalBTree extends LSMBTree implements ITwoPCIndex {
     @Override
     public ILSMIndexAccessor createAccessor(IModificationOperationCallback modificationCallback,
             ISearchOperationCallback searchCallback) {
-        return new LSMBTreeAccessor(lsmHarness, createOpContext(searchCallback, version));
+        ExternalBTreeOpContext opCtx = createOpContext(searchCallback, version);
+        return new LSMTreeIndexAccessor(getLsmHarness(), opCtx, cursorFactory);
     }
 
     @Override
     public ILSMIndexAccessor createAccessor(ISearchOperationCallback searchCallback, int targetIndexVersion)
             throws HyracksDataException {
-        return new LSMBTreeAccessor(lsmHarness, createOpContext(searchCallback, targetIndexVersion));
+        ExternalBTreeOpContext opCtx = createOpContext(searchCallback, targetIndexVersion);
+        return new LSMTreeIndexAccessor(getLsmHarness(), opCtx, cursorFactory);
     }
 
     @Override
@@ -668,7 +660,7 @@ public class ExternalBTree extends LSMBTree implements ITwoPCIndex {
             component = createDiskComponent(componentFactory, componentFileRefrences.getInsertIndexFileReference(),
                     componentFileRefrences.getBloomFilterFileReference(), false);
         }
-        ((ExternalIndexHarness) lsmHarness).addTransactionComponents(component);
+        getLsmHarness().addTransactionComponents(component);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/639fe8cb/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/ExternalBTreeOpContext.java
----------------------------------------------------------------------
diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/ExternalBTreeOpContext.java b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/ExternalBTreeOpContext.java
index 69c633c..f94c38a 100644
--- a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/ExternalBTreeOpContext.java
+++ b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/ExternalBTreeOpContext.java
@@ -18,40 +18,27 @@
  */
 package org.apache.hyracks.storage.am.lsm.btree.impls;
 
-import java.util.LinkedList;
-import java.util.List;
-
 import org.apache.hyracks.api.dataflow.value.IBinaryComparatorFactory;
 import org.apache.hyracks.storage.am.btree.api.IBTreeLeafFrame;
 import org.apache.hyracks.storage.am.common.api.ITreeIndexFrameFactory;
-import org.apache.hyracks.storage.am.common.ophelpers.IndexOperation;
-import org.apache.hyracks.storage.am.lsm.common.api.ILSMComponent;
-import org.apache.hyracks.storage.am.lsm.common.api.ILSMDiskComponent;
 import org.apache.hyracks.storage.am.lsm.common.api.ILSMHarness;
 import org.apache.hyracks.storage.am.lsm.common.impls.AbstractLSMIndexOperationContext;
-import org.apache.hyracks.storage.common.IModificationOperationCallback;
 import org.apache.hyracks.storage.common.ISearchOperationCallback;
-import org.apache.hyracks.storage.common.ISearchPredicate;
 import org.apache.hyracks.storage.common.MultiComparator;
 
 public class ExternalBTreeOpContext extends AbstractLSMIndexOperationContext {
     private IBTreeLeafFrame insertLeafFrame;
     private IBTreeLeafFrame deleteLeafFrame;
-    private IndexOperation op;
     private final MultiComparator cmp;
     private final MultiComparator bloomFilterCmp;
-    private final ISearchOperationCallback searchCallback;
-    private final List<ILSMComponent> componentHolder;
-    private final List<ILSMDiskComponent> componentsToBeMerged;
-    private final List<ILSMDiskComponent> componentsToBeReplicated;
     private final int targetIndexVersion;
-    private ISearchPredicate searchPredicate;
     private LSMBTreeCursorInitialState searchInitialState;
 
     public ExternalBTreeOpContext(ITreeIndexFrameFactory insertLeafFrameFactory,
             ITreeIndexFrameFactory deleteLeafFrameFactory, ISearchOperationCallback searchCallback,
             int numBloomFilterKeyFields, IBinaryComparatorFactory[] cmpFactories, int targetIndexVersion,
             ILSMHarness lsmHarness) {
+        super(null, null, null, searchCallback, null);
         if (cmpFactories != null) {
             this.cmp = MultiComparator.create(cmpFactories);
         } else {
@@ -66,80 +53,21 @@ public class ExternalBTreeOpContext extends AbstractLSMIndexOperationContext {
         if (deleteLeafFrame != null && this.cmp != null) {
             deleteLeafFrame.setMultiComparator(cmp);
         }
-        this.componentHolder = new LinkedList<>();
-        this.componentsToBeMerged = new LinkedList<>();
-        this.componentsToBeReplicated = new LinkedList<>();
-        this.searchCallback = searchCallback;
         this.targetIndexVersion = targetIndexVersion;
         searchInitialState = new LSMBTreeCursorInitialState(insertLeafFrameFactory, cmp, bloomFilterCmp, lsmHarness,
                 null, searchCallback, null);
     }
 
     @Override
-    public void setOperation(IndexOperation newOp) {
-        reset();
-        this.op = newOp;
-    }
-
-    @Override
-    public void reset() {
-        super.reset();
-        componentHolder.clear();
-        componentsToBeMerged.clear();
-        componentsToBeReplicated.clear();
-    }
-
-    @Override
-    public IndexOperation getOperation() {
-        return op;
-    }
-
-    @Override
-    public List<ILSMComponent> getComponentHolder() {
-        return componentHolder;
-    }
-
-    @Override
-    public ISearchOperationCallback getSearchOperationCallback() {
-        return searchCallback;
-    }
-
-    // Disk only index should never needs a modification callback
-    @Override
-    public IModificationOperationCallback getModificationCallback() {
-        return null;
-    }
-
-    @Override
     public void setCurrentMutableComponentId(int currentMutableComponentId) {
         // Do nothing: this method should never be called for this class
     }
 
-    @Override
-    public List<ILSMDiskComponent> getComponentsToBeMerged() {
-        return componentsToBeMerged;
-    }
-
     // Used by indexes with global transaction
     public int getTargetIndexVersion() {
         return targetIndexVersion;
     }
 
-    @Override
-    public void setSearchPredicate(ISearchPredicate searchPredicate) {
-        this.searchPredicate = searchPredicate;
-    }
-
-    @Override
-    public ISearchPredicate getSearchPredicate() {
-        return searchPredicate;
-    }
-
-    @Override
-    public List<ILSMDiskComponent> getComponentsToBeReplicated() {
-        return componentsToBeReplicated;
-    }
-
     public LSMBTreeCursorInitialState getSearchInitialState() {
         return searchInitialState;
     }


Mime
View raw message