Why is Cache.asMap() not consistent with Cache.siz

2019-04-25 07:20发布

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?

2条回答
一纸荒年 Trace。
2楼-- · 2019-04-25 08:07

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.

查看更多
神经病院院长
3楼-- · 2019-04-25 08:09

Ben gave a good high-level response. The low-level response is:

asMap() views have the luxury of traversing each element in the cache, and thus can skip invalid entries which are pending cleanup. On the other hand, size() is expected to be a quick operation, and it would be silly to traverse the entire cache just to get a more accurate size estimate.

The CacheBuilder javadocs go into more detail regarding the cleanup that needs to happen in various situations (such as expireAfterWrite, in your case).

查看更多
登录 后发表回答