Program: 15917
Project: 15917
Buggy source:
/** 
 * Store changes. Changes that are marked as temporary are rolled back after a restart.
 * @param temp whether the changes are only temporary (not committed), andshould be rolled back after a crash
 * @return the new version (incremented if there were changes)
 */
private synchronized long store(boolean temp){
  if (closed) {
    return currentVersion;
  }
  if (fileStore == null) {
    return incrementVersion();
  }
  if (currentStoreVersion >= 0) {
    return currentVersion;
  }
  if (!hasUnsavedChanges()) {
    return currentVersion;
  }
  if (fileStore.isReadOnly()) {
    throw DataUtils.newIllegalStateException(DataUtils.ERROR_WRITING_FAILED,"String_Node_Str");
  }
  int currentUnsavedPageCount=unsavedPageCount;
  currentStoreVersion=currentVersion;
  long storeVersion=currentStoreVersion;
  long version=++currentVersion;
  long time=getTime();
  lastStoreTime=time;
  if (temp) {
    meta.put("String_Node_Str",Long.toString(lastCommittedVersion));
    long minVersion=Long.MAX_VALUE;
    Chunk minChunk=null;
    for (    Chunk c : chunks.values()) {
      if (c.version < minVersion) {
        minVersion=c.version;
        minChunk=c;
      }
    }
    retainChunk=minChunk;
  }
 else {
    lastCommittedVersion=version;
    meta.remove("String_Node_Str");
    retainChunk=null;
  }
  Chunk lastChunk=chunks.get(lastChunkId);
  if (lastChunk != null) {
    meta.put("String_Node_Str" + lastChunk.id,lastChunk.asString());
    time=Math.max(lastChunk.time,time);
  }
  Chunk c;
  c=new Chunk(++lastChunkId);
  c.maxLength=Long.MAX_VALUE;
  c.maxLengthLive=Long.MAX_VALUE;
  c.start=Long.MAX_VALUE;
  c.length=Integer.MAX_VALUE;
  c.time=time;
  c.version=version;
  chunks.put(c.id,c);
  meta.put("String_Node_Str" + c.id,c.asString());
  ArrayList<MVMap<?,?>> list=New.arrayList(maps.values());
  ArrayList<MVMap<?,?>> changed=New.arrayList();
  for (  MVMap<?,?> m : list) {
    m.setWriteVersion(version);
    long v=m.getVersion();
    if (v >= 0 && v >= lastStoredVersion) {
      m.waitUntilWritten(storeVersion);
      MVMap<?,?> r=m.openVersion(storeVersion);
      if (r.getRoot().getPos() == 0) {
        changed.add(r);
      }
    }
  }
  for (  MVMap<?,?> m : changed) {
    Page p=m.getRoot();
    if (p.getTotalCount() == 0) {
      meta.put("String_Node_Str" + m.getId(),"String_Node_Str");
    }
 else {
      meta.put("String_Node_Str" + m.getId(),String.valueOf(Integer.MAX_VALUE));
    }
  }
  Set<Chunk> removedChunks=applyFreedSpace(storeVersion,time);
  ByteBuffer buff=getWriteBuffer();
  c.writeHeader(buff);
  c.maxLength=0;
  c.maxLengthLive=0;
  for (  MVMap<?,?> m : changed) {
    Page p=m.getRoot();
    if (p.getTotalCount() > 0) {
      buff=p.writeUnsavedRecursive(c,buff);
      long root=p.getPos();
      meta.put("String_Node_Str" + m.getId(),"String_Node_Str" + root);
    }
  }
  meta.put("String_Node_Str" + c.id,c.asString());
  meta.setWriteVersion(version);
  buff=meta.getRoot().writeUnsavedRecursive(c,buff);
  int chunkLength=buff.position();
  int length=MathUtils.roundUpInt(chunkLength,BLOCK_SIZE) + BLOCK_SIZE;
  if (length > buff.capacity()) {
    buff=DataUtils.ensureCapacity(buff,length - buff.capacity());
  }
  buff.limit(length);
  long end=getEndPosition();
  long filePos;
  if (reuseSpace) {
    filePos=fileStore.allocate(length);
  }
 else {
    filePos=end;
    fileStore.markUsed(end,length);
  }
  boolean storeAtEndOfFile=filePos + length >= end;
  for (  Chunk x : removedChunks) {
    int len=MathUtils.roundUpInt(x.length,BLOCK_SIZE) + BLOCK_SIZE;
    fileStore.free(x.start,len);
  }
  c.start=filePos;
  c.length=chunkLength;
  c.metaRootPos=meta.getRoot().getPos();
  buff.position(0);
  c.writeHeader(buff);
  rootChunkStart=filePos;
  revertTemp(storeVersion);
  buff.position(buff.limit() - BLOCK_SIZE);
  byte[] header=getStoreHeaderBytes();
  buff.put(header);
  buff.put(new byte[BLOCK_SIZE - header.length]);
  buff.position(0);
  fileStore.writeFully(filePos,buff);
  releaseWriteBuffer(buff);
  if (!storeAtEndOfFile) {
    writeStoreHeader();
    shrinkFileIfPossible(1);
  }
  for (  MVMap<?,?> m : changed) {
    Page p=m.getRoot();
    if (p.getTotalCount() > 0) {
      p.writeEnd();
    }
  }
  meta.getRoot().writeEnd();
  unsavedPageCount=Math.max(0,unsavedPageCount - currentUnsavedPageCount);
  currentStoreVersion=-1;
  if (!temp) {
    metaChanged=false;
    lastStoredVersion=storeVersion;
  }
  return version;
}

