Merge "Make DeltaBaseCache per-ObjectReader"

This commit is contained in:
Chris Aniszczyk 2011-04-02 13:35:54 -04:00 committed by Code Review
commit 7b3a6ef530
3 changed files with 43 additions and 42 deletions

View File

@ -54,35 +54,36 @@ private static int hash(final long position) {
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());
}
static void reconfigure(WindowCacheConfig cfg) {
defaultMaxByteCount = cfg.getDeltaBaseCacheLimit();
}
DeltaBaseCache() {
maxByteCount = defaultMaxByteCount;
cache = new Slot[CACHE_SZ]; cache = new Slot[CACHE_SZ];
for (int i = 0; i < CACHE_SZ; i++)
cache[i] = new Slot();
} }
static synchronized void reconfigure(final WindowCacheConfig cfg) { Entry get(final PackFile pack, final long position) {
final int dbLimit = cfg.getDeltaBaseCacheLimit(); Slot e = cache[hash(position)];
if (maxByteCount != dbLimit) { if (e == null)
maxByteCount = dbLimit; return null;
releaseMemory();
}
}
static synchronized Entry get(final PackFile pack, final long position) {
final Slot e = cache[hash(position)];
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 @@ static synchronized Entry get(final PackFile pack, final long position) {
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)];
clearEntry(e); if (e == null) {
e = new Slot();
cache[hash(position)] = e;
} else {
clearEntry(e);
}
openByteCount += data.length; openByteCount += data.length;
releaseMemory(); releaseMemory();
@ -111,7 +117,7 @@ static synchronized void store(final PackFile pack, final long position,
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 @@ private static void releaseMemory() {
} }
} }
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 @@ private static void moveToHead(final Slot e) {
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 @@ private static void unlink(final Slot e) {
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;

View File

@ -236,7 +236,6 @@ void resolve(Set<ObjectId> matches, AbbreviatedObjectId id, int matchLimit)
* Close the resources utilized by this repository * Close the resources utilized by this repository
*/ */
public void close() { public void close() {
DeltaBaseCache.purge(this);
WindowCache.purge(this); WindowCache.purge(this);
synchronized (this) { synchronized (this) {
loadedIdx = null; loadedIdx = null;
@ -723,7 +722,7 @@ ObjectLoader load(final WindowCursor curs, long pos)
if (sz != delta.deltaSize) if (sz != delta.deltaSize)
break SEARCH; break SEARCH;
DeltaBaseCache.Entry e = DeltaBaseCache.get(this, base); DeltaBaseCache.Entry e = curs.getDeltaBaseCache().get(this, base);
if (e != null) { if (e != null) {
type = e.type; type = e.type;
data = e.data; data = e.data;
@ -741,7 +740,7 @@ ObjectLoader load(final WindowCursor curs, long pos)
if (sz != delta.deltaSize) if (sz != delta.deltaSize)
break SEARCH; break SEARCH;
DeltaBaseCache.Entry e = DeltaBaseCache.get(this, base); DeltaBaseCache.Entry e = curs.getDeltaBaseCache().get(this, base);
if (e != null) { if (e != null) {
type = e.type; type = e.type;
data = e.data; data = e.data;
@ -769,7 +768,7 @@ ObjectLoader load(final WindowCursor curs, long pos)
if (cached) if (cached)
cached = false; cached = false;
else if (delta.next == null) else if (delta.next == null)
DeltaBaseCache.store(this, delta.basePos, data, type); curs.getDeltaBaseCache().store(this, delta.basePos, data, type);
pos = delta.deltaPos; pos = delta.deltaPos;

View File

@ -83,12 +83,20 @@ final class WindowCursor extends ObjectReader implements ObjectReuseAsIs {
private ByteWindow window; private ByteWindow window;
private DeltaBaseCache baseCache;
final FileObjectDatabase db; final FileObjectDatabase db;
WindowCursor(FileObjectDatabase db) { WindowCursor(FileObjectDatabase db) {
this.db = db; this.db = db;
} }
DeltaBaseCache getDeltaBaseCache() {
if (baseCache == null)
baseCache = new DeltaBaseCache();
return baseCache;
}
@Override @Override
public ObjectReader newReader() { public ObjectReader newReader() {
return new WindowCursor(db); return new WindowCursor(db);
@ -334,6 +342,7 @@ int getStreamFileThreshold() {
/** Release the current window cursor. */ /** Release the current window cursor. */
public void release() { public void release() {
window = null; window = null;
baseCache = null;
try { try {
InflaterCache.release(inf); InflaterCache.release(inf);
} finally { } finally {