You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2009/03/04 11:57:46 UTC

svn commit: r749962 - in /camel/branches/camel-1.x: ./ camel-core/src/main/java/org/apache/camel/impl/ camel-core/src/main/java/org/apache/camel/impl/converter/ camel-core/src/main/java/org/apache/camel/model/language/ camel-core/src/test/java/org/apac...

Author: davsclaus
Date: Wed Mar  4 10:57:45 2009
New Revision: 749962

URL: http://svn.apache.org/viewvc?rev=749962&view=rev
Log:
Merged revisions 749956 via svnmerge from 
https://svn.apache.org/repos/asf/camel/trunk

........
  r749956 | davsclaus | 2009-03-04 11:18:08 +0100 (Wed, 04 Mar 2009) | 1 line
  
  CAMEL-1417: Fixed performance issue with StreamInterceptor causing too many convertions attempts that is bound to fail. Improved logic in MessageSupport to also avoid type convertions if not possible. In the rude performance test we get a 2x gain on my laptop. And the Camel715 can now again be run with 50000 loops in about 5 sec, giving a 10x gain.
........

Added:
    camel/branches/camel-1.x/camel-core/src/test/java/org/apache/camel/processor/RoutePerformanceTest.java
      - copied unchanged from r749956, camel/trunk/camel-core/src/test/java/org/apache/camel/processor/RoutePerformanceTest.java
Modified:
    camel/branches/camel-1.x/   (props changed)
    camel/branches/camel-1.x/camel-core/src/main/java/org/apache/camel/impl/MessageSupport.java
    camel/branches/camel-1.x/camel-core/src/main/java/org/apache/camel/impl/converter/DefaultTypeConverter.java
    camel/branches/camel-1.x/camel-core/src/main/java/org/apache/camel/model/language/ExpressionType.java

Propchange: camel/branches/camel-1.x/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Wed Mar  4 10:57:45 2009
@@ -1 +1 @@
-/camel/trunk:736980,739733,739904,740251,740295,740306,740596,740663,741848,742231,742705,742739,742854,742856,742898,742906,743613,743762,743773,743920,743959-743960,744123,745105,745367,745541,745751,745826,745978,746269,746872,746895,746962,747258,747678-747704,748392,748436,748821,749563-749564,749574,749628-749629
+/camel/trunk:736980,739733,739904,740251,740295,740306,740596,740663,741848,742231,742705,742739,742854,742856,742898,742906,743613,743762,743773,743920,743959-743960,744123,745105,745367,745541,745751,745826,745978,746269,746872,746895,746962,747258,747678-747704,748392,748436,748821,749563-749564,749574,749628-749629,749956

Propchange: camel/branches/camel-1.x/
------------------------------------------------------------------------------
Binary property 'svnmerge-integrated' - no diff available.

Modified: camel/branches/camel-1.x/camel-core/src/main/java/org/apache/camel/impl/MessageSupport.java
URL: http://svn.apache.org/viewvc/camel/branches/camel-1.x/camel-core/src/main/java/org/apache/camel/impl/MessageSupport.java?rev=749962&r1=749961&r2=749962&view=diff
==============================================================================
--- camel/branches/camel-1.x/camel-core/src/main/java/org/apache/camel/impl/MessageSupport.java (original)
+++ camel/branches/camel-1.x/camel-core/src/main/java/org/apache/camel/impl/MessageSupport.java Wed Mar  4 10:57:45 2009
@@ -21,6 +21,7 @@
 import org.apache.camel.Message;
 import org.apache.camel.NoTypeConversionAvailableException;
 import org.apache.camel.TypeConverter;
