#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LEN 100
#define CACHE_CAPACITY 3
#define HASH_SIZE 1024
// Node cho doubly linked list và hash table
typedef struct Node {
int key;
char value[MAX_LEN];
int freq;
struct Node *prev, *next;
struct Node *hnext; // next trong hash chain
} Node;
// Hash map đơn giản
Node* hashmap[HASH_SIZE];
// Hàm băm đơn giản
int hash(int key) {
return key % HASH_SIZE;
}
Node* hash_get(int key) {
int idx = hash(key);
Node* cur = hashmap[idx];
while (cur) {
if (cur->key == key) return cur;
cur = cur->hnext;
}
return NULL;
}
void hash_put(Node* node) {
int idx = hash(node->key);
node->hnext = hashmap[idx];
hashmap[idx] = node;
}
void hash_remove(int key) {
int idx = hash(key);
Node *cur = hashmap[idx], *prev = NULL;
while (cur) {
if (cur->key == key) {
if (prev) prev->hnext = cur->hnext;
else hashmap[idx] = cur->hnext;
return;
}
prev = cur;
cur = cur->hnext;
}
}
// ==== LRU ====
Node *lru_head = NULL, *lru_tail = NULL;
int lru_size = 0;
void lru_move_to_front(Node* node) {
if (node == lru_head) return;
if (node->prev) node->prev->next = node->next;
if (node->next) node->next->prev = node->prev;
if (node == lru_tail) lru_tail = node->prev;
node->prev = NULL;
node->next = lru_head;
if (lru_head) lru_head->prev = node;
lru_head = node;
if (!lru_tail) lru_tail = lru_head;
}
void lru_remove_tail() {
if (!lru_tail) return;
Node* temp = lru_tail;
if (lru_tail->prev) lru_tail->prev->next = NULL;
lru_tail = lru_tail->prev;
if (!lru_tail) lru_head = NULL;
hash_remove(temp->key);
lru_size--;
}
void lru_put(int key, const char* value) {
Node* node = hash_get(key);
if (node) {
strncpy(node
->value
, value
, MAX_LEN
); lru_move_to_front(node);
return;
}
if (lru_size == CACHE_CAPACITY) lru_remove_tail();
Node
* new_node
= (Node
*)malloc(sizeof(Node
)); new_node->key = key;
strncpy(new_node
->value
, value
, MAX_LEN
); new_node->prev = new_node->next = new_node->hnext = NULL;
new_node->freq = 1;
new_node->next = lru_head;
if (lru_head) lru_head->prev = new_node;
lru_head = new_node;
if (!lru_tail) lru_tail = lru_head;
hash_put(new_node);
lru_size++;
}
char* lru_get(int key) {
Node* node = hash_get(key);
if (!node) return NULL;
node->freq++;
lru_move_to_front(node);
return node->value;
}
void print_lru_cache() {
Node* cur = lru_head;
while (cur) {
printf("(%d:%s) ", cur
->key
, cur
->value
); cur = cur->next;
}
}
// ==== MRU ====
Node *mru_head = NULL, *mru_tail = NULL;
int mru_size = 0;
void mru_remove_head() {
if (!mru_head) return;
Node* temp = mru_head;
if (mru_head->next) mru_head->next->prev = NULL;
mru_head = mru_head->next;
if (!mru_head) mru_tail = NULL;
hash_remove(temp->key);
mru_size--;
}
void mru_put(int key, const char* value) {
Node* node = hash_get(key);
if (node) {
strncpy(node
->value
, value
, MAX_LEN
); return;
}
if (mru_size == CACHE_CAPACITY) mru_remove_head();
Node
* new_node
= (Node
*)malloc(sizeof(Node
)); new_node->key = key;
strncpy(new_node
->value
, value
, MAX_LEN
); new_node->prev = mru_tail;
new_node->next = NULL;
new_node->hnext = NULL;
new_node->freq = 1;
if (mru_tail) mru_tail->next = new_node;
mru_tail = new_node;
if (!mru_head) mru_head = new_node;
hash_put(new_node);
mru_size++;
}
void print_mru_cache() {
Node* cur = mru_head;
while (cur) {
printf("(%d:%s) ", cur
->key
, cur
->value
); cur = cur->next;
}
}
// ==== MFU ====
Node* mfu_list = NULL;
int mfu_size = 0;
void mfu_remove_most_frequent() {
Node *prev = NULL, *cur = mfu_list, *target = NULL, *target_prev = NULL;
int max_freq = -1;
while (cur) {
if (cur->freq > max_freq) {
max_freq = cur->freq;
target = cur;
target_prev = prev;
}
prev = cur;
cur = cur->next;
}
if (!target) return;
if (target_prev) target_prev->next = target->next;
else mfu_list = target->next;
hash_remove(target->key);
mfu_size--;
}
void mfu_put(int key, const char* value) {
Node* node = hash_get(key);
if (node) {
strncpy(node
->value
, value
, MAX_LEN
); node->freq++;
return;
}
if (mfu_size == CACHE_CAPACITY) mfu_remove_most_frequent();
Node
* new_node
= (Node
*)malloc(sizeof(Node
)); new_node->key = key;
strncpy(new_node
->value
, value
, MAX_LEN
); new_node->prev = new_node->next = NULL;
new_node->hnext = NULL;
new_node->freq = 1;
new_node->next = mfu_list;
mfu_list = new_node;
hash_put(new_node);
mfu_size++;
}
void print_mfu_cache() {
Node* cur = mfu_list;
while (cur) {
printf("(%d:%s|f%d) ", cur
->key
, cur
->value
, cur
->freq
); cur = cur->next;
}
}
int main() {
printf("=== LRU Cache Test ===\n"); lru_put(1, "A"); lru_put(2, "B"); lru_put(3, "C");
print_lru_cache();
lru_get(2); print_lru_cache();
lru_put(4, "D"); print_lru_cache();
memset(hashmap
, 0, sizeof(hashmap
)); printf("\n=== MRU Cache Test ===\n"); mru_put(1, "A"); mru_put(2, "B"); mru_put(3, "C");
print_mru_cache();
mru_put(4, "D"); print_mru_cache();
memset(hashmap
, 0, sizeof(hashmap
)); printf("\n=== MFU Cache Test ===\n"); mfu_put(1, "A"); mfu_put(2, "B"); mfu_put(3, "C");
print_mfu_cache();
mfu_put(2, "B"); mfu_put(4, "D");
print_mfu_cache();
return 0;
}
I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgoKI2RlZmluZSBNQVhfTEVOIDEwMAojZGVmaW5lIENBQ0hFX0NBUEFDSVRZIDMKI2RlZmluZSBIQVNIX1NJWkUgMTAyNAoKLy8gTm9kZSBjaG8gZG91Ymx5IGxpbmtlZCBsaXN0IHbDoCBoYXNoIHRhYmxlCnR5cGVkZWYgc3RydWN0IE5vZGUgewogICAgaW50IGtleTsKICAgIGNoYXIgdmFsdWVbTUFYX0xFTl07CiAgICBpbnQgZnJlcTsKICAgIHN0cnVjdCBOb2RlICpwcmV2LCAqbmV4dDsKICAgIHN0cnVjdCBOb2RlICpobmV4dDsgLy8gbmV4dCB0cm9uZyBoYXNoIGNoYWluCn0gTm9kZTsKCi8vIEhhc2ggbWFwIMSRxqFuIGdp4bqjbgpOb2RlKiBoYXNobWFwW0hBU0hfU0laRV07CgovLyBIw6BtIGLEg20gxJHGoW4gZ2nhuqNuCmludCBoYXNoKGludCBrZXkpIHsKICAgIHJldHVybiBrZXkgJSBIQVNIX1NJWkU7Cn0KCk5vZGUqIGhhc2hfZ2V0KGludCBrZXkpIHsKICAgIGludCBpZHggPSBoYXNoKGtleSk7CiAgICBOb2RlKiBjdXIgPSBoYXNobWFwW2lkeF07CiAgICB3aGlsZSAoY3VyKSB7CiAgICAgICAgaWYgKGN1ci0+a2V5ID09IGtleSkgcmV0dXJuIGN1cjsKICAgICAgICBjdXIgPSBjdXItPmhuZXh0OwogICAgfQogICAgcmV0dXJuIE5VTEw7Cn0KCnZvaWQgaGFzaF9wdXQoTm9kZSogbm9kZSkgewogICAgaW50IGlkeCA9IGhhc2gobm9kZS0+a2V5KTsKICAgIG5vZGUtPmhuZXh0ID0gaGFzaG1hcFtpZHhdOwogICAgaGFzaG1hcFtpZHhdID0gbm9kZTsKfQoKdm9pZCBoYXNoX3JlbW92ZShpbnQga2V5KSB7CiAgICBpbnQgaWR4ID0gaGFzaChrZXkpOwogICAgTm9kZSAqY3VyID0gaGFzaG1hcFtpZHhdLCAqcHJldiA9IE5VTEw7CiAgICB3aGlsZSAoY3VyKSB7CiAgICAgICAgaWYgKGN1ci0+a2V5ID09IGtleSkgewogICAgICAgICAgICBpZiAocHJldikgcHJldi0+aG5leHQgPSBjdXItPmhuZXh0OwogICAgICAgICAgICBlbHNlIGhhc2htYXBbaWR4XSA9IGN1ci0+aG5leHQ7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgcHJldiA9IGN1cjsKICAgICAgICBjdXIgPSBjdXItPmhuZXh0OwogICAgfQp9CgovLyA9PT09IExSVSA9PT09Ck5vZGUgKmxydV9oZWFkID0gTlVMTCwgKmxydV90YWlsID0gTlVMTDsKaW50IGxydV9zaXplID0gMDsKCnZvaWQgbHJ1X21vdmVfdG9fZnJvbnQoTm9kZSogbm9kZSkgewogICAgaWYgKG5vZGUgPT0gbHJ1X2hlYWQpIHJldHVybjsKICAgIGlmIChub2RlLT5wcmV2KSBub2RlLT5wcmV2LT5uZXh0ID0gbm9kZS0+bmV4dDsKICAgIGlmIChub2RlLT5uZXh0KSBub2RlLT5uZXh0LT5wcmV2ID0gbm9kZS0+cHJldjsKICAgIGlmIChub2RlID09IGxydV90YWlsKSBscnVfdGFpbCA9IG5vZGUtPnByZXY7CiAgICBub2RlLT5wcmV2ID0gTlVMTDsKICAgIG5vZGUtPm5leHQgPSBscnVfaGVhZDsKICAgIGlmIChscnVfaGVhZCkgbHJ1X2hlYWQtPnByZXYgPSBub2RlOwogICAgbHJ1X2hlYWQgPSBub2RlOwogICAgaWYgKCFscnVfdGFpbCkgbHJ1X3RhaWwgPSBscnVfaGVhZDsKfQoKdm9pZCBscnVfcmVtb3ZlX3RhaWwoKSB7CiAgICBpZiAoIWxydV90YWlsKSByZXR1cm47CiAgICBOb2RlKiB0ZW1wID0gbHJ1X3RhaWw7CiAgICBpZiAobHJ1X3RhaWwtPnByZXYpIGxydV90YWlsLT5wcmV2LT5uZXh0ID0gTlVMTDsKICAgIGxydV90YWlsID0gbHJ1X3RhaWwtPnByZXY7CiAgICBpZiAoIWxydV90YWlsKSBscnVfaGVhZCA9IE5VTEw7CiAgICBoYXNoX3JlbW92ZSh0ZW1wLT5rZXkpOwogICAgZnJlZSh0ZW1wKTsKICAgIGxydV9zaXplLS07Cn0KCnZvaWQgbHJ1X3B1dChpbnQga2V5LCBjb25zdCBjaGFyKiB2YWx1ZSkgewogICAgTm9kZSogbm9kZSA9IGhhc2hfZ2V0KGtleSk7CiAgICBpZiAobm9kZSkgewogICAgICAgIHN0cm5jcHkobm9kZS0+dmFsdWUsIHZhbHVlLCBNQVhfTEVOKTsKICAgICAgICBscnVfbW92ZV90b19mcm9udChub2RlKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBpZiAobHJ1X3NpemUgPT0gQ0FDSEVfQ0FQQUNJVFkpIGxydV9yZW1vdmVfdGFpbCgpOwogICAgTm9kZSogbmV3X25vZGUgPSAoTm9kZSopbWFsbG9jKHNpemVvZihOb2RlKSk7CiAgICBuZXdfbm9kZS0+a2V5ID0ga2V5OwogICAgc3RybmNweShuZXdfbm9kZS0+dmFsdWUsIHZhbHVlLCBNQVhfTEVOKTsKICAgIG5ld19ub2RlLT5wcmV2ID0gbmV3X25vZGUtPm5leHQgPSBuZXdfbm9kZS0+aG5leHQgPSBOVUxMOwogICAgbmV3X25vZGUtPmZyZXEgPSAxOwogICAgbmV3X25vZGUtPm5leHQgPSBscnVfaGVhZDsKICAgIGlmIChscnVfaGVhZCkgbHJ1X2hlYWQtPnByZXYgPSBuZXdfbm9kZTsKICAgIGxydV9oZWFkID0gbmV3X25vZGU7CiAgICBpZiAoIWxydV90YWlsKSBscnVfdGFpbCA9IGxydV9oZWFkOwogICAgaGFzaF9wdXQobmV3X25vZGUpOwogICAgbHJ1X3NpemUrKzsKfQoKY2hhciogbHJ1X2dldChpbnQga2V5KSB7CiAgICBOb2RlKiBub2RlID0gaGFzaF9nZXQoa2V5KTsKICAgIGlmICghbm9kZSkgcmV0dXJuIE5VTEw7CiAgICBub2RlLT5mcmVxKys7CiAgICBscnVfbW92ZV90b19mcm9udChub2RlKTsKICAgIHJldHVybiBub2RlLT52YWx1ZTsKfQoKdm9pZCBwcmludF9scnVfY2FjaGUoKSB7CiAgICBOb2RlKiBjdXIgPSBscnVfaGVhZDsKICAgIHByaW50ZigiTFJVIENhY2hlOiAiKTsKICAgIHdoaWxlIChjdXIpIHsKICAgICAgICBwcmludGYoIiglZDolcykgIiwgY3VyLT5rZXksIGN1ci0+dmFsdWUpOwogICAgICAgIGN1ciA9IGN1ci0+bmV4dDsKICAgIH0KICAgIHByaW50ZigiXG4iKTsKfQoKLy8gPT09PSBNUlUgPT09PQpOb2RlICptcnVfaGVhZCA9IE5VTEwsICptcnVfdGFpbCA9IE5VTEw7CmludCBtcnVfc2l6ZSA9IDA7Cgp2b2lkIG1ydV9yZW1vdmVfaGVhZCgpIHsKICAgIGlmICghbXJ1X2hlYWQpIHJldHVybjsKICAgIE5vZGUqIHRlbXAgPSBtcnVfaGVhZDsKICAgIGlmIChtcnVfaGVhZC0+bmV4dCkgbXJ1X2hlYWQtPm5leHQtPnByZXYgPSBOVUxMOwogICAgbXJ1X2hlYWQgPSBtcnVfaGVhZC0+bmV4dDsKICAgIGlmICghbXJ1X2hlYWQpIG1ydV90YWlsID0gTlVMTDsKICAgIGhhc2hfcmVtb3ZlKHRlbXAtPmtleSk7CiAgICBmcmVlKHRlbXApOwogICAgbXJ1X3NpemUtLTsKfQoKdm9pZCBtcnVfcHV0KGludCBrZXksIGNvbnN0IGNoYXIqIHZhbHVlKSB7CiAgICBOb2RlKiBub2RlID0gaGFzaF9nZXQoa2V5KTsKICAgIGlmIChub2RlKSB7CiAgICAgICAgc3RybmNweShub2RlLT52YWx1ZSwgdmFsdWUsIE1BWF9MRU4pOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIGlmIChtcnVfc2l6ZSA9PSBDQUNIRV9DQVBBQ0lUWSkgbXJ1X3JlbW92ZV9oZWFkKCk7CiAgICBOb2RlKiBuZXdfbm9kZSA9IChOb2RlKiltYWxsb2Moc2l6ZW9mKE5vZGUpKTsKICAgIG5ld19ub2RlLT5rZXkgPSBrZXk7CiAgICBzdHJuY3B5KG5ld19ub2RlLT52YWx1ZSwgdmFsdWUsIE1BWF9MRU4pOwogICAgbmV3X25vZGUtPnByZXYgPSBtcnVfdGFpbDsKICAgIG5ld19ub2RlLT5uZXh0ID0gTlVMTDsKICAgIG5ld19ub2RlLT5obmV4dCA9IE5VTEw7CiAgICBuZXdfbm9kZS0+ZnJlcSA9IDE7CiAgICBpZiAobXJ1X3RhaWwpIG1ydV90YWlsLT5uZXh0ID0gbmV3X25vZGU7CiAgICBtcnVfdGFpbCA9IG5ld19ub2RlOwogICAgaWYgKCFtcnVfaGVhZCkgbXJ1X2hlYWQgPSBuZXdfbm9kZTsKICAgIGhhc2hfcHV0KG5ld19ub2RlKTsKICAgIG1ydV9zaXplKys7Cn0KCnZvaWQgcHJpbnRfbXJ1X2NhY2hlKCkgewogICAgTm9kZSogY3VyID0gbXJ1X2hlYWQ7CiAgICBwcmludGYoIk1SVSBDYWNoZTogIik7CiAgICB3aGlsZSAoY3VyKSB7CiAgICAgICAgcHJpbnRmKCIoJWQ6JXMpICIsIGN1ci0+a2V5LCBjdXItPnZhbHVlKTsKICAgICAgICBjdXIgPSBjdXItPm5leHQ7CiAgICB9CiAgICBwcmludGYoIlxuIik7Cn0KCi8vID09PT0gTUZVID09PT0KTm9kZSogbWZ1X2xpc3QgPSBOVUxMOwppbnQgbWZ1X3NpemUgPSAwOwoKdm9pZCBtZnVfcmVtb3ZlX21vc3RfZnJlcXVlbnQoKSB7CiAgICBOb2RlICpwcmV2ID0gTlVMTCwgKmN1ciA9IG1mdV9saXN0LCAqdGFyZ2V0ID0gTlVMTCwgKnRhcmdldF9wcmV2ID0gTlVMTDsKICAgIGludCBtYXhfZnJlcSA9IC0xOwogICAgd2hpbGUgKGN1cikgewogICAgICAgIGlmIChjdXItPmZyZXEgPiBtYXhfZnJlcSkgewogICAgICAgICAgICBtYXhfZnJlcSA9IGN1ci0+ZnJlcTsKICAgICAgICAgICAgdGFyZ2V0ID0gY3VyOwogICAgICAgICAgICB0YXJnZXRfcHJldiA9IHByZXY7CiAgICAgICAgfQogICAgICAgIHByZXYgPSBjdXI7CiAgICAgICAgY3VyID0gY3VyLT5uZXh0OwogICAgfQogICAgaWYgKCF0YXJnZXQpIHJldHVybjsKICAgIGlmICh0YXJnZXRfcHJldikgdGFyZ2V0X3ByZXYtPm5leHQgPSB0YXJnZXQtPm5leHQ7CiAgICBlbHNlIG1mdV9saXN0ID0gdGFyZ2V0LT5uZXh0OwogICAgaGFzaF9yZW1vdmUodGFyZ2V0LT5rZXkpOwogICAgZnJlZSh0YXJnZXQpOwogICAgbWZ1X3NpemUtLTsKfQoKdm9pZCBtZnVfcHV0KGludCBrZXksIGNvbnN0IGNoYXIqIHZhbHVlKSB7CiAgICBOb2RlKiBub2RlID0gaGFzaF9nZXQoa2V5KTsKICAgIGlmIChub2RlKSB7CiAgICAgICAgc3RybmNweShub2RlLT52YWx1ZSwgdmFsdWUsIE1BWF9MRU4pOwogICAgICAgIG5vZGUtPmZyZXErKzsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBpZiAobWZ1X3NpemUgPT0gQ0FDSEVfQ0FQQUNJVFkpIG1mdV9yZW1vdmVfbW9zdF9mcmVxdWVudCgpOwogICAgTm9kZSogbmV3X25vZGUgPSAoTm9kZSopbWFsbG9jKHNpemVvZihOb2RlKSk7CiAgICBuZXdfbm9kZS0+a2V5ID0ga2V5OwogICAgc3RybmNweShuZXdfbm9kZS0+dmFsdWUsIHZhbHVlLCBNQVhfTEVOKTsKICAgIG5ld19ub2RlLT5wcmV2ID0gbmV3X25vZGUtPm5leHQgPSBOVUxMOwogICAgbmV3X25vZGUtPmhuZXh0ID0gTlVMTDsKICAgIG5ld19ub2RlLT5mcmVxID0gMTsKICAgIG5ld19ub2RlLT5uZXh0ID0gbWZ1X2xpc3Q7CiAgICBtZnVfbGlzdCA9IG5ld19ub2RlOwogICAgaGFzaF9wdXQobmV3X25vZGUpOwogICAgbWZ1X3NpemUrKzsKfQoKdm9pZCBwcmludF9tZnVfY2FjaGUoKSB7CiAgICBOb2RlKiBjdXIgPSBtZnVfbGlzdDsKICAgIHByaW50ZigiTUZVIENhY2hlOiAiKTsKICAgIHdoaWxlIChjdXIpIHsKICAgICAgICBwcmludGYoIiglZDolc3xmJWQpICIsIGN1ci0+a2V5LCBjdXItPnZhbHVlLCBjdXItPmZyZXEpOwogICAgICAgIGN1ciA9IGN1ci0+bmV4dDsKICAgIH0KICAgIHByaW50ZigiXG4iKTsKfQoKaW50IG1haW4oKSB7CiAgICBwcmludGYoIj09PSBMUlUgQ2FjaGUgVGVzdCA9PT1cbiIpOwogICAgbHJ1X3B1dCgxLCAiQSIpOyBscnVfcHV0KDIsICJCIik7IGxydV9wdXQoMywgIkMiKTsKICAgIHByaW50X2xydV9jYWNoZSgpOwogICAgbHJ1X2dldCgyKTsgcHJpbnRfbHJ1X2NhY2hlKCk7CiAgICBscnVfcHV0KDQsICJEIik7IHByaW50X2xydV9jYWNoZSgpOwoKICAgIG1lbXNldChoYXNobWFwLCAwLCBzaXplb2YoaGFzaG1hcCkpOwogICAgcHJpbnRmKCJcbj09PSBNUlUgQ2FjaGUgVGVzdCA9PT1cbiIpOwogICAgbXJ1X3B1dCgxLCAiQSIpOyBtcnVfcHV0KDIsICJCIik7IG1ydV9wdXQoMywgIkMiKTsKICAgIHByaW50X21ydV9jYWNoZSgpOwogICAgbXJ1X3B1dCg0LCAiRCIpOyBwcmludF9tcnVfY2FjaGUoKTsKCiAgICBtZW1zZXQoaGFzaG1hcCwgMCwgc2l6ZW9mKGhhc2htYXApKTsKICAgIHByaW50ZigiXG49PT0gTUZVIENhY2hlIFRlc3QgPT09XG4iKTsKICAgIG1mdV9wdXQoMSwgIkEiKTsgbWZ1X3B1dCgyLCAiQiIpOyBtZnVfcHV0KDMsICJDIik7CiAgICBwcmludF9tZnVfY2FjaGUoKTsKICAgIG1mdV9wdXQoMiwgIkIiKTsgbWZ1X3B1dCg0LCAiRCIpOwogICAgcHJpbnRfbWZ1X2NhY2hlKCk7CgogICAgcmV0dXJuIDA7Cn0K