private void addChunksToSaveTransaction( SaveTransactionBuilder saveTransactionBuilder, ChunkProvider chunkProvider) { unloadedAndSavingChunkMap.clear(); /** * New entries might be added concurrently. By using putAll + clear to transfer entries we might * loose new ones added in between putAll and clear. Bz iterating we can make sure that all * entires removed from unloadedAndUnsavedChunkMap get added to unloadedAndSavingChunkMap. */ Iterator<Map.Entry<Vector3i, CompressedChunkBuilder>> unsavedEntryIterator = unloadedAndUnsavedChunkMap.entrySet().iterator(); while (unsavedEntryIterator.hasNext()) { Map.Entry<Vector3i, CompressedChunkBuilder> entry = unsavedEntryIterator.next(); unloadedAndSavingChunkMap.put(entry.getKey(), entry.getValue()); unsavedEntryIterator.remove(); } chunkProvider .getAllChunks() .stream() .filter(ManagedChunk::isReady) .forEach( chunk -> { // If there is a newer undisposed version of the chunk,we don't need to save the // disposed version: unloadedAndSavingChunkMap.remove(chunk.getPosition()); ChunkImpl chunkImpl = (ChunkImpl) chunk; // this storage manager can only work with ChunkImpls saveTransactionBuilder.addLoadedChunk(chunk.getPosition(), chunkImpl); }); for (Map.Entry<Vector3i, CompressedChunkBuilder> entry : unloadedAndSavingChunkMap.entrySet()) { saveTransactionBuilder.addUnloadedChunk(entry.getKey(), entry.getValue()); } }
private boolean isSavingNecessary() { ChunkProvider chunkProvider = CoreRegistry.get(ChunkProvider.class); int unloadedChunkCount = unloadedAndUnsavedChunkMap.size(); int loadedChunkCount = chunkProvider.getAllChunks().size(); double totalChunkCount = unloadedChunkCount + loadedChunkCount; double percentageUnloaded = 100.0 * unloadedChunkCount / totalChunkCount; if (percentageUnloaded >= config.getSystem().getMaxUnloadedChunksPercentageTillSave()) { return true; } long currentTime = System.currentTimeMillis(); if (nextAutoSave == null) { scheduleNextAutoSave(); return false; } return currentTime >= nextAutoSave; }