aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/gtPlusPlus/api/objects
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/gtPlusPlus/api/objects')
-rw-r--r--src/main/java/gtPlusPlus/api/objects/GregtechException.java28
-rw-r--r--src/main/java/gtPlusPlus/api/objects/Logger.java179
-rw-r--r--src/main/java/gtPlusPlus/api/objects/data/AutoMap.java345
-rw-r--r--src/main/java/gtPlusPlus/api/objects/data/ConcurrentHashSet.java18
-rw-r--r--src/main/java/gtPlusPlus/api/objects/data/ConcurrentSet.java53
-rw-r--r--src/main/java/gtPlusPlus/api/objects/data/FlexiblePair.java39
-rw-r--r--src/main/java/gtPlusPlus/api/objects/data/ObjMap.java285
-rw-r--r--src/main/java/gtPlusPlus/api/objects/data/Pair.java35
-rw-r--r--src/main/java/gtPlusPlus/api/objects/data/Quad.java45
-rw-r--r--src/main/java/gtPlusPlus/api/objects/data/ReverseAutoMap.java175
-rw-r--r--src/main/java/gtPlusPlus/api/objects/data/Triplet.java27
-rw-r--r--src/main/java/gtPlusPlus/api/objects/data/TypeCounter.java178
-rw-r--r--src/main/java/gtPlusPlus/api/objects/data/WeightedCollection.java102
-rw-r--r--src/main/java/gtPlusPlus/api/objects/data/weakref/WeakAutoMap.java12
-rw-r--r--src/main/java/gtPlusPlus/api/objects/minecraft/AABB.java65
-rw-r--r--src/main/java/gtPlusPlus/api/objects/minecraft/BTF_FluidTank.java188
-rw-r--r--src/main/java/gtPlusPlus/api/objects/minecraft/BTF_Inventory.java228
-rw-r--r--src/main/java/gtPlusPlus/api/objects/minecraft/BlockPos.java250
-rw-r--r--src/main/java/gtPlusPlus/api/objects/minecraft/CubicObject.java62
-rw-r--r--src/main/java/gtPlusPlus/api/objects/minecraft/DimChunkPos.java52
-rw-r--r--src/main/java/gtPlusPlus/api/objects/minecraft/FakeBlockPos.java253
-rw-r--r--src/main/java/gtPlusPlus/api/objects/minecraft/FakeWorld.java173
-rw-r--r--src/main/java/gtPlusPlus/api/objects/minecraft/FluidGT6.java31
-rw-r--r--src/main/java/gtPlusPlus/api/objects/minecraft/FormattedTooltipString.java25
-rw-r--r--src/main/java/gtPlusPlus/api/objects/minecraft/GenericStack.java42
-rw-r--r--src/main/java/gtPlusPlus/api/objects/minecraft/ItemPackage.java58
-rw-r--r--src/main/java/gtPlusPlus/api/objects/minecraft/ItemStackData.java35
-rw-r--r--src/main/java/gtPlusPlus/api/objects/minecraft/NoConflictGTRecipeMap.java123
-rw-r--r--src/main/java/gtPlusPlus/api/objects/minecraft/SafeTexture.java64
-rw-r--r--src/main/java/gtPlusPlus/api/objects/minecraft/ShapedRecipe.java250
-rw-r--r--src/main/java/gtPlusPlus/api/objects/minecraft/TexturePackage.java55
-rw-r--r--src/main/java/gtPlusPlus/api/objects/minecraft/ThreadPooCollector.java111
-rw-r--r--src/main/java/gtPlusPlus/api/objects/minecraft/multi/NoEUBonusMultiBehaviour.java27
-rw-r--r--src/main/java/gtPlusPlus/api/objects/minecraft/multi/NoOutputBonusMultiBehaviour.java27
-rw-r--r--src/main/java/gtPlusPlus/api/objects/minecraft/multi/NoSpeedBonusMultiBehaviour.java27
-rw-r--r--src/main/java/gtPlusPlus/api/objects/minecraft/multi/SpecialMultiBehaviour.java44
-rw-r--r--src/main/java/gtPlusPlus/api/objects/random/CSPRNG_DO_NOT_USE.java271
-rw-r--r--src/main/java/gtPlusPlus/api/objects/random/UUIDGenerator.java449
-rw-r--r--src/main/java/gtPlusPlus/api/objects/random/XSTR.java278
39 files changed, 4709 insertions, 0 deletions
diff --git a/src/main/java/gtPlusPlus/api/objects/GregtechException.java b/src/main/java/gtPlusPlus/api/objects/GregtechException.java
new file mode 100644
index 0000000000..916dbc4aaf
--- /dev/null
+++ b/src/main/java/gtPlusPlus/api/objects/GregtechException.java
@@ -0,0 +1,28 @@
+package gtPlusPlus.api.objects;
+
+public class GregtechException extends Throwable {
+
+ private static final long serialVersionUID = 3601884582161841486L;
+
+ public GregtechException(String aError) {
+ this(aError, true);
+ }
+
+ public GregtechException(String aError, boolean aIsVerbose) {
+ Logger.ERROR("Throwing GT++ Exception!");
+ Logger.ERROR("[EXCEPTION] "+aError);
+ if (aIsVerbose) {
+ Logger.INFO("Throwing GT++ Exception!");
+ Logger.INFO("[EXCEPTION] "+aError);
+ printStackTrace();
+ }
+ }
+
+ @Override
+ public void printStackTrace() {
+ super.printStackTrace();
+ }
+
+
+
+}
diff --git a/src/main/java/gtPlusPlus/api/objects/Logger.java b/src/main/java/gtPlusPlus/api/objects/Logger.java
new file mode 100644
index 0000000000..1a1da6868b
--- /dev/null
+++ b/src/main/java/gtPlusPlus/api/objects/Logger.java
@@ -0,0 +1,179 @@
+package gtPlusPlus.api.objects;
+
+import cpw.mods.fml.common.FMLLog;
+import cpw.mods.fml.relauncher.FMLRelaunchLog;
+import gtPlusPlus.core.lib.CORE;
+import gtPlusPlus.preloader.CORE_Preloader;
+import gtPlusPlus.preloader.asm.AsmConfig;
+import org.apache.logging.log4j.LogManager;
+
+public class Logger {
+
+ public Logger(String string) {
+
+ }
+
+ // Logging Functions
+ public static final org.apache.logging.log4j.Logger modLogger = Logger.makeLogger();
+
+ // Generate GT++ Logger
+ public static org.apache.logging.log4j.Logger makeLogger() {
+ final org.apache.logging.log4j.Logger gtPlusPlusLogger = LogManager.getLogger("GT++");
+ return gtPlusPlusLogger;
+ }
+
+ private static final boolean enabled = !AsmConfig.disableAllLogging;
+
+ public static final org.apache.logging.log4j.Logger getLogger() {
+ return modLogger;
+ }
+
+ // Non-Dev Comments
+ public static void INFO(final String s) {
+ if (enabled) {
+ modLogger.info(s);
+ }
+ }
+
+ // Non-Dev Comments
+ public static void MACHINE_INFO(String s, Object... args) {
+ if (enabled) {
+ boolean localPlayer = CORE_Preloader.DEV_ENVIRONMENT;
+ if (CORE.ConfigSwitches.MACHINE_INFO || localPlayer) {
+ final String name1 = gtPlusPlus.core.util.reflect.ReflectionUtils.getMethodName(2);
+ modLogger.info("Machine Info: " + s + " | " + name1, args);
+ }
+ }
+ }
+
+ // Developer Comments
+ public static void WARNING(final String s) {
+ if (enabled) {
+ if (CORE_Preloader.DEBUG_MODE) {
+ modLogger.warn(s);
+ }
+ }
+ }
+
+ // Errors
+ public static void ERROR(final String s) {
+ if (enabled) {
+ if (CORE_Preloader.DEBUG_MODE) {
+ modLogger.fatal(s);
+ }
+ }
+ }
+
+ // Developer Logger
+ public static void SPECIFIC_WARNING(final String whatToLog, final String msg, final int line) {
+ if (enabled) {
+ // if (!CORE_Preloader.DEBUG_MODE){
+ FMLLog.warning("GT++ |" + line + "| " + whatToLog + " | " + msg);
+ // }
+ }
+ }
+
+ // ASM Comments
+ public static void LOG_ASM(final String s) {
+ if (enabled) {
+ FMLRelaunchLog.info("[Special ASM Logging] ", s);
+ }
+ }
+
+
+
+
+
+
+
+
+
+
+ /**
+ * Special Loggers
+ */
+
+ /**
+ * Special Logger for Bee related content
+ */
+ public static void BEES(final String s) {
+ if (enabled) {
+ if (CORE_Preloader.DEV_ENVIRONMENT || CORE_Preloader.DEBUG_MODE) {
+ modLogger.info("[Bees] "+s);
+ }
+ }
+ }
+ /**
+ * Special Logger for Debugging Bee related content
+ */
+ public static void DEBUG_BEES(final String s) {
+ if (enabled) {
+ if (CORE_Preloader.DEV_ENVIRONMENT || CORE_Preloader.DEBUG_MODE) {
+ modLogger.info("[Debug][Bees] "+s);
+ }
+ }
+ }
+
+
+
+ /**
+ * Special Logger for Materials related content
+ */
+ public static void MATERIALS(final String s) {
+ if (enabled) {
+ if (CORE_Preloader.DEV_ENVIRONMENT || CORE_Preloader.DEBUG_MODE) {
+ modLogger.info("[Materials] "+s);
+ }
+ }
+ }
+ /**
+ * Special Logger for Debugging Materials related content
+ */
+ public static void DEBUG_MATERIALS(final String s) {
+ if (enabled) {
+ if (CORE_Preloader.DEV_ENVIRONMENT || CORE_Preloader.DEBUG_MODE) {
+ modLogger.info("[Debug][Materials] "+s);
+ }
+ }
+ }
+
+ /**
+ * Special Logger for Reflection related content
+ */
+ public static void REFLECTION(final String s) {
+ if (enabled) {
+ if (CORE_Preloader.DEV_ENVIRONMENT || CORE_Preloader.DEBUG_MODE) {
+ modLogger.info("[Reflection] "+s);
+ }
+ }
+ }
+
+
+ /**
+ * Special Logger for Darkworld related content
+ */
+ public static void WORLD(final String s) {
+ if (enabled) {
+ if (CORE_Preloader.DEV_ENVIRONMENT || CORE_Preloader.DEBUG_MODE) {
+ modLogger.info("[WorldGen] "+s);
+ }
+ }
+ }
+
+ public static void RECIPE(String string) {
+ if (enabled) {
+ if (/*CORE_Preloader.DEV_ENVIRONMENT || */CORE_Preloader.DEBUG_MODE) {
+ modLogger.info("[Recipe] "+string);
+ }
+ }
+ }
+
+ public static void SPACE(final String s) {
+ if (enabled) {
+ modLogger.info("[Space] "+s);
+ }
+ }
+
+
+
+}
diff --git a/src/main/java/gtPlusPlus/api/objects/data/AutoMap.java b/src/main/java/gtPlusPlus/api/objects/data/AutoMap.java
new file mode 100644
index 0000000000..e04f1af03a
--- /dev/null
+++ b/src/main/java/gtPlusPlus/api/objects/data/AutoMap.java
@@ -0,0 +1,345 @@
+package gtPlusPlus.api.objects.data;
+
+import java.io.Serializable;
+import java.util.*;
+
+public class AutoMap<V> implements Iterable<V>, Cloneable, Serializable, Collection<V>, Queue<V>, List<V> {
+
+ /**
+ * The Internal Map
+ */
+ protected final Map<Integer, V> mInternalMap;
+ protected final Map<String, Integer> mInternalNameMap;
+
+ /**
+ * The Internal ID
+ */
+ private int mInternalID = 0;
+ private static final long serialVersionUID = 3771412318075131790L;
+
+
+ public AutoMap() {
+ this(new LinkedHashMap<Integer, V>());
+ }
+
+ public Map<Integer, V> getMap(){
+ return mInternalMap;
+ }
+
+ public AutoMap(Map<Integer, V> defaultMapType) {
+ mInternalMap = defaultMapType;
+ mInternalNameMap = new LinkedHashMap<String, Integer>();
+ }
+
+ /**
+ * Generates an AutoMap from the List.
+ * @param aList - Data to be inserted into the AutoMap.
+ */
+ public AutoMap(List<V> aList) {
+ mInternalMap = new LinkedHashMap<Integer, V>();
+ mInternalNameMap = new LinkedHashMap<String, Integer>();
+ if (aList != null && aList.size() > 0) {
+ for (V obj : aList) {
+ add(obj);
+ }
+ }
+ }
+ /**
+ * Generates an AutoMap from a Set.
+ * @param aList - Data to be inserted into the AutoMap.
+ */
+ public AutoMap(Set<V> aList) {
+ mInternalMap = new LinkedHashMap<Integer, V>();
+ mInternalNameMap = new LinkedHashMap<String, Integer>();
+ if (aList != null && aList.size() > 0) {
+ for (V obj : aList) {
+ add(obj);
+ }
+ }
+ }
+ /**
+ * Generates an AutoMap from a Collection.
+ * @param aList - Data to be inserted into the AutoMap.
+ */
+ public AutoMap(Collection<V> aList) {
+ mInternalMap = new LinkedHashMap<Integer, V>();
+ mInternalNameMap = new LinkedHashMap<String, Integer>();
+ if (aList != null && aList.size() > 0) {
+ for (V obj : aList) {
+ add(obj);
+ }
+ }
+ }
+
+ /**
+ * Generates an AutoMap from a Array.
+ * @param aArray - Data to be inserted into the AutoMap.
+ */
+ public AutoMap(V[] aArray) {
+ mInternalMap = new LinkedHashMap<Integer, V>();
+ mInternalNameMap = new LinkedHashMap<String, Integer>();
+ if (aArray != null && aArray.length > 0) {
+ for (V obj : aArray) {
+ add(obj);
+ }
+ }
+ }
+
+ @Override
+ public Iterator<V> iterator() {
+ return values().iterator();
+ }
+
+ public synchronized boolean setValue(V object){
+ int mOriginalID = this.mInternalID;
+ put(object);
+ if (this.mInternalMap.get(mOriginalID).equals(object) || mOriginalID > this.mInternalID){
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+
+ public synchronized V put(V object){
+ return set(object);
+ }
+
+ public synchronized boolean add(V object){
+ return set(object) != null;
+ }
+
+ public synchronized V set(V object){
+ if (object == null) {
+ return null;
+ }
+ mInternalNameMap.put(""+object.hashCode(), (mInternalID+1));
+ return mInternalMap.put(mInternalID++, object);
+ }
+
+ public synchronized V get(int id){
+ return mInternalMap.get(id);
+ }
+
+ public synchronized Collection<V> values(){
+ return mInternalMap.values();
+ }
+
+ public synchronized int size(){
+ return mInternalMap.size();
+ }
+
+ public synchronized int hashCode(){
+ return mInternalMap.hashCode();
+ }
+
+ public synchronized boolean containsKey(int key){
+ return mInternalMap.containsKey(key);
+ }
+
+ public synchronized boolean containsValue(V value){
+ return mInternalMap.containsValue(value);
+ }
+
+ public synchronized boolean isEmpty(){
+ return mInternalMap.isEmpty();
+ }
+
+ public synchronized void clear(){
+ this.mInternalID = 0;
+ this.mInternalMap.clear();
+ this.mInternalNameMap.clear();
+ return;
+ }
+
+ @SuppressWarnings("unchecked")
+ public V[] toArray() {
+ V[] toR = (V[]) java.lang.reflect.Array.newInstance(mInternalMap.get(0).getClass(), mInternalMap.size());
+ for (int i = 0; i < mInternalMap.size(); i++) {
+ toR[i] = mInternalMap.get(i);
+ }
+ return toR;
+ }
+
+ public synchronized final int getInternalID() {
+ return mInternalID;
+ }
+
+ public synchronized final boolean remove(Object value) {
+ value.getClass();
+ if (this.mInternalMap.containsValue(value)) {
+ return this.mInternalMap.remove(mInternalNameMap.get(""+value.hashCode()), value);
+ }
+ return false;
+ }
+
+ @Override
+ public boolean contains(Object o) {
+ for (V g : this.mInternalMap.values()) {
+ if (g.equals(o)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public <V> V[] toArray(V[] a) {
+ return (V[]) toArray();
+ }
+
+ @Override
+ public boolean containsAll(Collection<?> c) {
+ boolean aTrue = true;
+ for (Object g : c) {
+ if (!this.contains(g)) {
+ aTrue = false;
+ }
+ }
+ return aTrue;
+ }
+
+ @Override
+ public boolean addAll(Collection<? extends V> c) {
+ boolean aTrue = true;
+ for (V g : c) {
+ if (!this.add(g)) {
+ aTrue = false;
+ }
+ }
+ return aTrue;
+ }
+
+ @Override
+ public boolean removeAll(Collection<?> c) {
+ boolean aTrue = true;
+ for (Object g : c) {
+ if (!this.remove(g)) {
+ aTrue = false;
+ }
+ }
+ return aTrue;
+ }
+
+ @Override
+ public boolean retainAll(Collection<?> c) {
+ AutoMap<?> aTempAllocation = new AutoMap<Object>();
+ boolean aTrue = false;
+ aTempAllocation = this;
+ aTempAllocation.removeAll(c);
+ aTempAllocation.clear();
+ aTrue = aTempAllocation.isEmpty();
+ aTempAllocation.clear();
+ return aTrue;
+ }
+
+ @Override
+ public boolean offer(V e) {
+ return add(e);
+ }
+
+ @Override
+ public V remove() {
+ V y = this.get(0);
+ if (remove(y))
+ return y;
+ else
+ return null;
+ }
+
+ @Override
+ public V poll() {
+ if (this.mInternalMap.isEmpty()) {
+ return null;
+ }
+ return remove();
+ }
+
+ @Override
+ public V element() {
+ if (this.mInternalMap.isEmpty()) {
+ return null;
+ }
+ return this.get(0);
+ }
+
+ @Override
+ public V peek() {
+ return element();
+ }
+
+ @Override
+ public boolean addAll(int index, Collection<? extends V> c) {
+ for (V y : c) {
+ add(y);
+ }
+ return true;
+ }
+
+ @Override
+ public V set(int index, V element) {
+ return mInternalMap.put(index, element);
+ }
+
+ @Override
+ public void add(int index, V element) {
+ add(element);
+ }
+
+ @Override
+ public V remove(int index) {
+ V h = mInternalMap.get(index);
+ set(index, null);
+ return h;
+ }
+
+ @Override
+ public int indexOf(Object o) {
+ int aCount = 0;
+ for (V of : mInternalMap.values()) {
+ if (of != o) {
+ aCount++;
+ continue;
+ }
+ else {
+ return aCount;
+ }
+ }
+ return -1;
+ }
+
+ @Override
+ public int lastIndexOf(Object o) {
+ //TODO
+ return indexOf(o);
+ }
+
+ @Override
+ public ListIterator<V> listIterator() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public ListIterator<V> listIterator(int index) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public List<V> subList(int fromIndex, int toIndex) {
+ AutoMap<V> aNewSubList = new AutoMap<V>();
+ for (int slot=fromIndex; slot<=toIndex; slot++) {
+ V obj = mInternalMap.get(slot);
+ if (obj == null) {
+ continue;
+ }
+ else {
+ aNewSubList.put(obj);
+ }
+ }
+ return aNewSubList;
+ }
+
+}
diff --git a/src/main/java/gtPlusPlus/api/objects/data/ConcurrentHashSet.java b/src/main/java/gtPlusPlus/api/objects/data/ConcurrentHashSet.java
new file mode 100644
index 0000000000..991908e402
--- /dev/null
+++ b/src/main/java/gtPlusPlus/api/objects/data/ConcurrentHashSet.java
@@ -0,0 +1,18 @@
+package gtPlusPlus.api.objects.data;
+
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+public class ConcurrentHashSet<V> extends ConcurrentSet<V> {
+
+ private static final long serialVersionUID = -1293478938482781728L;
+
+ public ConcurrentHashSet() {
+ this(new ConcurrentHashMap<Integer, V>());
+ }
+
+ public ConcurrentHashSet(ConcurrentMap<Integer, V> defaultMapType) {
+ super(defaultMapType);
+ }
+
+}
diff --git a/src/main/java/gtPlusPlus/api/objects/data/ConcurrentSet.java b/src/main/java/gtPlusPlus/api/objects/data/ConcurrentSet.java
new file mode 100644
index 0000000000..1d3ffc1c01
--- /dev/null
+++ b/src/main/java/gtPlusPlus/api/objects/data/ConcurrentSet.java
@@ -0,0 +1,53 @@
+package gtPlusPlus.api.objects.data;
+
+import java.io.Serializable;
+import java.util.AbstractSet;
+import java.util.Iterator;
+import java.util.concurrent.ConcurrentMap;
+
+public abstract class ConcurrentSet<E> extends AbstractSet<E> implements Serializable {
+
+ private static final long serialVersionUID = -6761513279741915432L;
+
+ private final ConcurrentMap<Integer, E> mInternalMap;
+
+ private int mInternalID = 0;
+
+ /**
+ * Creates a new instance which wraps the specified {@code map}.
+ */
+ public ConcurrentSet(ConcurrentMap<Integer, E> aMap) {
+ mInternalMap = aMap;
+ }
+
+ @Override
+ public int size() {
+ return mInternalMap.size();
+ }
+
+ @Override
+ public boolean contains(Object o) {
+ return mInternalMap.containsKey(o);
+ }
+
+ @Override
+ public boolean add(E o) {
+ return mInternalMap.putIfAbsent(mInternalID++, o) == null;
+ }
+
+ @Override
+ public boolean remove(Object o) {
+ return mInternalMap.remove(o) != null;
+ }
+
+ @Override
+ public void clear() {
+ this.mInternalID = 0;
+ mInternalMap.clear();
+ }
+
+ @Override
+ public Iterator<E> iterator() {
+ return mInternalMap.values().iterator();
+ }
+}
diff --git a/src/main/java/gtPlusPlus/api/objects/data/FlexiblePair.java b/src/main/java/gtPlusPlus/api/objects/data/FlexiblePair.java
new file mode 100644
index 0000000000..64f57b4e5a
--- /dev/null
+++ b/src/main/java/gtPlusPlus/api/objects/data/FlexiblePair.java
@@ -0,0 +1,39 @@
+package gtPlusPlus.api.objects.data;
+
+import java.io.Serializable;
+
+import com.google.common.base.Objects;
+
+public class FlexiblePair<K,V> implements Serializable {
+
+ /**
+ * SVUID
+ */
+ private static final long serialVersionUID = 1250550491092812443L;
+ private final K key;
+ private V value;
+
+ public FlexiblePair(final K key, final V value){
+ this.key = key;
+ this.value = value;
+ }
+
+ final public K getKey(){
+ return this.key;
+ }
+
+ final public V getValue(){
+ return this.value;
+ }
+
+ final public void setValue(V aObj) {
+ value = aObj;
+ }
+
+ @Override
+ public int hashCode() {
+ Integer aCode = Objects.hashCode(getKey(), getValue());
+ return aCode != null ? aCode : super.hashCode();
+ }
+
+} \ No newline at end of file
diff --git a/src/main/java/gtPlusPlus/api/objects/data/ObjMap.java b/src/main/java/gtPlusPlus/api/objects/data/ObjMap.java
new file mode 100644
index 0000000000..49dd70d2b8
--- /dev/null
+++ b/src/main/java/gtPlusPlus/api/objects/data/ObjMap.java
@@ -0,0 +1,285 @@
+package gtPlusPlus.api.objects.data;
+
+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;
+