Merged hyracks_lsm_tree r1860:1879.

git-svn-id: https://hyracks.googlecode.com/svn/branches/hyracks_inverted_index_updates_new@1880 123451ca-8445-de46-9d55-352943316053
diff --git a/hyracks-control/hyracks-control-nc/src/main/java/edu/uci/ics/hyracks/control/nc/Task.java b/hyracks-control/hyracks-control-nc/src/main/java/edu/uci/ics/hyracks/control/nc/Task.java
index 91e1d51..eba3ec9 100644
--- a/hyracks-control/hyracks-control-nc/src/main/java/edu/uci/ics/hyracks/control/nc/Task.java
+++ b/hyracks-control/hyracks-control-nc/src/main/java/edu/uci/ics/hyracks/control/nc/Task.java
@@ -308,19 +308,22 @@
                 reader.open();
                 try {
                     writer.open();
-                    ByteBuffer buffer = allocateFrame();
-                    while (reader.nextFrame(buffer)) {
-                        if (aborted) {
-                            return;
+                    try {
+                        ByteBuffer buffer = allocateFrame();
+                        while (reader.nextFrame(buffer)) {
+                            if (aborted) {
+                                return;
+                            }
+                            buffer.flip();
+                            writer.nextFrame(buffer);
+                            buffer.compact();
                         }
-                        buffer.flip();
-                        writer.nextFrame(buffer);
-                        buffer.compact();
+                    } catch (Exception e) {
+                        writer.fail();
+                        throw e;
+                    } finally {
+                        writer.close();
                     }
-                    writer.close();
-                } catch (Exception e) {
-                    writer.fail();
-                    throw e;
                 } finally {
                     reader.close();
                 }
@@ -346,6 +349,7 @@
 
     @Override
     public void sendApplicationMessageToCC(byte[] message, String nodeId) throws Exception {
-        this.ncs.sendApplicationMessageToCC(message, this.getJobletContext().getApplicationContext().getApplicationName(), nodeId);
+        this.ncs.sendApplicationMessageToCC(message, this.getJobletContext().getApplicationContext()
+                .getApplicationName(), nodeId);
     }
 }
\ No newline at end of file
diff --git a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeDataflowHelper.java b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeDataflowHelper.java
index f307c8a..1bef90d 100644
--- a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeDataflowHelper.java
+++ b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/dataflow/BTreeDataflowHelper.java
@@ -30,7 +30,7 @@
     }
 
     @Override
-    public ITreeIndex getIndexInstance() throws HyracksDataException {
+    public ITreeIndex createIndexInstance() throws HyracksDataException {
         try {
             return BTreeUtils.createBTree(opDesc.getStorageManager().getBufferCache(ctx), opDesc.getStorageManager()
                     .getFileMapProvider(ctx), treeOpDesc.getTreeIndexTypeTraits(), treeOpDesc
diff --git a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/impls/BTree.java b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/impls/BTree.java
index 152ac32..3d3b27f 100644
--- a/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/impls/BTree.java
+++ b/hyracks-storage-am-btree/src/main/java/edu/uci/ics/hyracks/storage/am/btree/impls/BTree.java
@@ -476,6 +476,7 @@
                 restartOp = updateLeaf(tuple, targetTupleIndex, pageId, ctx);
             }
         } else {
+            targetTupleIndex = ctx.leafFrame.findInsertTupleIndex(tuple);
             restartOp = insertLeaf(tuple, targetTupleIndex, pageId, ctx);
         }
         return restartOp;
@@ -1001,7 +1002,7 @@
                 throw new UnsortedInputException("Input stream given to BTree bulk load is not sorted.");
             }
         }
-        
+
         protected void handleException() throws HyracksDataException {
             // Unlatch and unpin pages.
             for (NodeFrontier nodeFrontier : nodeFrontiers) {
@@ -1009,7 +1010,7 @@
                 bufferCache.unpin(nodeFrontier.page);
             }
         }
