From 7b8e03613eb71eac397f7d9c4a7f47d494eaf9d0 Mon Sep 17 00:00:00 2001 From: Glease <4586901+Glease@users.noreply.github.com> Date: Thu, 23 Dec 2021 23:20:22 +0800 Subject: Optimize OrePrefixes.contains and OrePrefixes.add (#832) 1. Convert global map mCachedResults to an instance field. 2. Convert the post add null check to a builtin null check via GT_ArrayList 3. Use new GT_ItemStack2 (which has a slightly better hash function than stackToInt) --- src/main/java/gregtech/api/enums/OrePrefixes.java | 36 ++++---------------- .../java/gregtech/api/objects/GT_ArrayList.java | 11 +++---- .../java/gregtech/api/objects/GT_ItemStack2.java | 38 ++++++++++++++++++++++ 3 files changed, 50 insertions(+), 35 deletions(-) create mode 100644 src/main/java/gregtech/api/objects/GT_ItemStack2.java (limited to 'src/main/java') diff --git a/src/main/java/gregtech/api/enums/OrePrefixes.java b/src/main/java/gregtech/api/enums/OrePrefixes.java index 1fc7c0c3af..8c7f8b7c57 100644 --- a/src/main/java/gregtech/api/enums/OrePrefixes.java +++ b/src/main/java/gregtech/api/enums/OrePrefixes.java @@ -1,6 +1,5 @@ package gregtech.api.enums; -import com.google.common.base.Objects; import com.google.common.collect.ImmutableList; import gregtech.api.GregTech_API; import gregtech.api.enums.TC_Aspects.TC_AspectStack; @@ -8,9 +7,11 @@ import gregtech.api.interfaces.ICondition; import gregtech.api.interfaces.IMaterialHandler; import gregtech.api.interfaces.IOreRecipeRegistrator; import gregtech.api.interfaces.ISubTagContainer; +import gregtech.api.objects.GT_ArrayList; +import gregtech.api.objects.GT_HashSet; +import gregtech.api.objects.GT_ItemStack2; import gregtech.api.objects.ItemData; import gregtech.api.objects.MaterialStack; -import gregtech.api.objects.ObjMap; import gregtech.api.util.GT_Log; import gregtech.api.util.GT_Utility; import gregtech.loaders.materialprocessing.ProcessingModSupport; @@ -569,7 +570,7 @@ public enum OrePrefixes { bulletGtLarge.mSecondaryMaterial = new MaterialStack(Materials.Brass, ingot.mMaterialAmount / 3); } - public final ArrayList mPrefixedItems = new ArrayList(); + public final ArrayList mPrefixedItems = new GT_ArrayList<>(false, 16); public final short mTextureIndex; public final String mRegularLocalName, mLocalizedMaterialPre, mLocalizedMaterialPost; public final boolean mIsUsedForOreProcessing, mIsEnchantable, mIsUnificatable, mIsMaterialBased, mIsSelfReferencing, mIsContainer, mDontUnificateActively, mIsUsedForBlocks, mAllowNormalRecycling, mGenerateDefaultItem; @@ -590,6 +591,7 @@ public enum OrePrefixes { public MaterialStack mSecondaryMaterial = null; public OrePrefixes mPrefixInto = this; public float mHeatDamage = 0.0F; // Negative for Frost Damage + private final GT_HashSet mContainsTestCache = new GT_HashSet<>(512, 0.5f); public static List mPreventableComponents = new LinkedList<>(Arrays.asList(OrePrefixes.gem, OrePrefixes.ingotHot, OrePrefixes.ingotDouble, OrePrefixes.ingotTriple, OrePrefixes.ingotQuadruple, OrePrefixes.ingotQuintuple, OrePrefixes.plate, OrePrefixes.plateDouble, OrePrefixes.plateTriple, OrePrefixes.plateQuadruple, OrePrefixes.plateQuintuple, OrePrefixes.plateDense, OrePrefixes.stick, OrePrefixes.round, OrePrefixes.bolt, OrePrefixes.screw, OrePrefixes.ring, OrePrefixes.foil, OrePrefixes.toolHeadSword, OrePrefixes.toolHeadPickaxe, OrePrefixes.toolHeadShovel, OrePrefixes.toolHeadAxe, OrePrefixes.toolHeadHoe, OrePrefixes.toolHeadHammer, OrePrefixes.toolHeadFile, OrePrefixes.toolHeadSaw, OrePrefixes.toolHeadDrill, OrePrefixes.toolHeadChainsaw, OrePrefixes.toolHeadWrench, OrePrefixes.toolHeadUniversalSpade, OrePrefixes.toolHeadSense, OrePrefixes.toolHeadPlow, OrePrefixes.toolHeadArrow, OrePrefixes.toolHeadBuzzSaw, OrePrefixes.turbineBlade, OrePrefixes.wireFine, OrePrefixes.gearGtSmall, OrePrefixes.rotor, OrePrefixes.stickLong, OrePrefixes.springSmall, OrePrefixes.spring, OrePrefixes.arrowGtWood, OrePrefixes.arrowGtPlastic, OrePrefixes.gemChipped, OrePrefixes.gemFlawed, OrePrefixes.gemFlawless, OrePrefixes.gemExquisite, OrePrefixes.gearGt, OrePrefixes.crateGtDust, OrePrefixes.crateGtIngot, OrePrefixes.crateGtGem, OrePrefixes.crateGtPlate, OrePrefixes.itemCasing)); /** * Yes this Value can be changed to add Bits for the MetaGenerated-Item-Check. @@ -898,37 +900,13 @@ public enum OrePrefixes { if (!contains(aStack)) { mPrefixedItems.add(aStack); // It's now in there... so update the cache - getSet(this.toString().toUpperCase()).put(Objects.hashCode(aStack.getItem(), aStack.getItemDamage()), true); + mContainsTestCache.add(new GT_ItemStack2(aStack)); } - while (mPrefixedItems.contains(null)) mPrefixedItems.remove(null); return true; } - private static final LinkedHashMap>mCachedResults = new LinkedHashMap>(); - - private ObjMap getSet(final String prefix) { - ObjMap foundSet = mCachedResults.get(prefix); - if (foundSet == null){ - foundSet = new ObjMap(512, 0.5f); - mCachedResults.put(prefix, foundSet); - } - - return foundSet; - } - public boolean contains(ItemStack aStack) { - if (aStack == null) { - return false; - } - - final ObjMap aCurrentSet = getSet(this.toString().toUpperCase()); - final Boolean result = aCurrentSet.get(Objects.hashCode(aStack.getItem(), aStack.getItemDamage())); - - if (result != null) { - return result; - } - - return false; + return !GT_Utility.isStackInvalid(aStack) && mContainsTestCache.contains(new GT_ItemStack2(aStack)); } public boolean containsUnCached(ItemStack aStack) { diff --git a/src/main/java/gregtech/api/objects/GT_ArrayList.java b/src/main/java/gregtech/api/objects/GT_ArrayList.java index 8c491e86c4..a9efd8d0a0 100644 --- a/src/main/java/gregtech/api/objects/GT_ArrayList.java +++ b/src/main/java/gregtech/api/objects/GT_ArrayList.java @@ -1,8 +1,11 @@ package gregtech.api.objects; +import com.google.common.collect.Collections2; + import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.Objects; public class GT_ArrayList extends ArrayList { private static final long serialVersionUID = 1L; @@ -46,15 +49,11 @@ public class GT_ArrayList extends ArrayList { @Override public boolean addAll(Collection aList) { - boolean rReturn = super.addAll(aList); - if (!mAllowNulls) {size_sS=size(); for (int i = 0; i < size_sS; i++) if (get(i) == null) {remove(i--);size_sS=size();}} - return rReturn; + return super.addAll(Collections2.filter(aList, Objects::nonNull)); } @Override public boolean addAll(int aIndex, Collection aList) { - boolean rReturn = super.addAll(aIndex, aList); - if (!mAllowNulls) {size_sS=size(); for (int i = 0; i < size_sS; i++) if (get(i) == null) {remove(i--);size_sS=size();}} - return rReturn; + return super.addAll(aIndex, Collections2.filter(aList, Objects::nonNull)); } } diff --git a/src/main/java/gregtech/api/objects/GT_ItemStack2.java b/src/main/java/gregtech/api/objects/GT_ItemStack2.java new file mode 100644 index 0000000000..93f2da6d6b --- /dev/null +++ b/src/main/java/gregtech/api/objects/GT_ItemStack2.java @@ -0,0 +1,38 @@ +package gregtech.api.objects; + +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; + +/** + * GT_ItemStack, but with a better hashCode(). Due to this change, it should not be placed in the same hash based + * data structure with GT_ItemStack. It also shouldn't be used to construct search query into a hash based data structure + * that contains GT_ItemStack. + */ +public class GT_ItemStack2 extends GT_ItemStack { + + public GT_ItemStack2(Item aItem, long aStackSize, long aMetaData) { + super(aItem, aStackSize, aMetaData); + } + + public GT_ItemStack2(ItemStack aStack) { + super(aStack); + } + + public GT_ItemStack2(ItemStack aStack, boolean wildcard) { + super(aStack, wildcard); + } + + @Override + public boolean equals(Object aStack) { + if (aStack == this) return true; + if (aStack instanceof GT_ItemStack) { + return ((GT_ItemStack) aStack).mItem == mItem && ((GT_ItemStack) aStack).mMetaData == mMetaData; + } + return false; + } + + @Override + public int hashCode() { + return mItem.hashCode() * 38197 + mMetaData; + } +} -- cgit