Merge changes Ibb3467f7,I2af99903

* changes:
  Always use try/finally around DfsBlockCache.clockLock
  DfsBlockCache: Fix NPE when evicting empty cell
This commit is contained in:
Robin Rosenberg 2011-11-10 02:07:04 -05:00 committed by Code Review
commit c0392381ee
1 changed files with 42 additions and 36 deletions

View File

@ -206,7 +206,7 @@ else if (eb < 4)
blockSizeShift = Integer.numberOfTrailingZeros(blockSize); blockSizeShift = Integer.numberOfTrailingZeros(blockSize);
clockLock = new ReentrantLock(true /* fair */); clockLock = new ReentrantLock(true /* fair */);
clockHand = new Ref<Object>(null, -1, 0, null); clockHand = new Ref<Object>(new DfsPackKey(), -1, 0, null);
clockHand.next = clockHand; clockHand.next = clockHand;
readAheadLimit = cfg.getReadAheadLimit(); readAheadLimit = cfg.getReadAheadLimit();
@ -389,36 +389,39 @@ DfsBlock getOrLoad(DfsPackFile pack, long position, DfsReader ctx)
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private void reserveSpace(int reserve) { private void reserveSpace(int reserve) {
clockLock.lock(); clockLock.lock();
long live = liveBytes + reserve; try {
if (maxBytes < live) { long live = liveBytes + reserve;
Ref prev = clockHand; if (maxBytes < live) {
Ref hand = clockHand.next; Ref prev = clockHand;
do { Ref hand = clockHand.next;
if (hand.hot) { do {
// Value was recently touched. Clear if (hand.hot) {
// hot and give it another chance. // Value was recently touched. Clear
hand.hot = false; // hot and give it another chance.
prev = hand; hand.hot = false;
hand = hand.next; prev = hand;
continue; hand = hand.next;
} else if (prev == hand) continue;
break; } else if (prev == hand)
break;
// No recent access since last scan, kill // No recent access since last scan, kill
// value and remove from clock. // value and remove from clock.
Ref dead = hand; Ref dead = hand;
hand = hand.next; hand = hand.next;
prev.next = hand; prev.next = hand;
dead.next = null; dead.next = null;
dead.value = null; dead.value = null;
live -= dead.size; live -= dead.size;
dead.pack.cachedSize.addAndGet(-dead.size); dead.pack.cachedSize.addAndGet(-dead.size);
statEvict++; statEvict++;
} while (maxBytes < live); } while (maxBytes < live);
clockHand = prev; clockHand = prev;
}
liveBytes = live;
} finally {
clockLock.unlock();
} }
liveBytes = live;
clockLock.unlock();
} }
private void creditSpace(int credit) { private void creditSpace(int credit) {
@ -429,13 +432,16 @@ private void creditSpace(int credit) {
private void addToClock(Ref ref, int credit) { private void addToClock(Ref ref, int credit) {
clockLock.lock(); clockLock.lock();
if (credit != 0) try {
liveBytes -= credit; if (credit != 0)
Ref ptr = clockHand; liveBytes -= credit;
ref.next = ptr.next; Ref ptr = clockHand;
ptr.next = ref; ref.next = ptr.next;
clockHand = ref; ptr.next = ref;
clockLock.unlock(); clockHand = ref;
} finally {
clockLock.unlock();
}
} }
void put(DfsBlock v) { void put(DfsBlock v) {