|
|
@ -54,35 +54,36 @@ class DeltaBaseCache { |
|
|
|
return (((int) position) << 22) >>> 22; |
|
|
|
return (((int) position) << 22) >>> 22; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private static int maxByteCount; |
|
|
|
private static volatile int defaultMaxByteCount; |
|
|
|
|
|
|
|
|
|
|
|
private static final Slot[] cache; |
|
|
|
private final int maxByteCount; |
|
|
|
|
|
|
|
|
|
|
|
private static Slot lruHead; |
|
|
|
private final Slot[] cache; |
|
|
|
|
|
|
|
|
|
|
|
private static Slot lruTail; |
|
|
|
private Slot lruHead; |
|
|
|
|
|
|
|
|
|
|
|
private static int openByteCount; |
|
|
|
private Slot lruTail; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private int openByteCount; |
|
|
|
|
|
|
|
|
|
|
|
static { |
|
|
|
static { |
|
|
|
DEAD = new SoftReference<Entry>(null); |
|
|
|
DEAD = new SoftReference<Entry>(null); |
|
|
|
maxByteCount = new WindowCacheConfig().getDeltaBaseCacheLimit(); |
|
|
|
reconfigure(new WindowCacheConfig()); |
|
|
|
|
|
|
|
|
|
|
|
cache = new Slot[CACHE_SZ]; |
|
|
|
|
|
|
|
for (int i = 0; i < CACHE_SZ; i++) |
|
|
|
|
|
|
|
cache[i] = new Slot(); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static synchronized void reconfigure(final WindowCacheConfig cfg) { |
|
|
|
static void reconfigure(WindowCacheConfig cfg) { |
|
|
|
final int dbLimit = cfg.getDeltaBaseCacheLimit(); |
|
|
|
defaultMaxByteCount = cfg.getDeltaBaseCacheLimit(); |
|
|
|
if (maxByteCount != dbLimit) { |
|
|
|
|
|
|
|
maxByteCount = dbLimit; |
|
|
|
|
|
|
|
releaseMemory(); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
DeltaBaseCache() { |
|
|
|
|
|
|
|
maxByteCount = defaultMaxByteCount; |
|
|
|
|
|
|
|
cache = new Slot[CACHE_SZ]; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static synchronized Entry get(final PackFile pack, final long position) { |
|
|
|
Entry get(final PackFile pack, final long position) { |
|
|
|
final Slot e = cache[hash(position)]; |
|
|
|
Slot e = cache[hash(position)]; |
|
|
|
|
|
|
|
if (e == null) |
|
|
|
|
|
|
|
return null; |
|
|
|
if (e.provider == pack && e.position == position) { |
|
|
|
if (e.provider == pack && e.position == position) { |
|
|
|
final Entry buf = e.data.get(); |
|
|
|
final Entry buf = e.data.get(); |
|
|
|
if (buf != null) { |
|
|
|
if (buf != null) { |
|
|
@ -93,13 +94,18 @@ class DeltaBaseCache { |
|
|
|
return null; |
|
|
|
return null; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static synchronized void store(final PackFile pack, final long position, |
|
|
|
void store(final PackFile pack, final long position, |
|
|
|
final byte[] data, final int objectType) { |
|
|
|
final byte[] data, final int objectType) { |
|
|
|
if (data.length > maxByteCount) |
|
|
|
if (data.length > maxByteCount) |
|
|
|
return; // Too large to cache.
|
|
|
|
return; // Too large to cache.
|
|
|
|
|
|
|
|
|
|
|
|
final Slot e = cache[hash(position)]; |
|
|
|
Slot e = cache[hash(position)]; |
|
|
|
|
|
|
|
if (e == null) { |
|
|
|
|
|
|
|
e = new Slot(); |
|
|
|
|
|
|
|
cache[hash(position)] = e; |
|
|
|
|
|
|
|
} else { |
|
|
|
clearEntry(e); |
|
|
|
clearEntry(e); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
openByteCount += data.length; |
|
|
|
openByteCount += data.length; |
|
|
|
releaseMemory(); |
|
|
|
releaseMemory(); |
|
|
@ -111,7 +117,7 @@ class DeltaBaseCache { |
|
|
|
moveToHead(e); |
|
|
|
moveToHead(e); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private static void releaseMemory() { |
|
|
|
private void releaseMemory() { |
|
|
|
while (openByteCount > maxByteCount && lruTail != null) { |
|
|
|
while (openByteCount > maxByteCount && lruTail != null) { |
|
|
|
final Slot currOldest = lruTail; |
|
|
|
final Slot currOldest = lruTail; |
|
|
|
final Slot nextOldest = currOldest.lruPrev; |
|
|
|
final Slot nextOldest = currOldest.lruPrev; |
|
|
@ -128,16 +134,7 @@ class DeltaBaseCache { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static synchronized void purge(final PackFile file) { |
|
|
|
private void moveToHead(final Slot e) { |
|
|
|
for (final Slot e : cache) { |
|
|
|
|
|
|
|
if (e.provider == file) { |
|
|
|
|
|
|
|
clearEntry(e); |
|
|
|
|
|
|
|
unlink(e); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static void moveToHead(final Slot e) { |
|
|
|
|
|
|
|
unlink(e); |
|
|
|
unlink(e); |
|
|
|
e.lruPrev = null; |
|
|
|
e.lruPrev = null; |
|
|
|
e.lruNext = lruHead; |
|
|
|
e.lruNext = lruHead; |
|
|
@ -148,7 +145,7 @@ class DeltaBaseCache { |
|
|
|
lruHead = e; |
|
|
|
lruHead = e; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private static void unlink(final Slot e) { |
|
|
|
private void unlink(final Slot e) { |
|
|
|
final Slot prev = e.lruPrev; |
|
|
|
final Slot prev = e.lruPrev; |
|
|
|
final Slot next = e.lruNext; |
|
|
|
final Slot next = e.lruNext; |
|
|
|
if (prev != null) |
|
|
|
if (prev != null) |
|
|
@ -157,17 +154,13 @@ class DeltaBaseCache { |
|
|
|
next.lruPrev = prev; |
|
|
|
next.lruPrev = prev; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private static void clearEntry(final Slot e) { |
|
|
|
private void clearEntry(final Slot e) { |
|
|
|
openByteCount -= e.sz; |
|
|
|
openByteCount -= e.sz; |
|
|
|
e.provider = null; |
|
|
|
e.provider = null; |
|
|
|
e.data = DEAD; |
|
|
|
e.data = DEAD; |
|
|
|
e.sz = 0; |
|
|
|
e.sz = 0; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private DeltaBaseCache() { |
|
|
|
|
|
|
|
throw new UnsupportedOperationException(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static class Entry { |
|
|
|
static class Entry { |
|
|
|
final byte[] data; |
|
|
|
final byte[] data; |
|
|
|
|
|
|
|
|
|
|
|