diff --git a/CHANGES.txt b/CHANGES.txt index a7f4d031874..1fd37f0a36f 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -54,6 +54,10 @@ Bug Fixes to the original ValueSource.getValues(reader) so custom sources will work. (yonik) +* SOLR-1572: FastLRUCache correctly implemented the LRU policy only + for the first 2B accesses. (yonik) + + Other Changes ---------------------- diff --git a/src/common/org/apache/solr/common/util/ConcurrentLRUCache.java b/src/common/org/apache/solr/common/util/ConcurrentLRUCache.java index 1ca39693904..35c0e04eeba 100644 --- a/src/common/org/apache/solr/common/util/ConcurrentLRUCache.java +++ b/src/common/org/apache/solr/common/util/ConcurrentLRUCache.java @@ -106,8 +106,11 @@ public class ConcurrentLRUCache { if (val == null) return null; CacheEntry e = new CacheEntry(key, val, stats.accessCounter.incrementAndGet()); CacheEntry oldCacheEntry = map.put(key, e); + int currentSize; if (oldCacheEntry == null) { - stats.size.incrementAndGet(); + currentSize = stats.size.incrementAndGet(); + } else { + currentSize = stats.size.get(); } if (islive) { stats.putCounter.incrementAndGet(); @@ -125,7 +128,7 @@ public class ConcurrentLRUCache { // // Thread safety note: isCleaning read is piggybacked (comes after) other volatile reads // in this method. - if (stats.size.get() > upperWaterMark && !isCleaning) { + if (currentSize > upperWaterMark && !isCleaning) { if (newThreadForCleanup) { new Thread() { public void run() { @@ -174,7 +177,7 @@ public class ConcurrentLRUCache { int numKept = 0; long newestEntry = timeCurrent; long newNewestEntry = -1; - long newOldestEntry = Integer.MAX_VALUE; + long newOldestEntry = Long.MAX_VALUE; int wantToKeep = lowerWaterMark; int wantToRemove = sz - lowerWaterMark; @@ -222,8 +225,8 @@ public class ConcurrentLRUCache { // over the values we collected, with updated min and max values. while (sz - numRemoved > acceptableWaterMark && --numPasses>=0) { - oldestEntry = newOldestEntry == Integer.MAX_VALUE ? oldestEntry : newOldestEntry; - newOldestEntry = Integer.MAX_VALUE; + oldestEntry = newOldestEntry == Long.MAX_VALUE ? oldestEntry : newOldestEntry; + newOldestEntry = Long.MAX_VALUE; newestEntry = newNewestEntry; newNewestEntry = -1; wantToKeep = lowerWaterMark - numKept; @@ -270,8 +273,8 @@ public class ConcurrentLRUCache { // inserting into a priority queue if (sz - numRemoved > acceptableWaterMark) { - oldestEntry = newOldestEntry == Integer.MAX_VALUE ? oldestEntry : newOldestEntry; - newOldestEntry = Integer.MAX_VALUE; + oldestEntry = newOldestEntry == Long.MAX_VALUE ? oldestEntry : newOldestEntry; + newOldestEntry = Long.MAX_VALUE; newestEntry = newNewestEntry; newNewestEntry = -1; wantToKeep = lowerWaterMark - numKept; @@ -338,7 +341,7 @@ public class ConcurrentLRUCache { // System.out.println("items removed:" + numRemoved + " numKept=" + numKept + " initialQueueSize="+ wantToRemove + " finalQueueSize=" + queue.size() + " sz-numRemoved=" + (sz-numRemoved)); } - oldestEntry = newOldestEntry == Integer.MAX_VALUE ? oldestEntry : newOldestEntry; + oldestEntry = newOldestEntry == Long.MAX_VALUE ? oldestEntry : newOldestEntry; this.oldestEntry = oldestEntry; } finally { isCleaning = false; // set before markAndSweep.unlock() for visibility