merge key and value arrays
we have several hundred thousand of those MiniMaps and this reduces the memory requirement by 8 bytes per instance
This commit is contained in:
@@ -15,18 +15,16 @@ public class MiniMap<K, V> {
|
|||||||
private static final Object[] EMPTY_ARRAY = new Object[0];
|
private static final Object[] EMPTY_ARRAY = new Object[0];
|
||||||
private static final MiniMap<?,?> EMPTY_MAP = new MiniMap<>();
|
private static final MiniMap<?,?> EMPTY_MAP = new MiniMap<>();
|
||||||
|
|
||||||
private Object[] keys;
|
// keys are on even indices (0,2,4,...) and values on uneven (1,3,5,...)
|
||||||
private Object[] values;
|
private Object[] keysValues;
|
||||||
|
|
||||||
|
|
||||||
public MiniMap() {
|
public MiniMap() {
|
||||||
keys = EMPTY_ARRAY;
|
keysValues = EMPTY_ARRAY;
|
||||||
values = EMPTY_ARRAY;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public MiniMap(final MiniMap<K, V> miniMap){
|
public MiniMap(final MiniMap<K, V> miniMap){
|
||||||
keys = miniMap.keys.clone();
|
keysValues = miniMap.keysValues.clone();
|
||||||
values = miniMap.values.clone();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@@ -35,7 +33,7 @@ public class MiniMap<K, V> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int size() {
|
public int size() {
|
||||||
return keys.length;
|
return keysValues.length / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isEmpty() {
|
public boolean isEmpty() {
|
||||||
@@ -49,10 +47,11 @@ public class MiniMap<K, V> {
|
|||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public V get(Object key) {
|
public V get(Object key) {
|
||||||
|
|
||||||
for (int i = 0; i < keys.length; i++) {
|
final int size = size();
|
||||||
Object object = keys[i];
|
for (int i = 0; i < size; i++) {
|
||||||
|
Object object = keysValues[2*i];
|
||||||
if (Objects.equals(key, object)) {
|
if (Objects.equals(key, object)) {
|
||||||
return (V) values[i];
|
return (V) keysValues[2*i+1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@@ -63,25 +62,23 @@ public class MiniMap<K, V> {
|
|||||||
V oldValue = get(key);
|
V oldValue = get(key);
|
||||||
|
|
||||||
if (oldValue != null) {
|
if (oldValue != null) {
|
||||||
for (int i = 0; i < keys.length; i++) {
|
final int size = size();
|
||||||
Object object = keys[i];
|
for (int i = 0; i < size; i++) {
|
||||||
|
Object object = keysValues[2*i];
|
||||||
if (Objects.equals(key, object)) {
|
if (Objects.equals(key, object)) {
|
||||||
values[i] = value;
|
keysValues[2*i+1] = value;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
final Object[] newKeys = new Object[keys.length + 1];
|
final Object[] newKeysValues = new Object[keysValues.length + 2];
|
||||||
System.arraycopy(keys, 0, newKeys, 0, keys.length);
|
System.arraycopy(keysValues, 0, newKeysValues, 0, keysValues.length);
|
||||||
|
|
||||||
final Object[] newValues = new Object[values.length + 1];
|
|
||||||
System.arraycopy(values, 0, newValues, 0, values.length);
|
|
||||||
|
|
||||||
newKeys[newKeys.length - 1] = key;
|
newKeysValues[newKeysValues.length - 2] = key;
|
||||||
newValues[newValues.length - 1] = value;
|
newKeysValues[newKeysValues.length - 1] = value;
|
||||||
|
|
||||||
keys = newKeys;
|
keysValues = newKeysValues;
|
||||||
values = newValues;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return oldValue;
|
return oldValue;
|
||||||
@@ -94,26 +91,28 @@ public class MiniMap<K, V> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void clear() {
|
public void clear() {
|
||||||
keys = EMPTY_ARRAY;
|
keysValues = EMPTY_ARRAY;
|
||||||
values = EMPTY_ARRAY;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public Set<K> keySet() {
|
public Set<K> keySet() {
|
||||||
final Set<K> result = new HashSet<>(keys.length);
|
final Set<K> result = new HashSet<>(size());
|
||||||
|
|
||||||
for (Object k : keys) {
|
final int size = size();
|
||||||
result.add((K) k);
|
for (int i = 0; i < size; i++) {
|
||||||
|
K k = (K) keysValues[2*i];
|
||||||
|
result.add(k);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public Set<V> values() {
|
public Set<V> values() {
|
||||||
final Set<V> result = new HashSet<>(values.length);
|
final Set<V> result = new HashSet<>(size());
|
||||||
|
final int size = size();
|
||||||
for (Object v : values) {
|
for (int i = 0; i < size; i++) {
|
||||||
result.add((V) v);
|
V v = (V) keysValues[2*i+1];
|
||||||
|
result.add(v);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -122,8 +121,7 @@ public class MiniMap<K, V> {
|
|||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
final int prime = 31;
|
final int prime = 31;
|
||||||
int result = 1;
|
int result = 1;
|
||||||
result = prime * result + Arrays.hashCode(keys);
|
result = prime * result + Arrays.hashCode(keysValues);
|
||||||
result = prime * result + Arrays.hashCode(values);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,9 +135,7 @@ public class MiniMap<K, V> {
|
|||||||
if (getClass() != obj.getClass())
|
if (getClass() != obj.getClass())
|
||||||
return false;
|
return false;
|
||||||
MiniMap other = (MiniMap) obj;
|
MiniMap other = (MiniMap) obj;
|
||||||
if (!Arrays.equals(keys, other.keys))
|
if (!Arrays.equals(keysValues, other.keysValues))
|
||||||
return false;
|
|
||||||
if (!Arrays.equals(values, other.values))
|
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user