The previous shot covered the insert, retrieve, and refresh operations on the cache. In this shot, we will learn about listeners, eviction, and statistics in Guava Cache.
Caches are limited by the ram size. Therefore, existing keys have to be removed to make space for the new keys to be inserted. This is called cache eviction.
There are different cache eviction strategies.
The time-based eviction strategy refers to the expiration of keys based on the duration of time passed since insertion or the last access of the key in the cache.
Method | Description |
---|---|
CacheBuilder.expireAfterAccess(long, TimeUnit) |
Evict the entry after the specified amount of time has passed since the last access of the entry. |
CacheBuilder.expireAfterWrite(long, TimeUnit) |
Evict the entry after the specified amount of time has passed since the entry was created or updated. |
TimeUnit
in Java provides time durations at a given unit of granularity.
The size of the cache can be restricted with CacheBuilder.maximumSize()
. If the cache size reaches the limit, the oldest items will be evicted. This is called size-based eviction.
LoadingCache<String, Integer> cache = CacheBuilder.newBuilder()
.maximumSize(1000)
.build(new CacheLoader<String, Integer>() {
@Override
public Integer load(String key) {
return key.length();
}
});
In the code above, a cache with maximum size as 1000
is constructed.
In some cases, keys in a cache have to be removed explicitly. Explicit eviction of keys can be done through the following methods.
Method | Description |
---|---|
cache.invalidateAll(); |
Evict all the entries in the cache. |
cache.invalidateAll(Iterable); |
Evict the list of keys in the cache. |
cache.invalidate(Key); |
Evict the given entry in the cache. |
Guava Cache provides flexibility to add removal listeners to take action on eviction of keys from the cache.
In the below code, notification.getCause()
returns the reason due to which the entry in the cache was evicted. There are five reasons for an entry to be removed. They are as follows:
The code below shows how to register a removal listener that prints out the key and the reason why it was removed.
LoadingCache<String, Integer> cache = CacheBuilder.newBuilder().removalListener(new RemovalListener<String, Integer>() {@Overridepublic void onRemoval(RemovalNotification<String, Integer> notification) {System.out.println("Key - " + notification.getKey() + " removed due to " + notification.getCause());}}).build(new CacheLoader<String, Integer>() {@Overridepublic Integer load(String key) {return key.length();}})
We can use CacheBuilder.recordStats()
during the cache construction to enable tracking statistics for a given cache.
Some of the statistics tracked are as follows:
Method | Description |
---|---|
hitCount() |
Returns the number of times Cache lookup was successful. |
missCount() |
Returns the number of times Cache lookup failed. |
evictionCount() |
Returns the number of times entries were evicted. |
Refer to CacheStats for different statistics provided.
The code below shows how to enable statistics on a cache and how to access the different counters available.
LoadingCache<String, Integer> cache = CacheBuilder.newBuilder().recordStats().build(new CacheLoader<String, Integer>() {@Overridepublic Integer load(String key) {return key.length();}});cache.get("hello");cache.put("hi", 2);System.out.println(cache.get("hello"));System.out.println(cache.get("jinfs"));System.out.println("cache hit rate - " + cache.stats().hitRate());System.out.println("cache miss rate - " + cache.stats().missRate());