HHH-7633 Cache System#identity for IdentityMap reuse

This commit is contained in:
Sanne Grinovero 2012-09-21 14:26:26 +02:00
parent f85e9247e9
commit 29ad8e9cb9
1 changed files with 30 additions and 9 deletions

View File

@ -195,10 +195,10 @@ public final class IdentityMap<K,V> implements Map<K,V> {
}
public static final class IdentityMapEntry<K,V> implements java.util.Map.Entry<K,V> {
private K key;
private final K key;
private V value;
IdentityMapEntry(K key, V value) {
IdentityMapEntry(final K key, final V value) {
this.key=key;
this.value=value;
}
@ -211,15 +211,22 @@ public final class IdentityMap<K,V> implements Map<K,V> {
return value;
}
public V setValue(V value) {
public V setValue(final V value) {
V result = this.value;
this.value = value;
return result;
}
}
/**
* We need to base the identity on {@link System#identityHashCode(Object)} but
* attempt to lazily initialize and cache this value: being a native invocation
* it is an expensive value to retrieve.
*/
public static final class IdentityKey<K> implements Serializable {
private K key;
private final K key;
private int hash = 0;
IdentityKey(K key) {
this.key = key;
@ -233,7 +240,21 @@ public final class IdentityMap<K,V> implements Map<K,V> {
@Override
public int hashCode() {
return System.identityHashCode(key);
if ( this.hash == 0 ) {
//We consider "zero" as non-initialized value
final int newHash = System.identityHashCode( key );
if ( newHash == 0 ) {
//So make sure we don't store zeros as it would trigger initialization again:
//any value is fine as long as we're deterministic.
this.hash = -1;
return -1;
}
else {
this.hash = newHash;
return newHash;
}
}
return hash;
}
@Override