/**
* This file is part of Waarp Project.
*
* Copyright 2009, Frederic Bregier, and individual contributors by the @author tags. See the
* COPYRIGHT.txt in the distribution for a full listing of individual contributors.
*
* All Waarp Project is free software: you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* Waarp is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with Waarp. If not, see
* <http://www.gnu.org/licenses/>.
*/
package org.waarp.common.lru;
import java.util.Collection;
import java.util.Iterator;
/**
* Threadsafe synchronized implementation of LruCache based on LinkedHashMap. Threadsafety is
* provided by method synchronization.
*
* This cache implementation should be used with low number of threads.
*
* @author Frederic Bregier
* @author Damian Momot
*/
public class SynchronizedLruCache<K, V> extends AbstractLruCache<K, V> {
public static final int DEFAULT_INITIAL_CAPACITY = 16;
public static final float DEFAULT_LOAD_FACTOR = 0.75f;
private final CapacityLruLinkedHashMap<K, InterfaceLruCacheEntry<V>> cacheMap;
/**
* Creates new SynchronizedLruCache
*
* @param capacity
* max cache capacity
* @param ttl
* time to live in milliseconds
* @param initialCapacity
* initial cache capacity
* @param loadFactor
*/
public SynchronizedLruCache(int capacity, long ttl, int initialCapacity,
float loadFactor) {
super(ttl);
cacheMap = new CapacityLruLinkedHashMap<K, InterfaceLruCacheEntry<V>>(
capacity, initialCapacity, loadFactor);
}
/**
* Creates new SynchronizedLruCache with DEFAULT_LOAD_FACTOR
*
* @param capacity
* max cache capacity
* @param ttl
* time to live in milliseconds
* @param initialCapacity
* initial cache capacity
*/
public SynchronizedLruCache(int capacity, long ttl, int initialCapacity) {
this(capacity, ttl, initialCapacity, DEFAULT_LOAD_FACTOR);
}
/**
* Creates new SynchronizedLruCache with DEFAULT_LOAD_FACTOR and DEFAULT_INITIAL_CAPACITY
*
* @param capacity
* max cache capacity
* @param ttl
* time to live in milliseconds
*/
public SynchronizedLruCache(int capacity, long ttl) {
this(capacity, ttl, DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR);
}
synchronized public void clear() {
cacheMap.clear();
}
@Override
synchronized public V get(K key) {
return super.get(key);
}
public int getCapacity() {
return cacheMap.getCapacity();
}
@Override
protected InterfaceLruCacheEntry<V> getEntry(K key) {
return cacheMap.get(key);
}
synchronized public int size() {
return cacheMap.size();
}
synchronized public void put(K key, V value, long ttl) {
super.put(key, value, ttl);
}
@Override
protected void putEntry(K key, InterfaceLruCacheEntry<V> entry) {
cacheMap.put(key, entry);
}
synchronized public V remove(K key) {
InterfaceLruCacheEntry<V> cv = cacheMap.remove(key);
if (cv != null) {
return cv.getValue();
}
return null;
}
synchronized public int forceClearOldest() {
long timeRef = System.currentTimeMillis();
Collection<InterfaceLruCacheEntry<V>> collection = cacheMap.values();
Iterator<InterfaceLruCacheEntry<V>> iterator = collection.iterator();
int nb = 0;
while (iterator.hasNext()) {
InterfaceLruCacheEntry<V> v = iterator.next();
if (!v.isStillValid(timeRef)) {
iterator.remove();
nb++;
}
}
return nb;
}
}