英文:
Caffeine cache - multiple expire configurations
问题
过期时间可以通过多种方式进行配置:
- expireAfterWrite(写入后过期)
- expireAfterAccess(访问后过期)
- expireAfter(过期后)
虽然这3种方法看起来都很有帮助,但在内部它们配置了不同的缓存变量。
我的问题是:为什么要为过期配置设置专门的变量?乍一看,expireAfterWrite
和 expireAfterAccess
可以通过重用 expireAfter(Expiry)
并传递某个特定的 Expiry 对象来实现。
英文:
Expiration can be configured in multiple ways:
- expireAfterWrite
- expireAfterAccess
- expireAfter(Expiry)
While all 3 methods look helpful, internally they configure different cache variables.
My question is: what is the purpose to have dedicated variables for expiration configuration. At first glance, expireAfterWrite
and expireAfterAccess
could be implemented reusing expireAfter(Expiry)
passing a certain Expiry object.
答案1
得分: 2
这是因为变量过期时间 expireAfter
是在版本 2.5.0 中引入的。如果这个特性首先出现,其他部分会重用它,就像你提到的那样。然而,迁移的收益似乎不大,因此它们保持为独立的实现。懒惰可能是最好的答案。
变量引入较晚的原因是因为 Caffeine 仅使用摊还O(1)算法。当时的其他缓存实现使用O(lg n)优先级队列(堆、红黑树、eb树、跳表或基数树)来实现变量过期,或者强制设置最大大小并让无效条目保留直至大小被逐出。在这些方法中,缓存操作随着其增长而变慢,或者污染会降低命中率。
据我所知,Caffeine 是第一个使用分层时间轮的缓存。该算法通过使用哈希而不是比较进行排序,达到了O(1)的复杂度。该实现使用位操作来提高效率,例如移位和掩码,而不是除法和取模。这个结果是一种非常快速且可扩展的方法,与固定过期算法(简单的LRU风格列表)相当。详情在这篇文章中有概述。
英文:
This is because variable expiration, expireAfter
, was introduced later in version 2.5.0. If that feature had come first then the others would have reused it, as you mentioned. There doesn't seem to be much to gain by migrating over, though, so its left as independent implementations. Laziness is probably the best answer.
The reason variable came late is because Caffeine uses only amortized O(1) algorithms. Other caches at the time implemented variable expiration using either a O(lg n) priority queues (heap, redblack, ebtree, skiplist, or radix tree), or forced a maximum size and let the dead entry linger until size evicted. In those approaches, either cache operations slow as it grows or the pollution would degrade the hit rate.
To my knowledge, Caffeine was the first cache to utilize a hierarchical timing wheel instead. This is algorithm is O(1) by using hashing rather than comparison to sort with. The implementation uses bitwise operations for added efficiency, e.g. shift and masks versus division and modulus. This result is a very fast and scalable approach and comparable to the fixed expiration's algorithm (a simple LRU style list). The details are summarized in this article.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论