Skip to content

Commit ffaf8fb

Browse files
committed
more optimizations
1 parent 08dbf37 commit ffaf8fb

File tree

16 files changed

+48
-45
lines changed

16 files changed

+48
-45
lines changed

src/main/java/net/potato/tuff/TuffX.java

Lines changed: 42 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,11 @@ public class TuffX extends JavaPlugin implements Listener, PluginMessageListener
6363

6464
private ExecutorService chunkProcessorPool;
6565

66+
private final ThreadLocal<Map<BlockData, int[]>> threadLocalConversionCache = ThreadLocal.withInitial(HashMap::new);
67+
private final ThreadLocal<short[]> threadLocalBlockArray = ThreadLocal.withInitial(() -> new short[4096]);
68+
private final ThreadLocal<byte[]> threadLocalLightArray = ThreadLocal.withInitial(() -> new byte[4096]);
69+
private final ThreadLocal<ByteArrayOutputStream> threadLocalOutStream = ThreadLocal.withInitial(() -> new ByteArrayOutputStream(8256));
70+
6671
private void logDebug(String message) {
6772
if (debug) getLogger().log(Level.INFO, "[TuffX-Debug] " + message);
6873
}
@@ -239,48 +244,27 @@ public void run() {
239244

240245
for (int i = 0; i < CHUNKS_PER_TICK && !queue.isEmpty(); i++) {
241246
Vector vec = queue.poll();
242-
if (vec != null) {
243-
World world = player.getWorld();
244-
WorldChunkKey key = new WorldChunkKey(world.getName(), vec.getBlockX(), vec.getBlockZ());
245-
246-
List<byte[]> cachedData = chunkPayloadCache.getIfPresent(key);
247-
248-
if (cachedData != null) {
249-
logDebug("Cache HIT for chunk: " + key);
250-
sendPayloadsToPlayer(player, cachedData);
251-
checkIfInitialLoadComplete(player);
252-
} else {
253-
logDebug("Cache MISS for chunk: " + key + ". Generating...");
254-
new BukkitRunnable() {
255-
@Override
256-
public void run() {
257-
if (world.isChunkLoaded(key.x(), key.z())) {
258-
processAndSendChunk(player, world.getChunkAt(key.x(), key.z()));
259-
} else {
260-
world.loadChunk(key.x(), key.z(), true);
261-
processAndSendChunk(player, world.getChunkAt(key.x(), key.z()));
262-
}
263-
}
264-
}.runTaskAsynchronously(TuffX.this);
265-
}
247+
if (vec == null) continue;
248+
249+
World world = player.getWorld();
250+
WorldChunkKey key = new WorldChunkKey(world.getName(), vec.getBlockX(), vec.getBlockZ());
251+
252+
List<byte[]> cachedData = chunkPayloadCache.getIfPresent(key);
253+
if (cachedData != null) {
254+
sendPayloadsToPlayer(player, cachedData);
255+
checkIfInitialLoadComplete(player);
256+
continue;
266257
}
267-
}
268-
}
269-
}
270-
}.runTaskTimer(this, 0L, 1L);
271-
}
272258

273-
private void sendPayloadsToPlayer(Player player, List<byte[]> payloads) {
274-
new BukkitRunnable() {
275-
@Override
276-
public void run() {
277-
if (player.isOnline()) {
278-
for (byte[] payload : payloads) {
279-
player.sendPluginMessage(TuffX.this, CHANNEL, payload);
259+
if (world.isChunkLoaded(key.x(), key.z())) {
260+
processAndSendChunk(player, world.getChunkAt(key.x(), key.z()));
261+
} else {
262+
queue.add(vec);
263+
}
280264
}
281265
}
282266
}
283-
}.runTask(this);
267+
}.runTaskTimer(this, 0L, 1L);
284268
}
285269

286270
@EventHandler(priority = EventPriority.MONITOR)
@@ -315,7 +299,8 @@ private void processAndSendChunk(final Player player, final Chunk chunk) {
315299
chunkProcessorPool.submit(() -> {
316300
final List<byte[]> processedPayloads = new ArrayList<>();
317301
final ChunkSnapshot snapshot = chunk.getChunkSnapshot(true, false, false);
318-
final Map<BlockData, int[]> conversionCache = new HashMap<>();
302+
final Map<BlockData, int[]> conversionCache = threadLocalConversionCache.get();
303+
conversionCache.clear();
319304

320305
for (int sectionY = -4; sectionY < 0; sectionY++) {
321306
if (!player.isOnline()) {
@@ -347,6 +332,19 @@ public void run() {
347332
});
348333
}
349334

335+
private void sendPayloadsToPlayer(Player player, List<byte[]> payloads) {
336+
new BukkitRunnable() {
337+
@Override
338+
public void run() {
339+
if (player.isOnline()) {
340+
for (byte[] payload : payloads) {
341+
player.sendPluginMessage(TuffX.this, CHANNEL, payload);
342+
}
343+
}
344+
}
345+
}.runTask(this);
346+
}
347+
350348
private void invalidateChunkCache(World world, int blockX, int blockZ) {
351349
WorldChunkKey key = new WorldChunkKey(world.getName(), blockX >> 4, blockZ >> 4);
352350
chunkPayloadCache.invalidate(key);
@@ -404,8 +402,8 @@ private byte[] createWelcomePayload(String message, int someNumber) {
404402
}
405403

406404
private byte[] createSectionPayload(ChunkSnapshot snapshot, int cx, int cz, int sectionY, Map<BlockData, int[]> cache) throws IOException {
407-
short[] blockDataArray = new short[4096];
408-
byte[] lightDataArray = new byte[4096];
405+
short[] blockDataArray = threadLocalBlockArray.get();
406+
byte[] lightDataArray = threadLocalLightArray.get();
409407

410408
boolean hasAnythingToSend = false;
411409
int baseY = sectionY * 16;
@@ -436,10 +434,11 @@ private byte[] createSectionPayload(ChunkSnapshot snapshot, int cx, int cz, int
436434
if (!hasAnythingToSend) {
437435
return null;
438436
}
437+
438+
ByteArrayOutputStream bout = threadLocalOutStream.get();
439+
bout.reset();
439440

440-
try (ByteArrayOutputStream bout = new ByteArrayOutputStream(8256);
441-
DataOutputStream out = new DataOutputStream(bout)) {
442-
441+
try (DataOutputStream out = new DataOutputStream(bout)) {
443442
out.writeUTF("chunk_data");
444443
out.writeInt(cx);
445444
out.writeInt(cz);

target/TuffX.jar

-652 Bytes
Binary file not shown.

target/classes/config.yml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,9 @@ enabled-worlds:
1010

1111
#the amount of threads for the chunk processor to use - using more threads processes chunks faster, but increases CPU usage
1212
#-1 is automatic
13-
chunk-processor-threads: -1
13+
chunk-processor-threads: -1
14+
15+
#the size of the cache
16+
cache-size: 512
17+
#how long until the cache expires (minutes)
18+
cache-expiration: 5
0 Bytes
Binary file not shown.
-1.39 KB
Binary file not shown.
-595 Bytes
Binary file not shown.
97 Bytes
Binary file not shown.
-97 Bytes
Binary file not shown.
0 Bytes
Binary file not shown.
0 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)