VirtualWorld cache/optimizations

This commit is contained in:
Jesse Boyd 2018-04-13 19:49:03 +10:00
parent d8d273a163
commit 6c67192fe2
No known key found for this signature in database
GPG Key ID: 59F1DE6293AF6E1F
2 changed files with 31 additions and 12 deletions

View File

@ -17,6 +17,7 @@ public class FaweLimit {
public int SPEED_REDUCTION = Integer.MAX_VALUE; public int SPEED_REDUCTION = Integer.MAX_VALUE;
public boolean FAST_PLACEMENT = false; public boolean FAST_PLACEMENT = false;
public boolean CONFIRM_LARGE = true; public boolean CONFIRM_LARGE = true;
// public boolean[] STRIP_NBT = null;
public static FaweLimit MAX; public static FaweLimit MAX;
@ -65,6 +66,7 @@ public class FaweLimit {
MAX.MAX_EXPRESSION_MS = 50; MAX.MAX_EXPRESSION_MS = 50;
MAX.FAST_PLACEMENT = true; MAX.FAST_PLACEMENT = true;
MAX.CONFIRM_LARGE = true; MAX.CONFIRM_LARGE = true;
// MAX.STRIP_NBT = null;
} }
public boolean MAX_CHANGES() { public boolean MAX_CHANGES() {

View File

@ -41,6 +41,8 @@ import java.util.*;
* An Immutable virtual world used to display & select schematics * An Immutable virtual world used to display & select schematics
*/ */
public class SchemVis extends ImmutableVirtualWorld { public class SchemVis extends ImmutableVirtualWorld {
private static final WeakHashMap<File, Integer> DIMENSION_CACHE = new WeakHashMap<>();
private final WorldData worldData; private final WorldData worldData;
private final Long2ObjectOpenHashMap<Map.Entry<File, Long>> files; private final Long2ObjectOpenHashMap<Map.Entry<File, Long>> files;
@ -260,28 +262,33 @@ public class SchemVis extends ImmutableVirtualWorld {
* @param schemDimensions * @param schemDimensions
* @return * @return
*/ */
private BlockVector2D registerAndGetChunkOffset(BlockVector schemDimensions, File file) { private BlockVector2D registerAndGetChunkOffset(BlockVector2D schemDimensions, File file) {
int chunkX = schemDimensions.getBlockX() >> 4; int chunkX = schemDimensions.getBlockX() >> 4;
int chunkZ = schemDimensions.getBlockZ() >> 4; int chunkZ = schemDimensions.getBlockZ() >> 4;
MutableBlockVector2D pos2 = new MutableBlockVector2D(); MutableBlockVector2D pos2 = new MutableBlockVector2D();
MutableBlockVector2D curPos = lastPos; MutableBlockVector2D curPos = lastPos;
// Find next free position // Find next free position
while (!isAreaFree(curPos, pos2.setComponents(curPos.getBlockX() + chunkX, curPos.getBlockZ() + chunkZ))) { while (!isAreaFree(curPos, pos2.setComponents(curPos.getBlockX() + chunkX, curPos.getBlockZ() + chunkZ))) {
if (curPos == lastPos && !files.containsKey(MathMan.pairInt(curPos.getBlockX(), curPos.getBlockZ()))) { // if (curPos == lastPos && !files.containsKey(MathMan.pairInt(curPos.getBlockX(), curPos.getBlockZ()))) {
curPos = new MutableBlockVector2D(); // curPos = new MutableBlockVector2D();
curPos.setComponents(lastPos.getBlockX(), lastPos.getBlockZ()); // curPos.setComponents(lastPos.getBlockX(), lastPos.getBlockZ());
} // }
curPos.nextPosition(); curPos.nextPosition();
} }
// Register the chunks // Register the chunks
Map.Entry<File, Long> originValue = getEntry(file, MathMan.pairInt(curPos.getBlockX(), curPos.getBlockZ())); Map.Entry<File, Long> originValue = getEntry(file, MathMan.pairInt(curPos.getBlockX(), curPos.getBlockZ()));
long pairX, pos;
for (int x = 0; x <= chunkX; x++) { for (int x = 0; x <= chunkX; x++) {
int xx = curPos.getBlockX() + x;
pairX = ((long) xx) << 32;
for (int z = 0; z <= chunkZ; z++) { for (int z = 0; z <= chunkZ; z++) {
long pos = MathMan.pairInt(curPos.getBlockX() + x, curPos.getBlockZ() + z); int zz = curPos.getBlockZ() + z;
pos = pairX + (zz & 0xffffffffL);
files.put(pos, originValue); files.put(pos, originValue);
} }
} }
return curPos; for (int i = 0; i < Math.min(chunkX, chunkZ); i++) curPos.nextPosition();
return curPos.toBlockVector2D();
} }
private boolean isAreaFree(BlockVector2D chunkPos1, BlockVector2D chunkPos2 /* inclusive */) { private boolean isAreaFree(BlockVector2D chunkPos1, BlockVector2D chunkPos2 /* inclusive */) {
@ -305,9 +312,18 @@ public class SchemVis extends ImmutableVirtualWorld {
public void add(File file) throws IOException { public void add(File file) throws IOException {
File cached = new File(file.getParentFile(), "." + file.getName() + ".cached"); File cached = new File(file.getParentFile(), "." + file.getName() + ".cached");
Integer dimensionPair = DIMENSION_CACHE.get(file);
if (dimensionPair != null) {
int width = (char) MathMan.unpairX(dimensionPair);
int length = (char) MathMan.unpairY(dimensionPair);
BlockVector2D dimensions = new BlockVector2D(width, length);
BlockVector2D offset = registerAndGetChunkOffset(dimensions, cached);
return;
}
if (cached.exists() && file.lastModified() <= cached.lastModified()) { if (cached.exists() && file.lastModified() <= cached.lastModified()) {
try (FileInputStream fis = new FileInputStream(cached)) { try (InputStream fis = new BufferedInputStream(new FileInputStream(cached), 4)) {
BlockVector dimensions = new BlockVector(IOUtil.readVarInt(fis), IOUtil.readVarInt(fis), IOUtil.readVarInt(fis)); BlockVector2D dimensions = new BlockVector2D(IOUtil.readVarInt(fis), IOUtil.readVarInt(fis));
DIMENSION_CACHE.put(file, MathMan.pair((short) dimensions.getBlockX(), (short) dimensions.getBlockZ()));
BlockVector2D offset = registerAndGetChunkOffset(dimensions, cached); BlockVector2D offset = registerAndGetChunkOffset(dimensions, cached);
} }
} else { } else {
@ -321,12 +337,11 @@ public class SchemVis extends ImmutableVirtualWorld {
clipboard.setOrigin(clipboard.getMinimumPoint()); clipboard.setOrigin(clipboard.getMinimumPoint());
try { try {
MCAQueue queue = new MCAQueue(null, null, false); MCAQueue queue = new MCAQueue(null, null, false);
BlockVector dimensions = clipboard.getDimensions().toBlockVector(); BlockVector2D dimensions = clipboard.getDimensions().toVector2D().toBlockVector2D();
BlockVector2D offset = registerAndGetChunkOffset(dimensions, cached); BlockVector2D offset = registerAndGetChunkOffset(dimensions, cached);
new Schematic(clipboard).paste(queue, Vector.ZERO, true); new Schematic(clipboard).paste(queue, Vector.ZERO, true);
try (FileOutputStream fos = new FileOutputStream(cached)) { try (FileOutputStream fos = new FileOutputStream(cached)) {
IOUtil.writeVarInt(fos, dimensions.getBlockX()); IOUtil.writeVarInt(fos, dimensions.getBlockX());
IOUtil.writeVarInt(fos, dimensions.getBlockY());
IOUtil.writeVarInt(fos, dimensions.getBlockZ()); IOUtil.writeVarInt(fos, dimensions.getBlockZ());
try (FaweOutputStream cos = MainUtil.getCompressedOS(fos, 2)) { try (FaweOutputStream cos = MainUtil.getCompressedOS(fos, 2)) {
@ -354,6 +369,8 @@ public class SchemVis extends ImmutableVirtualWorld {
java.nio.file.Files.setAttribute(path, "dos:hidden", Boolean.TRUE, LinkOption.NOFOLLOW_LINKS); java.nio.file.Files.setAttribute(path, "dos:hidden", Boolean.TRUE, LinkOption.NOFOLLOW_LINKS);
} }
} }
DIMENSION_CACHE.put(file, MathMan.pair((short) dimensions.getBlockX(), (short) dimensions.getBlockZ()));
} finally { } finally {
if (clipboard instanceof Closeable) { if (clipboard instanceof Closeable) {
((Closeable) clipboard).close(); ((Closeable) clipboard).close();
@ -398,7 +415,7 @@ public class SchemVis extends ImmutableVirtualWorld {
int OCZ = MathMan.unpairIntY(origin); int OCZ = MathMan.unpairIntY(origin);
try { try {
try (FileInputStream fis = new FileInputStream(cached)) { try (FileInputStream fis = new FileInputStream(cached)) {
BlockVector dimensions = new BlockVector(IOUtil.readVarInt(fis), IOUtil.readVarInt(fis), IOUtil.readVarInt(fis)); BlockVector2D dimensions = new BlockVector2D(IOUtil.readVarInt(fis), IOUtil.readVarInt(fis));
try (FaweInputStream in = MainUtil.getCompressedIS(fis)) { try (FaweInputStream in = MainUtil.getCompressedIS(fis)) {
try (NBTInputStream nis = new NBTInputStream(in)) { try (NBTInputStream nis = new NBTInputStream(in)) {