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

≯℡__Kan透↙ 提交于 2019-12-08 11:29:44

问题


I have implemented a simple LRU cache as a doubly linked list written manually from scratch. The cache is filled with objects Request distinguished by their numeric (integer) ID. These Request objects are generated as a stream of L random independent and identically distributed requests for a set of N < L predefined Request objects and arrive to the cache one by one (i.e. in a serial fashion). Then I check for cache hit or miss and if the current cache size has reached the maximum cache size and then, depending on the case, I perform insertion of the requested item to the cache or replacement of the LRU cached item from the requested item.

One of the operations of the cache is the following: when I have a cache hit, then if the requested item is not in the head, it has to be moved there.

As an example, let's say that the cache has max size M = 4 and its contents at a given time are as follows:

Item: 7 | 3 | 4 | 5

Cache position index: 0 | 1 | 2 | 3 (0 is head, 3 is tail)

Now if we have for example a cache hit for the item 4, since this item is not located at the head of the cache, it should be moved there and the result will be:

Item: 4 | 7 | 3 | 5

Cache position index: 0 | 1 | 2 | 3 (0 is head, 3 is tail)

However, when I run the code the result is this instead:

Item: 4| 7 | 3 | 4 | 5

Cache position index: 0 | 1 | 2 | 3 | 4 (0 is head, 4 is tail)

In other words, the relevant item (in this example, item 4) is not removed from the cache and then added to the head, but it is simply added to the head. Therefore, cache size is increased by 1 (in this example, it has become 5, which is greater than the max cache size M = 4).

Here is the relevant code, along with a comment that shows I think the nature of the problem:

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;

        }

    }

As I state to the comment, if after the first line of code I set the object request to null in order to remove it, then the following lines of code will move to the head a null object. How to solve this? I assume I have to use a temporal Request variable in the following piece of code, but I haven't figured out yet how to do it.


回答1:


For this to work variable head is initialized by a dummy:

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

For the cache hit, remove the entry from the list first:

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

Then add it to the list head:

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

Maybe see some real world implementation here: https://github.com/headissue/cache2k/blob/master/core/src/main/java/org/cache2k/impl/LruCache.java

Good luck!



来源:https://stackoverflow.com/questions/22196377/lru-cache-with-doubly-linked-list-from-scratch-movetohead-java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!