首页
学习
活动
专区
圈层
工具
发布

LRU-2执行
EN

Stack Overflow用户
提问于 2015-07-22 02:36:07
回答 1查看 1.4K关注 0票数 0

我试图用的PriorityQueue实现一个LRU-2缓存。在我看来,我可以在poll()add()中完成O(LogN)时间,但是对于缓存中的搜索,需要花费O(N)时间。对于如何在LRU-2缓存中使用poll()add()search()O(LogN)时间内实现有什么建议吗?还是根本不可能做到?

EN

回答 1

Stack Overflow用户

发布于 2015-07-27 16:21:52

经过一点挣扎,我得到了一个MaxHeap和HashMap的LRU-2,操作最多需要O(log )时间。以下是Java中LRU-2的代码。代码也在我的GitHub上。

Node.java,这是HashMap和MaxHeap中的值。

代码语言:javascript
复制
package me.york;

class Node<K, V extends Comparable<V>> implements Comparable<Node<K, V>> {
private K key;
private V value;
private int index;
private long lastTime;
private long lastSecondTime;
public static long INIT = -1;

Node(K key, V value) {
    this.key = key;
    this.value = value;
    lastTime = INIT;
    lastSecondTime = INIT;
}

@Override
public int compareTo(Node<K, V> o) {
    return (int)(lastSecondTime-o.getLastSecondTime());
}

K getKey() {
    return key;
}

V getValue() {
    return value;
}

int getIndex() {
    return index;
}

void setIndex(int index) {
    this.index = index;
}

long getLastTime() {
    return lastTime;
}

void setLastTime(long lastTime) {
    this.lastTime = lastTime;
}

long getLastSecondTime() {
    return lastSecondTime;
}

void setLastSecondTime(long lastSecondTime) {
    this.lastSecondTime = lastSecondTime;
}
}

MaxHeap.java,LRU-2算法的主要逻辑就在这一类中.

代码语言:javascript
复制
package me.york;

class MaxHeap<K, V extends Comparable<V>> {
private Node<K, V>[] heap;
private int currentSize;
private long count;

MaxHeap(int size) {
    count = 0;
    currentSize = 1;
    heap = new Node[size + 1];
}

boolean isFull() {
    return currentSize >= heap.length;
}

Node<K, V> add(Node<K, V> value) {
    Node<K, V> previous = value;
    if (currentSize >= heap.length) {
        previous = removeMax();
    }
    if (value.getLastSecondTime() != Node.INIT) {
        value.setLastSecondTime(value.getLastTime());
    } else {
        value.setLastSecondTime(count);
    }
    value.setLastTime(count++);
    value.setIndex(currentSize);
    heap[currentSize++] = value;
    siftUp(currentSize - 1);
    return previous;
}

Node<K, V> getMax() {
    return heap[0];
}

Node<K, V> removeMax() {
    return remove(0);
}

Node<K, V> reVisited(int index) {
    Node<K, V> node = heap[index];
    remove(node.getIndex());
    add(node);
    return node;
}

Node<K, V> remove(int index) {
    Node<K, V> previous = heap[index];
    heap[index] = heap[--currentSize];
    siftDown(index);
    return previous;
}

private void siftDown(int index) {
    int left = 2 * index;
    int right = 2 * index + 1;
    int largest;
    if (left < currentSize && heap[left].compareTo(heap[index]) > 0)
        largest = left;
    else
        largest = index;
    if (right < currentSize && heap[right].compareTo(heap[largest]) > 0)
        largest = right;
    if (largest != index) {
        Node<K, V> temp = heap[index];
        heap[index] = heap[largest];
        heap[largest] = temp;
        heap[index].setIndex(largest);
        heap[largest].setIndex(index);
        siftDown(largest);
    }
}

private void siftUp(int index) {
    while (index > 1 && heap[index].compareTo(heap[index / 2]) > 0) {
        Node<K, V> temp = heap[index];
        heap[index] = heap[index / 2];
        heap[index / 2] = temp;
        heap[index].setIndex(index / 2);
        heap[index / 2].setIndex(index);
        index = index / 2;
    }
}
}

LRU2Cache.java,-这是LRU-2缓存算法的条目.它只提供两个函数,get()和put()。

代码语言:javascript
复制
package me.york;

import java.util.HashMap;
import java.util.Map;

public class LRU2Cache<K, V extends Comparable<V>> {
private MaxHeap<K, V> maxHeap;
private Map<K, Node<K, V>> map;

public LRU2Cache(int cacheSize) {
    maxHeap = new MaxHeap<K, V>(cacheSize);
    map = new HashMap<K, Node<K, V>>((int) ((float) cacheSize / 0.75F + 1.0F));
}

public void put(K key, V value) {
    if (key != null && value != null) {
        Node<K, V> previous;
        if ((previous = map.get(key)) != null) {
            maxHeap.remove(previous.getIndex());
        }
        if (maxHeap.isFull())
            map.remove(maxHeap.getMax().getKey());
        previous = new Node<K, V>(key, value);
        map.put(key, previous);
        maxHeap.add(previous);
    }
}

public V get(K key) {
    V value = null;
    if (key != null) {
        Node<K, V> node = map.get(key);
        if (node != null) {
            value = node.getValue();
            maxHeap.reVisited(node.getIndex());
        }
    }
    return value;
}
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31552927

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档