wip chunk based bitset

This commit is contained in:
Jesse Boyd 2019-07-12 02:10:32 +10:00
parent d6a8e9738a
commit 14d5275e05
No known key found for this signature in database
GPG Key ID: 59F1DE6293AF6E1F
7 changed files with 166 additions and 156 deletions

View File

@ -17,6 +17,7 @@ import com.sk89q.worldedit.function.operation.Operations;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.function.visitor.RegionVisitor;
import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.util.Countable;
import com.sk89q.worldedit.world.World;
@ -103,6 +104,10 @@ public class MultiThreadedQueue extends AbstractDelegateExtent implements IQueue
return filter;
}
public int getChanges() {
return -1;
}
@Override
public int countBlocks(final Region region, final Mask searchMask) {
return
@ -116,19 +121,25 @@ public class MultiThreadedQueue extends AbstractDelegateExtent implements IQueue
@Override
public <B extends BlockStateHolder<B>> int setBlocks(Region region, B block) throws MaxChangedBlocksException {
apply(region, block);
return 0;
return getChanges();
}
@Override
public int setBlocks(Region region, Pattern pattern) throws MaxChangedBlocksException {
apply(region, pattern);
return 0;
return getChanges();
}
@Override
public int setBlocks(Set<BlockVector3> vset, Pattern pattern) {
TODO
return getChanges();
}
@Override
public int replaceBlocks(Region region, Mask mask, Pattern pattern) throws MaxChangedBlocksException {
apply(region, mask.toFilter(pattern));
return 0;
return getChanges();
}
@Override

View File

@ -686,39 +686,4 @@ public abstract class FawePlayer<T> extends Metadatable {
}
return proxy;
}
/**
* Get the tracked EditSession(s) for this player<br>
* - Queued or autoqueued EditSessions are considered tracked
*
* @param requiredStage
* @return
*/
public Map<EditSession, SetQueue.QueueStage> getTrackedSessions(SetQueue.QueueStage requiredStage) {
Map<EditSession, SetQueue.QueueStage> map = new ConcurrentHashMap<>(8, 0.9f, 1);
if (requiredStage == null || requiredStage == SetQueue.QueueStage.ACTIVE) {
for (FaweQueue queue : SetQueue.IMP.getActiveQueues()) {
Collection<EditSession> sessions = queue.getEditSessions();
for (EditSession session : sessions) {
FawePlayer currentPlayer = session.getPlayer();
if (currentPlayer == this) {
map.put(session, SetQueue.QueueStage.ACTIVE);
}
}
}
}
if (requiredStage == null || requiredStage == SetQueue.QueueStage.INACTIVE) {
for (FaweQueue queue : SetQueue.IMP.getInactiveQueues()) {
Collection<EditSession> sessions = queue.getEditSessions();
for (EditSession session : sessions) {
FawePlayer currentPlayer = session.getPlayer();
if (currentPlayer == this) {
map.put(session, SetQueue.QueueStage.INACTIVE);
}
}
}
}
return map;
}
}

View File

@ -0,0 +1,109 @@
package com.boydti.fawe.object.collection;
import com.sk89q.worldedit.math.BlockVector3;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
import java.util.Iterator;
import java.util.Set;
public class ChunkBVecSet implements Set<BlockVector3> {
private final int offsetX, offsetZ;
private final ChunkBitSet set;
private int size = 0;
public ChunkBVecSet(int size) {
this(Integer.MAX_VALUE, Integer.MAX_VALUE, new ChunkBitSet(size));
}
public ChunkBVecSet(ChunkBitSet set, int offsetX, int offsetZ) {
this.offsetX = offsetX;
this.offsetZ = offsetZ;
this.set = set;
}
public ChunkBitSet getBitSet() {
return set;
}
@Override
public int size() {
return size;
}
@Override
public boolean isEmpty() {
return size() == 0;
}
@Override
public boolean contains(Object o) {
try {
return contain((BlockVector3) o);
} catch (ClassCastException e) {
e.printStackTrace();
return false;
}
}
public boolean contain(BlockVector3 obj) {
return contain(obj.getX(), obj.getY(), obj.getZ());
}
public boolean contain(int x, int y, int z) {
return set.get(x - offsetX, y, z - offsetZ);
}
@NotNull
@Override
public Iterator<BlockVector3> iterator() {
return null;
}
@NotNull
@Override
public Object[] toArray() {
return new Object[0];
}
@NotNull
@Override
public <T> T[] toArray(@NotNull T[] a) {
return null;
}
@Override
public boolean add(BlockVector3 blockVector3) {
return false;
}
@Override
public boolean remove(Object o) {
return false;
}
@Override
public boolean containsAll(@NotNull Collection<?> c) {
return false;
}
@Override
public boolean addAll(@NotNull Collection<? extends BlockVector3> c) {
return false;
}
@Override
public boolean retainAll(@NotNull Collection<?> c) {
return false;
}
@Override
public boolean removeAll(@NotNull Collection<?> c) {
return false;
}
@Override
public void clear() {
}
}

View File

@ -26,6 +26,10 @@ public class ChunkBitSet {
return rows[x >> 4].get(this.rows, x, y, z);
}
public void add(int x, int y, int z) {
rows[x >> 4].add(this.rows, x, y, z);
}
public void set(int x, int y, int z) {
rows[x >> 4].set(this.rows, x, y, z);
}
@ -37,6 +41,10 @@ public class ChunkBitSet {
private interface IRow {
default boolean get(IRow[] rows, int x, int y, int z) { return false; }
void set(IRow[] rows, int x, int y, int z);
default boolean add(IRow[] rows, int x, int y, int z) {
set(rows, x, y, z);
return true;
}
default void clear(IRow[] rows, int x, int y, int z) { return; }
}
@ -85,6 +93,11 @@ public class ChunkBitSet {
this.rows[z >> 4].set(this.rows, x, y, z);
}
@Override
public boolean add(IRow[] parent, int x, int y, int z) {
return this.rows[z >> 4].add(this.rows, x, y, z);
}
@Override
public void clear(IRow[] parent, int x, int y, int z) {
this.rows[z >> 4].clear(this.rows, x, y, z);
@ -109,6 +122,11 @@ public class ChunkBitSet {
this.rows[y >> 4].set(this.rows, x, y, z);
}
@Override
public boolean add(IRow[] parent, int x, int y, int z) {
return this.rows[y >> 4].add(this.rows, x, y, z);
}
@Override
public void clear(IRow[] parent, int x, int y, int z) {
this.rows[y >> 4].set(this.rows, x, y, z);
@ -134,6 +152,19 @@ public class ChunkBitSet {
bits[i >> 6] |= (1L << (i & 0x3F));
}
@Override
public boolean add(IRow[] parent, int x, int y, int z) {
int i = ((y & 15) << 8) | ((z & 15) << 4) | (x & 15);
int offset = i >> 6;
long value = bits[offset];
long mask = (1L << (i & 0x3F));
if ((value & mask) != 0) {
bits[offset] = value | mask;
return true;
}
return false;
}
@Override
public void clear(IRow[] parent, int x, int y, int z) {
int i = ((y & 15) << 8) | ((z & 15) << 4) | (x & 15);

View File

@ -24,8 +24,6 @@ import com.boydti.fawe.config.BBC;
import com.boydti.fawe.config.Settings;
import com.boydti.fawe.object.FaweLimit;
import com.boydti.fawe.object.FawePlayer;
import com.boydti.fawe.object.FaweQueue;
import com.boydti.fawe.object.HasFaweQueue;
import com.boydti.fawe.object.HistoryExtent;
import com.boydti.fawe.object.RegionWrapper;
import com.boydti.fawe.object.RunnableVal;
@ -45,7 +43,6 @@ import com.boydti.fawe.util.EditSessionBuilder;
import com.boydti.fawe.util.ExtentTraverser;
import com.boydti.fawe.util.MaskTraverser;
import com.boydti.fawe.util.MathMan;
import com.boydti.fawe.util.SetQueue;
import com.boydti.fawe.util.TaskManager;
import com.google.common.base.Supplier;
import com.sk89q.jnbt.CompoundTag;
@ -944,7 +941,7 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
}
public int setBlocks(final Set<BlockVector3> vset, final Pattern pattern) {
RegionVisitor visitor = new RegionVisitor(vset, new BlockReplace(getExtent(), pattern), this);
RegionVisitor visitor = new RegionVisitor(vset, new BlockReplace(getExtent(), pattern));
Operations.completeBlindly(visitor);
changes += visitor.getAffected();
return changes;

View File

@ -581,4 +581,10 @@ public interface Extent extends InputExtent, OutputExtent {
return setBlocks(centerRegion, pattern);
}
default int setBlocks(final Set<BlockVector3> vset, final Pattern pattern) {
RegionVisitor visitor = new RegionVisitor(vset, new BlockReplace(getExtent(), pattern));
Operations.completeBlindly(visitor);
return 0;
}
}

View File

@ -20,13 +20,6 @@
package com.sk89q.worldedit.function.visitor;
import com.boydti.fawe.config.BBC;
import com.boydti.fawe.config.Settings;
import com.boydti.fawe.example.MappedFaweQueue;
import com.boydti.fawe.object.FaweQueue;
import com.boydti.fawe.object.HasFaweQueue;
import com.boydti.fawe.object.exception.FaweException;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.function.RegionFunction;
import com.sk89q.worldedit.function.operation.Operation;
@ -34,7 +27,6 @@ import com.sk89q.worldedit.function.operation.RunContext;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.Region;
import java.util.Iterator;
import java.util.List;
/**
@ -46,7 +38,6 @@ public class RegionVisitor implements Operation {
public final RegionFunction function;
public int affected = 0;
public final Iterable<? extends BlockVector3> iterable;
private final MappedFaweQueue queue;
/**
* Deprecated in favor of the other constructors which will preload chunks during iteration
@ -56,22 +47,14 @@ public class RegionVisitor implements Operation {
*/
@Deprecated
public RegionVisitor(Region region, RegionFunction function) {
this(region, function, (FaweQueue) null);
this((Iterable<BlockVector3>) region, function);
}
public RegionVisitor(Region region, RegionFunction function, EditSession editSession) {
this(region, function, editSession != null ? editSession.getQueue() : null);
}
public RegionVisitor(Region region, RegionFunction function, FaweQueue queue) {
this((Iterable<BlockVector3>) region, function, queue);
}
public RegionVisitor(Iterable<? extends BlockVector3> iterable, RegionFunction function, HasFaweQueue hasQueue) {
@Deprecated
public RegionVisitor(Iterable<BlockVector3> iterable, RegionFunction function) {
this.region = iterable instanceof Region ? (Region) iterable : null;
this.function = function;
this.iterable = iterable;
this.queue = hasQueue != null && hasQueue.getQueue() instanceof MappedFaweQueue ? (MappedFaweQueue) hasQueue.getQueue() : null;
}
/**
@ -85,100 +68,8 @@ public class RegionVisitor implements Operation {
@Override
public Operation resume(RunContext run) throws WorldEditException {
if (queue != null && Settings.IMP.QUEUE.PRELOAD_CHUNKS > 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.IMP.QUEUE.PRELOAD_CHUNKS;
try {
for (; ; ) {
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;
}
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;
queue.queueChunkLoad(vcx, vcz);
count++;
}
// Skip the next 15 blocks
leadIter.next();
leadIter.next();
leadIter.next();
leadIter.next();
leadIter.next();
leadIter.next();
leadIter.next();
leadIter.next();
leadIter.next();
leadIter.next();
leadIter.next();
leadIter.next();
leadIter.next();
leadIter.next();
leadIter.next();
}
}
apply(trailIter.next());
apply(trailIter.next());
apply(trailIter.next());
apply(trailIter.next());
apply(trailIter.next());
apply(trailIter.next());
apply(trailIter.next());
apply(trailIter.next());
apply(trailIter.next());
apply(trailIter.next());
apply(trailIter.next());
apply(trailIter.next());
apply(trailIter.next());
apply(trailIter.next());
apply(trailIter.next());
}
} catch (FaweException e) {
throw new RuntimeException(e);
} catch (Throwable ignore) {
ignore.printStackTrace();
}
try {
while (true) {
apply(trailIter.next());
apply(trailIter.next());
}
} catch (FaweException e) {
throw new RuntimeException(e);
} catch (Throwable ignore) {
}
} else {
for (BlockVector3 pt : iterable) {
apply(pt);
}
for (BlockVector3 pt : iterable) {
apply(pt);
}
return null;
}