Fixes #30
The CuboidRegion class will now queue blocks in layers for a chunk before moving onto the next chunk. This results in higher cache hits for history enabled queues. It also allows the block placer to start earlier during preprocessing with edits affecting > 64 (configurable) chunks. Note: with history on disk enabled, this means near unlimited sized edits (for certain commands) might be feasible.
This commit is contained in:
parent
caa0e475ad
commit
5097f0cf63
@ -3,13 +3,10 @@ package com.boydti.fawe.bukkit.v0;
|
|||||||
import com.boydti.fawe.Fawe;
|
import com.boydti.fawe.Fawe;
|
||||||
import com.boydti.fawe.object.FaweChunk;
|
import com.boydti.fawe.object.FaweChunk;
|
||||||
import com.boydti.fawe.util.FaweQueue;
|
import com.boydti.fawe.util.FaweQueue;
|
||||||
import com.boydti.fawe.util.SetQueue;
|
|
||||||
import com.boydti.fawe.util.TaskManager;
|
import com.boydti.fawe.util.TaskManager;
|
||||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||||
import java.util.ArrayDeque;
|
import java.util.ArrayDeque;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Chunk;
|
import org.bukkit.Chunk;
|
||||||
@ -28,6 +25,7 @@ public abstract class BukkitQueue_0 extends FaweQueue implements Listener {
|
|||||||
* Map of chunks in the queue
|
* Map of chunks in the queue
|
||||||
*/
|
*/
|
||||||
private ConcurrentHashMap<Long, FaweChunk<Chunk>> blocks = new ConcurrentHashMap<>();
|
private ConcurrentHashMap<Long, FaweChunk<Chunk>> blocks = new ConcurrentHashMap<>();
|
||||||
|
private ArrayDeque<FaweChunk<Chunk>> chunks = new ArrayDeque<>();
|
||||||
|
|
||||||
public BukkitQueue_0(String world) {
|
public BukkitQueue_0(String world) {
|
||||||
super(world);
|
super(world);
|
||||||
@ -41,7 +39,10 @@ public abstract class BukkitQueue_0 extends FaweQueue implements Listener {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isChunkLoaded(int x, int z) {
|
public boolean isChunkLoaded(int x, int z) {
|
||||||
return Bukkit.getWorld(world).isChunkLoaded(x, z);
|
if (bukkitWorld == null) {
|
||||||
|
bukkitWorld = Bukkit.getServer().getWorld(world);
|
||||||
|
}
|
||||||
|
return bukkitWorld.isChunkLoaded(x, z);
|
||||||
// long id = ((long) x << 32) | (z & 0xFFFFFFFFL);
|
// long id = ((long) x << 32) | (z & 0xFFFFFFFFL);
|
||||||
// HashSet<Long> map = this.loaded.get(world);
|
// HashSet<Long> map = this.loaded.get(world);
|
||||||
// if (map != null) {
|
// if (map != null) {
|
||||||
@ -67,6 +68,7 @@ public abstract class BukkitQueue_0 extends FaweQueue implements Listener {
|
|||||||
result.addTask(runnable);
|
result.addTask(runnable);
|
||||||
FaweChunk<Chunk> previous = this.blocks.put(pair, result);
|
FaweChunk<Chunk> previous = this.blocks.put(pair, result);
|
||||||
if (previous == null) {
|
if (previous == null) {
|
||||||
|
chunks.add(result);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.blocks.put(pair, previous);
|
this.blocks.put(pair, previous);
|
||||||
@ -87,6 +89,7 @@ public abstract class BukkitQueue_0 extends FaweQueue implements Listener {
|
|||||||
result.setBlock(x & 15, y, z & 15, id, data);
|
result.setBlock(x & 15, y, z & 15, id, data);
|
||||||
FaweChunk<Chunk> previous = this.blocks.put(pair, result);
|
FaweChunk<Chunk> previous = this.blocks.put(pair, result);
|
||||||
if (previous == null) {
|
if (previous == null) {
|
||||||
|
chunks.add(result);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
this.blocks.put(pair, previous);
|
this.blocks.put(pair, previous);
|
||||||
@ -106,6 +109,8 @@ public abstract class BukkitQueue_0 extends FaweQueue implements Listener {
|
|||||||
if (previous != null) {
|
if (previous != null) {
|
||||||
this.blocks.put(pair, previous);
|
this.blocks.put(pair, previous);
|
||||||
result = previous;
|
result = previous;
|
||||||
|
} else {
|
||||||
|
chunks.add(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result.setBiome(x & 15, z & 15, biome);
|
result.setBiome(x & 15, z & 15, biome);
|
||||||
@ -118,18 +123,23 @@ public abstract class BukkitQueue_0 extends FaweQueue implements Listener {
|
|||||||
if (this.blocks.size() == 0) {
|
if (this.blocks.size() == 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
Iterator<Entry<Long, FaweChunk<Chunk>>> iter = this.blocks.entrySet().iterator();
|
synchronized (blocks) {
|
||||||
FaweChunk<Chunk> toReturn = iter.next().getValue();
|
FaweChunk<Chunk> chunk = chunks.poll();
|
||||||
if (SetQueue.IMP.isWaiting()) {
|
if (chunk != null) {
|
||||||
return null;
|
blocks.remove(chunk.longHash());
|
||||||
|
this.execute(chunk);
|
||||||
|
return chunk;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
iter.remove();
|
|
||||||
this.execute(toReturn);
|
|
||||||
return toReturn;
|
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int size() {
|
||||||
|
return chunks.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
private ArrayDeque<FaweChunk<Chunk>> toUpdate = new ArrayDeque<>();
|
private ArrayDeque<FaweChunk<Chunk>> toUpdate = new ArrayDeque<>();
|
||||||
@ -156,7 +166,11 @@ public abstract class BukkitQueue_0 extends FaweQueue implements Listener {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setChunk(FaweChunk<?> chunk) {
|
public void setChunk(FaweChunk<?> chunk) {
|
||||||
this.blocks.put(chunk.longHash(), (FaweChunk<Chunk>) chunk);
|
FaweChunk<Chunk> previous = this.blocks.put(chunk.longHash(), (FaweChunk<Chunk>) chunk);
|
||||||
|
if (previous != null) {
|
||||||
|
chunks.remove(previous);
|
||||||
|
}
|
||||||
|
chunks.add((FaweChunk<Chunk>) chunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract Collection<FaweChunk<Chunk>> sendChunk(Collection<FaweChunk<Chunk>> fcs);
|
public abstract Collection<FaweChunk<Chunk>> sendChunk(Collection<FaweChunk<Chunk>> fcs);
|
||||||
|
@ -155,6 +155,9 @@ public class BukkitQueue_1_8 extends BukkitQueue_0 {
|
|||||||
} else if (cy == lcy) {
|
} else if (cy == lcy) {
|
||||||
return ls != null ? ls[FaweCache.CACHE_J[y][x & 15][z & 15]] : 0;
|
return ls != null ? ls[FaweCache.CACHE_J[y][x & 15][z & 15]] : 0;
|
||||||
}
|
}
|
||||||
|
if (lc == null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Object storage = ((Object[]) fieldSections.of(lc).get())[cy];
|
Object storage = ((Object[]) fieldSections.of(lc).get())[cy];
|
||||||
if (storage == null) {
|
if (storage == null) {
|
||||||
ls = null;
|
ls = null;
|
||||||
|
@ -149,6 +149,9 @@ public class BukkitQueue_1_9 extends BukkitQueue_0 {
|
|||||||
}
|
}
|
||||||
lc = methodGetType.of(methodGetHandleChunk.of(bukkitWorld.getChunkAt(cx, cz)).call());
|
lc = methodGetType.of(methodGetHandleChunk.of(bukkitWorld.getChunkAt(cx, cz)).call());
|
||||||
}
|
}
|
||||||
|
if (lc == null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
int combined = (int) methodGetCombinedId.call(lc.call(x & 15, y, z & 15));
|
int combined = (int) methodGetCombinedId.call(lc.call(x & 15, y, z & 15));
|
||||||
return ((combined & 4095) << 4) + (combined >> 12);
|
return ((combined & 4095) << 4) + (combined >> 12);
|
||||||
}
|
}
|
||||||
|
@ -42,13 +42,13 @@ public class FaweAPI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void fixLighting(String world, int x, int z, final boolean fixAll) {
|
public static void fixLighting(String world, int x, int z, final boolean fixAll) {
|
||||||
FaweQueue queue = SetQueue.IMP.getNewQueue(world);
|
FaweQueue queue = SetQueue.IMP.getNewQueue(world, false);
|
||||||
queue.fixLighting(queue.getChunk(x, z), fixAll);
|
queue.fixLighting(queue.getChunk(x, z), fixAll);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static void fixLighting(final Chunk chunk, final boolean fixAll) {
|
public static void fixLighting(final Chunk chunk, final boolean fixAll) {
|
||||||
FaweQueue queue = SetQueue.IMP.getNewQueue(chunk.getWorld().getName());
|
FaweQueue queue = SetQueue.IMP.getNewQueue(chunk.getWorld().getName(), false);
|
||||||
queue.fixLighting(queue.getChunk(chunk.getX(), chunk.getZ()), fixAll);
|
queue.fixLighting(queue.getChunk(chunk.getX(), chunk.getZ()), fixAll);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -141,7 +141,7 @@ public class FaweAPI {
|
|||||||
tagMap = null;
|
tagMap = null;
|
||||||
tag = null;
|
tag = null;
|
||||||
|
|
||||||
FaweQueue queue = SetQueue.IMP.getNewQueue(loc.world);
|
FaweQueue queue = SetQueue.IMP.getNewQueue(loc.world, true);
|
||||||
|
|
||||||
for (int y = 0; y < height; y++) {
|
for (int y = 0; y < height; y++) {
|
||||||
final int yy = y_offset + y;
|
final int yy = y_offset + y;
|
||||||
|
@ -27,6 +27,9 @@ public class Settings {
|
|||||||
public static int CHUNK_WAIT = 0;
|
public static int CHUNK_WAIT = 0;
|
||||||
public static boolean REGION_RESTRICTIONS = true;
|
public static boolean REGION_RESTRICTIONS = true;
|
||||||
public static int ALLOCATE = 0;
|
public static int ALLOCATE = 0;
|
||||||
|
public static int QUEUE_SIZE = 64;
|
||||||
|
public static int QUEUE_MAX_WAIT = 1000;
|
||||||
|
public static int QUEUE_DISCARD_AFTER = 60000;
|
||||||
|
|
||||||
public static HashMap<String, FaweLimit> limits;
|
public static HashMap<String, FaweLimit> limits;
|
||||||
|
|
||||||
@ -73,6 +76,9 @@ public class Settings {
|
|||||||
options.put("history.buffer-size", BUFFER_SIZE);
|
options.put("history.buffer-size", BUFFER_SIZE);
|
||||||
options.put("region-restrictions", REGION_RESTRICTIONS);
|
options.put("region-restrictions", REGION_RESTRICTIONS);
|
||||||
options.put("queue.extra-time-ms", ALLOCATE);
|
options.put("queue.extra-time-ms", ALLOCATE);
|
||||||
|
options.put("queue.target-size", QUEUE_SIZE);
|
||||||
|
options.put("queue.max-wait-ms", QUEUE_MAX_WAIT);
|
||||||
|
options.put("queue.discard-after-ms", QUEUE_DISCARD_AFTER);
|
||||||
options.put("metrics", METRICS);
|
options.put("metrics", METRICS);
|
||||||
|
|
||||||
// Default limit
|
// Default limit
|
||||||
@ -85,8 +91,6 @@ public class Settings {
|
|||||||
FaweLimit limit = new FaweLimit();
|
FaweLimit limit = new FaweLimit();
|
||||||
limit.load(config.getConfigurationSection("limits." + key), defaultLimit, false);
|
limit.load(config.getConfigurationSection("limits." + key), defaultLimit, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
for (final Entry<String, Object> node : options.entrySet()) {
|
for (final Entry<String, Object> node : options.entrySet()) {
|
||||||
if (!config.contains(node.getKey())) {
|
if (!config.contains(node.getKey())) {
|
||||||
config.set(node.getKey(), node.getValue());
|
config.set(node.getKey(), node.getValue());
|
||||||
@ -104,6 +108,9 @@ public class Settings {
|
|||||||
BUFFER_SIZE = config.getInt("history.buffer-size", BUFFER_SIZE);
|
BUFFER_SIZE = config.getInt("history.buffer-size", BUFFER_SIZE);
|
||||||
CHUNK_WAIT = config.getInt("history.chunk-wait-ms");
|
CHUNK_WAIT = config.getInt("history.chunk-wait-ms");
|
||||||
ALLOCATE = config.getInt("queue.extra-time-ms");
|
ALLOCATE = config.getInt("queue.extra-time-ms");
|
||||||
|
QUEUE_SIZE = config.getInt("queue.target-size");
|
||||||
|
QUEUE_MAX_WAIT = config.getInt("queue.max-wait-ms");
|
||||||
|
QUEUE_DISCARD_AFTER = config.getInt("queue.discard-after-ms");
|
||||||
if (STORE_HISTORY_ON_DISK = config.getBoolean("history.use-disk")) {
|
if (STORE_HISTORY_ON_DISK = config.getBoolean("history.use-disk")) {
|
||||||
LocalSession.MAX_HISTORY_SIZE = Integer.MAX_VALUE;
|
LocalSession.MAX_HISTORY_SIZE = Integer.MAX_VALUE;
|
||||||
}
|
}
|
||||||
|
@ -55,6 +55,8 @@ public abstract class FaweQueue {
|
|||||||
|
|
||||||
public abstract int getCombinedId4Data(int x, int y, int z);
|
public abstract int getCombinedId4Data(int x, int y, int z);
|
||||||
|
|
||||||
|
public abstract int size();
|
||||||
|
|
||||||
public void enqueue() {
|
public void enqueue() {
|
||||||
SetQueue.IMP.enqueue(this);
|
SetQueue.IMP.enqueue(this);
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,6 @@ import com.boydti.fawe.object.FaweChunk;
|
|||||||
import java.util.ArrayDeque;
|
import java.util.ArrayDeque;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
|
||||||
|
|
||||||
public class SetQueue {
|
public class SetQueue {
|
||||||
|
|
||||||
@ -15,19 +14,15 @@ public class SetQueue {
|
|||||||
*/
|
*/
|
||||||
public static final SetQueue IMP = new SetQueue();
|
public static final SetQueue IMP = new SetQueue();
|
||||||
|
|
||||||
public final ArrayDeque<FaweQueue> queues;
|
public final ArrayDeque<FaweQueue> activeQueues;
|
||||||
|
public final ArrayDeque<FaweQueue> inactiveQueues;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Track the time in ticks
|
* Used to calculate elapsed time in milliseconds and ensure block placement doesn't lag the server
|
||||||
*/
|
|
||||||
private final AtomicInteger time_waiting = new AtomicInteger(2);
|
|
||||||
private final AtomicInteger time_current = new AtomicInteger(0);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used to calculate elapsed time in milliseconds and ensure block placement doesn't lag the server
|
|
||||||
*/
|
*/
|
||||||
private long last;
|
private long last;
|
||||||
private long last2;
|
private long secondLast;
|
||||||
|
private long lastSuccess;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A queue of tasks that will run when the queue is empty
|
* A queue of tasks that will run when the queue is empty
|
||||||
@ -36,7 +31,8 @@ public class SetQueue {
|
|||||||
|
|
||||||
|
|
||||||
public SetQueue() {
|
public SetQueue() {
|
||||||
queues = new ArrayDeque();
|
activeQueues = new ArrayDeque();
|
||||||
|
inactiveQueues = new ArrayDeque<>();
|
||||||
TaskManager.IMP.repeat(new Runnable() {
|
TaskManager.IMP.repeat(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
@ -52,51 +48,84 @@ public class SetQueue {
|
|||||||
if (SetQueue.this.forceChunkSet()) {
|
if (SetQueue.this.forceChunkSet()) {
|
||||||
System.gc();
|
System.gc();
|
||||||
} else {
|
} else {
|
||||||
SetQueue.this.time_current.incrementAndGet();
|
|
||||||
SetQueue.this.tasks();
|
SetQueue.this.tasks();
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
final long free = Settings.ALLOCATE + 50 + Math.min((50 + SetQueue.this.last) - (SetQueue.this.last = System.currentTimeMillis()), SetQueue.this.last2 - System.currentTimeMillis());
|
final long free = Settings.ALLOCATE + 50 + Math.min((50 + SetQueue.this.last) - (SetQueue.this.last = System.currentTimeMillis()), SetQueue.this.secondLast - System.currentTimeMillis());
|
||||||
SetQueue.this.time_current.incrementAndGet();
|
|
||||||
do {
|
do {
|
||||||
if (SetQueue.this.isWaiting()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
final FaweChunk<?> current = next();
|
final FaweChunk<?> current = next();
|
||||||
if (current == null) {
|
if (current == null) {
|
||||||
SetQueue.this.time_waiting.set(Math.max(SetQueue.this.time_waiting.get(), SetQueue.this.time_current.get() - 2));
|
lastSuccess = last;
|
||||||
SetQueue.this.tasks();
|
SetQueue.this.tasks();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} while (((SetQueue.this.last2 = System.currentTimeMillis()) - SetQueue.this.last) < free);
|
} while (((SetQueue.this.secondLast = System.currentTimeMillis()) - SetQueue.this.last) < free);
|
||||||
SetQueue.this.time_waiting.set(SetQueue.this.time_current.get() - 1);
|
|
||||||
}
|
}
|
||||||
}, 1);
|
}, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void enqueue(FaweQueue queue) {
|
public void enqueue(FaweQueue queue) {
|
||||||
queues.add(queue);
|
inactiveQueues.remove(queue);
|
||||||
|
activeQueues.add(queue);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<FaweQueue> getQueues() {
|
public List<FaweQueue> getQueues() {
|
||||||
return new ArrayList<>(queues);
|
return new ArrayList<>(activeQueues);
|
||||||
}
|
}
|
||||||
|
|
||||||
public FaweQueue getNewQueue(String world) {
|
public FaweQueue getNewQueue(String world, boolean autoqueue) {
|
||||||
return Fawe.imp().getNewQueue(world);
|
FaweQueue queue = Fawe.imp().getNewQueue(world);
|
||||||
|
if (autoqueue) {
|
||||||
|
inactiveQueues.add(queue);
|
||||||
|
}
|
||||||
|
return queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public FaweChunk<?> next() {
|
public FaweChunk<?> next() {
|
||||||
while (queues.size() > 0) {
|
while (activeQueues.size() > 0) {
|
||||||
FaweQueue queue = queues.poll();
|
FaweQueue queue = activeQueues.poll();
|
||||||
final FaweChunk<?> set = queue.next();
|
final FaweChunk<?> set = queue.next();
|
||||||
if (set != null) {
|
if (set != null) {
|
||||||
queues.add(queue);
|
activeQueues.add(queue);
|
||||||
return set;
|
return set;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (inactiveQueues.size() > 0) {
|
||||||
|
ArrayList<FaweQueue> tmp = new ArrayList<>(inactiveQueues);
|
||||||
|
if (Settings.QUEUE_MAX_WAIT != -1) {
|
||||||
|
long now = System.currentTimeMillis();
|
||||||
|
long diff = now - lastSuccess;
|
||||||
|
if (diff > Settings.QUEUE_MAX_WAIT) {
|
||||||
|
for (FaweQueue queue : tmp) {
|
||||||
|
FaweChunk result = queue.next();
|
||||||
|
if (result != null) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (diff > Settings.QUEUE_DISCARD_AFTER) {
|
||||||
|
// These edits never finished
|
||||||
|
inactiveQueues.clear();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (Settings.QUEUE_SIZE != -1) {
|
||||||
|
int total = 0;
|
||||||
|
for (FaweQueue queue : tmp) {
|
||||||
|
total += queue.size();
|
||||||
|
}
|
||||||
|
if (total > Settings.QUEUE_SIZE) {
|
||||||
|
for (FaweQueue queue : tmp) {
|
||||||
|
FaweChunk result = queue.next();
|
||||||
|
if (result != null) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,16 +133,8 @@ public class SetQueue {
|
|||||||
return next() != null;
|
return next() != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isWaiting() {
|
|
||||||
return this.time_waiting.get() >= this.time_current.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isDone() {
|
public boolean isDone() {
|
||||||
return (this.time_waiting.get() + 1) < this.time_current.get();
|
return activeQueues.size() == 0 && inactiveQueues.size() == 0;
|
||||||
}
|
|
||||||
|
|
||||||
public void setWaiting() {
|
|
||||||
this.time_waiting.set(this.time_current.get() + 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean addTask(final Runnable whenDone) {
|
public boolean addTask(final Runnable whenDone) {
|
||||||
|
@ -232,7 +232,7 @@ public class EditSession implements Extent {
|
|||||||
}
|
}
|
||||||
final Actor actor = event.getActor();
|
final Actor actor = event.getActor();
|
||||||
|
|
||||||
this.queue = SetQueue.IMP.getNewQueue(world.getName());
|
this.queue = SetQueue.IMP.getNewQueue(world.getName(), true);
|
||||||
this.world = (world = new WorldWrapper((AbstractWorld) world));
|
this.world = (world = new WorldWrapper((AbstractWorld) world));
|
||||||
this.wrapper = Fawe.imp().getEditSessionWrapper(this);
|
this.wrapper = Fawe.imp().getEditSessionWrapper(this);
|
||||||
// Not a player; bypass history
|
// Not a player; bypass history
|
||||||
|
@ -348,36 +348,62 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion {
|
|||||||
private Vector min = getMinimumPoint();
|
private Vector min = getMinimumPoint();
|
||||||
private Vector max = getMaximumPoint();
|
private Vector max = getMaximumPoint();
|
||||||
|
|
||||||
int minX = min.getBlockX();
|
int bx = min.getBlockX();
|
||||||
int minY = min.getBlockY();
|
int by = min.getBlockY();
|
||||||
int minZ = min.getBlockZ();
|
int bz = min.getBlockZ();
|
||||||
|
|
||||||
int maxX = max.getBlockX();
|
int tx = max.getBlockX();
|
||||||
int maxY = max.getBlockY();
|
int ty = max.getBlockY();
|
||||||
int maxZ = max.getBlockZ();
|
int tz = max.getBlockZ();
|
||||||
|
|
||||||
private int nextX = min.getBlockX();
|
private int x = min.getBlockX();
|
||||||
private int nextY = min.getBlockY();
|
private int y = min.getBlockY();
|
||||||
private int nextZ = min.getBlockZ();
|
private int z = min.getBlockZ();
|
||||||
|
|
||||||
|
int cx = x >> 4;
|
||||||
|
int cz = z >> 4;
|
||||||
|
int cbx = Math.max(bx, cx << 4);
|
||||||
|
int cbz = Math.max(bz, cz << 4);
|
||||||
|
int ctx = Math.min(tx, 15 + (cx << 4));
|
||||||
|
int ctz = Math.min(tz, 15 + (cz << 4));
|
||||||
|
|
||||||
|
public boolean hasNext = true;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasNext() {
|
public boolean hasNext() {
|
||||||
return (nextX != Integer.MIN_VALUE);
|
return hasNext;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlockVector next() {
|
public BlockVector next() {
|
||||||
if (!hasNext()) throw new java.util.NoSuchElementException();
|
v.x = x;
|
||||||
v.x = nextX;
|
v.y = y;
|
||||||
v.y = nextY;
|
v.z = z;
|
||||||
v.z = nextZ;
|
if (++x > ctx) {
|
||||||
if (++nextX > maxX) {
|
if (++z > ctz) {
|
||||||
nextX = minX;
|
if (++y > ty) {
|
||||||
if (++nextY > maxY) {
|
y = by;
|
||||||
nextY = minY;
|
if (x > tx) {
|
||||||
if (++nextZ > maxZ) {
|
x = bx;
|
||||||
nextX = Integer.MIN_VALUE;
|
if (z > tz) {
|
||||||
|
hasNext = false;
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
z = cbz;
|
||||||
|
}
|
||||||
|
cx = x >> 4;
|
||||||
|
cz = z >> 4;
|
||||||
|
cbx = Math.max(bx, cx << 4);
|
||||||
|
cbz = Math.max(bz, cz << 4);
|
||||||
|
ctx = Math.min(tx, 15 + (cx << 4));
|
||||||
|
ctz = Math.min(tz, 15 + (cz << 4));
|
||||||
|
} else {
|
||||||
|
x = cbx;
|
||||||
|
z = cbz;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
x = cbx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return v;
|
return v;
|
||||||
|
@ -2,12 +2,9 @@ package com.boydti.fawe.forge.v0;
|
|||||||
|
|
||||||
import com.boydti.fawe.object.FaweChunk;
|
import com.boydti.fawe.object.FaweChunk;
|
||||||
import com.boydti.fawe.util.FaweQueue;
|
import com.boydti.fawe.util.FaweQueue;
|
||||||
import com.boydti.fawe.util.SetQueue;
|
|
||||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||||
import java.util.ArrayDeque;
|
import java.util.ArrayDeque;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import org.spongepowered.api.Sponge;
|
import org.spongepowered.api.Sponge;
|
||||||
import org.spongepowered.api.world.Chunk;
|
import org.spongepowered.api.world.Chunk;
|
||||||
@ -22,6 +19,7 @@ public abstract class SpongeQueue_0 extends FaweQueue {
|
|||||||
* Map of chunks in the queue
|
* Map of chunks in the queue
|
||||||
*/
|
*/
|
||||||
private final ConcurrentHashMap<Long, FaweChunk<Chunk>> blocks = new ConcurrentHashMap<>();
|
private final ConcurrentHashMap<Long, FaweChunk<Chunk>> blocks = new ConcurrentHashMap<>();
|
||||||
|
private ArrayDeque<FaweChunk<Chunk>> chunks = new ArrayDeque<>();
|
||||||
|
|
||||||
public SpongeQueue_0(String world) {
|
public SpongeQueue_0(String world) {
|
||||||
super(world);
|
super(world);
|
||||||
@ -43,6 +41,7 @@ public abstract class SpongeQueue_0 extends FaweQueue {
|
|||||||
result.addTask(runnable);
|
result.addTask(runnable);
|
||||||
final FaweChunk<Chunk> previous = this.blocks.put(pair, result);
|
final FaweChunk<Chunk> previous = this.blocks.put(pair, result);
|
||||||
if (previous == null) {
|
if (previous == null) {
|
||||||
|
chunks.add(result);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.blocks.put(pair, previous);
|
this.blocks.put(pair, previous);
|
||||||
@ -63,6 +62,7 @@ public abstract class SpongeQueue_0 extends FaweQueue {
|
|||||||
result.setBlock(x & 15, y, z & 15, id, data);
|
result.setBlock(x & 15, y, z & 15, id, data);
|
||||||
final FaweChunk<Chunk> previous = this.blocks.put(pair, result);
|
final FaweChunk<Chunk> previous = this.blocks.put(pair, result);
|
||||||
if (previous == null) {
|
if (previous == null) {
|
||||||
|
chunks.add(result);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
this.blocks.put(pair, previous);
|
this.blocks.put(pair, previous);
|
||||||
@ -94,18 +94,23 @@ public abstract class SpongeQueue_0 extends FaweQueue {
|
|||||||
if (this.blocks.size() == 0) {
|
if (this.blocks.size() == 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
final Iterator<Map.Entry<Long, FaweChunk<Chunk>>> iter = this.blocks.entrySet().iterator();
|
synchronized (blocks) {
|
||||||
final FaweChunk<Chunk> toReturn = iter.next().getValue();
|
FaweChunk<Chunk> chunk = chunks.poll();
|
||||||
if (SetQueue.IMP.isWaiting()) {
|
if (chunk != null) {
|
||||||
return null;
|
blocks.remove(chunk.longHash());
|
||||||
|
this.execute(chunk);
|
||||||
|
return chunk;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
iter.remove();
|
} catch (Throwable e) {
|
||||||
this.execute(toReturn);
|
|
||||||
return toReturn;
|
|
||||||
} catch (final Throwable e) {
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int size() {
|
||||||
|
return chunks.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
private final ArrayDeque<FaweChunk<Chunk>> toUpdate = new ArrayDeque<>();
|
private final ArrayDeque<FaweChunk<Chunk>> toUpdate = new ArrayDeque<>();
|
||||||
@ -132,7 +137,11 @@ public abstract class SpongeQueue_0 extends FaweQueue {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setChunk(final FaweChunk<?> chunk) {
|
public void setChunk(final FaweChunk<?> chunk) {
|
||||||
this.blocks.put(chunk.longHash(), (FaweChunk<Chunk>) chunk);
|
FaweChunk<Chunk> previous = this.blocks.put(chunk.longHash(), (FaweChunk<Chunk>) chunk);
|
||||||
|
if (previous != null) {
|
||||||
|
chunks.remove(previous);
|
||||||
|
}
|
||||||
|
chunks.add((FaweChunk<Chunk>) chunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract Collection<FaweChunk<Chunk>> sendChunk(final Collection<FaweChunk<Chunk>> fcs);
|
public abstract Collection<FaweChunk<Chunk>> sendChunk(final Collection<FaweChunk<Chunk>> fcs);
|
||||||
|
Loading…
Reference in New Issue
Block a user