forked from dimpeshmalviya/C-Language-Programs
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathLRUCache.c
More file actions
176 lines (147 loc) · 4.43 KB
/
LRUCache.c
File metadata and controls
176 lines (147 loc) · 4.43 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
/*
Program Name: LRU Cache Implementation in C
Problem Statement:
Implement a Least Recently Used (LRU) cache with a fixed capacity.
The cache should support two operations:
1. get(key) -> returns the value if the key exists, else -1.
2. put(key, value) -> adds the key-value pair to the cache, evicting
the least recently used item if the cache is full.
Concepts Used: Linked List, Hashing (array of pointers), Memory Management
*/
#include <stdio.h>
#include <stdlib.h>
#define CACHE_SIZE 3 // Change cache size here
#define HASH_SIZE 10 // Simple hash table size
// Node of Doubly Linked List
typedef struct Node {
int key;
int value;
struct Node *prev, *next;
} Node;
// LRU Cache structure
typedef struct LRUCache {
Node *head, *tail; // Doubly linked list for LRU order
Node *hash[HASH_SIZE]; // Simple hash table
int size;
} LRUCache;
// Helper function: Create new node
Node* createNode(int key, int value) {
Node* newNode = (Node*)malloc(sizeof(Node));
newNode->key = key;
newNode->value = value;
newNode->prev = newNode->next = NULL;
return newNode;
}
// Simple hash function
int hashFunc(int key) {
return key % HASH_SIZE;
}
// Initialize LRU Cache
LRUCache* initCache() {
LRUCache *cache = (LRUCache*)malloc(sizeof(LRUCache));
cache->head = cache->tail = NULL;
cache->size = 0;
for(int i = 0; i < HASH_SIZE; i++)
cache->hash[i] = NULL;
return cache;
}
// Remove node from linked list
void removeNode(LRUCache *cache, Node *node) {
if(node->prev) node->prev->next = node->next;
else cache->head = node->next;
if(node->next) node->next->prev = node->prev;
else cache->tail = node->prev;
}
// Add node to head (most recently used)
void addToHead(LRUCache *cache, Node *node) {
node->next = cache->head;
node->prev = NULL;
if(cache->head) cache->head->prev = node;
cache->head = node;
if(cache->tail == NULL) cache->tail = node;
}
// Get value by key
int get(LRUCache *cache, int key) {
int h = hashFunc(key);
Node *node = cache->hash[h];
while(node) {
if(node->key == key) {
// Move node to head (most recently used)
removeNode(cache, node);
addToHead(cache, node);
return node->value;
}
node = node->next;
}
return -1; // Not found
}
// Put key-value into cache
void put(LRUCache *cache, int key, int value) {
int h = hashFunc(key);
Node *node = cache->hash[h];
// Check if key exists
while(node) {
if(node->key == key) {
node->value = value;
removeNode(cache, node);
addToHead(cache, node);
return;
}
node = node->next;
}
// Key not present, create new node
Node *newNode = createNode(key, value);
addToHead(cache, newNode);
// Add to hash (simple chaining)
newNode->next = cache->hash[h];
if(cache->hash[h]) cache->hash[h]->prev = newNode;
cache->hash[h] = newNode;
cache->size++;
// Evict if cache size exceeds capacity
if(cache->size > CACHE_SIZE) {
Node *toRemove = cache->tail;
removeNode(cache, toRemove);
// Remove from hash
int hh = hashFunc(toRemove->key);
Node *temp = cache->hash[hh];
if(temp == toRemove) cache->hash[hh] = toRemove->next;
else {
while(temp->next && temp->next != toRemove) temp = temp->next;
if(temp->next) temp->next = toRemove->next;
}
free(toRemove);
cache->size--;
}
}
// Print cache (most recent -> least recent)
void printCache(LRUCache *cache) {
Node *curr = cache->head;
printf("Cache state (MRU -> LRU): ");
while(curr) {
printf("[%d:%d] ", curr->key, curr->value);
curr = curr->next;
}
printf("\n");
}
// Driver code
int main() {
LRUCache *cache = initCache();
put(cache, 1, 100);
put(cache, 2, 200);
put(cache, 3, 300);
printCache(cache); // Should show 3->2->1
printf("Get key 2: %d\n", get(cache, 2)); // Access 2, moves to head
printCache(cache); // 2->3->1
put(cache, 4, 400); // Evicts least recently used (key 1)
printCache(cache); // 4->2->3
printf("Get key 1: %d\n", get(cache, 1)); // -1, evicted
return 0;
}
/*
Sample Output:
Cache state (MRU -> LRU): [3:300] [2:200] [1:100]
Get key 2: 200
Cache state (MRU -> LRU): [2:200] [3:300] [1:100]
Cache state (MRU -> LRU): [4:400] [2:200] [3:300]
Get key 1: -1
*/