-        
+
         protected void propagateBulk(int level) throws HyracksDataException {
             if (splitKey.getBuffer() == null)
                 return;
diff --git a/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/api/IIndexDataflowHelper.java b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/api/IIndexDataflowHelper.java
index 5ec8f2f..a712c26 100644
--- a/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/api/IIndexDataflowHelper.java
+++ b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/api/IIndexDataflowHelper.java
@@ -1,19 +1,21 @@
 package edu.uci.ics.hyracks.storage.am.common.api;
 
-import edu.uci.ics.hyracks.api.context.IHyracksTaskContext;
 import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
 import edu.uci.ics.hyracks.api.io.FileReference;
 import edu.uci.ics.hyracks.storage.am.common.dataflow.IIndex;
-import edu.uci.ics.hyracks.storage.am.common.dataflow.IIndexOperatorDescriptor;
 
 public interface IIndexDataflowHelper {
-    public IIndex getIndexInstance() throws HyracksDataException;
+    public void create() throws HyracksDataException;
+
+    public void close() throws HyracksDataException;
+
+    public void open() throws HyracksDataException;
+
+    public void destroy() throws HyracksDataException;
+
+    public IIndex getIndexInstance();
 
     public FileReference getFileReference();
 
     public long getResourceID();
-
-    public IIndexOperatorDescriptor getOperatorDescriptor();
-
-    public IHyracksTaskContext getHyracksTaskContext();
 }
diff --git a/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/api/IIndexLifecycleManager.java b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/api/IIndexLifecycleManager.java
index f9eef0e..4bec1a0 100644
--- a/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/api/IIndexLifecycleManager.java
+++ b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/api/IIndexLifecycleManager.java
@@ -4,11 +4,13 @@
 import edu.uci.ics.hyracks.storage.am.common.dataflow.IIndex;
 
 public interface IIndexLifecycleManager {
-    public void create(IIndexDataflowHelper helper) throws HyracksDataException;
+    public IIndex getIndex(long resourceID);
 
-    public void destroy(IIndexDataflowHelper helper) throws HyracksDataException;
+    public void register(long resourceID, IIndex index) throws HyracksDataException;
 
-    public IIndex open(IIndexDataflowHelper helper) throws HyracksDataException;
+    public void unregister(long resourceID) throws HyracksDataException;
 
-    public void close(IIndexDataflowHelper helper) throws HyracksDataException;
-}
+    public void open(long resourceID) throws HyracksDataException;
+
+    public void close(long resourceID);
+}
\ No newline at end of file
diff --git a/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/IndexDataflowHelper.java b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/IndexDataflowHelper.java
index 8246f4b..c678844 100644
--- a/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/IndexDataflowHelper.java
+++ b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/IndexDataflowHelper.java
@@ -15,16 +15,20 @@
 
 package edu.uci.ics.hyracks.storage.am.common.dataflow;
 
+import java.io.IOException;
+
 import edu.uci.ics.hyracks.api.context.IHyracksTaskContext;
 import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
 import edu.uci.ics.hyracks.api.io.FileReference;
 import edu.uci.ics.hyracks.storage.am.common.api.IIndexDataflowHelper;
+import edu.uci.ics.hyracks.storage.am.common.api.IIndexLifecycleManager;
 import edu.uci.ics.hyracks.storage.common.file.IIndexArtifactMap;
 
 public abstract class IndexDataflowHelper implements IIndexDataflowHelper {
 
     protected final IIndexOperatorDescriptor opDesc;
     protected final IHyracksTaskContext ctx;
+    protected final IIndexLifecycleManager lcManager;
     protected final IIndexArtifactMap indexArtifactMap;
     protected final FileReference file;
 
@@ -33,30 +37,88 @@
     public IndexDataflowHelper(IIndexOperatorDescriptor opDesc, final IHyracksTaskContext ctx, int partition) {
         this.opDesc = opDesc;
         this.ctx = ctx;
+        this.lcManager = opDesc.getLifecycleManagerProvider().getLifecycleManager(ctx);
         this.indexArtifactMap = opDesc.getStorageManager().getIndexArtifactMap(ctx);
         this.file = opDesc.getFileSplitProvider().getFileSplits()[partition].getLocalFile();
     }
 
-    public abstract IIndex getIndexInstance() throws HyracksDataException;
+    protected abstract IIndex createIndexInstance() throws HyracksDataException;
 
-    @Override
+    public IIndex getIndexInstance() {
+        return index;
+    }
+
+    public void create() throws HyracksDataException {
+        synchronized (lcManager) {
+            long resourceID = getResourceID();
+            index = lcManager.getIndex(resourceID);
+            if (index != null) {
+                lcManager.unregister(resourceID);
+            } else {
+                index = createIndexInstance();
+            }
+
+            // The previous resource ID needs to be removed since calling IIndex.create() may possibly destroy 
+            // any physical artifact that the IIndexArtifactMap is managing (e.g. a file containing the resource ID). 
+            // Once the index has been created, a new resource ID can be generated.
+            if (resourceID != -1) {
+                indexArtifactMap.delete(file.getFile().getPath(), ctx.getIOManager().getIODevices());
+            }
+            index.create();
+            try {
+                resourceID = indexArtifactMap.create(file.getFile().getPath(), ctx.getIOManager().getIODevices());
+            } catch (IOException e) {
+                throw new HyracksDataException(e);
+            }
+            lcManager.register(resourceID, index);
+        }
+    }
+
+    public void open() throws HyracksDataException {
+        synchronized (lcManager) {
+            long resourceID = getResourceID();
+
+            if (resourceID == -1) {
+                throw new HyracksDataException("Index does not have a valid resource ID. Has it been created yet?");
+            }
+
+            index = lcManager.getIndex(resourceID);
+            if (index == null) {
+                index = createIndexInstance();
+                lcManager.register(resourceID, index);
+            }
+            lcManager.open(resourceID);
+        }
+    }
+
+    public void close() {
+        synchronized (lcManager) {
+            lcManager.close(getResourceID());
+        }
+    }
+
+    public void destroy() throws HyracksDataException {
+        synchronized (lcManager) {
+            long resourceID = getResourceID();
+            index = lcManager.getIndex(resourceID);
+            if (index != null) {
+                lcManager.unregister(resourceID);
+            } else {
+                index = createIndexInstance();
+            }
+
+            if (resourceID != -1) {
+                indexArtifactMap.delete(file.getFile().getPath(), ctx.getIOManager().getIODevices());
+            }
+            index.destroy();
+        }
+    }
+
     public FileReference getFileReference() {
         return file;
     }
 
-    public IIndex getIndex() {
-        return index;
-    }
-
     public long getResourceID() {
         return indexArtifactMap.get(file.getFile().getPath());
     }
-
-    public IIndexOperatorDescriptor getOperatorDescriptor() {
-        return opDesc;
-    }
-
-    public IHyracksTaskContext getHyracksTaskContext() {
-        return ctx;
-    }
 }
