Synchronize auto queries

This commit is contained in:
Alexander Söderberg 2020-08-17 01:27:45 +02:00
parent 87f0b1fc97
commit 351ae1b2c7
No known key found for this signature in database
GPG Key ID: C0207FF7EA146678

View File

@ -1,5 +1,7 @@
package com.plotsquared.core.services.plots;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.intellectualsites.services.types.Service;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot;
@ -11,10 +13,15 @@ import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.function.Predicate;
public interface AutoService extends Service<AutoService.AutoQuery, List<Plot>> {
Cache<PlotId, Plot> plotCandidateCache = CacheBuilder.newBuilder()
.expireAfterWrite(20, TimeUnit.SECONDS).build();
Object plotLock = new Object();
final class AutoQuery {
private final PlotPlayer<?> player;
@ -101,12 +108,18 @@ public interface AutoService extends Service<AutoService.AutoQuery, List<Plot>>
final class SinglePlotService implements AutoService, Predicate<AutoQuery> {
@Nullable @Override public List<Plot> handle(@Nonnull AutoQuery autoQuery) {
final Plot plot = autoQuery.getPlotArea().getNextFreePlot(autoQuery.getPlayer(), autoQuery.getStartId());
if (plot == null) {
return null;
}
Plot plot;
do {
synchronized (plotLock) {
plot = autoQuery.getPlotArea().getNextFreePlot(autoQuery.getPlayer(), autoQuery.getStartId());
if (plot != null && plotCandidateCache.getIfPresent(plot.getId()) == null) {
plotCandidateCache.put(plot.getId(), plot);
return Collections.singletonList(plot);
}
}
} while (plot != null);
return null;
}
@Override public boolean test(@Nonnull final AutoQuery autoQuery) {
return autoQuery.sizeX == 1 && autoQuery.sizeZ == 1;
@ -119,16 +132,27 @@ public interface AutoService extends Service<AutoService.AutoQuery, List<Plot>>
@Override public List<Plot> handle(@Nonnull final AutoQuery autoQuery) {
/* TODO: Add timeout? */
while (true) {
final PlotId start = autoQuery.getPlotArea().getMeta("lastPlot", PlotId.of(0, 0)).getNextId();
final PlotId end = PlotId.of(start.getX() + autoQuery.getSizeX() - 1, start.getY() + autoQuery.getSizeZ() - 1);
final List<Plot> plots = autoQuery.getPlotArea().canClaim(autoQuery.getPlayer(), start, end);
outer: while (true) {
synchronized (plotLock) {
final PlotId start =
autoQuery.getPlotArea().getMeta("lastPlot", PlotId.of(0, 0)).getNextId();
final PlotId end = PlotId.of(start.getX() + autoQuery.getSizeX() - 1,
start.getY() + autoQuery.getSizeZ() - 1);
final List<Plot> plots =
autoQuery.getPlotArea().canClaim(autoQuery.getPlayer(), start, end);
if (plots != null && !plots.isEmpty()) {
autoQuery.getPlotArea().setMeta("lastPlot", start);
for (final Plot plot : plots) {
if (plotCandidateCache.getIfPresent(plot.getId()) != null) {
continue outer;
}
plotCandidateCache.put(plot.getId(), plot);
}
return plots;
}
}
}
}
@Override public boolean test(@Nonnull final AutoQuery autoQuery) {
return autoQuery.getPlotArea().getType() != PlotAreaType.PARTIAL;