forked from I2P_Developers/i2p.i2p
* ByteCache, ByteArray:
- Cleanups and javadocs - Prevent release of a wrong-sized array
This commit is contained in:
@ -24,11 +24,21 @@ public class ByteArray implements Serializable, Comparable {
|
|||||||
public ByteArray() {
|
public ByteArray() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets valid */
|
/**
|
||||||
|
* Sets valid = data.length, unless data is null
|
||||||
|
* Sets offset = 0
|
||||||
|
* @param data may be null
|
||||||
|
*/
|
||||||
public ByteArray(byte[] data) {
|
public ByteArray(byte[] data) {
|
||||||
_data = data;
|
_data = data;
|
||||||
_valid = (data != null ? data.length : 0);
|
_valid = (data != null ? data.length : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets offset = offset
|
||||||
|
* Sets valid = length
|
||||||
|
* @param data may be null but why would you do that
|
||||||
|
*/
|
||||||
public ByteArray(byte[] data, int offset, int length) {
|
public ByteArray(byte[] data, int offset, int length) {
|
||||||
_data = data;
|
_data = data;
|
||||||
_offset = offset;
|
_offset = offset;
|
||||||
|
@ -16,7 +16,7 @@ import net.i2p.data.ByteArray;
|
|||||||
* For small arrays where the management of valid bytes in ByteArray
|
* For small arrays where the management of valid bytes in ByteArray
|
||||||
* and prezeroing isn't required, use SimpleByteArray instead.
|
* and prezeroing isn't required, use SimpleByteArray instead.
|
||||||
*
|
*
|
||||||
* Heap size control - survey of usage (April 2010) :
|
* Heap size control - survey of usage:
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
Size Max MaxMem From
|
Size Max MaxMem From
|
||||||
@ -34,6 +34,8 @@ import net.i2p.data.ByteArray;
|
|||||||
|
|
||||||
8K 8 64K I2PTunnel HTTPResponseOutputStream
|
8K 8 64K I2PTunnel HTTPResponseOutputStream
|
||||||
|
|
||||||
|
16K 16 256K I2PSnark
|
||||||
|
|
||||||
32K 4 128K SAM StreamSession
|
32K 4 128K SAM StreamSession
|
||||||
32K 10 320K SAM v2StreamSession
|
32K 10 320K SAM v2StreamSession
|
||||||
32K 64 2M UDP OMS
|
32K 64 2M UDP OMS
|
||||||
@ -67,7 +69,10 @@ public final class ByteCache {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a cache responsible for objects of the given size
|
* Get a cache responsible for objects of the given size.
|
||||||
|
* Warning, if you store the result in a static field, the cleaners will
|
||||||
|
* not operate after a restart on Android, as the old context's SimpleScheduler will have shut down.
|
||||||
|
* TODO tie this to the context or clean up all calls.
|
||||||
*
|
*
|
||||||
* @param cacheSize how large we want the cache to grow
|
* @param cacheSize how large we want the cache to grow
|
||||||
* (number of objects, NOT memory size)
|
* (number of objects, NOT memory size)
|
||||||
@ -103,7 +108,7 @@ public final class ByteCache {
|
|||||||
/** list of available and available entries */
|
/** list of available and available entries */
|
||||||
private Queue<ByteArray> _available;
|
private Queue<ByteArray> _available;
|
||||||
private int _maxCached;
|
private int _maxCached;
|
||||||
private int _entrySize;
|
private final int _entrySize;
|
||||||
private long _lastOverflow;
|
private long _lastOverflow;
|
||||||
|
|
||||||
/** do we actually want to cache? Warning - setting to false may NPE, this should be fixed or removed */
|
/** do we actually want to cache? Warning - setting to false may NPE, this should be fixed or removed */
|
||||||
@ -120,7 +125,7 @@ public final class ByteCache {
|
|||||||
_maxCached = maxCachedEntries;
|
_maxCached = maxCachedEntries;
|
||||||
_entrySize = entrySize;
|
_entrySize = entrySize;
|
||||||
_lastOverflow = -1;
|
_lastOverflow = -1;
|
||||||
SimpleScheduler.getInstance().addPeriodicEvent(new Cleanup(), CLEANUP_FREQUENCY + (entrySize % 7)); //stagger
|
SimpleScheduler.getInstance().addPeriodicEvent(new Cleanup(), CLEANUP_FREQUENCY + (entrySize % 777)); //stagger
|
||||||
I2PAppContext.getGlobalContext().statManager().createRateStat("byteCache.memory." + entrySize, "Memory usage (B)", "Router", new long[] { 10*60*1000 });
|
I2PAppContext.getGlobalContext().statManager().createRateStat("byteCache.memory." + entrySize, "Memory usage (B)", "Router", new long[] { 10*60*1000 });
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,8 +141,11 @@ public final class ByteCache {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the next available structure, either from the cache or a brand new one
|
* Get the next available structure, either from the cache or a brand new one.
|
||||||
*
|
* Returned ByteArray will have valid = 0 and offset = 0.
|
||||||
|
* Returned ByteArray may or may not be zero, depends on whether
|
||||||
|
* release(ba) or release(ba, false) was called.
|
||||||
|
* Which is a problem, you should really specify shouldZero on acquire, not release.
|
||||||
*/
|
*/
|
||||||
public final ByteArray acquire() {
|
public final ByteArray acquire() {
|
||||||
if (_cache) {
|
if (_cache) {
|
||||||
@ -149,7 +157,7 @@ public final class ByteCache {
|
|||||||
byte data[] = new byte[_entrySize];
|
byte data[] = new byte[_entrySize];
|
||||||
ByteArray rv = new ByteArray(data);
|
ByteArray rv = new ByteArray(data);
|
||||||
rv.setValid(0);
|
rv.setValid(0);
|
||||||
rv.setOffset(0);
|
//rv.setOffset(0);
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,11 +168,17 @@ public final class ByteCache {
|
|||||||
public final void release(ByteArray entry) {
|
public final void release(ByteArray entry) {
|
||||||
release(entry, true);
|
release(entry, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void release(ByteArray entry, boolean shouldZero) {
|
public final void release(ByteArray entry, boolean shouldZero) {
|
||||||
if (_cache) {
|
if (_cache) {
|
||||||
if ( (entry == null) || (entry.getData() == null) )
|
if (entry == null || entry.getData() == null)
|
||||||
return;
|
return;
|
||||||
|
if (entry.getData().length != _entrySize) {
|
||||||
|
Log log = I2PAppContext.getGlobalContext().logManager().getLog(ByteCache.class);
|
||||||
|
if (log.shouldLog(Log.WARN))
|
||||||
|
log.warn("Bad size", new Exception("I did it"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
entry.setValid(0);
|
entry.setValid(0);
|
||||||
entry.setOffset(0);
|
entry.setOffset(0);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user