synchronized void packDatabase(TaskMonitor monitor) throws CancelledException, IOException {

		if (isReadOnly || dbHandle == null || bfMgr == null || bfMgr.getCurrentVersion() == 0 ||
			!updateLock.haveLock()) {
			throw new IOException("Update not allowed");
		}
		if (monitor == null) {
			monitor = TaskMonitor.DUMMY;
		}
		monitor.setMessage("Waiting...");
		if (packedDbLock != null) {
			lock(packedDbLock, true, true);
		}
		try {
			File packedFile = packedDbFile.getFile(false); // if not read-only packedDbFile must be a file
			File dbFile = bfMgr.getBufferFile(bfMgr.getCurrentVersion());
			File parentFile = packedFile.getAbsoluteFile().getParentFile();
			File tmpFile = File.createTempFile(TEMPDB_PREFIX, TEMPDB_EXT, parentFile);
			Msg.debug(PackedDatabase.class, "Packing database " + dbFile + " -> " + packedFile);
			packDatabase(itemName, contentType, dbFile, tmpFile, monitor);

			File bakFile = new File(parentFile, packedFile.getName() + ".bak");
			bakFile.delete();

			long oldTime = packedFile.lastModified();

			packedFile.renameTo(bakFile);
			if (!tmpFile.renameTo(packedFile)) {
				bakFile.renameTo(packedFile);
				throw new IOException("Update failed for " + packedFile);
			}

			bakFile.delete();
			dbTime = packedFile.lastModified();

			if (oldTime == dbTime) {
				// ensure that last-modified time on file changes
				dbTime += 1000;
				packedFile.setLastModified(dbTime);
			}

			if (isCached) {
				try {
					PackedDatabaseCache.getCache().updateLastModified(packedDbFile, dbTime);
				}
				catch (IOException e) {
					Msg.warn(this, "cache update failed: " + e.getMessage());
				}
			}
		}
		finally {
			if (packedDbLock != null) {
				packedDbLock.removeLock();
			}
		}
	}
Using the temporary unpacked database, update the packed storage file
using the latest buffer file version.
@param monitor pack monitor
@throws CancelledException if pack is cancelled
@throws IOException if IO error occurs
Ghidra/Framework/FileSystem/src/main/java/ghidra/framework/store/db/PackedDatabase.java