From af8ab9ec932b8a38857a1f3644db648d5b63b06f Mon Sep 17 00:00:00 2001 From: phk Date: Mon, 26 Jun 2006 14:00:40 +0000 Subject: [PATCH] Move a bit more responsibility into the hash-slinger to get a cleaner interface. git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@234 d4fa192b-c00b-0410-8231-f00ffab90ce4 --- varnish-cache/bin/varnishd/cache.h | 14 ++-- varnish-cache/bin/varnishd/cache_hash.c | 8 +-- varnish-cache/bin/varnishd/hash_simple_list.c | 67 ++++++++++++------- 3 files changed, 47 insertions(+), 42 deletions(-) diff --git a/varnish-cache/bin/varnishd/cache.h b/varnish-cache/bin/varnishd/cache.h index 1aae9c86..8f1cac6a 100644 --- a/varnish-cache/bin/varnishd/cache.h +++ b/varnish-cache/bin/varnishd/cache.h @@ -29,16 +29,14 @@ struct worker; /* Hashing -----------------------------------------------------------*/ typedef void hash_init_f(void); -typedef struct objhead *hash_lookup_f(unsigned char *key, struct objhead *nobj); +typedef struct objhead *hash_lookup_f(const char *key, struct objhead *nobj); typedef void hash_deref_f(struct objhead *obj); -typedef void hash_purge_f(struct objhead *obj); struct hash_slinger { const char *name; hash_init_f *init; hash_lookup_f *lookup; hash_deref_f *deref; - hash_purge_f *purge; }; extern struct hash_slinger hsl_slinger; @@ -66,14 +64,13 @@ extern struct stevedore *stevedore; /* -------------------------------------------------------------------*/ struct object { - unsigned char hash[16]; unsigned refcnt; - unsigned valid; - unsigned cacheable; - struct objhead *objhead; pthread_cond_t cv; + unsigned valid; + unsigned cacheable; + unsigned busy; unsigned len; time_t ttl; @@ -85,8 +82,7 @@ struct object { }; struct objhead { - unsigned char hash[16]; - unsigned refcnt; + void *hashpriv; pthread_mutex_t mtx; TAILQ_HEAD(,object) objects; diff --git a/varnish-cache/bin/varnishd/cache_hash.c b/varnish-cache/bin/varnishd/cache_hash.c index ffa0fa9f..0949c886 100644 --- a/varnish-cache/bin/varnishd/cache_hash.c +++ b/varnish-cache/bin/varnishd/cache_hash.c @@ -8,7 +8,6 @@ #include #include #include -#include #include #include @@ -23,8 +22,6 @@ HSH_Lookup(struct worker *w, struct http *h) { struct objhead *oh; struct object *o; - unsigned char key[16]; - MD5_CTX ctx; char *b; assert(hash != NULL); @@ -43,10 +40,7 @@ HSH_Lookup(struct worker *w, struct http *h) } assert(http_GetURL(h, &b)); - MD5Init(&ctx); - MD5Update(&ctx, b, strlen(b)); - MD5Final(key, &ctx); - oh = hash->lookup(key, w->nobjhead); + oh = hash->lookup(b, w->nobjhead); if (oh == w->nobjhead) w->nobjhead = NULL; AZ(pthread_mutex_lock(&oh->mtx)); diff --git a/varnish-cache/bin/varnishd/hash_simple_list.c b/varnish-cache/bin/varnishd/hash_simple_list.c index 63e7375a..69c8a88f 100644 --- a/varnish-cache/bin/varnishd/hash_simple_list.c +++ b/varnish-cache/bin/varnishd/hash_simple_list.c @@ -1,5 +1,7 @@ /* * $Id$ + * + * This is the reference hash(/lookup) implementation */ #include @@ -12,14 +14,23 @@ #include #include +/*--------------------------------------------------------------------*/ + struct hsl_entry { TAILQ_ENTRY(hsl_entry) list; + char *key; struct objhead *obj; + unsigned refcnt; }; static TAILQ_HEAD(, hsl_entry) hsl_head = TAILQ_HEAD_INITIALIZER(hsl_head); static pthread_mutex_t hsl_mutex; +/*-------------------------------------------------------------------- + * The ->init method is called during process start and allows + * initialization to happen before the first lookup. + */ + static void hsl_init(void) { @@ -27,23 +38,31 @@ hsl_init(void) AZ(pthread_mutex_init(&hsl_mutex, NULL)); } +/*-------------------------------------------------------------------- + * Lookup and possibly insert element. + * If nobj != NULL and the lookup does not find key, nobj is inserted. + * If nobj == NULL and the lookup does not find key, NULL is returned. + * A reference to the returned object is held. + */ + static struct objhead * -hsl_lookup(unsigned char *key, struct objhead *nobj) +hsl_lookup(const char *key, struct objhead *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); + i = strcmp(key, he->key); + if (i < 0) + continue; if (i == 0) { - he->obj->refcnt++; + he->refcnt++; nobj = he->obj; + nobj->hashpriv = he; AZ(pthread_mutex_unlock(&hsl_mutex)); return (nobj); } - if (i < 0) - continue; if (nobj == NULL) { AZ(pthread_mutex_unlock(&hsl_mutex)); return (NULL); @@ -53,8 +72,10 @@ hsl_lookup(unsigned char *key, struct objhead *nobj) he2 = calloc(sizeof *he2, 1); assert(he2 != NULL); he2->obj = nobj; - nobj->refcnt++; - memcpy(nobj->hash, key, sizeof nobj->hash); + he2->refcnt = 1; + he2->key = strdup(key); + assert(he2->key != NULL); + nobj->hashpriv = he2; if (he != NULL) TAILQ_INSERT_BEFORE(he, he2, list); else @@ -63,37 +84,31 @@ hsl_lookup(unsigned char *key, struct objhead *nobj) return (nobj); } -static void -hsl_deref(struct objhead *obj) -{ - - AZ(pthread_mutex_lock(&hsl_mutex)); - obj->refcnt--; - AZ(pthread_mutex_unlock(&hsl_mutex)); -} +/*-------------------------------------------------------------------- + * Dereference and if no references are left, free. + */ static void -hsl_purge(struct objhead *obj) +hsl_deref(struct objhead *obj) { struct hsl_entry *he; - assert(obj->refcnt > 0); + assert(obj->hashpriv != NULL); + he = obj->hashpriv; 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; - } + if (--he->refcnt == 0) { + free(he->key); + TAILQ_REMOVE(&hsl_head, he, list); + free(he); } - assert(he != NULL); + AZ(pthread_mutex_unlock(&hsl_mutex)); } +/*--------------------------------------------------------------------*/ + struct hash_slinger hsl_slinger = { "simple_list", hsl_init, hsl_lookup, hsl_deref, - hsl_purge }; -- 2.39.5