From: phk Date: Tue, 11 Apr 2006 08:28:20 +0000 (+0000) Subject: Beginnings of the object lookup stuff: A simple list based X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9066f29282adb2417497c49746ed30b57a983879;p=varnish Beginnings of the object lookup stuff: A simple list based implementation to get things moving. git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@137 d4fa192b-c00b-0410-8231-f00ffab90ce4 --- diff --git a/varnish-cache/bin/varnishd/Makefile.am b/varnish-cache/bin/varnishd/Makefile.am index 6317a539..9380faf9 100644 --- a/varnish-cache/bin/varnishd/Makefile.am +++ b/varnish-cache/bin/varnishd/Makefile.am @@ -15,6 +15,7 @@ varnishd_SOURCES = \ cache_shmlog.c \ cache_vcl.c \ cli_event.c \ + hash_simple_list.c \ mgt_child.c \ tcp.c \ varnishd.c diff --git a/varnish-cache/bin/varnishd/cache.h b/varnish-cache/bin/varnishd/cache.h index b93e9341..c4a16c01 100644 --- a/varnish-cache/bin/varnishd/cache.h +++ b/varnish-cache/bin/varnishd/cache.h @@ -15,6 +15,28 @@ struct worker { struct worker; #endif +/* Hashing -----------------------------------------------------------*/ +struct object { /* XXX: this goes elsewhere in due time */ + unsigned char hash[16]; + unsigned refcnt; +}; + +typedef void hash_init_f(void); +typedef struct object *hash_lookup_f(unsigned char *key, struct object *nobj); +typedef void hash_purge_f(struct object *obj); + +struct hash_slinger { + const char *name; + hash_init_f *init; + hash_lookup_f *lookup; + hash_purge_f *purge; +}; + +extern struct hash_slinger hsl_slinger; + +/* Prototypes etc ----------------------------------------------------*/ + + /* cache_acceptor.c */ void *vca_main(void *arg); void vca_retire_session(struct sess *sp); diff --git a/varnish-cache/bin/varnishd/hash_simple_list.c b/varnish-cache/bin/varnishd/hash_simple_list.c new file mode 100644 index 00000000..72323da0 --- /dev/null +++ b/varnish-cache/bin/varnishd/hash_simple_list.c @@ -0,0 +1,89 @@ +/* + * $Id$ + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +struct hsl_entry { + TAILQ_ENTRY(hsl_entry) list; + struct object *obj; +}; + +static TAILQ_HEAD(, hsl_entry) hsl_head = TAILQ_HEAD_INITIALIZER(hsl_head); +static pthread_mutex_t hsl_mutex; + +static void +hsl_init(void) +{ + + AZ(pthread_mutex_init(&hsl_mutex, NULL)); +} + +static struct object * +hsl_lookup(unsigned char *key, struct object *nobj) +{ + struct hsl_entry *he, *he2; + int i; + + AZ(pthread_mutex_lock(&hsl_mutex)); + TAILQ_FOREACH(he, &hsl_head, list) { + i = memcmp(key, he->obj->hash, sizeof he->obj->hash); + if (i == 0) { + he->obj->refcnt++; + nobj = he->obj; + AZ(pthread_mutex_unlock(&hsl_mutex)); + return (nobj); + } + if (i < 0) + continue; + if (nobj == NULL) { + AZ(pthread_mutex_unlock(&hsl_mutex)); + return (NULL); + } + break; + } + he2 = calloc(sizeof *he2, 1); + assert(he2 != NULL); + he2->obj = nobj; + nobj->refcnt++; + if (he != NULL) + TAILQ_INSERT_BEFORE(he, he2, list); + else + TAILQ_INSERT_TAIL(&hsl_head, he2, list); + AZ(pthread_mutex_unlock(&hsl_mutex)); + return (nobj); +} + +static void +hsl_purge(struct object *obj) +{ + struct hsl_entry *he; + + assert(obj->refcnt > 0); + AZ(pthread_mutex_lock(&hsl_mutex)); + TAILQ_FOREACH(he, &hsl_head, list) { + if (he->obj == obj) { + TAILQ_REMOVE(&hsl_head, he, list); + AZ(pthread_mutex_unlock(&hsl_mutex)); + free(he); + return; + } + } + assert(he != NULL); +} + +struct hash_slinger hsl_slinger = { + "simple_list", + hsl_init, + hsl_lookup, + hsl_purge +};