3131#include "mpool.h"
3232#include "clamav.h"
3333#include "cache.h"
34+ #include "math.h"
3435#include "fmap.h"
3536
3637#include "clamav_rust.h"
3738
38- /* The number of root trees and the chooser function
39+ /* The chooser function
3940 Each tree is protected by a mutex against concurrent access */
40- /* #define TREES 1 */
41- /* static inline unsigned int getkey(uint8_t *hash) { return 0; } */
42- #define TREES 256
43- static inline unsigned int getkey (uint8_t * hash )
41+ static inline unsigned int getkey (uint8_t * hash , size_t trees )
4442{
4543 if (hash ) {
46- return * hash ;
44+ return ( hash [ 0 ] | ((( unsigned int ) hash [ 1 ]) << 8 )) % trees ;
4745 }
4846
4947 return 0 ;
5048}
51- /* #define TREES 4096 */
52- /* static inline unsigned int getkey(uint8_t *hash) { return hash[0] | ((unsigned int)(hash[1] & 0xf)<<8) ; } */
53- /* #define TREES 65536 */
54- /* static inline unsigned int getkey(uint8_t *hash) { return hash[0] | (((unsigned int)hash[1])<<8) ; } */
55-
56- /* The number of nodes in each tree */
57- #define NODES 256
5849
5950/* SPLAY --------------------------------------------------------------------- */
6051struct node { /* a node */
@@ -77,33 +68,35 @@ struct cache_set { /* a tree */
7768
7869struct CACHE {
7970 struct cache_set cacheset ;
71+ size_t trees ;
72+ size_t nodes_per_tree ;
8073#ifdef CL_THREAD_SAFE
8174 pthread_mutex_t mutex ;
8275#endif
8376};
8477
8578/* Allocates all the nodes and sets up the replacement chain */
86- static int cacheset_init (struct cache_set * cs , mpool_t * mempool )
79+ static int cacheset_init (struct cache_set * cs , mpool_t * mempool , size_t nodes_per_tree )
8780{
8881 unsigned int i ;
8982
9083#ifndef USE_MPOOL
9184 UNUSEDPARAM (mempool );
9285#endif
9386
94- cs -> data = MPOOL_CALLOC (mempool , NODES , sizeof (* cs -> data ));
87+ cs -> data = MPOOL_CALLOC (mempool , nodes_per_tree , sizeof (* cs -> data ));
9588 cs -> root = NULL ;
9689
9790 if (!cs -> data )
9891 return 1 ;
9992
100- for (i = 1 ; i < NODES ; i ++ ) {
93+ for (i = 1 ; i < nodes_per_tree ; i ++ ) {
10194 cs -> data [i - 1 ].next = & cs -> data [i ];
10295 cs -> data [i ].prev = & cs -> data [i - 1 ];
10396 }
10497
10598 cs -> first = cs -> data ;
106- cs -> last = & cs -> data [NODES - 1 ];
99+ cs -> last = & cs -> data [nodes_per_tree - 1 ];
107100
108101 return 0 ;
109102}
@@ -540,7 +533,7 @@ static int cache_lookup_hash(unsigned char *md5, size_t len, struct CACHE *cache
540533 return ret ;
541534 }
542535
543- key = getkey (md5 );
536+ key = getkey (md5 , cache -> trees );
544537
545538 c = & cache [key ];
546539
@@ -575,12 +568,20 @@ int clean_cache_init(struct cl_engine *engine)
575568 return 0 ;
576569 }
577570
578- if (!(cache = MPOOL_MALLOC (engine -> mempool , sizeof (struct CACHE ) * TREES ))) {
571+ size_t trees = ceil (sqrt (engine -> cache_size ));
572+ size_t nodes_per_tree = ceil (sqrt (engine -> cache_size ));
573+
574+ cli_dbgmsg ("clean_cache_init: Requested cache size: %d. Actual cache size: %d. Trees: %d. Nodes per tree: %d.\n" , engine -> cache_size , trees * nodes_per_tree , trees , nodes_per_tree );
575+
576+ if (!(cache = MPOOL_MALLOC (engine -> mempool , sizeof (struct CACHE ) * trees ))) {
579577 cli_errmsg ("clean_cache_init: mpool malloc fail\n" );
580578 return 1 ;
581579 }
582580
583- for (i = 0 ; i < TREES ; i ++ ) {
581+ cache -> trees = trees ;
582+ cache -> nodes_per_tree = nodes_per_tree ;
583+
584+ for (i = 0 ; i < trees ; i ++ ) {
584585#ifdef CL_THREAD_SAFE
585586 if (pthread_mutex_init (& cache [i ].mutex , NULL )) {
586587 cli_errmsg ("clean_cache_init: mutex init fail\n" );
@@ -590,7 +591,7 @@ int clean_cache_init(struct cl_engine *engine)
590591 return 1 ;
591592 }
592593#endif
593- if (cacheset_init (& cache [i ].cacheset , engine -> mempool )) {
594+ if (cacheset_init (& cache [i ].cacheset , engine -> mempool , cache -> nodes_per_tree )) {
594595 for (j = 0 ; j < i ; j ++ ) cacheset_destroy (& cache [j ].cacheset , engine -> mempool );
595596#ifdef CL_THREAD_SAFE
596597 for (j = 0 ; j <= i ; j ++ ) pthread_mutex_destroy (& cache [j ].mutex );
@@ -615,7 +616,7 @@ void clean_cache_destroy(struct cl_engine *engine)
615616 return ;
616617 }
617618
618- for (i = 0 ; i < TREES ; i ++ ) {
619+ for (i = 0 ; i < cache -> trees ; i ++ ) {
619620 cacheset_destroy (& cache [i ].cacheset , engine -> mempool );
620621#ifdef CL_THREAD_SAFE
621622 pthread_mutex_destroy (& cache [i ].mutex );
@@ -667,7 +668,7 @@ void clean_cache_add(unsigned char *md5, size_t size, cli_ctx *ctx)
667668
668669 level = (ctx -> fmap && ctx -> fmap -> dont_cache_flag ) ? ctx -> recursion_level : 0 ;
669670
670- key = getkey (md5 );
671+ key = getkey (md5 , ctx -> engine -> cache -> trees );
671672 c = & ctx -> engine -> cache [key ];
672673
673674#ifdef CL_THREAD_SAFE
@@ -709,7 +710,7 @@ void clean_cache_remove(unsigned char *md5, size_t size, const struct cl_engine
709710 return ;
710711 }
711712
712- key = getkey (md5 );
713+ key = getkey (md5 , engine -> cache -> trees );
713714
714715 c = & engine -> cache [key ];
715716#ifdef CL_THREAD_SAFE
0 commit comments