Commit 264b5d6b authored by RAVIKANT KUMAR YADAV's avatar RAVIKANT KUMAR YADAV

initial commit

parents
*.gch
*.out
ClientData/clientResponses.txt
obj/*
checklist
\ No newline at end of file
PUT 110 value111_110
PUT 12 value12_12
PUT 12 value12_12
PUT 12 value12_12
PUT 12 value12_12
PUT 12 value12_12
PUT 12 value12_12
PUT 12 value12_12
PUT 1 value11_11_11
PUT 12 value12_12
PUT 13 value13_13
PUT 14 value14_14
GET 11
GET 12
DEL 12
DEL 11
GET 11
GET 13
PUT 110 value111_110
PUT 12 value12_12
PUT 12 value12_12
PUT 12 value12_12
PUT 12 value12_12
PUT 12 value12_12
PUT 12 value12_12
PUT 12 value12_12
PUT 12 value12_12
PUT 1 value11_11_11
PUT 12 value12_12
PUT 13 value13_13
PUT 14 value14_14
GET 11
GET 12
DEL 12
DEL 11
GET 11
GET 13
PUT 110 value111_110
PUT 12 value12_12
PUT 12 value12_12
PUT 12 value12_12
PUT 12 value12_12
PUT 12 value12_12
PUT 12 value12_12
PUT 12 value12_12
all: gendir client server kvstore xmlParser kvcache
CC = gcc
OBJDIR = obj
BUILD_DIR = build
SERVER_DIR = ServerData
OBJ_SERVER = $(OBJDIR)/server.o
OBJ_CLIENT = $(OBJDIR)/client.o
OBJ_KVSTORE = $(OBJDIR)/kvstore.o
OBJ_KVCACHE = $(OBJDIR)/kvcache.o
OBJ_XML = $(OBJDIR)/xmlParserRunner.o
OBJ_THREADPOOL = $(OBJDIR)/threadpool.o
HEADERDIR = include
HEADER = $(HEADERDIR)/*.h
CFLAGS = -c -Iinclude/
gendir:
mkdir -p $(OBJDIR)
mkdir -p $(SERVER_DIR)
mkdir -p $(BUILD_DIR)
# .PHONY: client
client: $(BUILD_DIR)/client
$(OBJ_CLIENT): src/client.c $(HEADER)
$(CC) $(CFLAGS) $< -o $@
$(BUILD_DIR)/client: $(OBJ_CLIENT)
$(CC) $(OBJ_CLIENT) -o $@
xmlParser: $(BUILD_DIR)/xmlParser
$(OBJ_XML): src/xmlParserRunner.c $(HEADER)
$(CC) $(CFLAGS) $< -o $@
$(BUILD_DIR)/xmlParser: $(OBJ_XML)
$(CC) $(OBJ_XML) -o $@
# threadpool: $(BUILD_DIR)/threadpool
# $(OBJ_THREADPOOL): src/threadpoolRunner.c $(HEADER)
# $(CC) $(CFLAGS) $< -o $@
# $(BUILD_DIR)/threadpool: $(OBJ_THREADPOOL)
# $(CC) $(OBJ_THREADPOOL) -o $@ -lpthread
server: $(BUILD_DIR)/server
$(OBJ_SERVER): src/server.c $(HEADER)
$(CC) $(CFLAGS) $< -o $@
$(BUILD_DIR)/server: $(OBJ_SERVER)
$(CC) $(OBJ_SERVER) -o $@ -lpthread
kvstore: $(BUILD_DIR)/kvstore
$(OBJ_KVSTORE): src/kvstoreRunner.c $(HEADER)
$(CC) $(CFLAGS) $< -o $@
$(BUILD_DIR)/kvstore: $(OBJ_KVSTORE)
$(CC) $(OBJ_KVSTORE) -o $@
kvcache: $(BUILD_DIR)/kvcache
$(OBJ_KVCACHE): src/kvcacheRunner.c $(HEADER)
$(CC) $(CFLAGS) $< -o $@
$(BUILD_DIR)/kvcache: $(OBJ_KVCACHE)
$(CC) $(OBJ_KVCACHE) -o $@
clean:
@rm -rf *.out obj/* build/*
@rmdir obj build
KVStore:
Steps to execute:
1. Run make command in parent directory.
2. Go in build directory to run the executables.
a. Run server as : ./server <port number> <number of sets> <n-way in set associative cache>
b. Run client as : ./client <server_ip> <port number> <Input Request fIle> <Output Response file>
Note: For step 2 , above given Sequence of command line parameters must be followed.
Directory Structure:
1. /build: Contains all the excecutable files.
2. /ClientData: Contains default request file and generated response file.
3. /include: Contains header files.
4. /ServerData: Contains the multiple generated csv file each for a unique set ID.
StoreXML file when generated by toXML method in KVCache and CacheXML file when generated by dumpToFile method in KVStore.
5. /src: Contains all the source file.
Steps to generate XML files:
1. StoreXML : At any point of time, after server serves request of client.
Run the executable ./kvstore in parent directory
https://aticleworld.com/parse-xml-response-in-c/
https://www.ibm.com/support/knowledgecenter/ssw_ibm_i_71/rzab6/poll.htm
<?xml version="1.0" encoding="UTF-8"?>
<KVCache>
<Set Id="0">
<CacheEntry isReferenced="​​false"isValid="​false">
<Key></Key>
<Value></Value>
</CacheEntry>
<CacheEntry isReferenced="​​false"isValid="​false">
<Key></Key>
<Value></Value>
</CacheEntry>
<CacheEntry isReferenced="​​false"isValid="​false">
<Key></Key>
<Value></Value>
</CacheEntry>
<CacheEntry isReferenced="​​false"isValid="​false">
<Key></Key>
<Value></Value>
</CacheEntry>
<CacheEntry isReferenced="​​false"isValid="​false">
<Key></Key>
<Value></Value>
</CacheEntry>
<CacheEntry isReferenced="​​false"isValid="​false">
<Key></Key>
<Value></Value>
</CacheEntry>
<CacheEntry isReferenced="​​false"isValid="​false">
<Key></Key>
<Value></Value>
</CacheEntry>
<CacheEntry isReferenced="​​false"isValid="​false">
<Key></Key>
<Value></Value>
</CacheEntry>
</Set>
<Set Id="1">
<CacheEntry isReferenced="​​false"isValid="​true">
<Key>1</Key>
<Value>value11_11_11</Value>
</CacheEntry>
<CacheEntry isReferenced="​​false"isValid="​false">
<Key></Key>
<Value></Value>
</CacheEntry>
<CacheEntry isReferenced="​​false"isValid="​false">
<Key></Key>
<Value></Value>
</CacheEntry>
<CacheEntry isReferenced="​​false"isValid="​false">
<Key></Key>
<Value></Value>
</CacheEntry>
<CacheEntry isReferenced="​​false"isValid="​false">
<Key></Key>
<Value></Value>
</CacheEntry>
<CacheEntry isReferenced="​​false"isValid="​false">
<Key></Key>
<Value></Value>
</CacheEntry>
<CacheEntry isReferenced="​​false"isValid="​false">
<Key></Key>
<Value></Value>
</CacheEntry>
<CacheEntry isReferenced="​​false"isValid="​false">
<Key></Key>
<Value></Value>
</CacheEntry>
</Set>
<Set Id="2">
<CacheEntry isReferenced="​​false"isValid="​false">
<Key>12</Key>
<Value>value12_12</Value>
</CacheEntry>
<CacheEntry isReferenced="​​false"isValid="​true">
<Key>13</Key>
<Value>value13_13</Value>
</CacheEntry>
<CacheEntry isReferenced="​​false"isValid="​true">
<Key>14</Key>
<Value>value14_14</Value>
</CacheEntry>
<CacheEntry isReferenced="​​true"isValid="​true">
<Key>12</Key>
<Value>value12_12</Value>
</CacheEntry>
<CacheEntry isReferenced="​​false"isValid="​false">
<Key></Key>
<Value></Value>
</CacheEntry>
<CacheEntry isReferenced="​​false"isValid="​false">
<Key></Key>
<Value></Value>
</CacheEntry>
<CacheEntry isReferenced="​​false"isValid="​false">
<Key></Key>
<Value></Value>
</CacheEntry>
<CacheEntry isReferenced="​​false"isValid="​false">
<Key></Key>
<Value></Value>
</CacheEntry>
</Set>
<Set Id="3">
<CacheEntry isReferenced="​​false"isValid="​true">
<Key>110</Key>
<Value>value111_110</Value>
</CacheEntry>
<CacheEntry isReferenced="​​false"isValid="​false">
<Key></Key>
<Value></Value>
</CacheEntry>
<CacheEntry isReferenced="​​false"isValid="​false">
<Key></Key>
<Value></Value>
</CacheEntry>
<CacheEntry isReferenced="​​false"isValid="​false">
<Key></Key>
<Value></Value>
</CacheEntry>
<CacheEntry isReferenced="​​false"isValid="​false">
<Key></Key>
<Value></Value>
</CacheEntry>
<CacheEntry isReferenced="​​false"isValid="​false">
<Key></Key>
<Value></Value>
</CacheEntry>
<CacheEntry isReferenced="​​false"isValid="​false">
<Key></Key>
<Value></Value>
</CacheEntry>
<CacheEntry isReferenced="​​false"isValid="​false">
<Key></Key>
<Value></Value>
</CacheEntry>
</Set>
</KVCache>
\ No newline at end of file
12,value12_12
13,value13_13
14,value14_14
File added
File added
File added
File added
File added
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include <pthread.h>
#include"kvstore.h"
#define MAXKEYSIZE 260
#define MAXVALUESIZE 262150
typedef struct data{
char key[MAXKEYSIZE];
char value[MAXVALUESIZE];
int chance;
int isReferenced;
int isfree;
// /struct data *next;
}cdata;
typedef struct SetLock{
pthread_mutex_t work_mutex;
//pthread_cond_t work_cond;
pthread_cond_t work_cond;
} SetLock;
SetLock *setLock;
struct data **kvc;
int *lastVisited;
int setValue( int len )
{
return len%sets;
}
void cacheInit(){
int i,j;
kvc=(struct data**)malloc(sets*(sizeof(struct data *)));
for(i=0;i<sets;i++)
{
*(kvc+i)=(struct data*)malloc(nway*sizeof(struct data ));
//You can use this also. Meaning of both is same.
//arr[i]=(int*)malloc(sizeof(int)*col);
}
setLock = (SetLock*) malloc(sets * sizeof(SetLock));
lastVisited = (int*)malloc(sets * sizeof(int));
for(i=0;i<sets;i++)
{
for(j=0;j<nway;j++)
{
lastVisited[i] = -1;
kvc[i][j].chance = 0;
kvc[i][j].isfree = 1;
kvc[i][j].isReferenced = 0;
// kvc[i][j].isfree = 1;
}
pthread_mutex_init(&(setLock[i].work_mutex), NULL);
}
}
int isPresent( int set , char key[]){
int i;
for( i =0 ; i<nway ; i++)
{
if(!strcmp(kvc[set][i].key , key) && kvc[set][i].chance != -1)
{
return i;
}
}
return -1;
}
void findSlot(int set , char key[] , char value[])
{
// printf("(%d)\n", lastVisited[set] );
int i, j =0;
// int counter = 10 ;
for(i= ((lastVisited[set]+1)%nway); j<nway ; j++ )
{
i = ( i + j ) % nway;
if( kvc[set][i].chance == 0 )
{
lastVisited[set] = i ;
// kvc[set][i].chance = 0;
strcpy (kvc[set][i].key , key);
strcpy (kvc[set][i].value , value);
kvc[set][i].isfree = 0;
// printf("success %s \t %s\n", kvc[set][i].key , kvc[set][i].value );
// printf("%d\t%dsuccess\n", );
return;
}
}
}
void updateCache(int set ,int pos ,char value[])
{
memset(kvc[set][pos].value , 0 , sizeof(kvc[set][pos].value));
strcpy (kvc[set][pos].value , value );
kvc[set][pos].isReferenced = 0;
//printf("updated %s \t %s\n", kvc[set][pos].key , kvc[set][pos].value );
}
int putData(char key[] , char value[])
{
int set = setValue(strlen(key ));
int pos = isPresent(set , key);
pthread_mutex_lock(&(setLock[set].work_mutex));
if(pos != -1)
{
updateCache( set , pos , value );
}
else{
findSlot(set , key , value);
}
writeRecordToFile(key , value);
pthread_mutex_unlock(&(setLock[set].work_mutex));
}
char * getData( char key[]){
int set = setValue(strlen(key));
int i;
pthread_mutex_lock(&(setLock[set].work_mutex));
for( i =0 ; i<nway ; i++)
{
if(!strcmp(kvc[set][i].key , key) && kvc[set][i].chance != -1 && kvc[set][i].isfree ==0)
{
// printf("\nCache Hit");
kvc[set][i].chance = 1;
kvc[set][i].isReferenced = 1;
pthread_mutex_unlock(&(setLock[set].work_mutex));
return kvc[set][i].value;
}
}
// printf("\ncache miss");
char* value = restoreFromFile(key);
if(value)
{
findSlot(set , key , value);
}
pthread_mutex_unlock(&(setLock[set].work_mutex));
return value;
}
int delData(char key[]){
int set = setValue(strlen(key));
pthread_mutex_lock(&(setLock[set].work_mutex));
int i;
for( i =0 ; i<nway ; i++)
{
if(!strcmp(kvc[set][i].key , key))
{
kvc[set][i].isfree = 1;
kvc[set][i].isReferenced = 0;
pthread_mutex_unlock(&(setLock[set].work_mutex));
return delRecord(key);
}
}
pthread_mutex_unlock(&(setLock[set].work_mutex));
return delRecord(key);
}
void toXML(char filename[])
{
FILE *outfile = fopen(filename, "w");
fprintf(outfile,"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\t<KVCache>\n");
for(int i=0; i<sets; i++)
{
fprintf(outfile, "\t\t<Set Id=\"%d\">\n", i);
for(int j=0; j<nway; j++)
{
fprintf(outfile, "\t\t\t<CacheEntry isReferenced=\"​");
if(kvc[i][j].isReferenced == 1)
fprintf(outfile, "​true\"");
else
fprintf(outfile, "​false\"");
if(kvc[i][j].isfree == 1)
fprintf(outfile, "​isValid=\"​false\">\n");
else
fprintf(outfile, "​isValid=\"​true\">\n");
fprintf(outfile, "\t\t\t\t<Key>%s</Key>\n", kvc[i][j].key);
fprintf(outfile, "\t\t\t\t<Value>%s</Value>\n", kvc[i][j].value);
fprintf(outfile, "\t\t\t</CacheEntry>\n");
}
fprintf(outfile, "\t\t</Set>\n");
}
fprintf(outfile,"\t</KVCache>");
fclose(outfile);
}
int sets = 4;
int nway = 8;
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "common.h"
typedef struct Data
{
char key[260];
char value[256*1024];
struct Data *next;
} DataNode;
DataNode *createNode(char key[], char value[]){
DataNode *temp; // declare a node
temp = (struct Data*)malloc(sizeof(struct Data)); // allocate memory using malloc()
temp->next = NULL;// make next point to NULL
strcpy(temp->key, key);
strcpy(temp->value, value);
return temp;//return the new node
}
void getFileName(char key[], char filename[])
{
char len[10];
snprintf(len, 10, "%ld", (strlen(key)%sets));
// len = len % sets
strcat(filename, len);
strcat(filename, ".csv");
}
void printFile(FILE *fp)
{
DataNode input;
while(fread(&input, sizeof(struct Data), 1, fp))
{
printf("%s - %s\n", input.key, input.value);
}
}
int delRecord(char key[])
{
FILE *infile;
FILE *outfile;
char infileName[50] = "ServerData/kvstore_setid_";
char outfileName[50] = "ServerData/temp_";
getFileName(key, infileName);
getFileName(key, outfileName);
infile = fopen (infileName, "r+");
if (infile == NULL)
{
//fprintf(stderr, "\nError opend file\n");
return -1;
}
outfile = fopen (outfileName, "w+");
if (outfile == NULL)
{
//fprintf(stderr, "\nError opend file\n");
return -1;
}
DataNode myrecord;
int found = 0;
// while (fread(&myrecord,sizeof(struct Data),1,infile)) {
// if (!strcmp (key, myrecord.key)) {
// // printf("A record with requested key found and deleted.\n\n");
// found=1;
// } else {
// fwrite(&myrecord, sizeof(struct Data), 1, outfile);
// }
// }
char buf[256*1025];
while(fgets(buf, 256*1025, infile))
{
char *keyTemp = (char *)strtok(buf, ",");
char *valueTemp = (char *)strtok(NULL, "\n");
if (!strcmp (key, keyTemp)) {
// printf("A record with requested key found and deleted.\n\n");
found=1;
} else {
// fwrite(&myrecord, sizeof(struct Data), 1, outfile);
fprintf(outfile,"%s,%s\n",keyTemp,valueTemp);
}
}
fclose(infile);
fclose(outfile);
remove(infileName);
rename(outfileName, infileName);
if (! found) {
// printf("No record(s) found with the requested key for Delete: %s\n\n", key);
return -1;
}
return 1;
}
int writeRecordToFile(char key[], char value[])
{
FILE *outfile;
// DataNode input;
// long num_rec = 1;
char filename[200] = "ServerData/kvstore_setid_";
getFileName(key, filename);
delRecord(key);
outfile = fopen (filename, "a+");
if (outfile == NULL)
{
fprintf(stderr, "\nError opend file\n");
return -1;
}
// strcpy(input.key, key);
// strcpy(input.value, value);
// fwrite (&input, sizeof(struct Data), 1, outfile);
fprintf(outfile,"%s,%s\n",key,value);
fclose(outfile);
//puts("Success in writing");
return 1;
}
char *restoreFromFile(char key[])
{
FILE *infile;
char filename[200] = "ServerData/kvstore_setid_";
getFileName(key, filename);
infile = fopen (filename, "r+");
if (infile == NULL)
{
//fprintf(stderr, "\nError opend file\n");
return NULL;
}
static DataNode input;
char buf[256*1025];
while(fgets(buf, 256*1025, infile))
{
char *keyTemp = (char *)strtok(buf, ",");
char *valueTemp = (char *)strtok(NULL, "\n");
if (!strcmp (key, keyTemp)) {
// printf("A record with requested key found and deleted.\n\n");
return valueTemp;
}
}
fclose(infile);
return NULL;
}
void dumpToFile(char filename[])
{
FILE *infile;
FILE *outfile = fopen(filename, "w");
if (outfile == NULL)
{
//fprintf(stderr, "\nError opend file\n");
return;
}
fprintf(outfile,"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\t<KVStore>\n");
for(int i=0; i<sets; i++)
{
char infileName[50];
sprintf(infileName, "ServerData/kvstore_setid_%d.csv", i);
infile = fopen(infileName, "r+");
if (infile == NULL)
{
//fprintf(stderr, "\nError opend file\n");
continue;
}
char buf[256*1025];
while(fgets(buf, 256*1025, infile))
{
char *keyTemp = (char *)strtok(buf, ",");
char *valueTemp = (char *)strtok(NULL, "\n");
fprintf(outfile,"\t\t<KVPair>\n\t\t\t<Key>​%s</Key>\n\t\t\t<Value>​%s</Value>\n\t\t</KVPair>\n",keyTemp,valueTemp);
}
fclose(infile);
}
fprintf(outfile,"\t</KVStore>");
fclose(outfile);
}
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <sys/socket.h>
#include "xmlParser.h"
#include "KVCache.h"
#define MAXKEYSIZE 260
#define MAXVALUESIZE 262150
void serveRequest(char buffer[], int *rc, int *fd)
{
char key[MAXKEYSIZE]={0}, value[MAXVALUESIZE]={0}, msg[50]={0}, msgType[10]={0};
ParseXML(msg, msgType, key, value, buffer);
char *response;
// printf("key - %ld\n",strlen(key));
// printf("msgType - %s\n",msgType);
// printf("key - %s\n",key);
// printf("value - %s\n\n",value);
int flag = -1;
if(strlen(key) > 256)
{
strcpy(msgType, "resp");
strcpy(msg, "Oversized key");
response = GenerateXML("", "", msg, msgType);
// puts(response);
}
else if(strlen(value) > 256*1024)
{
strcpy(msgType, "resp");
strcpy(msg, "Oversized value");
response = GenerateXML("", "", msg, msgType);
// puts(response);
}
else
{
if(!strcmp(msgType, "putreq"))
{
strcpy(msgType, "resp");
putData(key, value);
strcpy(msg, "Success");
response = GenerateXML("", "", msg, msgType);
// puts(response);
}
else if(!strcmp(msgType, "getreq"))
{
strcpy(msgType, "resp");
char *temp = getData(key);
if(temp)
{
strcpy(value, temp);
strcpy(msg, "");
}
else
{
strcpy(value, "");
strcpy(key, "");
strcpy(msg, "Does not exist");
}
response = GenerateXML(key, value, msg, msgType);
}
else if(!strcmp(msgType, "delreq"))
{
strcpy(msgType, "resp");
if(delData(key) == 1)
{
strcpy(msg, "Success");
}
else
{
strcpy(msg, "Does not exist");
}
response = GenerateXML("", "", msg, msgType);
}
}
response[strlen(response)] = '\0';
printf("ThreadID : %ld\n\n", pthread_self());
*rc = send(*fd, response, strlen(response), 0);
}
\ No newline at end of file
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <stdbool.h>
#include <stddef.h>
struct tpool;
typedef struct tpool tpool_t;
typedef void (*thread_func_t)(char *arg, int *rc, int *fd);
tpool_t *tpool_create(size_t num);
void tpool_destroy(tpool_t *tm);
bool tpool_add_work(tpool_t *tm, thread_func_t func, void *arg, void *rc, void *fd);
void tpool_wait(tpool_t *tm);
struct tpool_work {
thread_func_t func;
void *arg;
void *rc;
void *fd;
struct tpool_work *next;
};
typedef struct tpool_work tpool_work_t;
struct tpool {
tpool_work_t *work_first;
tpool_work_t *work_last;
pthread_mutex_t work_mutex;
pthread_cond_t work_cond;
pthread_cond_t working_cond;
size_t working_cnt;
size_t thread_cnt;
bool stop;
};
static tpool_work_t *tpool_work_create(thread_func_t func, void *arg, void *rc, void *fd)
{
tpool_work_t *work;
if (func == NULL)
return NULL;
work = malloc(sizeof(*work));
work->func = func;
work->arg = arg;
work->rc = rc;
work->fd = fd;
work->next = NULL;
return work;
}
static void tpool_work_destroy(tpool_work_t *work)
{
if (work == NULL)
return;
free(work);
}
static tpool_work_t *tpool_work_get(tpool_t *tm)
{
tpool_work_t *work;
if (tm == NULL)
return NULL;
work = tm->work_first;
if (work == NULL)
return NULL;
if (work->next == NULL) {
tm->work_first = NULL;
tm->work_last = NULL;
} else {
tm->work_first = work->next;
}
return work;
}
static void *tpool_worker(void *arg)
{
tpool_t *tm = arg;
tpool_work_t *work;
while (1) {
pthread_mutex_lock(&(tm->work_mutex));
if (tm->stop)
break;
if (tm->work_first == NULL)
pthread_cond_wait(&(tm->work_cond), &(tm->work_mutex));
work = tpool_work_get(tm);
tm->working_cnt++;
pthread_mutex_unlock(&(tm->work_mutex));
if (work != NULL) {
work->func(work->arg, work->rc, work->fd);
tpool_work_destroy(work);
}
pthread_mutex_lock(&(tm->work_mutex));
tm->working_cnt--;
if (!tm->stop && tm->working_cnt == 0 && tm->work_first == NULL)
pthread_cond_signal(&(tm->working_cond));
pthread_mutex_unlock(&(tm->work_mutex));
}
tm->thread_cnt--;
pthread_cond_signal(&(tm->working_cond));
pthread_mutex_unlock(&(tm->work_mutex));
return NULL;
}
tpool_t *tpool_create(size_t num)
{
tpool_t *tm;
pthread_t thread;
size_t i;
if (num == 0)
num = 2;
tm = calloc(1, sizeof(*tm));
tm->thread_cnt = num;
pthread_mutex_init(&(tm->work_mutex), NULL);
pthread_cond_init(&(tm->work_cond), NULL);
pthread_cond_init(&(tm->working_cond), NULL);
tm->work_first = NULL;
tm->work_last = NULL;
for (i=0; i<num; i++) {
pthread_create(&thread, NULL, tpool_worker, tm);
pthread_detach(thread);
}
return tm;
}
void tpool_destroy(tpool_t *tm)
{
tpool_work_t *work;
tpool_work_t *work2;
if (tm == NULL)
return;
pthread_mutex_lock(&(tm->work_mutex));
work = tm->work_first;
while (work != NULL) {
work2 = work->next;
tpool_work_destroy(work);
work = work2;
}
tm->stop = true;
pthread_cond_broadcast(&(tm->work_cond));
pthread_mutex_unlock(&(tm->work_mutex));
tpool_wait(tm);
pthread_mutex_destroy(&(tm->work_mutex));
pthread_cond_destroy(&(tm->work_cond));
pthread_cond_destroy(&(tm->working_cond));
free(tm);
}
bool tpool_add_work(tpool_t *tm, thread_func_t func, void *arg, void *rc, void *fd)
{
tpool_work_t *work;
if (tm == NULL)
return false;
work = tpool_work_create(func, arg, rc, fd);
if (work == NULL)
return false;
pthread_mutex_lock(&(tm->work_mutex));
if (tm->work_first == NULL) {
tm->work_first = work;
tm->work_last = tm->work_first;
} else {
tm->work_last->next = work;
tm->work_last = work;
}
pthread_cond_broadcast(&(tm->work_cond));
pthread_mutex_unlock(&(tm->work_mutex));
return true;
}
void tpool_wait(tpool_t *tm)
{
if (tm == NULL)
return;
pthread_mutex_lock(&(tm->work_mutex));
while (1) {
if ((!tm->stop && tm->working_cnt != 0) || (tm->stop && tm->thread_cnt != 0)) {
pthread_cond_wait(&(tm->working_cond), &(tm->work_mutex));
} else {
break;
}
}
pthread_mutex_unlock(&(tm->work_mutex));
}
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAXKEYSIZE 260
#define MAXVALUESIZE 262150
#define MAXBUFSIZE 264000
int GetXmlTagValueSpecific(char *RespBuffer, char *TagValue, char FirstTag[100], char SecondTag[100])
{
int len=0, pos = 0;
int PosFirstTag=0, PosSecondTag=0;
//check enter buffer
len = strlen(RespBuffer);
if (len<=0)
{
return -1;
}
//Get first tag position
for (pos=0; pos<len; pos++)
{
if ( !memcmp(FirstTag, RespBuffer+pos, strlen(FirstTag)) )
{
PosFirstTag = pos;
break;
}
}
//Get second tag position
for (pos=0; pos<len; pos++)
{
if ( !memcmp(SecondTag, RespBuffer+pos, strlen(SecondTag)) )
{
PosSecondTag = pos;
break;
}
}
if ( (PosFirstTag !=0) && (PosSecondTag !=0) )
{
if (PosSecondTag-PosFirstTag-strlen(FirstTag))
{
//Get tag value
memcpy( TagValue, RespBuffer+PosFirstTag+strlen(FirstTag), PosSecondTag-PosFirstTag-strlen(FirstTag) );
if (strlen(TagValue))
{
return 1;
}
}
}
return -1;
}
int GetXmlTagValue(char *RespBuffer, char *Tag, char *TagValue)
{
int len=0, pos = 0;
char FirstTag[100] = {0}; //First Tag
char SecondTag[100] = {0};//Second Tag
int PosFirstTag=0, PosSecondTag=0;
//check enter buffer
len = strlen(RespBuffer);
if (len<=0)
{
return -1;
}
//Create first Tag
memset(FirstTag, 0, sizeof(FirstTag));
strcpy(FirstTag, "<");
strcat(FirstTag, Tag);
strcat(FirstTag, ">");
//Create second tag
memset(SecondTag, 0, sizeof(SecondTag));
strcpy(SecondTag, "</");
strcat(SecondTag, Tag);
strcat(SecondTag, ">");
//Get first tag position
for (pos=0; pos<len; pos++)
{
if ( !memcmp(FirstTag, RespBuffer+pos, strlen(FirstTag)) )
{
PosFirstTag = pos;
break;
}
}
//Get second tag position
for (pos=0; pos<len; pos++)
{
if ( !memcmp(SecondTag, RespBuffer+pos, strlen(SecondTag)) )
{
PosSecondTag = pos;
break;
}
}
if ( (PosFirstTag !=0) && (PosSecondTag !=0) )
{
if (PosSecondTag-PosFirstTag-strlen(FirstTag))
{
//Get tag value
memcpy( TagValue, RespBuffer+PosFirstTag+strlen(FirstTag), PosSecondTag-PosFirstTag-strlen(FirstTag) );
if (strlen(TagValue))
{
return 1;
}
}
}
return -1;
}
void ParseXML(char msg[], char msgType[], char key[], char value[], char data[]){
//Tag name which value you want to access
char Tag[10] = {0};
char FirstTag[] = "<KVMessage type=\"";
char SecondTag[] = "\">";
//Buffer to store tag value
char TagValue[MAXBUFSIZE]= {0};
//Function to get tag value
GetXmlTagValueSpecific(data,TagValue, FirstTag, SecondTag);
strcpy(msgType, TagValue);
memset(Tag, 0, sizeof Tag);
strcpy(Tag, "Key");
memset(TagValue, 0, sizeof TagValue);
GetXmlTagValue(data,Tag, TagValue);
strcpy(key, TagValue);
// printf("%s : %ld\n",Tag, strlen(TagValue));
memset(Tag, 0, sizeof Tag);
strcpy(Tag, "Value");
memset(TagValue, 0, sizeof TagValue);
GetXmlTagValue(data,Tag, TagValue);
strcpy(value, TagValue);
// printf("%s : %s\n",Tag, TagValue);
memset(Tag, 0, sizeof Tag);
strcpy(Tag, "Message");
memset(TagValue, 0, sizeof TagValue);
GetXmlTagValue(data,Tag, TagValue);
strcpy(msg, TagValue);
// printf("%s : %s\n",Tag, TagValue);
}
char *GenerateXML(char key[], char value[], char msg[], char msgType[]){
char *response = (char *)malloc(MAXBUFSIZE * sizeof(char));
strcat(response, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
strcat(response, "<KVMessage type=\"");
strcat(response, msgType);
strcat(response, "\">");
if(strcmp(key, "") && strcmp(value, ""))
{
strcat(response,"<Key>");
strcat(response,key);
strcat(response,"</Key>");
strcat(response,"<Value>");
strcat(response,value);
strcat(response,"</Value>");
}
else if(strcmp(key, ""))
{
strcat(response,"<Key>");
strcat(response,key);
strcat(response,"</Key>");
}
else
{
strcat(response,"<Message>");
strcat(response,msg);
strcat(response,"</Message>");
}
strcat(response,"</KVMessage>");
return response;
}
\ No newline at end of file
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/wait.h>
#include <signal.h>
#include <errno.h>
#include <sys/select.h>
#include <sys/poll.h>
#include <sys/time.h>
#include <unistd.h>
#include "xmlParser.h"
#define MAXBUF 300000
char *toXML(char buffer[]){
char delim[] = " ";
char msgType[10] = {0};
char key[260] = {0};
char value[256*1024 + 10] = {0};
char *ptr = strtok(buffer, delim);
if(!strcmp(ptr, "PUT"))
{
strcpy(msgType, "putreq");
}
else if(!strcmp(ptr, "GET"))
{
strcpy(msgType, "getreq");
}
else if(!strcmp(ptr, "DEL"))
{
strcpy(msgType, "delreq");
}
else
{
printf("error in parsing");
// TODO specify error types
}
ptr = strtok(NULL, delim);
strcpy(key, ptr);
ptr = strtok(NULL, delim);
if(ptr)
strcpy(value, ptr);
else
strcpy(value, "");
char *response = GenerateXML(key, value, "", msgType);
response[strlen(response)] = '\0';
return response;
}
//WRITING RESPONSE IN THE FILE
void bufferDump(char resp[], FILE *optr)
{
char buffer[300000]="";
char key[256]={0}, value[256*1024]={0}, msg[50]={0}, msgType[10]={0};
ParseXML(msg, msgType, key, value, resp);
// strcat(buffer, msgType);
// strcat(buffer, " ");
if(!strcmp(msg, ""))
{
strcat(buffer, key);
strcat(buffer, " ");
strcat(buffer, value);
}
else
{
strcat(buffer, msg);
}
//strcat(buffer, "\0");
printf("%s\n",buffer);
fprintf(optr,"%s\n", buffer);
}
void main(int argc, char *argv[])
{
char msg[MAXBUF];
struct sockaddr_in addr = {0};
int n, sockfd,num=1;
// srandom(getpid());
/* Create socket and connect to server */
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd < 0)
{
puts("Network Error: Could not create socket");
exit(1);
}
int port = 8080;
char server_ip[20] = "127.0.0.1";
char inputfile[100] = "ClientData/batchRequest.txt";
char outputfile[100] = "ClientData/batchResponse.txt";
if(argc >= 2)
strcpy(server_ip, argv[1]);
if(argc >= 3)
port = atoi(argv[2]);
if(argc >= 4)
strcpy(inputfile, argv[3]);
if(argc >= 5)
strcpy(outputfile, argv[4]);
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = inet_addr(server_ip);
if(connect(sockfd, (struct sockaddr*)&addr, sizeof(addr)) == -1)
{
puts("Network Error: Could not connect");
exit(1);
}
printf("child {%d} connected \n", getpid());
FILE *iptr;
FILE *optr;
if ((iptr = fopen(inputfile, "r")) == NULL)
{
printf("Error! opening file");
// Program exits if file pointer returns NULL.
exit(1);
}
// sprintf(filename, "ClientData/clientResponses_%d.txt",getpid() );
if ((optr = fopen(outputfile, "a")) == NULL)
{
printf("Error! opening file");
// Program exits if file pointer returns NULL.
exit(1);
}
char buffer[300000];
while(fgets(buffer, 300000, iptr) != NULL){
char *buf = strtok(buffer, "\n");
printf("SENDING: %ld bytes\n", strlen(buf));
printf("===\n");
buf = toXML(buf);
// puts(buf);
write(sockfd, buf, strlen(buf));
// sleep(2);
char resp[300000];
int len = read(sockfd, resp, 300000);
resp[len] = '\0';
// puts(resp);
bufferDump(resp, optr);
// sleep(3);
// fclose(optr);
}
fclose(iptr);
fclose(optr);
}
\ No newline at end of file
#include<stdio.h>
#include<stdlib.h>
#include"KVCache.h"
int main()
{
// int i,j;
// kvc=(struct data**)malloc(sets*(sizeof(struct data *)));
// for(i=0;i<sets;i++)
// {
// *(kvc+i)=(struct data*)malloc(10*sizeof(struct data ));
// //You can use this also. Meaning of both is same.
// //arr[i]=(int*)malloc(sizeof(int)*col);
// }
// for(i=0;i<sets;i++)
// for(j=0;j<nway;j++)
// {
// lastVisited[i] = -1;
// kvc[i][j].chance = 0;
// kvc[i][j].isfree = 1;
// kvc[i][j].isReferenced = 0;
// // kvc[i][j].isfree = 1;
// }
cacheInit();
toXML("ServerData/CacheXML.xml");
}
// for(i=9; i < 12 ; i++)
// {
// for(j=0;j<nway; j++){
// if(kvc[i][j].isfree == 0)
// printf( "%s\t" , kvc[i][j].key );
// }
// printf("\n");
// }
// if(delData("thisiske22"))
// printf("(del_success)\n" );
// else
// printf("del_failed\n");
// for(i=9; i < 12 ; i++)
// {
// for(j=0;j<nway; j++){
// if(kvc[i][j].isfree == 0)
// printf( "%s\t" , kvc[i][j].key );
// }
// printf("\n");
// }
// char *newValue = getData("thisiskey6");
// if(newValue)
// puts(newValue);
// else
// puts("Not Found");
// for(i=9; i < 12 ; i++)
// {
// for(j=0;j<nway; j++){
// if(kvc[i][j].isfree == 0)
// printf( "%s\t" , kvc[i][j].key );
// }
// printf("\n");
// }
// putData("thisiskey6" , "thisiskeyvalue444444");
// putData("thisiske22" , "thisiskeyvalue1111111111111111111");
// newValue = getData("thisiskey6");
// if(newValue)
// puts(newValue);
// else
// puts("Not Found");
//}
#include "kvstore.h"
#include <stdio.h>
#include <string.h>
DataNode *head;
// extern int sets;
// extern int nway;
// sets = 256;
// nway = 10;
void main()
{
// head = createNode("thisisnewkey0", "thisisnewvalue");
// head->next = createNode("thisisnewkey00", "thisisnewvalue");
// head->next->next = createNode("thisisnewkey000", "thisisnewvalue");
// writeRecordToFile("thisisnewkey0", "thisisnewvalue");
// writeRecordToFile("thisisnewkey0", "thisisnewvalueupdated");
// writeRecordToFile("thisisnewkey0", "thisisndsfffffffffffffffffffffffewvalueupdated");
// writeRecordToFile("thisisnewkey22", "thisisnewvalue");
// writeRecordToFile("thisisnewkey333", "thisisnewvalue");
// writeRecordToFile("thisisnewkey334", "thisisnewvalue");
// writeRecordToFile("thisisnewkey7", "thisisnewvalue77676767676");
// char *node;
// node = restoreFromFile("thisisnewkey7");
// if(node)
// printf("%s\n", node);
// else
// puts("Not Found");
dumpToFile("ServerData/StoreXML.xml");
// delRecord("thisisnewkey333");
// node = restoreFromFile("thisisnewkey333");
// if(node)
// printf("%s\n", node);
// else
// puts("Not Found");
// FILE *fp = fopen ("ServerData/kvstore_13.dat", "r+b");
// printFile(fp);
// fclose(fp);
}
\ No newline at end of file
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/poll.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <errno.h>
#include <string.h>
#include "threadpool.h"
#include "serveRequest.h"
#define MAXKEYSIZE 260
#define MAXVALUESIZE 262150
#define MAXBUFSIZE 264000
//#ifndef
#define CACHEPRINT 1
//ss#endif
#define TRUE 1
#define FALSE 0
size_t num_threads = 4;
void main (int argc, char *argv[])
{
int len, rc, on = 1;
int listen_sd = -1, new_sd = -1;
int desc_ready, end_server = FALSE, compress_array = FALSE;
int close_conn;
char buffer[MAXBUFSIZE];
struct sockaddr_in addr;
int timeout;
struct pollfd fds[200];
int nfds = 2, current_size = 0, i, j;
int port = 8080;
if(argc >= 2)
port = atoi(argv[1]);
if(argc >= 3)
sets = atoi(argv[2]);
if(argc >= 4)
nway = atoi(argv[3]);
if(argc >= 5)
num_threads = atoi(argv[4]);
cacheInit();
tpool_t *tm;
tm = tpool_create(num_threads);
listen_sd = socket(AF_INET, SOCK_STREAM, 0);
if (listen_sd < 0)
{
perror("Network Error: Could not create socket");
exit(-1);
}
rc = setsockopt(listen_sd, SOL_SOCKET, SO_REUSEADDR,
(char *)&on, sizeof(on));
if (rc < 0)
{
perror("setsockopt() failed");
close(listen_sd);
exit(-1);
}
rc = ioctl(listen_sd, FIONBIO, (char *)&on);
if (rc < 0)
{
perror("ioctl() failed");
close(listen_sd);
exit(-1);
}
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
//memcpy(&addr.sin_addr, &INADDR_ANY, sizeof(INADDR_ANY));
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = htons(port);
rc = bind(listen_sd,
(struct sockaddr *)&addr, sizeof(addr));
if (rc < 0)
{
perror("bind() failed");
close(listen_sd);
exit(-1);
}
rc = listen(listen_sd, 32);
if (rc < 0)
{
perror("listen() failed");
close(listen_sd);
exit(-1);
}
memset(fds, 0 , sizeof(fds));
fds[0].fd = listen_sd;
fds[0].events = POLLIN;
timeout = (30 * 1000);
do
{
printf("Waiting on poll()...\n");
rc = poll(fds, nfds, timeout);
if (rc < 0)
{
perror(" poll() failed");
break;
}
if (rc == 0)
{
printf(" poll() timed out. End program.\n");
break;
}
current_size = nfds;
for (i = 0; i < current_size; i++)
{
if(fds[i].revents == 0)
continue;
if(fds[i].revents != POLLIN)
{
printf(" Error! revents = %d\n", fds[i].revents);
// end_server = TRUE;
// break;
}
if (fds[i].fd == listen_sd)
{
printf(" Listening socket is readable\n");
do
{
new_sd = accept(listen_sd, NULL, NULL);
if (new_sd < 0)
{
if (errno != EWOULDBLOCK)
{
perror(" accept() failed");
// end_server = TRUE;
}
// break;
}
printf(" New incoming connection - %d\n", new_sd);
fds[nfds].fd = new_sd;
fds[nfds].events = POLLIN;
nfds++;
} while (new_sd != -1);
}
else
{
printf(" Descriptor %d is readable\n", fds[i].fd);
close_conn = FALSE;
// do
// {
memset(buffer, 0, sizeof(buffer));
rc = recv(fds[i].fd, buffer, sizeof(buffer), 0);
if (rc < 0)
{
if (errno != EWOULDBLOCK)
{
perror(" recv() failed");
close_conn = TRUE;
}
//break;
}
else if (rc == 0)
{
printf(" Connection closed\n");
close_conn = TRUE;
// break;
}
else
{
len = rc;
printf(" %d bytes received\n", len);
tpool_add_work(tm, serveRequest, buffer, &rc, &fds[i].fd);
usleep(1000);
if (rc < 0)
{
perror(" send() failed");
close_conn = TRUE;
}
}
// } while(TRUE);
if (close_conn)
{
close(fds[i].fd);
fds[i].fd = -1;
compress_array = TRUE;
}
} /* End of existing connection is readable */
} /* End of loop through pollable descriptors */
if (compress_array)
{
compress_array = FALSE;
for (i = 0; i < nfds; i++)
{
if (fds[i].fd == -1)
{
for(j = i; j < nfds; j++)
{
fds[j].fd = fds[j+1].fd;
}
i--;
nfds--;
}
}
}
} while (end_server == FALSE); /* End of serving running. */
tpool_wait(tm);
tpool_destroy(tm);
for (i = 0; i < nfds; i++)
{
if(fds[i].fd >= 0)
close(fds[i].fd);
}
#ifdef CACHEPRINT
toXML("ServerData/CacheXML.xml");
#endif
}
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
// #include "KVCache.h"
#include "threadpool.h"
#include "serveRequest.h"
static const size_t num_threads = 1;
static const size_t num_items = 10;
// void worker(void *arg)
// {
// // int *val = arg;
// char *val = arg;
// //int old = *val;
// //*val += 1000;
// printf("tid=%ld, val=%s\n", pthread_self(), val);
// // if (*val%2)
// // usleep(100000);
// }
void worker(char *arg, char **arg2)
{
// int *val = arg;
// char *val = arg;
//int old = *val;
static int c =0;
//*val += 1000;
char *temp = (char *)malloc(30*sizeof(char));
strcpy(temp, "new data");
printf("tid=%ld\n", pthread_self());
// strcpy(arg, "go to hell");
// printf("tid=%ld, val=%s\n", pthread_self(), arg);
temp[strlen(temp)] = '\0';
*arg2 = temp;
c++;
//if (c%2)
//usleep(100000);
}
int main(int argc, char **argv)
{
tpool_t *tm;
int *vals;
size_t i;
cacheInit();
tm = tpool_create(num_threads);
vals = calloc(num_items, sizeof(*vals));
char buffer[] = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><KVMessage type=\"putreq\"><Key>333</Key><Value>value111_111</Value></KVMessage>";
char *tempBuffer;
for (i=0; i<num_items; i++) {
vals[i] = i;
tpool_add_work(tm, serveRequest, buffer, &tempBuffer);
}
usleep(100);
tpool_wait(tm);
for (i=0; i<num_items; i++) {
printf("%d from main function: %s\n",i, tempBuffer);// printf("%d\n", vals[i]);
}
free(vals);
tpool_destroy(tm);
return 0;
}
\ No newline at end of file
#include "xmlParser.h"
void main()
{
char key[100], value[100], msg[100], msgType[100];
char *resp = GenerateXML("", "", "thisismsg", "thisismsgtype");
printf("%s\n", resp);
ParseXML(msg, msgType, key, value, resp);
printf("\nKey: %s\n", key);
printf("Value: %s\n", value);
printf("Msg: %s\n", msg);
printf("MsgType: %s\n", msgType);
}
\ 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