是否计划了有关最大规模驱逐的其他替代策略?我需要一个MRU算法,以便系统从缓存中受益。系统将记录存储在磁盘上或内存中缓存页面中的块中,而页面/记录不是聚类的(更新后可能不会预先存储)。我的案例中的记录是树结构中的节点。
系统按升序分配记录ID(即最初它们是预先订购的),并且还将记录存储在具有递增ID(0,1,2 ......)的页面中。然而,在更新之后,如果需要以预先的顺序遍历记录/节点,则可能是读取具有记录1,2,3,4,5,6,7,8,9,10的页面......但是已在节点6和7之间插入节点(例如,具有大子树的节点11)。在这种情况下,缓存仅在保留第一页(存储记录1,2 ...,10,如果缓存大小为1,根节点11的子树属于另一页)时才有用。然后第一页必须是取样两次。与其他树遍历方法类似,MRU比LRU更有用,但也许存在其他可能更适合的聪明算法。可能是自我调整的一个方面。
很抱歉我的用例(版本化数据存储系统)有很长的描述,但我希望它是一个有效的用例。因此,如果基于大小的驱逐是可配置的将是很好的,因为在某些情况下LRU可能也完全有意义(但可能不适用于树遍历)。
编辑:我可能甚至不需要并发支持,只要我一次只允许一个写事务(因为Guava将条目分成不同的段,因此它不使用全局LRU算法)。
答案 0 :(得分:3)
设计理念是不对基于大小的驱逐策略决定逐出哪个元素的算法行为做出保证。这提供了灵活性,可以演变为更高级的驱逐策略,例如LIRS,并改进缓存的设计,例如:不被分割。合同是缓存将尝试智能地选择满足大多数用例的受害者。
目前的实现已经过于复杂了,imho,我不赞成提供许多调整算法的切换器。这将使api对一小部分用户造成混淆,限制了设计改进的能力,并将复杂性提高到超出可容忍的水平。当Guava的通才方法不合适时,最好能够推出最适合您问题的解决方案。
正确答案取决于您的使用案例。如果您不需要高并发性,那么有许多明显的答案。但是,如果你这样做,那么分支ConcurrentLinkedHashMap使用MRU政策可能是最不痛苦的。自定义实现的中间立场,例如也许使用缓冲策略的简化版本,可能是最容易封装在大型代码库中的。