boolean containsValue(Object value) { if ( count != 0 ) { // read-volatile HashEntry<K, V>[] tab = table; int len = tab.length; for ( int i = 0; i < len; i++ ) { for ( HashEntry<K, V> e = tab[i]; e != null; e = e.next ) { Object opaque = e.valueRef; V v; if ( opaque == null ) { v = readValueUnderLock( e ); // recheck } else { v = e.dereferenceValue( opaque ); } if ( value.equals( v ) ) { return true; } } } } return false; }
&& ( refRemove || hash != e.hash || !keyEq( key, e.key() ) ) ) { e = e.next; V v = e.value(); if ( value == null || value.equals( v ) ) { oldValue = v; HashEntry<K, V> newFirst = e.next; for ( HashEntry<K, V> p = first; p != e; p = p.next ) { K pKey = p.key(); if ( pKey == null ) { // Skip GC'd keys c--; newFirst = newHashEntry( pKey, p.hash, newFirst, p.value() );
boolean replace(K key, int hash, V oldValue, V newValue) { lock(); try { removeStale(); HashEntry<K, V> e = getFirst( hash ); while ( e != null && ( e.hash != hash || !keyEq( key, e.key() ) ) ) { e = e.next; } boolean replaced = false; if ( e != null && oldValue.equals( e.value() ) ) { replaced = true; e.setValue( newValue, valueType, refQueue ); } return replaced; } finally { unlock(); } }
&& ( refRemove || hash != e.hash || !keyEq( key, e.key() ) ) ) { e = e.next; V v = e.value(); if ( value == null || value.equals( v ) ) { oldValue = v; HashEntry<K, V> newFirst = e.next; for ( HashEntry<K, V> p = first; p != e; p = p.next ) { K pKey = p.key(); if ( pKey == null ) { // Skip GC'd keys c--; newFirst = newHashEntry( pKey, p.hash, newFirst, p.value() );
boolean containsValue(Object value) { if ( count != 0 ) { // read-volatile HashEntry<K, V>[] tab = table; int len = tab.length; for ( int i = 0; i < len; i++ ) { for ( HashEntry<K, V> e = tab[i]; e != null; e = e.next ) { Object opaque = e.valueRef; V v; if ( opaque == null ) { v = readValueUnderLock( e ); // recheck } else { v = e.dereferenceValue( opaque ); } if ( value.equals( v ) ) { return true; } } } } return false; }
/** * Reads value field of an entry under lock. Called if value * field ever appears to be null. This is possible only if a * compiler happens to reorder a HashEntry initialization with * its table assignment, which is legal under memory model * but is not known to ever occur. */ V readValueUnderLock(HashEntry<K, V> e) { lock(); try { removeStale(); return e.value(); } finally { unlock(); } }
V get(Object key, int hash) { if ( count != 0 ) { // read-volatile HashEntry<K, V> e = getFirst( hash ); while ( e != null ) { if ( e.hash == hash && keyEq( key, e.key() ) ) { Object opaque = e.valueRef; if ( opaque != null ) { return e.dereferenceValue( opaque ); } return readValueUnderLock( e ); // recheck } e = e.next; } } return null; }
V replace(K key, int hash, V newValue) { lock(); try { removeStale(); HashEntry<K, V> e = getFirst( hash ); while ( e != null && ( e.hash != hash || !keyEq( key, e.key() ) ) ) { e = e.next; } V oldValue = null; if ( e != null ) { oldValue = e.value(); e.setValue( newValue, valueType, refQueue ); } return oldValue; } finally { unlock(); } }
final V value() { return dereferenceValue( valueRef ); }
boolean replace(K key, int hash, V oldValue, V newValue) { lock(); try { removeStale(); HashEntry<K, V> e = getFirst( hash ); while ( e != null && ( e.hash != hash || !keyEq( key, e.key() ) ) ) { e = e.next; } boolean replaced = false; if ( e != null && oldValue.equals( e.value() ) ) { replaced = true; e.setValue( newValue, valueType, refQueue ); } return replaced; } finally { unlock(); } }
final void setValue(V value, ReferenceType valueType, ReferenceQueue<Object> refQueue) { this.valueRef = newValueReference( value, valueType, refQueue ); }
boolean containsKey(Object key, int hash) { if ( count != 0 ) { // read-volatile HashEntry<K, V> e = getFirst( hash ); while ( e != null ) { if ( e.hash == hash && keyEq( key, e.key() ) ) { return true; } e = e.next; } } return false; }
Segment( int initialCapacity, float lf, ReferenceType keyType, ReferenceType valueType, boolean identityComparisons) { loadFactor = lf; this.keyType = keyType; this.valueType = valueType; this.identityComparisons = identityComparisons; setTable( HashEntry.<K, V>newArray( initialCapacity ) ); }
HashEntry<K, V> newHashEntry(K key, int hash, HashEntry<K, V> next, V value) { return new HashEntry<K, V>( key, hash, next, value, keyType, valueType, refQueue ); }
HashEntry( K key, int hash, HashEntry<K, V> next, V value, ReferenceType keyType, ReferenceType valueType, ReferenceQueue<Object> refQueue) { this.hash = hash; this.next = next; this.keyRef = newKeyReference( key, keyType, refQueue ); this.valueRef = newValueReference( value, valueType, refQueue ); }