Browse code

tie cache to engine

aCaB authored on 2010/01/15 02:54:53
Showing 7 changed files
... ...
@@ -306,8 +306,6 @@ int main(int argc, char **argv)
306 306
 	break;
307 307
     }
308 308
 
309
-    cl_cache_init(256);
310
-
311 309
     if(!(engine = cl_engine_new())) {
312 310
 	logg("!Can't initialize antivirus engine\n");
313 311
 	ret = 1;
... ...
@@ -144,8 +144,6 @@ int main(int argc, char **argv)
144 144
 
145 145
     gettimeofday(&t1, NULL);
146 146
 
147
-    cl_cache_init(512);
148
-
149 147
     ret = scanmanager(opts);
150 148
 
151 149
     if(!optget(opts, "no-summary")->enabled) {
... ...
@@ -38,10 +38,9 @@
38 38
 #include "cache.h"
39 39
 #include "fmap.h"
40 40
 
41
-static mpool_t *mempool = NULL;
41
+#define NODES 256
42 42
 
43
-//#define DONT_CACHE
44
-//#define USE_LRUHASHCACHE
43
+/*#define USE_LRUHASHCACHE*/
45 44
 #define USE_SPLAY
46 45
 
47 46
 #ifdef USE_LRUHASHCACHE
... ...
@@ -53,38 +52,23 @@ struct cache_key {
53 53
 
54 54
 struct cache_set {
55 55
     struct cache_key *data;
56
-    size_t capacity;
57 56
     size_t maxelements; /* considering load factor */
58 57
     size_t maxdeleted;
59 58
     size_t elements;
60 59
     size_t deleted;
61
-    size_t version;
62 60
     struct cache_key *lru_head, *lru_tail;
63 61
 };
64 62
 
65
-#define CACHE_INVALID_VERSION ~0u
66 63
 #define CACHE_KEY_DELETED ~0u
67 64
 #define CACHE_KEY_EMPTY 0
68 65
 
69
-static void cache_setversion(struct cache_set* map, uint32_t version)
70
-{
71
-    unsigned i;
72
-    if (map->version == version)
73
-	return;
74
-    map->version = version;
75
-    map->elements = 0; /* all elements have expired now */
76
-    for (i=0;i<map->capacity;i++)
77
-	map->data[i].size = 0;
78
-    map->lru_head = map->lru_tail = NULL;
79
-}
80
-
81 66
 static void cacheset_lru_remove(struct cache_set *map, size_t howmany)
82 67
 {
83 68
     while (howmany--) {
84 69
 	struct cache_key *old;
85 70
 	assert(map->lru_head);
86 71
 	assert(!old->lru_prev);
87
-	// Remove a key from the head of the list
72
+	/* Remove a key from the head of the list */
88 73
 	old = map->lru_head;
89 74
 	map->lru_head = old->lru_next;
90 75
 	old->size = CACHE_KEY_DELETED;
... ...
@@ -110,7 +94,7 @@ static inline int cacheset_lookup_internal(struct cache_set *map,
110 110
 					   uint32_t *insert_pos, int deletedok)
111 111
 {
112 112
     const struct cache_key*data = map->data;
113
-    uint32_t capmask = map->capacity - 1;
113
+    uint32_t capmask = NODES - 1;
114 114
     const struct cache_key *k;
115 115
     uint32_t idx, tries = 0;
116 116
     uint64_t md5_0, md5_1;
... ...
@@ -165,24 +149,24 @@ static inline void lru_addtail(struct cache_set *map, struct cache_key *newkey)
165 165
 
166 166
 static pthread_mutex_t pool_mutex = PTHREAD_MUTEX_INITIALIZER;
167 167
 
168
-static void cacheset_add(struct cache_set *map, unsigned char *md5, size_t size);
169
-static int cacheset_init(struct cache_set *map, unsigned int entries);
168
+static void cacheset_add(struct cache_set *map, unsigned char *md5, size_t size, mpool_t *mempool);
169
+static int cacheset_init(struct cache_set *map, mpool_t *mempool);
170 170
 
171
-static void cacheset_rehash(struct cache_set *map)
171
+static void cacheset_rehash(struct cache_set *map, mpool_t *mempool)
172 172
 {
173 173
     unsigned i;
174 174
     int ret;
175 175
     struct cache_set tmp_set;
176 176
     struct cache_key *key;
177 177
     pthread_mutex_lock(&pool_mutex);
178
-    ret = cacheset_init(&tmp_set, map->capacity);
178
+    ret = cacheset_init(&tmp_set, mempool);
179 179
     pthread_mutex_unlock(&pool_mutex);
180 180
     if (ret)
181 181
 	return;
182 182
 
183 183
     key = map->lru_head;
184 184
     for (i=0;key && i < tmp_set.maxelements/2;i++) {
185
-	cacheset_add(&tmp_set, (unsigned char*)&key->digest, key->size);
185
+	cacheset_add(&tmp_set, (unsigned char*)&key->digest, key->size, mempool);
186 186
 	key = key->lru_next;
187 187
     }
188 188
     pthread_mutex_lock(&pool_mutex);
... ...
@@ -191,7 +175,7 @@ static void cacheset_rehash(struct cache_set *map)
191 191
     memcpy(map, &tmp_set, sizeof(tmp_set));
192 192
 }
193 193
 
194
-static void cacheset_add(struct cache_set *map, unsigned char *md5, size_t size)
194
+static void cacheset_add(struct cache_set *map, unsigned char *md5, size_t size, mpool_t *mempool)
195 195
 {
196 196
     int ret;
197 197
     uint32_t pos;
... ...
@@ -200,7 +184,7 @@ static void cacheset_add(struct cache_set *map, unsigned char *md5, size_t size)
200 200
     if (map->elements >= map->maxelements) {
201 201
 	cacheset_lru_remove(map, 1);
202 202
 	if (map->deleted >= map->maxdeleted) {
203
-	    cacheset_rehash(map);
203
+	    cacheset_rehash(map, mempool);
204 204
 	}
205 205
     }
206 206
     assert(map->elements < map->maxelements);
... ...
@@ -231,27 +215,30 @@ static int cacheset_lookup(struct cache_set *map, unsigned char *md5, size_t siz
231 231
 
232 232
     ret = cacheset_lookup_internal(map, md5, size, &pos, 0);
233 233
     if (!ret)
234
-	return CACHE_INVALID_VERSION;
234
+	return 0;
235 235
     newkey = &map->data[pos];
236 236
     /* update LRU position: move to tail */
237 237
     lru_remove(map, newkey);
238 238
     lru_addtail(map, newkey);
239
-    return map->version;
239
+    return 1;
240 240
 }
241 241
 
242
-static int cacheset_init(struct cache_set *map, unsigned int entries) {
243
-    map->data = mpool_calloc(mempool, entries, sizeof(*map->data));
242
+static int cacheset_init(struct cache_set *map, mpool_t *mempool) {
243
+    map->data = mpool_calloc(mempool, NODES, sizeof(*map->data));
244 244
     if (!map->data)
245 245
 	return CL_EMEM;
246
-    map->capacity = entries;
247
-    map->maxelements = 80*entries / 100;
248
-    map->maxdeleted = map->capacity - map->maxelements - 1;
246
+    map->maxelements = 80 * NODES / 100;
247
+    map->maxdeleted = NODES - map->maxelements - 1;
249 248
     map->elements = 0;
250
-    map->version = CACHE_INVALID_VERSION;
251 249
     map->lru_head = map->lru_tail = NULL;
252
-    map->version = 1337;
253 250
     return 0;
254 251
 }
252
+
253
+static inline void cacheset_destroy(struct cache_set *cs, mpool_t *mempool) {
254
+    mpool_free(mempool, cs->data);
255
+    cs->data = NULL;
256
+}
257
+
255 258
 #endif /* USE_LRUHASHCACHE */
256 259
 
257 260
 #ifdef USE_SPLAY
... ...
@@ -272,25 +259,30 @@ struct cache_set {
272 272
     struct node *last;
273 273
 };
274 274
 
275
-static int cacheset_init(struct cache_set *cs, unsigned int entries) {
275
+static int cacheset_init(struct cache_set *cs, mpool_t *mempool) {
276 276
     unsigned int i;
277
-    cs->data = mpool_calloc(mempool, entries,  sizeof(*cs->data));
277
+    cs->data = mpool_calloc(mempool, NODES,  sizeof(*cs->data));
278 278
     cs->root = NULL;
279 279
 
280 280
     if(!cs->data)
281
-	return CL_EMEM;
281
+	return 1;
282 282
 
283
-    for(i=1; i<entries; i++) {
283
+    for(i=1; i<NODES; i++) {
284 284
 	cs->data[i-1].next = &cs->data[i];
285 285
 	cs->data[i].prev = &cs->data[i-1];
286 286
     }
287 287
 
288 288
     cs->first = cs->data;
289
-    cs->last = &cs->data[entries-1];
289
+    cs->last = &cs->data[NODES-1];
290 290
 
291 291
     return 0;
292 292
 }
293 293
 
294
+static inline void cacheset_destroy(struct cache_set *cs, mpool_t *mempool) {
295
+    mpool_free(mempool, cs->data);
296
+    cs->data = NULL;
297
+}
298
+
294 299
 static inline int cmp(int64_t *a, int64_t *b) {
295 300
     if(a[1] < b[1]) return -1;
296 301
     if(a[1] > b[1]) return 1;
... ...
@@ -304,14 +296,14 @@ static inline int cmp(int64_t *a, int64_t *b) {
304 304
 /* } */
305 305
 
306 306
 
307
-//#define PRINT_TREE
307
+/*#define PRINT_TREE*/
308 308
 #ifdef PRINT_TREE
309 309
 #define ptree printf
310 310
 #else
311 311
 #define ptree (void)
312 312
 #endif
313 313
 
314
-//#define CHECK_TREE
314
+/*#define CHECK_TREE*/
315 315
 #ifdef CHECK_TREE
316 316
 static int printtree(struct cache_set *cs, struct node *n, int d) {
317 317
     int i;
... ...
@@ -355,9 +347,7 @@ static int printtree(struct cache_set *cs, struct node *n, int d) {
355 355
     return ab;
356 356
 }
357 357
 #else
358
-static inline int printtree(struct cache_set *cs, struct node *n, int d) {
359
-    return 0;
360
-}
358
+#define printtree(a,b,c) (0)
361 359
 #endif
362 360
 
363 361
 static int splay(int64_t *md5, struct cache_set *cs) {
... ...
@@ -484,7 +474,7 @@ static int cacheset_lookup(struct cache_set *cs, unsigned char *md5, size_t size
484 484
 	    printf("\n");
485 485
 	}
486 486
 #endif
487
-	return 1337;
487
+	return 1;
488 488
     }
489 489
     return 0;
490 490
 }
... ...
@@ -503,7 +493,7 @@ static void cacheset_add(struct cache_set *cs, unsigned char *md5, size_t size)
503 503
     }
504 504
 
505 505
     newnode = cs->first;
506
-    //#define TAKE_FIRST
506
+    /*#define TAKE_FIRST*/
507 507
 #ifdef TAKE_FIRST
508 508
     if((newnode->left || newnode->right || newnode->up)) {
509 509
 	if(!splay(newnode->digest, cs)) {
... ...
@@ -616,90 +606,71 @@ static inline unsigned int getkey(uint8_t *hash) { return *hash; }
616 616
 /* #define TREES 65536 */
617 617
 /* static inline unsigned int getkey(uint8_t *hash) { return hash[0] | (((unsigned int)hash[1])<<8) ; } */
618 618
 
619
-static struct CACHE {
619
+struct CACHE {
620 620
     struct cache_set cacheset;
621 621
     pthread_mutex_t mutex;
622
-    uint32_t lastdb;
623
-} *cache = NULL;
624
-
625
-
626
-static int cache_lookup_hash(unsigned char *md5, cli_ctx *ctx);
622
+};
627 623
 
628
-int cl_cache_init(unsigned int entries) {
629
-    unsigned int i;
630
-    int ret;
631 624
 
632
-#ifndef DONT_CACHE
633
-    if(!entries)
634
-#endif
635
-	return 0;
625
+int cli_cache_init(struct cl_engine *engine) {
626
+    static struct CACHE *cache;
627
+    unsigned int i, j;
636 628
 
637
-    if(!(mempool = mpool_create())) {
638
-	cli_errmsg("mpool init fail\n");
629
+    if(!engine) {
630
+	cli_errmsg("cli_cache_init: mpool malloc fail\n");
639 631
 	return 1;
640 632
     }
641
-    if(!(cache = mpool_malloc(mempool, sizeof(struct CACHE) * TREES))) {
642
-	cli_errmsg("mpool malloc fail\n");
643
-	mpool_destroy(mempool);
644
-	mempool = NULL;
633
+
634
+    if(!(cache = mpool_malloc(engine->mempool, sizeof(struct CACHE) * TREES))) {
635
+	cli_errmsg("cli_cache_init: mpool malloc fail\n");
645 636
 	return 1;
646 637
     }
647 638
 
648 639
     for(i=0; i<TREES; i++) {
649 640
 	if(pthread_mutex_init(&cache[i].mutex, NULL)) {
650
-	    cli_errmsg("mutex init fail\n");
651
-	    mpool_destroy(mempool);
652
-	    mempool = NULL;
653
-	    cache = NULL;
641
+	    cli_errmsg("cli_cache_init: mutex init fail\n");
642
+	    for(j=0; j<i; j++) cacheset_destroy(&cache[j].cacheset, engine->mempool);
643
+	    for(j=0; j<i; j++) pthread_mutex_destroy(&cache[j].mutex);
644
+	    mpool_free(engine->mempool, cache);
654 645
 	    return 1;
655 646
 	}
656
-	ret = cacheset_init(&cache[i].cacheset, entries);
657
-	if(ret) {
658
-	    mpool_destroy(mempool);
659
-	    mempool = NULL;
660
-	    cache = NULL;
647
+	if(cacheset_init(&cache[i].cacheset, engine->mempool)) {
648
+	    for(j=0; j<i; j++) cacheset_destroy(&cache[j].cacheset, engine->mempool);
649
+	    for(j=0; j<=i; j++) pthread_mutex_destroy(&cache[j].mutex);
650
+	    mpool_free(engine->mempool, cache);
661 651
 	    return 1;
662 652
 	}
663 653
     }
664
-
665
-    {
666
-	int f = open("/home/acab/hashes", O_RDONLY);
667
-	struct stat s;
668
-	fstat(f, &s);
669
-	char *pippo = mmap(NULL, s.st_size, PROT_READ, MAP_PRIVATE, f, 0);
670
-	while(s.st_size >= 17) {
671
-	    if(*pippo == 'C')
672
-		cache_lookup_hash(pippo+1, NULL);
673
-	    else if(*pippo == 'A')
674
-		cache_add(pippo+1, NULL);
675
-	    else {
676
-		printf("bad hash\n");
677
-		abort();
678
-	    }
679
-	    pippo += 17;
680
-	    s.st_size -= 17;
681
-	}
682
-	printf("that's all\n");
683
-	abort();
684
-    }
654
+    engine->cache = cache;
685 655
     return 0;
686 656
 }
687 657
 
658
+void cli_cache_destroy(struct cl_engine *engine) {
659
+    static struct CACHE *cache;
660
+    unsigned int i;
688 661
 
689
-static int cache_lookup_hash(unsigned char *md5, cli_ctx *ctx) {
690
-    int ret = CL_VIRUS;
662
+    if(!engine || !(cache = engine->cache))
663
+	return;
664
+
665
+    for(i=0; i<TREES; i++) {
666
+	cacheset_destroy(&cache[i].cacheset, engine->mempool);
667
+	pthread_mutex_destroy(&cache[i].mutex);
668
+    }
669
+    mpool_free(engine->mempool, cache);
670
+}
671
+
672
+static int cache_lookup_hash(unsigned char *md5, struct CACHE *cache) {
691 673
     unsigned int key = getkey(md5);
674
+    int ret = CL_VIRUS;
692 675
     struct CACHE *c;
693 676
 
694
-    if(!cache) return ret;
695
-
696 677
     c = &cache[key];
697 678
     if(pthread_mutex_lock(&c->mutex)) {
698
-	cli_errmsg("mutex lock fail\n");
679
+	cli_errmsg("cache_lookup_hash: cache_lookup_hash: mutex lock fail\n");
699 680
 	return ret;
700 681
     }
701 682
 
702
-    ret = (cacheset_lookup(&c->cacheset, md5, 1024) == 1337) ? CL_CLEAN : CL_VIRUS;
683
+    ret = (cacheset_lookup(&c->cacheset, md5, 1024)) ? CL_CLEAN : CL_VIRUS;
703 684
     if(ret == CL_CLEAN) cli_warnmsg("cached\n");
704 685
     pthread_mutex_unlock(&c->mutex);
705 686
     return ret;
... ...
@@ -709,15 +680,24 @@ void cache_add(unsigned char *md5, cli_ctx *ctx) {
709 709
     unsigned int key = getkey(md5);
710 710
     struct CACHE *c;
711 711
 
712
-    if(!cache) return;
712
+    if(!ctx || !ctx->engine || !ctx->engine->cache)
713
+       return;
713 714
 
714
-    c = &cache[key];
715
+    c = &ctx->engine->cache[key];
715 716
     if(pthread_mutex_lock(&c->mutex)) {
716
-	cli_errmsg("mutex lock fail\n");
717
+	cli_errmsg("cli_add: mutex lock fail\n");
717 718
 	return;
718 719
     }
719 720
 
721
+#ifdef USE_LRUHASHCACHE
722
+    cacheset_add(&c->cacheset, md5, 1024, ctx->engine->mempool);
723
+#else
724
+#ifdef USE_SPLAY
720 725
     cacheset_add(&c->cacheset, md5, 1024);
726
+#else
727
+#error #define USE_SPLAY or USE_LRUHASHCACHE
728
+#endif
729
+#endif
721 730
 
722 731
     pthread_mutex_unlock(&c->mutex);
723 732
     return;
... ...
@@ -728,7 +708,8 @@ int cache_check(unsigned char *hash, cli_ctx *ctx) {
728 728
     size_t todo = map->len, at = 0;
729 729
     cli_md5_ctx md5;
730 730
 
731
-    if(!cache) return CL_VIRUS;
731
+    if(!ctx || !ctx->engine || !ctx->engine->cache)
732
+       return CL_VIRUS;
732 733
 
733 734
     cli_md5_init(&md5);
734 735
     while(todo) {
... ...
@@ -741,5 +722,5 @@ int cache_check(unsigned char *hash, cli_ctx *ctx) {
741 741
 	cli_md5_update(&md5, buf, readme);
742 742
     }
743 743
     cli_md5_final(hash, &md5);
744
-    return cache_lookup_hash(hash, ctx);
744
+    return cache_lookup_hash(hash, ctx->engine->cache);
745 745
 }
... ...
@@ -26,5 +26,6 @@
26 26
 
27 27
 void cache_add(unsigned char *md5, cli_ctx *ctx);
28 28
 int cache_check(unsigned char *hash, cli_ctx *ctx);
29
-
29
+int cli_cache_init(struct cl_engine *engine);
30
+void cli_cache_destroy(struct cl_engine *engine);
30 31
 #endif
... ...
@@ -208,7 +208,6 @@ extern const char *cl_retver(void);
208 208
 
209 209
 /* others */
210 210
 extern const char *cl_strerror(int clerror);
211
-extern int cl_cache_init(unsigned int entries);
212 211
 
213 212
 #ifdef __cplusplus
214 213
 }
... ...
@@ -219,6 +219,9 @@ struct cl_engine {
219 219
     /* Icon reference storage */
220 220
     struct icon_matcher *iconcheck;
221 221
 
222
+    /* Negative cache storage */
223
+    struct CACHE *cache;
224
+
222 225
     /* Used for memory pools */
223 226
     mpool_t *mempool;
224 227
 
... ...
@@ -2188,6 +2188,9 @@ int cl_load(const char *path, struct cl_engine *engine, unsigned int *signo, uns
2188 2188
 	cli_dbgmsg("Bytecode engine disabled\n");
2189 2189
     }
2190 2190
 
2191
+    if(cli_cache_init(engine))
2192
+	return CL_EMEM;
2193
+
2191 2194
     engine->dboptions |= dboptions;
2192 2195
 
2193 2196
     switch(sb.st_mode & S_IFMT) {
... ...
@@ -2537,6 +2540,9 @@ int cl_engine_free(struct cl_engine *engine)
2537 2537
     if(engine->tmpdir)
2538 2538
 	mpool_free(engine->mempool, engine->tmpdir);
2539 2539
 
2540
+    if(engine->cache)
2541
+	cli_cache_destroy(engine);
2542
+
2540 2543
     cli_ftfree(engine);
2541 2544
     if(engine->ignored) {
2542 2545
 	cli_bm_free(engine->ignored);