private void saveFreeIndexList() throws IOException {

		DataBuffer buf = new DataBuffer(recoveryFile.getBufferSize());
		if (freeListIndex < 0) {
			freeListIndex = vfIndexProvider.allocateIndex();
			buf.setId(freeListIndex);
			buf.putInt(NEXT_BUFFER_INDEX_OFFSET, -1);
			recoveryFile.setParameter(FREE_LIST_BUFFER_INDEX_PARM, freeListIndex);
		}
		else {
			recoveryFile.get(buf, freeListIndex);
		}
		recoveryFile.setParameter(FREE_LIST_SIZE_PARM, freeIndexes.length);

		int maxOffset = (recoveryFile.getBufferSize() - 4) & ~0x03;
		int offset = FIRST_ENTRY_OFFSET;

		// Save freeIndexes entries
		int thisIndex = freeListIndex;
		for (int i = 0; i <= freeIndexes.length; i++) {

			if (offset > maxOffset) {

				boolean newBuf = false;
				int nextIndex = buf.getInt(NEXT_BUFFER_INDEX_OFFSET);
				if (nextIndex < 0) {
					nextIndex = vfIndexProvider.allocateIndex();
					newBuf = true;
				}

				buf.putInt(NEXT_BUFFER_INDEX_OFFSET, nextIndex);
				recoveryFile.put(buf, thisIndex);

				thisIndex = nextIndex;
				if (newBuf) {
					buf.setId(thisIndex);
					buf.putInt(NEXT_BUFFER_INDEX_OFFSET, -1);
				}
				else {
					recoveryFile.get(buf, thisIndex);
				}

				offset = FIRST_ENTRY_OFFSET;
			}

			// Save list entry as single integer
			int val = (i == freeIndexes.length ? -1 : freeIndexes[i]);
			offset = buf.putInt(offset, val);
		}

		// Make sure last buffer is saved
		recoveryFile.put(buf, thisIndex);
	}
Construct a read-only recovery file
@param srcBf the original source buffer file to which this file applies.
@param rfile version buffer file to be updated/created
@throws IOException if the file already exists or an IO error occurs
Ghidra/Framework/DB/src/main/java/db/buffers/RecoveryFile.java