Fixed version (ground truth):
/** 
 * Store changes. Changes that are marked as temporary are rolled back after a restart.
 * @param temp whether the changes are only temporary (not committed), andshould be rolled back after a crash
 * @return the new version (incremented if there were changes)
 */
private synchronized long store(boolean temp){
  if (closed) {
    return currentVersion;
  }
  if (fileStore == null) {
    return incrementVersion();
  }
  if (currentStoreVersion >= 0) {
    return currentVersion;
  }
  if (!hasUnsavedChanges()) {
    return currentVersion;
  }
  if (fileStore.isReadOnly()) {
    throw DataUtils.newIllegalStateException(DataUtils.ERROR_WRITING_FAILED,"String_Node_Str");
  }
  int currentUnsavedPageCount=unsavedPageCount;
  currentStoreVersion=currentVersion;
  long storeVersion=currentStoreVersion;
  long version=++currentVersion;
  long time=getTime();
  lastStoreTime=time;
  if (temp) {
    meta.put("String_Node_Str",Long.toString(lastCommittedVersion));
    long minVersion=Long.MAX_VALUE;
    Chunk minChunk=null;
    for (    Chunk c : chunks.values()) {
      if (c.version < minVersion) {
        minVersion=c.version;
        minChunk=c;
      }
    }
    retainChunk=minChunk;
  }
 else {
    lastCommittedVersion=version;
    meta.remove("String_Node_Str");
    retainChunk=null;
  }
  Chunk lastChunk=chunks.get(lastChunkId);
  if (lastChunk != null) {
    meta.put("String_Node_Str" + lastChunk.id,lastChunk.asString());
    time=Math.max(lastChunk.time,time);
  }
  Chunk c;
  c=new Chunk(++lastChunkId);
  c.maxLength=Long.MAX_VALUE;
  c.maxLengthLive=Long.MAX_VALUE;
  c.start=Long.MAX_VALUE;
  c.length=Integer.MAX_VALUE;
  c.time=time;
  c.version=version;
  chunks.put(c.id,c);
  meta.put("String_Node_Str" + c.id,c.asString());
  ArrayList<MVMap<?,?>> list=New.arrayList(maps.values());
  ArrayList<MVMap<?,?>> changed=New.arrayList();
  for (  MVMap<?,?> m : list) {
    m.setWriteVersion(version);
    long v=m.getVersion();
    if (v >= 0 && v >= lastStoredVersion) {
      m.waitUntilWritten(storeVersion);
      MVMap<?,?> r=m.openVersion(storeVersion);
      if (r.getRoot().getPos() == 0) {
        changed.add(r);
      }
    }
  }
  for (  MVMap<?,?> m : changed) {
    Page p=m.getRoot();
    if (p.getTotalCount() == 0) {
      meta.put("String_Node_Str" + m.getId(),"String_Node_Str");
    }
 else {
      meta.put("String_Node_Str" + m.getId(),String.valueOf(Integer.MAX_VALUE));
    }
  }
  Set<Chunk> removedChunks=applyFreedSpace(storeVersion,time);
  ByteBuffer buff=getWriteBuffer();
  c.writeHeader(buff);
  c.maxLength=0;
  c.maxLengthLive=0;
  for (  MVMap<?,?> m : changed) {
    Page p=m.getRoot();
    if (p.getTotalCount() > 0) {
      buff=p.writeUnsavedRecursive(c,buff);
      long root=p.getPos();
      meta.put("String_Node_Str" + m.getId(),"String_Node_Str" + root);
    }
  }
  meta.put("String_Node_Str" + c.id,c.asString());
  meta.setWriteVersion(version);
  buff=meta.getRoot().writeUnsavedRecursive(c,buff);
  int chunkLength=buff.position();
  int length=MathUtils.roundUpInt(chunkLength,BLOCK_SIZE) + BLOCK_SIZE;
  if (length > buff.capacity()) {
    buff=DataUtils.ensureCapacity(buff,length - buff.capacity());
  }
  buff.limit(length);
  for (  Chunk x : removedChunks) {
    int len=MathUtils.roundUpInt(x.length,BLOCK_SIZE) + BLOCK_SIZE;
    fileStore.free(x.start,len);
  }
  long end=getEndPosition();
  long filePos;
  if (reuseSpace) {
    filePos=fileStore.allocate(length);
  }
 else {
    filePos=end;
    fileStore.markUsed(end,length);
  }
  boolean storeAtEndOfFile=filePos + length >= end;
  c.start=filePos;
  c.length=chunkLength;
  c.metaRootPos=meta.getRoot().getPos();
  buff.position(0);
  c.writeHeader(buff);
  rootChunkStart=filePos;
  revertTemp(storeVersion);
  buff.position(buff.limit() - BLOCK_SIZE);
  byte[] header=getStoreHeaderBytes();
  buff.put(header);
  buff.put(new byte[BLOCK_SIZE - header.length]);
  buff.position(0);
  fileStore.writeFully(filePos,buff);
  releaseWriteBuffer(buff);
  if (!storeAtEndOfFile) {
    writeStoreHeader();
    shrinkFileIfPossible(1);
  }
  for (  MVMap<?,?> m : changed) {
    Page p=m.getRoot();
    if (p.getTotalCount() > 0) {
      p.writeEnd();
    }
  }
  meta.getRoot().writeEnd();
  unsavedPageCount=Math.max(0,unsavedPageCount - currentUnsavedPageCount);
  currentStoreVersion=-1;
  if (!temp) {
    metaChanged=false;
    lastStoredVersion=storeVersion;
  }
  return version;
}