Compare commits

...
1 Commits
Author SHA1 Message Date
slprime 8e6b31de18 Speed up GUID cache and bookmark recipe lookups (#1119) 2026-11-13 23:25:20 +02:00
7 changed files with 46 additions and 27 deletions

No files matched your search

+1 -1
View File
@@ -131,7 +131,7 @@ public class ItemZoom extends Widget implements IContainerInputHandler {
final boolean sameStack = this.stack != null && this.stack.isItemEqual(stack)
&& ItemStack.areItemStackTagsEqual(this.stack, stack);
if (!sameStack) {
this.stack = StackInfo.loadFromNBT(StackInfo.itemStackToNBT(stack), 0);
this.stack = StackInfo.withAmount(stack, 0);
}
} else {
this.stack = null;
@@ -7,7 +7,6 @@ import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import codechicken.nei.BookmarkPanel.BookmarkViewMode;
import codechicken.nei.ItemSorter;
@@ -132,7 +131,7 @@ public class BookmarkGridGenerator {
itemIndex++;
}
} else if (group.crafting != null && group.crafting.itemToRecipe.values().contains(bookmarkItem.recipeId)) {
} else if (group.crafting != null && group.crafting.recipeToItems.containsKey(bookmarkItem.recipeId)) {
absoluteSlotIndex = generateCollapsedRecipe(prevBookmarkItem, itemIndex, absoluteSlotIndex, borderGrid);
prevBookmarkItem = bookmarkItem;
@@ -218,8 +217,7 @@ public class BookmarkGridGenerator {
}
private List<Integer> getShadows(BookmarkGroup group, RecipeId recipeId) {
return group.crafting.itemToRecipe.entrySet().stream().filter(entry -> recipeId.equals(entry.getValue()))
.map(entry -> entry.getKey()).collect(Collectors.toList());
return new ArrayList<>(group.crafting.recipeToItems.getOrDefault(recipeId, Collections.emptyList()));
}
private int nextSlotIndex(int index, BookmarkItem previousMeta, BookmarkItem meta, BookmarkViewMode viewMode) {
@@ -111,6 +111,7 @@ public class RecipeChainDetails {
public final Map<Integer, BookmarkChainItem> calculatedItems = new HashMap<>();
public final Map<Integer, RecipeId> itemToRecipe = new HashMap<>();
public final Map<RecipeId, List<Integer>> recipeToItems = new HashMap<>();
public final Set<RecipeId> outputRecipes = new HashSet<>();
public final Set<RecipeId> recipeInMiddle = new HashSet<>();
@@ -124,6 +125,7 @@ public class RecipeChainDetails {
}
this.itemToRecipe.clear();
this.recipeToItems.clear();
this.outputRecipes.clear();
this.recipeInMiddle.clear();
this.calculatedItems.clear();
@@ -180,6 +182,10 @@ public class RecipeChainDetails {
}
for (Map.Entry<Integer, RecipeId> entry : this.itemToRecipe.entrySet()) {
this.recipeToItems.computeIfAbsent(entry.getValue(), recipeId -> new ArrayList<>()).add(entry.getKey());
}
for (Map.Entry<Integer, BookmarkItem> entry : chainItems.entrySet()) {
final int itemIndex = entry.getKey();
if (itemIndex >= 0 && this.calculatedItems.containsKey(itemIndex)) {
@@ -37,8 +37,8 @@ public class SortableItem {
&& (group.viewMode == BookmarkViewMode.TODO_LIST || group.crafting != null);
this.crossGroup = !group.collapsed && group.viewMode == BookmarkViewMode.TODO_LIST
&& bookmarkItem.type != BookmarkItemType.INGREDIENT;
this.isCollapsedRecipe = group.crafting != null && group.crafting.itemToRecipe.values().stream()
.anyMatch(recipeId -> this.bookmarkItem.equalsRecipe(recipeId, this.bookmarkItem.groupId));
this.isCollapsedRecipe = group.crafting != null && this.bookmarkItem.recipeId != null
&& group.crafting.recipeToItems.containsKey(this.bookmarkItem.recipeId);
this.update();
}
@@ -4,6 +4,7 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
@@ -16,7 +17,7 @@ import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.IFluidContainerItem;
import codechicken.nei.ClientHandler;
import codechicken.nei.ItemStackMap;
import codechicken.nei.ItemStackMap.StackMetaKey;
import codechicken.nei.LRUCache;
import codechicken.nei.api.IStackStringifyHandler;
import codechicken.nei.api.ItemInfo;
@@ -31,7 +32,7 @@ public class StackInfo {
private static final FluidStack NULL_FLUID = new FluidStack(FluidRegistry.WATER, 0);
public static final List<IStackStringifyHandler> stackStringifyHandlers = new ArrayList<>();
private static final Map<String, HashMap<String, String[]>> guidfilters = new HashMap<>();
private static final ItemStackMap<String> guidcache = new ItemStackMap<>();
private static final Map<Item, Map<StackMetaKey, String>> guidcache = new ConcurrentHashMap<>();
private static final LRUCache<ItemStackKey, FluidStack> fluidcache = new LRUCache<>(200);
private static boolean isPausedItemDamageSound = false;
@@ -182,7 +183,9 @@ public class StackInfo {
}
public static String getItemStackGUID(ItemStack stack) {
String guid = guidcache.get(stack);
final Item stackItem = stack.getItem();
final Map<StackMetaKey, String> itemGuids = stackItem != null ? guidcache.get(stackItem) : null;
String guid = itemGuids != null ? itemGuids.get(new StackMetaKey(stack)) : null;
if (guid != null) {
return guid;
@@ -190,7 +193,7 @@ public class StackInfo {
final NBTTagCompound nbTag = itemStackToNBT(stack, false);
if (nbTag == null) {
if (nbTag == null || stack.getItem() == null) {
return "unknown";
}
@@ -239,16 +242,15 @@ public class StackInfo {
}
});
synchronized (guidcache) {
guidcache.put(stack, keys.toString());
}
guid = keys.toString();
} else {
synchronized (guidcache) {
guidcache.put(stack, NBTHelper.toString(nbTag));
}
guid = NBTHelper.toString(nbTag);
}
return guidcache.get(stack);
guidcache.computeIfAbsent(stack.getItem(), item -> new ConcurrentHashMap<>())
.put(new StackMetaKey(stack.copy()), guid);
return guid;
}
public static void loadGuidFilters() {
@@ -10,6 +10,9 @@ import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidRegistry;
import net.minecraftforge.fluids.FluidStack;
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import codechicken.nei.api.IStackStringifyHandler;
import codechicken.nei.item.ItemFluidDisplay;
import cpw.mods.fml.common.registry.GameRegistry;
@@ -22,6 +25,11 @@ public class GTFluidStackStringifyHandler implements IStackStringifyHandler {
protected static Class<?> gtMetaGeneratedTool = null;
protected static Field playSound = null;
private static final Supplier<Item> AE2FC_FLUID_PACKET = Suppliers
.memoize(() -> GameRegistry.findItem("ae2fc", "fluid_packet"));
private static final Supplier<Item> AE2FC_FLUID_DROP = Suppliers
.memoize(() -> GameRegistry.findItem("ae2fc", "fluid_drop"));
static {
try {
final ClassLoader loader = GTFluidStackStringifyHandler.class.getClassLoader();
@@ -94,11 +102,11 @@ public class GTFluidStackStringifyHandler implements IStackStringifyHandler {
return new FluidStack(fluid, 0);
}
} else if (item == GameRegistry.findItem("ae2fc", "fluid_packet")) {
} else if (item == AE2FC_FLUID_PACKET.get()) {
NBTTagCompound nbtTag = stack.getTagCompound();
return FluidStack.loadFluidStackFromNBT((NBTTagCompound) nbtTag.getTag("FluidStack"));
} else if (item == GameRegistry.findItem("ae2fc", "fluid_drop")) {
} else if (item == AE2FC_FLUID_DROP.get()) {
NBTTagCompound nbtTag = stack.getTagCompound();
Fluid fluid = FluidRegistry.getFluid(nbtTag.getString("Fluid").toLowerCase());
@@ -113,9 +121,9 @@ public class GTFluidStackStringifyHandler implements IStackStringifyHandler {
@Override
public ItemStack normalizeRecipeQueryStack(ItemStack stack) {
final Item item = stack.getItem();
if (stack.getItem() == GameRegistry.findItem("ae2fc", "fluid_drop")
|| stack.getItem() == GameRegistry.findItem("ae2fc", "fluid_packet")) {
if (item == AE2FC_FLUID_DROP.get() || item == AE2FC_FLUID_PACKET.get()) {
final FluidStack fluidStack = getFluid(stack);
if (fluidStack != null) {
@@ -139,8 +147,7 @@ public class GTFluidStackStringifyHandler implements IStackStringifyHandler {
@Override
public boolean isFluidDisplayItem(ItemStack stack) {
final Item item = stack.getItem();
return (itemFluidDisplay != null && itemFluidDisplay.isInstance(item))
|| item == GameRegistry.findItem("ae2fc", "fluid_packet");
return (itemFluidDisplay != null && itemFluidDisplay.isInstance(item)) || item == AE2FC_FLUID_PACKET.get();
}
}
@@ -10,6 +10,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Stream;
import net.minecraft.creativetab.CreativeTabs;
@@ -128,8 +129,8 @@ public class ItemUntranslator {
private static final String CONFIG_FILE = "untranslator.cfg";
private static final ItemUntranslator instance = new ItemUntranslator();
private final Map<String, String> secondNames = new HashMap<>();
private final Map<String, String> processedNames = new HashMap<>();
private final Map<String, String> secondNames = new ConcurrentHashMap<>();
private final Map<String, String> processedNames = new ConcurrentHashMap<>();
private ItemUntranslator() {}
@@ -241,14 +242,19 @@ public class ItemUntranslator {
return EnumChatFormatting.getTextWithoutFormattingCodes(name).trim();
}
public synchronized String getItemStackDisplayName(ItemStack stack) {
public String getItemStackDisplayName(ItemStack stack) {
if (stack == null || this.secondNames.isEmpty()) {
return "";
}
final String guidKey = StackInfo.getItemStackGUID(stack);
final String displayName = this.processedNames.get(guidKey);
return displayName != null ? displayName : processDisplayName(stack, guidKey);
}
private synchronized String processDisplayName(ItemStack stack, String guidKey) {
return this.processedNames.computeIfAbsent(guidKey, stackKey -> {
String displayName = this.secondNames.get(stackKey);