001/**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.camel.util;
018
019import java.util.concurrent.atomic.AtomicBoolean;
020
021import org.apache.camel.util.concurrent.ThreadHelper;
022import org.slf4j.Logger;
023import org.slf4j.LoggerFactory;
024
025/**
026 * Factory to create {@link LRUCache} instances.
027 */
028public final class LRUCacheFactory {
029
030    private static final Logger LOG = LoggerFactory.getLogger(LRUCacheFactory.class);
031
032    private static final AtomicBoolean INIT = new AtomicBoolean();
033
034    private LRUCacheFactory() {
035    }
036
037    /**
038     * Warm-up the LRUCache to startup Apache Camel faster.
039     */
040    @SuppressWarnings("unchecked")
041    public static void warmUp() {
042        // create a dummy map in a separate thread to warm-up the Caffeine cache concurrently
043        // while Camel is starting up. This allows us to overall startup Camel a bit faster
044        // as Caffeine takes 150+ millis to initialize.
045        if (INIT.compareAndSet(false, true)) {
046            // only need to init Caffeine once in the JVM/classloader
047            Runnable task = () -> {
048                StopWatch watch = new StopWatch();
049                LOG.debug("Warming up LRUCache ...");
050                newLRUCache(16);
051                LOG.debug("Warming up LRUCache complete in {} millis", watch.taken());
052            };
053
054            String threadName = ThreadHelper.resolveThreadName(null, "LRUCacheFactory");
055
056            Thread thread = new Thread(task, threadName);
057            thread.start();
058        }
059    }
060
061    /**
062     * Constructs an empty <tt>LRUCache</tt> instance with the
063     * specified maximumCacheSize, and will stop on eviction.
064     *
065     * @param maximumCacheSize the max capacity.
066     * @throws IllegalArgumentException if the initial capacity is negative
067     */
068    public static LRUCache newLRUCache(int maximumCacheSize) {
069        LOG.trace("Creating LRUCache with maximumCacheSize: {}", maximumCacheSize);
070        return new LRUCache(maximumCacheSize);
071    }
072
073    /**
074     * Constructs an empty <tt>LRUCache</tt> instance with the
075     * specified initial capacity, maximumCacheSize, and will stop on eviction.
076     *
077     * @param initialCapacity  the initial capacity.
078     * @param maximumCacheSize the max capacity.
079     * @throws IllegalArgumentException if the initial capacity is negative
080     */
081    public static LRUCache newLRUCache(int initialCapacity, int maximumCacheSize) {
082        LOG.trace("Creating LRUCache with initialCapacity: {}, maximumCacheSize: {}", initialCapacity, maximumCacheSize);
083        return new LRUCache(initialCapacity, maximumCacheSize);
084    }
085
086    /**
087     * Constructs an empty <tt>LRUCache</tt> instance with the
088     * specified initial capacity, maximumCacheSize,load factor and ordering mode.
089     *
090     * @param initialCapacity  the initial capacity.
091     * @param maximumCacheSize the max capacity.
092     * @param stopOnEviction   whether to stop service on eviction.
093     * @throws IllegalArgumentException if the initial capacity is negative
094     */
095    public static LRUCache newLRUCache(int initialCapacity, int maximumCacheSize, boolean stopOnEviction) {
096        LOG.trace("Creating LRUCache with initialCapacity: {}, maximumCacheSize: {}, stopOnEviction: {}", initialCapacity, maximumCacheSize, stopOnEviction);
097        return new LRUCache(initialCapacity, maximumCacheSize, stopOnEviction);
098    }
099
100    /**
101     * Constructs an empty <tt>LRUSoftCache</tt> instance with the
102     * specified maximumCacheSize, and will stop on eviction.
103     *
104     * @param maximumCacheSize the max capacity.
105     * @throws IllegalArgumentException if the initial capacity is negative
106     */
107    public static LRUSoftCache newLRUSoftCache(int maximumCacheSize) {
108        LOG.trace("Creating LRUSoftCache with maximumCacheSize: {}", maximumCacheSize);
109        return new LRUSoftCache(maximumCacheSize);
110    }
111
112    /**
113     * Constructs an empty <tt>LRUWeakCache</tt> instance with the
114     * specified maximumCacheSize, and will stop on eviction.
115     *
116     * @param maximumCacheSize the max capacity.
117     * @throws IllegalArgumentException if the initial capacity is negative
118     */
119    public static LRUWeakCache newLRUWeakCache(int maximumCacheSize) {
120        LOG.trace("Creating LRUWeakCache with maximumCacheSize: {}", maximumCacheSize);
121        return new LRUWeakCache(maximumCacheSize);
122    }
123}