void runLockedCleanup(long now) { if (tryLock()) { try { drainReferenceQueues(); expireEntries(now); // calls drainRecencyQueue readCount.set(0); } finally { unlock(); } } }
count = 0; // write-volatile } finally { unlock(); postWriteCleanup();
/** * This method is a convenience for testing. Code should call {@link Segment#newEntry} directly. */ @VisibleForTesting ReferenceEntry<K, V> newEntry(K key, int hash, @Nullable ReferenceEntry<K, V> next) { Segment<K, V> segment = segmentFor(hash); segment.lock(); try { return segment.newEntry(key, hash, next); } finally { segment.unlock(); } }
/** * This method is a convenience for testing. Code should call {@link Segment#newEntry} directly. */ @VisibleForTesting ReferenceEntry<K, V> newEntry(K key, int hash, @NullableDecl ReferenceEntry<K, V> next) { Segment<K, V> segment = segmentFor(hash); segment.lock(); try { return segment.newEntry(key, hash, next); } finally { segment.unlock(); } }
unlock(); postWriteCleanup();
return loadingValueReference; } finally { unlock(); postWriteCleanup();
void runLockedCleanup(long now) { if (tryLock()) { try { drainReferenceQueues(); expireEntries(now); // calls drainRecencyQueue readCount.set(0); } finally { unlock(); } } }
/** Cleanup collected entries when the lock is available. */ void tryDrainReferenceQueues() { if (tryLock()) { try { drainReferenceQueues(); } finally { unlock(); } } }
/** Cleanup expired entries when the lock is available. */ void tryExpireEntries(long now) { if (tryLock()) { try { expireEntries(now); } finally { unlock(); // don't call postWriteCleanup as we're in a read } } }
unlock(); if (!isHeldByCurrentThread()) { // don't cleanup inside of put postWriteCleanup();
unlock(); postWriteCleanup();
unlock(); postWriteCleanup();
unlock(); postWriteCleanup();
/** * This method is a convenience for testing. Code should call {@link Segment#newEntry} directly. */ @VisibleForTesting ReferenceEntry<K, V> newEntry(K key, int hash, @NullableDecl ReferenceEntry<K, V> next) { Segment<K, V> segment = segmentFor(hash); segment.lock(); try { return segment.newEntry(key, hash, next); } finally { segment.unlock(); } }
boolean removeLoadingValue(K key, int hash, 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(); } }
static void drainRecencyQueue(Segment<?, ?> segment) { segment.lock(); try { segment.cleanUp(); } finally { segment.unlock(); } }
/** Cleanup expired entries when the lock is available. */ void tryExpireEntries(long now) { if (tryLock()) { try { expireEntries(now); } finally { unlock(); // don't call postWriteCleanup as we're in a read } } }
static void expireEntries(Segment<?, ?> segment, long now) { segment.lock(); try { segment.expireEntries(now); segment.cleanUp(); } finally { segment.unlock(); } }
static void drainReferenceQueue(LocalCache.Segment<?, ?> segment) { segment.lock(); try { segment.drainReferenceQueues(); } finally { segment.unlock(); } }
/** Cleanup collected entries when the lock is available. */ void tryDrainReferenceQueues() { if (tryLock()) { try { drainReferenceQueues(); } finally { unlock(); } } }