engine/cache.c

Go to the documentation of this file.
00001 #include "cache.h"
00002 #include <stdlib.h>
00003 #include <string.h>
00004 #include <stdio.h>
00005 
00006 //#define DEBUG
00007 
00008 /***************************************
00009 * Set up a new cache
00010 ***************************************/
00011 Cache* InitCache(int TimeoutLen){
00012         Cache*          NewCache;
00013         
00014 #ifdef DEBUGPATH
00015         printf("In InitCache\n");
00016 #endif
00017         
00018         NewCache=calloc(sizeof(Cache),1);
00019         NewCache->TimeoutLen=TimeoutLen;
00020         
00021         return NewCache;
00022 }
00023 
00024 /**********************************************
00025 * Given a Key, find the Cache bin
00026 **********************************************/
00027 int CacheGetBin(Cache* c, unsigned char* Key, int KeyLen){
00028         int             i;
00029         
00030 #ifdef DEBGUPATH
00031         printf("In CacheGetBin\n");
00032 #endif
00033 
00034         for (i=0;i<c->NumKeys;i++){
00035                 if (c->Keys[i].KeyLen==KeyLen){
00036                         if (memcmp(c->Keys[i].Key, Key, KeyLen)==0){
00037                                 return i;
00038                         }
00039                 }
00040         }
00041         
00042         return CACHE_NONE;
00043 }
00044 
00045 /*********************************************
00046 * Create a new bin to put stuff in
00047 *********************************************/
00048 int CacheCreateBin(Cache* c, unsigned char* Key, int KeyLen){
00049 #ifdef DEBUGPATH
00050         printf("In CacheCreateBin\n");
00051 #endif
00052 
00053         /*check to see if we're full*/
00054         if (c->NumKeys>=CACHE_MAX_KEYS){
00055 #ifdef DEBUG    
00056                 printf("Cache is full\n");
00057 #endif          
00058                 return CACHE_NONE;
00059         }
00060 
00061         /*allocate a new one*/
00062         c->Keys[c->NumKeys].Key=malloc(KeyLen);
00063         memcpy(c->Keys[c->NumKeys].Key, Key, KeyLen);
00064         c->Keys[c->NumKeys].KeyLen=KeyLen;
00065         c->Keys[c->NumKeys].NumItems=0;
00066 
00067         c->NumKeys++;
00068         
00069         return c->NumKeys-1;
00070 }
00071 
00072 
00073 /*********************************************
00074 * put a new item in a cache bin
00075 *********************************************/
00076 int CacheBinAdd(CacheItems* ci, unsigned char* Data, int DataLen){
00077 #ifdef DEBUGPATH
00078         printf("In CacheBinAdd\n");
00079 #endif
00080 
00081         if (ci->NumItems==CACHE_MAX_ITEMS_PER_KEY){
00082 #ifdef DEBUG
00083                 printf("This key if full\n");
00084 #endif  
00085                 return FALSE;
00086         }
00087         
00088         ci->Items[ci->NumItems].Data=malloc(DataLen);
00089         memcpy(ci->Items[ci->NumItems].Data, Data, DataLen);
00090         ci->Items[ci->NumItems].DataLen=DataLen;
00091         
00092         ci->NumItems++;
00093                 
00094         return TRUE;
00095 }
00096 
00097 /************************************************
00098 * Kill any keys that have timed out
00099 ************************************************/
00100 void CacheTimeout(Cache* c, int Now){
00101         int             i;
00102         
00103 #ifdef DEBUGPATH
00104         printf("In CacheTimeout\n");
00105 #endif
00106 
00107         for (i=0;i<c->NumKeys;i++){
00108                 if ( (c->Keys[i].LastTime+c->TimeoutLen) < Now){
00109                         CacheDelKey(c, c->Keys[i].Key, c->Keys[i].KeyLen, 0);
00110                 }
00111         }
00112 }
00113 
00114 
00115 /*********************************************
00116 * Put some data into the cache
00117 *********************************************/
00118 int CacheAdd(Cache* c, unsigned char* Key, int KeyLen, unsigned char* Data, int DataLen, int Now){
00119         int     BinID;
00120         
00121 #ifdef DEBUGPATH
00122         printf("In CacheAdd\n");
00123 #endif
00124 
00125         /*go find the bin, if it exists*/
00126         BinID=CacheGetBin(c, Key, KeyLen);
00127         if (BinID==CACHE_NONE){
00128 #ifdef DEBUG
00129                 printf("First Item in this bin\n");
00130 #endif
00131                 BinID=CacheCreateBin(c, Key, KeyLen);           
00132         }
00133         if (BinID==CACHE_NONE){
00134 #ifdef DEBUG
00135                 printf("Failed to create a new bin\n");
00136 #endif  
00137                 return FALSE;
00138         }
00139 
00140         /*now add the key to that bin*/
00141         if (!CacheBinAdd(&c->Keys[BinID], Data, DataLen)){
00142 #ifdef DEBUG
00143                 printf("Failed to add to key. full?\n");
00144 #endif  
00145                 return FALSE;
00146         }
00147         c->Keys[BinID].LastTime=Now;
00148 
00149         CacheTimeout(c, Now);
00150                 
00151         return TRUE;
00152 }
00153 
00154 /************************************************
00155 * We're done with this key, kill it
00156 *************************************************/
00157 int CacheDelKey(Cache* c, unsigned char* Key, int KeyLen, int Now){
00158         int                     KeyID;
00159         int                     i;
00160         CacheItems*     ci;
00161         
00162 #ifdef DEBUGPATH
00163         printf("In CacheDelKey\n");
00164 #endif
00165 
00166         /*go find the bin*/
00167         KeyID=CacheGetBin(c, Key, KeyLen);
00168         if (KeyID==CACHE_NONE){
00169 #ifdef DEBUG
00170                 printf("There is no such key\n");
00171 #endif  
00172                 return FALSE;
00173         }
00174         
00175         /*get rid of the items in that bin*/
00176         ci = &c->Keys[KeyID];
00177         for (i=0;i<ci->NumItems;i++){
00178                 if (ci->Items[i].Data) free(ci->Items[i].Data);
00179                 ci->Items[i].Data=NULL;
00180                 ci->Items[i].DataLen=0;
00181         }
00182         
00183         /*get rid of the bin*/
00184         if (ci->Key) free(ci->Key);
00185         ci->Key=NULL;
00186         ci->KeyLen=0;
00187         ci->NumItems=0;
00188         
00189         /*move everything up*/
00190         memcpy(&c->Keys[KeyID], &c->Keys[KeyID+1], sizeof(CacheItems) * (c->NumKeys-KeyID));
00191         c->NumKeys--;
00192         
00193         CacheTimeout(c, Now);
00194                 
00195         return TRUE;    
00196 }
00197 
00198 /********************************************
00199 * Retrieve the contents of the key
00200 ********************************************/
00201 CacheItems* CacheGet(Cache* c, unsigned char* Key, int KeyLen, int Now){
00202         int     KeyID;
00203         
00204 #ifdef DEBUGPATH
00205         printf("In CacheGet\n");
00206 #endif
00207 
00208         KeyID=CacheGetBin(c, Key, KeyLen);
00209         if (KeyID==CACHE_NONE){
00210 #ifdef DEBUG
00211                 printf("No Such key\n");
00212 #endif  
00213                 return NULL;
00214         }
00215         
00216         CacheTimeout(c, Now);
00217         
00218         return &c->Keys[KeyID];
00219 }
00220 
00221 /***************************************************
00222 * We're all done with this cache, free everything
00223 ***************************************************/
00224 void DestroyCache(Cache* c){
00225         int i,j;
00226 #ifdef DEBUGPATH
00227         printf("in DestroyCache\n");
00228 #endif
00229 
00230 
00231         for (i=0;i<c->NumKeys;i++){
00232                 for (j=0;j<c->Keys[i].NumItems;j++){
00233                         if (c->Keys[i].Items[j].Data) free(c->Keys[i].Items[j].Data);
00234                 }
00235                 if (c->Keys[i].Key) free(c->Keys[i].Key);
00236         }
00237         
00238         free(c);
00239         c=NULL;
00240 }

Generated on Sat Jul 7 23:33:10 2007 for HLBR by  doxygen 1.5.2