Program: 16147
Project: 16147
Buggy source:
/** 
 * Run one recovery stage. There are three recovery stages: 0: only the undo steps are run (restoring the state before the last checkpoint). 1: the pages that are used by the transaction log are allocated. 2: the committed operations are re-applied.
 * @param stage the recovery stage
 */
void recover(int stage) throws SQLException {
  if (trace.isDebugEnabled()) {
    trace.debug("String_Node_Str" + stage);
  }
  if (stage == RECOVERY_STAGE_ALLOCATE) {
    PageInputStream in=new PageInputStream(store,firstTrunkPage,firstDataPage);
    in.allocateAllPages();
    return;
  }
  pageIn=new PageInputStream(store,firstTrunkPage,firstDataPage);
  in=new DataInputStream(pageIn);
  int logId=0;
  Data data=store.createData();
  try {
    pos=0;
    while (true) {
      int x=in.read();
      if (x < 0) {
        break;
      }
      pos++;
      if (x == UNDO) {
        int pageId=in.readInt();
        in.readFully(data.getBytes(),0,store.getPageSize());
        if (stage == RECOVERY_STAGE_UNDO) {
          if (!undo.get(pageId)) {
            if (trace.isDebugEnabled()) {
              trace.debug("String_Node_Str" + pageId);
            }
            store.writePage(pageId,data);
            undo.set(pageId);
          }
        }
      }
 else       if (x == ADD || x == REMOVE) {
        int sessionId=in.readInt();
        int tableId=in.readInt();
        Row row=readRow(in,data);
        if (stage == RECOVERY_STAGE_UNDO && x == ADD) {
          store.allocateIfHead(pos,tableId,row);
        }
 else         if (stage == RECOVERY_STAGE_REDO) {
          if (isSessionCommitted(sessionId,logId,pos)) {
            if (trace.isDebugEnabled()) {
              trace.debug("String_Node_Str" + (x == ADD ? "String_Node_Str" : "String_Node_Str") + "String_Node_Str"+ tableId+ "String_Node_Str"+ row);
            }
            store.redo(pos,tableId,row,x == ADD);
          }
 else {
            if (trace.isDebugEnabled()) {
              trace.debug("String_Node_Str" + sessionId + "String_Node_Str"+ (x == ADD ? "String_Node_Str" : "String_Node_Str")+ "String_Node_Str"+ tableId+ "String_Node_Str"+ row);
            }
          }
        }
      }
 else       if (x == TRUNCATE) {
        int sessionId=in.readInt();
        int tableId=in.readInt();
        if (stage == RECOVERY_STAGE_REDO) {
          if (isSessionCommitted(sessionId,logId,pos)) {
            if (trace.isDebugEnabled()) {
              trace.debug("String_Node_Str" + tableId);
            }
            store.redoTruncate(tableId);
          }
 else {
            if (trace.isDebugEnabled()) {
              trace.debug("String_Node_Str" + sessionId + "String_Node_Str"+ tableId);
            }
          }
        }
      }
 else       if (x == PREPARE_COMMIT) {
        int sessionId=in.readInt();
        int len=in.readInt();
        byte[] t=new byte[len];
        in.readFully(t);
        String transaction=StringUtils.utf8Decode(t);
        if (trace.isDebugEnabled()) {
          trace.debug("String_Node_Str" + sessionId + "String_Node_Str"+ transaction+ "String_Node_Str"+ pos);
        }
        if (stage == RECOVERY_STAGE_UNDO) {
          int page=pageIn.getDataPage();
          setPrepareCommit(sessionId,page,transaction);
        }
      }
 else       if (x == ROLLBACK) {
        int sessionId=in.readInt();
        if (trace.isDebugEnabled()) {
          trace.debug("String_Node_Str" + sessionId + "String_Node_Str"+ pos);
        }
      }
 else       if (x == COMMIT) {
        int sessionId=in.readInt();
        if (trace.isDebugEnabled()) {
          trace.debug("String_Node_Str" + sessionId + "String_Node_Str"+ pos);
        }
        if (stage == RECOVERY_STAGE_UNDO) {
          setLastCommitForSession(sessionId,logId,pos);
        }
      }
 else       if (x == NOOP) {
      }
 else       if (x == CHECKPOINT) {
        logId++;
      }
 else       if (x == FREE_LOG) {
        int count=in.readInt();
        for (int i=0; i < count; i++) {
          int pageId=in.readInt();
          if (stage == RECOVERY_STAGE_REDO) {
            store.freePage(pageId,false,null);
          }
        }
      }
 else {
        if (trace.isDebugEnabled()) {
          trace.debug("String_Node_Str");
          break;
        }
      }
    }
  }
 catch (  EOFException e) {
    trace.debug("String_Node_Str" + e.toString());
  }
catch (  IOException e) {
    throw Message.convertIOException(e,"String_Node_Str");
  }
  undo=new BitField();
}

