[
https://issues.apache.org/jira/browse/SOLR-665?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12617639#action_12617639
]
Fuad Efendi commented on SOLR-665:
----------------------------------
This is extremely simple Concurrent LRU, I spent an hour to create it; it is
based on ConcurrentHashMap. I don't use java.util.concurrent.locks, and I am
trying to focus on _requirements only_ avoiding implementing unnecessary
methods of Map interface (so that I am not following _contract_ ;) very sorry!)
{code}
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class ConcurrentLRU<K, V> {
protected ConcurrentHashMap<K, ValueWrapper<V>> map;
protected int maxEntries;
public ConcurrentLRU(int maxEntries) {
map = new ConcurrentHashMap<K, ValueWrapper<V>>();
this.maxEntries = maxEntries;
}
public V put(K key, V value) {
ValueWrapper<V> wrapper = map.put(key, new
ValueWrapper<V>(value));
checkRemove();
return value;
}
void checkRemove() {
if (map.size() <= maxEntries)
return;
Map.Entry<K, ValueWrapper<V>> eldestEntry = null;
long eldestAge = Long.MAX_VALUE;
for (Map.Entry<K, ValueWrapper<V>> entry : map.entrySet()) {
long popularity = entry.getValue().popularity;
if (eldestEntry == null ||
eldestEntry.getValue().popularity > popularity) {
eldestEntry = entry;
}
}
map.remove(eldestEntry.getKey(), eldestEntry.getValue());
}
public V get(Object key) {
ValueWrapper<V> wrapper = map.get(key);
return wrapper == null ? null : wrapper.getValue();
}
public final static class ValueWrapper<V> {
static volatile long popularityCounter;
volatile long popularity;
V value;
ValueWrapper(V value) {
this.value = value;
popularity = popularityCounter++;
}
public boolean equals(Object o) {
if (!(o instanceof ValueWrapper)) {
return false;
}
return (value == null ? ((ValueWrapper) o).value ==
null : value.equals(((ValueWrapper) o).value));
}
public int hashCode() {
return value.hashCode();
}
public V getValue() {
popularity = popularityCounter++;
return value;
}
}
}
{code}
> FIFO Cache (Unsynchronized): 9x times performance boost
> -------------------------------------------------------
>
> Key: SOLR-665
> URL: https://issues.apache.org/jira/browse/SOLR-665
> Project: Solr
> Issue Type: Improvement
> Affects Versions: 1.3
> Environment: JRockit R27 (Java 6)
> Reporter: Fuad Efendi
> Attachments: FIFOCache.java
>
> Original Estimate: 672h
> Remaining Estimate: 672h
>
> Attached is modified version of LRUCache where
> 1. map = new LinkedHashMap(initialSize, 0.75f, false) - so that
> "reordering"/true (performance bottleneck of LRU) is replaced to
> "insertion-order"/false (so that it became FIFO)
> 2. Almost all (absolutely unneccessary) synchronized statements commented out
> See discussion at
> http://www.nabble.com/LRUCache---synchronized%21--td16439831.html
> Performance metrics (taken from SOLR Admin):
> LRU
> Requests: 7638
> Average Time-Per-Request: 15300
> Average Request-per-Second: 0.06
> FIFO:
> Requests: 3355
> Average Time-Per-Request: 1610
> Average Request-per-Second: 0.11
> Performance increased 9 times which roughly corresponds to a number of CPU in
> a system, http://www.tokenizer.org/ (Shopping Search Engine at Tokenizer.org)
> Current number of documents: 7494689
> name: filterCache
> class: org.apache.solr.search.LRUCache
> version: 1.0
> description: LRU Cache(maxSize=10000000, initialSize=1000)
> stats: lookups : 15966954582
> hits : 16391851546
> hitratio : 0.102
> inserts : 4246120
> evictions : 0
> size : 2668705
> cumulative_lookups : 16415839763
> cumulative_hits : 16411608101
> cumulative_hitratio : 0.99
> cumulative_inserts : 4246246
> cumulative_evictions : 0
> Thanks
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.