[NO ISSUE][OTH] Avoid Allocating Buffers on Chunked OutputStream

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

Details:

- Avoid allocating additional buffers when reporting
  errors to ChunkedResponse.

Change-Id: I36cbbb157b2e4013582e7161852b1a32286e709a
Reviewed-on: https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/8723
Integration-Tests: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Reviewed-by: Ali Alsuliman <ali.al.solaiman@gmail.com>
diff --git a/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/ChunkedNettyOutputStream.java b/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/ChunkedNettyOutputStream.java
index 36da9ab..9a940b1 100644
--- a/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/ChunkedNettyOutputStream.java
+++ b/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/ChunkedNettyOutputStream.java
@@ -112,9 +112,7 @@
                 buffer = null;
                 buffer = ctx.alloc().buffer(size);
             } else {
-                ByteBuf aBuffer = ctx.alloc().buffer(buffer.readableBytes());
-                aBuffer.writeBytes(buffer);
-                response.error(aBuffer);
+                response.error(buffer);
                 buffer.clear();
             }
         }
diff --git a/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/ChunkedResponse.java b/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/ChunkedResponse.java
index 40cbd9b..e00c519 100644
--- a/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/ChunkedResponse.java
+++ b/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/ChunkedResponse.java
@@ -71,7 +71,7 @@
     private PrintWriter writer;
     private DefaultHttpResponse response;
     private boolean headerSent;
-    private ByteBuf error;
+    private ByteBuf errorBuf;
     private ChannelFuture future;
     private boolean done;
 
@@ -119,7 +119,7 @@
         } else {
             outputStream.close();
         }
-        if (error == null && response.status() == HttpResponseStatus.OK) {
+        if (errorBuf == null && response.status() == HttpResponseStatus.OK) {
             if (!done) {
                 respond(LastHttpContent.EMPTY_LAST_CONTENT);
             }
@@ -127,14 +127,14 @@
             // There was an error
             if (headerSent) {
                 LOGGER.log(Level.WARN, "Error after header write of chunked response");
-                if (error != null) {
-                    error.release();
+                if (errorBuf != null) {
+                    errorBuf.release();
                 }
                 future = ctx.channel().close().addListener(handler);
             } else {
                 // we didn't send anything to the user, we need to send an non-chunked error response
                 fullResponse(response.protocolVersion(), response.status(),
-                        error == null ? ctx.alloc().buffer(0, 0) : error, response.headers());
+                        errorBuf == null ? ctx.alloc().buffer(0, 0) : errorBuf, response.headers());
             }
         }
         done = true;
@@ -152,12 +152,13 @@
     }
 
     public void error(ByteBuf error) {
-        if (this.error == null) {
-            this.error = error;
-        } else {
-            this.error.capacity(this.error.capacity() + error.capacity());
-            this.error.writeBytes(error);
+        if (errorBuf == null) {
+            errorBuf = ctx.alloc().buffer(error.readableBytes());
         }
+        if (errorBuf.capacity() < this.errorBuf.capacity() + error.capacity()) {
+            errorBuf.capacity(this.errorBuf.capacity() + error.capacity());
+        }
+        errorBuf.writeBytes(error);
     }
 
     @Override