00001 #include "cache.h"
00002 #include <stdlib.h>
00003 #include <string.h>
00004 #include <stdio.h>
00005
00006
00007
00008
00009
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
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
00047
00048 int CacheCreateBin(Cache* c, unsigned char* Key, int KeyLen){
00049 #ifdef DEBUGPATH
00050 printf("In CacheCreateBin\n");
00051 #endif
00052
00053
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
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
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
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
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
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
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
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
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
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
00184 if (ci->Key) free(ci->Key);
00185 ci->Key=NULL;
00186 ci->KeyLen=0;
00187 ci->NumItems=0;
00188
00189
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
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
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 }