Prune world gen tasks above limit in multiplayer

This commit is contained in:
s809
2024-12-09 12:03:49 +05:00
parent 2dc9b9a43f
commit 979c3788f1
5 changed files with 53 additions and 45 deletions
@@ -45,6 +45,7 @@ import java.awt.*;
import java.io.File;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;
import java.util.stream.IntStream;
@@ -174,7 +175,8 @@ public class GeneratedFullDataSourceProvider extends FullDataSourceProviderV2 im
}
@Override
public boolean canQueueRetrieval()
public boolean canQueueRetrieval() { return this.canQueueRetrieval(false); }
public boolean canQueueRetrieval(boolean pruneWaitingTasksAboveLimit)
{
if (!super.canQueueRetrieval())
{
@@ -220,9 +222,22 @@ public class GeneratedFullDataSourceProvider extends FullDataSourceProviderV2 im
return false;
}
int availableTaskSlots = maxQueueCount - worldGenQueue.getWaitingTaskCount();
if (availableTaskSlots <= 0)
{
if (pruneWaitingTasksAboveLimit)
{
AtomicInteger tasksToCancel = new AtomicInteger(-availableTaskSlots + 1);
worldGenQueue.removeRetrievalRequestIf(x -> tasksToCancel.getAndDecrement() > 0);
}
else
{
// don't queue additional world gen requests beyond the max allotted count
return false;
}
}
// don't queue additional world gen requests beyond the max allotted count
return worldGenQueue.getWaitingTaskCount() < maxQueueCount;
return true;
}
@Override
@@ -238,7 +253,7 @@ public class GeneratedFullDataSourceProvider extends FullDataSourceProviderV2 im
CompletableFuture<WorldGenResult> worldGenFuture = worldGenQueue.submitRetrievalTask(genPos, (byte) (DhSectionPos.getDetailLevel(genPos) - DhSectionPos.SECTION_MINIMUM_DETAIL_LEVEL), genTaskTracker);
worldGenFuture.whenComplete((genTaskResult, ex) ->
{
LOGGER.info("gen task complete ["+DhSectionPos.toString(genPos)+"]");
//LOGGER.info("gen task complete ["+DhSectionPos.toString(genPos)+"]");
//this.onWorldGenTaskComplete(genTaskResult, ex);
});
@@ -66,6 +66,9 @@ public class RemoteFullDataSourceProvider extends GeneratedFullDataSourceProvide
// override methods //
//==================//
@Override
public boolean canQueueRetrieval() { return this.canQueueRetrieval(true); }
@Override
@Nullable
public FullDataSourceV2 get(long pos)
@@ -180,7 +180,7 @@ public abstract class AbstractFullDataNetworkRequestQueue implements IDebugRende
{
Map.Entry<Long, RequestQueueEntry> mapEntry = this.waitingTasksBySectionPos.entrySet().stream()
.filter(task -> task.getValue().networkDataSourceFuture == null)
.min(Comparator.comparingInt(x -> posDistanceSquared(targetPos, x.getKey())))
.min(Comparator.comparingInt(x -> DhSectionPos.getChebyshevSignedBlockDistance(x.getKey(), targetPos)))
.orElse(null);
if (mapEntry == null)
@@ -310,7 +310,9 @@ public abstract class AbstractFullDataNetworkRequestQueue implements IDebugRende
public void removeRetrievalRequestIf(DhSectionPos.ICancelablePrimitiveLongConsumer removeIf)
{
for (Map.Entry<Long, RequestQueueEntry> mapEntry : this.waitingTasksBySectionPos.entrySet())
for (Map.Entry<Long, RequestQueueEntry> mapEntry : (Iterable<? extends Map.Entry<Long, RequestQueueEntry>>) this.waitingTasksBySectionPos.entrySet().stream()
.sorted(Comparator.comparingInt((Map.Entry<Long, RequestQueueEntry> entry) -> DhSectionPos.getChebyshevSignedBlockDistance(entry.getKey(), Objects.requireNonNull(this.level.getTargetPosForGeneration()))).reversed())
::iterator)
{
long pos = mapEntry.getKey();
RequestQueueEntry entry = mapEntry.getValue();
@@ -401,15 +403,6 @@ public abstract class AbstractFullDataNetworkRequestQueue implements IDebugRende
//================//
// helper methods //
//================//
protected static int posDistanceSquared(DhBlockPos2D targetPos, long pos)
{ return (int) DhSectionPos.getCenterBlockPos(pos).distSquared(targetPos); }
//================//
// helper classes //
//================//
@@ -239,12 +239,12 @@ public class FullDataSourceRequestHandler
}
else if (requestGroup.isWorldGenTaskComplete())
{
LOGGER.info("sending - retry [" + DhSectionPos.toString(pos) + "]");
//LOGGER.info("sending - retry [" + DhSectionPos.toString(pos) + "]");
this.tryFulfillDataSourceRequestGroup(requestGroup, pos);
}
else
{
LOGGER.info("sending - queueing [" + DhSectionPos.toString(pos) + "]");
//LOGGER.info("sending - queueing [" + DhSectionPos.toString(pos) + "]");
this.fullDataSourceProvider().queuePositionForRetrieval(pos);
}
});
@@ -19,6 +19,7 @@
package com.seibel.distanthorizons.core.render;
import com.google.common.base.Suppliers;
import com.seibel.distanthorizons.core.config.Config;
import com.seibel.distanthorizons.core.dataObjects.fullData.sources.FullDataSourceV2;
import com.seibel.distanthorizons.core.dataObjects.render.ColumnRenderSource;
@@ -43,6 +44,7 @@ import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
import it.unimi.dsi.fastutil.longs.LongArrayList;
import org.apache.logging.log4j.Logger;
import org.jetbrains.annotations.Nullable;
import javax.annotation.WillNotClose;
import java.awt.*;
@@ -50,8 +52,10 @@ import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Supplier;
/**
* A render section represents an area that could be rendered.
@@ -100,9 +104,9 @@ public class LodRenderSection implements IDebugRenderable, AutoCloseable
/** Stored as a class variable so we can reuse it's result across multiple LOD loads if necessary */
private ReferencedRenderSourceFutureWrapper renderSourceLoadingRefFuture = null;
private boolean missingPositionsCalculated = false;
/** should be an empty array if no positions need to be generated */
private LongArrayList missingGenerationPos = null;
@Nullable
private Supplier<LongArrayList> missingGenerationPos;
private boolean checkedIfFullDataSourceExists = false;
private boolean fullDataSourceExists = false;
@@ -429,7 +433,7 @@ public class LodRenderSection implements IDebugRenderable, AutoCloseable
// full data retrieval (world gen) //
//=================================//
public boolean isFullyGenerated() { return this.missingPositionsCalculated && this.missingGenerationPos.isEmpty(); }
public boolean isFullyGenerated() { return this.missingGenerationPos != null && this.missingGenerationPos.get().isEmpty(); }
/** Returns true if an LOD exists, regardless of what data is in it */
public boolean getFullDataSourceExists()
{
@@ -452,42 +456,35 @@ public class LodRenderSection implements IDebugRenderable, AutoCloseable
}
}
public boolean missingPositionsCalculated() { return this.missingPositionsCalculated; }
public int ungeneratedPositionCount() { return (this.missingGenerationPos != null) ? this.missingGenerationPos.size() : 0; }
public boolean missingPositionsCalculated() { return this.missingGenerationPos != null; }
public int ungeneratedPositionCount() { return (this.missingGenerationPos != null) ? this.missingGenerationPos.get().size() : 0; }
public void tryQueuingMissingLodRetrieval()
{
if (this.fullDataSourceProvider.canRetrieveMissingDataSources() && this.fullDataSourceProvider.canQueueRetrieval())
{
// calculate the missing positions if not already done
if (!this.missingPositionsCalculated)
if (this.missingGenerationPos == null)
{
this.missingGenerationPos = this.fullDataSourceProvider.getPositionsToRetrieve(this.pos);
if (this.missingGenerationPos != null)
{
this.missingPositionsCalculated = true;
}
//this.missingGenerationPos = Suppliers.memoize(() -> this.fullDataSourceProvider.getPositionsToRetrieve(this.pos));
this.missingGenerationPos = Suppliers.memoizeWithExpiration(() -> this.fullDataSourceProvider.getPositionsToRetrieve(this.pos), 1, TimeUnit.MINUTES);
}
// if the missing positions were found, queue them
if (this.missingGenerationPos != null)
// queue from last to first to prevent shifting the array unnecessarily
for (int i = this.missingGenerationPos.get().size() - 1; i >= 0; i--)
{
// queue from last to first to prevent shifting the array unnecessarily
for (int i = this.missingGenerationPos.size() - 1; i >= 0; i--)
if (!this.fullDataSourceProvider.canQueueRetrieval())
{
if (!this.fullDataSourceProvider.canQueueRetrieval())
{
// the data source provider isn't accepting any more jobs
break;
}
long pos = this.missingGenerationPos.removeLong(i);
boolean positionQueued = (this.fullDataSourceProvider.queuePositionForRetrieval(pos) != null);
if (!positionQueued)
{
// shouldn't normally happen, but just in case
this.missingGenerationPos.add(pos);
}
// the data source provider isn't accepting any more jobs
break;
}
long pos = this.missingGenerationPos.get().removeLong(i);
boolean positionQueued = (this.fullDataSourceProvider.queuePositionForRetrieval(pos) != null);
if (!positionQueued)
{
// shouldn't normally happen, but just in case
this.missingGenerationPos.get().add(pos);
}
}
}