diff --git a/source/net/yacy/cora/storage/ComparableARC.java b/source/net/yacy/cora/storage/ComparableARC.java index 8d40d0184..31d1aadf5 100644 --- a/source/net/yacy/cora/storage/ComparableARC.java +++ b/source/net/yacy/cora/storage/ComparableARC.java @@ -22,6 +22,7 @@ package net.yacy.cora.storage; import java.util.Comparator; +import java.util.Iterator; import java.util.LinkedList; import java.util.Map; import java.util.TreeMap; @@ -44,25 +45,57 @@ public final class ComparableARC extends SimpleARC implements Map(); } - public V put(K k, V v) { + public synchronized V put(K k, V v) { V r = super.put(k, v); - keys.add(k); + if (r == null) keys.add(k); if (keys.size() > this.limit) { K w = this.keys.removeFirst(); + assert w != null; V t = super.remove(w); - assert t != null; + assert t != null : "keys.size() = " + keys.size() + ", limit = " + this.limit; } return r; } - public V remove(Object k) { + public void putAll(Map map) { + for (Map.Entry entry: map.entrySet()) put(entry.getKey(), entry.getValue()); + } + public synchronized V remove(Object k) { V r = super.remove(k); - this.keys.remove(k); + if (r == null) return null; + @SuppressWarnings("unchecked") + boolean removed = removeFromKeys((K) k); + assert removed; return r; } - public void clear() { + public synchronized Map.Entry pollFirstEntry() { + Map.Entry entry = super.pollFirstEntry(); + boolean removed = removeFromKeys(entry.getKey()); + assert removed; + return entry; + } + public synchronized Map.Entry pollLastEntry() { + Map.Entry entry = super.pollLastEntry(); + boolean removed = removeFromKeys(entry.getKey()); + assert removed; + return entry; + } + public synchronized void clear() { super.clear(); this.keys.clear(); } + private boolean removeFromKeys(K k) { + assert k != null; + Iterator i = keys.iterator(); + K x; + while (i.hasNext()) { + x = i.next(); + if (super.comparator().compare(k, x) == 0) { + i.remove(); + return true; + } + } + return false; + } } } diff --git a/source/net/yacy/cora/storage/ConcurrentARC.java b/source/net/yacy/cora/storage/ConcurrentARC.java index f8f47f818..bb9b29631 100644 --- a/source/net/yacy/cora/storage/ConcurrentARC.java +++ b/source/net/yacy/cora/storage/ConcurrentARC.java @@ -42,6 +42,11 @@ public final class ConcurrentARC extends AbstractMap implements Map< private final int mask; private final ARC arc[]; + /** + * create a concurrent ARC based on a HashARC. The type of the key elements must implement a hashing function + * @param cacheSize the number of maximum entries + * @param partitions the number of partitions + */ @SuppressWarnings("unchecked") public ConcurrentARC(final int cacheSize, final int partitions) { int m = 1; @@ -52,6 +57,12 @@ public final class ConcurrentARC extends AbstractMap implements Map< this.mask = m; } + /** + * create a concurrent ARC based on a ComparableARC + * @param cacheSize the number of maximum entries + * @param partitions the number of partitions + * @param comparator a comparator for the key object which may be of type byte[] + */ @SuppressWarnings("unchecked") public ConcurrentARC(final int cacheSize, final int partitions, Comparator comparator) { int m = 1; diff --git a/source/net/yacy/kelondro/blob/MapHeap.java b/source/net/yacy/kelondro/blob/MapHeap.java index a2127a83e..fe813e0c5 100644 --- a/source/net/yacy/kelondro/blob/MapHeap.java +++ b/source/net/yacy/kelondro/blob/MapHeap.java @@ -55,7 +55,7 @@ import net.yacy.kelondro.util.kelondroException; public class MapHeap implements Map> { private BLOB blob; - private ARC> cache; + private ARC> cache; private final char fillchar; @@ -67,7 +67,7 @@ public class MapHeap implements Map> { final int cachesize, char fillchar) throws IOException { this.blob = new Heap(heapFile, keylength, ordering, buffermax); - this.cache = new ConcurrentARC>(cachesize, Runtime.getRuntime().availableProcessors()); + this.cache = new ConcurrentARC>(cachesize, Runtime.getRuntime().availableProcessors(), ordering); this.fillchar = fillchar; } @@ -147,7 +147,7 @@ public class MapHeap implements Map> { if (blob != null) blob.insert(key, sb); // write map to cache - if (cache != null) cache.put(new String(key), newMap); + if (cache != null) cache.put(key, newMap); } } @@ -176,7 +176,7 @@ public class MapHeap implements Map> { synchronized (this) { // remove from cache - cache.remove(new String(key)); + cache.remove(key); // remove from file blob.delete(key); @@ -208,7 +208,7 @@ public class MapHeap implements Map> { byte[] key = normalizeKey((byte[]) k); boolean h; synchronized (this) { - h = this.cache.containsKey(new String(key)) || this.blob.containsKey(key); + h = this.cache.containsKey(key) || this.blob.containsKey(key); } return h; } @@ -262,8 +262,7 @@ public class MapHeap implements Map> { Map map; if (storeCache) { synchronized (this) { - String keys = new String(key); - map = cache.get(keys); + map = cache.get(key); if (map != null) return map; // read object @@ -276,7 +275,7 @@ public class MapHeap implements Map> { } // write map to cache - cache.put(keys, map); + cache.put(key, map); } // return value @@ -284,7 +283,7 @@ public class MapHeap implements Map> { } else { byte[] b; synchronized (this) { - map = cache.get(new String(key)); + map = cache.get(key); if (map != null) return map; b = blob.get(key); }