LFU内存淘汰算法的简单实现

  • LFU: Least Frequently Used
class LFUCLass {
    // mapping from key to val, KV chart
    HashMap<Integer, Interger> keyToVal;
    // mapping from key to freq, KF chart
    HashMap<Integer, Interger> keyToFreq;
    // mapping from freq to key, FK chart
    HashMap<Integer, Interger> freqToKeys;

    // logging the least freq
    int minFreq;
    // logging the largest col of LFU cache
    int cap;

    public LFUCache(int capacity) {
        keyToVal = new HashMap<>();
        keyToFreq = new HashMap<>();
        freqToKeys = new HashMap<>();
        this.cap = capacity;
        this.minFreq = 0;
    }

    pubic int get(int key) {
        if(!kryToVal.containsKey(key)) {
            return -1;
        }
        // increase the freq corresponding to the key
        increaseFreq(key);
        return ketToVal.get(key);
    }

    public void put(int key, int val) {
        if(this.cap <= 0) return;

        // if key is existed
        if(keyToVal.containsKey(key)) {
            keyToVal.put(key, val);

            increaseFreq(key);
            return;
        }

        // if key is not existed
        if(this.cap <= keyToVal.size()) {
            removeMinFreq();
        }

        //insert key and val, freq is 1
        //insert KV chart
        keyToVal.put(key, val);
        //insert FK chart
        keyToFreq.put(key, 1);
        //insert FK chart
        freqToKeys.putIfAbsent(1, new LinkedHashSet<>());
        freqToKeys.get(1).add(key);

        this.minFreq = 1;
    }
}
  • define removeMinFreq and increaseFreq functions
private void removeMinFreq() {
    LinkedHashSet<Interger> keyList = freqToKeys.get(this.minFreq);
    // the first one inserted should be eliminated
    int deletedKey = keyList.iterator().next();

    // update FK chart
    keyList.remove(deletedKey);
    if(keyList.isEmpty()) {
        freqToKeys.remove(this.minFreq);
    }
    // update KV chart
    keyToVal.remove(deletedKey);
    // update KF chart
    keyToFreq.remove(deletedKey);
}

private void increaseFreq(int key) {
    int freq = keyToFreq.get(key);

    // update KF chart
    keyToFreq.put(key, freq + 1);
    // update FK chart
    freqToKeys.get(freq).remove(key);
    freqToKeys.putIfAbsent(freq + 1, new LinkedHashSet<>());
    freqToKays.get(freq + 1).add(key);

    // remove the key if the list is cleared
    if(freqToKeys.get(freq).isEmpty()) {
        freqToKeys.remove(freq);
        // if the freq is minFreq, update minFreq
        if(freq == this.minFreq) {
            this.minFreq++;
        }
    }
}
Licensed under CC BY-NC-SA 4.0
comments powered by Disqus
Built with Hugo
Theme Stack designed by Jimmy