Program: 132314
Project: 132314
Buggy source:
public void testLogIterator() throws Exception {
  final int numLogFiles=3;
  for (int k=0; k < numLogFiles; k++) {
    final AtomicInteger count=new AtomicInteger(0);
    SyncListener sl=new SyncListener(){
      public void synced(      LogEntry entry){
synchronized (entry) {
          count.incrementAndGet();
          entry.notifyAll();
        }
      }
      public void failed(      LogEntry entry,      Exception ex){
synchronized (entry) {
          count.incrementAndGet();
          entry.notifyAll();
        }
      }
    }
;
    LogEntry e=null;
    for (int i=0; i < 100; i++) {
      String pl="String_Node_Str" + (k * 100 + i + 1);
      ReusableBuffer plb=ReusableBuffer.wrap(pl.getBytes());
      e=new LogEntry(plb,sl,LogEntry.PAYLOAD_TYPE_INSERT);
      l.append(e);
    }
synchronized (e) {
      if (count.get() < 100)       e.wait(1000);
    }
    e.free();
    try {
      l.lockLogger();
      LSN lsn=l.switchLogFile(false);
    }
  finally {
      l.unlockLogger();
    }
  }
  File[] logFiles=new File(testdir).listFiles();
  DiskLogIterator it=new DiskLogIterator(logFiles,LSMDatabase.NO_DB_LSN);
  assertTrue(it.hasNext());
  for (int i=1; i <= numLogFiles * 100; i++) {
    LogEntry next=it.next();
    String entry=new String(next.getPayload().array());
    assertEquals("String_Node_Str" + i,entry);
    next.free();
  }
  assertFalse(it.hasNext());
  it.destroy();
  for (int k=0; k < 5; k++) {
    LSN lsn=new LSN(1,(int)(Math.random() * numLogFiles * 100));
    it=new DiskLogIterator(logFiles,lsn);
    assertTrue(it.hasNext());
    for (int i=(int)lsn.getSequenceNo(); i <= numLogFiles * 100; i++) {
      LogEntry next=it.next();
      String entry=new String(next.getPayload().array());
      assertEquals("String_Node_Str" + i,entry);
      next.free();
    }
    assertFalse(it.hasNext());
    it.destroy();
  }
}

Fixed version (ground truth):
public void testLogIterator() throws Exception {
  final int numLogFiles=3;
  for (int k=0; k < numLogFiles; k++) {
    final AtomicInteger count=new AtomicInteger(0);
    SyncListener sl=new SyncListener(){
      public void synced(      LogEntry entry){
synchronized (entry) {
          count.incrementAndGet();
          entry.notifyAll();
        }
      }
      public void failed(      LogEntry entry,      Exception ex){
synchronized (entry) {
          System.err.println(ex);
          count.incrementAndGet();
          entry.notifyAll();
        }
      }
    }
;
    LogEntry e=null;
    for (int i=0; i < 100; i++) {
      String pl="String_Node_Str" + (k * 100 + i + 1);
      ReusableBuffer plb=ReusableBuffer.wrap(pl.getBytes());
      e=new LogEntry(plb,sl,LogEntry.PAYLOAD_TYPE_INSERT);
      l.append(e);
    }
synchronized (e) {
      if (count.get() < 100)       e.wait();
    }
    e.free();
    try {
      l.lockLogger();
      LSN lsn=l.switchLogFile(false);
    }
  finally {
      l.unlockLogger();
    }
  }
  File[] logFiles=new File(testdir).listFiles();
  assertEquals(numLogFiles + 1,logFiles.length);
  DiskLogIterator it=new DiskLogIterator(logFiles,LSMDatabase.NO_DB_LSN);
  assertTrue(it.hasNext());
  for (int i=1; i <= numLogFiles * 100; i++) {
    LogEntry next=it.next();
    String entry=new String(next.getPayload().array());
    assertEquals("String_Node_Str" + i,entry);
    next.free();
  }
  assertFalse(it.hasNext());
  it.destroy();
  for (  int k : new int[]{1,100,101,200,201,300,77,112,189,222}) {
    LSN lsn=new LSN(1,k);
    it=new DiskLogIterator(logFiles,lsn);
    assertTrue(it.hasNext());
    for (int i=(int)lsn.getSequenceNo(); i <= numLogFiles * 100; i++) {
      LogEntry next=it.next();
      String entry=new String(next.getPayload().array());
      assertEquals("String_Node_Str" + i,entry);
      next.free();
    }
    assertFalse(it.hasNext());
    it.destroy();
  }
}