【问题标题】:LRU cache with Doubly Linked List from scratch - moveToHead (Java)从头开始使用双向链表的 LRU 缓存 - moveToHead (Java)
【发布时间】:2014-03-05 11:26:55
【问题描述】:

我已经实现了一个简单的 LRU 缓存,它是一个从头开始手动编写的双向链表。缓存中填充了对象请求,这些对象通过它们的数字(整数)ID 来区分。这些 Request 对象作为一组 N

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

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

项目:7 | 3 | 4 | 5

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

现在,如果我们有一个缓存命中项目 4,因为这个项目不在缓存的头部,它应该被移动到那里,结果将是:

项目:4 | 7 | 3 | 5

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

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

物品:4| 7 | 3 | 4 | 5

缓存位置索引: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 对象。如何解决这个问题?我假设我必须在以下代码中使用临时请求变量,但我还没有想出如何去做。

【问题讨论】:

    标签: java caching doubly-linked-list lru


    【解决方案1】:

    为此,变量 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

    祝你好运!

    【讨论】:

      猜你喜欢
      • 2020-06-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-13
      • 2011-12-15
      • 2015-07-19
      • 2020-01-22
      • 1970-01-01
      相关资源
      最近更新 更多