LFU 缓存实现

LFU 缓存实现

原理: 使用优先队列+hashmap

1.Node 中定义 freq 为频率,index 是时间戳

public interface ICache<K, V> {

    V get(K key);

    void put(K key, V value);
}

Cache

public class Cache<K, V> implements ICache<K, V> {

    private Map<K, Node<K, V>> map;
    private Queue<Node<K, V>> queue;
    private int capacity;
    private int size;

    public Cache(int capacity) {
        this.capacity = capacity;
        queue = new PriorityQueue<>(capacity);
        map = new HashMap<>();
    }


    @Override
    public V get(K key) {
        Node<K, V> node = map.get(key);
        if (node == null) {
            throw new RuntimeException("不存在");
        }
        node.freq++;
        node.index++;
        queue.remove(node);
        queue.offer(node);
        return node.getData();
    }

    @Override
    public void put(K key, V value) {
        Node<K, V> node = map.get(key);
        if (node != null) {
            node.freq++;
            node.index++;
            node.setKey(key);
            node.setData(value);
            queue.remove(node);
            queue.offer(node);
        } else {
            if (size == capacity) {
                Node<K, V> poll = queue.poll();
                System.out.println("cache full, remove node key: " + poll.getKey());
                size--;
                map.remove(poll.getKey());
            }
            node = new Node<>();
            node.freq++;
            node.index++;
            node.setData(value);
            node.setKey(key);
            queue.offer(node);
            size++;
            map.put(key, node);
        }
    }
}

Node

@Data
public class Node<K, T> implements Comparable<Node<K, T>> {

    private T data;
    private K key;
    //频率
    public int freq;
    //时间
    public int index;

    @Override
    public int compareTo(Node<K, T> o) {
        //先根据频率,后根据时间戳排序
        int diff = this.freq - o.freq;
        return diff == 0 ? this.index - o.index : diff;
    }
}

测试:

public static void main(String[] args) {
    ICache<String, Integer> cache = new Cache<>(3);

    cache.put("a", 1);
    cache.put("a", 2);
    cache.put("a", 4);
    cache.put("b", 1);
    cache.put("b", 1);
    cache.put("c", 1);
    cache.put("c", 2);
    cache.put("b", 2);
    cache.put("e", 1);
    try {
        System.out.println(cache.get("b"));
    } catch (Exception e) {
        e.printStackTrace();
    }
    System.out.println(cache.get("a"));


}

结果:

cache full, remove node key: c
2
4

你可能感兴趣的:(每日一问,缓存)