diff --git a/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/IndexLifecycleManager.java b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/IndexLifecycleManager.java
index 852c8a8..24e6bfd 100644
--- a/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/IndexLifecycleManager.java
+++ b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/IndexLifecycleManager.java
@@ -1,16 +1,11 @@
 package edu.uci.ics.hyracks.storage.am.common.dataflow;
 
-import java.io.IOException;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
 
-import edu.uci.ics.hyracks.api.context.IHyracksTaskContext;
 import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
-import edu.uci.ics.hyracks.api.io.IIOManager;
-import edu.uci.ics.hyracks.storage.am.common.api.IIndexDataflowHelper;
 import edu.uci.ics.hyracks.storage.am.common.api.IIndexLifecycleManager;
-import edu.uci.ics.hyracks.storage.common.file.IIndexArtifactMap;
 
 public class IndexLifecycleManager implements IIndexLifecycleManager {
     private static final long DEFAULT_MEMORY_BUDGET = 1024 * 1024 * 100; // 100 megabytes
@@ -30,89 +25,91 @@
         this.memoryUsed = 0;
     }
 
-    @Override
-    public synchronized void create(IIndexDataflowHelper helper) throws HyracksDataException {
-        IHyracksTaskContext ctx = helper.getHyracksTaskContext();
-        IIOManager ioManager = ctx.getIOManager();
-        IIndexArtifactMap indexArtifactMap = helper.getOperatorDescriptor().getStorageManager()
-                .getIndexArtifactMap(ctx);
-        IIndex index = helper.getIndexInstance();
-
-        boolean generateResourceID = helper.getResourceID() == -1 ? true : false;
-        if (generateResourceID) {
-            try {
-                indexArtifactMap.create(helper.getFileReference().getFile().getPath(), ioManager.getIODevices());
-            } catch (IOException e) {
-                throw new HyracksDataException(e);
-            }
-        }
-
-        index.create();
-    }
-
-    @Override
-    public synchronized void destroy(IIndexDataflowHelper helper) throws HyracksDataException {
-        IHyracksTaskContext ctx = helper.getHyracksTaskContext();
-        IIOManager ioManager = ctx.getIOManager();
-        IIndexArtifactMap indexArtifactMap = helper.getOperatorDescriptor().getStorageManager()
-                .getIndexArtifactMap(ctx);
-        IIndex index = helper.getIndexInstance();
-
-        indexArtifactMap.delete(helper.getFileReference().getFile().getPath(), ioManager.getIODevices());
-        index.destroy();
-    }
-
-    @Override
-    public synchronized IIndex open(IIndexDataflowHelper helper) throws HyracksDataException {
-        long resourceID = helper.getResourceID();
-        IndexInfo info = indexInfos.get(resourceID);
-
-        if (info == null) {
-            IIndex index = helper.getIndexInstance();
-            if (memoryUsed + index.getInMemorySize() > memoryBudget) {
-                if (!evictCandidateIndex()) {
-                    throw new HyracksDataException("Cannot activate index since memory budget would be exceeded.");
-                }
-            }
-
-            info = new IndexInfo(index, resourceID);
-            indexInfos.put(resourceID, info);
-            index.activate();
-            memoryUsed += index.getInMemorySize();
-        }
-
-        info.touch();
-        return info.index;
-    }
-
     private boolean evictCandidateIndex() throws HyracksDataException {
         IndexInfo info = Collections.min(indexInfos.values());
-        if (info.referenceCount != 0) {
+        if (info.referenceCount != 0 || !info.isOpen) {
             return false;
         }
 
         info.index.deactivate();
-        indexInfos.remove(info.resourceID);
+        memoryUsed -= info.index.getInMemorySize();
+        info.isOpen = false;
 
         return true;
     }
 
     @Override
-    public synchronized void close(IIndexDataflowHelper helper) throws HyracksDataException {
-        indexInfos.get(helper.getResourceID()).untouch();
+    public IIndex getIndex(long resourceID) {
+        IndexInfo info = indexInfos.get(resourceID);
+        return info == null ? null : info.index;
+    }
+
+    @Override
+    public void register(long resourceID, IIndex index) throws HyracksDataException {
+        if (indexInfos.containsKey(resourceID)) {
+            throw new HyracksDataException("Index with resource ID " + resourceID + " already exists.");
+        }
+
+        indexInfos.put(resourceID, new IndexInfo(index));
+    }
+
+    @Override
+    public void unregister(long resourceID) throws HyracksDataException {
+        IndexInfo info = indexInfos.remove(resourceID);
+        if (info == null) {
+            throw new HyracksDataException("Index with resource ID " + resourceID + " does not exist.");
+        }
+
+        if (info.referenceCount != 0) {
+            indexInfos.put(resourceID, info);
+            throw new HyracksDataException("Cannot remove index while it is open.");
+        }
+
+        if (info.isOpen) {
+            info.index.deactivate();
+            memoryUsed -= info.index.getInMemorySize();
+        }
+    }
+
+    @Override
+    public void open(long resourceID) throws HyracksDataException {
+        IndexInfo info = indexInfos.get(resourceID);
+        if (info == null) {
+            throw new HyracksDataException("Failed to open index with resource ID " + resourceID
+                    + " since it does not exist.");
+        }
+
+        long inMemorySize = info.index.getInMemorySize();
+        while (memoryUsed + inMemorySize > memoryBudget) {
+            if (!evictCandidateIndex()) {
+                throw new HyracksDataException("Cannot activate index since memory budget would be exceeded.");
+            }
+        }
+
+        if (!info.isOpen) {
+            info.index.activate();
+            info.isOpen = true;
+            memoryUsed += inMemorySize;
+        }
+        info.touch();
+    }
+
+    @Override
+    public void close(long resourceID) {
+        indexInfos.get(resourceID).untouch();
     }
 
     private class IndexInfo implements Comparable<IndexInfo> {
         private final IIndex index;
-        private final long resourceID;
         private int referenceCount;
         private long lastAccess;
+        private boolean isOpen;
 
-        public IndexInfo(IIndex index, long resourceID) {
+        public IndexInfo(IIndex index) {
             this.index = index;
-            this.resourceID = resourceID;
             this.lastAccess = -1;
             this.referenceCount = 0;
+            this.isOpen = false;
         }
 
         public void touch() {
@@ -127,20 +124,27 @@
 
         @Override
         public int compareTo(IndexInfo i) {
-            // sort by (referenceCount, lastAccess), ascending
-            if (referenceCount < i.referenceCount) {
+            // sort by (isOpen, referenceCount, lastAccess) ascending, where true < false
+            if (isOpen && !i.isOpen) {
                 return -1;
-            } else if (referenceCount > i.referenceCount) {
+            } else if (!isOpen && i.isOpen) {
                 return 1;
             } else {
-                if (lastAccess < i.lastAccess) {
+                if (referenceCount < i.referenceCount) {
                     return -1;
-                } else if (lastAccess > i.lastAccess) {
+                } else if (referenceCount > i.referenceCount) {
                     return 1;
                 } else {
-                    return 0;
+                    if (lastAccess < i.lastAccess) {
+                        return -1;
+                    } else if (lastAccess > i.lastAccess) {
+                        return 1;
+                    } else {
+                        return 0;
+                    }
                 }
             }
+
         }
 
         public String toString() {
diff --git a/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/TreeIndexBulkLoadOperatorNodePushable.java b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/TreeIndexBulkLoadOperatorNodePushable.java
index 3ecc477..6ec2336 100644
--- a/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/TreeIndexBulkLoadOperatorNodePushable.java
+++ b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/TreeIndexBulkLoadOperatorNodePushable.java
@@ -23,7 +23,6 @@
 import edu.uci.ics.hyracks.dataflow.common.comm.io.FrameTupleAccessor;
 import edu.uci.ics.hyracks.dataflow.std.base.AbstractUnaryInputSinkOperatorNodePushable;
 import edu.uci.ics.hyracks.storage.am.common.api.IIndexBulkLoader;
-import edu.uci.ics.hyracks.storage.am.common.api.IIndexLifecycleManager;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndex;
 import edu.uci.ics.hyracks.storage.am.common.api.IndexException;
 import edu.uci.ics.hyracks.storage.am.common.tuples.PermutingFrameTupleReference;
@@ -31,7 +30,6 @@
 public class TreeIndexBulkLoadOperatorNodePushable extends AbstractUnaryInputSinkOperatorNodePushable {
     private final AbstractTreeIndexOperatorDescriptor opDesc;
     private final IHyracksTaskContext ctx;
-    private final IIndexLifecycleManager lcManager;
     private final float fillFactor;
     private final boolean verifyInput;
     private final TreeIndexDataflowHelper treeIndexHelper;
@@ -44,10 +42,10 @@
     private PermutingFrameTupleReference tuple = new PermutingFrameTupleReference();
 
     public TreeIndexBulkLoadOperatorNodePushable(AbstractTreeIndexOperatorDescriptor opDesc, IHyracksTaskContext ctx,
-            int partition, int[] fieldPermutation, float fillFactor, boolean verifyInput, IRecordDescriptorProvider recordDescProvider) {
+            int partition, int[] fieldPermutation, float fillFactor, boolean verifyInput,
+            IRecordDescriptorProvider recordDescProvider) {
         this.opDesc = opDesc;
         this.ctx = ctx;
-        this.lcManager = opDesc.getLifecycleManagerProvider().getLifecycleManager(ctx);
         this.treeIndexHelper = (TreeIndexDataflowHelper) opDesc.getIndexDataflowHelperFactory()
                 .createIndexDataflowHelper(opDesc, ctx, partition);
         this.fillFactor = fillFactor;
@@ -60,11 +58,13 @@
     public void open() throws HyracksDataException {
         RecordDescriptor recDesc = recordDescProvider.getInputRecordDescriptor(opDesc.getActivityId(), 0);
         accessor = new FrameTupleAccessor(ctx.getFrameSize(), recDesc);
-        treeIndex = (ITreeIndex) lcManager.open(treeIndexHelper);
+
+        treeIndexHelper.open();
+        treeIndex = (ITreeIndex) treeIndexHelper.getIndexInstance();
         try {
             bulkLoader = treeIndex.createBulkLoader(fillFactor, verifyInput);
         } catch (Exception e) {
-            lcManager.close(treeIndexHelper);
+            treeIndexHelper.close();
             throw new HyracksDataException(e);
         }
     }
@@ -76,10 +76,10 @@
         for (int i = 0; i < tupleCount; i++) {
             tuple.reset(accessor, i);
             try {
-				bulkLoader.add(tuple);
-			} catch (IndexException e) {
-				throw new HyracksDataException(e);
-			}
+                bulkLoader.add(tuple);
+            } catch (IndexException e) {
+                throw new HyracksDataException(e);
+            }
         }
     }
 
@@ -90,11 +90,12 @@
         } catch (Exception e) {
             throw new HyracksDataException(e);
         } finally {
-            lcManager.close(treeIndexHelper);
+            treeIndexHelper.close();
         }
     }
 
     @Override
     public void fail() throws HyracksDataException {
+        writer.fail();
     }
 }
\ No newline at end of file
diff --git a/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/TreeIndexCreateOperatorNodePushable.java b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/TreeIndexCreateOperatorNodePushable.java
index a52d4d8..ee8df92 100644
--- a/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/TreeIndexCreateOperatorNodePushable.java
+++ b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/TreeIndexCreateOperatorNodePushable.java
@@ -20,15 +20,12 @@
 import edu.uci.ics.hyracks.api.dataflow.value.RecordDescriptor;
 import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
 import edu.uci.ics.hyracks.dataflow.std.base.AbstractOperatorNodePushable;
-import edu.uci.ics.hyracks.storage.am.common.api.IIndexLifecycleManager;
 
 public class TreeIndexCreateOperatorNodePushable extends AbstractOperatorNodePushable {
     private final TreeIndexDataflowHelper treeIndexHelper;
-    private final IIndexLifecycleManager lcManager;
 
     public TreeIndexCreateOperatorNodePushable(AbstractTreeIndexOperatorDescriptor opDesc, IHyracksTaskContext ctx,
             int partition) {
-        this.lcManager = opDesc.getLifecycleManagerProvider().getLifecycleManager(ctx);
         this.treeIndexHelper = (TreeIndexDataflowHelper) opDesc.getIndexDataflowHelperFactory()
                 .createIndexDataflowHelper(opDesc, ctx, partition);
     }
@@ -49,7 +46,7 @@
 
     @Override
     public void initialize() throws HyracksDataException {
-        lcManager.create(treeIndexHelper);
+        treeIndexHelper.create();
     }
 
     @Override
diff --git a/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/TreeIndexDataflowHelper.java b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/TreeIndexDataflowHelper.java
index 6548261..afa8015 100644
--- a/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/TreeIndexDataflowHelper.java
+++ b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/TreeIndexDataflowHelper.java
@@ -29,8 +29,6 @@
         this.treeOpDesc = (ITreeIndexOperatorDescriptor) opDesc;
     }
 
-    public abstract IIndex getIndexInstance() throws HyracksDataException;
-
     public ITreeIndexCursor createDiskOrderScanCursor(ITreeIndexFrame leafFrame) throws HyracksDataException {
         return new TreeDiskOrderScanCursor(leafFrame);
     }
diff --git a/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/TreeIndexDiskOrderScanOperatorNodePushable.java b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/TreeIndexDiskOrderScanOperatorNodePushable.java
index 1d31f1e..e8e5410 100644
--- a/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/TreeIndexDiskOrderScanOperatorNodePushable.java
+++ b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/TreeIndexDiskOrderScanOperatorNodePushable.java
@@ -24,7 +24,6 @@
 import edu.uci.ics.hyracks.dataflow.common.comm.util.FrameUtils;
 import edu.uci.ics.hyracks.dataflow.common.data.accessors.ITupleReference;
 import edu.uci.ics.hyracks.dataflow.std.base.AbstractUnaryOutputSourceOperatorNodePushable;
-import edu.uci.ics.hyracks.storage.am.common.api.IIndexLifecycleManager;
 import edu.uci.ics.hyracks.storage.am.common.api.ISearchOperationCallback;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndex;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexAccessor;
@@ -35,7 +34,6 @@
 public class TreeIndexDiskOrderScanOperatorNodePushable extends AbstractUnaryOutputSourceOperatorNodePushable {
     private final AbstractTreeIndexOperatorDescriptor opDesc;
     private final IHyracksTaskContext ctx;
-    private final IIndexLifecycleManager lcManager;
     private final TreeIndexDataflowHelper treeIndexHelper;
     private ITreeIndex treeIndex;
 
@@ -43,14 +41,14 @@
             IHyracksTaskContext ctx, int partition) {
         this.opDesc = opDesc;
         this.ctx = ctx;
-        this.lcManager = opDesc.getLifecycleManagerProvider().getLifecycleManager(ctx);
         this.treeIndexHelper = (TreeIndexDataflowHelper) opDesc.getIndexDataflowHelperFactory()
                 .createIndexDataflowHelper(opDesc, ctx, partition);
     }
 
     @Override
     public void initialize() throws HyracksDataException {
-        treeIndex = (ITreeIndex) lcManager.open(treeIndexHelper);
+        treeIndexHelper.open();
+        treeIndex = (ITreeIndex) treeIndexHelper.getIndexInstance();
         try {
             ITreeIndexFrame cursorFrame = treeIndex.getLeafFrameFactory().createFrame();
             ITreeIndexCursor cursor = treeIndexHelper.createDiskOrderScanCursor(cursorFrame);
@@ -97,12 +95,13 @@
                 writer.close();
             }
         } catch (Exception e) {
+            treeIndexHelper.close();
             throw new HyracksDataException(e);
         }
     }
 
     @Override
     public void deinitialize() throws HyracksDataException {
-        lcManager.close(treeIndexHelper);
+        treeIndexHelper.close();
     }
 }
\ No newline at end of file
diff --git a/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/TreeIndexDropOperatorNodePushable.java b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/TreeIndexDropOperatorNodePushable.java
index 005f22a..6f74e49 100644
--- a/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/TreeIndexDropOperatorNodePushable.java
+++ b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/TreeIndexDropOperatorNodePushable.java
@@ -15,24 +15,17 @@
 
 package edu.uci.ics.hyracks.storage.am.common.dataflow;
 
-import java.util.logging.Logger;
-
 import edu.uci.ics.hyracks.api.comm.IFrameWriter;
 import edu.uci.ics.hyracks.api.context.IHyracksTaskContext;
 import edu.uci.ics.hyracks.api.dataflow.value.RecordDescriptor;
 import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
 import edu.uci.ics.hyracks.dataflow.std.base.AbstractOperatorNodePushable;
-import edu.uci.ics.hyracks.storage.am.common.api.IIndexLifecycleManager;
 
 public class TreeIndexDropOperatorNodePushable extends AbstractOperatorNodePushable {
-    private static final Logger LOGGER = Logger.getLogger(TreeIndexDropOperatorNodePushable.class.getName());
-
     private final TreeIndexDataflowHelper treeIndexHelper;
-    private final IIndexLifecycleManager lcManager;
 
     public TreeIndexDropOperatorNodePushable(AbstractTreeIndexOperatorDescriptor opDesc, IHyracksTaskContext ctx,
             int partition) {
-        this.lcManager = opDesc.getLifecycleManagerProvider().getLifecycleManager(ctx);
         this.treeIndexHelper = (TreeIndexDataflowHelper) opDesc.getIndexDataflowHelperFactory()
                 .createIndexDataflowHelper(opDesc, ctx, partition);
     }
@@ -53,7 +46,7 @@
 
     @Override
     public void initialize() throws HyracksDataException {
-        lcManager.destroy(treeIndexHelper);
+        treeIndexHelper.destroy();
     }
 
     @Override
diff --git a/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/TreeIndexInsertUpdateDeleteOperatorNodePushable.java b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/TreeIndexInsertUpdateDeleteOperatorNodePushable.java
index 3af2b22..c7c5a9d 100644
--- a/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/TreeIndexInsertUpdateDeleteOperatorNodePushable.java
+++ b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/TreeIndexInsertUpdateDeleteOperatorNodePushable.java
@@ -25,7 +25,6 @@
 import edu.uci.ics.hyracks.dataflow.common.data.accessors.FrameTupleReference;
 import edu.uci.ics.hyracks.dataflow.std.base.AbstractUnaryInputUnaryOutputOperatorNodePushable;
 import edu.uci.ics.hyracks.storage.am.common.api.IIndexAccessor;
-import edu.uci.ics.hyracks.storage.am.common.api.IIndexLifecycleManager;
 import edu.uci.ics.hyracks.storage.am.common.api.IModificationOperationCallback;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndex;
 import edu.uci.ics.hyracks.storage.am.common.api.ITupleFilter;
@@ -37,7 +36,6 @@
 public class TreeIndexInsertUpdateDeleteOperatorNodePushable extends AbstractUnaryInputUnaryOutputOperatorNodePushable {
     private final AbstractTreeIndexOperatorDescriptor opDesc;
     private final IHyracksTaskContext ctx;
-    private final IIndexLifecycleManager lcManager;
     private final TreeIndexDataflowHelper treeIndexHelper;
     private FrameTupleAccessor accessor;
     private final IRecordDescriptorProvider recordDescProvider;
@@ -54,7 +52,6 @@
             IRecordDescriptorProvider recordDescProvider, IndexOp op) {
         this.opDesc = opDesc;
         this.ctx = ctx;
-        this.lcManager = opDesc.getLifecycleManagerProvider().getLifecycleManager(ctx);
         this.treeIndexHelper = (TreeIndexDataflowHelper) opDesc.getIndexDataflowHelperFactory()
                 .createIndexDataflowHelper(opDesc, ctx, partition);
         this.recordDescProvider = recordDescProvider;
@@ -68,7 +65,8 @@
         accessor = new FrameTupleAccessor(ctx.getFrameSize(), inputRecDesc);
         writeBuffer = ctx.allocateFrame();
         writer.open();
-        ITreeIndex treeIndex = (ITreeIndex) lcManager.open(treeIndexHelper);
+        treeIndexHelper.open();
+        ITreeIndex treeIndex = (ITreeIndex) treeIndexHelper.getIndexInstance();
         try {
             modCallback = opDesc.getOpCallbackProvider().getModificationOperationCallback(
                     treeIndexHelper.getResourceID());
@@ -79,7 +77,7 @@
                 frameTuple = new FrameTupleReference();
             }
         } catch (Exception e) {
-            lcManager.close(treeIndexHelper);
+            treeIndexHelper.close();
             throw new HyracksDataException(e);
         }
     }
@@ -136,7 +134,7 @@
         try {
             writer.close();
         } finally {
-            lcManager.close(treeIndexHelper);
+            treeIndexHelper.close();
         }
 
     }
diff --git a/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/TreeIndexSearchOperatorNodePushable.java b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/TreeIndexSearchOperatorNodePushable.java
index 18f27cb..657163c 100644
--- a/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/TreeIndexSearchOperatorNodePushable.java
+++ b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/TreeIndexSearchOperatorNodePushable.java
@@ -30,7 +30,6 @@
 import edu.uci.ics.hyracks.dataflow.std.base.AbstractUnaryInputUnaryOutputOperatorNodePushable;
 import edu.uci.ics.hyracks.storage.am.common.api.IIndexAccessor;
 import edu.uci.ics.hyracks.storage.am.common.api.IIndexCursor;
-import edu.uci.ics.hyracks.storage.am.common.api.IIndexLifecycleManager;
 import edu.uci.ics.hyracks.storage.am.common.api.ISearchOperationCallback;
 import edu.uci.ics.hyracks.storage.am.common.api.ISearchPredicate;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndex;
@@ -40,7 +39,6 @@
 public abstract class TreeIndexSearchOperatorNodePushable extends AbstractUnaryInputUnaryOutputOperatorNodePushable {
     protected final AbstractTreeIndexOperatorDescriptor opDesc;
     protected final IHyracksTaskContext ctx;
-    protected final IIndexLifecycleManager lcManager;
     protected final TreeIndexDataflowHelper treeIndexHelper;
     protected FrameTupleAccessor accessor;
 
@@ -63,7 +61,6 @@
             int partition, IRecordDescriptorProvider recordDescProvider) {
         this.opDesc = opDesc;
         this.ctx = ctx;
-        this.lcManager = opDesc.getLifecycleManagerProvider().getLifecycleManager(ctx);
         this.treeIndexHelper = (TreeIndexDataflowHelper) opDesc.getIndexDataflowHelperFactory()
                 .createIndexDataflowHelper(opDesc, ctx, partition);
         this.retainInput = opDesc.getRetainInput();
@@ -82,7 +79,8 @@
     public void open() throws HyracksDataException {
         accessor = new FrameTupleAccessor(ctx.getFrameSize(), inputRecDesc);
         writer.open();
-        treeIndex = (ITreeIndex) lcManager.open(treeIndexHelper);
+        treeIndexHelper.open();
+        treeIndex = (ITreeIndex) treeIndexHelper.getIndexInstance();
         try {
             cursorFrame = treeIndex.getLeafFrameFactory().createFrame();
             searchPred = createSearchPredicate();
@@ -99,7 +97,7 @@
                 frameTuple = new FrameTupleReference();
             }
         } catch (Exception e) {
-            lcManager.close(treeIndexHelper);
+            treeIndexHelper.close();
             throw new HyracksDataException(e);
         }
     }
@@ -159,7 +157,7 @@
                 throw new HyracksDataException(e);
             }
         } finally {
-            lcManager.close(treeIndexHelper);
+            treeIndexHelper.close();
         }
     }
 
