Commit 402105da authored by Samarth Joshi's avatar Samarth Joshi

Removing commented code

parent 2a0b2d19
No preview for this file type
...@@ -14,21 +14,7 @@ client library interfaces to do the actual operations. ...@@ -14,21 +14,7 @@ client library interfaces to do the actual operations.
#define SA struct sockaddr #define SA struct sockaddr
#include "KVClientLibrary.c" #include "KVClientLibrary.c"
struct message* requestMessage; struct message* requestMessage;
void func(int sockfd,struct message* requestMessage)
{
char buff[MAX];
int n=0;
for (;;) {
bzero(buff, sizeof(buff));
if(1)
{
n++;
printf("[Message sent to server]\n[[Status:%c]\n[Key:%s]\n[Value:%s]]\n",requestMessage->status,requestMessage->key,requestMessage->value);
write(sockfd, requestMessage, sizeof(struct message));
sleep(2);
}
}
}
int main(int argc, char const *argv[]) int main(int argc, char const *argv[])
{ {
int sock = 0, valread; int sock = 0, valread;
...@@ -59,9 +45,12 @@ int main(int argc, char const *argv[]) ...@@ -59,9 +45,12 @@ int main(int argc, char const *argv[])
char key[256]="abc"; char key[256]="abc";
char value[256]="cde"; char value[256]="cde";
char error[256]; char error[256];
printf("%d",(int)put(sock,key, value,error)); //printf("%d",(int)put(sock,key, value,error));
printf("%d",(int)del(sock,key,error)); //printf("%d",(int)del(sock,key,error));
printf("%d",(int)get(sock,key, value,error)); //printf("%d",(int)get(sock,key, value,error));
while (1) {
printf("%d",(int)put(sock, key, value, error));
}
return 0; return 0;
} }
\ No newline at end of file
No preview for this file type
/*
KVServer will consist of a main thread that will perform the following steps:
1. It will read a config file and set up a listening socket on a port specified in the config file.
2. Create n threads at startup which will be specified in the config file.
3. Perform accept() on the listening socket and pass each established connection to one of
the n threads in a round robin fashion. For example, the first connection is passed on to
the first thread of those n thread for processing, and so on.
The KVServer will also have worker threads that are responsible for the following actions:
1. Each worker thread will set up and monitor an epoll context for the set of connections it
is responsible for.
2. It runs an infinite loop that will monitor its client connections for work (in addition, if there
are new connections for the thread, it must add it to the epoll context). After reading
requests from clients, it will process those requests, and write a response back to the
client.
Key Value Cache: The server will have limited memory (specified via a config file parameter
that lays out how many key value entries the server is allowed to hold in memory) and so this
will serve as cache to the files that will hold the persistent representation of the data. The cache
will be a fully associative cache (flat structure) with two possible replacement/eviction policies:
a. LRU:
b. LFU: Least Frequently used
Dirty entries evicted from this cache will have to be written out to the persistent representation
which will be a file. You are free to use locality to evict more than one entry and bring in
additional entries by locality to drive performance.
Persistence: All keys and corresponding values are stored on disk in files. How you organize
the keys into files is up to you. We suggest that you keep keys that are “close” to each other in a
single file. You also need to think about how keys are arranged in a file - if you want to read in
one key (and corresponding value), you should do a lseek to the specific place in the file
where the key will be. The meta data about key positions and files that exist can be in memory -
think about using bitmaps.
Interfaces:
● Your key-value server will support 3 interfaces:
1. Value GET (Key k): Retrieves the key-value pair corresponding to the provided key.
2. PUT (Key k, Value v): Inserts/Overwrites the key-value pair into the store.
3. DEL( Key k): Removes the key-value pair corresponding to the provided key from the
store.
● You must use the exact request/response formats defined later in the specification for
communication between external and internal components.
● 'Keys' and 'values' are always strings with non-zero lengths. They cannot be nulls either.
● Each key and value cannot be greater than 256 bytes . If the size is breached, return an
error. (Assume each character to be 1 byte in size)
● When PUTing a key-value pair, if the key already exists, then the value is overwritten.
● When GETing a value, if the key does not exist, return an error message.
● You should ensure the following synchronization properties in your key-value service:
1. Reads (GETs) and updates (PUTs and DELETEs) are atomic.
2. An update consists of modifying a (key, value) entry in both the cache and
persistent representation (you can choose to do this lazily).
3. Do NOT lock the entire cache for each write. Only lock that entry so that
operations on other keys can proceed in parallel. If you do use locks, use multiple
readers single writer locks for efficiency.
KVClient
*/
#include <stdio.h> #include <stdio.h>
#include <pthread.h> #include <pthread.h>
#include <stdlib.h> #include <stdlib.h>
...@@ -82,6 +20,8 @@ void *worker(void *args) { ...@@ -82,6 +20,8 @@ void *worker(void *args) {
int epollfd; int epollfd;
int *newfd=malloc(sizeof(int)); int *newfd=malloc(sizeof(int));
char *name = (char *) malloc(5 * sizeof(char));
epollfd = epoll_create1(0); epollfd = epoll_create1(0);
if (epollfd == -1) { if (epollfd == -1) {
perror("epoll_create1"); perror("epoll_create1");
...@@ -105,32 +45,23 @@ void *worker(void *args) { ...@@ -105,32 +45,23 @@ void *worker(void *args) {
} }
for ( i= 0; i < nfds; ++i ) { for ( i= 0; i < nfds; ++i ) {
if (events[i].data.fd == read_pipe) { if (events[i].data.fd == read_pipe) {
/* if we get a request from main thread to add new client /* if we get a request from main thread to add new client */
ie. events[i].data.fd is equal to the pipe which we use to talk with main thread
- read this newfd from pipe
- add this newfd to epoll instance to monitor for client requests
*/
read(read_pipe, newfd, sizeof(newfd)); read(read_pipe, newfd, sizeof(newfd));
printf("\nread %d\n", *newfd); printf("[%s] read %d\n", name, *newfd);
ev.data.fd=*newfd; ev.data.fd=*newfd;
ev.events = EPOLLIN | EPOLLRDHUP; ev.events = EPOLLIN | EPOLLRDHUP;
if (epoll_ctl(epollfd, EPOLL_CTL_ADD, *newfd, &ev) == -1) { if (epoll_ctl(epollfd, EPOLL_CTL_ADD, *newfd, &ev) == -1) {
perror("epoll_ctl: read_pipe"); perror("epoll_ctl: read_pipe");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
} else { } else {
/* if we get a request from client /* if we get a request from client (GET, PUSH, DEL) */
ie. events[i].data.fd is equal to the client socket fd
*/
int flag = events[i].events; int flag = events[i].events;
if (flag & EPOLLRDHUP) { if (flag & EPOLLRDHUP) {
/* Connection was closed. /* Connection was closed. */
- Remove socket from epoll instance
- Close the socket and dont process more info from this socket
Note: This if block should be before EPOLLIN
*/
epoll_ctl( epollfd, EPOLL_CTL_DEL, events[i].data.fd , NULL ); epoll_ctl( epollfd, EPOLL_CTL_DEL, events[i].data.fd , NULL );
close(events[i].data.fd); close(events[i].data.fd);
continue; continue;
...@@ -158,21 +89,19 @@ void *worker(void *args) { ...@@ -158,21 +89,19 @@ void *worker(void *args) {
int main (int argc, int argv) { int main (int argc, int argv) {
int i; int i;
int next = 0; // to decide which worker thread to assign client in round robin fashion int next_thread_to_assign = 0;
pthread_t *threads; // set of all worker threads pthread_t *worker_threads;
int pool_thread_size = 1; // TODO: get pool thread size from config file int pool_thread_size = 5; // TODO: get pool thread size from config file
int sockfd, newsockfd, portno, clilen, n; int sockfd, newsockfd, portno, clilen, n;
struct sockaddr_in serv_addr, cli_addr; struct sockaddr_in serv_addr, cli_addr;
//int *pipes = (int*) malloc(pool_thread_size * 2 * sizeof(pipes)); //int *pipes = (int*) malloc(pool_thread_size * 2 * sizeof(pipes));
int pipes[5][2]; // TODO: initialize pipes dynamically int pipes[5][2]; // TODO: initialize pipes dynamically
// initialize thread pool with initial pool size worker_threads = malloc(pool_thread_size * sizeof(pthread_t));
threads = malloc(pool_thread_size * sizeof(pthread_t));
for( i=0; i < pool_thread_size; i++ ) { for( i=0; i < pool_thread_size; i++ ) {
pipe(pipes[i]); pipe(pipes[i]);
pthread_create( &threads[i], NULL, worker, &pipes[i]); pthread_create( &worker_threads[i], NULL, worker, &pipes[i]);
} }
sockfd = socket(AF_INET, SOCK_STREAM, 0); sockfd = socket(AF_INET, SOCK_STREAM, 0);
...@@ -202,101 +131,12 @@ int main (int argc, int argv) { ...@@ -202,101 +131,12 @@ int main (int argc, int argv) {
if (newsockfd < 0) if (newsockfd < 0)
perror("ERROR on accept"); perror("ERROR on accept");
write(pipes[next][1], &newsockfd, sizeof(newsockfd)); write(pipes[next_thread_to_assign][1], &newsockfd, sizeof(newsockfd));
printf("main thread value: %d\n",newsockfd); printf("main thread value: %d\n",newsockfd);
fflush(stdout); fflush(stdout);
next = (next+1) % pool_thread_size; next_thread_to_assign = (next_thread_to_assign+1) % pool_thread_size;
} }
return 0; return 0;
} }
/* \ No newline at end of file
#include <stdio.h>
#include <netdb.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include "KVMessageFormat.h"
#define MAX 80
#define PORT 6969
#define SA struct sockaddr
// Function designed for chat between client and server.
void func(int sockfd)
{
printf("receive functions:");
char buff[ sizeof(struct message)];
int n;
struct message* requestMessage=malloc(sizeof(struct message));
// infinite loop for chat
// read the message from client and copy it in buffer
read( sockfd , buff, sizeof(struct message));
// print buffer which contains the client contents
printf("From client: %c\t To client : ", buff[0]);
}
// Driver function
int main(int argc, char const *argv[])
{
int server_fd, new_socket, valread;
struct sockaddr_in address;
int opt = 1;
int addrlen = sizeof(address);
char buffer[1024] = {0};
char *hello = "Hello from server";
// Creating socket file descriptor
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0)
{
perror("socket failed");
exit(EXIT_FAILURE);
}
// Forcefully attaching socket to the port 8080
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT,
&opt, sizeof(opt)))
{
perror("setsockopt");
exit(EXIT_FAILURE);
}
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons( PORT );
// Forcefully attaching socket to the port 8080
if (bind(server_fd, (struct sockaddr *)&address,
sizeof(address))<0)
{
perror("bind failed");
exit(EXIT_FAILURE);
}
if (listen(server_fd, 3) < 0)
{
perror("listen");
exit(EXIT_FAILURE);
}
if ((new_socket = accept(server_fd, (struct sockaddr *)&address,
(socklen_t*)&addrlen))<0)
{
perror("accept");
exit(EXIT_FAILURE);
}
struct message *requestMessage= malloc(sizeof(struct message));
valread = read( new_socket , requestMessage, sizeof(struct message));
printf("[Message Received from client]\n[[Status:%c]\n[Key:%s]\n[Value:%s]]",requestMessage->status,requestMessage->key,requestMessage->value);
struct message *replyMessage=malloc(sizeof(struct message));
replyMessage->status='0';
char buff[256]="success";
memcpy(replyMessage->key,buff,256);
replyMessage->value[0]='\0';
send(new_socket , replyMessage , sizeof(struct message) , 0 );
printf("\n[Message sent to client]\n[[Status:%c]\n[Key:%s]\n[Value:%s]]",replyMessage->status,replyMessage->key,replyMessage->value);
return 0;
}
*/
\ 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