diff --git a/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/V2/FullDataUpdatePropagatorV2.java b/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/V2/FullDataUpdatePropagatorV2.java index 398fa7634..f34f9eba0 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/V2/FullDataUpdatePropagatorV2.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/V2/FullDataUpdatePropagatorV2.java @@ -227,7 +227,7 @@ public class FullDataUpdatePropagatorV2 implements IDebugRenderable, AutoCloseab parentDataSource.applyToParent = true; } - this.dataUpdater.updateDataSource(parentDataSource, false); + this.dataUpdater.updateDataSource(parentDataSource); } } } @@ -328,7 +328,7 @@ public class FullDataUpdatePropagatorV2 implements IDebugRenderable, AutoCloseab childDataSource.applyToChildren = true; } - this.dataUpdater.updateDataSource(childDataSource, false); + this.dataUpdater.updateDataSource(childDataSource); } } } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/V2/FullDataUpdaterV2.java b/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/V2/FullDataUpdaterV2.java index d82f707bf..4a41b3167 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/V2/FullDataUpdaterV2.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/V2/FullDataUpdaterV2.java @@ -63,7 +63,7 @@ public class FullDataUpdaterV2 implements IDebugRenderable, AutoCloseable /** * Can be used if you don't want to lock the current thread - * Otherwise the sync version {@link FullDataUpdaterV2#updateDataSource(FullDataSourceV2, boolean)} may be a better choice. + * Otherwise the sync version {@link FullDataUpdaterV2#updateDataSource(FullDataSourceV2)} may be a better choice. */ public CompletableFuture updateDataSourceAsync(@NotNull FullDataSourceV2 inputDataSource) { @@ -86,7 +86,7 @@ public class FullDataUpdaterV2 implements IDebugRenderable, AutoCloseable { try { - this.updateDataSource(inputDataSource, true); + this.updateDataSource(inputDataSource); } catch (Exception e) { @@ -107,7 +107,7 @@ public class FullDataUpdaterV2 implements IDebugRenderable, AutoCloseable } /** After this method returns the inputData will be written to file. */ - public void updateDataSource(@NotNull FullDataSourceV2 inputData, boolean lockOnUpdatePos) + public void updateDataSource(@NotNull FullDataSourceV2 inputData) { if (this.isShutdownRef.get()) { @@ -117,25 +117,20 @@ public class FullDataUpdaterV2 implements IDebugRenderable, AutoCloseable long updatePos = inputData.getPos(); - boolean methodLocked = false; // a lock is necessary to prevent two threads from writing to the same position at once, // if that happens only the second update will apply and the LOD will end up with hole(s) ReentrantLock updateLock = this.updateLockProvider.getLock(updatePos); try { - if (lockOnUpdatePos) - { - methodLocked = true; - updateLock.lock(); - this.lockedPosSet.add(updatePos); - } + updateLock.lock(); + this.lockedPosSet.add(updatePos); // get or create the data source try (FullDataSourceV2 recipientDataSource = this.provider.get(updatePos)) { - if (recipientDataSource != null) + if (recipientDataSource != null) // will be null if the repo was shut down { boolean dataModified = recipientDataSource.updateFromDataSource(inputData); if (dataModified) @@ -170,11 +165,8 @@ public class FullDataUpdaterV2 implements IDebugRenderable, AutoCloseable } finally { - if (methodLocked) - { - updateLock.unlock(); - this.lockedPosSet.remove(updatePos); - } + updateLock.unlock(); + this.lockedPosSet.remove(updatePos); } } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/generation/WorldGenerationQueue.java b/core/src/main/java/com/seibel/distanthorizons/core/generation/WorldGenerationQueue.java index a864cea83..f1bc52d26 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/generation/WorldGenerationQueue.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/generation/WorldGenerationQueue.java @@ -210,7 +210,7 @@ public class WorldGenerationQueue implements IFullDataSourceRetrievalQueue, IDeb while (!this.isGeneratorBusy() && taskStarted) { - taskStarted = this.startNextWorldGenTask(this.generationTargetPos); + taskStarted = this.tryStartNextWorldGenTask(this.generationTargetPos); } } catch (Exception e) @@ -240,7 +240,7 @@ public class WorldGenerationQueue implements IFullDataSourceRetrievalQueue, IDeb * @param targetPos the position to center the generation around * @return false if no tasks were found to generate */ - private boolean startNextWorldGenTask(DhBlockPos2D targetPos) + private boolean tryStartNextWorldGenTask(DhBlockPos2D targetPos) { if (this.waitingTasks.isEmpty()) { @@ -249,23 +249,23 @@ public class WorldGenerationQueue implements IFullDataSourceRetrievalQueue, IDeb - Mapper closestTaskMap = this.waitingTasks.reduceEntries(1024, - entry -> new Mapper(entry.getValue(), DhSectionPos.getSectionBBoxPos(entry.getValue().pos).getCenterBlockPos().toPos2D().chebyshevDist(targetPos.toPos2D())), - (aMapper, bMapper) -> aMapper.dist < bMapper.dist ? aMapper : bMapper); + TaskDistancePair closestTaskPair = this.waitingTasks.reduceEntries(1024, + entry -> new TaskDistancePair(entry.getValue(), DhSectionPos.getSectionBBoxPos(entry.getValue().pos).getCenterBlockPos().toPos2D().chebyshevDist(targetPos.toPos2D())), + (TaskDistancePair aTaskPair, TaskDistancePair bTaskPair) -> (aTaskPair.dist < bTaskPair.dist) ? aTaskPair : bTaskPair); - if (closestTaskMap == null) + if (closestTaskPair == null) { // FIXME concurrency issue return false; } - WorldGenTask closestTask = closestTaskMap.task; + WorldGenTask closestTask = closestTaskPair.task; // remove the task we found, we are going to start it and don't want to run it multiple times this.waitingTasks.remove(closestTask.pos, closestTask); // do we need to modify this task to generate it? - if (this.canGeneratePos(closestTask.pos)) + if (this.canGenerateDetailLevel(DhSectionPos.getDetailLevel(closestTask.pos))) { // detail level is correct for generation, start generation @@ -276,11 +276,7 @@ public class WorldGenerationQueue implements IFullDataSourceRetrievalQueue, IDeb { // no task exists for this position, start one InProgressWorldGenTaskGroup newTaskGroup = new InProgressWorldGenTaskGroup(closestTaskGroup); - boolean taskStarted = this.tryStartingWorldGenTaskGroup(newTaskGroup); - if (!taskStarted) - { - //LOGGER.trace("Unable to start task: "+closestTask.pos+", skipping. Task position may have already been generated."); - } + this.startWorldGenTaskGroup(newTaskGroup); } else { @@ -289,7 +285,7 @@ public class WorldGenerationQueue implements IFullDataSourceRetrievalQueue, IDeb // the newly selected task, we cannot use it, // as some chunks may have already been written into. - //LOGGER.trace("A task already exists for this position, todo: "+closestTask.pos); + //LOGGER.warn("A task already exists for this position, todo: "+DhSectionPos.toString(closestTask.pos)); } // a task has been started @@ -321,8 +317,7 @@ public class WorldGenerationQueue implements IFullDataSourceRetrievalQueue, IDeb return true; } } - /** @return true if the task was started, false otherwise */ - private boolean tryStartingWorldGenTaskGroup(InProgressWorldGenTaskGroup newTaskGroup) + private void startWorldGenTaskGroup(InProgressWorldGenTaskGroup newTaskGroup) { byte taskDetailLevel = newTaskGroup.group.dataDetail; long taskPos = newTaskGroup.group.pos; @@ -375,7 +370,6 @@ public class WorldGenerationQueue implements IFullDataSourceRetrievalQueue, IDeb }); this.inProgressGenTasksByLodPos.put(taskPos, newTaskGroup); - return true; } private CompletableFuture startGenerationEvent( long requestPos, @@ -689,9 +683,9 @@ public class WorldGenerationQueue implements IFullDataSourceRetrievalQueue, IDeb // helper methods // //================// - private boolean canGeneratePos(long taskPos) + private boolean canGenerateDetailLevel(byte taskDetailLevel) { - byte requestedDetailLevel = (byte) (DhSectionPos.getDetailLevel(taskPos) - DhSectionPos.SECTION_MINIMUM_DETAIL_LEVEL); + byte requestedDetailLevel = (byte) (taskDetailLevel - DhSectionPos.SECTION_MINIMUM_DETAIL_LEVEL); return (this.highestDataDetail <= requestedDetailLevel && requestedDetailLevel <= this.lowestDataDetail); } @@ -701,11 +695,12 @@ public class WorldGenerationQueue implements IFullDataSourceRetrievalQueue, IDeb // helper classes // //================// - private static class Mapper + private static class TaskDistancePair { public final WorldGenTask task; public final int dist; - public Mapper(WorldGenTask task, int dist) + + public TaskDistancePair(WorldGenTask task, int dist) { this.task = task; this.dist = dist;