Program: 16097
Project: 16097
Buggy source:
int addRowTry(Row row) throws SQLException {
  index.getPageStore().logUndo(this,data);
  int rowLength=getRowLength(row);
  int pageSize=index.getPageStore().getPageSize();
  int last=entryCount == 0 ? pageSize : offsets[entryCount - 1];
  int keyOffsetPairLen=2 + data.getVarLongLen(row.getKey());
  if (entryCount > 0 && last - rowLength < start + keyOffsetPairLen) {
    int x=find(row.getKey());
    if (entryCount > 1) {
      if (entryCount < 5) {
        return entryCount / 2;
      }
      int third=entryCount / 3;
      return x < third ? third : x >= 2 * third ? 2 * third : x;
    }
    return x;
  }
  index.getPageStore().logUndo(this,data);
  int offset=last - rowLength;
  int[] newOffsets=new int[entryCount + 1];
  long[] newKeys=new long[entryCount + 1];
  Row[] newRows=new Row[entryCount + 1];
  int x;
  if (entryCount == 0) {
    x=0;
  }
 else {
    readAllRows();
    x=find(row.getKey());
    if (x < keys.length && keys[x] == row.getKey()) {
      throw index.getDuplicateKeyException();
    }
    System.arraycopy(offsets,0,newOffsets,0,x);
    System.arraycopy(keys,0,newKeys,0,x);
    System.arraycopy(rows,0,newRows,0,x);
    if (x < entryCount) {
      for (int j=x; j < entryCount; j++) {
        newOffsets[j + 1]=offsets[j] - rowLength;
      }
      System.arraycopy(keys,x,newKeys,x + 1,entryCount - x);
      System.arraycopy(rows,x,newRows,x + 1,entryCount - x);
    }
  }
  written=false;
  last=x == 0 ? pageSize : offsets[x - 1];
  offset=last - rowLength;
  entryCount++;
  start+=keyOffsetPairLen;
  newOffsets[x]=offset;
  newKeys[x]=row.getKey();
  newRows[x]=row;
  memorySize+=row.getMemorySize();
  offsets=newOffsets;
  keys=newKeys;
  rows=newRows;
  index.getPageStore().updateRecord(this);
  if (offset < start) {
    if (entryCount > 1) {
      Message.throwInternalError();
    }
    start+=4;
    int remaining=rowLength - (pageSize - start);
    offset=start;
    offsets[x]=offset;
    int previous=getPos();
    int dataOffset=pageSize;
    int page=index.getPageStore().allocatePage();
    firstOverflowPageId=page;
    this.overflowRowSize=pageSize + rowLength;
    write();
    rowRef=new SoftReference<Row>(rows[0]);
    rows[0]=null;
    Data all=index.getPageStore().createData();
    all.checkCapacity(data.length());
    all.write(data.getBytes(),0,data.length());
    data.truncate(index.getPageStore().getPageSize());
    do {
      int type, size, next;
      if (remaining <= pageSize - PageDataOverflow.START_LAST) {
        type=Page.TYPE_DATA_OVERFLOW | Page.FLAG_LAST;
        size=remaining;
        next=0;
      }
 else {
        type=Page.TYPE_DATA_OVERFLOW;
        size=pageSize - PageDataOverflow.START_MORE;
        next=index.getPageStore().allocatePage();
      }
      PageDataOverflow overflow=PageDataOverflow.create(index.getPageStore(),page,type,previous,next,all,dataOffset,size);
      index.getPageStore().updateRecord(overflow);
      dataOffset+=size;
      remaining-=size;
      previous=page;
      page=next;
    }
 while (remaining > 0);
  }
  return -1;
}

Fixed version (ground truth):
int addRowTry(Row row) throws SQLException {
  index.getPageStore().logUndo(this,data);
  int rowLength=getRowLength(row);
  int pageSize=index.getPageStore().getPageSize();
  int last=entryCount == 0 ? pageSize : offsets[entryCount - 1];
  int keyOffsetPairLen=2 + data.getVarLongLen(row.getKey());
  if (entryCount > 0 && last - rowLength < start + keyOffsetPairLen) {
    int x=find(row.getKey());
    if (entryCount > 1) {
      if (entryCount < 5) {
        return entryCount / 2;
      }
      int third=entryCount / 3;
      return x < third ? third : x >= 2 * third ? 2 * third : x;
    }
    return x;
  }
  index.getPageStore().logUndo(this,data);
  int offset=last - rowLength;
  int[] newOffsets=new int[entryCount + 1];
  long[] newKeys=new long[entryCount + 1];
  Row[] newRows=new Row[entryCount + 1];
  int x;
  if (entryCount == 0) {
    x=0;
  }
 else {
    readAllRows();
    x=find(row.getKey());
    if (x < keys.length && keys[x] == row.getKey()) {
      throw index.getDuplicateKeyException();
    }
    System.arraycopy(offsets,0,newOffsets,0,x);
    System.arraycopy(keys,0,newKeys,0,x);
    System.arraycopy(rows,0,newRows,0,x);
    if (x < entryCount) {
      for (int j=x; j < entryCount; j++) {
        newOffsets[j + 1]=offsets[j] - rowLength;
      }
      System.arraycopy(keys,x,newKeys,x + 1,entryCount - x);
      System.arraycopy(rows,x,newRows,x + 1,entryCount - x);
    }
  }
  written=false;
  last=x == 0 ? pageSize : offsets[x - 1];
  offset=last - rowLength;
  entryCount++;
  start+=keyOffsetPairLen;
  newOffsets[x]=offset;
  newKeys[x]=row.getKey();
  newRows[x]=row;
  memorySize+=row.getMemorySize();
  offsets=newOffsets;
  keys=newKeys;
  rows=newRows;
  index.getPageStore().update(this);
  if (offset < start) {
    if (entryCount > 1) {
      Message.throwInternalError();
    }
    start+=4;
    int remaining=rowLength - (pageSize - start);
    offset=start;
    offsets[x]=offset;
    int previous=getPos();
    int dataOffset=pageSize;
    int page=index.getPageStore().allocatePage();
    firstOverflowPageId=page;
    this.overflowRowSize=pageSize + rowLength;
    write();
    rowRef=new SoftReference<Row>(rows[0]);
    rows[0]=null;
    Data all=index.getPageStore().createData();
    all.checkCapacity(data.length());
    all.write(data.getBytes(),0,data.length());
    data.truncate(index.getPageStore().getPageSize());
    do {
      int type, size, next;
      if (remaining <= pageSize - PageDataOverflow.START_LAST) {
        type=Page.TYPE_DATA_OVERFLOW | Page.FLAG_LAST;
        size=remaining;
        next=0;
      }
 else {
        type=Page.TYPE_DATA_OVERFLOW;
        size=pageSize - PageDataOverflow.START_MORE;
        next=index.getPageStore().allocatePage();
      }
      PageDataOverflow overflow=PageDataOverflow.create(index.getPageStore(),page,type,previous,next,all,dataOffset,size);
      index.getPageStore().update(overflow);
      dataOffset+=size;
      remaining-=size;
      previous=page;
      page=next;
    }
 while (remaining > 0);
  }
  return -1;
}