/** * Returns {@code true} if the given objects are considered equivalent. * * <p>The {@code equivalent} method implements an equivalence relation on object references: * * <ul> * <li>It is <i>reflexive</i>: for any reference {@code x}, including null, {@code * equivalent(x, x)} returns {@code true}. * <li>It is <i>symmetric</i>: for any references {@code x} and {@code y}, {@code * equivalent(x, y) == equivalent(y, x)}. * <li>It is <i>transitive</i>: for any references {@code x}, {@code y}, and {@code z}, if * {@code equivalent(x, y)} returns {@code true} and {@code equivalent(y, z)} returns {@code * true}, then {@code equivalent(x, z)} returns {@code true}. * <li>It is <i>consistent</i>: for any references {@code x} and {@code y}, multiple invocations * of {@code equivalent(x, y)} consistently return {@code true} or consistently return {@code * false} (provided that neither {@code x} nor {@code y} is modified). * </ul> */ public final boolean equivalent( T a, T b) { if (a == b) { return true; } if (a == null || b == null) { return false; } return doEquivalent(a, b); }
/** * Returns a hash code for {@code t}. * * <p>The {@code hash} has the following properties: * <ul> * <li>It is <i>consistent</i>: for any reference {@code x}, multiple invocations of * {@code hash(x}} consistently return the same value provided {@code x} remains unchanged * according to the definition of the equivalence. The hash need not remain consistent from * one execution of an application to another execution of the same application. * <li>It is <i>distributable across equivalence</i>: for any references {@code x} and {@code y}, * if {@code equivalent(x, y)}, then {@code hash(x) == hash(y)}. It is <i>not</i> necessary * that the hash be distributable across <i>inequivalence</i>. If {@code equivalence(x, y)} * is false, {@code hash(x) == hash(y)} may still be true. * <li>{@code hash(null)} is {@code 0}. * </ul> */ public final int hash(@Nullable T t) { if (t == null) { return 0; } return doHash(t); }
@Nonnull @Override Equivalence<Object> defaultEquivalence() { return Equivalence.equals(); } },
for (ReferenceEntry<K, V> e = table.get(j); e != null; e = e.getNext()) { V v = segment.getLiveValue(e, now); if (v != null && valueEquivalence.equivalent(value, v)) { return true;
@Nonnull @Override Equivalence<Object> defaultEquivalence() { return Equivalence.identity(); } };
int hash( Object key) { int h = keyEquivalence.hash(key); return rehash(h); }
@Nullable ReferenceEntry<K, V> getEntry(Object key, int hash) { for (ReferenceEntry<K, V> e = getFirst(hash); e != null; e = e.getNext()) { if (e.getHash() != hash) { continue; } K entryKey = e.getKey(); if (entryKey == null) { tryDrainReferenceQueues(); continue; } if (map.keyEquivalence.equivalent(key, entryKey)) { return e; } } return null; }
@Nonnull @Override Equivalence<Object> defaultEquivalence() { return Equivalence.identity(); } },
K entryKey = e.getKey(); if (e.getHash() == hash && entryKey != null && map.keyEquivalence.equivalent(key, entryKey)) { ValueReference<K, V> v = e.getValueReference(); if (v == valueReference) {
boolean removeLoadingValue(K key, int hash, @Nonnull LoadingValueReference<K, V> valueReference) { lock(); try { AtomicReferenceArray<ReferenceEntry<K, V>> table = this.table; int index = hash & (table.length() - 1); ReferenceEntry<K, V> first = table.get(index); for (ReferenceEntry<K, V> e = first; e != null; e = e.getNext()) { K entryKey = e.getKey(); if (e.getHash() == hash && entryKey != null && map.keyEquivalence.equivalent(key, entryKey)) { ValueReference<K, V> v = e.getValueReference(); if (v == valueReference) { if (valueReference.isActive()) { e.setValueReference(valueReference.getOldValue()); } else { ReferenceEntry<K, V> newFirst = removeEntryFromChain(first, e); table.set(index, newFirst); } return true; } return false; } } return false; } finally { unlock(); postWriteCleanup(); } }
K entryKey = e.getKey(); if (e.getHash() == hash && entryKey != null && map.keyEquivalence.equivalent(key, entryKey)) { ValueReference<K, V> valueReference = e.getValueReference(); V entryValue = valueReference.get(); if (map.valueEquivalence.equivalent(value, entryValue)) { cause = RemovalCause.EXPLICIT; } else if (entryValue == null && valueReference.isActive()) {
K entryKey = e.getKey(); if (e.getHash() == hash && entryKey != null && map.keyEquivalence.equivalent(key, entryKey)) { ValueReference<K, V> valueReference = e.getValueReference(); V entryValue = valueReference.get();
K entryKey = e.getKey(); if (e.getHash() == hash && entryKey != null && map.keyEquivalence.equivalent(key, entryKey)) { ValueReference<K, V> valueReference = e.getValueReference(); V entryValue = valueReference.get(); if (map.valueEquivalence.equivalent(oldValue, entryValue)) { ++modCount; enqueueNotification(key, hash, valueReference, RemovalCause.REPLACED);
K entryKey = e.getKey(); if (e.getHash() == hash && entryKey != null && map.keyEquivalence.equivalent(key, entryKey)) { valueReference = e.getValueReference(); if (valueReference.isLoading()) {
K entryKey = e.getKey(); if (e.getHash() == hash && entryKey != null && map.keyEquivalence.equivalent(key, entryKey)) {
K entryKey = e.getKey(); if (e.getHash() == hash && entryKey != null && map.keyEquivalence.equivalent(key, entryKey)) { ValueReference<K, V> valueReference = e.getValueReference(); V entryValue = valueReference.get();
K entryKey = e.getKey(); if (e.getHash() == hash && entryKey != null && map.keyEquivalence.equivalent(key, entryKey)) { ValueReference<K, V> valueReference = e.getValueReference(); V entryValue = valueReference.get();
K entryKey = e.getKey(); if (e.getHash() == hash && entryKey != null && map.keyEquivalence.equivalent(key, entryKey)) {