V get(Object key, int hash) { int c = count; if ( c != 0 ) { // read-volatile V result = null; HashEntry<K, V> e = getFirst( hash ); while ( e != null ) { if ( e.hash == hash && key.equals( e.key ) ) { V v = e.value; if ( v != null ) { result = v; break; } else { result = readValueUnderLock( e ); // recheck break; } } e = e.next; } // a hit if ( result != null ) { if ( eviction.onEntryHit( e ) ) { Set<HashEntry<K, V>> evicted = attemptEviction( false ); notifyEvictionListener( evicted ); } } return result; } return null; }
/** * Tests if the specified object is a key in this table. * * @param key possible key * * @return <tt>true</tt> if and only if the specified object * is a key in this table, as determined by the * <tt>equals</tt> method; <tt>false</tt> otherwise. * * @throws NullPointerException if the specified key is null */ @Override public boolean containsKey(Object key) { int hash = hash( key.hashCode() ); return segmentFor( hash ).containsKey( key, hash ); }
int c = segments[i].count; // read-volatile mcsum += mc[i] = segments[i].modCount; if ( segments[i].containsValue( value ) ) { return true; segments[i].lock(); if ( segments[i].containsValue( value ) ) { found = true; break; segments[i].unlock();
V put(K key, int hash, V value, boolean onlyIfAbsent) { lock(); Set<HashEntry<K, V>> evicted = null; try { int c = count; if ( c++ > threshold && eviction.strategy() == Eviction.NONE ) { rehash(); unlock(); notifyEvictionListener( evicted );
V get(Object key, int hash) { int c = count; if ( c != 0 ) { // read-volatile V result = null; HashEntry<K, V> e = getFirst( hash ); while ( e != null ) { if ( e.hash == hash && key.equals( e.key ) ) { V v = e.value; if ( v != null ) { result = v; break; } else { result = readValueUnderLock( e ); // recheck break; } } e = e.next; } // a hit if ( result != null ) { if ( eviction.onEntryHit( e ) ) { Set<HashEntry<K, V>> evicted = attemptEviction( false ); notifyEvictionListener( evicted ); } } return result; } return null; }
V replace(K key, int hash, V newValue) { lock(); Set<HashEntry<K, V>> evicted = null; try { HashEntry<K, V> e = getFirst( hash ); while ( e != null && ( e.hash != hash || !key.equals( e.key ) ) ) { e = e.next; } V oldValue = null; if ( e != null ) { oldValue = e.value; e.value = newValue; if ( eviction.onEntryHit( e ) ) { evicted = attemptEviction( true ); } } return oldValue; } finally { unlock(); notifyEvictionListener( evicted ); } }
private Set<HashEntry<K, V>> attemptEviction(boolean lockedAlready) { Set<HashEntry<K, V>> evicted = null; boolean obtainedLock = lockedAlready || tryLock(); if ( !obtainedLock && eviction.thresholdExpired() ) { lock(); obtainedLock = true; } if ( obtainedLock ) { try { if ( eviction.thresholdExpired() ) { evicted = eviction.execute(); } } finally { if ( !lockedAlready ) { unlock(); } } } return evicted; }
boolean replace(K key, int hash, V oldValue, V newValue) { lock(); Set<HashEntry<K, V>> evicted = null; try { HashEntry<K, V> e = getFirst( hash ); while ( e != null && ( e.hash != hash || !key.equals( e.key ) ) ) { e = e.next; } boolean replaced = false; if ( e != null && oldValue.equals( e.value ) ) { replaced = true; e.value = newValue; if ( eviction.onEntryHit( e ) ) { evicted = attemptEviction( true ); } } return replaced; } finally { unlock(); notifyEvictionListener( evicted ); } }
/** * 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 { return e.value; } finally { unlock(); } }
/** * Tests if the specified object is a key in this table. * * @param key possible key * * @return <tt>true</tt> if and only if the specified object * is a key in this table, as determined by the * <tt>equals</tt> method; <tt>false</tt> otherwise. * * @throws NullPointerException if the specified key is null */ @Override public boolean containsKey(Object key) { int hash = hash( key.hashCode() ); return segmentFor( hash ).containsKey( key, hash ); }
/** * Returns the value to which the specified key is mapped, * or {@code null} if this map contains no mapping for the key. * <p/> * <p>More formally, if this map contains a mapping from a key * {@code k} to a value {@code v} such that {@code key.equals(k)}, * then this method returns {@code v}; otherwise it returns * {@code null}. (There can be at most one such mapping.) * * @throws NullPointerException if the specified key is null */ @Override public V get(Object key) { int hash = hash( key.hashCode() ); return segmentFor( hash ).get( key, hash ); }
/** * Removes all of the mappings from this map. */ @Override public void clear() { for ( int i = 0; i < segments.length; ++i ) { segments[i].clear(); } }
boolean containsKey(Object key, int hash) { if ( count != 0 ) { // read-volatile HashEntry<K, V> e = getFirst( hash ); while ( e != null ) { if ( e.hash == hash && key.equals( e.key ) ) { return true; } e = e.next; } } return false; }
int c = segments[i].count; // read-volatile mcsum += mc[i] = segments[i].modCount; if ( segments[i].containsValue( value ) ) { return true; segments[i].lock(); if ( segments[i].containsValue( value ) ) { found = true; break; segments[i].unlock();