Truncate a temporary file before deleting it.

 - Before RunFileReader tries to delete a temporary file,
   make sure to truncate the file since OS might keep the
   deleted file for a while, thus taking disk space.

Change-Id: Ie906c9f950e2f31af6f1b5ecc9cb35829d3edf8a
Reviewed-on: https://asterix-gerrit.ics.uci.edu/1501
Sonar-Qube: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Reviewed-by: Yingyi Bu <buyingyi@gmail.com>
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Integration-Tests: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
diff --git a/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/exceptions/ErrorCode.java b/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/exceptions/ErrorCode.java
index 35002f8..3826f01 100644
--- a/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/exceptions/ErrorCode.java
+++ b/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/exceptions/ErrorCode.java
@@ -53,6 +53,7 @@
     public static final int RESULT_FAILURE_EXCEPTION = 16;
     public static final int RESULT_FAILURE_NO_EXCEPTION = 17;
     public static final int INCONSISTENT_RESULT_METADATA = 18;
+    public static final int CANNOT_TRUNCATE_OR_DELETE_FILE = 19;
 
     // Compilation error codes.
     public static final int RULECOLLECTION_NOT_INSTANCE_OF_LIST = 10001;
diff --git a/hyracks-fullstack/hyracks/hyracks-api/src/main/resources/errormsg/en.properties b/hyracks-fullstack/hyracks/hyracks-api/src/main/resources/errormsg/en.properties
index de58f33..931429a 100644
--- a/hyracks-fullstack/hyracks/hyracks-api/src/main/resources/errormsg/en.properties
+++ b/hyracks-fullstack/hyracks/hyracks-api/src/main/resources/errormsg/en.properties
@@ -37,5 +37,5 @@
 16 = Failure producing result set %1$s for job %2$s
 17 = No exception for failed result set %1$s for job %2$s
 18 = Inconsistent metadata for result set %1$s"
-
+19 = Can't truncate or delete the file: %1$s
 10000 = The given rule collection %1$s is not an instance of the List class.
diff --git a/hyracks-fullstack/hyracks/hyracks-dataflow-common/pom.xml b/hyracks-fullstack/hyracks/hyracks-dataflow-common/pom.xml
index 5e30a74..4044142 100644
--- a/hyracks-fullstack/hyracks/hyracks-dataflow-common/pom.xml
+++ b/hyracks-fullstack/hyracks/hyracks-dataflow-common/pom.xml
@@ -69,7 +69,6 @@
       <groupId>org.apache.hyracks</groupId>
       <artifactId>hyracks-control-nc</artifactId>
       <version>${project.version}</version>
-      <scope>test</scope>
     </dependency>
     <dependency>
       <groupId>commons-io</groupId>
diff --git a/hyracks-fullstack/hyracks/hyracks-dataflow-common/src/main/java/org/apache/hyracks/dataflow/common/io/RunFileReader.java b/hyracks-fullstack/hyracks/hyracks-dataflow-common/src/main/java/org/apache/hyracks/dataflow/common/io/RunFileReader.java
index 71ac6a6..b69f377 100644
--- a/hyracks-fullstack/hyracks/hyracks-dataflow-common/src/main/java/org/apache/hyracks/dataflow/common/io/RunFileReader.java
+++ b/hyracks-fullstack/hyracks/hyracks-dataflow-common/src/main/java/org/apache/hyracks/dataflow/common/io/RunFileReader.java
@@ -18,14 +18,18 @@
  */
 package org.apache.hyracks.dataflow.common.io;
 
+import java.io.IOException;
+
 import org.apache.commons.io.FileUtils;
 import org.apache.hyracks.api.comm.FrameHelper;
 import org.apache.hyracks.api.comm.IFrame;
 import org.apache.hyracks.api.comm.IFrameReader;
+import org.apache.hyracks.api.exceptions.ErrorCode;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.api.io.FileReference;
 import org.apache.hyracks.api.io.IFileHandle;
 import org.apache.hyracks.api.io.IIOManager;
+import org.apache.hyracks.control.nc.io.FileHandle;
 
 public class RunFileReader implements IFrameReader {
     private final FileReference file;
@@ -44,7 +48,9 @@
 
     @Override
     public void open() throws HyracksDataException {
-        handle = ioManager.open(file, IIOManager.FileReadWriteMode.READ_ONLY, null);
+        // Opens RW mode because we need to truncate the given file if required.
+        handle = ioManager.open(file, IIOManager.FileReadWriteMode.READ_WRITE,
+                IIOManager.FileSyncMode.METADATA_ASYNC_DATA_ASYNC);
         readPtr = 0;
     }
 
@@ -79,9 +85,17 @@
 
     @Override
     public void close() throws HyracksDataException {
-        ioManager.close(handle);
         if (deleteAfterClose) {
-            FileUtils.deleteQuietly(file.getFile());
+            try {
+                // Truncates the file size to zero since OS might be keeping the file for a while.
+                ((FileHandle) handle).getFileChannel().truncate(0);
+                ioManager.close(handle);
+                FileUtils.deleteQuietly(file.getFile());
+            } catch (IOException e) {
+                throw HyracksDataException.create(ErrorCode.CANNOT_TRUNCATE_OR_DELETE_FILE, e, file.toString());
+            }
+        } else {
+            ioManager.close(handle);
         }
     }