diff --git a/build.gradle.kts b/build.gradle.kts index fdf0a5e..69ec3c6 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -15,18 +15,18 @@ repositories { } dependencies { - implementation("com.artillexstudios.axapi:axapi:1.4.289:all") + implementation("com.artillexstudios.axapi:axapi:1.4.295:all") implementation("dev.jorel:commandapi-bukkit-shade:9.5.0") implementation("org.bstats:bstats-bukkit:3.0.2") compileOnly("com.github.ben-manes.caffeine:caffeine:3.1.8") compileOnly("org.spigotmc:spigot-api:1.21-R0.1-SNAPSHOT") compileOnly("org.apache.commons:commons-lang3:3.14.0") - implementation("com.github.Redempt:Crunch:2.0.3") + implementation("com.github.Redempt:Crunch:2.0.3") // TODO: Load at runtime compileOnly("commons-io:commons-io:2.16.1") compileOnly("it.unimi.dsi:fastutil:8.5.13") compileOnly("org.slf4j:slf4j-api:2.0.9") compileOnly("com.zaxxer:HikariCP:5.1.0") - implementation("org.jooq:jooq:3.19.10") + implementation("org.jooq:jooq:3.19.10") // TODO: Load at runtime } tasks { diff --git a/src/main/java/com/artillexstudios/axminions/AxMinionsPlugin.java b/src/main/java/com/artillexstudios/axminions/AxMinionsPlugin.java index 9dd51c8..cf28f1a 100644 --- a/src/main/java/com/artillexstudios/axminions/AxMinionsPlugin.java +++ b/src/main/java/com/artillexstudios/axminions/AxMinionsPlugin.java @@ -22,6 +22,8 @@ import org.bstats.bukkit.Metrics; import org.bukkit.Bukkit; import org.bukkit.World; +import java.util.concurrent.TimeUnit; + public final class AxMinionsPlugin extends AxPlugin { private static AxMinionsPlugin instance; private Metrics metrics; @@ -74,8 +76,8 @@ public final class AxMinionsPlugin extends AxPlugin { } MinionTicker.cancel(); - DataHandler.databaseExecutor().stop(); CommandAPI.onDisable(); + DataHandler.stop(); DatabaseConnector.getInstance().close(); } diff --git a/src/main/java/com/artillexstudios/axminions/database/DataHandler.java b/src/main/java/com/artillexstudios/axminions/database/DataHandler.java index f617528..0b478b5 100644 --- a/src/main/java/com/artillexstudios/axminions/database/DataHandler.java +++ b/src/main/java/com/artillexstudios/axminions/database/DataHandler.java @@ -1,11 +1,12 @@ package com.artillexstudios.axminions.database; -import com.artillexstudios.axapi.data.ThreadedExecutor; import com.artillexstudios.axapi.nms.NMSHandlers; +import com.artillexstudios.axminions.config.Config; import com.artillexstudios.axminions.minions.MinionType; import com.artillexstudios.axminions.utils.LogUtils; import com.google.common.base.Preconditions; import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; import org.jooq.Record; import org.jooq.Record1; import org.jooq.Result; @@ -13,16 +14,29 @@ import org.jooq.impl.SQLDataType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.ArrayList; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; public final class DataHandler { - private static final ThreadedExecutor databaseExecutor = new ThreadedExecutor("AxMinions-Database-Thread"); + private static final ExecutorService databaseExecutor = Executors.newFixedThreadPool(3, new ThreadFactory() { + private static final AtomicInteger counter = new AtomicInteger(1); + + @Override + public Thread newThread(@NotNull Runnable r) { + return new Thread(null, r, "AxMinions-Database-Thread" + counter.getAndIncrement()); + } + }); private static final int FAILED_QUERY = -3042141; private static final Logger log = LoggerFactory.getLogger(DataHandler.class); public static CompletionStage setup() { - CompletableFuture[] futures = new CompletableFuture[2]; + ArrayList> futures = new ArrayList<>(); CompletionStage types = DatabaseConnector.getInstance().context().createTableIfNotExists(Tables.TYPES) .column(Fields.ID, SQLDataType.INTEGER.identity(true)) @@ -34,7 +48,7 @@ public final class DataHandler { return FAILED_QUERY; }); - futures[0] = types.toCompletableFuture(); + futures.add(types.toCompletableFuture()); CompletionStage users = DatabaseConnector.getInstance().context().createTableIfNotExists(Tables.USERS) .column(Fields.ID, SQLDataType.INTEGER.identity(true)) .column(Fields.UUID, SQLDataType.UUID) @@ -49,8 +63,20 @@ public final class DataHandler { return FAILED_QUERY; }); - futures[1] = users.toCompletableFuture(); - return CompletableFuture.allOf(futures); + if (Config.DATABASE_TYPE == DatabaseType.SQLITE) { + CompletableFuture pragma = new CompletableFuture<>(); + databaseExecutor.submit(() -> { + DatabaseConnector.getInstance().context().fetch("PRAGMA journal_mode=WAL;"); + DatabaseConnector.getInstance().context().execute("PRAGMA synchronous = off;"); + DatabaseConnector.getInstance().context().execute("PRAGMA page_size = 32768;"); + DatabaseConnector.getInstance().context().fetch("PRAGMA mmap_size = 30000000000;"); + pragma.complete(1); + }); + futures.add(pragma); + } + + futures.add(users.toCompletableFuture()); + return CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])); } public static CompletionStage>> updateUser(Player player) { @@ -101,7 +127,16 @@ public final class DataHandler { }); } - public static ThreadedExecutor databaseExecutor() { + public static void stop() { + try { + databaseExecutor.shutdown(); + databaseExecutor.awaitTermination(1, TimeUnit.MINUTES); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + + public static ExecutorService databaseExecutor() { return databaseExecutor; } } diff --git a/src/main/java/com/artillexstudios/axminions/database/DatabaseType.java b/src/main/java/com/artillexstudios/axminions/database/DatabaseType.java index a98e423..baccf47 100644 --- a/src/main/java/com/artillexstudios/axminions/database/DatabaseType.java +++ b/src/main/java/com/artillexstudios/axminions/database/DatabaseType.java @@ -12,6 +12,7 @@ public enum DatabaseType { HikariConfig hikariConfig = new HikariConfig(); hikariConfig.setDataSourceClassName("org.h2.jdbcx.JdbcDataSource"); hikariConfig.setPoolName("axminions-database-pool"); + hikariConfig.setMaximumPoolSize(Config.DATABASE_MAXIMUM_POOL_SIZE); hikariConfig.addDataSourceProperty("url", "jdbc:h2:./" + FileUtils.PLUGIN_DIRECTORY.toFile() + "/data"); return hikariConfig; } @@ -22,7 +23,8 @@ public enum DatabaseType { HikariConfig hikariConfig = new HikariConfig(); hikariConfig.setDriverClassName("org.sqlite.JDBC"); hikariConfig.setPoolName("axminions-database-pool"); - hikariConfig.addDataSourceProperty("url", "jdbc:h2:./" + FileUtils.PLUGIN_DIRECTORY.toFile() + "/data"); + hikariConfig.setMaximumPoolSize(Config.DATABASE_MAXIMUM_POOL_SIZE); + hikariConfig.setJdbcUrl("jdbc:sqlite:" + FileUtils.PLUGIN_DIRECTORY.toFile() + "/data"); return hikariConfig; } }, diff --git a/src/main/java/com/artillexstudios/axminions/utils/ItemCollection.java b/src/main/java/com/artillexstudios/axminions/utils/ItemCollection.java index 338283c..8fba1fd 100644 --- a/src/main/java/com/artillexstudios/axminions/utils/ItemCollection.java +++ b/src/main/java/com/artillexstudios/axminions/utils/ItemCollection.java @@ -1,11 +1,18 @@ package com.artillexstudios.axminions.utils; import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.ListIterator; +import java.util.function.IntFunction; +import java.util.function.Predicate; +import java.util.stream.Stream; -public class ItemCollection extends ArrayList { +public class ItemCollection { public static final ItemCollection EMPTY = new ItemCollection(0) { @Override public ItemStack remove(int index) { @@ -38,11 +45,94 @@ public class ItemCollection extends ArrayList { } }; + private final List items; + public ItemCollection(int size) { - super(size); + this.items = new ArrayList<>(size); } public ItemCollection(Collection collection) { - super(collection); + this.items = collection instanceof List list ? list : new ArrayList<>(collection); + } + + public boolean add(ItemStack itemStack) { + return this.items.add(itemStack); + } + + public void add(int index, ItemStack element) { + this.items.add(index, element); + } + + public boolean addAll(Collection c) { + return this.items.addAll(c); + } + + public boolean addAll(int index, Collection c) { + return this.items.addAll(index, c); + } + + public ItemStack get(int index) { + return this.items.get(index); + } + + public ItemStack remove(int index) { + return this.items.remove(index); + } + + public boolean remove(Object o) { + return this.items.remove(o); + } + + public boolean removeAll(Collection c) { + return this.items.removeAll(c); + } + + public boolean removeIf(Predicate filter) { + return this.items.removeIf(filter); + } + + public List items() { + return this.items; + } + + @NotNull + public Iterator iterator() { + return this.items.iterator(); + } + + @NotNull + public ListIterator listIterator() { + return this.items.listIterator(); + } + + @NotNull + public ListIterator listIterator(int index) { + return this.items.listIterator(index); + } + + public Stream stream() { + return this.items.stream(); + } + + @NotNull + public Object[] toArray() { + return this.items.toArray(); + } + + @NotNull + public T[] toArray(@NotNull T[] a) { + return this.items.toArray(a); + } + + public T[] toArray(IntFunction generator) { + return this.items.toArray(generator); + } + + public int size() { + return this.items.size(); + } + + public void clear() { + this.items.clear(); } }