Changed operation tracker to include an externally called completeOperation() for finally declaring an operation inactive on an lsm index.

git-svn-id: https://hyracks.googlecode.com/svn/branches/hyracks_lsm_tree@2363 123451ca-8445-de46-9d55-352943316053
diff --git a/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/api/IModificationOperationCallbackFactory.java b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/api/IModificationOperationCallbackFactory.java
new file mode 100644
index 0000000..11ca39d
--- /dev/null
+++ b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/api/IModificationOperationCallbackFactory.java
@@ -0,0 +1,11 @@
+package edu.uci.ics.hyracks.storage.am.common.api;
+
+import java.io.Serializable;
+
+import edu.uci.ics.hyracks.api.context.IHyracksTaskContext;
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+
+public interface IModificationOperationCallbackFactory extends Serializable {
+    public IModificationOperationCallback createModificationOperationCallback(long resourceId, IHyracksTaskContext ctx)
+            throws HyracksDataException;
+}
diff --git a/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/api/ISearchOperationCallbackFactory.java b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/api/ISearchOperationCallbackFactory.java
new file mode 100644
index 0000000..6389b8d
--- /dev/null
+++ b/hyracks-storage-am-common/src/main/java/edu/uci/ics/hyracks/storage/am/common/api/ISearchOperationCallbackFactory.java
@@ -0,0 +1,11 @@
+package edu.uci.ics.hyracks.storage.am.common.api;
+
+import java.io.Serializable;
+
+import edu.uci.ics.hyracks.api.context.IHyracksTaskContext;
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+
+public interface ISearchOperationCallbackFactory extends Serializable {
+    public ISearchOperationCallback createSearchOperationCallback(long resourceId, IHyracksTaskContext ctx)
+            throws HyracksDataException;
+}
diff --git a/hyracks-storage-am-lsm-common/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/common/api/ILSMOperationTracker.java b/hyracks-storage-am-lsm-common/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/common/api/ILSMOperationTracker.java
index 60af948..965daf8 100644
--- a/hyracks-storage-am-lsm-common/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/common/api/ILSMOperationTracker.java
+++ b/hyracks-storage-am-lsm-common/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/common/api/ILSMOperationTracker.java
@@ -4,28 +4,33 @@
 import edu.uci.ics.hyracks.storage.am.common.api.IIndexAccessor;
 
 /**
- * This interface exposes methods for tracking when operations (e.g. insert, search) 
- * enter and exit an {@link ILSMIndex}.
- * 
+ * This interface exposes methods for tracking and setting the status of operations for the purpose
+ * of coordinating flushes/merges in {@link ILSMIndex}.
  * Note that 'operation' below refers to {@link IIndexAccessor} methods.
- *  
+ * 
  * @author zheilbron
  */
 public interface ILSMOperationTracker {
 
     /**
-     * This method is guaranteed to be called whenever an operation first begins on the index, 
-     * before any traversals of the index structures (more specifically, before any 
-     * pages are pinned/latched).
-     * 
-     * @param index the index for which the operation entered
+     * An {@link ILSMIndex} will call this method before an operation enters it,
+     * i.e., before any latches are taken.
+     * After this method has been called, the operation is considered 'active'.
      */
-    public void threadEnter(ILSMIndex index) throws HyracksDataException;
+    public void beforeOperation(ILSMIndex index) throws HyracksDataException;
 
     /**
-     * This method is guaranteed to be called just before an operation is finished on the index.
-     * 
-     * @param index the index for which the operation exited
+     * An {@link ILSMIndex} will call this method after an operation has left the index,
+     * i.e., after all relevant latches have been released.
+     * After this method has been called, the operation is still considered 'active',
+     * until the issuer of the operation declares it completed by calling completeOperation().
      */
-    public void threadExit(ILSMIndex index) throws HyracksDataException;
+    public void afterOperation(ILSMIndex index) throws HyracksDataException;
+
+    /**
+     * This method must be called by whoever is requesting the index operation through an {@link IIndexAccessor}.
+     * The use of this method indicates that the operation is no longer 'active'
+     * for the purpose of coordinating flushes/merges.
+     */
+    public void completeOperation(ILSMIndex index) throws HyracksDataException;
 }
diff --git a/hyracks-storage-am-lsm-common/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/common/impls/LSMHarness.java b/hyracks-storage-am-lsm-common/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/common/impls/LSMHarness.java
index 9da5ceb..38159b9 100644
--- a/hyracks-storage-am-lsm-common/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/common/impls/LSMHarness.java
+++ b/hyracks-storage-am-lsm-common/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/common/impls/LSMHarness.java
@@ -86,12 +86,12 @@
         if (!lsmIndex.getFlushController().getFlushStatus(lsmIndex) && lsmIndex.getInMemoryFreePageManager().isFull()) {
             lsmIndex.getFlushController().setFlushStatus(lsmIndex, true);
         }