Fixed version (ground truth):
/** 
 * Run one recovery stage. There are three recovery stages: 0: only the undo steps are run (restoring the state before the last checkpoint). 1: the pages that are used by the transaction log are allocated. 2: the committed operations are re-applied.
 * @param stage the recovery stage
 */
void recover(int stage) throws SQLException {
  if (trace.isDebugEnabled()) {
    trace.debug("String_Node_Str" + stage);
  }
  if (stage == RECOVERY_STAGE_ALLOCATE) {
    PageInputStream in=new PageInputStream(store,firstTrunkPage,firstDataPage);
    usedLogPages=in.allocateAllPages();
    return;
  }
  pageIn=new PageInputStream(store,firstTrunkPage,firstDataPage);
  in=new DataInputStream(pageIn);
  int logId=0;
  Data data=store.createData();
  try {
    pos=0;
    while (true) {
      int x=in.read();
      if (x < 0) {
        break;
      }
      pos++;
      if (x == UNDO) {
        int pageId=in.readInt();
        in.readFully(data.getBytes(),0,store.getPageSize());
        if (stage == RECOVERY_STAGE_UNDO) {
          if (!undo.get(pageId)) {
            if (trace.isDebugEnabled()) {
              trace.debug("String_Node_Str" + pageId);
            }
            store.writePage(pageId,data);
            undo.set(pageId);
            undoAll.set(pageId);
          }
        }
      }
 else       if (x == ADD || x == REMOVE) {
        int sessionId=in.readInt();
        int tableId=in.readInt();
        Row row=readRow(in,data);
        if (stage == RECOVERY_STAGE_UNDO && x == ADD) {
          store.allocateIfHead(pos,tableId,row);
        }
 else         if (stage == RECOVERY_STAGE_REDO) {
          if (isSessionCommitted(sessionId,logId,pos)) {
            if (trace.isDebugEnabled()) {
              trace.debug("String_Node_Str" + (x == ADD ? "String_Node_Str" : "String_Node_Str") + "String_Node_Str"+ tableId+ "String_Node_Str"+ row);
            }
            store.redo(pos,tableId,row,x == ADD);
          }
 else {
            if (trace.isDebugEnabled()) {
              trace.debug("String_Node_Str" + sessionId + "String_Node_Str"+ (x == ADD ? "String_Node_Str" : "String_Node_Str")+ "String_Node_Str"+ tableId+ "String_Node_Str"+ row);
            }
          }
        }
      }
 else       if (x == TRUNCATE) {
        int sessionId=in.readInt();
        int tableId=in.readInt();
        if (stage == RECOVERY_STAGE_REDO) {
          if (isSessionCommitted(sessionId,logId,pos)) {
            if (trace.isDebugEnabled()) {
              trace.debug("String_Node_Str" + tableId);
            }
            store.redoTruncate(tableId);
          }
 else {
            if (trace.isDebugEnabled()) {
              trace.debug("String_Node_Str" + sessionId + "String_Node_Str"+ tableId);
            }
          }
        }
      }
 else       if (x == PREPARE_COMMIT) {
        int sessionId=in.readInt();
        int len=in.readInt();
        byte[] t=new byte[len];
        in.readFully(t);
        String transaction=StringUtils.utf8Decode(t);
        if (trace.isDebugEnabled()) {
          trace.debug("String_Node_Str" + sessionId + "String_Node_Str"+ transaction+ "String_Node_Str"+ pos);
        }
        if (stage == RECOVERY_STAGE_UNDO) {
          int page=pageIn.getDataPage();
          setPrepareCommit(sessionId,page,transaction);
        }
      }
 else       if (x == ROLLBACK) {
        int sessionId=in.readInt();
        if (trace.isDebugEnabled()) {
          trace.debug("String_Node_Str" + sessionId + "String_Node_Str"+ pos);
        }
      }
 else       if (x == COMMIT) {
        int sessionId=in.readInt();
        if (trace.isDebugEnabled()) {
          trace.debug("String_Node_Str" + sessionId + "String_Node_Str"+ pos);
        }
        if (stage == RECOVERY_STAGE_UNDO) {
          setLastCommitForSession(sessionId,logId,pos);
        }
      }
 else       if (x == NOOP) {
      }
 else       if (x == CHECKPOINT) {
        logId++;
      }
 else       if (x == FREE_LOG) {
        int count=in.readInt();
        for (int i=0; i < count; i++) {
          int pageId=in.readInt();
          if (stage == RECOVERY_STAGE_REDO) {
            if (!usedLogPages.get(pageId)) {
              store.freePage(pageId,false,null);
            }
          }
        }
      }
 else {
        if (trace.isDebugEnabled()) {
          trace.debug("String_Node_Str");
          break;
        }
      }
    }
  }
 catch (  EOFException e) {
    trace.debug("String_Node_Str" + e.toString());
  }
catch (  IOException e) {
    throw Message.convertIOException(e,"String_Node_Str");
  }
  undo=new BitField();
  if (stage == RECOVERY_STAGE_REDO) {
    usedLogPages=null;
  }
}