From 9401d5c906a3928dd2ec1fdc3ebb798ad91900b0 Mon Sep 17 00:00:00 2001 From: Radim Kolar <> Date: Tue, 22 Sep 2009 15:13:45 +0200 Subject: [PATCH 01/12] remove tweak.h from fifocache. it should not depends on FSP --- server/fifocache.c | 1 - 1 file changed, 1 deletion(-) diff --git a/server/fifocache.c b/server/fifocache.c index 43a3696..ab3790f 100644 --- a/server/fifocache.c +++ b/server/fifocache.c @@ -6,7 +6,6 @@ * (aka MIT/X11 License). */ -#include "tweak.h" #include #include #include From a18032611ed38144c042d6edacabb8d5cd045bb4 Mon Sep 17 00:00:00 2001 From: Radim Kolar <> Date: Tue, 22 Sep 2009 15:16:03 +0200 Subject: [PATCH 02/12] clarify copyright for fifocache - its dual licensed LGPL v2.1 with MIT if used as part of FSP --- server/fifocache.c | 6 +++--- server/fifocache.h | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/server/fifocache.c b/server/fifocache.c index ab3790f..0be400f 100644 --- a/server/fifocache.c +++ b/server/fifocache.c @@ -1,6 +1,6 @@ -/* - * Simple FIFO generic cache. (c) Radim Kolar 2003. - * This file is copyrighted as LGPL. +/* + * Simple FIFO generic cache. (c) Radim Kolar 2003, 2009 + * This file is copyrighted as LGPL v2.1 * * When this file is used as part of FSP, it uses 2-term BSD license * (aka MIT/X11 License). diff --git a/server/fifocache.h b/server/fifocache.h index 4cc5592..6796dd9 100644 --- a/server/fifocache.h +++ b/server/fifocache.h @@ -1,6 +1,6 @@ /* - * Simple FIFO generic cache. (c) Radim Kolar 2003. - * This file is copyrighted as LGPL. + * Simple FIFO generic cache. (c) Radim Kolar 2003, 2009 + * This file is copyrighted as LGPL v2.1 * * When this file is used as part of FSP, it uses 2-term BSD license * (aka MIT/X11 License). From ac199f985f37a8a2143a6a783e48dbc2ca863849 Mon Sep 17 00:00:00 2001 From: Radim Kolar <> Date: Tue, 22 Sep 2009 16:53:39 +0200 Subject: [PATCH 03/12] use void * instead of BYTE pointers --- server/fifocache.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/server/fifocache.h b/server/fifocache.h index 6796dd9..5085b2b 100644 --- a/server/fifocache.h +++ b/server/fifocache.h @@ -9,13 +9,13 @@ struct FifoCache { unsigned int cachesize; /* max. number of entries */ - BYTE *e_head; /* block of cache entries, every entry has entrysize bytes */ - BYTE *e_next; /* new intem will be placed there */ - const BYTE *e_stop; /* stop mark for entries, never write here! */ + void *e_head; /* block of cache entries, every entry has entrysize bytes */ + void *e_next; /* new intem will be placed there */ + const void *e_stop; /* stop mark for entries, never write here! */ unsigned int entrysize; /* size of 1 entry in bytes */ - BYTE *k_head; /* block of keys starts there */ - BYTE *k_next; /* new item */ - const BYTE *k_stop; /* stop mark for key entries */ + void *k_head; /* block of keys starts there */ + void *k_next; /* new item */ + const void *k_stop; /* stop mark for key entries */ unsigned int keysize; /* size of 1 key in bytes */ void (*k_destroy_func) (void *key); /* key destoy function */ void (*e_destroy_func) (void *key); /* element destoy function */ From 9fd3051b4f4ebed25c1bc109d6433139d0624b55 Mon Sep 17 00:00:00 2001 From: Radim Kolar <> Date: Tue, 22 Sep 2009 17:13:35 +0200 Subject: [PATCH 04/12] javadoc style comments added to fifocache --- server/fifocache.c | 117 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 104 insertions(+), 13 deletions(-) diff --git a/server/fifocache.c b/server/fifocache.c index 0be400f..263838b 100644 --- a/server/fifocache.c +++ b/server/fifocache.c @@ -1,4 +1,4 @@ -/* +/* * Simple FIFO generic cache. (c) Radim Kolar 2003, 2009 * This file is copyrighted as LGPL v2.1 * @@ -11,7 +11,19 @@ #include #include "fifocache.h" -/* allocates a memory for new cache stucture and init it */ +/** + * Create new FIFO cache. + * + * Allocates a memory for new cache stucture and initialise it. + * + * @param cachesize cache size in number of entries + * @param entrysize size of one entry in bytes + * @param edf entry destroy function + * @param kdf key destroy function + * @param kcf key compare function, must return zero for equals keys + * @return NULL or error, otherwise newly allocated fifocache structure + */ + struct FifoCache * f_cache_new(unsigned int cachesize,unsigned int entrysize, void (*edf) (void *),unsigned int keysize, void (*kdf) (void *), int (*kcf)(const void *,const void *)) { @@ -59,13 +71,30 @@ struct FifoCache * f_cache_new(unsigned int cachesize,unsigned int entrysize, return cache; } -/* set memory profile functions */ + +/** + * Set memory profile functions. + * + * Memory profile functions returns sizes of data referenced + * by keys or entries. In this cache entries and keys are fixed + * size. + * + * @param cache cache to operate on + * @param keysize returns size of key in bytes + * @param entrysize returns size of entry in bytes + */ void f_cache_set_memory_profilers(struct FifoCache *cache,unsigned int (*keysize) (void *key),unsigned int (*entrysize) (void *entry)) { cache->get_keysize=keysize; cache->get_entrysize=entrysize; } +/** + * Prints cache memory usage and hit/miss ratio. + * + * @param cache cache to operate on + * @param f FILE to write results to + */ void f_cache_stats(struct FifoCache *cache,FILE *f) { unsigned int i; @@ -110,12 +139,29 @@ void f_cache_stats(struct FifoCache *cache,FILE *f) cache->cachesize,used,sizeof(struct FifoCache), cache->cachesize*cache->keysize,dkey,cache->cachesize*cache->entrysize,dentry,cache->hit,cache->miss); } +/** + * Empty memory profiler function. + * + * Intended use is passing this function as argument to + * f_cache_set_memory_profilers. + * + * @return always 0 + */ unsigned int f_cache_void_profiler(void *anything) { return 0; } -/* destroys cache without deallocationg of elements itself */ +/** + * Destroys cache without calling destructor function on + * keys or elements. + * + * Keys and elements and cache control structure are zeroed and deallocated + * but if they pointed to another structures via pointers, then these + * structures are left intact. + * + * @param cache cache to be destroyed + */ void f_cache_destroy(struct FifoCache *cache) { if(cache==NULL) return; @@ -128,13 +174,20 @@ void f_cache_destroy(struct FifoCache *cache) memset(cache->k_head,0,cache->keysize*cache->cachesize); free(cache->k_head); } - cache->e_head=NULL; - cache->k_head=NULL; + memset(cache,0,sizeof(struct FifoCache); free(cache); } -/* copy record into cache, free existing record */ -/* returns pointer to data entry in cache */ +/** + * Copy record into cache replacing existing record. + * + * Always creates new record even if we already have record for key in + * cache. + * @param cache cache to put record into + * @param key key for record + * @param data data for record + * @return pointer to data entry in cache + */ void * f_cache_put(struct FifoCache *cache,const void *key,const void *data) { void *where; @@ -161,7 +214,14 @@ void * f_cache_put(struct FifoCache *cache,const void *key,const void *data) return where; } -/* find element by key */ +/** + * Find element by key. + * + * Linear search is performed. + * @param cache used cache + * @param key key for finding data + * @return cached data or NULL + */ void *f_cache_find(struct FifoCache *cache,const void *key) { unsigned int i; @@ -170,16 +230,24 @@ void *f_cache_find(struct FifoCache *cache,const void *key) if(cache->keysize==0) return NULL; for(i=0;icachesize;i++) + { if(!cache->k_compare_func(key,cache->k_head+i*cache->keysize)) { cache->hit++; return cache->e_head+i*cache->entrysize; } + } cache->miss++; return NULL; } -/* clear all elements from the cache */ +/** + * clear all elements from the cache. + * + * Cache itself is not destroyed and destroy functions are called. + * + * @param cache cache to be cleared + */ void f_cache_clear(struct FifoCache *cache) { unsigned int i; @@ -203,7 +271,17 @@ void f_cache_clear(struct FifoCache *cache) cache->hit=0; cache->miss=0; } -/* find key for given entry */ + +/** + * find key for given entry. + * + * Entry must been received from cache before. We also dont + * check if data have not been overwriten by new content after receiving. + * + * @param cache cache to search + * @param entry entry to search + * @return key for entry or NULL + */ void * f_cache_get_key(struct FifoCache *cache,const void *entry) { unsigned int i; @@ -216,7 +294,14 @@ void * f_cache_get_key(struct FifoCache *cache,const void *entry) return cache->k_head+cache->keysize*i; } -/* delete entry from cache, returns one if object is deleted */ +/** + * delete entry from cache. + * + * Destroy function is called on entry. + * @param cache from what cache to delete entry + * @param entry entry to be deleted + * @return one if object is deleted + */ int f_cache_delete_entry(struct FifoCache *cache, void *entry) { unsigned int i; @@ -237,7 +322,13 @@ int f_cache_delete_entry(struct FifoCache *cache, void *entry) return 1; } -/* returns how many objects was deleted */ +/** + * Perform searched delete + * + * @param cache cache to search + * @param key key used for deleting entries + * @return how many objects were deleted. + */ int f_cache_delete_by_key(struct FifoCache *cache, void *key) { unsigned int i; From a22c6b9cff10426066f06f8b16239eb7cf407262 Mon Sep 17 00:00:00 2001 From: Radim Kolar <> Date: Tue, 22 Sep 2009 17:21:50 +0200 Subject: [PATCH 05/12] removed last traces of BYTE datatype --- server/fifocache.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/server/fifocache.c b/server/fifocache.c index 263838b..8b40c82 100644 --- a/server/fifocache.c +++ b/server/fifocache.c @@ -111,7 +111,7 @@ void f_cache_stats(struct FifoCache *cache,FILE *f) { for(j=0;jkeysize;j++) { - if( *(cache->k_head+i*cache->keysize+j) != 0) + if( *(const char*)(cache->k_head+i*cache->keysize+j) != 0) { used++; break; @@ -174,7 +174,7 @@ void f_cache_destroy(struct FifoCache *cache) memset(cache->k_head,0,cache->keysize*cache->cachesize); free(cache->k_head); } - memset(cache,0,sizeof(struct FifoCache); + memset(cache,0,sizeof(struct FifoCache)); free(cache); } @@ -288,9 +288,10 @@ void * f_cache_get_key(struct FifoCache *cache,const void *entry) if(cache->entrysize==0 || cache->keysize==0) return NULL; /* check if pointer is good */ - if(entry<(const void *)cache->e_head || entry>=(const void *)cache->e_stop) return NULL; + if(entry<(const void *)cache->e_head || entry>=(const void *)cache->e_stop) + return NULL; /* find cache index */ - i=((const BYTE *)(entry)-cache->e_head)/cache->entrysize; + i=(entry-cache->e_head)/cache->entrysize; return cache->k_head+cache->keysize*i; } @@ -310,7 +311,7 @@ int f_cache_delete_entry(struct FifoCache *cache, void *entry) /* check if pointer is good */ if(entry<(const void *)cache->e_head || entry>=(const void *)cache->e_stop) return 0; /* find cache index */ - i=((BYTE *)(entry)-cache->e_head)/cache->entrysize; + i=(entry-cache->e_head)/cache->entrysize; /* deallocate */ if(cache->k_destroy_func) cache->k_destroy_func(cache->k_head+cache->keysize*i); From b7a2d77f86bd7fa5be5b758c3fc4e72971d9c200 Mon Sep 17 00:00:00 2001 From: Radim Kolar <> Date: Tue, 22 Sep 2009 17:41:09 +0200 Subject: [PATCH 06/12] define cache heads as int8_t * --- server/fifocache.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/server/fifocache.h b/server/fifocache.h index 5085b2b..9d040c6 100644 --- a/server/fifocache.h +++ b/server/fifocache.h @@ -1,3 +1,5 @@ +#include + /* * Simple FIFO generic cache. (c) Radim Kolar 2003, 2009 * This file is copyrighted as LGPL v2.1 @@ -9,11 +11,11 @@ struct FifoCache { unsigned int cachesize; /* max. number of entries */ - void *e_head; /* block of cache entries, every entry has entrysize bytes */ + int8_t *e_head;/* block of cache entries, every entry has entrysize bytes */ void *e_next; /* new intem will be placed there */ const void *e_stop; /* stop mark for entries, never write here! */ unsigned int entrysize; /* size of 1 entry in bytes */ - void *k_head; /* block of keys starts there */ + int8_t *k_head; /* block of keys starts there */ void *k_next; /* new item */ const void *k_stop; /* stop mark for key entries */ unsigned int keysize; /* size of 1 key in bytes */ From a876e9d6c8d8c5cd03c6d3883fb6f49e938088e1 Mon Sep 17 00:00:00 2001 From: Radim Kolar <> Date: Tue, 22 Sep 2009 17:48:36 +0200 Subject: [PATCH 07/12] next pointers in fifocache must be int8_t also --- server/fifocache.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/fifocache.h b/server/fifocache.h index 9d040c6..bff5edf 100644 --- a/server/fifocache.h +++ b/server/fifocache.h @@ -12,11 +12,11 @@ struct FifoCache { unsigned int cachesize; /* max. number of entries */ int8_t *e_head;/* block of cache entries, every entry has entrysize bytes */ - void *e_next; /* new intem will be placed there */ + int8_t *e_next; /* new intem will be placed there */ const void *e_stop; /* stop mark for entries, never write here! */ unsigned int entrysize; /* size of 1 entry in bytes */ int8_t *k_head; /* block of keys starts there */ - void *k_next; /* new item */ + int8_t *k_next; /* new item */ const void *k_stop; /* stop mark for key entries */ unsigned int keysize; /* size of 1 key in bytes */ void (*k_destroy_func) (void *key); /* key destoy function */ From 4fa6d2b64860a49df275f4c87144886dc5bf22bb Mon Sep 17 00:00:00 2001 From: Radim Kolar <> Date: Tue, 22 Sep 2009 17:53:33 +0200 Subject: [PATCH 08/12] convert entry * to int8_t before substracting pointers --- server/fifocache.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/fifocache.c b/server/fifocache.c index 8b40c82..4c9e769 100644 --- a/server/fifocache.c +++ b/server/fifocache.c @@ -291,7 +291,7 @@ void * f_cache_get_key(struct FifoCache *cache,const void *entry) if(entry<(const void *)cache->e_head || entry>=(const void *)cache->e_stop) return NULL; /* find cache index */ - i=(entry-cache->e_head)/cache->entrysize; + i=((int8_t *)entry-cache->e_head)/cache->entrysize; return cache->k_head+cache->keysize*i; } @@ -311,7 +311,7 @@ int f_cache_delete_entry(struct FifoCache *cache, void *entry) /* check if pointer is good */ if(entry<(const void *)cache->e_head || entry>=(const void *)cache->e_stop) return 0; /* find cache index */ - i=(entry-cache->e_head)/cache->entrysize; + i=((int8_t *)entry-cache->e_head)/cache->entrysize; /* deallocate */ if(cache->k_destroy_func) cache->k_destroy_func(cache->k_head+cache->keysize*i); From 76658177543910fa2796bab9e7093d9cad8430f8 Mon Sep 17 00:00:00 2001 From: Radim Kolar <> Date: Tue, 22 Sep 2009 17:55:04 +0200 Subject: [PATCH 09/12] we need to use const * pointer to avoid gcc warning --- server/fifocache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/fifocache.c b/server/fifocache.c index 4c9e769..db0552b 100644 --- a/server/fifocache.c +++ b/server/fifocache.c @@ -291,7 +291,7 @@ void * f_cache_get_key(struct FifoCache *cache,const void *entry) if(entry<(const void *)cache->e_head || entry>=(const void *)cache->e_stop) return NULL; /* find cache index */ - i=((int8_t *)entry-cache->e_head)/cache->entrysize; + i=((const int8_t *)entry-cache->e_head)/cache->entrysize; return cache->k_head+cache->keysize*i; } From eed479202c884df561a09589f287b7a34ec04194 Mon Sep 17 00:00:00 2001 From: Radim Kolar <> Date: Tue, 22 Sep 2009 17:59:33 +0200 Subject: [PATCH 10/12] make memory profilers to operate on const void * pointers, they have to reason for changing data --- server/fifocache.c | 2 +- server/fifocache.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/server/fifocache.c b/server/fifocache.c index db0552b..577896e 100644 --- a/server/fifocache.c +++ b/server/fifocache.c @@ -83,7 +83,7 @@ struct FifoCache * f_cache_new(unsigned int cachesize,unsigned int entrysize, * @param keysize returns size of key in bytes * @param entrysize returns size of entry in bytes */ -void f_cache_set_memory_profilers(struct FifoCache *cache,unsigned int (*keysize) (void *key),unsigned int (*entrysize) (void *entry)) +void f_cache_set_memory_profilers(struct FifoCache *cache,unsigned int (*keysize) (const void *key),unsigned int (*entrysize) (const void *entry)) { cache->get_keysize=keysize; cache->get_entrysize=entrysize; diff --git a/server/fifocache.h b/server/fifocache.h index bff5edf..59a4af9 100644 --- a/server/fifocache.h +++ b/server/fifocache.h @@ -24,13 +24,12 @@ struct FifoCache int (*k_compare_func) (const void *key1,const void *key2); /* element destoy function */ unsigned int hit; /* cache search hits */ unsigned int miss; /* cache search misses */ - unsigned int (*get_keysize) (void *key); /* return dynamic memory used by key */ - unsigned int (*get_entrysize) (void *entry); /* return dynamic memory used by entry */ + unsigned int (*get_keysize) (const void *key); /* return dynamic memory used by key */ + unsigned int (*get_entrysize) (const void *entry); /* return dynamic memory used by entry */ }; /* prototypes */ struct FifoCache * f_cache_new(unsigned int cachesize,unsigned int entrysize,void (*edf) (void *key),unsigned int keysize, void (*kdf) (void *key), int (*kcf)(const void *,const void *)); -void f_cache_set_memory_profilers(struct FifoCache *cache,unsigned int (*keysize) (void *key),unsigned int (*entrysize) (void *entry)); void f_cache_destroy(struct FifoCache *cache); void * f_cache_put(struct FifoCache *cache,const void *key,const void *data); void f_cache_clear(struct FifoCache *cache); @@ -40,4 +39,5 @@ void * f_cache_get_key(struct FifoCache *cache,const void *entry); int f_cache_delete_by_key(struct FifoCache *cache, void *key); /* utility functions */ unsigned int f_cache_void_profiler(void *anything); +void f_cache_set_memory_profilers(struct FifoCache *cache,unsigned int (*keysize) (const void *key),unsigned int (*entrysize) (const void *entry)); void f_cache_stats(struct FifoCache *cache,FILE *f); From 1f570b0049a11027aa43bb73bf597e0672b5bc05 Mon Sep 17 00:00:00 2001 From: Radim Kolar <> Date: Tue, 22 Sep 2009 18:06:16 +0200 Subject: [PATCH 11/12] add const to file FIFO cache profilers --- server/file.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/server/file.c b/server/file.c index dc53139..ec28602 100644 --- a/server/file.c +++ b/server/file.c @@ -66,9 +66,9 @@ static void fpcache_free_entry (void *entry) fclose(f->fp); } -static unsigned int fpcache_entry_profiler (void *entry) +static unsigned int fpcache_entry_profiler (const void *entry) { - FPCACHE *f=entry; + const FPCACHE *f=entry; if(f->fp) return sizeof(FILE); @@ -85,9 +85,9 @@ static void dirlistcache_free_entry (void * entry) free(d->listing); } -static unsigned int dirlistcache_entry_profiler (void *entry) +static unsigned int dirlistcache_entry_profiler (const void *entry) { - DIRLISTING *d=entry; + const DIRLISTING *d=entry; return d->listing_size; } @@ -108,10 +108,10 @@ static void dirstatcache_free_entry (void * entry) free(d->readme); } -static unsigned int dirstatcache_entry_profiler (void *entry) +static unsigned int dirstatcache_entry_profiler (const void *entry) { /* TODO profiling for owner ip_table */ - DIRINFO *d=entry; + const DIRINFO *d=entry; unsigned int res=0; if(d->realname) { @@ -144,9 +144,9 @@ static void string_free (void * entry) free(*s); } -static unsigned int string_profiler (void *entry) +static unsigned int string_profiler (const void *entry) { - char **s=entry; + char * const *s=entry; if(*s!=NULL) return(strlen(*s)); From c45f3e07940bf13b083cb555a509acf4761a57e7 Mon Sep 17 00:00:00 2001 From: Radim Kolar <> Date: Tue, 22 Sep 2009 18:16:28 +0200 Subject: [PATCH 12/12] print what we inserting into cache during test. fixed all gcc warnings. --- tests/cachecheck.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/tests/cachecheck.c b/tests/cachecheck.c index 6ecb271..376bd4b 100644 --- a/tests/cachecheck.c +++ b/tests/cachecheck.c @@ -9,8 +9,11 @@ #include #include "../server/fifocache.h" -static int intcompare(const int *i1,const int *i2) +static int intcompare(const void *vi1,const void *vi2) { + const int *i1,*i2; + i1 = vi1; + i2 = vi2; if(i1==NULL || i2==NULL) return 1; if(*i1==*i2) return 0; return 1; @@ -41,27 +44,31 @@ int main(int argv,char **argc) { struct FifoCache * cache; char file[20]; - char *s; + const char *s; int i; cache=f_cache_new(4,sizeof(file),NULL,sizeof(int),NULL,intcompare); assert(cache!=NULL); strcpy(file,"/jeden/soubor"); i=1; + printf("Puting key %d: %s\n",i,file); f_cache_put(cache,&i,file); strcpy(file,"/druhy"); i=2; + printf("Puting key %d: %s\n",i,file); f_cache_put(cache,&i,file); strcpy(file,"/treti"); i=3; + printf("Puting key %d: %s\n",i,file); f_cache_put(cache,&i,file); strcpy(file,"/ctvrty/soubor"); i=4; + printf("Puting key %d: %s\n",i,file); f_cache_put(cache,&i,file); for(i=0;i<=5;i++) { - printf("Finding key %d: %s\n",i,f_cache_find(cache,&i)); + printf("Finding key %d: %s\n",i,(char *)f_cache_find(cache,&i)); } f_cache_clear(cache); f_cache_destroy(cache); @@ -74,9 +81,9 @@ int main(int argv,char **argc) s="lamer2"; f_cache_put(cache,&s,NULL); s="lamer co tu neni"; - printf("find2: %s\n",f_cache_find(cache,&s)); + printf("find2: %s\n",(char *)f_cache_find(cache,&s)); s="lamer1"; - printf("find2: %s\n",f_cache_find(cache,&s)); + printf("find2: %s\n",(char *)f_cache_find(cache,&s)); return 0; }