-        opTracker.threadExit(lsmIndex);
+        opTracker.afterOperation(lsmIndex);
     }
 
     public void insertUpdateOrDelete(ITupleReference tuple, IIndexOperationContext ctx) throws HyracksDataException,
             IndexException {
-        opTracker.threadEnter(lsmIndex);
+        opTracker.beforeOperation(lsmIndex);
         // It is possible, due to concurrent execution of operations, that an operation will 
         // fail. In such a case, simply retry the operation. Refer to the specific LSMIndex code 
         // to see exactly why an operation might fail.
@@ -129,7 +129,7 @@
         // If the search doesn't include the in-memory component, then we don't have
         // to synchronize with a flush.
         if (includeMemComponent) {
-            opTracker.threadEnter(lsmIndex);
+            opTracker.beforeOperation(lsmIndex);
         }
 
         // Get a snapshot of the current on-disk Trees.
diff --git a/hyracks-storage-am-lsm-common/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/common/impls/ReferenceCountingOperationTracker.java b/hyracks-storage-am-lsm-common/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/common/impls/ReferenceCountingOperationTracker.java
index 5c0d575..cbd5aea 100644
--- a/hyracks-storage-am-lsm-common/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/common/impls/ReferenceCountingOperationTracker.java
+++ b/hyracks-storage-am-lsm-common/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/common/impls/ReferenceCountingOperationTracker.java
@@ -12,7 +12,7 @@
     private int threadRefCount = 0;
 
     @Override
-    public void threadEnter(ILSMIndex index) throws HyracksDataException {
+    public void beforeOperation(final ILSMIndex index) throws HyracksDataException {
         synchronized (this) {
             // flushFlag may be set to true even though the flush has not occurred yet.
             // If flushFlag is set, then the flush is queued to occur by the last exiting thread.
@@ -32,7 +32,13 @@
     }
 
     @Override
-    public void threadExit(final ILSMIndex index) throws HyracksDataException {
+    public void afterOperation(final ILSMIndex index) throws HyracksDataException {
+        // The operation is considered inactive, immediately after leaving the index.
+        completeOperation(index);
+    }
+
+    @Override
+    public void completeOperation(final ILSMIndex index) throws HyracksDataException {
         synchronized (this) {
             threadRefCount--;
 
@@ -49,4 +55,5 @@
             }
         }
     }
+
 }
diff --git a/hyracks-tests/hyracks-storage-am-lsm-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/btree/LSMBTreeModificationOperationCallbackTest.java b/hyracks-tests/hyracks-storage-am-lsm-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/btree/LSMBTreeModificationOperationCallbackTest.java
index 660197c..62a1d71 100644
--- a/hyracks-tests/hyracks-storage-am-lsm-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/btree/LSMBTreeModificationOperationCallbackTest.java
+++ b/hyracks-tests/hyracks-storage-am-lsm-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/btree/LSMBTreeModificationOperationCallbackTest.java
@@ -2,6 +2,7 @@
 
 import org.junit.Test;
 
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
 import edu.uci.ics.hyracks.dataflow.common.util.SerdeUtils;
 import edu.uci.ics.hyracks.dataflow.common.util.TupleUtils;
 import edu.uci.ics.hyracks.storage.am.btree.AbstractModificationOperationCallbackTest;
@@ -31,12 +32,17 @@
     protected void createIndexInstance() throws Exception {
         ILSMOperationTracker tracker = new ILSMOperationTracker() {
             @Override
-            public void threadExit(ILSMIndex index) {
+            public void afterOperation(ILSMIndex index) {
                 // Do nothing
             }
 
             @Override
-            public void threadEnter(ILSMIndex index) {
+            public void beforeOperation(ILSMIndex index) {
+                // Do nothing
+            }
+
+            @Override
+            public void completeOperation(ILSMIndex index) throws HyracksDataException {
                 // Do nothing
             }
         };
diff --git a/hyracks-tests/hyracks-storage-am-lsm-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/btree/LSMBTreeSearchOperationCallbackTest.java b/hyracks-tests/hyracks-storage-am-lsm-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/btree/LSMBTreeSearchOperationCallbackTest.java
index be79257..e51c8cc 100644
--- a/hyracks-tests/hyracks-storage-am-lsm-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/btree/LSMBTreeSearchOperationCallbackTest.java
+++ b/hyracks-tests/hyracks-storage-am-lsm-btree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/btree/LSMBTreeSearchOperationCallbackTest.java
@@ -35,12 +35,17 @@
     protected void createIndexInstance() throws Exception {
         ILSMOperationTracker tracker = new ILSMOperationTracker() {
             @Override
-            public void threadExit(ILSMIndex index) {
+            public void afterOperation(ILSMIndex index) {
                 // Do nothing
             }
 
             @Override
-            public void threadEnter(ILSMIndex index) {
+            public void beforeOperation(ILSMIndex index) {
+                // Do nothing
+            }
+
+            @Override
+            public void completeOperation(ILSMIndex index) throws HyracksDataException {
                 // Do nothing
             }
         };