/* * 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.shindig.common.cache; import com.google.common.base.Preconditions; import com.google.common.collect.MapMaker; import com.google.inject.ConfigurationException; import com.google.inject.Inject; import com.google.inject.Injector; import com.google.inject.Key; import com.google.inject.name.Named; import com.google.inject.name.Names; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; /** * A cache provider that always produces LRU caches. * * LRU cache sizes can be configured by specifying property names in the form * * shindig.cache.lru.<cache name>.capacity=foo * * The default value is expected under shindig.cache.lru.default.capacity * * An in memory LRU cache only scales so far. For a production-worthy cache, use * {@code EhCacheCacheProvider}. */ public class LruCacheProvider implements CacheProvider { private static final Logger LOG = Logger.getLogger(LruCacheProvider.class.getName()); private final int defaultCapacity; private final Injector injector; private final Map<String, Cache<?, ?>> caches = new MapMaker().makeMap(); @Inject public LruCacheProvider(Injector injector, @Named("shindig.cache.lru.default.capacity") int defaultCapacity) { this.injector = injector; this.defaultCapacity = defaultCapacity; } public LruCacheProvider(int capacity) { this(null, capacity); } private int getCapacity(String name) { if (injector != null && name != null) { String key = "shindig.cache.lru." + name + ".capacity"; Key<String> guiceKey = Key.get(String.class, Names.named(key)); try { if (injector.getBinding(guiceKey) == null) { LOG.warning("No LRU capacity configured for " + name); } else { String value = injector.getInstance(guiceKey); try { return Integer.parseInt(value); } catch (NumberFormatException e) { LOG.warning("Invalid LRU capacity configured for " + name); } } } catch ( ConfigurationException e ) { return defaultCapacity; } } return defaultCapacity; } @SuppressWarnings("unchecked") public <K, V> Cache<K, V> createCache(String name) { int capacity = getCapacity(Preconditions.checkNotNull(name)); Cache<K, V> cache = (Cache<K, V>) caches.get(name); if (cache == null) { if (LOG.isLoggable(Level.FINE)) { LOG.fine("Creating cache named " + name); } cache = new LruCache<K, V>(capacity); caches.put(name, cache); } return cache; } }