Commit 5ffd666b authored by Nilesh Jagdish's avatar Nilesh Jagdish

Replaced c-strings with cpp string

parent 3b45c310
#include <iostream>
#include <list>
#include <cstring>
#include <iterator>
#include <unordered_map>
#include <string>
#include "cache.h"
using namespace std;
/*
......@@ -14,29 +14,31 @@ using namespace std;
* 1. Search in cache :
* Use unordered_map to see if a key is present in the cache and if it is present, this operation
* should return 1
* This operation should also move searched key to start of the cache
* 2. Insert in cache :
* If cache is full, call LRU
* If cache has is not full, replace the frame with key-value pair to be inserted
* If cache is not full, add the key-value pair to start of the cache
* 3. LRU cache :
* Keep a pointer on a frame after the frame last replaced
* Move the pointer circularly, if a node has referenceBit = '0', then select this key-value for
* replacement
* Use bitmap to identify the file in which key is present
* (Use locality to evict more than one key-value pair?)
* And read the key-value pair in array element
* Delete the last element in cache
* Insert new key-value pair at the start of the cache
*
* Data Structures : 1. List of cacheNode - 32 keys
* 2. Unordered map - <key, array index>
*
*/
#define MAX_CACHE_SIZE 32
#define MAX_CACHE_SIZE 3
list<cacheNode> cache;
unordered_map<char *, list <cacheNode> :: iterator> hashTable;
unordered_map<string, list <cacheNode> :: iterator> hashTable;
int search(char* key) {
unordered_map<char *, list <cacheNode> :: iterator> :: iterator it = hashTable.find(key);
/*
* Returns 1 if key-value pair is present in cache and 0 otherwise
* If key is present, brings correspoding node to front of the cache(To identify recently used element)
*/
int search(string key) {
unordered_map<string, list <cacheNode> :: iterator> :: iterator it = hashTable.find(key);
if(it == hashTable.end()) {
return 0;
}
......@@ -44,31 +46,52 @@ int search(char* key) {
list <cacheNode> :: iterator cnode_it = it->second;
cache.push_front(*cnode_it);
cache.erase(cnode_it);
hashTable[key] = cache.begin();
return 1;
}
}
void lru(char* key, char *value) {
void lru(string key, string value) {
list <cacheNode> :: iterator it = prev(cache.end());
if(it->dirtyBit == '1') {
// Write back to persistent storage
}
else {
for (auto p : hashTable) {
cout << p.first << " : ";
cout << p.second->key << " " << p.second->value << " " << p.second->dirtyBit << endl ;
}
int num = hashTable.erase(it->key);
cache.pop_back();
for (auto p : hashTable) {
cout << p.first << " : ";
cout << p.second->key << " " << p.second->value << " " << p.second->dirtyBit << endl;
}
printf("-----------------------------\n");
cacheNode cnode;
cnode.key = key;
cnode.value = value;
cnode.dirtyBit = '0';
cache.push_back(cnode);
hashTable[key] = --cache.end();
}
}
/*
* Assumption here is that before calling insert, key-value pair does not already exist in cache
*/
void insert(char* key, char* value) {
void insert(string key, string value) {
cacheNode cnode;
if(cache.size() == MAX_CACHE_SIZE) {
// printf("LRU called\n");
lru(key, value);
}
else {
cnode.key = (char *)malloc(strlen(key) + 1);
strcpy(cnode.key, key);
cnode.value = (char *)malloc(strlen(value) + 1);
strcpy(cnode.value, value);
cnode.key = key;
cnode.value = value;
cnode.dirtyBit = '0';
cache.push_front(cnode);
hashTable[key] = cache.begin();
}
}
......@@ -76,16 +99,45 @@ void insert(char* key, char* value) {
* Testing code
*/
int main() {
char key1[] = "A";
char key2[] = "B";
char key3[] = "C";
char key4[] = "D";
char value[] = "1";
string key1 = "AB";
string key2 = "BC";
string key3 = "CD";
string key4 = "DE";
string key5 = "EF";
string value = "1";
insert(key1, value);
insert(key2, value);
for (auto p : hashTable) {
cout << p.first << " : ";
cout << p.second->key << " " << p.second->value << " " << p.second->dirtyBit << endl;
}
printf("-----------------------------\n");
insert(key3, value);
printf("%d\n", search(key1));
printf("%d\n", search(key2));
printf("%d\n", search(key3));
printf("%d\n", search(key4));
for (auto p : hashTable) {
cout << p.first << " : ";
cout << p.second->key << " " << p.second->value << " " << p.second->dirtyBit << endl;
}
printf("-----------------------------\n");
insert(key4, value);
for (auto p : hashTable) {
cout << p.first << " : ";
cout << p.second->key << " " << p.second->value << " " << p.second->dirtyBit << endl;
}
printf("-----------------------------\n");
cout << key1 << " " << search(key1) << endl;
cout << key2 << " " << search(key2) << endl;
cout << key3 << " " << search(key3) << endl;
cout << key4 << " " << search(key4) << endl;
printf("-----------------------------\n");
for (auto p : hashTable) {
cout << p.first << " : ";
cout << p.second->key << " " << p.second->value << " " << p.second->dirtyBit << endl;
}
printf("-----------------------------\n");
insert(key5, value);
for (auto p : hashTable) {
cout << p.first << " : ";
cout << p.second->key << " " << p.second->value << " " << p.second->dirtyBit << endl;
}
}
#include <iostream>
#include <list>
#include <iterator>
#include <string>
#include <unordered_map>
using namespace std;
/*
*
* Cache node structure :
* dirtyBit = '1' if value is modified, '0' if not modified
* referenceBit - To implement approximate LRU
* An iterator will iterate through the list to find first page which has referenceBit = '0'
* It replaces that key-value along with 3 following key-value pairs with the new key and its following
* 3 key-value pairs in persistent storage
* If referenceBit = '1', set it to '0' and move forward(in circular fashion)
* To implement perfect LRU(which might be costly in terms of performance) - need a global counter for time
*/
typedef struct cacheNode {
char* key;
char* value;
string key;
string value;
char dirtyBit;
} cacheNode;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment