Commit a6a13809 authored by Bandana's avatar Bandana

Update persistentStorage.c

parent 5983db43
#include <iostream>
#include <list>
#include <iterator>
#include <unordered_map>
#include <string>
#include <cstdlib>
#include<cstring>
// #include "cs_thread.h"
#include "cache.h"
#include "storage.h"
#include <iostream>
using namespace std;
/*
* The idea behind cache implementation :
* To implement LRU, Write-back, fully associative cache
* MAX Cache size - 32 key-value pairs
* Each cache node will consist of 1. key 2. value 3. dirty bit
* Algo :
* 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 is not full, add the key-value pair to start of the cache
* 3. LRU cache :
* (Use locality to evict more than one key-value pair?)
* 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 8
list<cacheNode> cache;
unordered_map<string, list <cacheNode> :: iterator> hashTable;
pthread_mutex_t cLock;
/*
* 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)
*/
string search(string key) {
unordered_map<string, list <cacheNode> :: iterator> :: iterator it = hashTable.find(key);
if(it == hashTable.end()) {
string ans = "";
return ans;
}
else {
list <cacheNode> :: iterator cnode_it = it->second;
cache.push_front(*cnode_it);
cache.erase(cnode_it);
hashTable[key] = cache.begin();
string ans = cnode_it->value;
return ans;
}
}
void lru(string key, string value) {
list <cacheNode> :: iterator it = prev(cache.end());
if(it->dirtyBit == '1') {
// Write back to persistent storage
}
else {
int num = hashTable.erase(it->key);
cache.pop_back();
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(string key, string value) {
cacheNode cnode;
if(cache.size() == MAX_CACHE_SIZE) {
// printf("LRU called\n");
lru(key, value);
}
else {
cnode.key = key;
cnode.value = value;
cnode.dirtyBit = '0';
cache.push_front(cnode);
hashTable[key] = cache.begin();
}
}
string GET(string key) {
// printf("GET function\n");
pthread_mutex_lock(&cLock);
string ans = search(key);
pthread_mutex_unlock(&cLock);
/*need to add ravi code*/
if(ans=="")
{
char * new_key = new char[key.size() + 1];
copy(key.begin(), key.end(), new_key);
new_key[key.size()] = '\0';
struct n1* dh = GETT(new_key);
string value;
if(dh==NULL)
{
string s(1, (char)240);
string result = s + "Get key not found";
printf("The key is not present\n");
// record[0]=240;
// record[1]='\0';
// char *pointer=record;
// pthread_mutex_lock(&m);
// readercout-=1;
// if(readercout==0){
// sem_post(&w);
// }
struct n1
{
char key[257];
int lineno;
char filename[5];
struct n1 *p1;
struct n1 *p2;
// pthread_mutex_unlock(&m);
// return dh;
}
else{
char filename2[10];
strcpy(filename2,dh->filename);
FILE *f=fopen(strcat(filename2,".txt"),"r");
char record[257];
fseek(f,dh->lineno*257,SEEK_SET);
fgets(record,256,f);
fclose(f);
int sp=0;
while (record[sp]!='#')
{
sp=sp+1;
}
record[sp]='\0';
value=record;
// char *recor=record;
// return recor;
// pthread_mutex_lock(&m);
// readercout-=1;
// if(readercout==0){
// sem_post(&w);
// }
int h;
// pthread_mutex_unlock(&m);
// return dh;
}
if(value[0] != (char)240) {
// cLock
pthread_mutex_lock(&cLock);
insert(key, value);
pthread_mutex_unlock(&cLock);
//uncLock
}
return value;
return "ERROR";
}
return ans;
}
string PUT(string key, string value) {
// cout << "PUT started" << endl;
pthread_mutex_lock(&cLock);
string ans = search(key);
if(ans == "") {
insert(key, value);
}
else {
unordered_map<string, list <cacheNode> :: iterator> :: iterator it = hashTable.find(key);
it->second->value = value;
}
pthread_mutex_unlock(&cLock);
// uncLock
char * new_key = new char[key.size() + 1];
copy(key.begin(), key.end(), new_key);
new_key[key.size()] = '\0';
char * new_value = new char[value.size() + 1];
copy(value.begin(), value.end(), new_value);
new_value[value.size()] = '\0';
// PUTT(new_key, new_value);
string s(1, (char)200);
string response = s + "Put Completed Successfully";
return response;
}
/*
* Delete from cache
*/
string DEL(string key) {
/*Need to add ravi code*/
//cLock
pthread_mutex_lock(&cLock);
string ans = search(key);
if(ans != "") {
unordered_map<string, list <cacheNode> :: iterator> :: iterator it = hashTable.find(key);
list<cacheNode> :: iterator cnode_it = it->second;
cache.erase(cnode_it);
hashTable.erase(key);
pthread_mutex_unlock(&cLock);
return "SUCCESS";
}
//uncLock
pthread_mutex_unlock(&cLock);
char * new_key = new char[key.size() + 1];
copy(key.begin(), key.end(), new_key);
new_key[key.size()] = '\0';
// string response=DELL(new_key);
string response = "ERROR";
return response;
}
/*
* Testing code
*/
// int main() {
// 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);
// 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;
// }
// printf("-----------------------------\n");
// DEL(key5);
// for (auto p : hashTable) {
// cout << p.first << " : ";
// cout << p.second->key << " " << p.second->value << " " << p.second->dirtyBit << endl;
// }
// }
};
struct n1* GETT(char *);
void PUTT(char *, char *);
string DELL(char *);
\ No newline at end of file
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