繁体   English   中英

从头开始具有双链表的LRU缓存-moveToHead(Java)

[英]LRU cache with Doubly Linked List from scratch - moveToHead (Java)

我已经实现了一个简单的LRU缓存作为从头开始手动编写的双链表。 缓存中填充了以数字(整数)ID区分的对象请求。 对于一组N <L个预定义请求对象,这些请求对象作为L个随机独立且相同分布的请求的流生成,并一个接一个地到达缓存(即以串行方式)。 然后,我检查高速缓存是否命中或未命中,以及当前高速缓存大小是否已达到最大高速缓存大小,然后根据情况,将请求的项插入高速缓存或从请求的项中替换LRU高速缓存的项。

缓存的操作之一如下:当我遇到缓存命中时,如果所请求的项目不在头部,则必须将其移到那里。

例如,假设高速缓存的最大大小为M = 4,并且在给定时间的内容如下:

项目:7 | 3 | 4 |

缓存位置索引:0 | 1 | 2 | 3(0是头,3是尾)

现在,例如,如果我们有一项针对项目4的缓存命中,则由于该项目不在缓存的开头,因此应将其移到那里,结果将是:

项目:4 | 7 | 3 |

缓存位置索引:0 | 1 | 2 | 3(0是头,3是尾)

但是,当我运行代码时,结果是这样的:

项目:4 | 7 | 3 | 4 |

缓存位置索引:0 | 1 | 2 | 3 | 4(0是头,4是尾)

换句话说,相关项(在此示例中为项4)不会从高速缓存中删除,而是添加到磁头中,而只是添加到磁头中。 因此,缓存大小增加了1(在此示例中,它变为5,大于最大缓存大小M = 4)。

这是相关的代码,以及说明我认为问题本质的注释:

public void moveToHead(Request request) {

        if(request != head) {

            // set previous node equal to the requested item
            request.left = request;

            // --> if I set here request = null; then I will move to the head a null object!!! What to do? <--

            // move requested item to head
            head.left = request;
            request.right = head;
            head = request;

        }

    }

正如我声明的那样,如果在代码的第一行之后将对象请求设置为null以便将其删除,则接下来的代码行将移至开头为null对象。 如何解决呢? 我假设我必须在下面的代码中使用一个临时的Request变量,但是我还没有弄清楚该怎么做。

为此,变量head由一个哑元初始化:

head = new Request();
head.left = head;
head.right = head,

对于缓存命中,请首先从列表中删除条目:

request.left.right = request.right;
request.right.left = request.left,

然后将其添加到列表头:

request.left = head;
request.right = head.right;
request.right.left = request;
head.right = request;

也许在这里看到一些真实的实现: https : //github.com/headissue/cache2k/blob/master/core/src/main/java/org/cache2k/impl/LruCache.java

祝好运!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM