mirror of
https://github.com/boy0001/FastAsyncWorldedit.git
synced 2025-01-04 07:28:17 +01:00
Optimize anvil delete
This commit is contained in:
parent
ecedd05651
commit
974cb3fdaf
@ -3,6 +3,7 @@ package com.boydti.fawe.command;
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.FaweCache;
|
||||
import com.boydti.fawe.config.BBC;
|
||||
import com.boydti.fawe.jnbt.NBTStreamer;
|
||||
import com.boydti.fawe.jnbt.anvil.MCAChunk;
|
||||
import com.boydti.fawe.jnbt.anvil.MCAClipboard;
|
||||
import com.boydti.fawe.jnbt.anvil.MCAFile;
|
||||
@ -12,6 +13,9 @@ import com.boydti.fawe.jnbt.anvil.MCAQueue;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.object.FaweQueue;
|
||||
import com.boydti.fawe.object.RegionWrapper;
|
||||
import com.boydti.fawe.object.RunnableVal;
|
||||
import com.boydti.fawe.object.RunnableVal2;
|
||||
import com.boydti.fawe.object.RunnableVal4;
|
||||
import com.boydti.fawe.object.mask.FaweBlockMatcher;
|
||||
import com.boydti.fawe.object.number.MutableLong;
|
||||
import com.boydti.fawe.util.ArrayUtil;
|
||||
@ -44,6 +48,8 @@ import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ForkJoinPool;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
@ -101,7 +107,7 @@ public class AnvilCommands {
|
||||
max = 3
|
||||
)
|
||||
@CommandPermissions("worldedit.anvil.deleteallold")
|
||||
public void deleteAllOld(Player player, EditSession editSession, String folder, int inhabitedTicks, @Optional("60000") int fileAgeMillis) throws WorldEditException {
|
||||
public void deleteAllOld(Player player, String folder, int inhabitedTicks, @Optional("60000") int fileAgeMillis) throws WorldEditException {
|
||||
FaweQueue defaultQueue = SetQueue.IMP.getNewQueue(folder, true, false);
|
||||
MCAQueue queue = new MCAQueue(folder, defaultQueue.getSaveFolder(), defaultQueue.hasSky());
|
||||
MCAFilterCounter result = queue.filterWorld(new MCAFilterCounter() {
|
||||
@ -115,16 +121,56 @@ public class AnvilCommands {
|
||||
if (modified - creation < fileAgeMillis) {
|
||||
mca.setDeleted(true);
|
||||
get().add(512 * 512 * 256);
|
||||
return null;
|
||||
}
|
||||
} catch (IOException | UnsupportedOperationException ignore) {}
|
||||
return mca;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MCAChunk applyChunk(MCAChunk chunk, MutableLong count) {
|
||||
if (chunk.getInhabitedTime() <= inhabitedTicks) {
|
||||
count.add(16 * 16 * 256);
|
||||
chunk.setDeleted(true);
|
||||
try {
|
||||
ForkJoinPool pool = new ForkJoinPool();
|
||||
mca.init();
|
||||
mca.forEachSortedChunk(new RunnableVal4<Integer, Integer, Integer, Integer>() {
|
||||
@Override
|
||||
public void run(Integer x, Integer z, Integer offset, Integer size) {
|
||||
try {
|
||||
byte[] bytes = mca.getChunkCompressedBytes(offset);
|
||||
if (bytes == null) return;
|
||||
Runnable task = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
mca.streamChunk(offset, new RunnableVal<NBTStreamer>() {
|
||||
@Override
|
||||
public void run(NBTStreamer value) {
|
||||
value.addReader(".Level.InhabitedTime", new RunnableVal2<Integer, Long>() {
|
||||
@Override
|
||||
public void run(Integer index, Long value) {
|
||||
if (value <= inhabitedTicks) {
|
||||
MCAChunk chunk = new MCAChunk(queue, x, z);
|
||||
chunk.setDeleted(true);
|
||||
synchronized (mca) {
|
||||
mca.setChunk(chunk);
|
||||
}
|
||||
get().add(16 * 16 * 256);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
};
|
||||
pool.submit(task);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
pool.awaitQuiescence(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
|
||||
mca.close(pool);
|
||||
pool.shutdown();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
package com.boydti.fawe.jnbt;
|
||||
|
||||
import com.boydti.fawe.config.BBC;
|
||||
import com.boydti.fawe.object.RunnableVal2;
|
||||
import com.boydti.fawe.object.exception.FaweException;
|
||||
import com.sk89q.jnbt.NBTInputStream;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
|
||||
@ -26,6 +26,21 @@ public class NBTStreamer {
|
||||
is.close();
|
||||
}
|
||||
|
||||
public void readQuick() throws IOException {
|
||||
try {
|
||||
is.readNamedTagLazy(new RunnableVal2<String, RunnableVal2>() {
|
||||
@Override
|
||||
public void run(String node, RunnableVal2 result) {
|
||||
if (readers.isEmpty()) {
|
||||
throw new FaweException(BBC.WORLDEDIT_CANCEL_REASON_MANUAL);
|
||||
}
|
||||
this.value2 = readers.remove(node);
|
||||
}
|
||||
});
|
||||
} catch (FaweException ignore) {}
|
||||
is.close();
|
||||
}
|
||||
|
||||
public <T, V> void addReader(String node, RunnableVal2<T, V> run) {
|
||||
if (run instanceof NBTStreamReader) {
|
||||
((NBTStreamReader) run).init(node);
|
||||
|
@ -52,6 +52,51 @@ public class MCAChunk extends FaweChunk<Void> {
|
||||
private int modified;
|
||||
private boolean deleted;
|
||||
|
||||
public MCAChunk(FaweQueue queue, int x, int z) {
|
||||
super(queue, x, z);
|
||||
this.ids = new byte[16][];
|
||||
this.data = new byte[16][];
|
||||
this.skyLight = new byte[16][];
|
||||
this.blockLight = new byte[16][];
|
||||
this.biomes = new byte[256];
|
||||
this.tiles = new HashMap<>();
|
||||
this.entities = new HashMap<>();
|
||||
this.lastUpdate = System.currentTimeMillis();
|
||||
this.heightMap = new int[256];
|
||||
this.setModified();
|
||||
}
|
||||
|
||||
public MCAChunk(MCAChunk parent, boolean shallow) {
|
||||
super(parent.getParent(), parent.getX(), parent.getZ());
|
||||
if (shallow) {
|
||||
this.ids = parent.ids;
|
||||
this.data = parent.data;
|
||||
this.skyLight = parent.skyLight;
|
||||
this.blockLight = parent.blockLight;
|
||||
this.biomes = parent.biomes;
|
||||
this.tiles = parent.tiles;
|
||||
this.entities = parent.entities;
|
||||
this.inhabitedTime = parent.inhabitedTime;
|
||||
this.lastUpdate = parent.lastUpdate;
|
||||
this.heightMap = parent.heightMap;
|
||||
this.modified = parent.modified;
|
||||
this.deleted = parent.deleted;
|
||||
} else {
|
||||
this.ids = (byte[][]) MainUtil.copyNd(parent.ids);
|
||||
this.data = (byte[][]) MainUtil.copyNd(parent.data);
|
||||
this.skyLight = (byte[][]) MainUtil.copyNd(parent.skyLight);
|
||||
this.blockLight = (byte[][]) MainUtil.copyNd(parent.blockLight);
|
||||
this.biomes = parent.biomes.clone();
|
||||
this.tiles = new HashMap<>(parent.tiles);
|
||||
this.entities = new HashMap<>(parent.entities);
|
||||
this.inhabitedTime = parent.inhabitedTime;
|
||||
this.lastUpdate = parent.lastUpdate;
|
||||
this.heightMap = parent.heightMap.clone();
|
||||
this.modified = parent.modified;
|
||||
this.deleted = parent.deleted;
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] toBytes(byte[] buffer) throws IOException {
|
||||
if (buffer == null) {
|
||||
buffer = new byte[8192];
|
||||
@ -393,51 +438,6 @@ public class MCAChunk extends FaweChunk<Void> {
|
||||
return FaweCache.asTag(root);
|
||||
}
|
||||
|
||||
public MCAChunk(FaweQueue queue, int x, int z) {
|
||||
super(queue, x, z);
|
||||
this.ids = new byte[16][];
|
||||
this.data = new byte[16][];
|
||||
this.skyLight = new byte[16][];
|
||||
this.blockLight = new byte[16][];
|
||||
this.biomes = new byte[256];
|
||||
this.tiles = new HashMap<>();
|
||||
this.entities = new HashMap<>();
|
||||
this.lastUpdate = System.currentTimeMillis();
|
||||
this.heightMap = new int[256];
|
||||
this.setModified();
|
||||
}
|
||||
|
||||
public MCAChunk(MCAChunk parent, boolean shallow) {
|
||||
super(parent.getParent(), parent.getX(), parent.getZ());
|
||||
if (shallow) {
|
||||
this.ids = parent.ids;
|
||||
this.data = parent.data;
|
||||
this.skyLight = parent.skyLight;
|
||||
this.blockLight = parent.blockLight;
|
||||
this.biomes = parent.biomes;
|
||||
this.tiles = parent.tiles;
|
||||
this.entities = parent.entities;
|
||||
this.inhabitedTime = parent.inhabitedTime;
|
||||
this.lastUpdate = parent.lastUpdate;
|
||||
this.heightMap = parent.heightMap;
|
||||
this.modified = parent.modified;
|
||||
this.deleted = parent.deleted;
|
||||
} else {
|
||||
this.ids = (byte[][]) MainUtil.copyNd(parent.ids);
|
||||
this.data = (byte[][]) MainUtil.copyNd(parent.data);
|
||||
this.skyLight = (byte[][]) MainUtil.copyNd(parent.skyLight);
|
||||
this.blockLight = (byte[][]) MainUtil.copyNd(parent.blockLight);
|
||||
this.biomes = parent.biomes.clone();
|
||||
this.tiles = new HashMap<>(parent.tiles);
|
||||
this.entities = new HashMap<>(parent.entities);
|
||||
this.inhabitedTime = parent.inhabitedTime;
|
||||
this.lastUpdate = parent.lastUpdate;
|
||||
this.heightMap = parent.heightMap.clone();
|
||||
this.modified = parent.modified;
|
||||
this.deleted = parent.deleted;
|
||||
}
|
||||
}
|
||||
|
||||
public MCAChunk(NBTInputStream nis, FaweQueue parent, int x, int z, int compressedSize) throws IOException {
|
||||
super(parent, x, z);
|
||||
ids = new byte[16][];
|
||||
|
@ -262,7 +262,7 @@ public class MCAFile {
|
||||
return values;
|
||||
}
|
||||
|
||||
private byte[] getChunkCompressedBytes(int offset) throws IOException{
|
||||
public byte[] getChunkCompressedBytes(int offset) throws IOException{
|
||||
if (offset == 0) {
|
||||
return null;
|
||||
}
|
||||
@ -296,15 +296,28 @@ public class MCAFile {
|
||||
streamChunk(getOffset(cx, cz), addReaders);
|
||||
}
|
||||
|
||||
public void streamChunk(int offset, RunnableVal<NBTStreamer> addReaders) throws IOException {
|
||||
if (offset == 0) {
|
||||
return;
|
||||
public void streamChunk(int offset, RunnableVal<NBTStreamer> withStream) throws IOException {
|
||||
byte[] data = getChunkCompressedBytes(offset);
|
||||
streamChunk(data, withStream);
|
||||
}
|
||||
|
||||
public void streamChunk(byte[] data, RunnableVal<NBTStreamer> withStream) throws IOException {
|
||||
if (data != null) {
|
||||
try {
|
||||
FastByteArrayInputStream nbtIn = new FastByteArrayInputStream(data);
|
||||
FastByteArrayInputStream bais = new FastByteArrayInputStream(data);
|
||||
InflaterInputStream iis = new InflaterInputStream(bais, new Inflater(), 1);
|
||||
fieldBuf2.set(iis, byteStore2.get());
|
||||
BufferedInputStream bis = new BufferedInputStream(iis);
|
||||
NBTInputStream nis = new NBTInputStream(bis);
|
||||
fieldBuf3.set(nis, byteStore3.get());
|
||||
NBTStreamer streamer = new NBTStreamer(nis);
|
||||
withStream.run(streamer);
|
||||
streamer.readQuick();
|
||||
} catch (IllegalAccessException unlikely) {
|
||||
unlikely.printStackTrace();
|
||||
}
|
||||
}
|
||||
NBTInputStream is = getChunkIS(offset);
|
||||
NBTStreamer ns = new NBTStreamer(is);
|
||||
addReaders.run(ns);
|
||||
ns.readFully();
|
||||
is.close();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -340,7 +340,6 @@ public class MCAQueue extends NMSMappedFaweQueue<FaweQueue, FaweChunk, FaweChunk
|
||||
}
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
System.out.println("Failed to load: r." + mcaX + "." + mcaZ + ".mca -> (local) " + rcx + "," + rcz);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user