blob: bf1df9e6d598dea86fb9871bfe13fbd6eaab9e07 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. 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. For additional information regarding
* copyright in this work, please see the NOTICE file in the top level
* directory of this distribution.
*/
package org.apache.roller.weblogger.util.cache;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import org.apache.roller.util.RollerConstants;
/**
* A simple LRU Cache.
*/
public class LRUCacheImpl implements Cache {
private String id = null;
private Map cache = null;
// for metrics
protected double hits = 0;
protected double misses = 0;
protected double puts = 0;
protected double removes = 0;
protected Date startTime = new Date();
protected LRUCacheImpl(String id) {
this.id = id;
this.cache = Collections.synchronizedMap(new LRULinkedHashMap(100));
}
protected LRUCacheImpl(String id, int maxsize) {
this.id = id;
this.cache = Collections.synchronizedMap(new LRULinkedHashMap(maxsize));
}
public String getId() {
return this.id;
}
/**
* Store an entry in the cache.
*/
public synchronized void put(String key, Object value) {
this.cache.put(key, value);
puts++;
}
/**
* Retrieve an entry from the cache.
*/
public synchronized Object get(String key) {
Object obj = this.cache.get(key);
// for metrics
if(obj == null) {
misses++;
} else {
hits++;
}
return obj;
}
public synchronized void remove(String key) {
this.cache.remove(key);
removes++;
}
public synchronized void clear() {
this.cache.clear();
// clear metrics
hits = 0;
misses = 0;
puts = 0;
removes = 0;
startTime = new Date();
}
public Map<String, Object> getStats() {
Map<String, Object> stats = new HashMap<String, Object>();
stats.put("startTime", this.startTime);
stats.put("hits", this.hits);
stats.put("misses", this.misses);
stats.put("puts", this.puts);
stats.put("removes", this.removes);
// calculate efficiency
if((misses - removes) > 0) {
double efficiency = hits / (misses + hits);
stats.put("efficiency", efficiency * RollerConstants.PERCENT_100);
}
return stats;
}
// David Flanaghan: http://www.davidflanagan.com/blog/000014.html
private static class LRULinkedHashMap extends LinkedHashMap {
protected int maxsize;
public LRULinkedHashMap(int maxsize) {
super(maxsize * 4 / 3 + 1, 0.75f, true);
this.maxsize = maxsize;
}
protected boolean removeEldestEntry(Map.Entry eldest) {
return this.size() > this.maxsize;
}
}
}