diff options
Diffstat (limited to 'src/main/java/gregtech/api')
-rw-r--r-- | src/main/java/gregtech/api/enums/ItemList.java | 2 | ||||
-rw-r--r-- | src/main/java/gregtech/api/enums/Materials.java | 2 | ||||
-rw-r--r-- | src/main/java/gregtech/api/enums/OrePrefixes.java | 21 | ||||
-rw-r--r-- | src/main/java/gregtech/api/objects/ObjMap.java | 281 |
4 files changed, 292 insertions, 14 deletions
diff --git a/src/main/java/gregtech/api/enums/ItemList.java b/src/main/java/gregtech/api/enums/ItemList.java index 90d561fab4..ec88b11a84 100644 --- a/src/main/java/gregtech/api/enums/ItemList.java +++ b/src/main/java/gregtech/api/enums/ItemList.java @@ -684,7 +684,7 @@ public enum ItemList implements IItemContainer { MNqCell_1, MNqCell_2, MNqCell_4,; public static final ItemList[] DYE_ONLY_ITEMS = {Color_00, Color_01, Color_02, Color_03, Color_04, Color_05, Color_06, Color_07, Color_08, Color_09, Color_10, Color_11, Color_12, Color_13, Color_14, Color_15}, SPRAY_CAN_DYES = {Spray_Color_00, Spray_Color_01, Spray_Color_02, Spray_Color_03, Spray_Color_04, Spray_Color_05, Spray_Color_06, Spray_Color_07, Spray_Color_08, Spray_Color_09, Spray_Color_10, Spray_Color_11, Spray_Color_12, Spray_Color_13, Spray_Color_14, Spray_Color_15}, SPRAY_CAN_DYES_USED = {Spray_Color_Used_00, Spray_Color_Used_01, Spray_Color_Used_02, Spray_Color_Used_03, Spray_Color_Used_04, Spray_Color_Used_05, Spray_Color_Used_06, Spray_Color_Used_07, Spray_Color_Used_08, Spray_Color_Used_09, Spray_Color_Used_10, Spray_Color_Used_11, Spray_Color_Used_12, Spray_Color_Used_13, Spray_Color_Used_14, Spray_Color_Used_15}, TRANSFORMERS = {Transformer_LV_ULV, Transformer_MV_LV, Transformer_HV_MV, Transformer_EV_HV, Transformer_IV_EV, Transformer_LuV_IV, Transformer_ZPM_LuV, Transformer_UV_ZPM, Transformer_MAX_UV}, MACHINE_HULLS = {Hull_ULV, Hull_LV, Hull_MV, Hull_HV, Hull_EV, Hull_IV, Hull_LuV, Hull_ZPM, Hull_UV, Hull_MAX}, HATCHES_DYNAMO = {Hatch_Dynamo_ULV, Hatch_Dynamo_LV, Hatch_Dynamo_MV, Hatch_Dynamo_HV, Hatch_Dynamo_EV, Hatch_Dynamo_IV, Hatch_Dynamo_LuV, Hatch_Dynamo_ZPM, Hatch_Dynamo_UV, Hatch_Dynamo_MAX}, HATCHES_ENERGY = {Hatch_Energy_ULV, Hatch_Energy_LV, Hatch_Energy_MV, Hatch_Energy_HV, Hatch_Energy_EV, Hatch_Energy_IV, Hatch_Energy_LuV, Hatch_Energy_ZPM, Hatch_Energy_UV, Hatch_Energy_MAX}, HATCHES_INPUT = {Hatch_Input_ULV, Hatch_Input_LV, Hatch_Input_MV, Hatch_Input_HV, Hatch_Input_EV, Hatch_Input_IV, Hatch_Input_LuV, Hatch_Input_ZPM, Hatch_Input_UV, Hatch_Input_MAX}, HATCHES_INPUT_BUS = {Hatch_Input_Bus_ULV, Hatch_Input_Bus_LV, Hatch_Input_Bus_MV, Hatch_Input_Bus_HV, Hatch_Input_Bus_EV, Hatch_Input_Bus_IV, Hatch_Input_Bus_LuV, Hatch_Input_Bus_ZPM, Hatch_Input_Bus_UV, Hatch_Input_Bus_MAX}, HATCHES_OUTPUT = {Hatch_Output_ULV, Hatch_Output_LV, Hatch_Output_MV, Hatch_Output_HV, Hatch_Output_EV, Hatch_Output_IV, Hatch_Output_LuV, Hatch_Output_ZPM, Hatch_Output_UV, Hatch_Output_MAX}, HATCHES_OUTPUT_BUS = {Hatch_Output_Bus_ULV, Hatch_Output_Bus_LV, Hatch_Output_Bus_MV, Hatch_Output_Bus_HV, Hatch_Output_Bus_EV, Hatch_Output_Bus_IV, Hatch_Output_Bus_LuV, Hatch_Output_Bus_ZPM, Hatch_Output_Bus_UV, Hatch_Output_Bus_MAX}, HATCHES_MUFFLER = {Hatch_Muffler_LV, Hatch_Muffler_LV, Hatch_Muffler_MV, Hatch_Muffler_HV, Hatch_Muffler_EV, Hatch_Muffler_IV, Hatch_Muffler_LuV, Hatch_Muffler_ZPM, Hatch_Muffler_UV, Hatch_Muffler_MAX}; - public static Fluid sOilExtraHeavy, sEpichlorhydrin, sDrillingFluid, sNitricAcid, sBlueVitriol, sNickelSulfate, sToluene, sNitrationMixture, sRocketFuel, sHydricSulfur, sIndiumConcentrate, sLeadZincSolution, sIron3Chloride, sHydrochloricAcid, sLifeEssence; + public static Fluid sOilExtraHeavy, sEpichlorhydrin, sDrillingFluid, sNitricAcid, sBlueVitriol, sNickelSulfate, sToluene, sNitrationMixture, sRocketFuel, sHydricSulfur, sIndiumConcentrate, sLeadZincSolution, sHydrochloricAcid; private ItemStack mStack; private boolean mHasNotBeenSet = true; diff --git a/src/main/java/gregtech/api/enums/Materials.java b/src/main/java/gregtech/api/enums/Materials.java index 2a74c1acdf..9edd55619c 100644 --- a/src/main/java/gregtech/api/enums/Materials.java +++ b/src/main/java/gregtech/api/enums/Materials.java @@ -362,7 +362,7 @@ public class Materials implements IColorModulationContainer, ISubTagContainer { public static Materials Elite = new Materials( -1, TextureSet.SET_NONE , 1.0F, 0, 0, 0 , 255, 255, 255, 0, "Elite" , "Elite" , 0, 0, -1, 0, false, false, 1, 1, 1, Dyes.dyeLightGray , Arrays.asList(new TC_AspectStack(TC_Aspects.MACHINA, 6)));
public static Materials Master = new Materials( -1, TextureSet.SET_NONE , 1.0F, 0, 0, 0 , 255, 255, 255, 0, "Master" , "Master" , 0, 0, -1, 0, false, false, 1, 1, 1, Dyes.dyeLightGray , Arrays.asList(new TC_AspectStack(TC_Aspects.MACHINA, 7)));
public static Materials Ultimate = new Materials( -1, TextureSet.SET_NONE , 1.0F, 0, 0, 0 , 255, 255, 255, 0, "Ultimate" , "Ultimate" , 0, 0, -1, 0, false, false, 1, 1, 1, Dyes.dyeLightGray , Arrays.asList(new TC_AspectStack(TC_Aspects.MACHINA, 8)));
- public static Materials Superconductor = new Materials( -1, TextureSet.SET_NONE , 1.0F, 0, 0, 0 , 255, 255, 255, 0, "Superconductor" , "Superconductor" , 0, 0, -1, 0, false, false, 1, 1, 1, Dyes.dyeLightGray , Arrays.asList(new TC_AspectStack(TC_Aspects.ELECTRUM, 8)));
+ public static Materials Superconductor = new Materials( -1, TextureSet.SET_NONE , 1.0F, 0, 0, 0 , 255, 255, 255, 0, "Superconductor" , "Superconductor UHV" , 0, 0, -1, 0, false, false, 1, 1, 1, Dyes.dyeLightGray , Arrays.asList(new TC_AspectStack(TC_Aspects.ELECTRUM, 8)));
public static Materials Infinite = new Materials( -1, TextureSet.SET_NONE , 1.0F, 0, 0, 0 , 255, 255, 255, 0, "Infinite" , "Infinite" , 0, 0, -1, 0, false, false, 1, 1, 1, Dyes.dyeLightGray );
/**
diff --git a/src/main/java/gregtech/api/enums/OrePrefixes.java b/src/main/java/gregtech/api/enums/OrePrefixes.java index 2dbeabf5c9..72f04dd7c9 100644 --- a/src/main/java/gregtech/api/enums/OrePrefixes.java +++ b/src/main/java/gregtech/api/enums/OrePrefixes.java @@ -8,6 +8,7 @@ import gregtech.api.interfaces.IOreRecipeRegistrator; import gregtech.api.interfaces.ISubTagContainer;
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;
@@ -865,38 +866,34 @@ public enum OrePrefixes { return true;
}
- private static final HashMap<String, HashMap<ItemStack, Boolean>>mCachedResults = new HashMap<String, HashMap<ItemStack, Boolean>>();
-
+ private static final LinkedHashMap<String, ObjMap<Integer, Boolean>>mCachedResults = new LinkedHashMap<String, ObjMap<Integer, Boolean>>();
+
public boolean contains(ItemStack aStack) {
-
if (aStack == null){
return false;
}
-
- HashMap<ItemStack, Boolean> aCurrentSet;
+ ObjMap<Integer, Boolean> aCurrentSet;
if (mCachedResults.get(this.toString()) != null){
aCurrentSet = mCachedResults.get(this.toString());
}
else {
- aCurrentSet = new HashMap<ItemStack, Boolean>();
+ aCurrentSet = new ObjMap<Integer, Boolean>((mPrefixedItems != null && mPrefixedItems.size() > 0 ? mPrefixedItems.size() : 1000), 0.5f);
mCachedResults.put(this.toString(), aCurrentSet);
}
- if (aCurrentSet.get(aStack) != null){
- return aCurrentSet.get(aStack);
+ if (aCurrentSet.get(aStack.hashCode()) != null){
+ return aCurrentSet.get(aStack.hashCode());
}
else {
for (ItemStack tStack : mPrefixedItems){
if (GT_Utility.areStacksEqual(aStack, tStack, !tStack.hasTagCompound())){
- aCurrentSet.put(aStack, true);
+ aCurrentSet.put(aStack.hashCode(), true);
return true;
}
}
}
-
- aCurrentSet.put(aStack, false);
-
+ aCurrentSet.put(aStack.hashCode(), false);
return false;
}
diff --git a/src/main/java/gregtech/api/objects/ObjMap.java b/src/main/java/gregtech/api/objects/ObjMap.java new file mode 100644 index 0000000000..0db6083cfe --- /dev/null +++ b/src/main/java/gregtech/api/objects/ObjMap.java @@ -0,0 +1,281 @@ +package gregtech.api.objects; + +import java.util.Arrays; + +/** + * Object-2-object map based on IntIntMap4a + */ +public class ObjMap<K, V> +{ + private static final Object FREE_KEY = new Object(); + private static final Object REMOVED_KEY = new Object(); + + /** Keys and values */ + private Object[] m_data; + + /** Value for the null key (if inserted into a map) */ + private Object m_nullValue; + private boolean m_hasNull; + + /** Fill factor, must be between (0 and 1) */ + private final float m_fillFactor; + /** We will resize a map once it reaches this size */ + private int m_threshold; + /** Current map size */ + private int m_size; + /** Mask to calculate the original position */ + private int m_mask; + /** Mask to wrap the actual array pointer */ + private int m_mask2; + + public ObjMap( final int size, final float fillFactor ) + { + if ( fillFactor <= 0 || fillFactor >= 1 ) + throw new IllegalArgumentException( "FillFactor must be in (0, 1)" ); + if ( size <= 0 ) + throw new IllegalArgumentException( "Size must be positive!" ); + final int capacity = arraySize(size, fillFactor); + m_mask = capacity - 1; + m_mask2 = capacity * 2 - 1; + m_fillFactor = fillFactor; + + m_data = new Object[capacity * 2]; + Arrays.fill( m_data, FREE_KEY ); + + m_threshold = (int) (capacity * fillFactor); + } + + @SuppressWarnings("unchecked") + public V get( final K key ) + { + if ( key == null ) + return (V) m_nullValue; //we null it on remove, so safe not to check a flag here + + int ptr = (key.hashCode() & m_mask) << 1; + Object k = m_data[ ptr ]; + + if ( k == FREE_KEY ) + return null; //end of chain already + if ( k.equals( key ) ) //we check FREE and REMOVED prior to this call + return (V) m_data[ ptr + 1 ]; + while ( true ) + { + ptr = (ptr + 2) & m_mask2; //that's next index + k = m_data[ ptr ]; + if ( k == FREE_KEY ) + return null; + if ( k.equals( key ) ) + return (V) m_data[ ptr + 1 ]; + } + } + + @SuppressWarnings("unchecked") + public V put( final K key, final V value ) + { + if ( key == null ) + return insertNullKey(value); + + int ptr = getStartIndex(key) << 1; + Object k = m_data[ptr]; + + if ( k == FREE_KEY ) //end of chain already + { + m_data[ ptr ] = key; + m_data[ ptr + 1 ] = value; + if ( m_size >= m_threshold ) + rehash( m_data.length * 2 ); //size is set inside + else + ++m_size; + return null; + } + else if ( k.equals( key ) ) //we check FREE and REMOVED prior to this call + { + final Object ret = m_data[ ptr + 1 ]; + m_data[ ptr + 1 ] = value; + return (V) ret; + } + + int firstRemoved = -1; + if ( k == REMOVED_KEY ) + firstRemoved = ptr; //we may find a key later + + while ( true ) + { + ptr = ( ptr + 2 ) & m_mask2; //that's next index calculation + k = m_data[ ptr ]; + if ( k == FREE_KEY ) + { + if ( firstRemoved != -1 ) + ptr = firstRemoved; + m_data[ ptr ] = key; + m_data[ ptr + 1 ] = value; + if ( m_size >= m_threshold ) + rehash( m_data.length * 2 ); //size is set inside + else + ++m_size; + return null; + } + else if ( k.equals( key ) ) + { + final Object ret = m_data[ ptr + 1 ]; + m_data[ ptr + 1 ] = value; + return (V) ret; + } + else if ( k == REMOVED_KEY ) + { + if ( firstRemoved == -1 ) + firstRemoved = ptr; + } + } + } + + @SuppressWarnings("unchecked") + public V remove( final K key ) + { + if ( key == null ) + return removeNullKey(); + + int ptr = getStartIndex(key) << 1; + Object k = m_data[ ptr ]; + if ( k == FREE_KEY ) + return null; //end of chain already + else if ( k.equals( key ) ) //we check FREE and REMOVED prior to this call + { + --m_size; + if ( m_data[ ( ptr + 2 ) & m_mask2 ] == FREE_KEY ) + m_data[ ptr ] = FREE_KEY; + else + m_data[ ptr ] = REMOVED_KEY; + final V ret = (V) m_data[ ptr + 1 ]; + m_data[ ptr + 1 ] = null; + return ret; + } + while ( true ) + { + ptr = ( ptr + 2 ) & m_mask2; //that's next index calculation + k = m_data[ ptr ]; + if ( k == FREE_KEY ) + return null; + else if ( k.equals( key ) ) + { + --m_size; + if ( m_data[ ( ptr + 2 ) & m_mask2 ] == FREE_KEY ) + m_data[ ptr ] = FREE_KEY; + else + m_data[ ptr ] = REMOVED_KEY; + final V ret = (V) m_data[ ptr + 1 ]; + m_data[ ptr + 1 ] = null; + return ret; + } + } + } + + @SuppressWarnings("unchecked") + private V insertNullKey(final V value) + { + if ( m_hasNull ) + { + final Object ret = m_nullValue; + m_nullValue = value; + return (V) ret; + } + else + { + m_nullValue = value; + ++m_size; + return null; + } + } + + @SuppressWarnings("unchecked") + private V removeNullKey() + { + if ( m_hasNull ) + { + final Object ret = m_nullValue; + m_nullValue = null; + m_hasNull = false; + --m_size; + return (V) ret; + } + else + { + return null; + } + } + + public int size() + { + return m_size; + } + + @SuppressWarnings("unchecked") + private void rehash( final int newCapacity ) + { + m_threshold = (int) (newCapacity/2 * m_fillFactor); + m_mask = newCapacity/2 - 1; + m_mask2 = newCapacity - 1; + + final int oldCapacity = m_data.length; + final Object[] oldData = m_data; + + m_data = new Object[ newCapacity ]; + Arrays.fill( m_data, FREE_KEY ); + + m_size = m_hasNull ? 1 : 0; + + for ( int i = 0; i < oldCapacity; i += 2 ) { + final Object oldKey = oldData[ i ]; + if( oldKey != FREE_KEY && oldKey != REMOVED_KEY ) + put( (K)oldKey, (V)oldData[ i + 1 ]); + } + } + + public int getStartIndex( final Object key ) + { + //key is not null here + return key.hashCode() & m_mask; + } + + /** Taken from FastUtil implementation */ + + /** Return the least power of two greater than or equal to the specified value. + * + * <p>Note that this function will return 1 when the argument is 0. + * + * @param x a long integer smaller than or equal to 2<sup>62</sup>. + * @return the least power of two greater than or equal to the specified value. + */ + public static long nextPowerOfTwo( long x ) { + if ( x == 0 ) return 1; + x--; + x |= x >> 1; + x |= x >> 2; + x |= x >> 4; + x |= x >> 8; + x |= x >> 16; + return ( x | x >> 32 ) + 1; + } + + /** Returns the least power of two smaller than or equal to 2<sup>30</sup> and larger than or equal to <code>Math.ceil( expected / f )</code>. + * + * @param expected the expected number of elements in a hash table. + * @param f the load factor. + * @return the minimum possible size for a backing array. + * @throws IllegalArgumentException if the necessary size is larger than 2<sup>30</sup>. + */ + public static int arraySize( final int expected, final float f ) { + final long s = Math.max( 2, nextPowerOfTwo( (long)Math.ceil( expected / f ) ) ); + if ( s > (1 << 30) ) throw new IllegalArgumentException( "Too large (" + expected + " expected elements with load factor " + f + ")" ); + return (int)s; + } + + //taken from FastUtil + private static final int INT_PHI = 0x9E3779B9; + + public static int phiMix( final int x ) { + final int h = x * INT_PHI; + return h ^ (h >> 16); +} + +} |