diff --git a/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/TreeIndexStatsOperatorNodePushable.java b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/TreeIndexStatsOperatorNodePushable.java
index 6f1f2ab..09d357d 100644
--- a/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/TreeIndexStatsOperatorNodePushable.java
+++ b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/dataflow/TreeIndexStatsOperatorNodePushable.java
@@ -25,7 +25,6 @@
 import edu.uci.ics.hyracks.dataflow.common.comm.util.FrameUtils;
 import edu.uci.ics.hyracks.dataflow.common.data.marshalling.UTF8StringSerializerDeserializer;
 import edu.uci.ics.hyracks.dataflow.std.base.AbstractUnaryOutputSourceOperatorNodePushable;
-import edu.uci.ics.hyracks.storage.am.common.api.IIndexLifecycleManager;
 import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndex;
 import edu.uci.ics.hyracks.storage.am.common.util.TreeIndexStats;
 import edu.uci.ics.hyracks.storage.am.common.util.TreeIndexStatsGatherer;
@@ -35,7 +34,6 @@
 public class TreeIndexStatsOperatorNodePushable extends AbstractUnaryOutputSourceOperatorNodePushable {
     private final AbstractTreeIndexOperatorDescriptor opDesc;
     private final IHyracksTaskContext ctx;
-    private final IIndexLifecycleManager lcManager;
     private final TreeIndexDataflowHelper treeIndexHelper;
     private TreeIndexStatsGatherer statsGatherer;
 
@@ -43,7 +41,6 @@
             int partition) {
         this.opDesc = opDesc;
         this.ctx = ctx;
-        this.lcManager = opDesc.getLifecycleManagerProvider().getLifecycleManager(ctx);
         this.treeIndexHelper = (TreeIndexDataflowHelper) opDesc.getIndexDataflowHelperFactory()
                 .createIndexDataflowHelper(opDesc, ctx, partition);
 
@@ -51,7 +48,6 @@
 
     @Override
     public void deinitialize() throws HyracksDataException {
-        lcManager.close(treeIndexHelper);
     }
 
     @Override
@@ -61,7 +57,8 @@
 
     @Override
     public void initialize() throws HyracksDataException {
-        ITreeIndex treeIndex = (ITreeIndex) lcManager.open(treeIndexHelper);
+        treeIndexHelper.open();
+        ITreeIndex treeIndex = (ITreeIndex) treeIndexHelper.getIndexInstance();
         try {
             writer.open();
             IBufferCache bufferCache = opDesc.getStorageManager().getBufferCache(ctx);
@@ -89,6 +86,7 @@
             writer.fail();
         } finally {
             writer.close();
+            treeIndexHelper.close();
         }
     }
 }
