You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@zookeeper.apache.org by si...@apache.org on 2012/06/06 18:13:56 UTC
svn commit: r1346966 - in /zookeeper/bookkeeper/trunk: CHANGES.txt
bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/LedgerCacheImpl.java
bookkeeper-server/src/test/java/org/apache/bookkeeper/bookie/LedgerCacheTest.java
Author: sijie
Date: Wed Jun 6 16:13:56 2012
New Revision: 1346966
URL: http://svn.apache.org/viewvc?rev=1346966&view=rev
Log:
BOOKKEEPER-287: NoSuchElementException in LedgerCacheImpl (sijie)
Modified:
zookeeper/bookkeeper/trunk/CHANGES.txt
zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/LedgerCacheImpl.java
zookeeper/bookkeeper/trunk/bookkeeper-server/src/test/java/org/apache/bookkeeper/bookie/LedgerCacheTest.java
Modified: zookeeper/bookkeeper/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/zookeeper/bookkeeper/trunk/CHANGES.txt?rev=1346966&r1=1346965&r2=1346966&view=diff
==============================================================================
--- zookeeper/bookkeeper/trunk/CHANGES.txt (original)
+++ zookeeper/bookkeeper/trunk/CHANGES.txt Wed Jun 6 16:13:56 2012
@@ -140,6 +140,8 @@ Release 4.1.0 - 2012-05-31
BOOKKEEPER-286: Compilation warning (ivank via sijie)
+ BOOKKEEPER-287: NoSuchElementException in LedgerCacheImpl (sijie)
+
hedwig-client/
BOOKKEEPER-217: NPE in hedwig client when enable DEBUG (sijie via ivank)
Modified: zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/LedgerCacheImpl.java
URL: http://svn.apache.org/viewvc/zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/LedgerCacheImpl.java?rev=1346966&r1=1346965&r2=1346966&view=diff
==============================================================================
--- zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/LedgerCacheImpl.java (original)
+++ zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/LedgerCacheImpl.java Wed Jun 6 16:13:56 2012
@@ -176,7 +176,7 @@ public class LedgerCacheImpl implements
}
} catch (IOException ie) {
// if we grab a clean page, but failed to update the page
- // we are exhuasting the count of ledger entry pages.
+ // we are exhausting the count of ledger entry pages.
// since this page will be never used, so we need to decrement
// page count of ledger cache.
lep.releasePage();
@@ -317,7 +317,7 @@ public class LedgerCacheImpl implements
if (!doAll) {
break;
}
- // Yeild. if we are doing all the ledgers we don't want to block other flushes that
+ // Yield. if we are doing all the ledgers we don't want to block other flushes that
// need to happen
try {
dirtyLedgers.wait(1);
@@ -449,22 +449,22 @@ public class LedgerCacheImpl implements
if (entry % entriesPerPage != 0) {
throw new IllegalArgumentException(entry + " is not a multiple of " + entriesPerPage);
}
- synchronized(this) {
- if (pageCount < pageLimit) {
- // let's see if we can allocate something
- LedgerEntryPage lep = new LedgerEntryPage(pageSize, entriesPerPage);
- lep.setLedger(ledger);
- lep.setFirstEntry(entry);
-
- // note, this will not block since it is a new page
- lep.usePage();
- pageCount++;
- return lep;
- }
- }
-
outerLoop:
while(true) {
+ synchronized(this) {
+ if (pageCount < pageLimit) {
+ // let's see if we can allocate something
+ LedgerEntryPage lep = new LedgerEntryPage(pageSize, entriesPerPage);
+ lep.setLedger(ledger);
+ lep.setFirstEntry(entry);
+
+ // note, this will not block since it is a new page
+ lep.usePage();
+ pageCount++;
+ return lep;
+ }
+ }
+
synchronized(cleanLedgers) {
if (cleanLedgers.isEmpty()) {
flushLedger(false);
@@ -475,6 +475,14 @@ public class LedgerCacheImpl implements
}
}
synchronized(this) {
+ // if ledgers deleted between checking pageCount and putting
+ // ledgers into cleanLedgers list, the cleanLedgers list would be empty.
+ // so give it a chance to go back to check pageCount again because
+ // deleteLedger would decrement pageCount to return the number of pages
+ // occupied by deleted ledgers.
+ if (cleanLedgers.isEmpty()) {
+ continue outerLoop;
+ }
Long cleanLedger = cleanLedgers.getFirst();
Map<Long, LedgerEntryPage> map = pages.get(cleanLedger);
while (map == null || map.isEmpty()) {
@@ -610,7 +618,13 @@ public class LedgerCacheImpl implements
// remove pages first to avoid page flushed when deleting file info
synchronized(this) {
- pages.remove(ledgerId);
+ Map<Long, LedgerEntryPage> lpages = pages.remove(ledgerId);
+ if (null != lpages) {
+ pageCount -= lpages.size();
+ if (pageCount < 0) {
+ LOG.error("Page count of ledger cache has been decremented to be less than zero.");
+ }
+ }
}
// Delete the ledger's index file and close the FileInfo
FileInfo fi = null;
Modified: zookeeper/bookkeeper/trunk/bookkeeper-server/src/test/java/org/apache/bookkeeper/bookie/LedgerCacheTest.java
URL: http://svn.apache.org/viewvc/zookeeper/bookkeeper/trunk/bookkeeper-server/src/test/java/org/apache/bookkeeper/bookie/LedgerCacheTest.java?rev=1346966&r1=1346965&r2=1346966&view=diff
==============================================================================
--- zookeeper/bookkeeper/trunk/bookkeeper-server/src/test/java/org/apache/bookkeeper/bookie/LedgerCacheTest.java (original)
+++ zookeeper/bookkeeper/trunk/bookkeeper-server/src/test/java/org/apache/bookkeeper/bookie/LedgerCacheTest.java Wed Jun 6 16:13:56 2012
@@ -126,6 +126,41 @@ public class LedgerCacheTest extends Tes
}
@Test
+ public void testDeleteLedger() throws Exception {
+ int numEntries = 10;
+ // limit open files & pages
+ conf.setOpenFileLimit(999).setPageLimit(2)
+ .setPageSize(8 * numEntries);
+ // create ledger cache
+ newLedgerCache();
+ try {
+ int numLedgers = 2;
+ byte[] masterKey = "blah".getBytes();
+ for (int i=1; i<=numLedgers; i++) {
+ ledgerCache.setMasterKey((long)i, masterKey);
+ for (int j=0; j<numEntries; j++) {
+ ledgerCache.putEntryOffset(i, j, i*numEntries + j);
+ }
+ }
+ // ledger cache is exhausted
+ // delete ledgers
+ for (int i=1; i<=numLedgers; i++) {
+ ledgerCache.deleteLedger((long)i);
+ }
+ // create num ledgers to add entries
+ for (int i=numLedgers+1; i<=2*numLedgers; i++) {
+ ledgerCache.setMasterKey((long)i, masterKey);
+ for (int j=0; j<numEntries; j++) {
+ ledgerCache.putEntryOffset(i, j, i*numEntries + j);
+ }
+ }
+ } catch (Exception e) {
+ LOG.error("Got Exception.", e);
+ fail("Failed to add entry.");
+ }
+ }
+
+ @Test
public void testPageEviction() throws Exception {
int numLedgers = 10;
byte[] masterKey = "blah".getBytes();