From 2a1bfa23607c17de24e4ccda12c64cac94b483e0 Mon Sep 17 00:00:00 2001 From: rfresh2 <89827146+rfresh2@users.noreply.github.com> Date: Wed, 4 Dec 2024 18:51:15 -0800 Subject: [PATCH 1/2] update sqlite and use batched inserts --- .../highlights/ChunkHighlightDatabase.java | 17 ++++++++--------- settings.gradle.kts | 2 +- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/common/src/main/java/xaeroplus/feature/render/highlights/ChunkHighlightDatabase.java b/common/src/main/java/xaeroplus/feature/render/highlights/ChunkHighlightDatabase.java index 569e3b15..bb200e9a 100644 --- a/common/src/main/java/xaeroplus/feature/render/highlights/ChunkHighlightDatabase.java +++ b/common/src/main/java/xaeroplus/feature/render/highlights/ChunkHighlightDatabase.java @@ -83,16 +83,15 @@ public void insertHighlightList(final List chunks, final Res private void insertHighlightsListInternal(final List chunks, final ResourceKey dimension) { try { - StringBuilder sb = new StringBuilder("INSERT OR IGNORE INTO \"" + getTableName(dimension) + "\" VALUES "); - for (int i = 0; i < chunks.size(); i++) { - ChunkHighlightData chunk = chunks.get(i); - sb.append("(").append(chunk.x()).append(", ").append(chunk.z()).append(", ").append(chunk.foundTime()).append(")"); - if (i < chunks.size() - 1) { - sb.append(", "); + try (var ps = connection.prepareStatement("INSERT OR IGNORE INTO \"" + getTableName(dimension) + "\" VALUES (?, ?, ?)")) { + for (int i = 0; i < chunks.size(); i++) { + final ChunkHighlightData chunk = chunks.get(i); + ps.setInt(1, chunk.x()); + ps.setInt(2, chunk.z()); + ps.setLong(3, chunk.foundTime()); + ps.addBatch(); } - } - try (var stmt = connection.createStatement()) { - stmt.executeUpdate(sb.toString()); + ps.executeBatch(); } } catch (Exception e) { XaeroPlus.LOGGER.error("Error inserting {} chunks into {} database in dimension: {}", chunks.size(), databaseName, dimension.location(), e); diff --git a/settings.gradle.kts b/settings.gradle.kts index f74595fe..e1131e66 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -37,7 +37,7 @@ dependencyResolutionManagement { library("balm-forge", "maven.modrinth:balm:7.3.6+forge-1.20.1") library("fabric-waystones", "maven.modrinth:fwaystones:3.3.2+mc1.20.1") library("worldtools", "maven.modrinth:worldtools:1.2.4+1.20.1") - library("sqlite", "org.rfresh.xerial:sqlite-jdbc:3.46.1.0") // relocated xerial sqlite to avoid conflicts with other mods + library("sqlite", "org.rfresh.xerial:sqlite-jdbc:3.47.1.0") // relocated xerial sqlite to avoid conflicts with other mods library("immediatelyfast", "maven.modrinth:immediatelyfast:1.2.18+1.20.4-fabric") library("modmenu", "maven.modrinth:modmenu:7.2.2") library("sodium", "maven.modrinth:sodium:mc1.20.1-0.5.11") From 317c7152e3bb654233685ba0124ae41813b4cf74 Mon Sep 17 00:00:00 2001 From: rfresh2 <89827146+rfresh2@users.noreply.github.com> Date: Wed, 4 Dec 2024 18:59:12 -0800 Subject: [PATCH 2/2] optimize out intermediary highlight list from getter --- .../ChunkHighlightCacheDimensionHandler.java | 13 +++----- .../highlights/ChunkHighlightDatabase.java | 33 ++++++++++++++++++- 2 files changed, 37 insertions(+), 9 deletions(-) diff --git a/common/src/main/java/xaeroplus/feature/render/highlights/ChunkHighlightCacheDimensionHandler.java b/common/src/main/java/xaeroplus/feature/render/highlights/ChunkHighlightCacheDimensionHandler.java index 896c639c..58be4d05 100644 --- a/common/src/main/java/xaeroplus/feature/render/highlights/ChunkHighlightCacheDimensionHandler.java +++ b/common/src/main/java/xaeroplus/feature/render/highlights/ChunkHighlightCacheDimensionHandler.java @@ -44,16 +44,13 @@ public void setWindow(int regionX, int regionZ, int regionSize) { private void loadHighlightsInWindow() { executorService.execute(() -> { - final List chunks = database.getHighlightsInWindow( + synchronized (this.chunks) { + database.getHighlightsInWindow( dimension, windowRegionX - windowRegionSize, windowRegionX + windowRegionSize, - windowRegionZ - windowRegionSize, windowRegionZ + windowRegionSize - ); - synchronized (this.chunks) { - for (int i = 0; i < chunks.size(); i++) { - final ChunkHighlightData chunk = chunks.get(i); - this.chunks.put(chunkPosToLong(chunk.x(), chunk.z()), chunk.foundTime()); - } + windowRegionZ - windowRegionSize, windowRegionZ + windowRegionSize, + (x, y, time) -> this.chunks.put(chunkPosToLong(x, y), time) + ); } }); } diff --git a/common/src/main/java/xaeroplus/feature/render/highlights/ChunkHighlightDatabase.java b/common/src/main/java/xaeroplus/feature/render/highlights/ChunkHighlightDatabase.java index bb200e9a..7be28633 100644 --- a/common/src/main/java/xaeroplus/feature/render/highlights/ChunkHighlightDatabase.java +++ b/common/src/main/java/xaeroplus/feature/render/highlights/ChunkHighlightDatabase.java @@ -112,7 +112,7 @@ public List getHighlightsInWindow( chunks.add(new ChunkHighlightData( resultSet.getInt("x"), resultSet.getInt("z"), - resultSet.getInt("foundTime"))); + resultSet.getLong("foundTime"))); } return chunks; } @@ -123,6 +123,37 @@ public List getHighlightsInWindow( return Collections.emptyList(); } + @FunctionalInterface + public interface HighlightConsumer { + void accept(int x, int z, long foundTime); + } + + // avoids instantiating the intermediary list + public void getHighlightsInWindow( + final ResourceKey dimension, + final int regionXMin, final int regionXMax, + final int regionZMin, final int regionZMax, + HighlightConsumer consumer + ) { + try (var statement = connection.createStatement()) { + try (ResultSet resultSet = statement.executeQuery( + "SELECT * FROM \"" + getTableName(dimension) + "\" " + + "WHERE x >= " + regionCoordToChunkCoord(regionXMin) + " AND x <= " + regionCoordToChunkCoord(regionXMax) + + " AND z >= " + regionCoordToChunkCoord(regionZMin) + " AND z <= " + regionCoordToChunkCoord(regionZMax))) { + while (resultSet.next()) { + consumer.accept( + resultSet.getInt("x"), + resultSet.getInt("z"), + resultSet.getLong("foundTime") + ); + } + } + } catch (final Exception e) { + XaeroPlus.LOGGER.error("Error getting chunks from {} database in dimension: {}, window: {}-{}, {}-{}", databaseName, dimension.location(), regionXMin, regionXMax, regionZMin, regionZMax, e); + // fall through + } + } + public void removeHighlight(final int x, final int z, final ResourceKey dimension) { try (var statement = connection.createStatement()) { statement.executeUpdate("DELETE FROM \"" + getTableName(dimension) + "\" WHERE x = " + x + " AND z = " + z);