Skip to content

Commit

Permalink
use non-annotated config for storage
Browse files Browse the repository at this point in the history
  • Loading branch information
TechLord22 committed Jan 1, 2024
1 parent 31fb657 commit 2a44a06
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 33 deletions.
2 changes: 2 additions & 0 deletions src/main/java/gregtech/GregTechMod.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import gregtech.api.GTValues;
import gregtech.api.GregTechAPI;
import gregtech.api.modules.ModuleContainerRegistryEvent;
import gregtech.api.persistence.PersistentData;
import gregtech.client.utils.BloomEffectUtil;
import gregtech.modules.GregTechModules;
import gregtech.modules.ModuleManager;
Expand Down Expand Up @@ -50,6 +51,7 @@ public GregTechMod() {

@EventHandler
public void onConstruction(FMLConstructionEvent event) {
PersistentData.instance().init();
moduleManager = ModuleManager.getInstance();
GregTechAPI.moduleManager = moduleManager;
moduleManager.registerContainer(new GregTechModules());
Expand Down
56 changes: 56 additions & 0 deletions src/main/java/gregtech/api/persistence/PersistentData.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package gregtech.api.persistence;

import gregtech.api.GTValues;

import net.minecraftforge.common.config.Configuration;
import net.minecraftforge.fml.common.Loader;

import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.io.File;
import java.nio.file.Path;

public final class PersistentData {

public static final String CATEGORY_NAME = "persistent data";

private static final PersistentData INSTANCE = new PersistentData();
private static final String FILE_NAME = "persistent_data.cfg";

private @Nullable Configuration config;

public static @NotNull PersistentData instance() {
return INSTANCE;
}

private PersistentData() {}

/**
* @return the persistent data storage
*/
public @NotNull Configuration getConfig() {
if (config == null) {
Path configFolderPath = Loader.instance().getConfigDir().toPath().resolve(GTValues.MODID);
File file = configFolderPath.resolve(FILE_NAME).toFile();
config = new Configuration(file);
}
return config;
}

@ApiStatus.Internal
public void init() {
Configuration configuration = getConfig();
configuration.load();
String comment = """
GregTech Persistent Data. Items in this file will persist across game loads.
Modifications to this file may be overwritten by GT.
If you are a modpack author, you should ship this file in releases.""";
configuration.addCustomCategoryComment(CATEGORY_NAME, comment);

if (configuration.hasChanged()) {
configuration.save();
}
}
}
53 changes: 36 additions & 17 deletions src/main/java/gregtech/api/recipes/GTRecipeInputCache.java
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
package gregtech.api.recipes;

import gregtech.api.GTValues;
import gregtech.api.persistence.PersistentData;
import gregtech.api.recipes.ingredients.GTRecipeInput;
import gregtech.api.util.GTLog;
import gregtech.common.ConfigHolder;

import net.minecraftforge.common.config.Config;
import net.minecraftforge.common.config.ConfigManager;
import net.minecraftforge.common.config.Configuration;
import net.minecraftforge.common.config.Property;

import it.unimi.dsi.fastutil.Hash;
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;

import java.util.ArrayList;
import java.util.Collections;
Expand All @@ -27,24 +29,27 @@
*/
public final class GTRecipeInputCache {

/**
* The minimum size for the cache
*/
public static final int MINIMUM_CACHE_SIZE = 8192;
private static final int MINIMUM_CACHE_SIZE = 1 << 13;
private static final int MAXIMUM_CACHE_SIZE = 1 << 30;

private static ObjectOpenHashSet<GTRecipeInput> instances;

private static ObjectOpenHashSet<GTRecipeInput> INSTANCES;
private static final String DATA_NAME = "expectedIngredientInstances";
private static final String DATA_COMMENT = """
The expected amount of unique GT recipe ingredients.
This setting improves memory allocation and garbage collection during game-load.""";

private GTRecipeInputCache() {}

public static boolean isCacheEnabled() {
return INSTANCES != null;
return instances != null;
}

@ApiStatus.Internal
public static void enableCache() {
if (!isCacheEnabled()) {
int size = calculateOptimalExpectedSize();
INSTANCES = new ObjectOpenHashSet<>(size);
instances = new ObjectOpenHashSet<>(size);

if (ConfigHolder.misc.debug || GTValues.isDeobfEnvironment()) {
GTLog.logger.info("GTRecipeInput cache enabled with expected size {}", size);
Expand All @@ -55,19 +60,31 @@ public static void enableCache() {
@ApiStatus.Internal
public static void disableCache() {
if (isCacheEnabled()) {
int size = INSTANCES.size();
int size = instances.size();
if (ConfigHolder.misc.debug || GTValues.isDeobfEnvironment()) {
GTLog.logger.info("GTRecipeInput cache disabled; releasing {} unique instances", size);
}
INSTANCES = null;

if (ConfigHolder.persistentData.expectedIngredientInstances != size && size > MINIMUM_CACHE_SIZE) {
ConfigHolder.persistentData.expectedIngredientInstances = size;
ConfigManager.sync(GTValues.MODID, Config.Type.INSTANCE);
instances = null;

if (size >= MINIMUM_CACHE_SIZE && size < MAXIMUM_CACHE_SIZE) {
Configuration config = PersistentData.instance().getConfig();
Property expected = getExpectedInstanceAmount(config);

if (expected.getInt() != size) {
expected.set(size);
if (expected.hasChanged()) {
config.save();
}
}
}
}
}

private static @NotNull Property getExpectedInstanceAmount(@NotNull Configuration configuration) {
return configuration.get(PersistentData.CATEGORY_NAME, DATA_NAME, MINIMUM_CACHE_SIZE,
DATA_COMMENT, MINIMUM_CACHE_SIZE, MAXIMUM_CACHE_SIZE);
}

/**
* Tries to deduplicate the instance with previously cached instances. If there is no identical GTRecipeInput
* present in cache, the {@code recipeInput} will be put into cache, marked as cached, and returned subsequently.
Expand All @@ -82,7 +99,7 @@ public static GTRecipeInput deduplicate(GTRecipeInput recipeInput) {
if (!isCacheEnabled() || recipeInput.isCached()) {
return recipeInput;
}
GTRecipeInput cached = INSTANCES.addOrGet(recipeInput);
GTRecipeInput cached = instances.addOrGet(recipeInput);
if (cached == recipeInput) { // If recipeInput is cached just now...
cached.setCached();
}
Expand Down Expand Up @@ -129,12 +146,14 @@ public static List<GTRecipeInput> deduplicateInputs(List<GTRecipeInput> inputs)
* @return the optimal expected input cache size
*/
private static int calculateOptimalExpectedSize() {
int min = getExpectedInstanceAmount(PersistentData.instance().getConfig())
.getInt(MINIMUM_CACHE_SIZE);
for (int i = 13; i < 31; i++) {
int sizeToTest = 1 << i;
int arraySize = nextHighestPowerOf2((int) (sizeToTest / Hash.DEFAULT_LOAD_FACTOR));
int maxStoredBeforeRehash = (int) (arraySize * Hash.DEFAULT_LOAD_FACTOR);

if (maxStoredBeforeRehash >= ConfigHolder.persistentData.expectedIngredientInstances) {
if (maxStoredBeforeRehash >= min) {
return sizeToTest;
}
}
Expand Down
16 changes: 0 additions & 16 deletions src/main/java/gregtech/common/ConfigHolder.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import gregtech.api.GTValues;
import gregtech.api.GregTechAPI;
import gregtech.api.recipes.GTRecipeInputCache;

import net.minecraftforge.common.config.Config;

Expand Down Expand Up @@ -44,10 +43,6 @@ public class ConfigHolder {
@Config.RequiresMcRestart
public static WorldGenOptions worldgen = new WorldGenOptions();

@Config.Comment({ "Persistent Data for GT", "Do not modify the contents of this section." })
@Config.Name("Persistent Data")
public static PersistentData persistentData = new PersistentData();

public static class MachineOptions {

@Config.Comment({ "Whether insufficient energy supply should reset Machine recipe progress to zero.",
Expand Down Expand Up @@ -706,15 +701,4 @@ public static class NanoSaber {
@Config.Comment({ "The EU/t consumption of the NanoSaber.", "Default: 64" })
public int energyConsumption = 64;
}

public static class PersistentData {

@Config.Comment({ "The expected amount of unique GT recipe ingredients.",
"This setting improves memory allocation and garbage collection during game-load.",
"Do NOT modify this setting. This value is automatically adjusted by GT.",
"Manual changes are not preserved and WILL be overwritten." })
@Config.RangeInt(min = GTRecipeInputCache.MINIMUM_CACHE_SIZE, max = 1 << 30)
@Config.RequiresMcRestart
public int expectedIngredientInstances = GTRecipeInputCache.MINIMUM_CACHE_SIZE;
}
}

0 comments on commit 2a44a06

Please sign in to comment.