Author: jukka
Date: Wed Sep 29 16:41:48 2010
New Revision: 1002729
URL: http://svn.apache.org/viewvc?rev=1002729&view=rev
Log:
JCR-2699: Improve read/write concurrency
Better handling of the case where more than one entry needs to be removed from an LRU cache.
Modified:
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/util/BundleCache.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/MLRUItemStateCache.java
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/util/BundleCache.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/util/BundleCache.java?rev=1002729&r1=1002728&r2=1002729&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/util/BundleCache.java
(original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/util/BundleCache.java
Wed Sep 29 16:41:48 2010
@@ -16,7 +16,9 @@
*/
package org.apache.jackrabbit.core.persistence.util;
+import java.util.ArrayList;
import java.util.LinkedHashMap;
+import java.util.List;
import java.util.Map;
import org.apache.jackrabbit.core.id.NodeId;
@@ -71,10 +73,14 @@ public class BundleCache {
@Override
protected boolean removeEldestEntry(
Map.Entry<NodeId, NodePropBundle> e) {
- if (curSize > BundleCache.this.maxSize) {
+ long maxSize = BundleCache.this.maxSize;
+ if (curSize <= maxSize) {
+ return false;
+ } else if (curSize - e.getValue().getSize() <= maxSize) {
curSize -= e.getValue().getSize();
return true;
} else {
+ shrink();
return false;
}
}
@@ -97,6 +103,20 @@ public class BundleCache {
*/
public void setMaxSize(long maxSize) {
this.maxSize = maxSize;
+
+ if (curSize > maxSize) {
+ shrink();
+ }
+ }
+
+ private void shrink() {
+ List<NodePropBundle> list =
+ new ArrayList<NodePropBundle>(bundles.values());
+ for (int i = list.size() - 1; curSize > maxSize && i >= 0; i--) {
+ NodePropBundle bundle = list.get(i);
+ curSize -= bundle.getSize();
+ bundles.remove(bundle.getId());
+ }
}
/**
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/MLRUItemStateCache.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/MLRUItemStateCache.java?rev=1002729&r1=1002728&r2=1002729&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/MLRUItemStateCache.java
(original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/MLRUItemStateCache.java
Wed Sep 29 16:41:48 2010
@@ -84,10 +84,14 @@ public class MLRUItemStateCache implemen
maxMem / 1024, 0.75f, true /* access-ordered */) {
@Override
protected boolean removeEldestEntry(Map.Entry<ItemId, Entry> e) {
- if (totalMem > MLRUItemStateCache.this.maxMem) {
+ long maxMem = MLRUItemStateCache.this.maxMem;
+ if (totalMem <= maxMem) {
+ return false;
+ } else if (totalMem - e.getValue().size <= maxMem) {
totalMem -= e.getValue().size;
return true;
} else {
+ shrink();
return false;
}
}
@@ -248,21 +252,21 @@ public class MLRUItemStateCache implemen
// remove items, if too many
if (totalMem > maxMem) {
- totalMem = 0;
- List<Map.Entry<ItemId, Entry>> entries =
- new ArrayList<Map.Entry<ItemId, Entry>>(cache.entrySet());
- for (Map.Entry<ItemId, Entry> entry : entries) {
- long entrySize = entry.getValue().size;
- if (totalMem + entrySize > maxMem) {
- cache.remove(entry.getKey());
- } else {
- totalMem += entrySize;
- }
- }
+ shrink();
}
}
}
+ private void shrink() {
+ List<Map.Entry<ItemId, Entry>> list =
+ new ArrayList<Map.Entry<ItemId, Entry>>(cache.entrySet());
+ for (int i = list.size() - 1; totalMem > maxMem && i >= 0; i--) {
+ Map.Entry<ItemId, Entry> last = list.get(i);
+ totalMem -= last.getValue().size;
+ cache.remove(last.getKey());
+ }
+ }
+
/**
* Set the cache access listener. Only one listener per cache is supported.
*
|