diff --git a/server/fifocache.c b/server/fifocache.c index 43a3696..577896e 100644 --- a/server/fifocache.c +++ b/server/fifocache.c @@ -1,18 +1,29 @@ /* - * 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). */ -#include "tweak.h" #include #include #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 *)) { @@ -60,13 +71,30 @@ struct FifoCache * f_cache_new(unsigned int cachesize,unsigned int entrysize, return cache; } -/* set memory profile functions */ -void f_cache_set_memory_profilers(struct FifoCache *cache,unsigned int (*keysize) (void *key),unsigned int (*entrysize) (void *entry)) + +/** + * 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) (const void *key),unsigned int (*entrysize) (const 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; @@ -83,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; @@ -111,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; @@ -129,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; @@ -162,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; @@ -171,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; @@ -204,20 +271,38 @@ 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; 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=((const int8_t *)entry-cache->e_head)/cache->entrysize; 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; @@ -226,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=((int8_t *)entry-cache->e_head)/cache->entrysize; /* deallocate */ if(cache->k_destroy_func) cache->k_destroy_func(cache->k_head+cache->keysize*i); @@ -238,7 +323,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; diff --git a/server/fifocache.h b/server/fifocache.h index 4cc5592..59a4af9 100644 --- a/server/fifocache.h +++ b/server/fifocache.h @@ -1,6 +1,8 @@ +#include + /* - * 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). @@ -9,26 +11,25 @@ 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! */ + int8_t *e_head;/* block of cache entries, every entry has entrysize bytes */ + 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 */ - BYTE *k_head; /* block of keys starts there */ - BYTE *k_next; /* new item */ - const BYTE *k_stop; /* stop mark for key entries */ + int8_t *k_head; /* block of keys starts there */ + 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 */ void (*e_destroy_func) (void *key); /* element destoy function */ 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); @@ -38,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); 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)); 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; }