diff --git a/source/de/anomic/kelondro/kelondroMScoreCluster.java b/source/de/anomic/kelondro/kelondroMScoreCluster.java index 55649c7d3..16c0d6581 100644 --- a/source/de/anomic/kelondro/kelondroMScoreCluster.java +++ b/source/de/anomic/kelondro/kelondroMScoreCluster.java @@ -138,14 +138,23 @@ public final class kelondroMScoreCluster { addScore(objs, 1); } + public synchronized void decScore(Object[] objs) { + addScore(objs, -1); + } + public synchronized void incScore(Object obj) { addScore(obj, 1); } + public synchronized void decScore(Object obj) { + addScore(obj, -1); + } + public synchronized void setScore(Object obj, int newScore) { if (obj == null) return; //System.out.println("setScore " + obj.getClass().getName()); Long usk = (Long) refkeyDB.remove(obj); // get unique score key, old entry is not needed any more + if (newScore < 0) throw new kelondroOutOfLimitsException(newScore); if (usk == null) { // set new value @@ -182,6 +191,7 @@ public final class kelondroMScoreCluster { if (usk == null) { // set new value + if (incrementScore < 0) throw new kelondroOutOfLimitsException(incrementScore); usk = new Long(scoreKey(encnt++, incrementScore)); // put new value into cluster @@ -198,7 +208,9 @@ public final class kelondroMScoreCluster { int oldHandle = (int) (c & 0xFFFFFFFFL); // set new value - usk = new Long(scoreKey(oldHandle, oldScore + incrementScore)); // generates an unique key for a specific score + int newValue = oldScore + incrementScore; + if (newValue < 0) throw new kelondroOutOfLimitsException(newValue); + usk = new Long(scoreKey(oldHandle, newValue)); // generates an unique key for a specific score refkeyDB.put(obj, usk); keyrefDB.put(usk, obj); diff --git a/source/de/anomic/kelondro/kelondroOutOfLimitsException.java b/source/de/anomic/kelondro/kelondroOutOfLimitsException.java index 69918d78f..82aabae84 100644 --- a/source/de/anomic/kelondro/kelondroOutOfLimitsException.java +++ b/source/de/anomic/kelondro/kelondroOutOfLimitsException.java @@ -53,4 +53,8 @@ public class kelondroOutOfLimitsException extends java.lang.RuntimeException { super("Object size is " + actualSize + "; it exceeds the size limit " + expectedLimit); } + public kelondroOutOfLimitsException(int actualSize) { + super("Object size is " + actualSize + "; must not be negative"); + } + } diff --git a/source/de/anomic/plasma/plasmaWordIndexCache.java b/source/de/anomic/plasma/plasmaWordIndexCache.java index bda1e8d71..96bf7fbd4 100644 --- a/source/de/anomic/plasma/plasmaWordIndexCache.java +++ b/source/de/anomic/plasma/plasmaWordIndexCache.java @@ -207,14 +207,17 @@ public final class plasmaWordIndexCache implements plasmaWordIndexInterface { // cache settings public int maxURLinWordCache() { + if (hashScore.size() == 0) return 0; return hashScore.getMaxScore(); } public long minAgeOfWordCache() { + if (hashDate.size() == 0) return 0; return System.currentTimeMillis() - longEmit(hashDate.getMaxScore()); } public long maxAgeOfWordCache() { + if (hashDate.size() == 0) return 0; return System.currentTimeMillis() - longEmit(hashDate.getMinScore()); } @@ -345,25 +348,28 @@ public final class plasmaWordIndexCache implements plasmaWordIndexInterface { return count; } - public synchronized int tryRemoveURLs(String urlHash) { + public int tryRemoveURLs(String urlHash) { // this tries to delete an index from the cache that has this // urlHash assigned. This can only work if the entry is really fresh // Such entries must be searched in the latest entries - Iterator i = hashDate.scores(false); - String wordHash; - long t; - plasmaWordIndexEntryContainer c; int delCount = 0; - while (i.hasNext()) { - wordHash = (String) i.next(); - // check time - t = longEmit(hashDate.getScore(wordHash)); - if (System.currentTimeMillis() - t > ramCacheMinAge) return delCount; - // get container - c = (plasmaWordIndexEntryContainer) cache.get(wordHash); - if (c.remove(urlHash) != null) { - cache.put(wordHash, c); - delCount++; + synchronized (cache) { + Iterator i = hashDate.scores(false); + String wordHash; + long t; + plasmaWordIndexEntryContainer c; + while (i.hasNext()) { + wordHash = (String) i.next(); + // check time + t = longEmit(hashDate.getScore(wordHash)); + if (System.currentTimeMillis() - t > ramCacheMinAge) return delCount; + // get container + c = (plasmaWordIndexEntryContainer) cache.get(wordHash); + if (c.remove(urlHash) != null) { + cache.put(wordHash, c); + hashScore.decScore(wordHash); + delCount++; + } } } return delCount;