[英]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.