Advertisement
finalshare

MEMCACHE.C

Feb 8th, 2018
477
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.66 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <time.h>
  4. #include <string.h>
  5. #include <pthread.h>
  6. #include <assert.h>
  7. #include <limits.h>
  8. #include <stdint.h>
  9.  
  10. #define TRUE 1
  11. #define FALSE 0
  12.  
  13. #define STOREDATA 1
  14. #define RETRIEVEITEM 2
  15. #define DELETEITEM 3
  16. #define FLUSHALL 4
  17. #define EXIT 5
  18.  
  19. //Resource String.
  20. static char resTitle[]="=========== Memcache ===========\n";
  21. static char resOption1st[]="1)  Store data";
  22. static char resOption2nd[]="2)  Retrieve item";
  23. static char resOption3rd[]="3)  Delete item";
  24. static char resOption4th[]="4)  Flush all existing items";
  25. static char resOption5th[]="5)  Exit the program.";
  26.  
  27. static char resEnterChoice[]="\nEnter your choice: ";
  28. static char resEnterKey[]="Enter your key: ";
  29. static char resEnterVariable[]="Enter your variable: ";
  30. static char resEnterExpireTime[]="Enter expire time: ";
  31.  
  32. static char resGetData[]="Your data is: %s";
  33. static char resStoreSuccess[]="Store data success with key '%s', "
  34. "using on-the-fly compression expire time is %d seconds";
  35. static char resStoreForever[]="Store data success with key '%s', "
  36. "using on-the-fly compression.";
  37. static char resReEnterTime[]="The number of seconds may not exceed 2592000 "
  38. "and bigger than 0\n.";
  39.  
  40. static char resDeleteSuccess[]="Delete success.";
  41. static char resFlushSuccess[]="Success\n";
  42.  
  43. static char resDataNotExist[]="The data with key '%s' does not exist.";
  44. static char resDataExpired[]="The data was expired and removed from memory.";
  45. //Data define
  46.  
  47. static int memSize=1009;
  48. typedef struct dataForm{
  49.     char *key;
  50.     char *value;
  51.     time_t expireTime;
  52. };
  53. typedef struct hashNode{
  54.     int nodeCount;
  55.     struct dataForm ** node;
  56. };
  57. static struct hashNode * hashTable[1009];
  58.  
  59. //Function define
  60. unsigned long hash(unsigned char *str);
  61. void storeData(unsigned char *strKey,struct dataForm * data );
  62. void startService();
  63. struct dataForm * retrieveData(unsigned char *strKey);
  64. struct dataForm* makeDataForm(char* key,char *value,long expireTime);
  65. time_t getCurrentTime();
  66. int deleteData(unsigned char *strKey);
  67. void* refresh();
  68. void flushData();
  69. void initHashTable();
  70. void initThread();
  71.  
  72.  
  73. void* refresh(){
  74.     while(TRUE){
  75.         int i=0;
  76.         for (i=0;i<1009;++i){
  77.             int count=hashTable[i]->nodeCount;
  78.             int j;
  79.             for(j=0;j<count;++j){
  80.                 if (hashTable[i]->node[j]==0)
  81.                     continue;
  82.                 if (hashTable[i]->node[j]->expireTime<getCurrentTime()){
  83.                     hashTable[i]->node[j]->expireTime=UINT32_MAX;
  84.                 }
  85.             }
  86.         }
  87.     }
  88. }
  89. unsigned long hash(unsigned char *str){
  90.     unsigned long hash = 5381;
  91.     int c;
  92.  
  93.     while (c = *str++)
  94.         hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
  95.  
  96.     return hash%memSize;
  97. }
  98. void storeData(unsigned char *strKey,struct dataForm * data ){
  99.     int key=hash(strKey);
  100.     int index=0;
  101.     //Check collision
  102.     int count =hashTable[key]->nodeCount;
  103.     int i;
  104.     int size=0;
  105.     for(i=0;i<count;++i){
  106.         if (strcmp(hashTable[key]->node[i]->key,strKey)==0){
  107.             hashTable[key]->node[i]=data;
  108.             return 0;
  109.         };      
  110.     }
  111.     hashTable[key]->nodeCount++;
  112.     realloc(hashTable[key]->node,(count+1)*sizeof(struct hashNode*));
  113.     realloc(hashTable[key]->node[count+1],(count+1)*sizeof(struct dataForm*));
  114.     hashTable[key]->node[count]=data;
  115. }
  116. int deleteData(unsigned char *strKey){
  117.     int index=0;
  118.     int hashKey=hash(strKey);
  119.     int count =hashTable[hashKey]->nodeCount;
  120.     for (index=0;index<count;++index){
  121.         if(hashTable[hashKey]->node[index]==0)
  122.             continue;
  123.         if (strcmp(hashTable[hashKey]->node[index]->key,strKey)==0){
  124.             hashTable[hashKey]->node[index]=0;
  125.             return 0;
  126.         }
  127.     }
  128. }
  129. struct dataForm * retrieveData(unsigned char *strKey){
  130.     int index=0;
  131.     int hashKey=hash(strKey);
  132.     int count =hashTable[hashKey]->nodeCount;
  133.     for (index=0;index<count;++index){
  134.         if(hashTable[hashKey]->node[index]==0)
  135.             continue;
  136.         if (strcmp(hashTable[hashKey]->node[index]->key,strKey)==0){
  137.             return hashTable[hashKey]->node[index];
  138.         }
  139.     }
  140.     return 0;
  141. }
  142. struct dataForm* makeDataForm(char *key,char *data,time_t expireTime){
  143.     struct dataForm*x=malloc(sizeof(struct dataForm)+1);
  144.     x->value=malloc(strlen(data)+1);
  145.     x->key=malloc(strlen(key)+1);
  146.     strcpy((*x).key,key);
  147.     strcpy((*x).value,data);
  148.     (*x).expireTime=expireTime;
  149.     return x;
  150. }
  151. void flushData(){
  152.     int i=0;
  153.     for (i=0;i<1009;++i){
  154.         int count=hashTable[i]->nodeCount;
  155.         int j;
  156.         for(j=0;j<count;++j){
  157.                 deleteData(hashTable[i]->node[j]->key);
  158.             }
  159.     }
  160. }
  161. time_t getCurrentTime(){
  162.     time_t t;
  163.     time(&t);
  164.     return t;
  165. }
  166. void initHashTable(){
  167.     int i=0;
  168.     for (int i=0;i<1009;++i){
  169.         hashTable[i]=malloc(sizeof(struct hashNode));
  170.         hashTable[i]->node=malloc(sizeof(struct hashNode*));
  171.         hashTable[i]->nodeCount=0;
  172.     }
  173. }
  174. void initThread(){
  175.     pthread_t *thread;
  176.     int result_code = pthread_create(thread, NULL, refresh, NULL);
  177. }
  178. void startService(){
  179.     memset(hashTable,0,sizeof(struct hashNode*)*memSize);
  180.     initHashTable();
  181.     initThread();
  182.     puts(resTitle);
  183.     puts(resOption1st);
  184.     puts(resOption2nd);
  185.     puts(resOption3rd);
  186.     puts(resOption4th);
  187.     puts(resOption5th);
  188.     int choice;
  189.     char key[51];
  190.     char data[101];
  191.     struct dataForm *retrieved;
  192.     while(TRUE){
  193.         printf(resEnterChoice);
  194.         scanf("%d",&choice);
  195.         fpurge(stdin);
  196.         switch(choice){
  197.             case STOREDATA:
  198.                 printf(resEnterKey);    
  199.                 fgets(key,50,stdin);
  200.                 strtok(key, "\n");
  201.                 printf(resEnterVariable);
  202.                 fgets(data,100,stdin);
  203.                 strtok(data, "\n");
  204.                 printf(resEnterExpireTime);
  205.                 int expireTime;
  206.                 scanf("%d",&expireTime);
  207.                 while (expireTime>2592000 ||expireTime<0){
  208.                     printf(resReEnterTime);
  209.                     printf(resEnterExpireTime);
  210.                     scanf("%d",&expireTime);
  211.                 }
  212.                 int currentTime=getCurrentTime();
  213.                 if (expireTime==0)
  214.                     currentTime=0;
  215.                 storeData(key,makeDataForm(key,data,expireTime+currentTime));
  216.                 if (expireTime!=0)
  217.                     printf(resStoreSuccess,key,expireTime);
  218.                 else
  219.                     printf(resStoreForever,key);
  220.                 break;
  221.             case RETRIEVEITEM:
  222.                 printf(resEnterKey);
  223.                 fgets(key,50,stdin);
  224.                 strtok(key, "\n");
  225.                 retrieved=retrieveData(key);
  226.                 if (retrieved==NULL){
  227.                     printf(resDataNotExist,key);
  228.                 } else if(retrieved->expireTime ==UINT32_MAX){
  229.                     printf(resDataExpired);
  230.                     deleteData(key);
  231.                 } else {
  232.                     printf(resGetData,retrieved->value);
  233.                 }  
  234.                 break;
  235.             case DELETEITEM:
  236.                 printf(resEnterKey);
  237.                 fgets(key,50,stdin);
  238.                 strtok(key, "\n");
  239.                 deleteData(key);
  240.                 printf(resDeleteSuccess);  
  241.                 break;
  242.             case FLUSHALL:
  243.                 flushData();
  244.                 printf(resFlushSuccess);
  245.                 break;
  246.             case EXIT:
  247.                 exit(0);
  248.                 break;
  249.         }
  250.     }
  251. }
  252. int main(int argc, char** argv) {
  253.     startService();
  254.     return (EXIT_SUCCESS);
  255. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement