43 #define MAXKEYLEN 1000
44 #define MAXDATALEN 1000000
46 static void cache_impossible(
void)
51 static void set4(uint32 pos,uint32
u)
53 if (pos > size - 4) cache_impossible();
54 uint32_pack(
x + pos,
u);
57 static uint32 get4(uint32 pos)
60 if (pos > size - 4) cache_impossible();
61 uint32_unpack(
x + pos,&result);
65 static unsigned int hash(
const char *key,
unsigned int keylen)
67 unsigned int result = 5381;
70 result = (result << 5) + result;
71 result ^= (
unsigned char) *key;
80 char *
cache_get(
const char *key,
unsigned int keylen,
unsigned int *datalen,uint32 *ttl)
94 prevpos = hash(key,keylen);
99 if (get4(pos + 4) == keylen) {
100 if (pos + 20 + keylen > size) cache_impossible();
101 if (byte_equal(key,keylen,
x + pos + 20)) {
102 tai_unpack(
x + pos + 12,&expire);
104 if (tai_less(&expire,&
now))
return 0;
106 tai_sub(&expire,&expire,&
now);
107 d = tai_approx(&expire);
108 if (
d > 604800)
d = 604800;
112 if (
u > size - pos - 20 - keylen) cache_impossible();
115 return x + pos + 20 + keylen;
118 nextpos = prevpos ^ get4(pos);
121 if (++loop > 100)
return 0;
127 void cache_set(
const char *key,
unsigned int keylen,
const char *
data,
unsigned int datalen,uint32 ttl)
131 unsigned int entrylen;
132 unsigned int keyhash;
140 if (ttl > 604800) ttl = 604800;
142 entrylen = keylen + datalen + 20;
144 while (writer + entrylen > oldest) {
145 if (oldest == unused) {
146 if (writer <= hsize)
return;
153 set4(pos,get4(pos) ^ oldest);
155 oldest += get4(oldest + 4) + get4(oldest + 8) + 20;
156 if (oldest > unused) cache_impossible();
157 if (oldest == unused) {
163 keyhash = hash(key,keylen);
166 tai_uint(&expire,ttl);
167 tai_add(&expire,&expire,&
now);
171 set4(pos,get4(pos) ^ keyhash ^ writer);
172 set4(writer,pos ^ keyhash);
173 set4(writer + 4,keylen);
174 set4(writer + 8,datalen);
175 tai_pack(
x + writer + 12,&expire);
176 byte_copy(
x + writer + 20,keylen,key);
177 byte_copy(
x + writer + 20 + keylen,datalen,
data);
179 set4(keyhash,writer);
191 if (cachesize > 1000000000) cachesize = 1000000000;
192 if (cachesize < 100) cachesize = 100;
196 while (hsize <= (size >> 5)) hsize <<= 1;
int cache_init(unsigned int cachesize)
void cache_set(const char *key, unsigned int keylen, const char *data, unsigned int datalen, uint32 ttl)
char * cache_get(const char *key, unsigned int keylen, unsigned int *datalen, uint32 *ttl)
void d(const char *home, const char *subdir, int uid, int gid, int mode)