Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <time.h>
- #include <string.h>
- #include <pthread.h>
- #include <assert.h>
- #include <limits.h>
- #include <stdint.h>
- #define TRUE 1
- #define FALSE 0
- #define STOREDATA 1
- #define RETRIEVEITEM 2
- #define DELETEITEM 3
- #define FLUSHALL 4
- #define EXIT 5
- //Resource String.
- static char resTitle[]="=========== Memcache ===========\n";
- static char resOption1st[]="1) Store data";
- static char resOption2nd[]="2) Retrieve item";
- static char resOption3rd[]="3) Delete item";
- static char resOption4th[]="4) Flush all existing items";
- static char resOption5th[]="5) Exit the program.";
- static char resEnterChoice[]="\nEnter your choice: ";
- static char resEnterKey[]="Enter your key: ";
- static char resEnterVariable[]="Enter your variable: ";
- static char resEnterExpireTime[]="Enter expire time: ";
- static char resGetData[]="Your data is: %s";
- static char resStoreSuccess[]="Store data success with key '%s', "
- "using on-the-fly compression expire time is %d seconds";
- static char resStoreForever[]="Store data success with key '%s', "
- "using on-the-fly compression.";
- static char resReEnterTime[]="The number of seconds may not exceed 2592000 "
- "and bigger than 0\n.";
- static char resDeleteSuccess[]="Delete success.";
- static char resFlushSuccess[]="Success\n";
- static char resDataNotExist[]="The data with key '%s' does not exist.";
- static char resDataExpired[]="The data was expired and removed from memory.";
- //Data define
- static int memSize=1009;
- typedef struct dataForm{
- char *key;
- char *value;
- time_t expireTime;
- };
- typedef struct hashNode{
- int nodeCount;
- struct dataForm ** node;
- };
- static struct hashNode * hashTable[1009];
- //Function define
- unsigned long hash(unsigned char *str);
- void storeData(unsigned char *strKey,struct dataForm * data );
- void startService();
- struct dataForm * retrieveData(unsigned char *strKey);
- struct dataForm* makeDataForm(char* key,char *value,long expireTime);
- time_t getCurrentTime();
- int deleteData(unsigned char *strKey);
- void* refresh();
- void flushData();
- void initHashTable();
- void initThread();
- void* refresh(){
- while(TRUE){
- int i=0;
- for (i=0;i<1009;++i){
- int count=hashTable[i]->nodeCount;
- int j;
- for(j=0;j<count;++j){
- if (hashTable[i]->node[j]==0)
- continue;
- if (hashTable[i]->node[j]->expireTime<getCurrentTime()){
- hashTable[i]->node[j]->expireTime=UINT32_MAX;
- }
- }
- }
- }
- }
- unsigned long hash(unsigned char *str){
- unsigned long hash = 5381;
- int c;
- while (c = *str++)
- hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
- return hash%memSize;
- }
- void storeData(unsigned char *strKey,struct dataForm * data ){
- int key=hash(strKey);
- int index=0;
- //Check collision
- int count =hashTable[key]->nodeCount;
- int i;
- int size=0;
- for(i=0;i<count;++i){
- if (strcmp(hashTable[key]->node[i]->key,strKey)==0){
- hashTable[key]->node[i]=data;
- return 0;
- };
- }
- hashTable[key]->nodeCount++;
- realloc(hashTable[key]->node,(count+1)*sizeof(struct hashNode*));
- realloc(hashTable[key]->node[count+1],(count+1)*sizeof(struct dataForm*));
- hashTable[key]->node[count]=data;
- }
- int deleteData(unsigned char *strKey){
- int index=0;
- int hashKey=hash(strKey);
- int count =hashTable[hashKey]->nodeCount;
- for (index=0;index<count;++index){
- if(hashTable[hashKey]->node[index]==0)
- continue;
- if (strcmp(hashTable[hashKey]->node[index]->key,strKey)==0){
- hashTable[hashKey]->node[index]=0;
- return 0;
- }
- }
- }
- struct dataForm * retrieveData(unsigned char *strKey){
- int index=0;
- int hashKey=hash(strKey);
- int count =hashTable[hashKey]->nodeCount;
- for (index=0;index<count;++index){
- if(hashTable[hashKey]->node[index]==0)
- continue;
- if (strcmp(hashTable[hashKey]->node[index]->key,strKey)==0){
- return hashTable[hashKey]->node[index];
- }
- }
- return 0;
- }
- struct dataForm* makeDataForm(char *key,char *data,time_t expireTime){
- struct dataForm*x=malloc(sizeof(struct dataForm)+1);
- x->value=malloc(strlen(data)+1);
- x->key=malloc(strlen(key)+1);
- strcpy((*x).key,key);
- strcpy((*x).value,data);
- (*x).expireTime=expireTime;
- return x;
- }
- void flushData(){
- int i=0;
- for (i=0;i<1009;++i){
- int count=hashTable[i]->nodeCount;
- int j;
- for(j=0;j<count;++j){
- deleteData(hashTable[i]->node[j]->key);
- }
- }
- }
- time_t getCurrentTime(){
- time_t t;
- time(&t);
- return t;
- }
- void initHashTable(){
- int i=0;
- for (int i=0;i<1009;++i){
- hashTable[i]=malloc(sizeof(struct hashNode));
- hashTable[i]->node=malloc(sizeof(struct hashNode*));
- hashTable[i]->nodeCount=0;
- }
- }
- void initThread(){
- pthread_t *thread;
- int result_code = pthread_create(thread, NULL, refresh, NULL);
- }
- void startService(){
- memset(hashTable,0,sizeof(struct hashNode*)*memSize);
- initHashTable();
- initThread();
- puts(resTitle);
- puts(resOption1st);
- puts(resOption2nd);
- puts(resOption3rd);
- puts(resOption4th);
- puts(resOption5th);
- int choice;
- char key[51];
- char data[101];
- struct dataForm *retrieved;
- while(TRUE){
- printf(resEnterChoice);
- scanf("%d",&choice);
- fpurge(stdin);
- switch(choice){
- case STOREDATA:
- printf(resEnterKey);
- fgets(key,50,stdin);
- strtok(key, "\n");
- printf(resEnterVariable);
- fgets(data,100,stdin);
- strtok(data, "\n");
- printf(resEnterExpireTime);
- int expireTime;
- scanf("%d",&expireTime);
- while (expireTime>2592000 ||expireTime<0){
- printf(resReEnterTime);
- printf(resEnterExpireTime);
- scanf("%d",&expireTime);
- }
- int currentTime=getCurrentTime();
- if (expireTime==0)
- currentTime=0;
- storeData(key,makeDataForm(key,data,expireTime+currentTime));
- if (expireTime!=0)
- printf(resStoreSuccess,key,expireTime);
- else
- printf(resStoreForever,key);
- break;
- case RETRIEVEITEM:
- printf(resEnterKey);
- fgets(key,50,stdin);
- strtok(key, "\n");
- retrieved=retrieveData(key);
- if (retrieved==NULL){
- printf(resDataNotExist,key);
- } else if(retrieved->expireTime ==UINT32_MAX){
- printf(resDataExpired);
- deleteData(key);
- } else {
- printf(resGetData,retrieved->value);
- }
- break;
- case DELETEITEM:
- printf(resEnterKey);
- fgets(key,50,stdin);
- strtok(key, "\n");
- deleteData(key);
- printf(resDeleteSuccess);
- break;
- case FLUSHALL:
- flushData();
- printf(resFlushSuccess);
- break;
- case EXIT:
- exit(0);
- break;
- }
- }
- }
- int main(int argc, char** argv) {
- startService();
- return (EXIT_SUCCESS);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement