Various minor

Add extra info to debugpaste
Optimize nmsrelighter
This commit is contained in:
Jesse Boyd 2017-07-06 15:49:56 +10:00
parent e6e1a3c45f
commit ded70ab9e0
No known key found for this signature in database
GPG Key ID: 59F1DE6293AF6E1F
5 changed files with 139 additions and 75 deletions

View File

@ -21,6 +21,7 @@ import com.boydti.fawe.object.FaweQueue;
import com.boydti.fawe.regions.FaweMaskManager; import com.boydti.fawe.regions.FaweMaskManager;
import com.boydti.fawe.util.MainUtil; import com.boydti.fawe.util.MainUtil;
import com.boydti.fawe.util.ReflectionUtils; import com.boydti.fawe.util.ReflectionUtils;
import com.boydti.fawe.util.StringMan;
import com.boydti.fawe.util.TaskManager; import com.boydti.fawe.util.TaskManager;
import com.sk89q.worldedit.bukkit.BukkitWorld; import com.sk89q.worldedit.bukkit.BukkitWorld;
import com.sk89q.worldedit.bukkit.EditSessionBlockChangeDelegate; import com.sk89q.worldedit.bukkit.EditSessionBlockChangeDelegate;
@ -36,6 +37,7 @@ import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel; import java.nio.channels.ReadableByteChannel;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.List;
import java.util.UUID; import java.util.UUID;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.command.ConsoleCommandSender; import org.bukkit.command.ConsoleCommandSender;
@ -192,6 +194,18 @@ public class FaweBukkit implements IFawe, Listener {
} }
} }
@Override
public String getDebugInfo() {
StringBuilder msg = new StringBuilder();
List<String> pl = new ArrayList<>();
for (Plugin p : Bukkit.getPluginManager().getPlugins()) {
pl.add(p.getName());
}
msg.append("server.plugins: \n - " + StringMan.join(pl, " - ") + "\n");
msg.append("server.version: " + Bukkit.getVersion() + " / " + Bukkit.getBukkitVersion());
return msg.toString();
}
/** /**
* The task manager handles sync/async tasks * The task manager handles sync/async tasks
*/ */

View File

@ -40,4 +40,8 @@ public interface IFawe {
public String getName(UUID uuid); public String getName(UUID uuid);
public Object getBlocksHubApi(); public Object getBlocksHubApi();
public default String getDebugInfo() {
return "";
}
} }

View File

@ -8,7 +8,6 @@ import com.boydti.fawe.object.IntegerTrio;
import com.boydti.fawe.object.RunnableVal; import com.boydti.fawe.object.RunnableVal;
import com.boydti.fawe.util.MathMan; import com.boydti.fawe.util.MathMan;
import com.boydti.fawe.util.TaskManager; import com.boydti.fawe.util.TaskManager;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import java.util.ArrayDeque; import java.util.ArrayDeque;
import java.util.ArrayList; import java.util.ArrayList;
@ -19,14 +18,21 @@ import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Queue; import java.util.Queue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicBoolean;
public class NMSRelighter implements Relighter { public class NMSRelighter implements Relighter {
private final NMSMappedFaweQueue queue; private final NMSMappedFaweQueue queue;
private final Map<Long, RelightSkyEntry> skyToRelight; private final Map<Long, RelightSkyEntry> skyToRelight;
private final Map<Long, Map<Integer, Object>> lightQueue;
private final Object present = new Object(); private final Object present = new Object();
private final Map<Long, Integer> chunksToSend; private final Map<Long, Integer> chunksToSend;
private final ConcurrentLinkedQueue<RelightSkyEntry> queuedSkyToRelight = new ConcurrentLinkedQueue<>();
private final Map<Long, long[][][] /* z y x */ > lightQueue;
private final AtomicBoolean lightLock = new AtomicBoolean(false);
private final ConcurrentHashMap<Long, long[][][]> concurrentLightQueue;
private final int maxY; private final int maxY;
private volatile boolean relighting = false; private volatile boolean relighting = false;
@ -40,31 +46,77 @@ public class NMSRelighter implements Relighter {
this.skyToRelight = new Long2ObjectOpenHashMap<>(); this.skyToRelight = new Long2ObjectOpenHashMap<>();
this.lightQueue = new Long2ObjectOpenHashMap<>(); this.lightQueue = new Long2ObjectOpenHashMap<>();
this.chunksToSend = new Long2ObjectOpenHashMap<>(); this.chunksToSend = new Long2ObjectOpenHashMap<>();
this.concurrentLightQueue = new ConcurrentHashMap<>();
this.maxY = queue.getMaxY(); this.maxY = queue.getMaxY();
} }
@Override @Override
public boolean isEmpty() { public boolean isEmpty() {
return skyToRelight.isEmpty() && lightQueue.isEmpty(); return skyToRelight.isEmpty() && lightQueue.isEmpty() && queuedSkyToRelight.isEmpty() && concurrentLightQueue.isEmpty();
} }
public synchronized boolean addChunk(int cx, int cz, byte[] fix, int bitmask) { private void set(int x, int y, int z, long[][][] map) {
long pair = MathMan.pairInt(cx, cz); long[][] m1 = map[z];
if (m1 == null) {
m1 = map[z] = new long[16][];
}
long[] m2 = m1[x];
if (m2 == null) {
m2 = m1[x] = new long[4];
}
long value = m2[y >> 6] |= 1l << y;
}
public void addLightUpdate(int x, int y, int z) {
long index = MathMan.pairInt(x >> 4, z >> 4);
if (lightLock.compareAndSet(false, true)) {
synchronized (lightQueue) {
try {
long[][][] currentMap = lightQueue.get(index);
if (currentMap == null) {
currentMap = new long[16][][];
this.lightQueue.put(index, currentMap);
}
set(x & 15, y, z & 15, currentMap);
} finally {
lightLock.set(false);
}
}
} else {
long[][][] currentMap = concurrentLightQueue.get(index);
if (currentMap == null) {
currentMap = new long[16][][];
this.concurrentLightQueue.put(index, currentMap);
}
set(x & 15, y, z & 15, currentMap);
}
}
public boolean addChunk(int cx, int cz, byte[] fix, int bitmask) {
RelightSkyEntry toPut = new RelightSkyEntry(cx, cz, fix, bitmask); RelightSkyEntry toPut = new RelightSkyEntry(cx, cz, fix, bitmask);
RelightSkyEntry existing = skyToRelight.put(pair, toPut); queuedSkyToRelight.add(toPut);
if (existing != null) {
toPut.bitmask |= existing.bitmask;
if (fix != null) {
for (int i = 0; i < fix.length; i++) {
toPut.fix[i] &= existing.fix[i];
}
}
}
return true; return true;
} }
private synchronized Map<Long, RelightSkyEntry> getSkyMap() {
RelightSkyEntry entry;
while ((entry = queuedSkyToRelight.poll()) != null) {
long pair = MathMan.pairInt(entry.x, entry.z);
RelightSkyEntry existing = skyToRelight.put(pair, entry);
if (existing != null) {
entry.bitmask |= existing.bitmask;
if (entry.fix != null) {
for (int i = 0; i < entry.fix.length; i++) {
entry.fix[i] &= existing.fix[i];
}
}
}
}
return skyToRelight;
}
public synchronized void removeLighting() { public synchronized void removeLighting() {
Iterator<Map.Entry<Long, RelightSkyEntry>> iter = skyToRelight.entrySet().iterator(); Iterator<Map.Entry<Long, RelightSkyEntry>> iter = getSkyMap().entrySet().iterator();
while (iter.hasNext()) { while (iter.hasNext()) {
Map.Entry<Long, RelightSkyEntry> entry = iter.next(); Map.Entry<Long, RelightSkyEntry> entry = iter.next();
RelightSkyEntry chunk = entry.getValue(); RelightSkyEntry chunk = entry.getValue();
@ -78,7 +130,7 @@ public class NMSRelighter implements Relighter {
} }
} }
public synchronized void updateBlockLight(Map<Long, Map<Integer, Object>> map) { public synchronized void updateBlockLight(Map<Long, long[][][]> map) {
int size = map.size(); int size = map.size();
if (size == 0) { if (size == 0) {
return; return;
@ -88,21 +140,30 @@ public class NMSRelighter implements Relighter {
Map<IntegerTrio, Object> visited = new HashMap<>(); Map<IntegerTrio, Object> visited = new HashMap<>();
Map<IntegerTrio, Object> removalVisited = new HashMap<>(); Map<IntegerTrio, Object> removalVisited = new HashMap<>();
Iterator<Map.Entry<Long, Map<Integer, Object>>> iter = map.entrySet().iterator(); Iterator<Map.Entry<Long, long[][][]>> iter = map.entrySet().iterator();
while (iter.hasNext() && size-- > 0) { while (iter.hasNext() && size-- > 0) {
Map.Entry<Long, Map<Integer, Object>> entry = iter.next(); Map.Entry<Long, long[][][]> entry = iter.next();
long index = entry.getKey(); long index = entry.getKey();
Map<Integer, Object> blocks = entry.getValue(); long[][][] blocks = entry.getValue();
int chunkX = MathMan.unpairIntX(index); int chunkX = MathMan.unpairIntX(index);
int chunkZ = MathMan.unpairIntY(index); int chunkZ = MathMan.unpairIntY(index);
int bx = chunkX << 4; int bx = chunkX << 4;
int bz = chunkZ << 4; int bz = chunkZ << 4;
for (int blockHash : blocks.keySet()) { for (int lz = 0; lz < blocks.length; lz++) {
int x = (blockHash >> 12 & 0xF) + bx; long[][] m1 = blocks[lz];
int y = (blockHash & 0xFF); if (m1 == null) continue;
int z = (blockHash >> 8 & 0xF) + bz; for (int lx = 0; lx < m1.length; lx++) {
int lcx = x & 0xF; long[] m2 = m1[lx];
int lcz = z & 0xF; if (m2 == null) continue;
for (int i = 0; i < m2.length; i++) {
int yStart = i << 6;
long value = m2[i];
if (value != 0) {
for (int j = 0; j < 64; j++) {
if (((value >> j) & 1) == 1) {
int x = lx + bx;
int y = yStart + j;
int z = lz + bz;
int oldLevel = queue.getEmmittedLight(x, y, z); int oldLevel = queue.getEmmittedLight(x, y, z);
int newLevel = queue.getBrightness(x, y, z); int newLevel = queue.getBrightness(x, y, z);
if (oldLevel != newLevel) { if (oldLevel != newLevel) {
@ -117,6 +178,11 @@ public class NMSRelighter implements Relighter {
} }
} }
} }
}
}
}
}
}
iter.remove(); iter.remove();
} }
@ -194,18 +260,6 @@ public class NMSRelighter implements Relighter {
} }
} }
public synchronized void addLightUpdate(int x, int y, int z) {
long index = MathMan.pairInt((int) x >> 4, (int) z >> 4);
Map<Integer, Object> currentMap = lightQueue.get(index);
if (currentMap == null) {
currentMap = new Int2ObjectOpenHashMap<>();
synchronized (this) {
this.lightQueue.put(index, currentMap);
}
}
currentMap.put((int) MathMan.tripleBlockCoord(x, y, z), present);
}
public void fixLightingSafe(boolean sky) { public void fixLightingSafe(boolean sky) {
try { try {
if (sky) { if (sky) {
@ -219,7 +273,14 @@ public class NMSRelighter implements Relighter {
} }
public void fixBlockLighting() { public void fixBlockLighting() {
synchronized (lightQueue) {
while (!lightLock.compareAndSet(false, true));
try {
updateBlockLight(this.lightQueue); updateBlockLight(this.lightQueue);
} finally {
lightLock.set(false);
}
}
} }
public synchronized void sendChunks() { public synchronized void sendChunks() {
@ -251,8 +312,9 @@ public class NMSRelighter implements Relighter {
public synchronized void fixSkyLighting() { public synchronized void fixSkyLighting() {
// Order chunks // Order chunks
ArrayList<RelightSkyEntry> chunksList = new ArrayList<>(skyToRelight.size()); Map<Long, RelightSkyEntry> map = getSkyMap();
Iterator<Map.Entry<Long, RelightSkyEntry>> iter = skyToRelight.entrySet().iterator(); ArrayList<RelightSkyEntry> chunksList = new ArrayList<>(map.size());
Iterator<Map.Entry<Long, RelightSkyEntry>> iter = map.entrySet().iterator();
while (iter.hasNext()) { while (iter.hasNext()) {
Map.Entry<Long, RelightSkyEntry> entry = iter.next(); Map.Entry<Long, RelightSkyEntry> entry = iter.next();
chunksToSend.put(entry.getKey(), entry.getValue().bitmask); chunksToSend.put(entry.getKey(), entry.getValue().bitmask);
@ -433,22 +495,6 @@ public class NMSRelighter implements Relighter {
return true; return true;
} }
private class RelightBlockEntry {
public long coord;
public RelightBlockEntry(long pair) {
this.coord = pair;
}
public int getX() {
return MathMan.unpairIntX(coord);
}
public int getZ() {
return MathMan.unpairIntY(coord);
}
}
private class RelightSkyEntry implements Comparable { private class RelightSkyEntry implements Comparable {
public final int x; public final int x;
public final int z; public final int z;

View File

@ -85,7 +85,8 @@ public class HastebinUtility {
b.append("links.commands_yml: ").append(commandsYML).append('\n'); b.append("links.commands_yml: ").append(commandsYML).append('\n');
b.append("links.latest_log: ").append(latestLOG).append('\n'); b.append("links.latest_log: ").append(latestLOG).append('\n');
b.append("\n# Server Information\n"); b.append("\n# Server Information\n");
b.append("version.server: ").append(Fawe.imp().getPlatform()).append('\n'); b.append("server.platform: ").append(Fawe.imp().getPlatform()).append('\n');
b.append(Fawe.imp().getDebugInfo()).append('\n');
b.append("\n\n# YAY! Now, let's see what we can find in your JVM\n"); b.append("\n\n# YAY! Now, let's see what we can find in your JVM\n");
Runtime runtime = Runtime.getRuntime(); Runtime runtime = Runtime.getRuntime();
b.append("memory.free: ").append(runtime.freeMemory()).append('\n'); b.append("memory.free: ").append(runtime.freeMemory()).append('\n');

View File

@ -2390,7 +2390,6 @@ public class EditSession extends AbstractWorld implements HasFaweQueue, Lighting
int px = pos.getBlockX(); int px = pos.getBlockX();
int py = pos.getBlockY(); int py = pos.getBlockY();
int pz = pos.getBlockZ(); int pz = pos.getBlockZ();
MutableBlockVector mutable = new MutableBlockVector();
final int ceilRadiusX = (int) Math.ceil(radiusX); final int ceilRadiusX = (int) Math.ceil(radiusX);
final int ceilRadiusY = (int) Math.ceil(radiusY); final int ceilRadiusY = (int) Math.ceil(radiusY);
@ -2433,14 +2432,14 @@ public class EditSession extends AbstractWorld implements HasFaweQueue, Lighting
} }
} }
this.setBlock(mutable.setComponents(px + x, py + y, pz + z), block); this.setBlock(px + x, py + y, pz + z, block);
this.setBlock(mutable.setComponents(px - x, py + y, pz + z), block); this.setBlock(px - x, py + y, pz + z, block);
this.setBlock(mutable.setComponents(px + x, py - y, pz + z), block); this.setBlock(px + x, py - y, pz + z, block);
this.setBlock(mutable.setComponents(px + x, py + y, pz - z), block); this.setBlock(px + x, py + y, pz - z, block);
this.setBlock(mutable.setComponents(px - x, py - y, pz + z), block); this.setBlock(px - x, py - y, pz + z, block);
this.setBlock(mutable.setComponents(px + x, py - y, pz - z), block); this.setBlock(px + x, py - y, pz - z, block);
this.setBlock(mutable.setComponents(px - x, py + y, pz - z), block); this.setBlock(px - x, py + y, pz - z, block);
this.setBlock(mutable.setComponents(px - x, py - y, pz - z), block); this.setBlock(px - x, py - y, pz - z, block);
} }
} }
} }