SOLR-1893: Refactored some common code from LRUCache and FastLRUCache into SolrCacheBase

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1331622 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Chris M. Hostetter 2012-04-27 22:57:03 +00:00
parent e2507ce54c
commit 7f2ed71391
4 changed files with 133 additions and 125 deletions

View File

@ -529,6 +529,9 @@ Other Changes
on startup. This allows for faster startup times on some servlet containers.
(Bill Bell, hossman)
* SOLR-1893: Refactored some common code from LRUCache and FastLRUCache into
SolrCacheBase (Tomás Fernández Löbbe via hossman)
Documentation
----------------------

View File

@ -24,7 +24,6 @@ import org.apache.solr.core.SolrCore;
import java.io.IOException;
import java.io.Serializable;
import java.net.URL;
import java.util.List;
import java.util.Map;
import java.util.Set;
@ -50,18 +49,12 @@ public class FastLRUCache<K,V> extends SolrCacheBase implements SolrCache<K,V> {
private long warmupTime = 0;
private String name;
private AutoWarmCountRef autowarm;
private State state;
private CacheRegenerator regenerator;
private String description = "Concurrent LRU Cache";
private ConcurrentLRUCache<K,V> cache;
private int showItems = 0;
public Object init(Map args, Object persistence, CacheRegenerator regenerator) {
state = State.CREATED;
this.regenerator = regenerator;
name = (String) args.get("name");
super.init(args, regenerator);
String str = (String) args.get("size");
int limit = str == null ? 1024 : Integer.parseInt(str);
int minLimit;
@ -86,21 +79,12 @@ public class FastLRUCache<K,V> extends SolrCacheBase implements SolrCache<K,V> {
str = (String) args.get("initialSize");
final int initialSize = str == null ? limit : Integer.parseInt(str);
autowarm = new AutoWarmCountRef((String)args.get("autowarmCount"));
str = (String) args.get("cleanupThread");
boolean newThread = str == null ? false : Boolean.parseBoolean(str);
str = (String) args.get("showItems");
showItems = str == null ? 0 : Integer.parseInt(str);
description = "Concurrent LRU Cache(maxSize=" + limit + ", initialSize=" + initialSize +
", minSize="+minLimit + ", acceptableSize="+acceptableLimit+", cleanupThread="+newThread;
if (autowarm.isAutoWarmingOn()) {
description += ", autowarmCount=" + autowarm + ", regenerator=" + regenerator;
}
description += ')';
description = generateDescription(limit, initialSize, minLimit, acceptableLimit, newThread);
cache = new ConcurrentLRUCache<K,V>(limit, minLimit, acceptableLimit, initialSize, newThread, false, null);
cache.setAlive(false);
@ -117,14 +101,22 @@ public class FastLRUCache<K,V> extends SolrCacheBase implements SolrCache<K,V> {
statsList.add(cache.getStats());
return statsList;
}
public String name() {
return name;
/**
* @return Returns the description of this Cache.
*/
protected String generateDescription(int limit, int initialSize, int minLimit, int acceptableLimit, boolean newThread) {
String description = "Concurrent LRU Cache(maxSize=" + limit + ", initialSize=" + initialSize +
", minSize="+minLimit + ", acceptableSize="+acceptableLimit+", cleanupThread="+newThread;
if (isAutowarmingOn()) {
description += ", " + getAutowarmDescription();
}
description += ')';
return description;
}
public int size() {
return cache.size();
}
public V put(K key, V value) {
@ -140,20 +132,16 @@ public class FastLRUCache<K,V> extends SolrCacheBase implements SolrCache<K,V> {
}
public void setState(State state) {
this.state = state;
super.setState(state);
cache.setAlive(state == State.LIVE);
}
public State getState() {
return state;
}
public void warm(SolrIndexSearcher searcher, SolrCache old) throws IOException {
if (regenerator == null) return;
long warmingStartTime = System.currentTimeMillis();
FastLRUCache other = (FastLRUCache) old;
// warm entries
if (autowarm.isAutoWarmingOn()) {
if (isAutowarmingOn()) {
int sz = autowarm.getWarmCount(other.size());
Map items = other.cache.getLatestAccessedItems(sz);
Map.Entry[] itemsArr = new Map.Entry[items.size()];
@ -188,34 +176,14 @@ public class FastLRUCache<K,V> extends SolrCacheBase implements SolrCache<K,V> {
return FastLRUCache.class.getName();
}
public String getVersion() {
return SolrCore.version;
}
public String getDescription() {
return description;
}
public Category getCategory() {
return Category.CACHE;
}
public String getSource() {
return "$URL$";
}
public URL[] getDocs() {
return null;
}
// returns a ratio, not a percent.
private static String calcHitRatio(long lookups, long hits) {
if (lookups == 0) return "0.00";
if (lookups == hits) return "1.00";
int hundredths = (int) (hits * 100 / lookups); // rounded down
if (hundredths < 10) return "0.0" + hundredths;
return "0." + hundredths;
}
public NamedList getStatistics() {
NamedList<Serializable> lst = new SimpleOrderedMap<Serializable>();
@ -226,16 +194,6 @@ public class FastLRUCache<K,V> extends SolrCacheBase implements SolrCache<K,V> {
long inserts = stats.getCumulativePuts();
long evictions = stats.getCumulativeEvictions();
long size = stats.getCurrentSize();
lst.add("lookups", lookups);
lst.add("hits", hits);
lst.add("hitratio", calcHitRatio(lookups, hits));
lst.add("inserts", inserts);
lst.add("evictions", evictions);
lst.add("size", size);
lst.add("warmupTime", warmupTime);
long clookups = 0;
long chits = 0;
long cinserts = 0;
@ -248,6 +206,15 @@ public class FastLRUCache<K,V> extends SolrCacheBase implements SolrCache<K,V> {
cinserts += statistiscs.getCumulativePuts();
cevictions += statistiscs.getCumulativeEvictions();
}
lst.add("lookups", lookups);
lst.add("hits", hits);
lst.add("hitratio", calcHitRatio(lookups, hits));
lst.add("inserts", inserts);
lst.add("evictions", evictions);
lst.add("size", size);
lst.add("warmupTime", warmupTime);
lst.add("cumulative_lookups", clookups);
lst.add("cumulative_hits", chits);
lst.add("cumulative_hitratio", calcHitRatio(clookups, chits));
@ -272,7 +239,7 @@ public class FastLRUCache<K,V> extends SolrCacheBase implements SolrCache<K,V> {
@Override
public String toString() {
return name + getStatistics().toString();
return name() + getStatistics().toString();
}
}

View File

@ -17,15 +17,15 @@
package org.apache.solr.search;
import java.io.IOException;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.common.util.SimpleOrderedMap;
import org.apache.solr.core.SolrCore;
import java.util.*;
import java.util.concurrent.atomic.AtomicLong;
import java.io.IOException;
import java.net.URL;
/**
@ -55,26 +55,15 @@ public class LRUCache<K,V> extends SolrCacheBase implements SolrCache<K,V> {
private long warmupTime = 0;
private Map<K,V> map;
private String name;
private AutoWarmCountRef autowarm;
private State state;
private CacheRegenerator regenerator;
private String description="LRU Cache";
public Object init(Map args, Object persistence, CacheRegenerator regenerator) {
state=State.CREATED;
this.regenerator = regenerator;
name = (String)args.get("name");
super.init(args, regenerator);
String str = (String)args.get("size");
final int limit = str==null ? 1024 : Integer.parseInt(str);
str = (String)args.get("initialSize");
final int initialSize = Math.min(str==null ? 1024 : Integer.parseInt(str), limit);
autowarm = new AutoWarmCountRef((String)args.get("autowarmCount"));
description = "LRU Cache(maxSize=" + limit + ", initialSize=" + initialSize;
if (autowarm.isAutoWarmingOn()) {
description += ", autowarmCount=" + autowarm + ", regenerator=" + regenerator;
}
description += ')';
description = generateDescription(limit, initialSize);
map = new LinkedHashMap<K,V>(initialSize, 0.75f, true) {
@Override
@ -101,8 +90,17 @@ public class LRUCache<K,V> extends SolrCacheBase implements SolrCache<K,V> {
return persistence;
}
public String name() {
return name;
/**
*
* @return Returns the description of this cache.
*/
private String generateDescription(int limit, int initialSize) {
String description = "LRU Cache(maxSize=" + limit + ", initialSize=" + initialSize;
if (isAutowarmingOn()) {
description += ", " + getAutowarmDescription();
}
description += ')';
return description;
}
public int size() {
@ -113,7 +111,7 @@ public class LRUCache<K,V> extends SolrCacheBase implements SolrCache<K,V> {
public V put(K key, V value) {
synchronized (map) {
if (state == State.LIVE) {
if (getState() == State.LIVE) {
stats.inserts.incrementAndGet();
}
@ -127,7 +125,7 @@ public class LRUCache<K,V> extends SolrCacheBase implements SolrCache<K,V> {
public V get(K key) {
synchronized (map) {
V val = map.get(key);
if (state == State.LIVE) {
if (getState() == State.LIVE) {
// only increment lookups and hits if we are live.
lookups++;
stats.lookups.incrementAndGet();
@ -146,21 +144,13 @@ public class LRUCache<K,V> extends SolrCacheBase implements SolrCache<K,V> {
}
}
public void setState(State state) {
this.state = state;
}
public State getState() {
return state;
}
public void warm(SolrIndexSearcher searcher, SolrCache<K,V> old) throws IOException {
if (regenerator==null) return;
long warmingStartTime = System.currentTimeMillis();
LRUCache<K,V> other = (LRUCache<K,V>)old;
// warm entries
if (autowarm.isAutoWarmingOn()) {
if (isAutowarmingOn()) {
Object[] keys,vals = null;
// Don't do the autowarming in the synchronized block, just pull out the keys and values.
@ -214,42 +204,14 @@ public class LRUCache<K,V> extends SolrCacheBase implements SolrCache<K,V> {
return LRUCache.class.getName();
}
public String getVersion() {
return SolrCore.version;
}
public String getDescription() {
return description;
}
public Category getCategory() {
return Category.CACHE;
return description;
}
public String getSource() {
return "$URL$";
}
public URL[] getDocs() {
return null;
}
// returns a ratio, not a percent.
private static String calcHitRatio(long lookups, long hits) {
if (lookups==0) return "0.00";
if (lookups==hits) return "1.00";
int hundredths = (int)(hits*100/lookups); // rounded down
if (hundredths < 10) return "0.0" + hundredths;
return "0." + hundredths;
/*** code to produce a percent, if we want it...
int ones = (int)(hits*100 / lookups);
int tenths = (int)(hits*1000 / lookups) - ones*10;
return Integer.toString(ones) + '.' + tenths;
***/
}
public NamedList getStatistics() {
NamedList lst = new SimpleOrderedMap();
synchronized (map) {
@ -260,9 +222,8 @@ public class LRUCache<K,V> extends SolrCacheBase implements SolrCache<K,V> {
lst.add("evictions", evictions);
lst.add("size", map.size());
}
lst.add("warmupTime", warmupTime);
long clookups = stats.lookups.get();
long chits = stats.hits.get();
lst.add("cumulative_lookups", clookups);
@ -270,12 +231,12 @@ public class LRUCache<K,V> extends SolrCacheBase implements SolrCache<K,V> {
lst.add("cumulative_hitratio", calcHitRatio(clookups,chits));
lst.add("cumulative_inserts", stats.inserts.get());
lst.add("cumulative_evictions", stats.evictions.get());
return lst;
}
@Override
public String toString() {
return name + getStatistics().toString();
return name() + getStatistics().toString();
}
}

View File

@ -17,11 +17,28 @@
package org.apache.solr.search;
import java.io.Serializable;
import java.net.URL;
import java.util.Map;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.core.SolrCore;
import org.apache.solr.core.SolrInfoMBean.Category;
import org.apache.solr.search.SolrCache.State;
/**
* Common base class of reusable functionality for SolrCaches
*/
public abstract class SolrCacheBase {
protected CacheRegenerator regenerator;
private State state;
private String name;
protected AutoWarmCountRef autowarm;
/**
* Decides how many things to autowarm based on the size of another cache
*/
@ -68,5 +85,65 @@ public abstract class SolrCacheBase {
Math.min(previousCacheSize, autoWarmCount);
}
}
/**
* Returns a "Hit Ratio" (ie: max of 1.00, not a percentage) suitable for
* display purposes.
*/
protected static String calcHitRatio(long lookups, long hits) {
if (lookups==0) return "0.00";
if (lookups==hits) return "1.00";
int hundredths = (int)(hits*100/lookups); // rounded down
if (hundredths < 10) return "0.0" + hundredths;
return "0." + hundredths;
/*** code to produce a percent, if we want it...
int ones = (int)(hits*100 / lookups);
int tenths = (int)(hits*1000 / lookups) - ones*10;
return Integer.toString(ones) + '.' + tenths;
***/
}
public String getVersion() {
return SolrCore.version;
}
public Category getCategory() {
return Category.CACHE;
}
public URL[] getDocs() {
return null;
}
public void init(Map<String, String> args, CacheRegenerator regenerator) {
this.regenerator = regenerator;
state=State.CREATED;
name = (String) args.get("name");
autowarm = new AutoWarmCountRef((String)args.get("autowarmCount"));
}
protected String getAutowarmDescription() {
return "autowarmCount=" + autowarm + ", regenerator=" + regenerator;
}
protected boolean isAutowarmingOn() {
return autowarm.isAutoWarmingOn();
}
public void setState(State state) {
this.state = state;
}
public State getState() {
return state;
}
public String name() {
return this.name;
}
}