rls: Refactor estimatedSizeBytes updates (#12145)

Just use a regular method instead of reusing the EvictionListener API.
Fix a few comments as well. Both of these changes were based on review
comments to pre-existing code in #11203.

Contributes to #11243
This commit is contained in:
Eric Anderson 2025-06-12 04:01:19 +00:00 committed by GitHub
parent 30f6a4db77
commit 13fe008044
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 14 additions and 25 deletions

View File

@ -43,7 +43,8 @@ abstract class LinkedHashLruCache<K, V> implements LruCache<K, V> {
private final LinkedHashMap<K, SizedValue> delegate;
private final Ticker ticker;
private final EvictionListener<K, SizedValue> evictionListener;
@Nullable
private final EvictionListener<K, V> evictionListener;
private long estimatedSizeBytes;
private long estimatedMaxSizeBytes;
@ -53,7 +54,7 @@ abstract class LinkedHashLruCache<K, V> implements LruCache<K, V> {
final Ticker ticker) {
checkState(estimatedMaxSizeBytes > 0, "max estimated cache size should be positive");
this.estimatedMaxSizeBytes = estimatedMaxSizeBytes;
this.evictionListener = new SizeHandlingEvictionListener(evictionListener);
this.evictionListener = evictionListener;
this.ticker = checkNotNull(ticker, "ticker");
delegate = new LinkedHashMap<K, SizedValue>(
// rough estimate or minimum hashmap default
@ -135,7 +136,7 @@ abstract class LinkedHashLruCache<K, V> implements LruCache<K, V> {
estimatedSizeBytes += size;
existing = delegate.put(key, new SizedValue(size, value));
if (existing != null) {
evictionListener.onEviction(key, existing, EvictionType.REPLACED);
fireOnEviction(key, existing, EvictionType.REPLACED);
}
return existing == null ? null : existing.value;
}
@ -174,7 +175,7 @@ abstract class LinkedHashLruCache<K, V> implements LruCache<K, V> {
checkNotNull(cause, "cause");
SizedValue existing = delegate.remove(key);
if (existing != null) {
evictionListener.onEviction(key, existing, cause);
fireOnEviction(key, existing, cause);
}
return existing == null ? null : existing.value;
}
@ -185,7 +186,7 @@ abstract class LinkedHashLruCache<K, V> implements LruCache<K, V> {
while (iterator.hasNext()) {
Map.Entry<K, SizedValue> entry = iterator.next();
if (entry.getValue() != null) {
evictionListener.onEviction(entry.getKey(), entry.getValue(), EvictionType.EXPLICIT);
fireOnEviction(entry.getKey(), entry.getValue(), EvictionType.EXPLICIT);
}
iterator.remove();
}
@ -215,14 +216,13 @@ abstract class LinkedHashLruCache<K, V> implements LruCache<K, V> {
protected final boolean fitToLimit() {
boolean removedAnyUnexpired = false;
if (estimatedSizeBytes <= estimatedMaxSizeBytes) {
// new size is larger no need to do cleanup
return false;
}
// cleanup expired entries
long now = ticker.read();
cleanupExpiredEntries(now);
// cleanup eldest entry until new size limit
// cleanup eldest entry until the size of all entries fits within the limit
Iterator<Map.Entry<K, SizedValue>> lruIter = delegate.entrySet().iterator();
while (lruIter.hasNext() && estimatedMaxSizeBytes < this.estimatedSizeBytes) {
Map.Entry<K, SizedValue> entry = lruIter.next();
@ -230,8 +230,8 @@ abstract class LinkedHashLruCache<K, V> implements LruCache<K, V> {
break; // Violates some constraint like minimum age so stop our cleanup
}
lruIter.remove();
// eviction listener will update the estimatedSizeBytes
evictionListener.onEviction(entry.getKey(), entry.getValue(), EvictionType.SIZE);
// fireOnEviction will update the estimatedSizeBytes
fireOnEviction(entry.getKey(), entry.getValue(), EvictionType.SIZE);
removedAnyUnexpired = true;
}
return removedAnyUnexpired;
@ -270,7 +270,7 @@ abstract class LinkedHashLruCache<K, V> implements LruCache<K, V> {
Map.Entry<K, SizedValue> entry = lruIter.next();
if (isExpired(entry.getKey(), entry.getValue().value, now)) {
lruIter.remove();
evictionListener.onEviction(entry.getKey(), entry.getValue(), EvictionType.EXPIRED);
fireOnEviction(entry.getKey(), entry.getValue(), EvictionType.EXPIRED);
removedAny = true;
maxExpiredEntries--;
}
@ -283,21 +283,10 @@ abstract class LinkedHashLruCache<K, V> implements LruCache<K, V> {
invalidateAll();
}
/** A {@link EvictionListener} keeps track of size. */
private final class SizeHandlingEvictionListener implements EvictionListener<K, SizedValue> {
private final EvictionListener<K, V> delegate;
SizeHandlingEvictionListener(@Nullable EvictionListener<K, V> delegate) {
this.delegate = delegate;
}
@Override
public void onEviction(K key, SizedValue value, EvictionType cause) {
estimatedSizeBytes -= value.size;
if (delegate != null) {
delegate.onEviction(key, value.value, cause);
}
private void fireOnEviction(K key, SizedValue value, EvictionType cause) {
estimatedSizeBytes -= value.size;
if (evictionListener != null) {
evictionListener.onEviction(key, value.value, cause);
}
}