Commit 7899ba8b authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Move a bit more responsibility into the hash-slinger to get a cleaner

interface.



git-svn-id: http://www.varnish-cache.org/svn/trunk@234 d4fa192b-c00b-0410-8231-f00ffab90ce4
parent 1afc8aa1
......@@ -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;
......
......@@ -8,7 +8,6 @@
#include <string.h>
#include <sys/types.h>
#include <fcntl.h>
#include <md5.h>
#include <event.h>
#include <pthread.h>
......@@ -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));
......
/*
* $Id$
*
* This is the reference hash(/lookup) implementation
*/
#include <assert.h>
......@@ -12,14 +14,23 @@
#include <libvarnish.h>
#include <cache.h>
/*--------------------------------------------------------------------*/
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
};
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment