Repository: camel
Updated Branches:
  refs/heads/osgi-trouble [created] ea4c8ce4e


CAMEL-8602: Java 8: ConcurrentLinkedHashMap -> Caffeine


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/9cfb0288
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/9cfb0288
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/9cfb0288

Branch: refs/heads/osgi-trouble
Commit: 9cfb0288ceb6a11ebda329b7f275a97d556822a5
Parents: fa78b86
Author: Claus Ibsen <davscl...@apache.org>
Authored: Wed Mar 23 15:27:36 2016 +0100
Committer: Claus Ibsen <davscl...@apache.org>
Committed: Wed Mar 23 15:27:36 2016 +0100

----------------------------------------------------------------------
 camel-core/pom.xml                              |  10 +-
 .../java/org/apache/camel/ConsumerTemplate.java |   5 +
 .../java/org/apache/camel/ProducerTemplate.java |   5 +
 .../org/apache/camel/impl/ConsumerCache.java    |  10 ++
 .../camel/impl/DefaultConsumerTemplate.java     |   8 ++
 .../camel/impl/DefaultProducerTemplate.java     |   6 +
 .../org/apache/camel/impl/ProducerCache.java    |  11 ++
 .../org/apache/camel/spi/EndpointRegistry.java  |   5 +
 .../java/org/apache/camel/util/LRUCache.java    |  63 +++++++---
 .../org/apache/camel/util/LRUSoftCache.java     | 117 +------------------
 .../org/apache/camel/util/LRUWeakCache.java     | 116 +-----------------
 ...faultCamelContextEndpointCacheLimitTest.java |  10 +-
 .../DefaultCamelContextEndpointCacheTest.java   |   8 +-
 .../camel/impl/DefaultCamelContextTest.java     |   8 +-
 .../camel/impl/DefaultConsumerCacheTest.java    |   3 +
 .../camel/impl/DefaultConsumerTemplateTest.java |   6 +
 ...sumerTemplateWithCustomCacheMaxSizeTest.java |   3 +
 .../camel/impl/DefaultProducerCacheTest.java    |   9 ++
 .../camel/impl/DefaultProducerTemplateTest.java |   6 +
 .../EndpointRegistryKeepRouteEndpointsTest.java |   6 +-
 .../org/apache/camel/util/LRUCacheTest.java     |  14 ++-
 parent/pom.xml                                  |  10 +-
 22 files changed, 172 insertions(+), 267 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/9cfb0288/camel-core/pom.xml
----------------------------------------------------------------------
diff --git a/camel-core/pom.xml b/camel-core/pom.xml
index 51b7273..096f725 100644
--- a/camel-core/pom.xml
+++ b/camel-core/pom.xml
@@ -126,8 +126,8 @@
     <!-- required dependencies by camel-core -->
     <!-- which we shade into camel-core so its available for everybody out of 
the box -->
     <dependency>
-      <groupId>com.googlecode.concurrentlinkedhashmap</groupId>
-      <artifactId>concurrentlinkedhashmap-lru</artifactId>
+      <groupId>com.github.ben-manes.caffeine</groupId>
+      <artifactId>caffeine</artifactId>
     </dependency>
 
     <!-- required dependencies by camel-core -->
@@ -227,7 +227,7 @@
             <configuration>
               <artifactSet>
                 <includes>
-                  
<include>com.googlecode.concurrentlinkedhashmap:concurrentlinkedhashmap-lru</include>
+                  <include>com.github.ben-manes.caffeine:caffeine</include>
                 </includes>
                 <excludes>
                   <exclude>org.apache.camel:apt</exclude>
@@ -235,8 +235,8 @@
               </artifactSet>
               <relocations>
                 <relocation>
-                  <pattern>com.googlecode.concurrentlinkedhashmap</pattern>
-                  
<shadedPattern>org.apache.camel.com.googlecode.concurrentlinkedhashmap</shadedPattern>
+                  <pattern>com.github.benmanes.caffeine.cache</pattern>
+                  
<shadedPattern>org.apache.camel.com.github.benmanes.caffeine.cache</shadedPattern>
                 </relocation>
               </relocations>
             </configuration>

http://git-wip-us.apache.org/repos/asf/camel/blob/9cfb0288/camel-core/src/main/java/org/apache/camel/ConsumerTemplate.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/ConsumerTemplate.java 
b/camel-core/src/main/java/org/apache/camel/ConsumerTemplate.java
index ea7e249..b6b2583 100644
--- a/camel-core/src/main/java/org/apache/camel/ConsumerTemplate.java
+++ b/camel-core/src/main/java/org/apache/camel/ConsumerTemplate.java
@@ -81,6 +81,11 @@ public interface ConsumerTemplate extends Service {
      */
     int getCurrentCacheSize();
 
+    /**
+     * Cleanup the cache (purging stale entries)
+     */
+    void cleanUp();
+
     // Synchronous methods
     // -----------------------------------------------------------------------
 

http://git-wip-us.apache.org/repos/asf/camel/blob/9cfb0288/camel-core/src/main/java/org/apache/camel/ProducerTemplate.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/ProducerTemplate.java 
b/camel-core/src/main/java/org/apache/camel/ProducerTemplate.java
index 32533c1..2404d85 100644
--- a/camel-core/src/main/java/org/apache/camel/ProducerTemplate.java
+++ b/camel-core/src/main/java/org/apache/camel/ProducerTemplate.java
@@ -132,6 +132,11 @@ public interface ProducerTemplate extends Service {
      */
     boolean isEventNotifierEnabled();
 
+    /**
+     * Cleanup the cache (purging stale entries)
+     */
+    void cleanUp();
+
     // Synchronous methods
     // -----------------------------------------------------------------------
 

http://git-wip-us.apache.org/repos/asf/camel/blob/9cfb0288/camel-core/src/main/java/org/apache/camel/impl/ConsumerCache.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/impl/ConsumerCache.java 
b/camel-core/src/main/java/org/apache/camel/impl/ConsumerCache.java
index 399012c..2e6fdda 100644
--- a/camel-core/src/main/java/org/apache/camel/impl/ConsumerCache.java
+++ b/camel-core/src/main/java/org/apache/camel/impl/ConsumerCache.java
@@ -344,6 +344,16 @@ public class ConsumerCache extends ServiceSupport {
         }
     }
 
+    /**
+     * Cleanup the cache (purging stale entries)
+     */
+    public void cleanUp() {
+        if (consumers instanceof LRUCache) {
+            LRUCache<String, PollingConsumer> cache = (LRUCache<String, 
PollingConsumer>)consumers;
+            cache.cleanUp();
+        }
+    }
+
     public EndpointUtilizationStatistics getEndpointUtilizationStatistics() {
         return statistics;
     }

http://git-wip-us.apache.org/repos/asf/camel/blob/9cfb0288/camel-core/src/main/java/org/apache/camel/impl/DefaultConsumerTemplate.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/main/java/org/apache/camel/impl/DefaultConsumerTemplate.java 
b/camel-core/src/main/java/org/apache/camel/impl/DefaultConsumerTemplate.java
index 98c0394..2613919 100644
--- 
a/camel-core/src/main/java/org/apache/camel/impl/DefaultConsumerTemplate.java
+++ 
b/camel-core/src/main/java/org/apache/camel/impl/DefaultConsumerTemplate.java
@@ -22,9 +22,11 @@ import org.apache.camel.CamelContext;
 import org.apache.camel.ConsumerTemplate;
 import org.apache.camel.Endpoint;
 import org.apache.camel.Exchange;
+import org.apache.camel.PollingConsumer;
 import org.apache.camel.spi.Synchronization;
 import org.apache.camel.support.ServiceSupport;
 import org.apache.camel.util.CamelContextHelper;
+import org.apache.camel.util.LRUCache;
 import org.apache.camel.util.ServiceHelper;
 import org.apache.camel.util.UnitOfWorkHelper;
 import org.slf4j.Logger;
@@ -65,6 +67,12 @@ public class DefaultConsumerTemplate extends ServiceSupport 
implements ConsumerT
         return consumerCache.size();
     }
 
+    public void cleanUp() {
+        if (consumerCache != null) {
+            consumerCache.cleanUp();
+        }
+    }
+
     /**
      * @deprecated use {@link #getCamelContext()}
      */

http://git-wip-us.apache.org/repos/asf/camel/blob/9cfb0288/camel-core/src/main/java/org/apache/camel/impl/DefaultProducerTemplate.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/main/java/org/apache/camel/impl/DefaultProducerTemplate.java 
b/camel-core/src/main/java/org/apache/camel/impl/DefaultProducerTemplate.java
index aa3fa10..aee4973 100644
--- 
a/camel-core/src/main/java/org/apache/camel/impl/DefaultProducerTemplate.java
+++ 
b/camel-core/src/main/java/org/apache/camel/impl/DefaultProducerTemplate.java
@@ -92,6 +92,12 @@ public class DefaultProducerTemplate extends ServiceSupport 
implements ProducerT
         return eventNotifierEnabled;
     }
 
+    public void cleanUp() {
+        if (producerCache != null) {
+            producerCache.cleanUp();
+        }
+    }
+
     public void setEventNotifierEnabled(boolean eventNotifierEnabled) {
         this.eventNotifierEnabled = eventNotifierEnabled;
         // if we already created the cache then adjust its setting as well

http://git-wip-us.apache.org/repos/asf/camel/blob/9cfb0288/camel-core/src/main/java/org/apache/camel/impl/ProducerCache.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/impl/ProducerCache.java 
b/camel-core/src/main/java/org/apache/camel/impl/ProducerCache.java
index 9be2825..c016ea4 100644
--- a/camel-core/src/main/java/org/apache/camel/impl/ProducerCache.java
+++ b/camel-core/src/main/java/org/apache/camel/impl/ProducerCache.java
@@ -26,6 +26,7 @@ import org.apache.camel.Endpoint;
 import org.apache.camel.Exchange;
 import org.apache.camel.ExchangePattern;
 import org.apache.camel.FailedToCreateProducerException;
+import org.apache.camel.PollingConsumer;
 import org.apache.camel.Processor;
 import org.apache.camel.Producer;
 import org.apache.camel.ProducerCallback;
@@ -595,6 +596,16 @@ public class ProducerCache extends ServiceSupport {
         }
     }
 
+    /**
+     * Cleanup the cache (purging stale entries)
+     */
+    public void cleanUp() {
+        if (producers instanceof LRUCache) {
+            LRUCache<String, Producer> cache = (LRUCache<String, 
Producer>)producers;
+            cache.cleanUp();
+        }
+    }
+
     public EndpointUtilizationStatistics getEndpointUtilizationStatistics() {
         return statistics;
     }

http://git-wip-us.apache.org/repos/asf/camel/blob/9cfb0288/camel-core/src/main/java/org/apache/camel/spi/EndpointRegistry.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/main/java/org/apache/camel/spi/EndpointRegistry.java 
b/camel-core/src/main/java/org/apache/camel/spi/EndpointRegistry.java
index 3a42dfa..af1b8e7 100644
--- a/camel-core/src/main/java/org/apache/camel/spi/EndpointRegistry.java
+++ b/camel-core/src/main/java/org/apache/camel/spi/EndpointRegistry.java
@@ -75,4 +75,9 @@ public interface EndpointRegistry<K> extends Map<K, 
Endpoint>, StaticService {
      */
     boolean isDynamic(String key);
 
+    /**
+     * Cleanup the cache (purging stale entries)
+     */
+    void cleanUp();
+
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/9cfb0288/camel-core/src/main/java/org/apache/camel/util/LRUCache.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/util/LRUCache.java 
b/camel-core/src/main/java/org/apache/camel/util/LRUCache.java
index 07d36e1..4c18a31 100644
--- a/camel-core/src/main/java/org/apache/camel/util/LRUCache.java
+++ b/camel-core/src/main/java/org/apache/camel/util/LRUCache.java
@@ -22,8 +22,10 @@ import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicLong;
 
-import com.googlecode.concurrentlinkedhashmap.ConcurrentLinkedHashMap;
-import com.googlecode.concurrentlinkedhashmap.EvictionListener;
+import com.github.benmanes.caffeine.cache.Cache;
+import com.github.benmanes.caffeine.cache.Caffeine;
+import com.github.benmanes.caffeine.cache.RemovalCause;
+import com.github.benmanes.caffeine.cache.RemovalListener;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -36,7 +38,7 @@ import org.slf4j.LoggerFactory;
  * @see LRUSoftCache
  * @see LRUWeakCache
  */
-public class LRUCache<K, V> implements Map<K, V>, EvictionListener<K, V>, 
Serializable {
+public class LRUCache<K, V> implements Map<K, V>, RemovalListener<K, V>, 
Serializable {
     private static final long serialVersionUID = -342098639681884414L;
     private static final Logger LOG = LoggerFactory.getLogger(LRUCache.class);
 
@@ -46,7 +48,8 @@ public class LRUCache<K, V> implements Map<K, V>, 
EvictionListener<K, V>, Serial
 
     private int maxCacheSize = 10000;
     private boolean stopOnEviction;
-    private ConcurrentLinkedHashMap<K, V> map;
+    private final Cache<K, V> cache;
+    private final Map<K, V> map;
 
     /**
      * Constructs an empty <tt>LRUCache</tt> instance with the
@@ -81,10 +84,40 @@ public class LRUCache<K, V> implements Map<K, V>, 
EvictionListener<K, V>, Serial
      * @throws IllegalArgumentException if the initial capacity is negative
      */
     public LRUCache(int initialCapacity, int maximumCacheSize, boolean 
stopOnEviction) {
-        map = new ConcurrentLinkedHashMap.Builder<K, V>()
+        this(initialCapacity, maximumCacheSize, stopOnEviction, false, false, 
false);
+    }
+
+    /**
+     * Constructs an empty <tt>LRUCache</tt> instance with the
+     * specified initial capacity, maximumCacheSize,load factor and ordering 
mode.
+     *
+     * @param initialCapacity  the initial capacity.
+     * @param maximumCacheSize the max capacity.
+     * @param stopOnEviction   whether to stop service on eviction.
+     * @param soft             whether to use soft values a soft cache  
(default is false)
+     * @param weak             whether to use weak keys/values as a weak cache 
 (default is false)
+     * @param syncListener     whether to use synchronous call for the 
eviction listener (default is false)
+     * @throws IllegalArgumentException if the initial capacity is negative
+     */
+    public LRUCache(int initialCapacity, int maximumCacheSize, boolean 
stopOnEviction,
+                    boolean soft, boolean weak, boolean syncListener) {
+        Caffeine<K, V> caffeine = Caffeine.newBuilder()
                 .initialCapacity(initialCapacity)
-                .maximumWeightedCapacity(maximumCacheSize)
-                .listener(this).build();
+                .maximumSize(maximumCacheSize)
+                .removalListener(this);
+        if (soft) {
+            caffeine.softValues();
+        }
+        if (weak) {
+            caffeine.weakKeys();
+            caffeine.weakValues();
+        }
+        if (syncListener) {
+            caffeine.executor(Runnable::run);
+        }
+
+        this.cache = caffeine.build();
+        this.map = cache.asMap();
         this.maxCacheSize = maximumCacheSize;
         this.stopOnEviction = stopOnEviction;
     }
@@ -131,7 +164,7 @@ public class LRUCache<K, V> implements Map<K, V>, 
EvictionListener<K, V>, Serial
     }
 
     public void putAll(Map<? extends K, ? extends V> map) {
-        this.map.putAll(map);
+        this.cache.putAll(map);
     }
 
     @Override
@@ -142,23 +175,23 @@ public class LRUCache<K, V> implements Map<K, V>, 
EvictionListener<K, V>, Serial
 
     @Override
     public Set<K> keySet() {
-        return map.ascendingKeySet();
+        return map.keySet();
     }
 
     @Override
     public Collection<V> values() {
-        return map.ascendingMap().values();
+        return map.values();
     }
 
     @Override
     public Set<Entry<K, V>> entrySet() {
-        return map.ascendingMap().entrySet();
+        return map.entrySet();
     }
 
     @Override
-    public void onEviction(K key, V value) {
+    public void onRemoval(K key, V value, RemovalCause cause) {
         evicted.incrementAndGet();
-        LOG.trace("onEviction {} -> {}", key, value);
+        LOG.trace("onRemoval {} -> {}", key, value);
         if (stopOnEviction) {
             try {
                 // stop service as its evicted from cache
@@ -206,6 +239,10 @@ public class LRUCache<K, V> implements Map<K, V>, 
EvictionListener<K, V>, Serial
         evicted.set(0);
     }
 
+    public void cleanUp() {
+        cache.cleanUp();
+    }
+
     @Override
     public String toString() {
         return "LRUCache@" + ObjectHelper.getIdentityHashCode(this);

http://git-wip-us.apache.org/repos/asf/camel/blob/9cfb0288/camel-core/src/main/java/org/apache/camel/util/LRUSoftCache.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/util/LRUSoftCache.java 
b/camel-core/src/main/java/org/apache/camel/util/LRUSoftCache.java
index 074d291..6189026 100644
--- a/camel-core/src/main/java/org/apache/camel/util/LRUSoftCache.java
+++ b/camel-core/src/main/java/org/apache/camel/util/LRUSoftCache.java
@@ -17,11 +17,6 @@
 package org.apache.camel.util;
 
 import java.lang.ref.SoftReference;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.LinkedHashSet;
-import java.util.Map;
-import java.util.Set;
 
 /**
  * A Least Recently Used Cache which uses {@link SoftReference}.
@@ -54,123 +49,19 @@ import java.util.Set;
  * @see LRUWeakCache
  */
 public class LRUSoftCache<K, V> extends LRUCache<K, V> {
+
     private static final long serialVersionUID = 1L;
 
     public LRUSoftCache(int maximumCacheSize) {
-        super(maximumCacheSize);
+        this(16, maximumCacheSize);
     }
 
     public LRUSoftCache(int initialCapacity, int maximumCacheSize) {
-        super(initialCapacity, maximumCacheSize);
+        this(initialCapacity, maximumCacheSize, false);
     }
 
     public LRUSoftCache(int initialCapacity, int maximumCacheSize, boolean 
stopOnEviction) {
-        super(initialCapacity, maximumCacheSize, stopOnEviction);
-    }
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public V put(K key, V value) {
-        SoftReference<V> put = new SoftReference<V>(value);
-        SoftReference<V> prev = (SoftReference<V>) super.put(key, (V) put);
-        return prev != null ? prev.get() : null;
-    }
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public V get(Object o) {
-        SoftReference<V> ref = (SoftReference<V>) super.get(o);
-        return ref != null ? ref.get() : null;
-    }
-
-    @Override
-    public void putAll(Map<? extends K, ? extends V> map) {
-        for (Map.Entry<? extends K, ? extends V> entry : map.entrySet()) {
-            put(entry.getKey(), entry.getValue());
-        }
-    }
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public V remove(Object o) {
-        SoftReference<V> ref = (SoftReference<V>) super.remove(o);
-        return ref != null ? ref.get() : null;
-    }
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public Collection<V> values() {
-        // return a copy of all the active values
-        Collection<SoftReference<V>> col = (Collection<SoftReference<V>>) 
super.values();
-        Collection<V> answer = new ArrayList<V>();
-        for (SoftReference<V> ref : col) {
-            V value = ref.get();
-            if (value != null) {
-                answer.add(value);
-            }
-        }
-        return answer;
-    }
-
-    @Override
-    public int size() {
-        // only count as a size if there is a value
-        int size = 0;
-        for (V value : super.values()) {
-            SoftReference<?> ref = (SoftReference<?>) value;
-            if (ref != null && ref.get() != null) {
-                size++;
-            }
-        }
-        return size;
-    }
-
-    @Override
-    public boolean isEmpty() {
-        return size() == 0;
-    }
-
-    @Override
-    public boolean containsKey(Object o) {
-        // must lookup if the key has a value, as we only regard a key to be 
contained
-        // if the value is still there (the JVM can remove the soft reference 
if it need memory)
-        return get(o) != null;
-    }
-
-    @Override
-    public Set<Map.Entry<K, V>> entrySet() {
-        Set<Map.Entry<K, V>> original = super.entrySet();
-
-        // must use a copy to avoid concurrent modifications and be able to 
get/set value using
-        // the soft reference so the returned set is without the soft 
reference, and thus is
-        // use able for the caller to use
-        Set<Map.Entry<K, V>> answer = new LinkedHashSet<Map.Entry<K, 
V>>(original.size());
-        for (final Map.Entry<K, V> entry : original) {
-            Map.Entry<K, V> view = new Map.Entry<K, V>() {
-                @Override
-                public K getKey() {
-                    return entry.getKey();
-                }
-
-                @Override
-                @SuppressWarnings("unchecked")
-                public V getValue() {
-                    SoftReference<V> ref = (SoftReference<V>) entry.getValue();
-                    return ref != null ? ref.get() : null;
-                }
-
-                @Override
-                @SuppressWarnings("unchecked")
-                public V setValue(V v) {
-                    V put = (V) new SoftReference<V>(v);
-                    SoftReference<V> prev = (SoftReference<V>) 
entry.setValue(put);
-                    return prev != null ? prev.get() : null;
-                }
-            };
-            answer.add(view);
-        }
-
-        return answer;
+        super(initialCapacity, maximumCacheSize, stopOnEviction, true, false, 
false);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/camel/blob/9cfb0288/camel-core/src/main/java/org/apache/camel/util/LRUWeakCache.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/util/LRUWeakCache.java 
b/camel-core/src/main/java/org/apache/camel/util/LRUWeakCache.java
index 1ea9020..16d48f6 100644
--- a/camel-core/src/main/java/org/apache/camel/util/LRUWeakCache.java
+++ b/camel-core/src/main/java/org/apache/camel/util/LRUWeakCache.java
@@ -16,13 +16,6 @@
  */
 package org.apache.camel.util;
 
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.LinkedHashSet;
-import java.util.Map;
-import java.util.Set;
-
 /**
  * A Least Recently Used Cache which uses {@link java.lang.ref.WeakReference}.
  * <p/>
@@ -57,116 +50,11 @@ public class LRUWeakCache<K, V> extends LRUCache<K, V> {
     private static final long serialVersionUID = 1L;
 
     public LRUWeakCache(int maximumCacheSize) {
-        super(maximumCacheSize);
+        this(16, maximumCacheSize);
     }
 
     public LRUWeakCache(int initialCapacity, int maximumCacheSize) {
-        super(initialCapacity, maximumCacheSize);
-    }
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public V put(K key, V value) {
-        WeakReference<V> put = new WeakReference<V>(value);
-        WeakReference<V> prev = (WeakReference<V>) super.put(key, (V) put);
-        return prev != null ? prev.get() : null;
-    }
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public V get(Object o) {
-        WeakReference<V> ref = (WeakReference<V>) super.get(o);
-        return ref != null ? ref.get() : null;
-    }
-
-    @Override
-    public void putAll(Map<? extends K, ? extends V> map) {
-        for (Entry<? extends K, ? extends V> entry : map.entrySet()) {
-            put(entry.getKey(), entry.getValue());
-        }
-    }
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public V remove(Object o) {
-        WeakReference<V> ref = (WeakReference<V>) super.remove(o);
-        return ref != null ? ref.get() : null;
-    }
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public Collection<V> values() {
-        // return a copy of all the active values
-        Collection<WeakReference<V>> col = (Collection<WeakReference<V>>) 
super.values();
-        Collection<V> answer = new ArrayList<V>();
-        for (WeakReference<V> ref : col) {
-            V value = ref.get();
-            if (value != null) {
-                answer.add(value);
-            }
-        }
-        return answer;
-    }
-
-    @Override
-    public int size() {
-        // only count as a size if there is a value
-        int size = 0;
-        for (V value : super.values()) {
-            WeakReference<?> ref = (WeakReference<?>) value;
-            if (ref != null && ref.get() != null) {
-                size++;
-            }
-        }
-        return size;
-    }
-
-    @Override
-    public boolean isEmpty() {
-        return size() == 0;
-    }
-
-    @Override
-    public boolean containsKey(Object o) {
-        // must lookup if the key has a value, as we only regard a key to be 
contained
-        // if the value is still there (the JVM can remove the soft reference 
if it need memory)
-        return get(o) != null;
-    }
-
-    @Override
-    public Set<Entry<K, V>> entrySet() {
-        Set<Entry<K, V>> original = super.entrySet();
-
-        // must use a copy to avoid concurrent modifications and be able to 
get/set value using
-        // the soft reference so the returned set is without the soft 
reference, and thus is
-        // use able for the caller to use
-        Set<Entry<K, V>> answer = new LinkedHashSet<Entry<K, 
V>>(original.size());
-        for (final Entry<K, V> entry : original) {
-            Entry<K, V> view = new Entry<K, V>() {
-                @Override
-                public K getKey() {
-                    return entry.getKey();
-                }
-
-                @Override
-                @SuppressWarnings("unchecked")
-                public V getValue() {
-                    WeakReference<V> ref = (WeakReference<V>) entry.getValue();
-                    return ref != null ? ref.get() : null;
-                }
-
-                @Override
-                @SuppressWarnings("unchecked")
-                public V setValue(V v) {
-                    V put = (V) new WeakReference<V>(v);
-                    WeakReference<V> prev = (WeakReference<V>) 
entry.setValue(put);
-                    return prev != null ? prev.get() : null;
-                }
-            };
-            answer.add(view);
-        }
-
-        return answer;
+        super(initialCapacity, maximumCacheSize, false, false, true, false);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/camel/blob/9cfb0288/camel-core/src/test/java/org/apache/camel/impl/DefaultCamelContextEndpointCacheLimitTest.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/test/java/org/apache/camel/impl/DefaultCamelContextEndpointCacheLimitTest.java
 
b/camel-core/src/test/java/org/apache/camel/impl/DefaultCamelContextEndpointCacheLimitTest.java
index 71d4d69..9f0045e 100644
--- 
a/camel-core/src/test/java/org/apache/camel/impl/DefaultCamelContextEndpointCacheLimitTest.java
+++ 
b/camel-core/src/test/java/org/apache/camel/impl/DefaultCamelContextEndpointCacheLimitTest.java
@@ -35,7 +35,7 @@ public class DefaultCamelContextEndpointCacheLimitTest 
extends ContextTestSuppor
 
     public void testCacheEndpoints() throws Exception {
         // test that we cache at most 75 endpoints in camel context to avoid 
it eating to much memory
-        for (int i = 0; i < 78; i++) {
+        for (int i = 0; i < 100; i++) {
             String uri = "my:endpoint?id=" + i;
             DefaultEndpoint e = new DefaultEndpoint() {
                 public Producer createProducer() throws Exception {
@@ -54,11 +54,11 @@ public class DefaultCamelContextEndpointCacheLimitTest 
extends ContextTestSuppor
             context.addEndpoint(uri, e);
         }
 
+        // the eviction is async so force cleanup
+        context.getEndpointRegistry().cleanUp();
+
         Collection<Endpoint> col = context.getEndpoints();
-        assertEquals("Size should be 75", 75, col.size());
-        List<Endpoint> list = new ArrayList<Endpoint>(col);
-        assertEquals("my:endpoint?id=3", list.get(0).getEndpointUri());
-        assertEquals("my:endpoint?id=77", list.get(74).getEndpointUri());
+        assertTrue("Size should be at most 75 was " + col.size(), col.size() 
<= 75);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/camel/blob/9cfb0288/camel-core/src/test/java/org/apache/camel/impl/DefaultCamelContextEndpointCacheTest.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/test/java/org/apache/camel/impl/DefaultCamelContextEndpointCacheTest.java
 
b/camel-core/src/test/java/org/apache/camel/impl/DefaultCamelContextEndpointCacheTest.java
index 7312d0e..9ad3cfd 100644
--- 
a/camel-core/src/test/java/org/apache/camel/impl/DefaultCamelContextEndpointCacheTest.java
+++ 
b/camel-core/src/test/java/org/apache/camel/impl/DefaultCamelContextEndpointCacheTest.java
@@ -33,7 +33,7 @@ public class DefaultCamelContextEndpointCacheTest extends 
ContextTestSupport {
 
     public void testCacheEndpoints() throws Exception {
         // test that we cache at most 1000 endpoints in camel context to avoid 
it eating to much memory
-        for (int i = 0; i < 1003; i++) {
+        for (int i = 0; i < 1234; i++) {
             String uri = "my:endpoint?id=" + i;
             DefaultEndpoint e = new DefaultEndpoint() {
                 public Producer createProducer() throws Exception {
@@ -52,11 +52,11 @@ public class DefaultCamelContextEndpointCacheTest extends 
ContextTestSupport {
             context.addEndpoint(uri, e);
         }
 
+        // the eviction is async so force cleanup
+        context.getEndpointRegistry().cleanUp();
+
         Collection<Endpoint> col = context.getEndpoints();
         assertEquals("Size should be 1000", 1000, col.size());
-        List<Endpoint> list = new ArrayList<Endpoint>(col);
-        assertEquals("my:endpoint?id=3", list.get(0).getEndpointUri());
-        assertEquals("my:endpoint?id=1002", list.get(999).getEndpointUri());
     }
 
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/9cfb0288/camel-core/src/test/java/org/apache/camel/impl/DefaultCamelContextTest.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/test/java/org/apache/camel/impl/DefaultCamelContextTest.java 
b/camel-core/src/test/java/org/apache/camel/impl/DefaultCamelContextTest.java
index 3403ae4..88ed8d5 100644
--- 
a/camel-core/src/test/java/org/apache/camel/impl/DefaultCamelContextTest.java
+++ 
b/camel-core/src/test/java/org/apache/camel/impl/DefaultCamelContextTest.java
@@ -118,8 +118,12 @@ public class DefaultCamelContextTest extends TestSupport {
         assertEquals(2, list.size());
 
         Iterator<Endpoint> it = list.iterator();
-        assertEquals("log://bar", it.next().getEndpointUri());
-        assertEquals("log://baz", it.next().getEndpointUri());
+        String s1 = it.next().getEndpointUri();
+        String s2 = it.next().getEndpointUri();
+        assertTrue("log://bar".equals(s1) || "log://bar".equals(s2));
+        assertTrue("log://baz".equals(s1) || "log://baz".equals(s2));
+        assertTrue("log://baz".equals(s1) || "log://baz".equals(s2));
+        assertTrue("log://baz".equals(s1) || "log://baz".equals(s2));
 
         assertEquals(1, ctx.getEndpoints().size());
     }

http://git-wip-us.apache.org/repos/asf/camel/blob/9cfb0288/camel-core/src/test/java/org/apache/camel/impl/DefaultConsumerCacheTest.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/test/java/org/apache/camel/impl/DefaultConsumerCacheTest.java 
b/camel-core/src/test/java/org/apache/camel/impl/DefaultConsumerCacheTest.java
index b22284d..796a0d1 100644
--- 
a/camel-core/src/test/java/org/apache/camel/impl/DefaultConsumerCacheTest.java
+++ 
b/camel-core/src/test/java/org/apache/camel/impl/DefaultConsumerCacheTest.java
@@ -38,6 +38,9 @@ public class DefaultConsumerCacheTest extends 
ContextTestSupport {
             assertNotNull("the polling consumer should not be null", p);
         }
 
+        // the eviction is async so force cleanup
+        cache.cleanUp();
+
         assertEquals("Size should be 1000", 1000, cache.size());
         cache.stop();
     }

http://git-wip-us.apache.org/repos/asf/camel/blob/9cfb0288/camel-core/src/test/java/org/apache/camel/impl/DefaultConsumerTemplateTest.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/test/java/org/apache/camel/impl/DefaultConsumerTemplateTest.java
 
b/camel-core/src/test/java/org/apache/camel/impl/DefaultConsumerTemplateTest.java
index 3313b3e..63a0550 100644
--- 
a/camel-core/src/test/java/org/apache/camel/impl/DefaultConsumerTemplateTest.java
+++ 
b/camel-core/src/test/java/org/apache/camel/impl/DefaultConsumerTemplateTest.java
@@ -312,6 +312,9 @@ public class DefaultConsumerTemplateTest extends 
ContextTestSupport {
             template.receiveNoWait(e);
         }
 
+        // the eviction is async so force cleanup
+        template.cleanUp();
+
         assertEquals("Size should be 500", 500, 
template.getCurrentCacheSize());
         template.stop();
 
@@ -330,6 +333,9 @@ public class DefaultConsumerTemplateTest extends 
ContextTestSupport {
             template.receiveNoWait(e);
         }
 
+        // the eviction is async so force cleanup
+        template.cleanUp();
+
         assertEquals("Size should be 500", 500, 
template.getCurrentCacheSize());
         template.stop();
 

http://git-wip-us.apache.org/repos/asf/camel/blob/9cfb0288/camel-core/src/test/java/org/apache/camel/impl/DefaultConsumerTemplateWithCustomCacheMaxSizeTest.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/test/java/org/apache/camel/impl/DefaultConsumerTemplateWithCustomCacheMaxSizeTest.java
 
b/camel-core/src/test/java/org/apache/camel/impl/DefaultConsumerTemplateWithCustomCacheMaxSizeTest.java
index fba5a10..6ad0a84 100644
--- 
a/camel-core/src/test/java/org/apache/camel/impl/DefaultConsumerTemplateWithCustomCacheMaxSizeTest.java
+++ 
b/camel-core/src/test/java/org/apache/camel/impl/DefaultConsumerTemplateWithCustomCacheMaxSizeTest.java
@@ -45,6 +45,9 @@ public class 
DefaultConsumerTemplateWithCustomCacheMaxSizeTest extends ContextTe
             template.receiveNoWait(e);
         }
 
+        // the eviction is async so force cleanup
+        template.cleanUp();
+
         assertEquals("Size should be 200", 200, 
template.getCurrentCacheSize());
         template.stop();
 

http://git-wip-us.apache.org/repos/asf/camel/blob/9cfb0288/camel-core/src/test/java/org/apache/camel/impl/DefaultProducerCacheTest.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/test/java/org/apache/camel/impl/DefaultProducerCacheTest.java 
b/camel-core/src/test/java/org/apache/camel/impl/DefaultProducerCacheTest.java
index 3ef4523..6c53bf6 100644
--- 
a/camel-core/src/test/java/org/apache/camel/impl/DefaultProducerCacheTest.java
+++ 
b/camel-core/src/test/java/org/apache/camel/impl/DefaultProducerCacheTest.java
@@ -48,6 +48,9 @@ public class DefaultProducerCacheTest extends 
ContextTestSupport {
             cache.releaseProducer(e, p);
         }
 
+        // the eviction is async so force cleanup
+        cache.cleanUp();
+
         assertEquals("Size should be 1000", 1000, cache.size());
         cache.stop();
     }
@@ -64,8 +67,14 @@ public class DefaultProducerCacheTest extends 
ContextTestSupport {
             cache.releaseProducer(e, p);
         }
 
+        // the eviction is async so force cleanup
+        cache.cleanUp();
+
         assertEquals("Size should be 5", 5, cache.size());
 
+        // the eviction listener is async so sleep a bit
+        Thread.sleep(1000);
+
         // should have stopped the 3 evicted
         assertEquals(3, stopCounter.get());
 

http://git-wip-us.apache.org/repos/asf/camel/blob/9cfb0288/camel-core/src/test/java/org/apache/camel/impl/DefaultProducerTemplateTest.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/test/java/org/apache/camel/impl/DefaultProducerTemplateTest.java
 
b/camel-core/src/test/java/org/apache/camel/impl/DefaultProducerTemplateTest.java
index 8e5942b..6dc3c8e 100644
--- 
a/camel-core/src/test/java/org/apache/camel/impl/DefaultProducerTemplateTest.java
+++ 
b/camel-core/src/test/java/org/apache/camel/impl/DefaultProducerTemplateTest.java
@@ -270,6 +270,9 @@ public class DefaultProducerTemplateTest extends 
ContextTestSupport {
             template.sendBody(e, "Hello");
         }
 
+        // the eviction is async so force cleanup
+        template.cleanUp();
+
         assertEquals("Size should be 500", 500, 
template.getCurrentCacheSize());
         template.stop();
 
@@ -288,6 +291,9 @@ public class DefaultProducerTemplateTest extends 
ContextTestSupport {
             template.sendBody(e, "Hello");
         }
 
+        // the eviction is async so force cleanup
+        template.cleanUp();
+
         assertEquals("Size should be 500", 500, 
template.getCurrentCacheSize());
         template.stop();
 

http://git-wip-us.apache.org/repos/asf/camel/blob/9cfb0288/camel-core/src/test/java/org/apache/camel/impl/EndpointRegistryKeepRouteEndpointsTest.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/test/java/org/apache/camel/impl/EndpointRegistryKeepRouteEndpointsTest.java
 
b/camel-core/src/test/java/org/apache/camel/impl/EndpointRegistryKeepRouteEndpointsTest.java
index 676ab2a..e75e7c1 100644
--- 
a/camel-core/src/test/java/org/apache/camel/impl/EndpointRegistryKeepRouteEndpointsTest.java
+++ 
b/camel-core/src/test/java/org/apache/camel/impl/EndpointRegistryKeepRouteEndpointsTest.java
@@ -43,6 +43,9 @@ public class EndpointRegistryKeepRouteEndpointsTest extends 
ContextTestSupport {
             template.sendBody("mock:unknown" + i, "Hello " + i);
         }
 
+        // the eviction is async so force cleanup
+        context.getEndpointRegistry().cleanUp();
+
         // endpoints from routes is always kept in the cache
         assertTrue(context.hasEndpoint("direct://start") != null);
         assertTrue(context.hasEndpoint("log://foo") != null);
@@ -52,9 +55,6 @@ public class EndpointRegistryKeepRouteEndpointsTest extends 
ContextTestSupport {
         // and the dynamic cache only keeps the last 20
         assertFalse(context.hasEndpoint("mock://unknown0") != null);
         assertFalse(context.hasEndpoint("mock://unknown1") != null);
-        assertTrue(context.hasEndpoint("mock://unknown47") != null);
-        assertTrue(context.hasEndpoint("mock://unknown48") != null);
-        assertTrue(context.hasEndpoint("mock://unknown49") != null);
 
         // we should have 4 static, 20 dynamic and 24 in total
         assertEquals(4, context.getEndpointRegistry().staticSize());

http://git-wip-us.apache.org/repos/asf/camel/blob/9cfb0288/camel-core/src/test/java/org/apache/camel/util/LRUCacheTest.java
----------------------------------------------------------------------
diff --git a/camel-core/src/test/java/org/apache/camel/util/LRUCacheTest.java 
b/camel-core/src/test/java/org/apache/camel/util/LRUCacheTest.java
index d597f63..81ef485 100644
--- a/camel-core/src/test/java/org/apache/camel/util/LRUCacheTest.java
+++ b/camel-core/src/test/java/org/apache/camel/util/LRUCacheTest.java
@@ -28,7 +28,8 @@ public class LRUCacheTest extends TestCase {
 
     @Override
     protected void setUp() throws Exception {
-        cache = new LRUCache<String, Service>(10);
+        // for testing use sync listener
+        cache = new LRUCache<String, Service>(10, 10, true, false, false, 
true);
     }
 
     public void testLRUCache() {
@@ -44,7 +45,7 @@ public class LRUCacheTest extends TestCase {
         assertSame(service2, cache.get("B"));
     }
 
-    public void testLRUCacheEviction() {
+    public void testLRUCacheEviction() throws Exception {
         MyService service1 = new MyService();
         MyService service2 = new MyService();
         MyService service3 = new MyService();
@@ -85,12 +86,19 @@ public class LRUCacheTest extends TestCase {
         cache.put("K", service11);
         assertNull(service11.getStopped());
 
+        // the eviction is async so force cleanup
+        cache.cleanUp();
+
         // should evict the eldest, and stop the service
         assertTrue(service1.getStopped());
 
-        cache.put("L", service12);
         assertNull(service12.getStopped());
 
+        cache.put("L", service12);
+
+        // the eviction is async so force cleanup
+        cache.cleanUp();
+
         // should evict the eldest, and stop the service
         assertTrue(service2.getStopped());
 

http://git-wip-us.apache.org/repos/asf/camel/blob/9cfb0288/parent/pom.xml
----------------------------------------------------------------------
diff --git a/parent/pom.xml b/parent/pom.xml
index 9475392..c6785ab 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -79,6 +79,7 @@
     <braintree-gateway-version>2.55.0</braintree-gateway-version>
     <build-helper-maven-plugin-version>1.10</build-helper-maven-plugin-version>
     <c3p0-version>0.9.5.2</c3p0-version>
+    <caffeine-version>2.2.3</caffeine-version>
     <californium-version>1.0.0-M3</californium-version>
     
<camel-test-spring-artifactId>camel-test-spring</camel-test-spring-artifactId>
     <cassandra-driver-version>2.1.9</cassandra-driver-version>
@@ -127,7 +128,6 @@
     <commons-pool2-version>2.4.2</commons-pool2-version>
     <commons-vfs2-version>2.0</commons-vfs2-version>
     <compress-lzf-version>1.0.3</compress-lzf-version>
-    <concurrentlinkedhashmap.version>1.4.2</concurrentlinkedhashmap.version>
     <cobertura-maven-plugin-version>2.7</cobertura-maven-plugin-version>
     <cxf-version>3.1.5</cxf-version>
     <cxf-version-range>[3.0,4.0)</cxf-version-range>
@@ -2023,11 +2023,11 @@
         <version>${kafka-version}</version>
       </dependency>
       
-      <!-- API -->
+      <!-- embedded concurrent lru map -->
       <dependency>
-        <groupId>com.googlecode.concurrentlinkedhashmap</groupId>
-        <artifactId>concurrentlinkedhashmap-lru</artifactId>
-        <version>${concurrentlinkedhashmap.version}</version>
+        <groupId>com.github.ben-manes.caffeine</groupId>
+        <artifactId>caffeine</artifactId>
+        <version>${caffeine-version}</version>
       </dependency>
 
       <!-- optional dependencies -->

Reply via email to