private long save() { int currentUnsavedMemory = unsavedMemory; long version = ++currentVersion; long time = getTimeSinceCreation(); lastCommitTime = time; WriteBuffer buff = getWriteBuffer(); BTreeChunk c = new BTreeChunk(++lastChunkId); chunks.put(c.id, c); c.time = time; c.version = version; c.pagePositions = new ArrayList<Long>(); BTreePage p = map.root; if (p.getTotalCount() > 0) { p.writeUnsavedRecursive(c, buff); c.rootPagePos = p.getPos(); p.writeEnd(); } c.pagePositionsOffset = buff.position(); for (long pos : c.pagePositions) buff.putLong(pos); int chunkBodyLength = buff.position(); chunkBodyLength = MathUtils.roundUpInt(chunkBodyLength, BLOCK_SIZE); buff.limit(chunkBodyLength); buff.position(0); c.blockCount = chunkBodyLength / BLOCK_SIZE + CHUNK_HEADER_BLOCKS; // include chunk header(2 blocks). c.fileStorage = getFileStorage(c.id); // chunk header writeChunkHeader(c); // chunk body write(c.fileStorage, CHUNK_HEADER_SIZE, buff.getBuffer()); c.fileStorage.sync(); for (BTreeChunk chunk : chunks.values()) { if (chunk.changed) { writeChunkHeader(chunk); chunk.fileStorage.sync(); chunk.changed = false; } } releaseWriteBuffer(buff); // some pages might have been changed in the meantime (in the newest version) unsavedMemory = Math.max(0, unsavedMemory - currentUnsavedMemory); lastStoredVersion = version - 1; return version; }