How to implement a Least Frequently Used (LFU) cache?

后端 未结 7 1463
孤城傲影
孤城傲影 2021-01-31 04:50

Least Frequently Used (LFU) is a type of cache algorithm used to manage memory within a computer. The standard characteristics of this method involve the system keeping track of

7条回答
  •  梦谈多话
    2021-01-31 05:35

    1. According to me, the best way to implement a most-recently-used cache of objects would be to include a new variable as 'latestTS' for each object. TS stands for timestamp.

      // A static method that returns the current date and time as milliseconds since January 1st 1970 long latestTS = System.currentTimeMillis();

    2. ConcurrentLinkedHashMap is not yet implemented in Concurrent Java Collections. (Ref: Java Concurrent Collection API). However, you can try and use ConcurrentHashMap and DoublyLinkedList

    3. About the case to be considered: in such case, as I have said that you can declare latestTS variable, based upon the value of latestTS variable, you can remove an entry and add the new object. (Don't forget to update frequency and latestTS of the new object added)

    As you have mentioned, you can use LinkedHashMap as it gives element access in O(1) and also, you get the order traversal. Please, find the below code for LFU Cache: (PS: The below code is the answer for the question in the title i.e. "How to implement LFU cache")

    import java.util.LinkedHashMap;
    import java.util.Map;
    
    public class LFUCache {
    
        class CacheEntry
        {
            private String data;
            private int frequency;
    
            // default constructor
            private CacheEntry()
            {}
    
            public String getData() {
                return data;
            }
            public void setData(String data) {
                this.data = data;
            }
    
            public int getFrequency() {
                return frequency;
            }
            public void setFrequency(int frequency) {
                this.frequency = frequency;
            }       
    
        }
    
        private static int initialCapacity = 10;
    
        private static LinkedHashMap cacheMap = new LinkedHashMap();
        /* LinkedHashMap is used because it has features of both HashMap and LinkedList. 
         * Thus, we can get an entry in O(1) and also, we can iterate over it easily.
         * */
    
        public LFUCache(int initialCapacity)
        {
            this.initialCapacity = initialCapacity;
        }
    
        public void addCacheEntry(int key, String data)
        {
            if(!isFull())
            {
                CacheEntry temp = new CacheEntry();
                temp.setData(data);
                temp.setFrequency(0);
    
                cacheMap.put(key, temp);
            }
            else
            {
                int entryKeyToBeRemoved = getLFUKey();
                cacheMap.remove(entryKeyToBeRemoved);
    
                CacheEntry temp = new CacheEntry();
                temp.setData(data);
                temp.setFrequency(0);
    
                cacheMap.put(key, temp);
            }
        }
    
        public int getLFUKey()
        {
            int key = 0;
            int minFreq = Integer.MAX_VALUE;
    
            for(Map.Entry entry : cacheMap.entrySet())
            {
                if(minFreq > entry.getValue().frequency)
                {
                    key = entry.getKey();
                    minFreq = entry.getValue().frequency;
                }           
            }
    
            return key;
        }
    
        public String getCacheEntry(int key)
        {
            if(cacheMap.containsKey(key))  // cache hit
            {
                CacheEntry temp = cacheMap.get(key);
                temp.frequency++;
                cacheMap.put(key, temp);
                return temp.data;
            }
            return null; // cache miss
        }
    
        public static boolean isFull()
        {
            if(cacheMap.size() == initialCapacity)
                return true;
    
            return false;
        }
    }
    

提交回复
热议问题