[NO ISSUE][STO] Improve logging when failing to schedule a flush

- user model changes: no
- storage format changes: no
- interface changes: no

Details:
- Log partition info when failing to schedule a flush operation.
- Fix isCurrentMutableComponentEmpty() to consider the
  UNREADABLE_UNWRITABLE state.

Change-Id: I9bbc0be36633b896becc16d3eeddeef980db5802
Reviewed-on: https://asterix-gerrit.ics.uci.edu/2662
Sonar-Qube: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Contrib: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Reviewed-by: Murtadha Hubail <mhubail@apache.org>
Integration-Tests: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
diff --git a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/context/PrimaryIndexOperationTracker.java b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/context/PrimaryIndexOperationTracker.java
index 52c8962..0aa0d2b 100644
--- a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/context/PrimaryIndexOperationTracker.java
+++ b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/context/PrimaryIndexOperationTracker.java
@@ -51,8 +51,11 @@
 import org.apache.hyracks.storage.am.lsm.common.impls.LSMComponentId;
 import org.apache.hyracks.storage.common.IModificationOperationCallback;
 import org.apache.hyracks.storage.common.ISearchOperationCallback;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
 
 public class PrimaryIndexOperationTracker extends BaseOperationTracker implements IoOperationCompleteListener {
+    private static final Logger LOGGER = LogManager.getLogger();
     private final int partition;
     // Number of active operations on an ILSMIndex instance.
     private final AtomicInteger numActiveOperations;
@@ -113,23 +116,34 @@
             }
         }
 
+        ILSMIndex primaryLsmIndex = null;
         if (needsFlush || flushOnExit) {
             flushOnExit = false;
             // make the current mutable components READABLE_UNWRITABLE to stop coming modify operations from entering
             // them until the current flush is scheduled.
             LSMComponentId primaryId = null;
             //Double check that the primary index has been modified
+
             synchronized (this) {
                 if (numActiveOperations.get() > 0) {
                     throw new IllegalStateException(
                             "Can't request a flush on an index with active operations: " + numActiveOperations.get());
                 }
                 for (ILSMIndex lsmIndex : indexes) {
-                    if (lsmIndex.isPrimaryIndex() && lsmIndex.isCurrentMutableComponentEmpty()) {
-                        return;
+                    if (lsmIndex.isPrimaryIndex()) {
+                        if (lsmIndex.isCurrentMutableComponentEmpty()) {
+                            LOGGER.info("Primary index on dataset {} and partition {} is empty... skipping flush");
+                            return;
+                        }
+                        primaryLsmIndex = lsmIndex;
+                        break;
                     }
                 }
             }
+            if (primaryLsmIndex == null) {
+                throw new IllegalStateException(
+                        "Primary index not found in dataset " + dsInfo.getDatasetID() + " and partition " + partition);
+            }
             for (ILSMIndex lsmIndex : indexes) {
                 ILSMOperationTracker opTracker = lsmIndex.getOperationTracker();
                 synchronized (opTracker) {
@@ -148,7 +162,8 @@
                 }
             }
             if (primaryId == null) {
-                throw new IllegalStateException("Primary index not found in dataset " + dsInfo.getDatasetID());
+                throw new IllegalStateException("Primary index found in dataset " + dsInfo.getDatasetID()
+                        + " and partition " + partition + " and is modified but its component id is null");
             }
             LogRecord logRecord = new LogRecord();
             if (dsInfo.isDurable()) {
diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/AbstractLSMIndex.java b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/AbstractLSMIndex.java
index c9fb328..377a218 100644
--- a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/AbstractLSMIndex.java
+++ b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/AbstractLSMIndex.java
@@ -675,7 +675,7 @@
             ILSMMemoryComponent cmc = getCurrentMemoryComponent();
             ComponentState state = cmc.getState();
             return state == ComponentState.READABLE_UNWRITABLE_FLUSHING || state == ComponentState.INACTIVE
-                    || !cmc.isModified();
+                    || state == ComponentState.UNREADABLE_UNWRITABLE || !cmc.isModified();
         }
     }