eviction-recency

Least-recently-used cache eviction

LeastRecentlyUsed is an EvictionStrategy that, while its capacity is exceeded, removes the key whose last read or insert is oldest.

Rationale

Why. Keys used a moment ago tend to be used again soon.

Key Concepts

Recency

Role. Each Insert and Hit makes its key the most recent. A Miss changes nothing.

Pattern. STRATEGY, OBSERVER

How It Works

Guarantees. No public parameter takes null and no public method returns it, declared with contrax's @PreCondition(IsNotNull.class) and @PostCondition(IsNotNull.class).

Thread safety. An instance is not thread-safe: events must reach update one at a time.

Lane

Purpose. Eviction for workloads where recent use predicts the next.

Alternative. eviction-frequency when long-run popularity predicts better; eviction-insertion-order when reads must not change the order.

When to avoid. A scan over more keys than the capacity holds: each one pushes out a key that may be asked for next.

Usage

Room for two: reading a again keeps it, so b leaves

import java.time.Instant;
import java.util.Map;
import java.util.Optional;
import java.util.function.Supplier;
import java.util.stream.Stream;
import software.visionary.cache.Cache;
import software.visionary.cache.capacity.fixed.FixedSize;
import software.visionary.cache.events.CacheEvent;
import software.visionary.cache.events.Evict;
import software.visionary.cache.eviction.recency.LeastRecentlyUsed;
import software.visionary.cache.policy.CachePolicy;
import software.visionary.cache.topology.read.through.ReadThroughCacheFactory;
import software.visionary.events.Observer;

Map<String, Integer> source = Map.of("a", 1, "b", 2, "c", 3);
Supplier<Cache<String, Integer>> caches = new ReadThroughCacheFactory<>(
        key -> Optional.ofNullable(source.get(key)),
        new CachePolicy<>(() -> new FixedSize<>(2), LeastRecentlyUsed::new, Instant::now));
Observer<CacheEvent<String, ?>> printEvictions = event -> {
    if (event instanceof Evict<String, ?> evicted) { System.out.println("evicted " + evicted.key()); }
};

var cache = caches.get();
cache.add(printEvictions);
Stream.of("a", "b", "a", "c").forEach(cache::apply);

Output

evicted b

Dependencies

  • software.visionary:cache:2026.10.13 at Compile
  • software.visionary.contrax:processor:2026.10.13 at Processor
  • software.visionary:junit-closure:2026.09.17 at Testing

Views

Drawn from the release. A link in a view opens its source at the release tag.

architecture.svg
architecture.svg
classes.software.visionary.cache.eviction.recency.svg
classes.software.visionary.cache.eviction.recency.svg
packages.svg
packages.svg