diff --git a/jps/model/src/org/jetbrains/ether/dependencyView/PersistentMaplet.java b/jps/model/src/org/jetbrains/ether/dependencyView/PersistentMaplet.java index b6fcaa713052..e2aa19570405 100644 --- a/jps/model/src/org/jetbrains/ether/dependencyView/PersistentMaplet.java +++ b/jps/model/src/org/jetbrains/ether/dependencyView/PersistentMaplet.java @@ -15,9 +15,11 @@ */ package org.jetbrains.ether.dependencyView; +import com.intellij.util.containers.SLRUCache; import com.intellij.util.io.DataExternalizer; import com.intellij.util.io.KeyDescriptor; import com.intellij.util.io.PersistentHashMap; +import org.jetbrains.annotations.NotNull; import java.io.File; import java.io.IOException; @@ -33,11 +35,27 @@ import java.util.Map; * To change this template use File | Settings | File Templates. */ public class PersistentMaplet implements Maplet { + private static final Object NULL_OBJ = new Object(); + private static final int CACHE_SIZE = 512; private final PersistentHashMap myMap; + private final SLRUCache myCache; public PersistentMaplet(final File file, final KeyDescriptor k, final DataExternalizer v) { try { myMap = new PersistentHashMap(file, k, v); + myCache = new SLRUCache(CACHE_SIZE, CACHE_SIZE) { + @NotNull + @Override + public Object createValue(K key) { + try { + final V v1 = myMap.get(key); + return v1 == null? NULL_OBJ : v1; + } + catch (IOException e) { + throw new RuntimeException(e); + } + } + }; } catch (IOException e) { throw new RuntimeException(e); @@ -56,17 +74,14 @@ public class PersistentMaplet implements Maplet { @Override public V get(final Object key) { - try { - return myMap.get((K)key); - } - catch (IOException e) { - throw new RuntimeException(e); - } + final Object obj = myCache.get((K)key); + return obj == NULL_OBJ? null : (V)obj; } @Override public void put(final K key, final V value) { try { + myCache.remove(key); myMap.put(key, value); } catch (IOException e) { @@ -76,20 +91,17 @@ public class PersistentMaplet implements Maplet { @Override public void putAll(final Maplet m) { - try { - for (Map.Entry e : m.entrySet()) { - myMap.put(e.getKey(), e.getValue()); - } - } - catch (IOException e) { - throw new RuntimeException(e); + for (Map.Entry e : m.entrySet()) { + put(e.getKey(), e.getValue()); } } @Override public void remove(final Object key) { try { - myMap.remove((K)key); + final K _key = (K)key; + myCache.remove(_key); + myMap.remove(_key); } catch (IOException e) { throw new RuntimeException(e); @@ -99,6 +111,7 @@ public class PersistentMaplet implements Maplet { @Override public void close() { try { + myCache.clear(); myMap.close(); } catch (IOException e) { @@ -133,7 +146,7 @@ public class PersistentMaplet implements Maplet { try { for (final K key : myMap.getAllKeysWithExistingMapping()) { - final V value = myMap.get(key); + final V value = get(key); final Map.Entry entry = new Map.Entry() { @Override diff --git a/jps/model/src/org/jetbrains/ether/dependencyView/PersistentMultiMaplet.java b/jps/model/src/org/jetbrains/ether/dependencyView/PersistentMultiMaplet.java index e5497ab73994..f1a08a736098 100644 --- a/jps/model/src/org/jetbrains/ether/dependencyView/PersistentMultiMaplet.java +++ b/jps/model/src/org/jetbrains/ether/dependencyView/PersistentMultiMaplet.java @@ -15,9 +15,11 @@ */ package org.jetbrains.ether.dependencyView; +import com.intellij.util.containers.SLRUCache; import com.intellij.util.io.DataExternalizer; import com.intellij.util.io.KeyDescriptor; import com.intellij.util.io.PersistentHashMap; +import org.jetbrains.annotations.NotNull; import java.io.*; import java.util.Collection; @@ -33,16 +35,31 @@ import java.util.Map; * To change this template use File | Settings | File Templates. */ class PersistentMultiMaplet implements MultiMaplet { + private static final Collection NULL_COLLECTION = Collections.emptySet(); + private static final int CACHE_SIZE = 512; private final PersistentHashMap> myMap; private final DataExternalizer myValueExternalizer; + private final SLRUCache myCache; public PersistentMultiMaplet(final File file, final KeyDescriptor keyExternalizer, final DataExternalizer valueExternalizer, final TransientMultiMaplet.CollectionConstructor collectionFactory) throws IOException { myValueExternalizer = valueExternalizer; - myMap = new PersistentHashMap>(file, keyExternalizer, - new CollectionDataExternalizer(valueExternalizer, collectionFactory)); + myMap = new PersistentHashMap>(file, keyExternalizer, new CollectionDataExternalizer(valueExternalizer, collectionFactory)); + myCache = new SLRUCache(CACHE_SIZE, CACHE_SIZE) { + @NotNull + @Override + public Collection createValue(K key) { + try { + final Collection collection = myMap.get(key); + return collection == null? NULL_COLLECTION : collection; + } + catch (IOException e) { + throw new RuntimeException(e); + } + } + }; } @@ -58,17 +75,14 @@ class PersistentMultiMaplet implements MultiMaplet { @Override public Collection get(final K key) { - try { - return myMap.get(key); - } - catch (IOException e) { - throw new RuntimeException(e); - } + final Collection collection = myCache.get(key); + return collection == NULL_COLLECTION? null : collection; } @Override public void replace(K key, Collection value) { try { + myCache.remove(key); if (value == null) { myMap.remove(key); } @@ -84,6 +98,7 @@ class PersistentMultiMaplet implements MultiMaplet { @Override public void put(final K key, final Collection value) { try { + myCache.remove(key); myMap.appendData(key, new PersistentHashMap.ValueDataAppender() { public void append(DataOutput out) throws IOException { for (V v : value) { @@ -105,15 +120,16 @@ class PersistentMultiMaplet implements MultiMaplet { @Override public void removeAll(K key, Collection values) { try { - final Collection collection = myMap.get(key); + final Collection collection = myCache.get(key); - if (collection != null) { + if (collection != NULL_COLLECTION) { if (collection.removeAll(values)) { + myCache.remove(key); if (collection.isEmpty()) { myMap.remove(key); } else { - myMap.put(key, collection); + myMap.put(key, (Collection)collection); } } } @@ -126,15 +142,16 @@ class PersistentMultiMaplet implements MultiMaplet { @Override public void removeFrom(final K key, final V value) { try { - final Collection collection = myMap.get(key); + final Collection collection = myCache.get(key); - if (collection != null) { + if (collection != NULL_COLLECTION) { if (collection.remove(value)) { + myCache.remove(key); if (collection.isEmpty()) { myMap.remove(key); } else { - myMap.put(key, collection); + myMap.put(key, (Collection)collection); } } } @@ -147,6 +164,7 @@ class PersistentMultiMaplet implements MultiMaplet { @Override public void remove(final K key) { try { + myCache.remove(key); myMap.remove(key); } catch (IOException e) { @@ -180,6 +198,7 @@ class PersistentMultiMaplet implements MultiMaplet { @Override public void close() { try { + myCache.clear(); myMap.close(); } catch (IOException e) {