/** Records that the current thread is about to wait on the specified guard. */ @GuardedBy("lock") private void beginWaitingFor(Guard guard) { int waiters = guard.waiterCount++; if (waiters == 0) { // push guard onto activeGuards guard.next = activeGuards; activeGuards = guard; } }
/** Drains the reference queues used by this segment, if any. */ @GuardedBy("this") void maybeDrainReferenceQueues() {}
/** Records that the current thread is no longer waiting on the specified guard. */ @GuardedBy("lock") private void endWaitingFor(Guard guard) { int waiters = --guard.waiterCount; if (waiters == 0) { // unlink guard from activeGuards for (Guard p = activeGuards, pred = null; ; pred = p, p = p.next) { if (p == guard) { if (pred == null) { activeGuards = p.next; } else { pred.next = p.next; } p.next = null; // help GC break; } } } }
/** Records that the current thread is about to wait on the specified guard. */ @GuardedBy("lock") private void beginWaitingFor(Guard guard) { int waiters = guard.waiterCount++; if (waiters == 0) { // push guard onto activeGuards guard.next = activeGuards; activeGuards = guard; } }
/** Signals all threads waiting on guards. */ @GuardedBy("lock") private void signalAllWaiters() { for (Guard guard = activeGuards; guard != null; guard = guard.next) { guard.condition.signalAll(); } }
/** Signals all threads waiting on guards. */ @GuardedBy("lock") private void signalAllWaiters() { for (Guard guard = activeGuards; guard != null; guard = guard.next) { guard.condition.signalAll(); } }
/** * Drains the recency queue, updating eviction metadata that the entries therein were read in * the specified relative order. This currently amounts to adding them to relevant eviction * lists (accounting for the fact that they could have been removed from the map since being * added to the recency queue). */ @GuardedBy("this") void drainRecencyQueue() { ReferenceEntry<K, V> e; while ((e = recencyQueue.poll()) != null) { // An entry may be in the recency queue despite it being removed from // the map . This can occur when the entry was concurrently read while a // writer is removing it from the segment or after a clear has removed // all of the segment's entries. if (accessQueue.contains(e)) { accessQueue.add(e); } } }
/** * Performs routine cleanup prior to executing a write. This should be called every time a write * thread acquires the segment lock, immediately after acquiring the lock. * * <p>Post-condition: expireEntries has been run. */ @GuardedBy("this") void preWriteCleanup(long now) { runLockedCleanup(now); }
/** * Performs routine cleanup prior to executing a write. This should be called every time a write * thread acquires the segment lock, immediately after acquiring the lock. */ @GuardedBy("this") void preWriteCleanup() { runLockedCleanup(); }
@GuardedBy("this") void drainValueReferenceQueue() { Reference<? extends V> ref; int i = 0; while ((ref = valueReferenceQueue.poll()) != null) { @SuppressWarnings("unchecked") ValueReference<K, V> valueReference = (ValueReference<K, V>) ref; map.reclaimValue(valueReference); if (++i == DRAIN_MAX) { break; } } }
@GuardedBy("this") void drainKeyReferenceQueue(ReferenceQueue<K> keyReferenceQueue) { Reference<? extends K> ref; int i = 0; while ((ref = keyReferenceQueue.poll()) != null) { @SuppressWarnings("unchecked") E entry = (E) ref; map.reclaimKey(entry); if (++i == DRAIN_MAX) { break; } } }
@GuardedBy("this") void drainKeyReferenceQueue() { Reference<? extends K> ref; int i = 0; while ((ref = keyReferenceQueue.poll()) != null) { @SuppressWarnings("unchecked") ReferenceEntry<K, V> entry = (ReferenceEntry<K, V>) ref; map.reclaimKey(entry); if (++i == DRAIN_MAX) { break; } } }
@GuardedBy("this") void drainValueReferenceQueue(ReferenceQueue<V> valueReferenceQueue) { Reference<? extends V> ref; int i = 0; while ((ref = valueReferenceQueue.poll()) != null) { @SuppressWarnings("unchecked") WeakValueReference<K, V, E> valueReference = (WeakValueReference<K, V, E>) ref; map.reclaimValue(valueReference); if (++i == DRAIN_MAX) { break; } } }
/** * Performs routine cleanup prior to executing a write. This should be called every time a write * thread acquires the segment lock, immediately after acquiring the lock. * * <p>Post-condition: expireEntries has been run. */ @GuardedBy("this") void preWriteCleanup(long now) { runLockedCleanup(now); }
@GuardedBy("this") ReferenceEntry<K, V> getNextEvictable() { for (ReferenceEntry<K, V> e : accessQueue) { int weight = e.getValueReference().getWeight(); if (weight > 0) { return e; } } throw new AssertionError(); }
@GuardedBy("this") ReferenceEntry<K, V> newEntry(K key, int hash, @Nullable ReferenceEntry<K, V> next) { return map.entryFactory.newEntry(this, checkNotNull(key), hash, next); }
/** Checks that the current state is equal to the expected state. */ @GuardedBy("monitor") private void checkCurrentState(State expected) { State actual = state(); if (actual != expected) { if (actual == FAILED) { // Handle this specially so that we can include the failureCause, if there is one. throw new IllegalStateException( "Expected the service " + this + " to be " + expected + ", but the service has FAILED", failureCause()); } throw new IllegalStateException( "Expected the service " + this + " to be " + expected + ", but was " + actual); } }
/** * Updates the eviction metadata that {@code entry} was just read. This currently amounts to * adding {@code entry} to relevant eviction lists. * * <p>Note: this method should only be called under lock, as it directly manipulates the * eviction queues. Unlocked reads should use {@link #recordRead}. */ @GuardedBy("this") void recordLockedRead(ReferenceEntry<K, V> entry, long now) { if (map.recordsAccess()) { entry.setAccessTime(now); } accessQueue.add(entry); }
@Override @GuardedBy("ServiceManagerState.this.monitor") public boolean isSatisfied() { return states.count(TERMINATED) + states.count(FAILED) == numberOfServices; } }
/** * Exactly like guard.isSatisfied(), but in addition signals all waiting threads in the (hopefully * unlikely) event that isSatisfied() throws. */ @GuardedBy("lock") private boolean isSatisfied(Guard guard) { try { return guard.isSatisfied(); } catch (Throwable throwable) { signalAllWaiters(); throw throwable; } }