@Nonnull ReferenceEntry<K, V> getNextEvictable() { for (ReferenceEntry<K, V> e : accessQueue) { int weight = e.getValueReference().getWeight(); if (weight > 0) { return e; } } throw new AssertionError(); }
void enqueueNotification(K key, int hash, @Nonnull ValueReference<K, V> valueReference, RemovalCause cause) { totalWeight -= valueReference.getWeight(); if (map.removalNotificationQueue != DISCARDING_QUEUE) { V value = valueReference.get(); RemovalNotification<K, V> notification = RemovalNotification.create(key, value, cause); map.removalNotificationQueue.offer(notification); } }
/** * Performs eviction if the segment is over capacity. Avoids flushing the entire cache if the * newest entry exceeds the maximum weight all on its own. * * @param newest the most recently added entry */ void evictEntries(@Nonnull ReferenceEntry<K, V> newest) { if (!map.evictsBySize()) { return; } drainRecencyQueue(); // If the newest entry by itself is too heavy for the segment, don't bother evicting // anything else, just that if (newest.getValueReference().getWeight() > maxSegmentWeight) { if (!removeEntry(newest, newest.getHash(), RemovalCause.SIZE)) { throw new AssertionError(); } } while (totalWeight > maxSegmentWeight) { ReferenceEntry<K, V> e = getNextEvictable(); if (!removeEntry(e, e.getHash(), RemovalCause.SIZE)) { throw new AssertionError(); } } }
@Override public int getWeight() { return oldValue.getWeight(); }