[NO ISSUE][STO] Account For Pages With Multiple Pages in LAFWriter

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

Details:
- Always ensure that the LAFWriter entry pages are allocated
  for the main page as well as any extra pages.
- Account for null pages during backload failures to avoid NPEs.

Change-Id: Ib9a7a04fe97e4031001925134f7bfc14a97a6078
Reviewed-on: https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/5764
Reviewed-by: Michael Blow <mblow@apache.org>
Integration-Tests: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/impls/AbstractTreeIndex.java b/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/impls/AbstractTreeIndex.java
index 3158b79..df70d99 100644
--- a/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/impls/AbstractTreeIndex.java
+++ b/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/impls/AbstractTreeIndex.java
@@ -288,13 +288,17 @@
             // Unlatch and unpin pages that weren't in the queue to avoid leaking memory.
             compressedPageWriter.abort();
             for (NodeFrontier nodeFrontier : nodeFrontiers) {
-                ICachedPage frontierPage = nodeFrontier.page;
-                if (frontierPage.confiscated()) {
-                    bufferCache.returnPage(frontierPage, false);
+                if (nodeFrontier != null && nodeFrontier.page != null) {
+                    ICachedPage frontierPage = nodeFrontier.page;
+                    if (frontierPage.confiscated()) {
+                        bufferCache.returnPage(frontierPage, false);
+                    }
                 }
             }
             for (ICachedPage pageToDiscard : pagesToWrite) {
-                bufferCache.returnPage(pageToDiscard, false);
+                if (pageToDiscard != null) {
+                    bufferCache.returnPage(pageToDiscard, false);
+                }
             }
             releasedLatches = true;
         }
diff --git a/hyracks-fullstack/hyracks/hyracks-storage-common/src/main/java/org/apache/hyracks/storage/common/compression/file/LAFWriter.java b/hyracks-fullstack/hyracks/hyracks-storage-common/src/main/java/org/apache/hyracks/storage/common/compression/file/LAFWriter.java
index 9217415..3226786 100644
--- a/hyracks-fullstack/hyracks/hyracks-storage-common/src/main/java/org/apache/hyracks/storage/common/compression/file/LAFWriter.java
+++ b/hyracks-fullstack/hyracks/hyracks-storage-common/src/main/java/org/apache/hyracks/storage/common/compression/file/LAFWriter.java
@@ -83,22 +83,21 @@
     public void prepareWrite(ICachedPage cPage) throws HyracksDataException {
         final ICachedPageInternal internalPage = (ICachedPageInternal) cPage;
         final int entryPageId = getLAFEntryPageId(BufferedFileHandle.getPageId(internalPage.getDiskPageId()));
-
-        if (!cachedFrames.containsKey(entryPageId)) {
-            try {
-                //Writing new page(s). Confiscate the page(s) from the buffer cache.
-                prepareFrames(entryPageId, internalPage);
-            } catch (HyracksDataException e) {
-                abort();
-                throw e;
-            }
+        try {
+            //Writing new page(s). Confiscate the page(s) from the buffer cache.
+            prepareFrames(entryPageId, internalPage);
+        } catch (HyracksDataException e) {
+            abort();
+            throw e;
         }
     }
 
     private void prepareFrames(int entryPageId, ICachedPageInternal cPage) throws HyracksDataException {
-        //Confiscate the first page
-        confiscatePage(entryPageId);
-        //check if extra pages spans to the next entry page
+        // check if we need to confiscate a page for the main page
+        if (!cachedFrames.containsKey(entryPageId)) {
+            confiscatePage(entryPageId);
+        }
+        // check if extra pages span to the next entry page
         for (int i = 0; i < cPage.getFrameSizeMultiplier() - 1; i++) {
             final int extraEntryPageId = getLAFEntryPageId(cPage.getExtraBlockPageId() + i);
             if (!cachedFrames.containsKey(extraEntryPageId)) {