* ByteCache:

- Remove some locks with concurrent
This commit is contained in:
zzz
2010-03-08 21:32:14 +00:00
parent e70793c3bc
commit 9b05d8e774

View File

@@ -1,10 +1,10 @@
package net.i2p.util; package net.i2p.util;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue;
import net.i2p.I2PAppContext; import net.i2p.I2PAppContext;
import net.i2p.data.ByteArray; import net.i2p.data.ByteArray;
@@ -36,12 +36,12 @@ public final class ByteCache {
} }
private Log _log; private Log _log;
/** list of available and available entries */ /** list of available and available entries */
private final List _available; private Queue<ByteArray> _available;
private int _maxCached; private int _maxCached;
private int _entrySize; private int _entrySize;
private long _lastOverflow; private long _lastOverflow;
/** do we actually want to cache? */ /** do we actually want to cache? Warning - setting to false may NPE, this should be fixed or removed */
private static final boolean _cache = true; private static final boolean _cache = true;
/** how often do we cleanup the cache */ /** how often do we cleanup the cache */
@@ -51,7 +51,7 @@ public final class ByteCache {
private ByteCache(int maxCachedEntries, int entrySize) { private ByteCache(int maxCachedEntries, int entrySize) {
if (_cache) if (_cache)
_available = new ArrayList(maxCachedEntries); _available = new LinkedBlockingQueue(maxCachedEntries);
_maxCached = maxCachedEntries; _maxCached = maxCachedEntries;
_entrySize = entrySize; _entrySize = entrySize;
_lastOverflow = -1; _lastOverflow = -1;
@@ -62,6 +62,12 @@ public final class ByteCache {
private void resize(int maxCachedEntries) { private void resize(int maxCachedEntries) {
if (_maxCached >= maxCachedEntries) return; if (_maxCached >= maxCachedEntries) return;
_maxCached = maxCachedEntries; _maxCached = maxCachedEntries;
// make a bigger one, move the cached items over
Queue newLBQ = new LinkedBlockingQueue(maxCachedEntries);
ByteArray ba;
while ((ba = _available.poll()) != null)
newLBQ.offer(ba);
_available = newLBQ;
} }
/** /**
@@ -70,10 +76,9 @@ public final class ByteCache {
*/ */
public final ByteArray acquire() { public final ByteArray acquire() {
if (_cache) { if (_cache) {
synchronized (_available) { ByteArray rv = _available.poll();
if (_available.size() > 0) if (rv != null)
return (ByteArray)_available.remove(0); return rv;
}
} }
_lastOverflow = System.currentTimeMillis(); _lastOverflow = System.currentTimeMillis();
byte data[] = new byte[_entrySize]; byte data[] = new byte[_entrySize];
@@ -100,10 +105,7 @@ public final class ByteCache {
if (shouldZero) if (shouldZero)
Arrays.fill(entry.getData(), (byte)0x0); Arrays.fill(entry.getData(), (byte)0x0);
synchronized (_available) { _available.offer(entry);
if (_available.size() < _maxCached)
_available.add(entry);
}
} }
} }
@@ -112,13 +114,11 @@ public final class ByteCache {
if (System.currentTimeMillis() - _lastOverflow > EXPIRE_PERIOD) { if (System.currentTimeMillis() - _lastOverflow > EXPIRE_PERIOD) {
// we haven't exceeded the cache size in a few minutes, so lets // we haven't exceeded the cache size in a few minutes, so lets
// shrink the cache // shrink the cache
synchronized (_available) {
int toRemove = _available.size() / 2; int toRemove = _available.size() / 2;
for (int i = 0; i < toRemove; i++) for (int i = 0; i < toRemove; i++)
_available.remove(0); _available.poll();
if ( (toRemove > 0) && (_log.shouldLog(Log.DEBUG)) ) if ( (toRemove > 0) && (_log.shouldLog(Log.DEBUG)) )
_log.debug("Removing " + toRemove + " cached entries of size " + _entrySize); _log.debug("Removing " + toRemove + " cached entries of size " + _entrySize);
}
} }
} }
} }