From bcc743a4508fe730a3f1d1dcffb94b7e2f46683e Mon Sep 17 00:00:00 2001 From: Vishal M Yadav Date: Mon, 2 Dec 2024 18:10:02 +0530 Subject: [PATCH] added lfucache feature --- .../com/gatomalvado/done/lfucache/Dll.java | 63 +++++++++++++++ .../gatomalvado/done/lfucache/DllNode.java | 34 ++++++++ .../gatomalvado/done/lfucache/LfuCache.java | 79 +++++++++++++++++++ .../com/gatomalvado/done/lfucache/Main.java | 34 ++++++++ .../com/gatomalvado/todo/lfucache/Main.java | 7 -- 5 files changed, 210 insertions(+), 7 deletions(-) create mode 100644 src/main/java/com/gatomalvado/done/lfucache/Dll.java create mode 100644 src/main/java/com/gatomalvado/done/lfucache/DllNode.java create mode 100644 src/main/java/com/gatomalvado/done/lfucache/LfuCache.java create mode 100644 src/main/java/com/gatomalvado/done/lfucache/Main.java delete mode 100644 src/main/java/com/gatomalvado/todo/lfucache/Main.java diff --git a/src/main/java/com/gatomalvado/done/lfucache/Dll.java b/src/main/java/com/gatomalvado/done/lfucache/Dll.java new file mode 100644 index 0000000..f6ff99e --- /dev/null +++ b/src/main/java/com/gatomalvado/done/lfucache/Dll.java @@ -0,0 +1,63 @@ +package com.gatomalvado.done.lfucache; + +import lombok.Data; +import lombok.NoArgsConstructor; + +@NoArgsConstructor +@Data +public class Dll { + + private DllNode head; + private DllNode tail; + private int currSize; + + public void addFront(DllNode node) { + if(head == null) { + head = node; + tail = node; + return; + } + node.setNext(head); + head.setPrev(node); + head = node; + } + + public void removeNode(DllNode node) { + DllNode prev = node.getPrev(); + DllNode next = node.getNext(); + if(node == tail) { + // this is a tail node; + if(prev == null) { + // this is a head node too + head = null; + tail = null; + } else { + prev.setNext(null); + tail = prev; + } + } else if(node == head) { + // this is a head node; + if(next == null) { + // this is a tail node too; + head = null; + tail = null; + } else { + next.setPrev(null); + head = next; + } + } else { + if(prev != null) { + prev.setNext(next); + } + if(next != null) { + next.setPrev(prev); + } + } + + node.setPrev(null); + node.setNext(null); + this.currSize--; + + } + +} diff --git a/src/main/java/com/gatomalvado/done/lfucache/DllNode.java b/src/main/java/com/gatomalvado/done/lfucache/DllNode.java new file mode 100644 index 0000000..af906db --- /dev/null +++ b/src/main/java/com/gatomalvado/done/lfucache/DllNode.java @@ -0,0 +1,34 @@ +package com.gatomalvado.done.lfucache; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@AllArgsConstructor +@NoArgsConstructor +public class DllNode { + + private String key; + private String value; + private int freq; + private DllNode next; + private DllNode prev; + + public DllNode(String key, String value) { + this.key = key; + this.value = value; + this.freq = 1; + } + + @Override + public String toString() { + return "Node: {" + + "key: '" + key + '\'' + + ", value: '" + value + '\'' + + ", freq: " + freq + + '}'; + } +} diff --git a/src/main/java/com/gatomalvado/done/lfucache/LfuCache.java b/src/main/java/com/gatomalvado/done/lfucache/LfuCache.java new file mode 100644 index 0000000..a3cdc8b --- /dev/null +++ b/src/main/java/com/gatomalvado/done/lfucache/LfuCache.java @@ -0,0 +1,79 @@ +package com.gatomalvado.done.lfucache; + +import java.util.HashMap; +import java.util.Map; + +public class LfuCache { + + private int maxCap; + private Map storage; + private Map keyToListMap; + private int minFreq; + + public LfuCache(int maxCap) { + this.maxCap = maxCap; + storage = new HashMap<>(); + this.keyToListMap = new HashMap<>(); + } + + public String get(String key) { + DllNode node = storage.get(key); + if (node == null) { + System.out.println("no value exists for the key: "+key); + return null; + } + updateKey(node); + return node.getValue(); + } + + public void put(String key, String value) { + if(keyToListMap.containsKey(key)) { + DllNode node = storage.get(key); + node.setValue(value); + updateKey(node); + } else { + if(this.storage.size() == this.maxCap) { + Dll minFreqList = this.keyToListMap.get(this.minFreq); + DllNode tailNode = minFreqList.getTail(); + if(minFreqList != null) { + minFreqList.removeNode(tailNode); + } + if(minFreqList.getCurrSize() == 0) { + this.keyToListMap.remove(this.minFreq); + } + this.storage.remove(tailNode.getKey()); + } + + DllNode newNode = new DllNode(key, value); + storage.put(key, newNode); + this.minFreq = 1; + Dll newList = this.keyToListMap.get(this.minFreq); + if(newList == null) { + newList = new Dll(); + } + newList.addFront(newNode); + this.keyToListMap.put(this.minFreq, newList); + } + } + + public void updateKey(DllNode node) { + int currFreq = node.getFreq(); + node.setFreq(currFreq + 1); + Dll prevList = keyToListMap.get(currFreq); + prevList.removeNode(node); + Dll newList = keyToListMap.get(node.getFreq()); + if(newList == null) { + newList = new Dll(); + } + newList.addFront(node); + keyToListMap.put(node.getFreq(), newList); + if(prevList.getCurrSize() == 0) { + keyToListMap.remove(currFreq); + this.minFreq = node.getFreq(); + } + } + + public void printCache() { + System.out.println(storage); + } +} diff --git a/src/main/java/com/gatomalvado/done/lfucache/Main.java b/src/main/java/com/gatomalvado/done/lfucache/Main.java new file mode 100644 index 0000000..9dc1167 --- /dev/null +++ b/src/main/java/com/gatomalvado/done/lfucache/Main.java @@ -0,0 +1,34 @@ +package com.gatomalvado.done.lfucache; + +public class Main { + + public static void main(String[] args) { + LfuCache lfuCache = new LfuCache(4); + lfuCache.put("k1", "5"); + lfuCache.printCache(); + lfuCache.put("k2", "1"); + lfuCache.printCache(); + lfuCache.put("k3", "2"); + lfuCache.printCache(); + lfuCache.put("k4", "4"); + lfuCache.printCache(); + lfuCache.put("k5", "8"); + lfuCache.printCache(); + lfuCache.get("k1"); + lfuCache.printCache(); + lfuCache.put("k4", "8"); + lfuCache.printCache(); + lfuCache.put("k9", "8"); + lfuCache.printCache(); + lfuCache.put("k10", "8"); + lfuCache.printCache(); + lfuCache.get("k2"); + lfuCache.printCache(); + lfuCache.get("k3"); + lfuCache.printCache(); + lfuCache.get("k4"); + lfuCache.printCache(); + lfuCache.get("k1"); + lfuCache.printCache(); + } +} diff --git a/src/main/java/com/gatomalvado/todo/lfucache/Main.java b/src/main/java/com/gatomalvado/todo/lfucache/Main.java deleted file mode 100644 index 8110bdc..0000000 --- a/src/main/java/com/gatomalvado/todo/lfucache/Main.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.gatomalvado.todo.lfucache; - -public class Main { - public static void main(String[] args) { - - } -}