Author: markt
Date: Fri Sep 21 22:27:26 2012
New Revision: 1388709

URL: http://svn.apache.org/viewvc?rev=1388709&view=rev
Log:
When the DefaultServlet is under high load, parsing the content-type header 
generates significant garbage and takes noticeable time. Add a simple cache to 
address these issues.

Added:
    tomcat/trunk/java/org/apache/tomcat/util/collections/ConcurrentCache.java
      - copied, changed from r1387957, 
tomcat/trunk/java/org/apache/el/util/ConcurrentCache.java
    tomcat/trunk/java/org/apache/tomcat/util/http/parser/MediaTypeCache.java   
(with props)
Modified:
    tomcat/trunk/java/org/apache/catalina/connector/Response.java

Modified: tomcat/trunk/java/org/apache/catalina/connector/Response.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/connector/Response.java?rev=1388709&r1=1388708&r2=1388709&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/connector/Response.java (original)
+++ tomcat/trunk/java/org/apache/catalina/connector/Response.java Fri Sep 21 
22:27:26 2012
@@ -18,7 +18,6 @@ package org.apache.catalina.connector;
 
 import java.io.IOException;
 import java.io.PrintWriter;
-import java.io.StringReader;
 import java.net.MalformedURLException;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
@@ -51,8 +50,7 @@ import org.apache.tomcat.util.buf.UEncod
 import org.apache.tomcat.util.http.FastHttpDateFormat;
 import org.apache.tomcat.util.http.MimeHeaders;
 import org.apache.tomcat.util.http.ServerCookie;
-import org.apache.tomcat.util.http.parser.AstMediaType;
-import org.apache.tomcat.util.http.parser.HttpParser;
+import org.apache.tomcat.util.http.parser.MediaTypeCache;
 import org.apache.tomcat.util.http.parser.ParseException;
 import org.apache.tomcat.util.net.URL;
 import org.apache.tomcat.util.res.StringManager;
@@ -71,6 +69,9 @@ public class Response
 
     // ----------------------------------------------------------- Constructors
 
+    private static final MediaTypeCache MEDIA_TYPE_CACHE =
+            new MediaTypeCache(100);
+
     /**
      * Compliance with SRV.15.2.22.1. A call to Response.getWriter() if no
      * character encoding has been specified will result in subsequent calls to
@@ -708,10 +709,9 @@ public class Response
             return;
         }
 
-        AstMediaType m = null;
-        HttpParser hp = new HttpParser(new StringReader(type));
+        String[] m = null;
         try {
-             m = hp.MediaType();
+             m = MEDIA_TYPE_CACHE.parse(type);
         } catch (ParseException e) {
             // Invalid - Assume no charset and just pass through whatever
             // the user provided.
@@ -719,13 +719,12 @@ public class Response
             return;
         }
 
-        coyoteResponse.setContentTypeNoCharset(m.toStringNoCharset());
+        coyoteResponse.setContentTypeNoCharset(m[0]);
 
-        String charset = m.getCharset();
-        if (charset != null) {
+        if (m[1] != null) {
             // Ignore charset if getWriter() has already been called
             if (!usingWriter) {
-                coyoteResponse.setCharacterEncoding(charset);
+                coyoteResponse.setCharacterEncoding(m[1]);
                 isCharacterEncodingSet = true;
             }
         }

Copied: 
tomcat/trunk/java/org/apache/tomcat/util/collections/ConcurrentCache.java (from 
r1387957, tomcat/trunk/java/org/apache/el/util/ConcurrentCache.java)
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/collections/ConcurrentCache.java?p2=tomcat/trunk/java/org/apache/tomcat/util/collections/ConcurrentCache.java&p1=tomcat/trunk/java/org/apache/el/util/ConcurrentCache.java&r1=1387957&r2=1388709&rev=1388709&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/el/util/ConcurrentCache.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/collections/ConcurrentCache.java 
Fri Sep 21 22:27:26 2012
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.el.util;
+package org.apache.tomcat.util.collections;
 
 import java.util.Map;
 import java.util.WeakHashMap;

Added: tomcat/trunk/java/org/apache/tomcat/util/http/parser/MediaTypeCache.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/http/parser/MediaTypeCache.java?rev=1388709&view=auto
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/http/parser/MediaTypeCache.java 
(added)
+++ tomcat/trunk/java/org/apache/tomcat/util/http/parser/MediaTypeCache.java 
Fri Sep 21 22:27:26 2012
@@ -0,0 +1,61 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.tomcat.util.http.parser;
+
+import java.io.StringReader;
+
+import org.apache.tomcat.util.collections.ConcurrentCache;
+
+/**
+ * Caches the results of parsing content-type headers.
+ */
+public class MediaTypeCache {
+
+    private final ConcurrentCache<String,String[]> cache;
+
+    public MediaTypeCache(int size) {
+        cache = new ConcurrentCache<>(size);
+    }
+
+    /**
+     * Looks in the cache and returns the cached value if one is present. If no
+     * match exists in the cache, a new parser is created, the input parsed and
+     * the results placed in the cache and returned to the user.
+     *
+     * @param input The content-type header value to parse
+     * @return      The results are provided as a two element String array. The
+     *                  first element is the media type less the charset and
+     *                  the second element is the charset
+     *
+     * @throws ParseException if the input cannot be parsed
+     */
+    public String[] parse(String input) throws ParseException {
+        String[] result = cache.get(input);
+
+        if (result != null) {
+            return result;
+        }
+
+        HttpParser hp = new HttpParser(new StringReader(input));
+        AstMediaType m = hp.MediaType();
+
+        result = new String[] {m.toStringNoCharset(), m.getCharset()};
+        cache.put(input, result);
+
+        return result;
+    }
+}

Propchange: 
tomcat/trunk/java/org/apache/tomcat/util/http/parser/MediaTypeCache.java
------------------------------------------------------------------------------
    svn:eol-style = native



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to