http://git-wip-us.apache.org/repos/asf/asterixdb/blob/4ff6a36d/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTree.java
----------------------------------------------------------------------
diff --git 
a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTree.java
 
b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTree.java
index b4990d6..4610fd2 100644
--- 
a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTree.java
+++ 
b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTree.java
@@ -180,22 +180,24 @@ public class LSMBTree extends AbstractLSMIndex implements 
ITreeIndex {
         predicate.setLowKey(tuple);
         if (needKeyDupCheck) {
             // first check the inmemory component
+            boolean found;
             ctx.getCurrentMutableBTreeAccessor().search(memCursor, predicate);
             try {
-                if (memCursor.hasNext()) {
+                found = memCursor.hasNext();
+                if (found) {
                     memCursor.next();
                     LSMBTreeTupleReference lsmbtreeTuple = 
(LSMBTreeTupleReference) memCursor.getTuple();
                     if (!lsmbtreeTuple.isAntimatter()) {
                         throw 
HyracksDataException.create(ErrorCode.DUPLICATE_KEY);
-                    } else {
-                        memCursor.destroy();
-                        
ctx.getCurrentMutableBTreeAccessor().upsertIfConditionElseInsert(tuple,
-                                AntimatterAwareTupleAcceptor.INSTANCE);
-                        return true;
                     }
                 }
             } finally {
-                memCursor.destroy();
+                memCursor.close();
+            }
+            if (found) {
+                
ctx.getCurrentMutableBTreeAccessor().upsertIfConditionElseInsert(tuple,
+                        AntimatterAwareTupleAcceptor.INSTANCE);
+                return true;
             }
 
             // TODO: Can we just remove the above code that search the mutable
@@ -213,7 +215,7 @@ public class LSMBTree extends AbstractLSMIndex implements 
ITreeIndex {
                     throw HyracksDataException.create(ErrorCode.DUPLICATE_KEY);
                 }
             } finally {
-                searchCursor.destroy();
+                searchCursor.close();
                 // Add the current active mutable component back
                 ctx.getComponentHolder().add(0, firstComponent);
             }
@@ -241,7 +243,8 @@ public class LSMBTree extends AbstractLSMIndex implements 
ITreeIndex {
         MultiComparator comp = 
MultiComparator.create(getComparatorFactories());
         ISearchPredicate pred = new RangePredicate(null, null, true, true, 
comp, comp);
         ctx.getSearchInitialState().reset(pred, operationalComponents);
-        ((LSMBTreeSearchCursor) cursor).scan(ctx.getSearchInitialState(), 
pred);
+        ctx.getSearchInitialState().setDiskComponentScan(true);
+        ((LSMBTreeSearchCursor) cursor).open(ctx.getSearchInitialState(), 
pred);
     }
 
     @Override
@@ -249,46 +252,55 @@ public class LSMBTree extends AbstractLSMIndex implements 
ITreeIndex {
         LSMBTreeFlushOperation flushOp = (LSMBTreeFlushOperation) operation;
         LSMBTreeMemoryComponent flushingComponent = (LSMBTreeMemoryComponent) 
flushOp.getFlushingComponent();
         IIndexAccessor accessor = 
flushingComponent.getIndex().createAccessor(NoOpIndexAccessParameters.INSTANCE);
-
-        RangePredicate nullPred = new RangePredicate(null, null, true, true, 
null, null);
-        long numElements = 0L;
-        if (hasBloomFilter) {
-            //count elements in btree for creating Bloomfilter
-            IIndexCursor countingCursor = ((BTreeAccessor) 
accessor).createCountingSearchCursor();
-            accessor.search(countingCursor, nullPred);
+        ILSMDiskComponent component;
+        ILSMDiskComponentBulkLoader componentBulkLoader;
+        try {
+            RangePredicate nullPred = new RangePredicate(null, null, true, 
true, null, null);
+            long numElements = 0L;
+            if (hasBloomFilter) {
+                //count elements in btree for creating Bloomfilter
+                IIndexCursor countingCursor = ((BTreeAccessor) 
accessor).createCountingSearchCursor();
+                accessor.search(countingCursor, nullPred);
+                try {
+                    while (countingCursor.hasNext()) {
+                        countingCursor.next();
+                        ITupleReference countTuple = countingCursor.getTuple();
+                        numElements =
+                                
IntegerPointable.getInteger(countTuple.getFieldData(0), 
countTuple.getFieldStart(0));
+                    }
+                } finally {
+                    try {
+                        countingCursor.close();
+                    } finally {
+                        countingCursor.destroy();
+                    }
+                }
+            }
+            component = createDiskComponent(componentFactory, 
flushOp.getTarget(), null, flushOp.getBloomFilterTarget(),
+                    true);
+            componentBulkLoader = component.createBulkLoader(1.0f, false, 
numElements, false, false, false);
+            IIndexCursor scanCursor = accessor.createSearchCursor(false);
+            accessor.search(scanCursor, nullPred);
             try {
-                while (countingCursor.hasNext()) {
-                    countingCursor.next();
-                    ITupleReference countTuple = countingCursor.getTuple();
-                    numElements = 
IntegerPointable.getInteger(countTuple.getFieldData(0), 
countTuple.getFieldStart(0));
+                while (scanCursor.hasNext()) {
+                    scanCursor.next();
+                    // we can safely throw away updated tuples in secondary 
BTree components, because they correspond to
+                    // deleted tuples
+                    if (updateAware && ((LSMBTreeTupleReference) 
scanCursor.getTuple()).isUpdated()) {
+                        continue;
+                    }
+                    componentBulkLoader.add(scanCursor.getTuple());
                 }
             } finally {
-                countingCursor.destroy();
-            }
-        }
-
-        ILSMDiskComponent component =
-                createDiskComponent(componentFactory, flushOp.getTarget(), 
null, flushOp.getBloomFilterTarget(), true);
-
-        ILSMDiskComponentBulkLoader componentBulkLoader =
-                component.createBulkLoader(1.0f, false, numElements, false, 
false, false);
-
-        IIndexCursor scanCursor = accessor.createSearchCursor(false);
-        accessor.search(scanCursor, nullPred);
-        try {
-            while (scanCursor.hasNext()) {
-                scanCursor.next();
-                // we can safely throw away updated tuples in secondary BTree 
components, because they correspond to
-                // deleted tuples
-                if (updateAware && ((LSMBTreeTupleReference) 
scanCursor.getTuple()).isUpdated()) {
-                    continue;
+                try {
+                    scanCursor.close();
+                } finally {
+                    scanCursor.destroy();
                 }
-                componentBulkLoader.add(scanCursor.getTuple());
             }
         } finally {
-            scanCursor.destroy();
+            accessor.destroy();
         }
-
         if (component.getLSMComponentFilter() != null) {
             List<ITupleReference> filterTuples = new ArrayList<>();
             
filterTuples.add(flushingComponent.getLSMComponentFilter().getMinTuple());
@@ -313,9 +325,55 @@ public class LSMBTree extends AbstractLSMIndex implements 
ITreeIndex {
     public ILSMDiskComponent doMerge(ILSMIOOperation operation) throws 
HyracksDataException {
         LSMBTreeMergeOperation mergeOp = (LSMBTreeMergeOperation) operation;
         IIndexCursor cursor = mergeOp.getCursor();
-        RangePredicate rangePred = new RangePredicate(null, null, true, true, 
null, null);
-        search(mergeOp.getAccessor().getOpContext(), cursor, rangePred);
-        List<ILSMComponent> mergedComponents = mergeOp.getMergingComponents();
+        ILSMDiskComponent mergedComponent;
+        ILSMDiskComponentBulkLoader componentBulkLoader = null;
+        try {
+            try {
+                RangePredicate rangePred = new RangePredicate(null, null, 
true, true, null, null);
+                search(mergeOp.getAccessor().getOpContext(), cursor, 
rangePred);
+                try {
+                    List<ILSMComponent> mergedComponents = 
mergeOp.getMergingComponents();
+                    long numElements = getNumberOfElements(mergedComponents);
+                    mergedComponent = createDiskComponent(componentFactory, 
mergeOp.getTarget(), null,
+                            mergeOp.getBloomFilterTarget(), true);
+                    componentBulkLoader =
+                            mergedComponent.createBulkLoader(1.0f, false, 
numElements, false, false, false);
+                    while (cursor.hasNext()) {
+                        cursor.next();
+                        ITupleReference frameTuple = cursor.getTuple();
+                        componentBulkLoader.add(frameTuple);
+                    }
+                } finally {
+                    cursor.close();
+                }
+            } finally {
+                cursor.destroy();
+            }
+            if (mergedComponent.getLSMComponentFilter() != null) {
+                List<ITupleReference> filterTuples = new ArrayList<>();
+                for (int i = 0; i < mergeOp.getMergingComponents().size(); 
++i) {
+                    
filterTuples.add(mergeOp.getMergingComponents().get(i).getLSMComponentFilter().getMinTuple());
+                    
filterTuples.add(mergeOp.getMergingComponents().get(i).getLSMComponentFilter().getMaxTuple());
+                }
+                
getFilterManager().updateFilter(mergedComponent.getLSMComponentFilter(), 
filterTuples);
+                
getFilterManager().writeFilter(mergedComponent.getLSMComponentFilter(),
+                        mergedComponent.getMetadataHolder());
+            }
+        } catch (Throwable e) { // NOSONAR.. As per the contract, we should 
either abort or end
+            try {
+                if (componentBulkLoader != null) {
+                    componentBulkLoader.abort();
+                }
+            } catch (Throwable th) { // NOSONAR Don't lose the root failure
+                e.addSuppressed(th);
+            }
+            throw e;
+        }
+        componentBulkLoader.end();
+        return mergedComponent;
+    }
+
+    private long getNumberOfElements(List<ILSMComponent> mergedComponents) 
throws HyracksDataException {
         long numElements = 0L;
         if (hasBloomFilter) {
             //count elements in btree for creating Bloomfilter
@@ -324,32 +382,7 @@ public class LSMBTree extends AbstractLSMIndex implements 
ITreeIndex {
                         .getNumElements();
             }
         }
-        ILSMDiskComponent mergedComponent =
-                createDiskComponent(componentFactory, mergeOp.getTarget(), 
null, mergeOp.getBloomFilterTarget(), true);
-
-        ILSMDiskComponentBulkLoader componentBulkLoader =
-                mergedComponent.createBulkLoader(1.0f, false, numElements, 
false, false, false);
-        try {
-            while (cursor.hasNext()) {
-                cursor.next();
-                ITupleReference frameTuple = cursor.getTuple();
-                componentBulkLoader.add(frameTuple);
-            }
-        } finally {
-            cursor.destroy();
-        }
-        if (mergedComponent.getLSMComponentFilter() != null) {
-            List<ITupleReference> filterTuples = new ArrayList<>();
-            for (int i = 0; i < mergeOp.getMergingComponents().size(); ++i) {
-                
filterTuples.add(mergeOp.getMergingComponents().get(i).getLSMComponentFilter().getMinTuple());
-                
filterTuples.add(mergeOp.getMergingComponents().get(i).getLSMComponentFilter().getMaxTuple());
-            }
-            
getFilterManager().updateFilter(mergedComponent.getLSMComponentFilter(), 
filterTuples);
-            
getFilterManager().writeFilter(mergedComponent.getLSMComponentFilter(),
-                    mergedComponent.getMetadataHolder());
-        }
-        componentBulkLoader.end();
-        return mergedComponent;
+        return numElements;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/4ff6a36d/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreeCursorInitialState.java
----------------------------------------------------------------------
diff --git 
a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreeCursorInitialState.java
 
b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreeCursorInitialState.java
index dd1beee..9e8c848 100644
--- 
a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreeCursorInitialState.java
+++ 
b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreeCursorInitialState.java
@@ -36,11 +36,10 @@ public class LSMBTreeCursorInitialState implements 
ICursorInitialState {
     private MultiComparator cmp;
     private final MultiComparator bloomFilterCmp;
     private final ILSMHarness lsmHarness;
-
     private ISearchPredicate predicate;
     private ISearchOperationCallback searchCallback;
-
     private List<ILSMComponent> operationalComponents;
+    private boolean isDiskComponentScan;
 
     public LSMBTreeCursorInitialState(ITreeIndexFrameFactory leafFrameFactory, 
MultiComparator cmp,
             MultiComparator bloomFilterCmp, ILSMHarness lsmHarness, 
ISearchPredicate predicate,
@@ -105,7 +104,16 @@ public class LSMBTreeCursorInitialState implements 
ICursorInitialState {
 
     // make the cursor initial state re-usable
     public void reset(ISearchPredicate predicate, List<ILSMComponent> 
operationalComponents) {
+        isDiskComponentScan = false;
         this.predicate = predicate;
         this.operationalComponents = operationalComponents;
     }
+
+    public void setDiskComponentScan(boolean isDiskComponentScan) {
+        this.isDiskComponentScan = isDiskComponentScan;
+    }
+
+    public boolean isDiskComponentScan() {
+        return isDiskComponentScan;
+    }
 }

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/4ff6a36d/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreeDiskComponentScanCursor.java
----------------------------------------------------------------------
diff --git 
a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreeDiskComponentScanCursor.java
 
b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreeDiskComponentScanCursor.java
index a789ddd..dacd41f 100644
--- 
a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreeDiskComponentScanCursor.java
+++ 
b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreeDiskComponentScanCursor.java
@@ -20,6 +20,8 @@
 package org.apache.hyracks.storage.am.lsm.btree.impls;
 
 import org.apache.hyracks.api.exceptions.HyracksDataException;
+import org.apache.hyracks.api.util.DestroyUtils;
+import org.apache.hyracks.api.util.ExceptionUtils;
 import org.apache.hyracks.data.std.api.IValueReference;
 import org.apache.hyracks.data.std.primitive.BooleanPointable;
 import org.apache.hyracks.data.std.primitive.IntegerPointable;
@@ -61,7 +63,7 @@ public class LSMBTreeDiskComponentScanCursor extends 
LSMIndexSearchCursor {
     }
 
     @Override
-    public void open(ICursorInitialState initialState, ISearchPredicate 
searchPred) throws HyracksDataException {
+    public void doOpen(ICursorInitialState initialState, ISearchPredicate 
searchPred) throws HyracksDataException {
         LSMBTreeCursorInitialState lsmInitialState = 
(LSMBTreeCursorInitialState) initialState;
         cmp = lsmInitialState.getOriginalKeyComparator();
         operationalComponents = lsmInitialState.getOperationalComponents();
@@ -87,18 +89,18 @@ public class LSMBTreeDiskComponentScanCursor extends 
LSMIndexSearchCursor {
     }
 
     @Override
-    public void next() throws HyracksDataException {
+    public void doNext() throws HyracksDataException {
         foundNext = false;
     }
 
     @Override
-    public boolean hasNext() throws HyracksDataException {
+    public boolean doHasNext() throws HyracksDataException {
         if (foundNext) {
             return true;
         }
-        while (super.hasNext()) {
-            super.next();
-            LSMBTreeTupleReference diskTuple = (LSMBTreeTupleReference) 
super.getTuple();
+        while (super.doHasNext()) {
+            super.doNext();
+            LSMBTreeTupleReference diskTuple = (LSMBTreeTupleReference) 
super.doGetTuple();
             if (diskTuple.isAntimatter()) {
                 if (setAntiMatterTuple(diskTuple, 
outputElement.getCursorIndex())) {
                     foundNext = true;
@@ -167,23 +169,28 @@ public class LSMBTreeDiskComponentScanCursor extends 
LSMIndexSearchCursor {
     }
 
     @Override
-    public ITupleReference getTuple() {
+    public ITupleReference doGetTuple() {
         return outputTuple;
     }
 
     @Override
-    public void destroy() throws HyracksDataException {
+    public void doDestroy() throws HyracksDataException {
+        Throwable failure = null;
         if (lsmHarness != null) {
-            try {
-                for (int i = 0; i < rangeCursors.length; i++) {
-                    rangeCursors[i].destroy();
-                }
+            if (rangeCursors != null) {
+                failure = DestroyUtils.destroy(failure, rangeCursors);
                 rangeCursors = null;
-            } finally {
+            }
+            try {
                 lsmHarness.endScanDiskComponents(opCtx);
+            } catch (Throwable th) { // NOSONAR. Don't lose the root cause
+                failure = ExceptionUtils.suppress(failure, th);
             }
         }
         foundNext = false;
+        if (failure != null) {
+            throw HyracksDataException.create(failure);
+        }
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/4ff6a36d/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreeOpContext.java
----------------------------------------------------------------------
diff --git 
a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreeOpContext.java
 
b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreeOpContext.java
index 9cab94e..7795075 100644
--- 
a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreeOpContext.java
+++ 
b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreeOpContext.java
@@ -22,6 +22,8 @@ package org.apache.hyracks.storage.am.lsm.btree.impls;
 import java.util.List;
 
 import org.apache.hyracks.api.dataflow.value.IBinaryComparatorFactory;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
+import org.apache.hyracks.api.util.DestroyUtils;
 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;
@@ -63,6 +65,7 @@ public final class LSMBTreeOpContext extends 
AbstractLSMIndexOperationContext {
      */
     private BTree.BTreeAccessor currentMutableBTreeAccessor;
     private BTreeOpContext currentMutableBTreeOpCtx;
+    private boolean destroyed = false;
 
     public LSMBTreeOpContext(ILSMIndex index, List<ILSMMemoryComponent> 
mutableComponents,
             ITreeIndexFrameFactory insertLeafFrameFactory, 
ITreeIndexFrameFactory deleteLeafFrameFactory,
@@ -176,4 +179,18 @@ public final class LSMBTreeOpContext extends 
AbstractLSMIndexOperationContext {
     public MultiComparator getCmp() {
         return cmp;
     }
+
+    @Override
+    public void destroy() throws HyracksDataException {
+        if (destroyed) {
+            return;
+        }
+        destroyed = true;
+        Throwable failure = DestroyUtils.destroy(null, mutableBTreeAccessors);
+        failure = DestroyUtils.destroy(failure, mutableBTreeOpCtxs);
+        failure = DestroyUtils.destroy(failure, insertSearchCursor, memCursor);
+        if (failure != null) {
+            throw HyracksDataException.create(failure);
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/4ff6a36d/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreePointSearchCursor.java
----------------------------------------------------------------------
diff --git 
a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreePointSearchCursor.java
 
b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreePointSearchCursor.java
index 0c39a11..78564fd 100644
--- 
a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreePointSearchCursor.java
+++ 
b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreePointSearchCursor.java
@@ -37,12 +37,12 @@ import 
org.apache.hyracks.storage.am.lsm.common.api.ILSMComponentFilter;
 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.ILSMTreeTupleReference;
+import org.apache.hyracks.storage.common.EnforcedIndexCursor;
 import org.apache.hyracks.storage.common.ICursorInitialState;
-import org.apache.hyracks.storage.common.IIndexCursor;
 import org.apache.hyracks.storage.common.ISearchOperationCallback;
 import org.apache.hyracks.storage.common.ISearchPredicate;
 
-public class LSMBTreePointSearchCursor implements ILSMIndexCursor {
+public class LSMBTreePointSearchCursor extends EnforcedIndexCursor implements 
ILSMIndexCursor {
 
     private ITreeIndexCursor[] btreeCursors;
     private final ILSMIndexOperationContext opCtx;
@@ -66,7 +66,7 @@ public class LSMBTreePointSearchCursor implements 
ILSMIndexCursor {
     }
 
     @Override
-    public boolean hasNext() throws HyracksDataException {
+    public boolean doHasNext() throws HyracksDataException {
         if (nextHasBeenCalled) {
             return false;
         } else if (foundTuple) {
@@ -88,7 +88,7 @@ public class LSMBTreePointSearchCursor implements 
ILSMIndexCursor {
                         if (reconciled) {
                             searchCallback.cancel(predicate.getLowKey());
                         }
-                        btreeCursors[i].destroy();
+                        btreeCursors[i].close();
                         return false;
                     } else {
                         frameTuple = btreeCursors[i].getTuple();
@@ -109,7 +109,7 @@ public class LSMBTreePointSearchCursor implements 
ILSMIndexCursor {
                         btreeCursors[i].next();
                         if (((ILSMTreeTupleReference) 
btreeCursors[i].getTuple()).isAntimatter()) {
                             searchCallback.cancel(predicate.getLowKey());
-                            btreeCursors[i].destroy();
+                            btreeCursors[i].close();
                             return false;
                         } else {
                             frameTuple = btreeCursors[i].getTuple();
@@ -120,7 +120,7 @@ public class LSMBTreePointSearchCursor implements 
ILSMIndexCursor {
                         }
                     } else {
                         searchCallback.cancel(predicate.getLowKey());
-                        btreeCursors[i].destroy();
+                        btreeCursors[i].close();
                     }
                 } else {
                     frameTuple = btreeCursors[i].getTuple();
@@ -131,20 +131,16 @@ public class LSMBTreePointSearchCursor implements 
ILSMIndexCursor {
                     return true;
                 }
             } else {
-                btreeCursors[i].destroy();
+                btreeCursors[i].close();
             }
         }
         return false;
     }
 
     @Override
-    public void close() throws HyracksDataException {
+    public void doClose() throws HyracksDataException {
         try {
-            if (btreeCursors != null) {
-                for (int i = 0; i < numBTrees; ++i) {
-                    btreeCursors[i].close();
-                }
-            }
+            closeCursors();
             nextHasBeenCalled = false;
             foundTuple = false;
         } finally {
@@ -155,7 +151,7 @@ public class LSMBTreePointSearchCursor implements 
ILSMIndexCursor {
     }
 
     @Override
-    public void open(ICursorInitialState initialState, ISearchPredicate 
searchPred) throws HyracksDataException {
+    public void doOpen(ICursorInitialState initialState, ISearchPredicate 
searchPred) throws HyracksDataException {
         LSMBTreeCursorInitialState lsmInitialState = 
(LSMBTreeCursorInitialState) initialState;
         operationalComponents = lsmInitialState.getOperationalComponents();
         lsmHarness = lsmInitialState.getLSMHarness();
@@ -194,26 +190,23 @@ public class LSMBTreePointSearchCursor implements 
ILSMIndexCursor {
     }
 
     @Override
-    public void next() throws HyracksDataException {
+    public void doNext() throws HyracksDataException {
         nextHasBeenCalled = true;
     }
 
     @Override
-    public void destroy() throws HyracksDataException {
-        if (lsmHarness != null) {
-            try {
-                closeCursors();
-                btreeCursors = null;
-            } finally {
-                lsmHarness.endSearch(opCtx);
+    public void doDestroy() throws HyracksDataException {
+        if (btreeCursors != null) {
+            for (int i = 0; i < numBTrees; ++i) {
+                if (btreeCursors[i] != null) {
+                    btreeCursors[i].destroy();
+                }
             }
         }
-        nextHasBeenCalled = false;
-        foundTuple = false;
     }
 
     @Override
-    public ITupleReference getTuple() {
+    public ITupleReference doGetTuple() {
         return frameTuple;
     }
 
@@ -240,7 +233,7 @@ public class LSMBTreePointSearchCursor implements 
ILSMIndexCursor {
         if (btreeCursors != null) {
             for (int i = 0; i < numBTrees; ++i) {
                 if (btreeCursors[i] != null) {
-                    btreeCursors[i].destroy();
+                    btreeCursors[i].close();
                 }
             }
         }

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/4ff6a36d/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreeRangeSearchCursor.java
----------------------------------------------------------------------
diff --git 
a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreeRangeSearchCursor.java
 
b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreeRangeSearchCursor.java
index 1e401a2..5d23fef 100644
--- 
a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreeRangeSearchCursor.java
+++ 
b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreeRangeSearchCursor.java
@@ -23,6 +23,7 @@ import java.util.Iterator;
 import java.util.PriorityQueue;
 
 import org.apache.hyracks.api.exceptions.HyracksDataException;
+import org.apache.hyracks.api.util.DestroyUtils;
 import org.apache.hyracks.dataflow.common.comm.io.ArrayTupleBuilder;
 import org.apache.hyracks.dataflow.common.comm.io.ArrayTupleReference;
 import org.apache.hyracks.dataflow.common.utils.TupleUtils;
@@ -64,13 +65,13 @@ public class LSMBTreeRangeSearchCursor extends 
LSMIndexSearchCursor {
     }
 
     @Override
-    public void close() throws HyracksDataException {
-        super.close();
+    public void doClose() throws HyracksDataException {
+        super.doClose();
         canCallProceed = true;
     }
 
     @Override
-    public void next() throws HyracksDataException {
+    public void doNext() throws HyracksDataException {
         outputElement = outputPriorityQueue.poll();
         needPushElementIntoQueue = true;
         canCallProceed = false;
@@ -267,7 +268,6 @@ public class LSMBTreeRangeSearchCursor extends 
LSMIndexSearchCursor {
                     TupleUtils.copyTuple(switchComponentTupleBuilders[i], 
element.getTuple(), cmp.getKeyFieldCount());
                 }
                 rangeCursors[i].close();
-                rangeCursors[i].destroy();
                 switchRequest[i] = true;
                 switchedElements[i] = element;
             }
@@ -318,7 +318,7 @@ public class LSMBTreeRangeSearchCursor extends 
LSMIndexSearchCursor {
     }
 
     @Override
-    public void open(ICursorInitialState initialState, ISearchPredicate 
searchPred) throws HyracksDataException {
+    public void doOpen(ICursorInitialState initialState, ISearchPredicate 
searchPred) throws HyracksDataException {
         LSMBTreeCursorInitialState lsmInitialState = 
(LSMBTreeCursorInitialState) initialState;
         cmp = lsmInitialState.getOriginalKeyComparator();
         operationalComponents = lsmInitialState.getOperationalComponents();
@@ -331,10 +331,19 @@ public class LSMBTreeRangeSearchCursor extends 
LSMIndexSearchCursor {
         includeMutableComponent = false;
 
         int numBTrees = operationalComponents.size();
-        if (rangeCursors == null || rangeCursors.length != numBTrees) {
+        if (rangeCursors == null) {
             // object creation: should be relatively low
             rangeCursors = new IIndexCursor[numBTrees];
             btreeAccessors = new BTreeAccessor[numBTrees];
+        } else if (rangeCursors.length != numBTrees) {
+            // should destroy first
+            Throwable failure = DestroyUtils.destroy(null, btreeAccessors);
+            failure = DestroyUtils.destroy(failure, rangeCursors);
+            if (failure != null) {
+                throw HyracksDataException.create(failure);
+            }
+            rangeCursors = new IIndexCursor[numBTrees];
+            btreeAccessors = new BTreeAccessor[numBTrees];
         }
 
         for (int i = 0; i < numBTrees; i++) {

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/4ff6a36d/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreeSearchCursor.java
----------------------------------------------------------------------
diff --git 
a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreeSearchCursor.java
 
b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreeSearchCursor.java
index 0ceaf7b..02574ca 100644
--- 
a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreeSearchCursor.java
+++ 
b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreeSearchCursor.java
@@ -24,11 +24,11 @@ import 
org.apache.hyracks.dataflow.common.data.accessors.ITupleReference;
 import org.apache.hyracks.storage.am.btree.impls.RangePredicate;
 import org.apache.hyracks.storage.am.common.api.ILSMIndexCursor;
 import org.apache.hyracks.storage.am.lsm.common.api.ILSMIndexOperationContext;
+import org.apache.hyracks.storage.common.EnforcedIndexCursor;
 import org.apache.hyracks.storage.common.ICursorInitialState;
-import org.apache.hyracks.storage.common.IIndexCursor;
 import org.apache.hyracks.storage.common.ISearchPredicate;
 
-public class LSMBTreeSearchCursor implements ILSMIndexCursor {
+public class LSMBTreeSearchCursor extends EnforcedIndexCursor implements 
ILSMIndexCursor {
 
     public enum LSMBTreeSearchType {
         POINT,
@@ -47,40 +47,43 @@ public class LSMBTreeSearchCursor implements 
ILSMIndexCursor {
     }
 
     @Override
-    public void open(ICursorInitialState initialState, ISearchPredicate 
searchPred) throws HyracksDataException {
+    public void doOpen(ICursorInitialState initialState, ISearchPredicate 
searchPred) throws HyracksDataException {
         LSMBTreeCursorInitialState lsmInitialState = 
(LSMBTreeCursorInitialState) initialState;
         RangePredicate btreePred = (RangePredicate) searchPred;
-
-        currentCursor =
-                
btreePred.isPointPredicate(lsmInitialState.getOriginalKeyComparator()) ? 
pointCursor : rangeCursor;
+        currentCursor = lsmInitialState.isDiskComponentScan() ? scanCursor
+                : 
btreePred.isPointPredicate(lsmInitialState.getOriginalKeyComparator()) ? 
pointCursor : rangeCursor;
         currentCursor.open(lsmInitialState, searchPred);
     }
 
-    public void scan(ICursorInitialState initialState, ISearchPredicate 
searchPred) throws HyracksDataException {
-        currentCursor = scanCursor;
-        currentCursor.open(initialState, searchPred);
-    }
-
     @Override
-    public boolean hasNext() throws HyracksDataException {
+    public boolean doHasNext() throws HyracksDataException {
         return currentCursor.hasNext();
     }
 
     @Override
-    public void next() throws HyracksDataException {
+    public void doNext() throws HyracksDataException {
         currentCursor.next();
     }
 
     @Override
-    public void destroy() throws HyracksDataException {
-        if (currentCursor != null) {
-            currentCursor.destroy();
+    public void doDestroy() throws HyracksDataException {
+        try {
+            pointCursor.destroy();
+        } finally {
+            try {
+                rangeCursor.destroy();
+            } finally {
+                try {
+                    scanCursor.destroy();
+                } finally {
+                    currentCursor = null;
+                }
+            }
         }
-        currentCursor = null;
     }
 
     @Override
-    public void close() throws HyracksDataException {
+    public void doClose() throws HyracksDataException {
         if (currentCursor != null) {
             currentCursor.close();
         }
@@ -88,7 +91,7 @@ public class LSMBTreeSearchCursor implements ILSMIndexCursor {
     }
 
     @Override
-    public ITupleReference getTuple() {
+    public ITupleReference doGetTuple() {
         return currentCursor.getTuple();
     }
 

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/4ff6a36d/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreeWithBuddyAbstractCursor.java
----------------------------------------------------------------------
diff --git 
a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreeWithBuddyAbstractCursor.java
 
b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreeWithBuddyAbstractCursor.java
index b37fb20..8dcbcc4 100644
--- 
a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreeWithBuddyAbstractCursor.java
+++ 
b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreeWithBuddyAbstractCursor.java
@@ -36,12 +36,12 @@ 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.common.EnforcedIndexCursor;
 import org.apache.hyracks.storage.common.ICursorInitialState;
-import org.apache.hyracks.storage.common.IIndexCursor;
 import org.apache.hyracks.storage.common.ISearchPredicate;
 import org.apache.hyracks.storage.common.MultiComparator;
 
-public abstract class LSMBTreeWithBuddyAbstractCursor implements 
ILSMIndexCursor {
+public abstract class LSMBTreeWithBuddyAbstractCursor extends 
EnforcedIndexCursor implements ILSMIndexCursor {
 
     protected boolean open;
     protected BTreeRangeSearchCursor[] btreeCursors;
@@ -75,7 +75,7 @@ public abstract class LSMBTreeWithBuddyAbstractCursor 
implements ILSMIndexCursor
     }
 
     @Override
-    public void open(ICursorInitialState initialState, ISearchPredicate 
searchPred) throws HyracksDataException {
+    public void doOpen(ICursorInitialState initialState, ISearchPredicate 
searchPred) throws HyracksDataException {
 
         LSMBTreeWithBuddyCursorInitialState lsmInitialState = 
(LSMBTreeWithBuddyCursorInitialState) initialState;
         btreeCmp = lsmInitialState.getBTreeCmp();
@@ -142,7 +142,7 @@ public abstract class LSMBTreeWithBuddyAbstractCursor 
implements ILSMIndexCursor
     }
 
     @Override
-    public void destroy() throws HyracksDataException {
+    public void doDestroy() throws HyracksDataException {
         if (!open) {
             return;
         }
@@ -163,7 +163,7 @@ public abstract class LSMBTreeWithBuddyAbstractCursor 
implements ILSMIndexCursor
     }
 
     @Override
-    public ITupleReference getTuple() {
+    public ITupleReference doGetTuple() {
         return frameTuple;
     }
 }

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/4ff6a36d/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreeWithBuddySearchCursor.java
----------------------------------------------------------------------
diff --git 
a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreeWithBuddySearchCursor.java
 
b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreeWithBuddySearchCursor.java
index c7f5cea..c66cd69 100644
--- 
a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreeWithBuddySearchCursor.java
+++ 
b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreeWithBuddySearchCursor.java
@@ -37,13 +37,13 @@ public class LSMBTreeWithBuddySearchCursor extends 
LSMBTreeWithBuddyAbstractCurs
     }
 
     @Override
-    public void destroy() throws HyracksDataException {
-        super.destroy();
+    public void doDestroy() throws HyracksDataException {
+        super.doDestroy();
         currentCursor = 0;
     }
 
     @Override
-    public void close() throws HyracksDataException {
+    public void doClose() throws HyracksDataException {
         if (!open) {
             return;
         }
@@ -52,8 +52,8 @@ public class LSMBTreeWithBuddySearchCursor extends 
LSMBTreeWithBuddyAbstractCurs
         foundNext = false;
         try {
             for (int i = 0; i < numberOfTrees; i++) {
-                btreeCursors[i].destroy();
-                buddyBtreeCursors[i].destroy();
+                btreeCursors[i].close();
+                buddyBtreeCursors[i].close();
             }
             btreeCursors = null;
             buddyBtreeCursors = null;
@@ -70,7 +70,7 @@ public class LSMBTreeWithBuddySearchCursor extends 
LSMBTreeWithBuddyAbstractCurs
     }
 
     @Override
-    public boolean hasNext() throws HyracksDataException {
+    public boolean doHasNext() throws HyracksDataException {
         if (foundNext) {
             return true;
         }
@@ -94,7 +94,7 @@ public class LSMBTreeWithBuddySearchCursor extends 
LSMBTreeWithBuddyAbstractCurs
                             killerTupleFound = true;
                         }
                     } finally {
-                        buddyBtreeCursors[i].destroy();
+                        buddyBtreeCursors[i].close();
                     }
                 }
                 if (!killerTupleFound) {
@@ -103,7 +103,7 @@ public class LSMBTreeWithBuddySearchCursor extends 
LSMBTreeWithBuddyAbstractCurs
                     return true;
                 }
             }
-            btreeCursors[currentCursor].destroy();
+            btreeCursors[currentCursor].close();
             currentCursor++;
             searchNextCursor();
         }
@@ -111,7 +111,7 @@ public class LSMBTreeWithBuddySearchCursor extends 
LSMBTreeWithBuddyAbstractCurs
     }
 
     @Override
-    public void next() throws HyracksDataException {
+    public void doNext() throws HyracksDataException {
         foundNext = false;
     }
 
@@ -135,8 +135,8 @@ public class LSMBTreeWithBuddySearchCursor extends 
LSMBTreeWithBuddyAbstractCurs
     }
 
     @Override
-    public void open(ICursorInitialState initialState, ISearchPredicate 
searchPred) throws HyracksDataException {
-        super.open(initialState, searchPred);
+    public void doOpen(ICursorInitialState initialState, ISearchPredicate 
searchPred) throws HyracksDataException {
+        super.doOpen(initialState, searchPred);
         searchNextCursor();
     }
 }

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/4ff6a36d/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreeWithBuddySortedCursor.java
----------------------------------------------------------------------
diff --git 
a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreeWithBuddySortedCursor.java
 
b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreeWithBuddySortedCursor.java
index d889622..2913be1 100644
--- 
a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreeWithBuddySortedCursor.java
+++ 
b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBTreeWithBuddySortedCursor.java
@@ -47,7 +47,7 @@ public class LSMBTreeWithBuddySortedCursor extends 
LSMBTreeWithBuddyAbstractCurs
     }
 
     @Override
-    public void close() throws HyracksDataException {
+    public void doClose() throws HyracksDataException {
         depletedBtreeCursors = new boolean[numberOfTrees];
         foundNext = false;
         try {
@@ -90,7 +90,7 @@ public class LSMBTreeWithBuddySortedCursor extends 
LSMBTreeWithBuddyAbstractCurs
     }
 
     @Override
-    public boolean hasNext() throws HyracksDataException {
+    public boolean doHasNext() throws HyracksDataException {
         while (!foundNext) {
             frameTuple = null;
 
@@ -137,7 +137,7 @@ public class LSMBTreeWithBuddySortedCursor extends 
LSMBTreeWithBuddyAbstractCurs
                         break;
                     }
                 } finally {
-                    btreeCursors[i].destroy();
+                    btreeCursors[i].close();
                 }
             }
             if (!killed) {
@@ -149,14 +149,13 @@ public class LSMBTreeWithBuddySortedCursor extends 
LSMBTreeWithBuddyAbstractCurs
     }
 
     @Override
-    public void next() throws HyracksDataException {
+    public void doNext() throws HyracksDataException {
         foundNext = false;
     }
 
     @Override
-    public void open(ICursorInitialState initialState, ISearchPredicate 
searchPred) throws HyracksDataException {
-        super.open(initialState, searchPred);
-
+    public void doOpen(ICursorInitialState initialState, ISearchPredicate 
searchPred) throws HyracksDataException {
+        super.doOpen(initialState, searchPred);
         depletedBtreeCursors = new boolean[numberOfTrees];
         foundNext = false;
         for (int i = 0; i < numberOfTrees; i++) {
@@ -169,5 +168,4 @@ public class LSMBTreeWithBuddySortedCursor extends 
LSMBTreeWithBuddyAbstractCurs
             }
         }
     }
-
 }

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/4ff6a36d/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBuddyBTreeMergeCursor.java
----------------------------------------------------------------------
diff --git 
a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBuddyBTreeMergeCursor.java
 
b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBuddyBTreeMergeCursor.java
index b2f5327..fd13e62 100644
--- 
a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBuddyBTreeMergeCursor.java
+++ 
b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree/src/main/java/org/apache/hyracks/storage/am/lsm/btree/impls/LSMBuddyBTreeMergeCursor.java
@@ -45,7 +45,7 @@ public class LSMBuddyBTreeMergeCursor extends 
LSMIndexSearchCursor {
     }
 
     @Override
-    public void open(ICursorInitialState initialState, ISearchPredicate 
searchPred) throws HyracksDataException {
+    public void doOpen(ICursorInitialState initialState, ISearchPredicate 
searchPred) throws HyracksDataException {
         LSMBTreeWithBuddyCursorInitialState lsmInitialState = 
(LSMBTreeWithBuddyCursorInitialState) initialState;
         cmp = lsmInitialState.getBuddyBTreeCmp();
         operationalComponents = lsmInitialState.getOperationalComponents();

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/4ff6a36d/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/api/ILSMIndexAccessor.java
----------------------------------------------------------------------
diff --git 
a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/api/ILSMIndexAccessor.java
 
b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/api/ILSMIndexAccessor.java
index b8d64af..0e1a5e4 100644
--- 
a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/api/ILSMIndexAccessor.java
+++ 
b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/api/ILSMIndexAccessor.java
@@ -245,6 +245,9 @@ public interface ILSMIndexAccessor extends IIndexAccessor {
      * The returned tuples are first ordered on primary key, and then ordered 
on the descending order of
      * disk_component_position (older components get returned first)
      *
+     * If this method returns successfully, then the cursor has been opened. 
If an exception is thrown then
+     * the cursor was not opened
+     *
      * @param icursor
      *            Cursor over the index entries satisfying searchPred.
      * @throws HyracksDataException

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/4ff6a36d/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/ComponentReplacementContext.java
----------------------------------------------------------------------
diff --git 
a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/ComponentReplacementContext.java
 
b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/ComponentReplacementContext.java
index ee7afa0..dcac219 100644
--- 
a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/ComponentReplacementContext.java
+++ 
b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/ComponentReplacementContext.java
@@ -213,4 +213,9 @@ public class ComponentReplacementContext implements 
ILSMIndexOperationContext {
     public boolean isTracingEnabled() {
         return false;
     }
+
+    @Override
+    public void destroy() throws HyracksDataException {
+        // No Op.. Nothing to destroy
+    }
 }

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/4ff6a36d/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/LSMIndexSearchCursor.java
----------------------------------------------------------------------
diff --git 
a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/LSMIndexSearchCursor.java
 
b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/LSMIndexSearchCursor.java
index 7f3a371..900ee32 100644
--- 
a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/LSMIndexSearchCursor.java
+++ 
b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/LSMIndexSearchCursor.java
@@ -32,10 +32,11 @@ import 
org.apache.hyracks.storage.am.lsm.common.api.ILSMComponentFilter;
 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.ILSMTreeTupleReference;
+import org.apache.hyracks.storage.common.EnforcedIndexCursor;
 import org.apache.hyracks.storage.common.IIndexCursor;
 import org.apache.hyracks.storage.common.MultiComparator;
 
-public abstract class LSMIndexSearchCursor implements ILSMIndexCursor {
+public abstract class LSMIndexSearchCursor extends EnforcedIndexCursor 
implements ILSMIndexCursor {
     protected static final int SWITCH_COMPONENT_CYCLE = 100;
     protected final ILSMIndexOperationContext opCtx;
     protected final boolean returnDeletedTuples;
@@ -106,7 +107,7 @@ public abstract class LSMIndexSearchCursor implements 
ILSMIndexCursor {
     }
 
     @Override
-    public void close() throws HyracksDataException {
+    public void doClose() throws HyracksDataException {
         hasNextCallCount = 0;
         switchPossible = true;
         outputElement = null;
@@ -133,20 +134,20 @@ public abstract class LSMIndexSearchCursor implements 
ILSMIndexCursor {
     }
 
     @Override
-    public boolean hasNext() throws HyracksDataException {
+    public boolean doHasNext() throws HyracksDataException {
         hasNextCallCount++;
         checkPriorityQueue();
         return !outputPriorityQueue.isEmpty();
     }
 
     @Override
-    public void next() throws HyracksDataException {
+    public void doNext() throws HyracksDataException {
         outputElement = outputPriorityQueue.poll();
         needPushElementIntoQueue = true;
     }
 
     @Override
-    public void destroy() throws HyracksDataException {
+    public void doDestroy() throws HyracksDataException {
         try {
             if (outputPriorityQueue != null) {
                 outputPriorityQueue.clear();
@@ -167,7 +168,7 @@ public abstract class LSMIndexSearchCursor implements 
ILSMIndexCursor {
     }
 
     @Override
-    public ITupleReference getTuple() {
+    public ITupleReference doGetTuple() {
         return outputElement.getTuple();
     }
 
@@ -191,7 +192,7 @@ public abstract class LSMIndexSearchCursor implements 
ILSMIndexCursor {
             outputPriorityQueue.offer(e);
             return;
         }
-        rangeCursors[cursorIndex].destroy();
+        rangeCursors[cursorIndex].close();
         if (cursorIndex == 0) {
             includeMutableComponent = false;
         }

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/4ff6a36d/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/LSMTreeIndexAccessor.java
----------------------------------------------------------------------
diff --git 
a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/LSMTreeIndexAccessor.java
 
b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/LSMTreeIndexAccessor.java
index 4770d7c..9794a98 100644
--- 
a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/LSMTreeIndexAccessor.java
+++ 
b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/LSMTreeIndexAccessor.java
@@ -50,6 +50,7 @@ public class LSMTreeIndexAccessor implements 
ILSMIndexAccessor {
     protected final ILSMHarness lsmHarness;
     protected final ILSMIndexOperationContext ctx;
     protected final ICursorFactory cursorFactory;
+    private boolean destroyed = false;
 
     public LSMTreeIndexAccessor(ILSMHarness lsmHarness, 
ILSMIndexOperationContext ctx, ICursorFactory cursorFactory) {
         this.lsmHarness = lsmHarness;
@@ -234,4 +235,13 @@ public class LSMTreeIndexAccessor implements 
ILSMIndexAccessor {
     public ILSMIndexOperationContext getOpContext() {
         return ctx;
     }
+
+    @Override
+    public void destroy() throws HyracksDataException {
+        if (destroyed) {
+            return;
+        }
+        destroyed = true;
+        ctx.destroy();
+    }
 }

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/4ff6a36d/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/VirtualBufferCache.java
----------------------------------------------------------------------
diff --git 
a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/VirtualBufferCache.java
 
b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/VirtualBufferCache.java
index 1cfe345..ef9852d 100644
--- 
a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/VirtualBufferCache.java
+++ 
b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/VirtualBufferCache.java
@@ -385,6 +385,11 @@ public class VirtualBufferCache implements 
IVirtualBufferCache {
         public CacheBucket() {
             this.bucketLock = new ReentrantLock();
         }
+
+        @Override
+        public String toString() {
+            return CacheBucket.class.getSimpleName() + " -> " + (cachedPage == 
null ? "" : cachedPage.toString());
+        }
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/4ff6a36d/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-invertedindex/src/main/java/org/apache/hyracks/storage/am/lsm/invertedindex/api/IInvertedListCursor.java
----------------------------------------------------------------------
diff --git 
a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-invertedindex/src/main/java/org/apache/hyracks/storage/am/lsm/invertedindex/api/IInvertedListCursor.java
 
b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-invertedindex/src/main/java/org/apache/hyracks/storage/am/lsm/invertedindex/api/IInvertedListCursor.java
index abea6a0..e9b3f21 100644
--- 
a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-invertedindex/src/main/java/org/apache/hyracks/storage/am/lsm/invertedindex/api/IInvertedListCursor.java
+++ 
b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-invertedindex/src/main/java/org/apache/hyracks/storage/am/lsm/invertedindex/api/IInvertedListCursor.java
@@ -38,7 +38,7 @@ public interface IInvertedListCursor extends 
Comparable<IInvertedListCursor> {
     public ITupleReference getTuple();
 
     // getters
-    public int size();
+    public int size() throws HyracksDataException;
 
     public int getStartPageId();
 

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/4ff6a36d/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-invertedindex/src/main/java/org/apache/hyracks/storage/am/lsm/invertedindex/impls/LSMInvertedIndex.java
----------------------------------------------------------------------
diff --git 
a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-invertedindex/src/main/java/org/apache/hyracks/storage/am/lsm/invertedindex/impls/LSMInvertedIndex.java
 
b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-invertedindex/src/main/java/org/apache/hyracks/storage/am/lsm/invertedindex/impls/LSMInvertedIndex.java
index 05561f2..1beff71 100644
--- 
a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-invertedindex/src/main/java/org/apache/hyracks/storage/am/lsm/invertedindex/impls/LSMInvertedIndex.java
+++ 
b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-invertedindex/src/main/java/org/apache/hyracks/storage/am/lsm/invertedindex/impls/LSMInvertedIndex.java
@@ -270,28 +270,29 @@ public class LSMInvertedIndex extends AbstractLSMIndex 
implements IInvertedIndex
     @Override
     public ILSMDiskComponent doFlush(ILSMIOOperation operation) throws 
HyracksDataException {
         LSMInvertedIndexFlushOperation flushOp = 
(LSMInvertedIndexFlushOperation) operation;
-
         // Create an inverted index instance to be bulk loaded.
         ILSMDiskComponent component = createDiskComponent(componentFactory, 
flushOp.getTarget(),
                 flushOp.getDeletedKeysBTreeTarget(), 
flushOp.getBloomFilterTarget(), true);
-
         // Create a scan cursor on the BTree underlying the in-memory inverted 
index.
         LSMInvertedIndexMemoryComponent flushingComponent =
                 (LSMInvertedIndexMemoryComponent) 
flushOp.getFlushingComponent();
-
         RangePredicate nullPred = new RangePredicate(null, null, true, true, 
null, null);
-
         // Search the deleted keys BTree to calculate the number of elements 
for BloomFilter
+        long numBTreeTuples = 0L;
         BTreeAccessor deletedKeysBTreeAccessor =
                 
flushingComponent.getBuddyIndex().createAccessor(NoOpIndexAccessParameters.INSTANCE);
         IIndexCursor btreeCountingCursor = 
deletedKeysBTreeAccessor.createCountingSearchCursor();
-        deletedKeysBTreeAccessor.search(btreeCountingCursor, nullPred);
-        long numBTreeTuples = 0L;
         try {
-            while (btreeCountingCursor.hasNext()) {
-                btreeCountingCursor.next();
-                ITupleReference countTuple = btreeCountingCursor.getTuple();
-                numBTreeTuples = 
IntegerPointable.getInteger(countTuple.getFieldData(0), 
countTuple.getFieldStart(0));
+            deletedKeysBTreeAccessor.search(btreeCountingCursor, nullPred);
+            try {
+                while (btreeCountingCursor.hasNext()) {
+                    btreeCountingCursor.next();
+                    ITupleReference countTuple = 
btreeCountingCursor.getTuple();
+                    numBTreeTuples =
+                            
IntegerPointable.getInteger(countTuple.getFieldData(0), 
countTuple.getFieldStart(0));
+                }
+            } finally {
+                btreeCountingCursor.close();
             }
         } finally {
             btreeCountingCursor.destroy();
@@ -302,29 +303,34 @@ public class LSMInvertedIndex extends AbstractLSMIndex 
implements IInvertedIndex
 
         // Create a scan cursor on the deleted keys BTree underlying the 
in-memory inverted index.
         IIndexCursor deletedKeysScanCursor = 
deletedKeysBTreeAccessor.createSearchCursor(false);
-        deletedKeysBTreeAccessor.search(deletedKeysScanCursor, nullPred);
-
         try {
-            while (deletedKeysScanCursor.hasNext()) {
-                deletedKeysScanCursor.next();
-                componentBulkLoader.delete(deletedKeysScanCursor.getTuple());
+            deletedKeysBTreeAccessor.search(deletedKeysScanCursor, nullPred);
+            try {
+                while (deletedKeysScanCursor.hasNext()) {
+                    deletedKeysScanCursor.next();
+                    
componentBulkLoader.delete(deletedKeysScanCursor.getTuple());
+                }
+            } finally {
+                deletedKeysScanCursor.close();
             }
         } finally {
             deletedKeysScanCursor.destroy();
         }
-
         // Scan the in-memory inverted index
         InMemoryInvertedIndexAccessor memInvIndexAccessor =
                 
flushingComponent.getIndex().createAccessor(NoOpIndexAccessParameters.INSTANCE);
         BTreeAccessor memBTreeAccessor = 
memInvIndexAccessor.getBTreeAccessor();
         IIndexCursor scanCursor = memBTreeAccessor.createSearchCursor(false);
-        memBTreeAccessor.search(scanCursor, nullPred);
-
-        // Bulk load the disk inverted index from the in-memory inverted index.
         try {
-            while (scanCursor.hasNext()) {
-                scanCursor.next();
-                componentBulkLoader.add(scanCursor.getTuple());
+            memBTreeAccessor.search(scanCursor, nullPred);
+            // Bulk load the disk inverted index from the in-memory inverted 
index.
+            try {
+                while (scanCursor.hasNext()) {
+                    scanCursor.next();
+                    componentBulkLoader.add(scanCursor.getTuple());
+                }
+            } finally {
+                scanCursor.close();
             }
         } finally {
             scanCursor.destroy();
@@ -337,86 +343,88 @@ public class LSMInvertedIndex extends AbstractLSMIndex 
implements IInvertedIndex
             filterManager.writeFilter(component.getLSMComponentFilter(), 
component.getMetadataHolder());
         }
         flushingComponent.getMetadata().copy(component.getMetadata());
-
         componentBulkLoader.end();
-
         return component;
     }
 
     @Override
     public ILSMDiskComponent doMerge(ILSMIOOperation operation) throws 
HyracksDataException {
         LSMInvertedIndexMergeOperation mergeOp = 
(LSMInvertedIndexMergeOperation) operation;
-        IIndexCursor cursor = mergeOp.getCursor();
-
         RangePredicate mergePred = new RangePredicate(null, null, true, true, 
null, null);
-        ILSMIndexOperationContext opCtx = ((LSMIndexSearchCursor) 
cursor).getOpCtx();
-        // Scan diskInvertedIndexes ignoring the memoryInvertedIndex.
-        search(opCtx, cursor, mergePred);
-
-        // Create an inverted index instance.
-        ILSMDiskComponent component = createDiskComponent(componentFactory, 
mergeOp.getTarget(),
-                mergeOp.getDeletedKeysBTreeTarget(), 
mergeOp.getBloomFilterTarget(), true);
-
-        ILSMDiskComponentBulkLoader componentBulkLoader;
-
-        // In case we must keep the deleted-keys BTrees, then they must be 
merged *before* merging the inverted indexes so that
-        // lsmHarness.endSearch() is called once when the inverted indexes 
have been merged.
-        if 
(mergeOp.getMergingComponents().get(mergeOp.getMergingComponents().size() - 1) 
!= diskComponents
-                .get(diskComponents.size() - 1)) {
-            // Keep the deleted tuples since the oldest disk component is not 
included in the merge operation
-
-            LSMInvertedIndexDeletedKeysBTreeMergeCursor btreeCursor =
-                    new LSMInvertedIndexDeletedKeysBTreeMergeCursor(opCtx);
-            search(opCtx, btreeCursor, mergePred);
-
-            long numElements = 0L;
-            for (int i = 0; i < mergeOp.getMergingComponents().size(); ++i) {
-                numElements += ((LSMInvertedIndexDiskComponent) 
mergeOp.getMergingComponents().get(i)).getBloomFilter()
-                        .getNumElements();
+        IIndexCursor cursor = mergeOp.getCursor();
+        try {
+            ILSMIndexOperationContext opCtx = ((LSMIndexSearchCursor) 
cursor).getOpCtx();
+            // Scan diskInvertedIndexes ignoring the memoryInvertedIndex.
+            // Create an inverted index instance.
+            ILSMDiskComponent component = 
createDiskComponent(componentFactory, mergeOp.getTarget(),
+                    mergeOp.getDeletedKeysBTreeTarget(), 
mergeOp.getBloomFilterTarget(), true);
+            ILSMDiskComponentBulkLoader componentBulkLoader;
+            // In case we must keep the deleted-keys BTrees, then they must be 
merged *before* merging the inverted
+            // indexes so that lsmHarness.endSearch() is called once when the 
inverted indexes have been merged.
+            if 
(mergeOp.getMergingComponents().get(mergeOp.getMergingComponents().size() - 1) 
!= diskComponents
+                    .get(diskComponents.size() - 1)) {
+                // Keep the deleted tuples since the oldest disk component is 
not included in the merge operation
+                LSMInvertedIndexDeletedKeysBTreeMergeCursor btreeCursor =
+                        new LSMInvertedIndexDeletedKeysBTreeMergeCursor(opCtx);
+                try {
+                    long numElements = 0L;
+                    for (int i = 0; i < mergeOp.getMergingComponents().size(); 
++i) {
+                        numElements += ((LSMInvertedIndexDiskComponent) 
mergeOp.getMergingComponents().get(i))
+                                .getBloomFilter().getNumElements();
+                    }
+                    componentBulkLoader = component.createBulkLoader(1.0f, 
false, numElements, false, false, false);
+                    loadDeleteTuples(opCtx, btreeCursor, mergePred, 
componentBulkLoader);
+                } finally {
+                    btreeCursor.destroy();
+                }
+            } else {
+                componentBulkLoader = component.createBulkLoader(1.0f, false, 
0L, false, false, false);
             }
-
-            componentBulkLoader = component.createBulkLoader(1.0f, false, 
numElements, false, false, false);
+            search(opCtx, cursor, mergePred);
             try {
-                while (btreeCursor.hasNext()) {
-                    btreeCursor.next();
-                    ITupleReference tuple = btreeCursor.getTuple();
-                    componentBulkLoader.delete(tuple);
+                while (cursor.hasNext()) {
+                    cursor.next();
+                    ITupleReference tuple = cursor.getTuple();
+                    componentBulkLoader.add(tuple);
                 }
             } finally {
-                btreeCursor.destroy();
+                cursor.close();
             }
-        } else {
-            componentBulkLoader = component.createBulkLoader(1.0f, false, 0L, 
false, false, false);
+            if (component.getLSMComponentFilter() != null) {
+                List<ITupleReference> filterTuples = new ArrayList<>();
+                for (int i = 0; i < mergeOp.getMergingComponents().size(); 
++i) {
+                    ITupleReference min = 
mergeOp.getMergingComponents().get(i).getLSMComponentFilter().getMinTuple();
+                    ITupleReference max = 
mergeOp.getMergingComponents().get(i).getLSMComponentFilter().getMaxTuple();
+                    if (min != null) {
+                        filterTuples.add(min);
+                    }
+                    if (max != null) {
+                        filterTuples.add(max);
+                    }
+                }
+                
getFilterManager().updateFilter(component.getLSMComponentFilter(), 
filterTuples);
+                
getFilterManager().writeFilter(component.getLSMComponentFilter(), 
component.getMetadataHolder());
+            }
+            componentBulkLoader.end();
+            return component;
+        } finally {
+            cursor.close();
         }
+    }
 
+    private void loadDeleteTuples(ILSMIndexOperationContext opCtx,
+            LSMInvertedIndexDeletedKeysBTreeMergeCursor btreeCursor, 
RangePredicate mergePred,
+            ILSMDiskComponentBulkLoader componentBulkLoader) throws 
HyracksDataException {
+        search(opCtx, btreeCursor, mergePred);
         try {
-            while (cursor.hasNext()) {
-                cursor.next();
-                ITupleReference tuple = cursor.getTuple();
-                componentBulkLoader.add(tuple);
+            while (btreeCursor.hasNext()) {
+                btreeCursor.next();
+                ITupleReference tuple = btreeCursor.getTuple();
+                componentBulkLoader.delete(tuple);
             }
         } finally {
-            cursor.destroy();
+            btreeCursor.close();
         }
-        if (component.getLSMComponentFilter() != null) {
-            List<ITupleReference> filterTuples = new ArrayList<>();
-            for (int i = 0; i < mergeOp.getMergingComponents().size(); ++i) {
-                ITupleReference min = 
mergeOp.getMergingComponents().get(i).getLSMComponentFilter().getMinTuple();
-                ITupleReference max = 
mergeOp.getMergingComponents().get(i).getLSMComponentFilter().getMaxTuple();
-                if (min != null) {
-                    filterTuples.add(min);
-                }
-                if (max != null) {
-                    filterTuples.add(max);
-                }
-            }
-            getFilterManager().updateFilter(component.getLSMComponentFilter(), 
filterTuples);
-            getFilterManager().writeFilter(component.getLSMComponentFilter(), 
component.getMetadataHolder());
-        }
-
-        componentBulkLoader.end();
-
-        return component;
     }
 
     protected InMemoryInvertedIndex 
createInMemoryInvertedIndex(IVirtualBufferCache virtualBufferCache,

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/4ff6a36d/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-invertedindex/src/main/java/org/apache/hyracks/storage/am/lsm/invertedindex/impls/LSMInvertedIndexAccessor.java
----------------------------------------------------------------------
diff --git 
a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-invertedindex/src/main/java/org/apache/hyracks/storage/am/lsm/invertedindex/impls/LSMInvertedIndexAccessor.java
 
b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-invertedindex/src/main/java/org/apache/hyracks/storage/am/lsm/invertedindex/impls/LSMInvertedIndexAccessor.java
index 61fc84e..c33e2ce 100644
--- 
a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-invertedindex/src/main/java/org/apache/hyracks/storage/am/lsm/invertedindex/impls/LSMInvertedIndexAccessor.java
+++ 
b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-invertedindex/src/main/java/org/apache/hyracks/storage/am/lsm/invertedindex/impls/LSMInvertedIndexAccessor.java
@@ -43,6 +43,7 @@ public class LSMInvertedIndexAccessor implements 
ILSMIndexAccessor, IInvertedInd
 
     protected final ILSMHarness lsmHarness;
     protected final ILSMIndexOperationContext ctx;
+    private boolean destroyed = false;
 
     public LSMInvertedIndexAccessor(ILSMHarness lsmHarness, 
ILSMIndexOperationContext ctx) {
         this.lsmHarness = lsmHarness;
@@ -225,4 +226,13 @@ public class LSMInvertedIndexAccessor implements 
ILSMIndexAccessor, IInvertedInd
     public ILSMIndexOperationContext getOpContext() {
         return ctx;
     }
+
+    @Override
+    public void destroy() throws HyracksDataException {
+        if (destroyed) {
+            return;
+        }
+        destroyed = true;
+        ctx.destroy();
+    }
 }

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/4ff6a36d/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-invertedindex/src/main/java/org/apache/hyracks/storage/am/lsm/invertedindex/impls/LSMInvertedIndexDeletedKeysBTreeMergeCursor.java
----------------------------------------------------------------------
diff --git 
a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-invertedindex/src/main/java/org/apache/hyracks/storage/am/lsm/invertedindex/impls/LSMInvertedIndexDeletedKeysBTreeMergeCursor.java
 
b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-invertedindex/src/main/java/org/apache/hyracks/storage/am/lsm/invertedindex/impls/LSMInvertedIndexDeletedKeysBTreeMergeCursor.java
index 2a105f1..21ce940 100644
--- 
a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-invertedindex/src/main/java/org/apache/hyracks/storage/am/lsm/invertedindex/impls/LSMInvertedIndexDeletedKeysBTreeMergeCursor.java
+++ 
b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-invertedindex/src/main/java/org/apache/hyracks/storage/am/lsm/invertedindex/impls/LSMInvertedIndexDeletedKeysBTreeMergeCursor.java
@@ -43,7 +43,7 @@ public class LSMInvertedIndexDeletedKeysBTreeMergeCursor 
extends LSMIndexSearchC
     }
 
     @Override
-    public void open(ICursorInitialState initialState, ISearchPredicate 
searchPred) throws HyracksDataException {
+    public void doOpen(ICursorInitialState initialState, ISearchPredicate 
searchPred) throws HyracksDataException {
         LSMInvertedIndexRangeSearchCursorInitialState lsmInitialState =
                 (LSMInvertedIndexRangeSearchCursorInitialState) initialState;
         cmp = lsmInitialState.getOriginalKeyComparator();

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/4ff6a36d/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-invertedindex/src/main/java/org/apache/hyracks/storage/am/lsm/invertedindex/impls/LSMInvertedIndexOpContext.java
----------------------------------------------------------------------
diff --git 
a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-invertedindex/src/main/java/org/apache/hyracks/storage/am/lsm/invertedindex/impls/LSMInvertedIndexOpContext.java
 
b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-invertedindex/src/main/java/org/apache/hyracks/storage/am/lsm/invertedindex/impls/LSMInvertedIndexOpContext.java
index 55da252..cf95f78 100644
--- 
a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-invertedindex/src/main/java/org/apache/hyracks/storage/am/lsm/invertedindex/impls/LSMInvertedIndexOpContext.java
+++ 
b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-invertedindex/src/main/java/org/apache/hyracks/storage/am/lsm/invertedindex/impls/LSMInvertedIndexOpContext.java
@@ -23,6 +23,7 @@ import java.util.List;
 
 import org.apache.hyracks.api.dataflow.value.IBinaryComparatorFactory;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
+import org.apache.hyracks.api.util.DestroyUtils;
 import org.apache.hyracks.storage.am.common.impls.NoOpIndexAccessParameters;
 import org.apache.hyracks.storage.am.common.tuples.PermutingTupleReference;
 import org.apache.hyracks.storage.am.lsm.common.api.ILSMIndex;
@@ -46,6 +47,7 @@ public class LSMInvertedIndexOpContext extends 
AbstractLSMIndexOperationContext
     private IIndexAccessor[] deletedKeysBTreeAccessors;
     private IInvertedIndexAccessor currentMutableInvIndexAccessors;
     private IIndexAccessor currentDeletedKeysBTreeAccessors;
+    private boolean destroyed = false;
 
     public LSMInvertedIndexOpContext(ILSMIndex index, 
List<ILSMMemoryComponent> mutableComponents,
             IModificationOperationCallback modificationCallback, 
ISearchOperationCallback searchCallback,
@@ -94,4 +96,17 @@ public class LSMInvertedIndexOpContext extends 
AbstractLSMIndexOperationContext
     public IIndexAccessor getCurrentDeletedKeysBTreeAccessors() {
         return currentDeletedKeysBTreeAccessors;
     }
+
+    @Override
+    public void destroy() throws HyracksDataException {
+        if (destroyed) {
+            return;
+        }
+        destroyed = true;
+        Throwable failure = DestroyUtils.destroy(null, 
mutableInvIndexAccessors);
+        failure = DestroyUtils.destroy(failure, deletedKeysBTreeAccessors);
+        if (failure != null) {
+            throw HyracksDataException.create(failure);
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/4ff6a36d/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-invertedindex/src/main/java/org/apache/hyracks/storage/am/lsm/invertedindex/impls/LSMInvertedIndexRangeSearchCursor.java
----------------------------------------------------------------------
diff --git 
a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-invertedindex/src/main/java/org/apache/hyracks/storage/am/lsm/invertedindex/impls/LSMInvertedIndexRangeSearchCursor.java
 
b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-invertedindex/src/main/java/org/apache/hyracks/storage/am/lsm/invertedindex/impls/LSMInvertedIndexRangeSearchCursor.java
index 4afccef..12dc23f 100644
--- 
a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-invertedindex/src/main/java/org/apache/hyracks/storage/am/lsm/invertedindex/impls/LSMInvertedIndexRangeSearchCursor.java
+++ 
b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-invertedindex/src/main/java/org/apache/hyracks/storage/am/lsm/invertedindex/impls/LSMInvertedIndexRangeSearchCursor.java
@@ -51,12 +51,7 @@ public class LSMInvertedIndexRangeSearchCursor extends 
LSMIndexSearchCursor {
     }
 
     @Override
-    public void next() throws HyracksDataException {
-        super.next();
-    }
-
-    @Override
-    public void open(ICursorInitialState initState, ISearchPredicate 
searchPred) throws HyracksDataException {
+    public void doOpen(ICursorInitialState initState, ISearchPredicate 
searchPred) throws HyracksDataException {
         LSMInvertedIndexRangeSearchCursorInitialState lsmInitState =
                 (LSMInvertedIndexRangeSearchCursorInitialState) initState;
         cmp = lsmInitState.getOriginalKeyComparator();
@@ -107,13 +102,13 @@ public class LSMInvertedIndexRangeSearchCursor extends 
LSMIndexSearchCursor {
                 continue;
             }
             deletedKeysBTreeCursors[i].close();
+            
deletedKeysBTreeAccessors.get(i).search(deletedKeysBTreeCursors[i], 
keySearchPred);
             try {
-                
deletedKeysBTreeAccessors.get(i).search(deletedKeysBTreeCursors[i], 
keySearchPred);
                 if (deletedKeysBTreeCursors[i].hasNext()) {
                     return true;
                 }
             } finally {
-                deletedKeysBTreeCursors[i].destroy();
+                deletedKeysBTreeCursors[i].close();
             }
         }
         return false;

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/4ff6a36d/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-invertedindex/src/main/java/org/apache/hyracks/storage/am/lsm/invertedindex/impls/LSMInvertedIndexSearchCursor.java
----------------------------------------------------------------------
diff --git 
a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-invertedindex/src/main/java/org/apache/hyracks/storage/am/lsm/invertedindex/impls/LSMInvertedIndexSearchCursor.java
 
b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-invertedindex/src/main/java/org/apache/hyracks/storage/am/lsm/invertedindex/impls/LSMInvertedIndexSearchCursor.java
index ce9f760..fea9373 100644
--- 
a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-invertedindex/src/main/java/org/apache/hyracks/storage/am/lsm/invertedindex/impls/LSMInvertedIndexSearchCursor.java
+++ 
b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-invertedindex/src/main/java/org/apache/hyracks/storage/am/lsm/invertedindex/impls/LSMInvertedIndexSearchCursor.java
@@ -30,6 +30,7 @@ import 
org.apache.hyracks.storage.am.lsm.common.api.ILSMComponent.LSMComponentTy
 import org.apache.hyracks.storage.am.lsm.common.api.ILSMComponentFilter;
 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.common.EnforcedIndexCursor;
 import org.apache.hyracks.storage.common.ICursorInitialState;
 import org.apache.hyracks.storage.common.IIndexAccessor;
 import org.apache.hyracks.storage.common.IIndexCursor;
@@ -41,7 +42,7 @@ import org.apache.hyracks.storage.common.MultiComparator;
  * Searches the components one-by-one, completely consuming a cursor before 
moving on to the next one.
  * Therefore, the are no guarantees about sort order of the results.
  */
-public class LSMInvertedIndexSearchCursor implements ILSMIndexCursor {
+public class LSMInvertedIndexSearchCursor extends EnforcedIndexCursor 
implements ILSMIndexCursor {
 
     private IIndexAccessor currentAccessor;
     private IIndexCursor currentCursor;
@@ -66,7 +67,7 @@ public class LSMInvertedIndexSearchCursor implements 
ILSMIndexCursor {
     private final long[] hashes = BloomFilter.createHashArray();
 
     @Override
-    public void open(ICursorInitialState initialState, ISearchPredicate 
searchPred) throws HyracksDataException {
+    public void doOpen(ICursorInitialState initialState, ISearchPredicate 
searchPred) throws HyracksDataException {
         LSMInvertedIndexSearchCursorInitialState lsmInitState = 
(LSMInvertedIndexSearchCursorInitialState) initialState;
         harness = lsmInitState.getLSMHarness();
         operationalComponents = lsmInitState.getOperationalComponents();
@@ -109,7 +110,7 @@ public class LSMInvertedIndexSearchCursor implements 
ILSMIndexCursor {
                     return true;
                 }
             } finally {
-                deletedKeysBTreeCursors[i].destroy();
+                deletedKeysBTreeCursors[i].close();
             }
         }
         return false;
@@ -140,7 +141,7 @@ public class LSMInvertedIndexSearchCursor implements 
ILSMIndexCursor {
     }
 
     @Override
-    public boolean hasNext() throws HyracksDataException {
+    public boolean doHasNext() throws HyracksDataException {
         if (!tupleConsumed) {
             return true;
         }
@@ -148,7 +149,7 @@ public class LSMInvertedIndexSearchCursor implements 
ILSMIndexCursor {
             if (nextValidTuple()) {
                 return true;
             }
-            currentCursor.destroy();
+            currentCursor.close();
             accessorIndex++;
         }
         while (accessorIndex < indexAccessors.size()) {
@@ -160,28 +161,28 @@ public class LSMInvertedIndexSearchCursor implements 
ILSMIndexCursor {
                 return true;
             }
             // Close as we go to release resources.
-            currentCursor.destroy();
+            currentCursor.close();
             accessorIndex++;
         }
         return false;
     }
 
     @Override
-    public void next() throws HyracksDataException {
+    public void doNext() throws HyracksDataException {
         // Mark the tuple as consumed, so hasNext() can move on.
         tupleConsumed = true;
     }
 
     @Override
-    public void destroy() throws HyracksDataException {
-        close();
+    public void doDestroy() throws HyracksDataException {
+        doClose();
     }
 
     @Override
-    public void close() throws HyracksDataException {
+    public void doClose() throws HyracksDataException {
         try {
             if (currentCursor != null) {
-                currentCursor.destroy();
+                currentCursor.close();
                 currentCursor = null;
             }
             accessorIndex = 0;
@@ -193,7 +194,7 @@ public class LSMInvertedIndexSearchCursor implements 
ILSMIndexCursor {
     }
 
     @Override
-    public ITupleReference getTuple() {
+    public ITupleReference doGetTuple() {
         return currentCursor.getTuple();
     }
 

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/4ff6a36d/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-invertedindex/src/main/java/org/apache/hyracks/storage/am/lsm/invertedindex/inmemory/InMemoryInvertedIndexAccessor.java
----------------------------------------------------------------------
diff --git 
a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-invertedindex/src/main/java/org/apache/hyracks/storage/am/lsm/invertedindex/inmemory/InMemoryInvertedIndexAccessor.java
 
b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-invertedindex/src/main/java/org/apache/hyracks/storage/am/lsm/invertedindex/inmemory/InMemoryInvertedIndexAccessor.java
index 6777177..0795a4e 100644
--- 
a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-invertedindex/src/main/java/org/apache/hyracks/storage/am/lsm/invertedindex/inmemory/InMemoryInvertedIndexAccessor.java
+++ 
b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-invertedindex/src/main/java/org/apache/hyracks/storage/am/lsm/invertedindex/inmemory/InMemoryInvertedIndexAccessor.java
@@ -46,6 +46,7 @@ public class InMemoryInvertedIndexAccessor implements 
IInvertedIndexAccessor {
     protected IIndexOperationContext opCtx;
     protected InMemoryInvertedIndex index;
     protected BTreeAccessor btreeAccessor;
+    private boolean destroyed = false;
 
     public InMemoryInvertedIndexAccessor(InMemoryInvertedIndex index, 
IIndexOperationContext opCtx)
             throws HyracksDataException {
@@ -130,4 +131,20 @@ public class InMemoryInvertedIndexAccessor implements 
IInvertedIndexAccessor {
         btreeAccessor.getOpContext().resetNonIndexFieldsTuple(newTuple);
     }
 
+    @Override
+    public void destroy() throws HyracksDataException {
+        if (destroyed) {
+            return;
+        }
+        destroyed = true;
+        doDestroy();
+    }
+
+    private void doDestroy() throws HyracksDataException {
+        try {
+            btreeAccessor.destroy();
+        } finally {
+            opCtx.destroy();
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/4ff6a36d/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-invertedindex/src/main/java/org/apache/hyracks/storage/am/lsm/invertedindex/inmemory/InMemoryInvertedIndexOpContext.java
----------------------------------------------------------------------
diff --git 
a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-invertedindex/src/main/java/org/apache/hyracks/storage/am/lsm/invertedindex/inmemory/InMemoryInvertedIndexOpContext.java
 
b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-invertedindex/src/main/java/org/apache/hyracks/storage/am/lsm/invertedindex/inmemory/InMemoryInvertedIndexOpContext.java
index eec20fd..0457b46 100644
--- 
a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-invertedindex/src/main/java/org/apache/hyracks/storage/am/lsm/invertedindex/inmemory/InMemoryInvertedIndexOpContext.java
+++ 
b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-invertedindex/src/main/java/org/apache/hyracks/storage/am/lsm/invertedindex/inmemory/InMemoryInvertedIndexOpContext.java
@@ -20,6 +20,7 @@
 package org.apache.hyracks.storage.am.lsm.invertedindex.inmemory;
 
 import org.apache.hyracks.api.dataflow.value.IBinaryComparatorFactory;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
 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.RangePredicate;
@@ -46,6 +47,7 @@ public class InMemoryInvertedIndexOpContext implements 
IIndexOperationContext {
     // To generate in-memory BTree tuples for insertions.
     private final IBinaryTokenizerFactory tokenizerFactory;
     private InvertedIndexTokenizingTupleIterator tupleIter;
+    private boolean destroyed = false;
 
     InMemoryInvertedIndexOpContext(BTree btree, IBinaryComparatorFactory[] 
tokenCmpFactories,
             IBinaryTokenizerFactory tokenizerFactory) {
@@ -123,4 +125,15 @@ public class InMemoryInvertedIndexOpContext implements 
IIndexOperationContext {
     public void setTupleIter(InvertedIndexTokenizingTupleIterator tupleIter) {
         this.tupleIter = tupleIter;
     }
+
+    @Override
+    public void destroy() throws HyracksDataException {
+        if (destroyed) {
+            return;
+        }
+        destroyed = true;
+        if (btreeAccessor != null) {
+            btreeAccessor.destroy();
+        }
+    }
 }

Reply via email to