\ No newline at end of file
diff --git a/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/btree/dataflow/LSMBTreeDataflowHelper.java b/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/btree/dataflow/LSMBTreeDataflowHelper.java
index 25b8b8c..5ddd18d 100644
--- a/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/btree/dataflow/LSMBTreeDataflowHelper.java
+++ b/hyracks-storage-am-lsm-btree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/btree/dataflow/LSMBTreeDataflowHelper.java
@@ -64,7 +64,7 @@
     }
 
     @Override
-    public ITreeIndex getIndexInstance() throws HyracksDataException {
+    public ITreeIndex createIndexInstance() throws HyracksDataException {
         ITreeIndexMetaDataFrameFactory metaDataFrameFactory = new LIFOMetaDataFrameFactory();
         InMemoryBufferCache memBufferCache = new InMemoryBufferCache(new HeapBufferAllocator(), memPageSize,
                 memNumPages, new TransientFileMapManager());
diff --git a/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/dataflow/AbstractLSMRTreeDataflowHelper.java b/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/dataflow/AbstractLSMRTreeDataflowHelper.java
index 244e07c..53769b6 100644
--- a/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/dataflow/AbstractLSMRTreeDataflowHelper.java
+++ b/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/dataflow/AbstractLSMRTreeDataflowHelper.java
@@ -82,7 +82,7 @@
     }
 
     @Override
-    public ITreeIndex getIndexInstance() throws HyracksDataException {
+    public ITreeIndex createIndexInstance() throws HyracksDataException {
         ITreeIndexMetaDataFrameFactory metaDataFrameFactory = new LIFOMetaDataFrameFactory();
         InMemoryBufferCache memBufferCache = new DualIndexInMemoryBufferCache(new HeapBufferAllocator(), memPageSize,
                 memNumPages);
diff --git a/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/dataflow/RTreeDataflowHelper.java b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/dataflow/RTreeDataflowHelper.java
index f513460..0ee1a93 100644
--- a/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/dataflow/RTreeDataflowHelper.java
+++ b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/dataflow/RTreeDataflowHelper.java
@@ -37,7 +37,7 @@
     }
 
     @Override
-    public ITreeIndex getIndexInstance() throws HyracksDataException {
+    public ITreeIndex createIndexInstance() throws HyracksDataException {
         return RTreeUtils.createRTree(treeOpDesc.getStorageManager().getBufferCache(ctx), treeOpDesc
                 .getStorageManager().getFileMapProvider(ctx), treeOpDesc.getTreeIndexTypeTraits(),
                 valueProviderFactories, treeOpDesc.getTreeIndexComparatorFactories(), rtreePolicyType, file);