8 struct store *newstore(struct storeops *ops)
12 new = malloc(sizeof(*new));
15 new->cache = calloc(4096 * 4, sizeof(struct storecache));
19 #define min(a, b) (((b) < (a))?(b):(a))
21 static ssize_t cacheget(struct store *st, struct addr *a, void *buf, size_t len)
25 he = a->hash[0] | ((a->hash[1] & 0x0f) << 8);
26 for(i = 0; i < 4; i++) {
27 if(!addrcmp(&st->cache[he * 4 + i].a, a))
32 if(st->cache[he * 4 + i].data != NULL)
33 memcpy(buf, st->cache[he * 4 + i].data, min(len, st->cache[he * 4 + i].dlen));
34 return(st->cache[he * 4 + i].dlen);
37 static void cacheput(struct store *st, struct addr *a, const void *data, ssize_t len)
40 struct storecache tmp;
42 he = a->hash[0] | ((a->hash[1] & 0x0f) << 8);
43 for(i = 0; i < 4; i++) {
44 if(!addrcmp(&st->cache[he * 4 + i].a, a))
50 tmp = st->cache[he * 4 + i];
51 memmove(&st->cache[he * 4 + 1], &st->cache[he * 4], i * sizeof(struct storecache));
52 st->cache[he * 4] = tmp;
55 if(st->cache[he * 4 + 3].data != NULL)
56 free(st->cache[he * 4 + 3].data);
57 memmove(&st->cache[he * 4 + 1], &st->cache[he * 4], 3 * sizeof(struct storecache));
58 st->cache[he * 4].a = *a;
60 st->cache[he * 4].data = memcpy(malloc(len), data, len);
62 st->cache[he * 4].data = NULL;
63 st->cache[he * 4].dlen = len;
66 int storeput(struct store *st, const void *buf, size_t len, struct addr *at)
71 ret = st->ops->put(st, buf, len, &na);
73 cacheput(st, &na, buf, len);
79 ssize_t storeget(struct store *st, void *buf, size_t len, struct addr *at)
85 sz = cacheget(st, at2, buf, len);
91 sz = st->ops->get(st, buf, len, at2);
92 if((sz < 0) && (errno == ENOENT))
93 cacheput(st, at2, NULL, -1);
95 cacheput(st, at2, buf, sz);
99 int releasestore(struct store *st)
103 if((err = st->ops->release(st)) != 0)
109 int addrcmp(struct addr *a1, struct addr *a2)
111 return(memcmp(a1->hash, a2->hash, 32));
114 char *formataddr(struct addr *a)
119 for(i = 0; i < 32; i++)
120 sprintf(buf + (i * 2), "%02x", a->hash[i]);
125 static int hex2int(char hex)
127 if((hex >= 'a') && (hex <= 'f'))
128 return(hex - 'a' + 10);
129 if((hex >= 'A') && (hex <= 'F'))
130 return(hex - 'A' + 10);
131 if((hex >= '0') && (hex <= '9'))
136 int parseaddr(char *p, struct addr *a)
140 for(i = 0; i < 32; i++) {
141 if((d = hex2int(*p++)) < 0)
146 if((d = hex2int(*p++)) < 0)
157 int niladdr(struct addr *a)
161 for(i = 0; i < 32; i++) {