diff --git a/scm-webapp/src/main/java/sonia/scm/cache/CacheConfigurationReader.java b/scm-webapp/src/main/java/sonia/scm/cache/CacheConfigurationReader.java index a295ef8c33..43fe88ff58 100644 --- a/scm-webapp/src/main/java/sonia/scm/cache/CacheConfigurationReader.java +++ b/scm-webapp/src/main/java/sonia/scm/cache/CacheConfigurationReader.java @@ -64,14 +64,14 @@ public class CacheConfigurationReader { /** Field description */ - private static final String DEFAULT = "/config/cache.xml"; + private static final String DEFAULT = "/config/gcache.xml"; /** Field description */ private static final String MANUAL_RESOURCE = - "ext".concat(File.separator).concat("cache.xml"); + "ext".concat(File.separator).concat("gcache.xml"); /** Field description */ - private static final String MODULE_RESOURCES = "/META-INF/scm/cache.xml"; + private static final String MODULE_RESOURCES = "/META-INF/scm/gcache.xml"; /** * the logger for CacheConfigurationReader diff --git a/scm-webapp/src/main/java/sonia/scm/cache/CacheConfigurations.java b/scm-webapp/src/main/java/sonia/scm/cache/CacheConfigurations.java index 1b7689d497..ae56117bc5 100644 --- a/scm-webapp/src/main/java/sonia/scm/cache/CacheConfigurations.java +++ b/scm-webapp/src/main/java/sonia/scm/cache/CacheConfigurations.java @@ -51,7 +51,7 @@ import java.util.Iterator; * * @author Sebastian Sdorra */ -public class CacheConfigurations +public final class CacheConfigurations { /** @@ -61,7 +61,12 @@ public class CacheConfigurations LoggerFactory.getLogger(CacheConfigurations.class); //~--- methods -------------------------------------------------------------- + private CacheConfigurations() + { + } + + /** * Method description * diff --git a/scm-webapp/src/main/java/sonia/scm/cache/GuavaCache.java b/scm-webapp/src/main/java/sonia/scm/cache/GuavaCache.java index 8256c93520..082bc6df1c 100644 --- a/scm-webapp/src/main/java/sonia/scm/cache/GuavaCache.java +++ b/scm-webapp/src/main/java/sonia/scm/cache/GuavaCache.java @@ -33,7 +33,7 @@ package sonia.scm.cache; //~--- non-JDK imports -------------------------------------------------------- -import com.google.common.cache.CacheBuilder; +import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.Sets; import org.slf4j.Logger; @@ -44,7 +44,6 @@ import sonia.scm.Filter; //~--- JDK imports ------------------------------------------------------------ import java.util.Set; -import java.util.concurrent.TimeUnit; /** * @@ -84,72 +83,28 @@ public class GuavaCache implements Cache */ public GuavaCache(CacheConfiguration configuration, String name) { + this(GuavaCaches.create(configuration, name), + configuration.getCopyStrategy(), name); + } + + /** + * Constructs ... + * + * + * @param cache + * @param copyStrategy + * @param name + */ + @VisibleForTesting + protected GuavaCache(com.google.common.cache.Cache cache, + CopyStrategy copyStrategy, String name) + { + this.cache = cache; this.name = name; - if (configuration.getCopyStrategy() != null) + if (copyStrategy != null) { - copyStrategy = configuration.getCopyStrategy(); - } - - CacheBuilder builder = CacheBuilder.newBuilder(); - - if (configuration.getConcurrencyLevel() != null) - { - builder.concurrencyLevel(configuration.getConcurrencyLevel()); - } - - if (configuration.getExpireAfterAccess() != null) - { - builder.expireAfterAccess(configuration.getExpireAfterAccess(), - TimeUnit.MILLISECONDS); - } - - if (configuration.getExpireAfterWrite() != null) - { - builder.expireAfterWrite(configuration.getExpireAfterWrite(), - TimeUnit.MILLISECONDS); - } - - if (configuration.getInitialCapacity() != null) - { - builder.initialCapacity(configuration.getInitialCapacity()); - } - - if (configuration.getMaximumSize() != null) - { - builder.maximumSize(configuration.getMaximumSize()); - } - - if (configuration.getMaximumWeight() != null) - { - builder.maximumWeight(configuration.getMaximumWeight()); - } - - if (isEnabled(configuration.getRecordStats())) - { - builder.recordStats(); - } - - if (isEnabled(configuration.getSoftValues())) - { - builder.softValues(); - } - - if (isEnabled(configuration.getWeakKeys())) - { - builder.weakKeys(); - } - - if (isEnabled(configuration.getWeakValues())) - { - builder.weakKeys(); - } - - cache = builder.build(); - - if (logger.isTraceEnabled()) - { - logger.trace("create new guava cache from builder: {}", builder); + this.copyStrategy = copyStrategy; } } @@ -268,19 +223,6 @@ public class GuavaCache implements Cache return value; } - /** - * Method description - * - * - * @param v - * - * @return - */ - private boolean isEnabled(Boolean v) - { - return (v != null) && v; - } - //~--- fields --------------------------------------------------------------- /** Field description */ diff --git a/scm-webapp/src/main/java/sonia/scm/cache/GuavaCacheManager.java b/scm-webapp/src/main/java/sonia/scm/cache/GuavaCacheManager.java index 58783f411f..0cf964c0d5 100644 --- a/scm-webapp/src/main/java/sonia/scm/cache/GuavaCacheManager.java +++ b/scm-webapp/src/main/java/sonia/scm/cache/GuavaCacheManager.java @@ -34,6 +34,7 @@ package sonia.scm.cache; //~--- non-JDK imports -------------------------------------------------------- import com.google.common.collect.Maps; +import com.google.inject.Singleton; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -48,6 +49,7 @@ import java.util.Map; * * @author Sebastian Sdorra */ +@Singleton public class GuavaCacheManager implements CacheManager { @@ -57,6 +59,25 @@ public class GuavaCacheManager implements CacheManager private static final Logger logger = LoggerFactory.getLogger(GuavaCacheManager.class); + //~--- constructors --------------------------------------------------------- + + /** + * Constructs ... + * + */ + public GuavaCacheManager() + { + CacheConfigurationReader reader = new CacheConfigurationReader(); + CacheManagerConfiguration config = reader.read(); + + defaultConfiguration = config.getDefaultCache(); + + for (NamedCacheConfiguration ncc : config.getCaches()) + { + cacheMap.put(ncc.getName(), new GuavaCache(ncc)); + } + } + //~--- methods -------------------------------------------------------------- /** @@ -105,7 +126,7 @@ public class GuavaCacheManager implements CacheManager logger.debug( "cache {} does not exists, creating a new instance from default configuration: {}", name, defaultConfiguration); - cache = new GuavaCache(defaultConfiguration); + cache = new GuavaCache(defaultConfiguration, name); cacheMap.put(name, cache); } @@ -118,5 +139,5 @@ public class GuavaCacheManager implements CacheManager private Map cacheMap = Maps.newConcurrentMap(); /** Field description */ - private NamedCacheConfiguration defaultConfiguration; + private CacheConfiguration defaultConfiguration; } diff --git a/scm-webapp/src/main/java/sonia/scm/cache/GuavaCaches.java b/scm-webapp/src/main/java/sonia/scm/cache/GuavaCaches.java new file mode 100644 index 0000000000..1aba642ab0 --- /dev/null +++ b/scm-webapp/src/main/java/sonia/scm/cache/GuavaCaches.java @@ -0,0 +1,156 @@ +/** + * Copyright (c) 2010, Sebastian Sdorra All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. 2. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. 3. Neither the name of SCM-Manager; + * nor the names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * http://bitbucket.org/sdorra/scm-manager + * + */ + + + +package sonia.scm.cache; + +//~--- non-JDK imports -------------------------------------------------------- + +import com.google.common.cache.CacheBuilder; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +//~--- JDK imports ------------------------------------------------------------ + +import java.util.concurrent.TimeUnit; + +/** + * + * @author Sebastian Sdorra + */ +public final class GuavaCaches +{ + + /** + * the logger for GuavaCaches + */ + private static final Logger logger = + LoggerFactory.getLogger(GuavaCaches.class); + + //~--- constructors --------------------------------------------------------- + + /** + * Constructs ... + * + */ + private GuavaCaches() {} + + //~--- methods -------------------------------------------------------------- + + /** + * Method description + * + * + * @param configuration + * @param name + * + * @return + */ + public static com.google.common.cache.Cache create( + CacheConfiguration configuration, String name) + { + CacheBuilder builder = CacheBuilder.newBuilder(); + + if (configuration.getConcurrencyLevel() != null) + { + builder.concurrencyLevel(configuration.getConcurrencyLevel()); + } + + if (configuration.getExpireAfterAccess() != null) + { + builder.expireAfterAccess(configuration.getExpireAfterAccess(), + TimeUnit.SECONDS); + } + + if (configuration.getExpireAfterWrite() != null) + { + builder.expireAfterWrite(configuration.getExpireAfterWrite(), + TimeUnit.SECONDS); + } + + if (configuration.getInitialCapacity() != null) + { + builder.initialCapacity(configuration.getInitialCapacity()); + } + + if (configuration.getMaximumSize() != null) + { + builder.maximumSize(configuration.getMaximumSize()); + } + + if (configuration.getMaximumWeight() != null) + { + builder.maximumWeight(configuration.getMaximumWeight()); + } + + if (isEnabled(configuration.getRecordStats())) + { + builder.recordStats(); + } + + if (isEnabled(configuration.getSoftValues())) + { + builder.softValues(); + } + + if (isEnabled(configuration.getWeakKeys())) + { + builder.weakKeys(); + } + + if (isEnabled(configuration.getWeakValues())) + { + builder.weakKeys(); + } + + if (logger.isTraceEnabled()) + { + logger.trace("create new cache {} from builder: {}", name, builder); + } + + return builder.build(); + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @param v + * + * @return + */ + private static boolean isEnabled(Boolean v) + { + return (v != null) && v; + } +}