+import org.apache.camel.impl.converter.DefaultTypeConverter;
 import org.apache.camel.util.UuidGenerator;
 
 /**
@@ -56,16 +57,31 @@
         if (e != null) {
             CamelContext camelContext = e.getContext();
             if (camelContext != null) {
+                boolean tryConvert = true;
                 TypeConverter converter = camelContext.getTypeConverter();
-                try {
-                    // lets first try converting the message itself first
-                    // as for some types like InputStream v Reader its more efficient to do the transformation
-                    // from the Message itself as its got efficient implementations of them, before trying the
-                    // payload
-                    return converter.convertTo(type, e, body);
-                } catch (NoTypeConversionAvailableException ex) {
-                    // ignore
+                // if its the default type converter then use a performance shortcut to check if it can convert it
+                // this is faster than getting throwing and catching NoTypeConversionAvailableException
+                // the StreamCachingInterceptor will attempt to convert the payload to a StremCache for caching purpose
+                // so we get invoked on each node the exchange passes. So this is a little performance optimization
+                // to avoid the excessive exception handling
+                if (body != null && converter instanceof DefaultTypeConverter) {
+                    DefaultTypeConverter defaultTypeConverter = (DefaultTypeConverter) converter;
+                    // we can only check if there is no converter meaning we have tried to convert it beforehand
+                    // and then knows for sure there is no converter possible
+                    tryConvert = !defaultTypeConverter.hasNoConverterFor(type, body.getClass());
                 }
+                if (tryConvert) {
+                    try {
+                        // lets first try converting the body itself first
+                        // as for some types like InputStream v Reader its more efficient to do the transformation
+                        // from the body itself as its got efficient implementations of them, before trying the
+                        // message
+                        return converter.convertTo(type, e, body);
+                    } catch (NoTypeConversionAvailableException ex) {
+                        // ignore
+                    }
+                }
+                // fallback to the message itself
                 return converter.convertTo(type, this);
             }
         }

Modified: camel/branches/camel-1.x/camel-core/src/main/java/org/apache/camel/impl/converter/DefaultTypeConverter.java
URL: http://svn.apache.org/viewvc/camel/branches/camel-1.x/camel-core/src/main/java/org/apache/camel/impl/converter/DefaultTypeConverter.java?rev=749962&r1=749961&r2=749962&view=diff
==============================================================================
--- camel/branches/camel-1.x/camel-core/src/main/java/org/apache/camel/impl/converter/DefaultTypeConverter.java (original)
+++ camel/branches/camel-1.x/camel-core/src/main/java/org/apache/camel/impl/converter/DefaultTypeConverter.java Wed Mar  4 10:57:45 2009
@@ -46,6 +46,7 @@
 public class DefaultTypeConverter implements TypeConverter, TypeConverterRegistry {
     private static final transient Log LOG = LogFactory.getLog(DefaultTypeConverter.class);
     private final Map<TypeMapping, TypeConverter> typeMappings = new ConcurrentHashMap<TypeMapping, TypeConverter>();
+    private final Map<TypeMapping, TypeMapping> misses = new ConcurrentHashMap<TypeMapping, TypeMapping>();
     private Injector injector;
     private List<TypeConverterLoader> typeConverterLoaders = new ArrayList<TypeConverterLoader>();
     private List<TypeConverter> fallbackConverters = new ArrayList<TypeConverter>();
@@ -65,12 +66,32 @@
         return typeConverterLoaders;
     }    
     
+    /**
+     * Is there <b>NOT</b> a type converter registered being able to converter the
+     * given value to the type
+     * @param toType  the type to convert to
+     * @param fromType  the type to convert from
+     * @return <tt>true</tt> if there is <b>NOT</b> a converter, <tt>false</tt> if there is
+     */
+    @SuppressWarnings("unchecked")
+    public boolean hasNoConverterFor(Class toType, Class fromType) {
+        TypeMapping key = new TypeMapping(toType, fromType);
+        // we must only look in misses and not do the acutal convertions
+        // as for stream it can be impossible to re-read them and this
+        // method should not cause any overhead
+        return misses.containsKey(key);
+    }
+
     public <T> T convertTo(Class<T> type, Object value) {
         return convertTo(type, null, value);
     }
 
-    @SuppressWarnings("unchecked")
     public <T> T convertTo(Class<T> type, Exchange exchange, Object value) {
+        return doConvertTo(type, exchange, value);
+    }
+
+    @SuppressWarnings("unchecked")
+    public <T> T doConvertTo(Class<T> type, Exchange exchange, Object value) {
         if (LOG.isTraceEnabled()) {
             LOG.trace("Converting " + (value == null ? "null" : value.getClass().getCanonicalName())
                 + " -> " + type.getCanonicalName() + " with value: " + value);
@@ -117,6 +138,11 @@
             }
         }
 
+        synchronized (misses) {
+            TypeMapping key = new TypeMapping(type, value.getClass());
+            misses.put(key, key);
+        }
+
         // Could not find suitable conversion
         throw new NoTypeConversionAvailableException(value, type);
     }

Modified: camel/branches/camel-1.x/camel-core/src/main/java/org/apache/camel/model/language/ExpressionType.java
URL: http://svn.apache.org/viewvc/camel/branches/camel-1.x/camel-core/src/main/java/org/apache/camel/model/language/ExpressionType.java?rev=749962&r1=749961&r2=749962&view=diff
==============================================================================
--- camel/branches/camel-1.x/camel-core/src/main/java/org/apache/camel/model/language/ExpressionType.java (original)
+++ camel/branches/camel-1.x/camel-core/src/main/java/org/apache/camel/model/language/ExpressionType.java Wed Mar  4 10:57:45 2009
@@ -34,6 +34,7 @@
 import org.apache.camel.Expression;
 import org.apache.camel.Predicate;
 import org.apache.camel.builder.ExpressionClause;
+import org.apache.camel.builder.PredicateBuilder;
 import org.apache.camel.impl.DefaultRouteContext;
 import org.apache.camel.spi.Language;
 import org.apache.camel.spi.RouteContext;
@@ -139,7 +140,10 @@
         if (predicate == null) {
             if (expressionType != null) {
                 predicate = expressionType.createPredicate(routeContext);
-            } else {
+            } else if (expressionValue != null) {
+                predicate = PredicateBuilder.toPredicate(expressionValue);
+            } else if (getExpression() != null) {
+                ObjectHelper.notNull("language", getLanguage());
                 CamelContext camelContext = routeContext.getCamelContext();
                 Language language = camelContext.resolveLanguage(getLanguage());
                 predicate = language.createPredicate(getExpression());
@@ -153,7 +157,8 @@
         if (expressionValue == null) {
             if (expressionType != null) {
                 expressionValue = expressionType.createExpression(routeContext);
-            } else {
+            } else if (getExpression() != null) {
+                ObjectHelper.notNull("language", getLanguage());
                 CamelContext camelContext = routeContext.getCamelContext();
                 Language language = camelContext.resolveLanguage(getLanguage());
                 expressionValue = language.createExpression(getExpression());