commons-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ma...@apache.org
Subject commons-fileupload git commit: Improve performance for large multi-part boundaries. Patch provided by Felix Schumacher.
Date Mon, 22 Aug 2016 14:53:34 GMT
Repository: commons-fileupload
Updated Branches:
  refs/heads/master cdf7689ec -> afdedc958


Improve performance for large multi-part boundaries.
Patch provided by Felix Schumacher.

Project: http://git-wip-us.apache.org/repos/asf/commons-fileupload/repo
Commit: http://git-wip-us.apache.org/repos/asf/commons-fileupload/commit/afdedc95
Tree: http://git-wip-us.apache.org/repos/asf/commons-fileupload/tree/afdedc95
Diff: http://git-wip-us.apache.org/repos/asf/commons-fileupload/diff/afdedc95

Branch: refs/heads/master
Commit: afdedc9580dde03287979607f9ce441b23b6bc90
Parents: cdf7689
Author: Mark Thomas <markt@apache.org>
Authored: Mon Aug 22 15:53:19 2016 +0100
Committer: Mark Thomas <markt@apache.org>
Committed: Mon Aug 22 15:53:19 2016 +0100

----------------------------------------------------------------------
 src/changes/changes.xml                         |  1 +
 .../commons/fileupload/MultipartStream.java     | 59 +++++++++++++++-----
 2 files changed, 46 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/commons-fileupload/blob/afdedc95/src/changes/changes.xml
----------------------------------------------------------------------
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 0c9241f..3e53518 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -58,6 +58,7 @@ The <action> type attribute can be add,update,fix,remove.
       <action issue="FILEUPLOAD-245" dev="sebb" type="fix">DiskFileItem.get() may not
fully read the data</action>
       <action issue="FILEUPLOAD-243" dev="sebb" type="update" due-to="Ville Skyttä">Make
some MultipartStream private fields final</action>
       <action                        dev="ecki" type="add">Site: added security report</action>
+      <action                        dev="markt" due-to="Felix Schumacher">Improve
performance for large multi-part boundaries</action>
     </release>
 
     <release version="1.3.2" description="Bugfix release for 1.3.1" date="2016-05-26">

http://git-wip-us.apache.org/repos/asf/commons-fileupload/blob/afdedc95/src/main/java/org/apache/commons/fileupload/MultipartStream.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/fileupload/MultipartStream.java b/src/main/java/org/apache/commons/fileupload/MultipartStream.java
index 0d05b71..851c6eb 100644
--- a/src/main/java/org/apache/commons/fileupload/MultipartStream.java
+++ b/src/main/java/org/apache/commons/fileupload/MultipartStream.java
@@ -230,6 +230,11 @@ public class MultipartStream {
     private final byte[] boundary;
 
     /**
+     * The table for Knuth-Morris-Pratt search algorithm
+     */
+    private int[] boundaryTable;
+
+    /**
      * The length of the buffer used for processing the request.
      */
     private final int bufSize;
@@ -339,12 +344,14 @@ public class MultipartStream {
         this.notifier = pNotifier;
 
         this.boundary = new byte[this.boundaryLength];
+        this.boundaryTable = new int[this.boundaryLength + 1];
         this.keepRegion = this.boundary.length;
 
         System.arraycopy(BOUNDARY_PREFIX, 0, this.boundary, 0,
                 BOUNDARY_PREFIX.length);
         System.arraycopy(boundary, 0, this.boundary, BOUNDARY_PREFIX.length,
                 boundary.length);
+        computeBoundaryTable();
 
         head = 0;
         tail = 0;
@@ -506,6 +513,31 @@ public class MultipartStream {
         }
         System.arraycopy(boundary, 0, this.boundary, BOUNDARY_PREFIX.length,
                 boundary.length);
+        computeBoundaryTable();
+    }
+
+    /**
+     * Compute the table used for Knuth-Morris-Pratt search algorithm.
+     */
+    private void computeBoundaryTable() {
+        int position = 2;
+        int candidate = 0;
+
+        boundaryTable[0] = -1;
+        boundaryTable[1] = 0;
+
+        while (position <= boundaryLength) {
+            if (boundary[position - 1] == boundary[candidate]) {
+                boundaryTable[position] = candidate + 1;
+                candidate++;
+                position++;
+            } else if (candidate > 0) {
+                candidate = boundaryTable[candidate];
+            } else {
+                boundaryTable[position] = 0;
+                position++;
+            }
+        }
     }
 
     /**
@@ -628,6 +660,7 @@ public class MultipartStream {
         // First delimiter may be not preceeded with a CRLF.
         System.arraycopy(boundary, 2, boundary, 0, boundary.length - 2);
         boundaryLength = boundary.length - 2;
+        computeBoundaryTable();
         try {
             // Discard all data up to the delimiter.
             discardBodyData();
@@ -643,6 +676,7 @@ public class MultipartStream {
             boundaryLength = boundary.length;
             boundary[0] = CR;
             boundary[1] = LF;
+            computeBoundaryTable();
         }
     }
 
@@ -698,23 +732,20 @@ public class MultipartStream {
      *         not found.
      */
     protected int findSeparator() {
-        int first;
-        int match = 0;
-        int maxpos = tail - boundaryLength;
-        for (first = head; first <= maxpos && match != boundaryLength; first++)
{
-            first = findByte(boundary[0], first);
-            if (first == -1 || first > maxpos) {
-                return -1;
+
+        int bufferPos = this.head;
+        int tablePos = 0;
+
+        while (bufferPos < this.tail) {
+            while (tablePos >= 0 && buffer[bufferPos] != boundary[tablePos]) {
+                tablePos = boundaryTable[tablePos];
             }
-            for (match = 1; match < boundaryLength; match++) {
-                if (buffer[first + match] != boundary[match]) {
-                    break;
-                }
+            bufferPos++;
+            tablePos++;
+            if (tablePos == boundaryLength) {
+                return bufferPos - boundaryLength;
             }
         }
-        if (match == boundaryLength) {
-            return first - 1;
-        }
         return -1;
     }
 


Mime
View raw message