Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is Cache.asMap() not consistent with Cache.size()?

In the Guava Library, I am confused about why Cache.asMap() is not consistent with Cache.size(), unless Cache.cleanUp() is called.

Cache<Object, Object> cache = CacheBuilder.newBuilder()
           .expireAfterWrite(1, TimeUnit.SECONDS)
           .build();
cache.get(...);
...
//After some seconds, all entries are expired.
//cache.asMap() is EMPTY Map, but cache.size() != 0

So my question: Is it bug that Cache.asMap() is not consistent to Cache.size()? Although I notice the javadoc of Cache.size() is:

  /**
   * Returns the **approximate** number of entries in this cache.
   */

I can just guess it's related to a concurrent environment. And what does Cache.cleanUp() do exactly?

like image 461
卢声远 Shengyuan Lu Avatar asked May 04 '12 04:05

卢声远 Shengyuan Lu


1 Answers

Guava's cache is designed around lock amortization and the cleanUp method forces the cache to arrive at a consistent state. The Map.size() method is an approximation, but may count entries pending removal due to expiration or reference eviction. The visibility of the approximations in Guava's cache are rarely of much interest to an application, which tends to think of a cache as a transient data store. The different expectations of a cache from a Map led to the asMap method to allow the cache to be viewed as a map, but disfavor developers perceiving it that way.

The implementation details of the cache was covered in the StrangleLoop 2011 conference slides. The design document of ConcurrentLinkedHashMap, which Guava's cache was derived from, may also be of interest but describes a slightly different approach.

like image 186
Ben Manes Avatar answered Sep 20 '22 23:09

Ben Manes