Commit 5983db43 authored by Bandana's avatar Bandana

Update persistentStorage.c

parent ef7f340a
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <unistd.h>
#include <string.h>
// #include <cstdlib>
#include<fcntl.h>
#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>
#include<semaphore.h>
using namespace std;
pthread_mutex_t m;
sem_t w;
int readercout=0;
struct n1
{
char key[257];
int lineno;
char filename[5];
struct n1 *p1;
struct n1 *p2;
int h;
};
struct n2
{
char filename[5];
int nooffreeline;
struct n2 *pointer;
};
struct n1 *h1=NULL;
struct n2 *h2=NULL;
unsigned int nooffiles=0;
struct n2 * check(struct n2 *h2){
while (1)
{
if(h2==NULL){
return NULL;
}
else{
if((h2->nooffreeline)>0){
return h2;}
else{
h2=h2->pointer;
}
}
}
}
int max(int a,int b){
if(a>b){
return a;
}
return b;
}
int hei(struct n1*r){
if(r==NULL){
return 0;
}
return (1+max(hei(r->p1),hei(r->p2)));
}
struct n1* ll(struct n1*r){
struct n1*a=r->p1;
r->p1=r->p1->p2;
a->p2=r;
r->h=max(hei(r->p1),hei(r->p2));
a->h=max(hei(a->p1),hei(a->p2));
return a;
}
struct n1* rr(struct n1*r ){
struct n1*a=r->p2;
r->p2=a->p1;
a->p1=r;
a->h=max(hei(a->p1),hei(a->p2));
r->h=max(hei(r->p1),hei(r->p2));
return a;
}
struct n1 * add;
char lineno=100;
struct n1 * insert(struct n1 *r,char * key){
int tt=0;
if(r==NULL){
r=(struct n1 *)malloc(sizeof(struct n1));
strcpy(r->key,key);
r->p1=NULL;
r->p2=NULL;
r->h=0;
add=r;
struct n2 *tt2=check(h2);
if(tt2==NULL){
tt2=(struct n2 *)malloc(sizeof(struct n2));
char filename2[10];
sprintf(filename2,"%u",(nooffiles=nooffiles+1));
strcpy(tt2->filename,filename2);
// printf(" for the first time storing the file name in n2 is %s\n",tt2->filename);
strcpy(r->filename,filename2);
// printf(" for the first time storing the file name in n1 is %s\n",r->filename);
tt2->nooffreeline=19;
tt2->pointer=h2;
h2=tt2;
FILE *fptr=fopen(strcat(filename2,".txt"),"w");
fprintf(fptr,"aaaaaaaaaaaaaaaaaaaa############################################################################################################################################################################################################################################\n");
fclose(fptr);
// printf(" for the first time storing the file name in n2 is %s\n",tt2->filename);
// printf(" for the first time storing the file name in n1 is %s\n",r->filename);
}
else{
tt2->nooffreeline-=1;
char dum[38];
// sprintf(dum,"the no of free lines left in file %02d",tt2->nooffreeline);
// write(STDOUT_FILENO,dum,36);
// write(STDOUT_FILENO,"\n",1);
strcpy(r->filename,tt2->filename);
}
return r;
}
else{
if((tt=strcmp(key,r->key))>0){//the key i want to add is alphabeticaly greter than the one that is added strcmp(myelement,pre element)
r->p2=insert(r->p2,key);
r->h=max(hei(r->p1),hei(r->p2));
int r2;
if(r->p1==NULL){
r2=1+r->p2->h;
}else{
r2=r->p2->h-r->p1->h;
}
if(r2==1||r2==-1||r2==0){
return r;
}
else{
if(r2<0){
int r3;
if(r->p1->p1==NULL){
r3=1+r->p1->p2->h;
}
else if(r->p1->p2==NULL){
r3=-1-r->p1->p1->h;
}else{
r3=r->p1->p2->h-r->p1->p1->h;
}
if(r3<0){
//left -left
return ll(r);
}
else{
//left-right
r->p1=rr(r->p1);
return ll(r);
}
}
else{
int r3;
if(r->p2->p1==NULL){
r3=1+r->p2->p2->h;
}
else if(r->p2->p2==NULL){
r3=-1-r->p2->p1->h;
}else{
r3=r->p2->p2->h-r->p2->p1->h;
}
if(r3<0){
//right-left
r->p2=ll(r->p2);
return rr(r);
}
else{
//right-right
return rr(r);
}
}
}
}
else if(tt<0){
r->p1=insert(r->p1,key);
r->h=max(hei(r->p1),hei(r->p2));
int r2;
if(r->p2==NULL){
r2=-1-(r->p1->h);
}
else{
r2=r->p2->h-(r->p1->h);
}
if(r2==1||r2==-1||r2==0){
return r;
}
else{
if(r2<0){
int r3;
if(r->p1->p1==NULL){
r3=1+r->p1->p2->h;
}
else if(r->p1->p2==NULL){
r3=-1-r->p1->p1->h;
}else{
r3=r->p1->p2->h-r->p1->p1->h;
}
if(r3<0){
//left -left
return ll(r);
}
else{
//left-right
r->p1=rr(r->p1);
return ll(r);
}
}
else{
int r3;
if(r->p2->p1==NULL){
r3=1+r->p2->p2->h;
}
else if(r->p2->p2==NULL){
r3=-1-r->p2->p1->h;
}else{
r3=r->p2->p2->h-r->p2->p1->h;
}
if(r3<0){
//right-left
r->p2=ll(r->p2);
return rr(r);
}
else{
//right-right
return rr(r);
}
}
}
}
else{
add=r;
lineno=r->lineno;
return r;
}
}
/*
* 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;
}
}
struct n1* finding=NULL;
struct n1* pre;
struct n1* fpre(struct n1 *r){
if(r->p2==NULL){
pre=r;
return r->p1;
}
r->p2=fpre(r->p2);
r->h=max(hei(r->p1),hei(r->p2));
int r2;
if(r->p1==NULL){
if(r->p2==NULL){
return r;
}
else{
r2=1+r->p2->h;
}
}
else{
if(r->p2==NULL){
r2=-1-r->p1->h;
}
else{
r2=r->p2->h-r->p1->h;
}
}
if(r2==1||r2==-1||r2==0){
return r;
}
else{
if(r2<0){
int r3;
if(r->p1->p1==NULL){
r3=1+r->p1->p2->h;
}
else if(r->p1->p2==NULL){
r3=-1-r->p1->p1->h;
}else{
r3=r->p1->p2->h-r->p1->p1->h;
}
if(r3<0){
//left -left
return ll(r);
}
else{
//left-right
r->p1=rr(r->p1);
return ll(r);
}
}
else{
int r3;
if(r->p2->p1==NULL){
r3=1+r->p2->p2->h;
}
else if(r->p2->p2==NULL){
r3=-1-r->p2->p1->h;
}else{
r3=r->p2->p2->h-r->p2->p1->h;
}
if(r3<0){
//right-left
r->p2=ll(r->p2);
return rr(r);
}
else{
//right-right
return rr(r);
}
}
}
return r;
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();
}
}
struct n1* del(struct n1*r,char *key){
int tt;
if(r==NULL){
return NULL;
}
if((tt=strcmp(key,r->key))==0){//both are equal
if(r->p1==NULL&&r->p2==NULL){
finding=r;
return NULL;
}
if(r->p1==NULL){
finding=r;
return r->p2;
}
if(r->p2==NULL){
finding=r;
return r->p1;
}
finding=r;
fpre(r->p1);
pre->p1=r->p1;
pre->p2=r->p2;
return pre;
}
if(tt>0){//the key i want to add is alphabeticaly greter than the one that is added strcmp(myelement,pre element)
r->p2=del(r->p2,key);
r->h=max(hei(r->p1),hei(r->p2));
int r2;
if(r->p1==NULL){
if(r->p2==NULL){
return r;
}
else{
r2=1+r->p2->h;
}
}
else{
if(r->p2==NULL){
r2=-1-r->p1->h;
}
else{
r2=r->p2->h-r->p1->h;
}
}
if(r2==1||r2==-1||r2==0){
return r;
}
else{
if(r2<0){
int r3;
if(r->p1->p1==NULL){
r3=1+r->p1->p2->h;
}
else if(r->p1->p2==NULL){
r3=-1-r->p1->p1->h;
}else{
r3=r->p1->p2->h-r->p1->p1->h;
}
if(r3<0){
//left -left
return ll(r);
}
else{
//left-right
r->p1=rr(r->p1);
return ll(r);
}
}
else{
int r3;
if(r->p2->p1==NULL){
r3=1+r->p2->p2->h;
}
else if(r->p2->p2==NULL){
r3=-1-r->p2->p1->h;
}else{
r3=r->p2->p2->h-r->p2->p1->h;
}
if(r3<0){
//right-left
r->p2=ll(r->p2);
return rr(r);
}
else{
//right-right
return rr(r);
}
}
}
}
else{
r->p1=del(r->p1,key);
r->h=max(hei(r->p1),hei(r->p2));
int r2;
if(r->p1==NULL){
if(r->p2==NULL){
return r;
}
else{
r2=1+r->p2->h;
}
}
else{
if(r->p2==NULL){
r2=-1-r->p1->h;
}
else{
r2=r->p2->h-r->p1->h;
}
}
if(r2==1||r2==-1||r2==0){
return r;
}
else{
if(r2<0){
int r3;
if(r->p1->p1==NULL){
r3=1+r->p1->p2->h;
}
else if(r->p1->p2==NULL){
r3=-1-r->p1->p1->h;
}else{
r3=r->p1->p2->h-r->p1->p1->h;
}
if(r3<0){
//left -left
return ll(r);
}
else{
//left-right
r->p1=rr(r->p1);
return ll(r);
}
}
else{
int r3;
if(r->p2->p1==NULL){
r3=1+r->p2->p2->h;
}
else if(r->p2->p2==NULL){
r3=-1-r->p2->p1->h;
}else{
r3=r->p2->p2->h-r->p2->p1->h;
}
if(r3<0){
//right-left
r->p2=ll(r->p2);
return rr(r);
}
else{
//right-right
return rr(r);
}
}
}
}
/*
* 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();
}
}
struct n1* GETT(char * key){
pthread_mutex_lock(&m);
readercout+=1;
if(readercout==1){
sem_wait(&w);
}
pthread_mutex_unlock(&m);
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);
int tt;
struct n1 *dh=h1;
while(1)
{
if(dh==NULL)
string value;
if(dh==NULL)
{
string s(1, (char)240);
string result = s + "Get key not found";
......@@ -586,22 +117,20 @@ struct n1* GETT(char * key){
// record[0]=240;
// record[1]='\0';
// char *pointer=record;
pthread_mutex_lock(&m);
readercout-=1;
if(readercout==0){
sem_post(&w);
}
// pthread_mutex_lock(&m);
// readercout-=1;
// if(readercout==0){
// sem_post(&w);
// }
pthread_mutex_unlock(&m);
// pthread_mutex_unlock(&m);
return dh;
// return dh;
}
else
{
printf("%s = %s \n",key ,dh->key);
if((tt=strcmp(key,dh->key))==0)
{
char filename2[10];
else{
char filename2[10];
strcpy(filename2,dh->filename);
FILE *f=fopen(strcat(filename2,".txt"),"r");
char record[257];
......@@ -614,198 +143,29 @@ struct n1* GETT(char * key){
sp=sp+1;
}
record[sp]='\0';
string result=record;
value=record;
// char *recor=record;
// return recor;
pthread_mutex_lock(&m);
readercout-=1;
if(readercout==0){
sem_post(&w);
}
// pthread_mutex_lock(&m);
// readercout-=1;
// if(readercout==0){
// sem_post(&w);
// }
pthread_mutex_unlock(&m);
return dh;
}
else if(tt>0)
{
dh=dh->p2;
}
else{
dh=dh->p1;
}
}
}
}
// pthread_mutex_unlock(&m);
void PUTT(char *key,char *value){
sem_wait(&w);
printf("key = %s\nvalue=%s",key, value);
h1=insert(h1,key);
char filename2[10];
strcpy(filename2,add->filename);
FILE *f=fopen(strcat(filename2,".txt"),"r");
char s[21];
int n=0;
fgets(s,21,f);
fclose(f);
// printf("%s\n",s);
if(lineno==100){
while(s[n]!='a'){
n=n+1;
}
int mm=n;
add->lineno=n+1;
char dum[24];
// sprintf(dum,"the free line no is %02d",mm+1);
// write(STDOUT_FILENO,dum,22);
// write(STDOUT_FILENO,"\n",1);
n=strlen(value);
char ts[257];
strcpy(ts,value);
while(n!=256){
ts[n]='#';
n+=1;
}
ts[256]='\n';
n=open(filename2,O_WRONLY);
lseek(n,mm,SEEK_SET);
write(n,"n",1);
lseek(n,(add->lineno)*257,SEEK_SET);
write(n,ts,257);
close(n);
}
else{
n=strlen(value);
char ts[257];
strcpy(ts,value);
while(n!=256){
ts[n]='#';
n+=1;
}
ts[256]='\n';
n=open(strcat(add->filename,".txt"),O_WRONLY);
lseek(n,(add->lineno)*257,SEEK_SET);
lineno=100;
write(n,ts,257);
close(n);
}
printf("PUTT completed\n");
sem_post(&w);
}
// return dh;
struct n2 * checkfile(struct n2 *h2,char *s){
while (1)
{
if(h2==NULL){
// printf("return \n");
return NULL;
}
else{
// printf("%s = %s \n",h2->filename,s);
if(strcmp(h2->filename,s)==0){
// printf("if \n");
return h2;}
else{
h2=h2->pointer;
// printf("else \n");
}
}
}
}
string DELL(char *key){
sem_wait(&w);
h1=del(h1,key);
// write(STDOUT_FILENO,"came out of del \n",17);
// printf("key = %s\n", key);
if(finding==NULL){
printf("could not delete as key does not exist \n");
string s(1, (char)240);
string response = s + "Delete key not found";
sem_post(&w);
return response;
}
// write(STDOUT_FILENO,"the finding is not null \n",22);
char filename2[10];
strcpy(filename2,finding->filename);
int n=open(strcat(filename2,".txt"),O_WRONLY);
// write(STDOUT_FILENO,"test \n",6);
lseek(n,finding->lineno-1,SEEK_SET);
// write(STDOUT_FILENO,"test \n",6);
write(n,"a",1);
// write(STDOUT_FILENO,"test \n",6);
close(n);
// write(STDOUT_FILENO,"test \n",6);
// write(STDOUT_FILENO,"the file name i shoud be delted",31);
// write(STDOUT_FILENO,finding->filename,5);
// write(STDOUT_FILENO,"\n",1);
struct n2 *tp=checkfile(h2,finding->filename);
// write(STDOUT_FILENO,"the file name i shoud be delted",31);
// write(STDOUT_FILENO,finding->filename,1);
// write(STDOUT_FILENO,"\n",1);
if(tp==NULL){
printf("the checkfile has given NULL");
string s(1, (char)240);
string response = s + "Delete Failed";
sem_post(&w);
return response;
}
// write(STDOUT_FILENO,"test \n",6);
tp->nooffreeline=tp->nooffreeline-1;
// write(STDOUT_FILENO,"test \n",6);
free(finding);
finding=NULL;
// printf("del function completed\n");
string s(1, (char)200);
string response = s + "Delete Successful";
sem_post(&w);
return response;
}
}
void pp(struct n1*r){
if(r==NULL){
return;
}
pp(r->p1);
printf("%s\n",r->key);
pp(r->p2);
}
void pp2(struct n1*r){
if(r==NULL){
return;
}
printf("%s\n",r->key);
pp2(r->p1);
pp2(r->p2);
}
// int main()
// {
// PUTT("1",);
// return 0;
// }
......@@ -814,5 +174,120 @@ void pp2(struct n1*r){
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;
// }
// }
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