2013-05-03 69 views
2

是否计划了有关最大规模逐出的其他替换策略?我需要一个MRU算法,以便系统从缓存中受益。系统将数据以块的形式存储在磁盘上或缓存页面的内存中,而页面/记录未被聚集(可能不会在更新后以预先存储的形式存储)。在我的情况下,记录是树状结构中的节点。番石榴缓存/可配置逐出/缓存替换策略

系统按升序分配记录标识(即首先它们处于预订状态),并将记录存储在带有递增ID(0,1,2 ...)的页面中。然而,在更新之后,如果例如记录/节点需要以预先遍历的方式进行遍历,那么可能是页面被记录1,2,3,4,5,6,7,8,9,10 ...读取,但是已经在节点6和7之间插入节点(例如具有大子树的节点11)。在这种情况下,缓存仅在保留第一页(其中存储记录1,2 ...,如果缓存大小为1且以节点11为根的子树属于另一页时为10)时有用,则第一页必须是取而代之,其他树遍历方法的情况也是如此,MRU比LRU更有用,但也许存在其他更适合的聪明算法,可能是自调整的一个方面。对于我的用例(一个版本化的数据存储系统)的长篇描述,但我希望它是一个有效的用例。因此,如果基于大小的驱逐是可配置的,在某些情况下,LRU完全有意义但可能不适用于树遍历)

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

回答

3

设计理念是不对基于大小的驱逐策略决定驱逐哪个元素的算法行为做出保证。这提供了灵活性以演变为更高级的驱逐策略,例如LIRS,并且改进了高速缓存的设计,例如,不被分割。合同是缓存将尝试智能地选择一个满足大部分用例的受害者。

目前的实现已经过于复杂了,我不会赞成提供大量的调整算法的切换。这会让api让一小部分用户感到困惑,限制改进设计的能力,并增加超出可接受水平的复杂性。当番石榴的多面手方法不合适时,它最好推出自己最能解决问题的解决方案。

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

+0

我目前还不确定它是否是个好主意。也可能是按顺序读取第1,2,3和4页(而高速缓存/缓冲区的最大大小为3)。然后提取页面4会清除页面3,但可能需要再次读取,因为子树已经插入到页面3上的节点之间(并且子树位于页面4)。因此,前序遍历必须读取1,2,3和4,然后再读取3,因此LRU会更好;-)我猜这是一种两难的困境。对这样的节点进行聚类将是最好的,但是对于恰好一种访问模式(前,后,级,顺序等)来说也是如此。 – Johannes 2013-05-03 13:17:45

+0

这听起来像你想要像LIRS扫描居民政策。 – 2013-05-03 16:32:43

+0

谢谢,那么我会坚持使用Guava Caches,因为我正在广泛使用这个库。希望LIRS将在未来实施:-)或者......我认为(当然,现在知道;-))Charles Fry已经实施了LirsMap。 – Johannes 2013-05-03 17:16:45