2

是否计划了有关最大尺寸驱逐的其他替代策略?我需要一个 MRU 算法,这样系统才能从缓存中受益。系统将记录存储在磁盘上的块中或内存中的缓存页面中,而页面/记录不是集群的(更新后可能不会按预先顺序存储)。在我的例子中,记录是树结构中的节点。

系统按升序分配记录 ID(即首先它们是预排序的),并将记录存储在具有递增 ID(0、1、2...)的页面中。然而,在更新之后,如果需要按顺序遍历记录/节点,则可能会读取带有记录 1、2、3、4、5、6、7、8、9、10 的页面......但是在节点 6 和 7 之间插入了节点(例如,节点 11 具有大子树)。在这种情况下,缓存仅在保留第一页(如果缓存大小为 1 并且以节点 11 为根的子树属于另一页的情况下存储记录 1,2...,10)时才有用。那么第一页必须是提取两次。对于其他树遍历方法也是如此,MRU 比 LRU 更有用,但也许存在其他更适合的聪明算法。

很抱歉对我的用例(版本化数据存储系统)进行了冗长的描述,但我希望这是一个有效的用例。因此,如果基于大小的驱逐是可配置的,那就太好了,因为在某些情况下,LRU 也可能完全有意义(但可能不适用于树遍历)。

编辑:我可能什至不需要并发支持,只要我一次只允许一个写事务(因为 Guava 将条目分成不同的段,因此它不使用全局 LRU 算法)。

4

1 回答 1

3

设计理念是不保证基于大小的驱逐策略决定驱逐哪个元素的算法行为。这为进化到更高级的驱逐策略(例如LIRS )提供了灵活性,并改进了缓存的设计,例如不分段。约定是缓存将尝试智能地选择满足大多数用例的受害者。

当前的实现已经过于复杂,恕我直言,我不赞成提供许多调整算法的切换。这会使 api 对一小部分用户感到困惑,限制进行设计改进的能力,并将复杂性增加到超出可容忍的水平。当 Guava 的通才方法不适合时,最好推出最适合您的问题的自己的解决方案。

正确的答案取决于您的用例。如果您不需要高并发,那么有很多明显的答案。但是,如果你这样做了,那么将ConcurrentLinkedHashMap分叉以使用 MRU 策略可能是最不痛苦的。自定义实现的中间立场,例如可能使用缓冲策略的简化版本,可能是最容易封装在大型代码库中的。

于 2013-05-03T10:30:46.370 回答