Add remove, computeIfAbsent and keys() - #1
Merged
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds three methods to
LruCache:V remove(K key)removes an entry and returns its live value (nullif absent/expired).V computeIfAbsent(K key, Function loader)(plus an overload with an explicitttlMillis) returns the cached value or computes, stores and returns it.List<K> keys()returns a snapshot of the live keys, least- to most-recently-used (eviction order).Why
The cache offered no way to invalidate a single key, so callers had to
clear()everything or wait for TTL. The "get, check for null, load, put" pattern was left to every caller, and done naively from several threads it loads the same value repeatedly (a thundering herd on a cold key).computeIfAbsentruns under the existing lock, so concurrent callers for one key trigger exactly one load.keys()gives a debugging/inspection view without perturbing recency.Behaviour
removeis not a lookup: hit/miss statistics are untouched.computeIfAbsentcounts as exactly one hit or one miss. Anullloader result stores nothing; a thrown exception propagates and stores nothing; an expired entry is treated as a miss. Documented caveat: the loader runs under the lock, so it must not call back into the cache.keys()does not refresh recency (it iterates the entry set, which is not an access in access-orderedLinkedHashMap) and skips expired entries.CHANGELOG.md(1.3.0) and the README API table are updated.Testing
Compiled with
javac -Xlint:all(no warnings) andLruCacheTestpasses, with 23 new checks covering: remove return values, expired/absent, size and freed-slot reuse, and no stat impact; computeIfAbsent hit/miss accounting, null result, exception, both TTL overloads, and null-loader rejection; a contention test where 8 threads race for one key and the loader runs exactly once; andkeys()ordering, being a detached copy, not changing which entry gets evicted, and skipping expired entries.🤖 Generated with Claude Code