You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by as...@apache.org on 2016/01/08 22:33:44 UTC

cxf git commit: [CXF-6739] Refactor to reduce memory pressure in org.apache.cxf.attachment.AttachmentDeserializer: * reset and reuse the same StringBuilder for fetching each line from the message input stream, instead of allocating a new one (using 128

Repository: cxf
Updated Branches:
  refs/heads/master 8be09c80a -> 0222768ba


[CXF-6739] Refactor to reduce memory pressure in org.apache.cxf.attachment.AttachmentDeserializer:
 * reset and reuse the same StringBuilder for fetching each line from the message input stream, instead of allocating a new one (using 128 bytes) every time
 * avoid the ArrayList<String> intermediate model and directly convert the StringBuilder into entries for the resulting TreeMap object
 * remove part of the special treatment of lines strating with spaces, as with the existing code there's no way such a line could be added to the headerLines list while the buffer is empty unless it's the first line from the stream (which means the headerLines will be empty and hence there's no need to worry about appending it to the previous one).


Project: http://git-wip-us.apache.org/repos/asf/cxf/repo
Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/0222768b
Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/0222768b
Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/0222768b

Branch: refs/heads/master
Commit: 0222768baf6b60742c4a8332308edf2be0f4a2e4
Parents: 8be09c8
Author: Alessio Soldano <as...@redhat.com>
Authored: Fri Jan 8 13:31:40 2016 +0100
Committer: Alessio Soldano <as...@redhat.com>
Committed: Fri Jan 8 22:32:06 2016 +0100

----------------------------------------------------------------------
 .../cxf/attachment/AttachmentDeserializer.java  | 109 +++++++------------
 1 file changed, 42 insertions(+), 67 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cxf/blob/0222768b/core/src/main/java/org/apache/cxf/attachment/AttachmentDeserializer.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/cxf/attachment/AttachmentDeserializer.java b/core/src/main/java/org/apache/cxf/attachment/AttachmentDeserializer.java
index 8d54660..e8dd326 100644
--- a/core/src/main/java/org/apache/cxf/attachment/AttachmentDeserializer.java
+++ b/core/src/main/java/org/apache/cxf/attachment/AttachmentDeserializer.java
@@ -312,73 +312,41 @@ public class AttachmentDeserializer {
     
 
     private Map<String, List<String>> loadPartHeaders(InputStream in) throws IOException {
-        List<String> headerLines = new ArrayList<String>(10);
         StringBuilder buffer = new StringBuilder(128);
-        String line;
+        StringBuilder b = new StringBuilder(128);
+        Map<String, List<String>> heads = new TreeMap<String, List<String>>(String.CASE_INSENSITIVE_ORDER);
         // loop until we hit the end or a null line
-        while ((line = readLine(in)) != null) {
+        while (readLine(in, b)) {
             // lines beginning with white space get special handling
-            if (line.startsWith(" ") || line.startsWith("\t")) {
-                // this gets handled using the logic defined by
-                // the addHeaderLine method.  If this line is a continuation, but
-                // there's nothing before it, just call addHeaderLine to add it
-                // to the last header in the headers list
-                if (buffer.length() == 0) {
-                    addHeaderLine(headerLines, line);
-                } else {
+            char c = b.charAt(0);
+            if (c == ' ' || c == '\t') {
+                if (buffer.length() != 0) {
                     // preserve the line break and append the continuation
                     buffer.append("\r\n");
-                    buffer.append(line);
+                    buffer.append(b);
                 }
             } else {
                 // if we have a line pending in the buffer, flush it
                 if (buffer.length() > 0) {
-                    addHeaderLine(headerLines, buffer.toString());
+                    addHeaderLine(heads, buffer);
                     buffer.setLength(0);
                 }
                 // add this to the accumulator
-                buffer.append(line);
+                buffer.append(b);
             }
         }
 
         // if we have a line pending in the buffer, flush it
         if (buffer.length() > 0) {
-            addHeaderLine(headerLines, buffer.toString());
-        }
-        Map<String, List<String>> heads = new TreeMap<String, List<String>>(String.CASE_INSENSITIVE_ORDER);
-        for (String h: headerLines) {
-            int separator = h.indexOf(':');
-            String name = null;
-            String value = "";
-            if (separator == -1) {
-                name = h.trim();
-            } else {
-                name = h.substring(0, separator);
-                // step past the separator.  Now we need to remove any leading white space characters.
-                separator++;
-
-                while (separator < h.length()) {
-                    char ch = h.charAt(separator);
-                    if (ch != ' ' && ch != '\t' && ch != '\r' && ch != '\n') {
-                        break;
-                    }
-                    separator++;
-                }
-                value = h.substring(separator);
-            }
-            List<String> v = heads.get(name);
-            if (v == null) {
-                v = new ArrayList<String>(1);
-                heads.put(name, v);
-            }
-            v.add(value);
+            addHeaderLine(heads, buffer);
         }
         return heads;
     }
 
-    private String readLine(InputStream in) throws IOException {
-        StringBuilder buffer = new StringBuilder(128);
-
+    private boolean readLine(InputStream in, StringBuilder buffer) throws IOException {
+        if (buffer.length() != 0) {
+            buffer.setLength(0);
+        }
         int c;
 
         while ((c = in.read()) != -1) {
@@ -396,33 +364,40 @@ public class AttachmentDeserializer {
         }
 
         // no characters found...this was either an eof or a null line.
-        if (buffer.length() == 0) {
-            return null;
-        }
+        return buffer.length() != 0;
+    }
 
-        return buffer.toString();
-    }    
-    private void addHeaderLine(List<String> headers, String line) {
+    private void addHeaderLine(Map<String, List<String>> heads, StringBuilder line) {
         // null lines are a nop
-        if (line.length() == 0) {
+        final int size = line.length();
+        if (size == 0) {
             return;
         }
-
-        // we need to test the first character to see if this is a continuation whitespace
-        char ch = line.charAt(0);
-
-        // tabs and spaces are special.  This is a continuation of the last header in the list.
-        if (ch == ' ' || ch == '\t') {
-            int size = headers.size();
-            // it's possible that we have a leading blank line.
-            if (size > 0) {
-                line = headers.remove(size - 1) + line;
-                headers.add(line);
-            }
+        int separator = line.indexOf(":");
+        String name = null;
+        String value = "";
+        if (separator == -1) {
+            name = line.toString().trim();
         } else {
-            // this just gets appended to the end, preserving the addition order.
-            headers.add(line);
+            name = line.substring(0, separator);
+            // step past the separator.  Now we need to remove any leading white space characters.
+            separator++;
+
+            while (separator < size) {
+                char ch = line.charAt(separator);
+                if (ch != ' ' && ch != '\t' && ch != '\r' && ch != '\n') {
+                    break;
+                }
+                separator++;
+            }
+            value = line.substring(separator);
+        }
+        List<String> v = heads.get(name);
+        if (v == null) {
+            v = new ArrayList<String>(1);
+            heads.put(name, v);
         }
+        v.add(value);
     }
 
 }