use of com.fastasyncworldedit.core.internal.exception.FaweException in project FastAsyncWorldEdit by IntellectualSites.
the class RegionVisitor method resume.
@Override
public Operation resume(RunContext run) throws WorldEditException {
// FAWE start > allow chunk preloading
if (singleQueue != null && Settings.settings().QUEUE.PRELOAD_CHUNK_COUNT > 1) {
/*
* The following is done to reduce iteration cost
* - Preload chunks just in time
* - Only check every 16th block for potential chunk loads
* - Stop iteration on exception instead of hasNext
* - Do not calculate the stacktrace as it is expensive
*/
Iterator<? extends BlockVector3> trailIter = iterable.iterator();
Iterator<? extends BlockVector3> leadIter = iterable.iterator();
int lastTrailChunkX = Integer.MIN_VALUE;
int lastTrailChunkZ = Integer.MIN_VALUE;
int lastLeadChunkX = Integer.MIN_VALUE;
int lastLeadChunkZ = Integer.MIN_VALUE;
int loadingTarget = Settings.settings().QUEUE.PRELOAD_CHUNK_COUNT;
while (trailIter.hasNext()) {
BlockVector3 pt = trailIter.next();
apply(pt);
int cx = pt.getBlockX() >> 4;
int cz = pt.getBlockZ() >> 4;
if (cx != lastTrailChunkX || cz != lastTrailChunkZ) {
lastTrailChunkX = cx;
lastTrailChunkZ = cz;
int amount;
if (lastLeadChunkX == Integer.MIN_VALUE) {
lastLeadChunkX = cx;
lastLeadChunkZ = cz;
amount = loadingTarget;
} else {
amount = 1;
}
try {
lead: for (int count = 0; count < amount; ) {
BlockVector3 v = leadIter.next();
int vcx = v.getBlockX() >> 4;
int vcz = v.getBlockZ() >> 4;
if (vcx != lastLeadChunkX || vcz != lastLeadChunkZ) {
lastLeadChunkX = vcx;
lastLeadChunkZ = vcz;
singleQueue.addChunkLoad(vcx, vcz);
count++;
}
// Skip the next 15 blocks
for (int i = 0; i < 16; i++) {
if (!leadIter.hasNext()) {
break lead;
}
leadIter.next();
}
}
} catch (FaweException e) {
// Likely to be a low memory or cancellation exception.
throw new RuntimeException(e);
} catch (Throwable ignored) {
// Ignore as it is likely not something too important, and we can continue with the operation
}
}
for (int i = 0; i < 16; i++) {
if (!trailIter.hasNext()) {
return null;
}
apply(trailIter.next());
}
}
} else {
for (BlockVector3 pt : region) {
apply(pt);
}
}
// FAWE end
return null;
}
use of com.fastasyncworldedit.core.internal.exception.FaweException in project FastAsyncWorldEdit by IntellectualSites.
the class ParallelQueueExtent method apply.
@Override
@SuppressWarnings("rawtypes")
public <T extends Filter> T apply(Region region, T filter, boolean full) {
// The chunks positions to iterate over
final Set<BlockVector2> chunks = region.getChunks();
final Iterator<BlockVector2> chunksIter = chunks.iterator();
// Get a pool, to operate on the chunks in parallel
final int size = Math.min(chunks.size(), Settings.settings().QUEUE.PARALLEL_THREADS);
if (size <= 1 && chunksIter.hasNext()) {
BlockVector2 pos = chunksIter.next();
getExtent().apply(null, filter, region, pos.getX(), pos.getZ(), full);
} else {
final ForkJoinTask[] tasks = IntStream.range(0, size).mapToObj(i -> handler.submit(() -> {
try {
final Filter newFilter = filter.fork();
// Create a chunk that we will reuse/reset for each operation
final SingleThreadQueueExtent queue = (SingleThreadQueueExtent) getNewQueue();
queue.setFastMode(fastmode);
queue.setFaweExceptionArray(faweExceptionReasonsUsed);
synchronized (queue) {
try {
ChunkFilterBlock block = null;
while (true) {
// Get the next chunk posWeakChunk
final int chunkX;
final int chunkZ;
synchronized (chunksIter) {
if (!chunksIter.hasNext()) {
break;
}
final BlockVector2 pos = chunksIter.next();
chunkX = pos.getX();
chunkZ = pos.getZ();
}
block = queue.apply(block, newFilter, region, chunkX, chunkZ, full);
}
queue.flush();
} catch (Throwable t) {
if (t instanceof FaweException) {
Fawe.handleFaweException(faweExceptionReasonsUsed, (FaweException) t, LOGGER);
} else if (t.getCause() instanceof FaweException) {
Fawe.handleFaweException(faweExceptionReasonsUsed, (FaweException) t.getCause(), LOGGER);
} else {
throw t;
}
}
}
} catch (Throwable e) {
String message = e.getMessage();
int hash = message.hashCode();
if (lastException != hash) {
lastException = hash;
exceptionCount = 0;
LOGGER.catching(e);
} else if (exceptionCount < Settings.settings().QUEUE.PARALLEL_THREADS) {
exceptionCount++;
LOGGER.warn(message);
}
}
})).toArray(ForkJoinTask[]::new);
// Join filters
for (ForkJoinTask task : tasks) {
if (task != null) {
task.quietlyJoin();
}
}
filter.join();
}
return filter;
}
use of com.fastasyncworldedit.core.internal.exception.FaweException in project FastAsyncWorldEdit by IntellectualSites.
the class SingleThreadQueueExtent method pollSubmissions.
private void pollSubmissions(int targetSize, boolean aggressive) {
final int overflow = submissions.size() - targetSize;
if (aggressive) {
if (targetSize == 0) {
while (!submissions.isEmpty()) {
iterateSubmissions();
}
}
for (int i = 0; i < overflow; i++) {
iterateSubmissions();
}
} else {
for (int i = 0; i < overflow; i++) {
Future next = submissions.peek();
while (next != null) {
if (next.isDone()) {
Future after = null;
try {
after = (Future) next.get();
} catch (FaweException e) {
Fawe.handleFaweException(faweExceptionReasonsUsed, e, LOGGER);
} catch (ExecutionException | InterruptedException e) {
if (e.getCause() instanceof FaweException) {
Fawe.handleFaweException(faweExceptionReasonsUsed, (FaweException) e.getCause(), LOGGER);
} else {
String message = e.getMessage();
int hash = message.hashCode();
if (lastException != hash) {
lastException = hash;
exceptionCount = 0;
LOGGER.catching(e);
} else if (exceptionCount < Settings.settings().QUEUE.PARALLEL_THREADS) {
exceptionCount++;
LOGGER.warn(message);
}
}
} finally {
/*
* If the execution failed, namely next.get() threw an exception,
* we don't want to process that Future again. Instead, we just drop
* it and set it to null, otherwise to the returned next Future.
*/
next = after;
}
} else {
return;
}
}
submissions.poll();
}
}
}
use of com.fastasyncworldedit.core.internal.exception.FaweException in project FastAsyncWorldEdit by IntellectualSites.
the class SingleThreadQueueExtent method iterateSubmissions.
private void iterateSubmissions() {
Future first = submissions.poll();
try {
while (first != null) {
first = (Future) first.get();
}
} catch (FaweException e) {
Fawe.handleFaweException(faweExceptionReasonsUsed, e, LOGGER);
} catch (ExecutionException | InterruptedException e) {
if (e.getCause() instanceof FaweException) {
Fawe.handleFaweException(faweExceptionReasonsUsed, (FaweException) e.getCause(), LOGGER);
} else {
String message = e.getMessage();
int hash = message.hashCode();
if (lastException != hash) {
lastException = hash;
exceptionCount = 0;
LOGGER.catching(e);
} else if (exceptionCount < Settings.settings().QUEUE.PARALLEL_THREADS) {
exceptionCount++;
LOGGER.warn(message);
}
}
}
}
Aggregations