Skip to content

ConcurrentLru: Time‐based eviction

Alex Peck edited this page May 15, 2024 · 11 revisions

ConcurrentLru optionally supports 3 modes of time-based eviction:

  • Expire after access: evict after a fixed duration since an entry's most recent read or write.
ICache<string, int> expireAfter = new ConcurrentLruBuilder<string, int>()
   .WithExpireAfterAccess(TimeSpan.FromSeconds(10))
   .Build();
  • Expire after write: evict after a fixed duration since an entry's creation or most recent replacement. This is the policy used in ConcurrentTLru.
ICache<string, int> expireAfter = new ConcurrentLruBuilder<string, int>()
   .WithExpireAfterWrite(TimeSpan.FromSeconds(10))
   .Build();
  • Expire after: evict after a duration calculated for each item using the specified IExpiryCalculator.
public class Expiry : IExpiryCalculator<string, int>
{
    public Duration GetExpireAfterCreate(string key, int value) => Duration.FromSeconds(value);
    public Duration GetExpireAfterRead(string key, int value, Duration current) => current;
    public Duration GetExpireAfterUpdate(string key, int value, Duration current) => k.StartsWith('a') ? current : Duration.FromSeconds(value);
}

ICache<string, int> expireAfter = new ConcurrentLruBuilder<string, int>()
   .WithExpireAfter(new Expiry())
   .Build();

Time-based expiry policies are mutually exclusive: attempting to combine them will cause the Build() method to throw an exception at runtime.

Expiration is performed as part of the queue cycling logic whenever a new value is added to the cache. If the turnover of items is low, or there is little cache activity items will remain in the cache.

Expired items can also be removed by calling the TrimExpired method of the appropriate cache policy. This can be done in the background if eager expiry is required. Trim and TrimExpired are both O(n) operations when a time-based eviction policy is used, where n is the number of items in the cache.

cache.Policy.ExpireAfter.Value.TrimExpired();