Commit 884f8ebd authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Kick the hash_slinger interface around a bit:

Isolate more stuff in hash_slinger.h.

Remove hash_slinger from cache.h, include in .c's as necessary.

Save a malloc per objhead by putting a few fields into the objhead
for the hash_slingers to use.

Preinitialize the refcount when we precreate the objhead.

Move the hash-string allocation into HSH_Copy(), no point in
duplication of mandatory step.




git-svn-id: http://www.varnish-cache.org/svn/trunk/varnish-cache@3405 d4fa192b-c00b-0410-8231-f00ffab90ce4
parent ee4e0f91
...@@ -29,6 +29,12 @@ ...@@ -29,6 +29,12 @@
* $Id$ * $Id$
*/ */
/*
* This macro can be used in .h files to isolate bits that the manager
* should not (need to) see, such as pthread mutexes etc.
*/
#define VARNISH_CACHE_CHILD 1
#include <sys/time.h> #include <sys/time.h>
#include <sys/uio.h> #include <sys/uio.h>
#include <sys/socket.h> #include <sys/socket.h>
...@@ -213,8 +219,6 @@ struct workreq { ...@@ -213,8 +219,6 @@ struct workreq {
void *priv; void *priv;
}; };
#include "hash_slinger.h"
/* Backend Request ---------------------------------------------------*/ /* Backend Request ---------------------------------------------------*/
struct bereq { struct bereq {
...@@ -291,19 +295,6 @@ struct object { ...@@ -291,19 +295,6 @@ struct object {
int hits; int hits;
}; };
struct objhead {
unsigned magic;
#define OBJHEAD_MAGIC 0x1b96615d
void *hashpriv;
struct lock mtx;
unsigned refcnt;
VTAILQ_HEAD(,object) objects;
char *hash;
unsigned hashlen;
VTAILQ_HEAD(, sess) waitinglist;
};
/* -------------------------------------------------------------------*/ /* -------------------------------------------------------------------*/
struct sess { struct sess {
...@@ -449,18 +440,6 @@ int Fetch(struct sess *sp); ...@@ -449,18 +440,6 @@ int Fetch(struct sess *sp);
int FetchReqBody(struct sess *sp); int FetchReqBody(struct sess *sp);
void Fetch_Init(void); void Fetch_Init(void);
/* cache_hash.c */
void HSH_Prealloc(struct sess *sp);
void HSH_Freestore(struct object *o);
int HSH_Compare(const struct sess *sp, const struct objhead *o);
void HSH_Copy(const struct sess *sp, const struct objhead *o);
struct object *HSH_Lookup(struct sess *sp);
void HSH_Unbusy(const struct sess *sp);
void HSH_Ref(struct object *o);
void HSH_Deref(struct object *o);
double HSH_Grace(double g);
void HSH_Init(void);
/* cache_http.c */ /* cache_http.c */
const char *http_StatusMessage(unsigned); const char *http_StatusMessage(unsigned);
void HTTP_Init(void); void HTTP_Init(void);
......
...@@ -75,6 +75,7 @@ DOT acceptor -> start [style=bold,color=green,weight=4] ...@@ -75,6 +75,7 @@ DOT acceptor -> start [style=bold,color=green,weight=4]
#include "vcl.h" #include "vcl.h"
#include "cli_priv.h" #include "cli_priv.h"
#include "cache.h" #include "cache.h"
#include "hash_slinger.h"
static unsigned xids; static unsigned xids;
......
...@@ -52,6 +52,7 @@ ...@@ -52,6 +52,7 @@
#include "cache.h" #include "cache.h"
#include "vlu.h" #include "vlu.h"
#include "vsb.h" #include "vsb.h"
#include "hash_slinger.h"
pthread_t cli_thread; pthread_t cli_thread;
static struct lock cli_mtx; static struct lock cli_mtx;
......
...@@ -60,6 +60,7 @@ ...@@ -60,6 +60,7 @@
#include "shmlog.h" #include "shmlog.h"
#include "binary_heap.h" #include "binary_heap.h"
#include "cache.h" #include "cache.h"
#include "hash_slinger.h"
/* /*
* Objects have sideways references in the binary heap and the LRU list * Objects have sideways references in the binary heap and the LRU list
......
...@@ -65,6 +65,7 @@ ...@@ -65,6 +65,7 @@
#include "shmlog.h" #include "shmlog.h"
#include "cache.h" #include "cache.h"
#include "stevedore.h" #include "stevedore.h"
#include "hash_slinger.h"
static const struct hash_slinger *hash; static const struct hash_slinger *hash;
...@@ -91,12 +92,23 @@ HSH_Prealloc(struct sess *sp) ...@@ -91,12 +92,23 @@ HSH_Prealloc(struct sess *sp)
w->nobjhead = calloc(sizeof *w->nobjhead, 1); w->nobjhead = calloc(sizeof *w->nobjhead, 1);
XXXAN(w->nobjhead); XXXAN(w->nobjhead);
w->nobjhead->magic = OBJHEAD_MAGIC; w->nobjhead->magic = OBJHEAD_MAGIC;
w->nobjhead->refcnt = 1;
VTAILQ_INIT(&w->nobjhead->objects); VTAILQ_INIT(&w->nobjhead->objects);
VTAILQ_INIT(&w->nobjhead->waitinglist); VTAILQ_INIT(&w->nobjhead->waitinglist);
Lck_New(&w->nobjhead->mtx); Lck_New(&w->nobjhead->mtx);
VSL_stats->n_objecthead++; VSL_stats->n_objecthead++;
} else } else
CHECK_OBJ_NOTNULL(w->nobjhead, OBJHEAD_MAGIC); CHECK_OBJ_NOTNULL(w->nobjhead, OBJHEAD_MAGIC);
#if 0
/* Make sure there is space enough for the hash-string */
if (w->nobjhead->hashlen < sp->lhashptr) {
w->objhead->hash = realloc(w->objhead->hash, sp->lhashptr);
w->objhead->hashlen = sp->lhashptr;
AN(w->objhead->hash);
}
#endif
if (w->nobj == NULL) { if (w->nobj == NULL) {
st = STV_alloc(sp, params->obj_workspace); st = STV_alloc(sp, params->obj_workspace);
XXXAN(st); XXXAN(st);
...@@ -167,7 +179,7 @@ HSH_Compare(const struct sess *sp, const struct objhead *oh) ...@@ -167,7 +179,7 @@ HSH_Compare(const struct sess *sp, const struct objhead *oh)
} }
void void
HSH_Copy(const struct sess *sp, const struct objhead *oh) HSH_Copy(const struct sess *sp, struct objhead *oh)
{ {
unsigned u, v; unsigned u, v;
char *b; char *b;
...@@ -175,7 +187,9 @@ HSH_Copy(const struct sess *sp, const struct objhead *oh) ...@@ -175,7 +187,9 @@ HSH_Copy(const struct sess *sp, const struct objhead *oh)
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC); CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC);
assert(oh->hashlen >= sp->lhashptr); oh->hash = malloc(sp->lhashptr);
XXXAN(oh->hash);
oh->hashlen = sp->lhashptr;
b = oh->hash; b = oh->hash;
for (u = 0; u < sp->ihashptr; u += 2) { for (u = 0; u < sp->ihashptr; u += 2) {
v = pdiff(sp->hashptr[u], sp->hashptr[u + 1]); v = pdiff(sp->hashptr[u], sp->hashptr[u + 1]);
...@@ -210,6 +224,7 @@ HSH_Lookup(struct sess *sp) ...@@ -210,6 +224,7 @@ HSH_Lookup(struct sess *sp)
CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC); CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC);
Lck_Lock(&oh->mtx); Lck_Lock(&oh->mtx);
} else { } else {
AN(w->nobjhead);
oh = hash->lookup(sp, w->nobjhead); oh = hash->lookup(sp, w->nobjhead);
CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC); CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC);
if (oh == w->nobjhead) if (oh == w->nobjhead)
......
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#include "shmlog.h" #include "shmlog.h"
#include "cache.h" #include "cache.h"
#include "stevedore.h" #include "stevedore.h"
#include "hash_slinger.h"
/*-------------------------------------------------------------------- /*--------------------------------------------------------------------
* Per thread storage for the session currently being processed by * Per thread storage for the session currently being processed by
......
...@@ -71,6 +71,7 @@ ...@@ -71,6 +71,7 @@
#include "cli_priv.h" #include "cli_priv.h"
#include "cache.h" #include "cache.h"
#include "stevedore.h" #include "stevedore.h"
#include "hash_slinger.h"
VTAILQ_HEAD(workerhead, worker); VTAILQ_HEAD(workerhead, worker);
......
...@@ -50,6 +50,7 @@ ...@@ -50,6 +50,7 @@
#include "vrt_obj.h" #include "vrt_obj.h"
#include "vcl.h" #include "vcl.h"
#include "cache.h" #include "cache.h"
#include "hash_slinger.h"
#include "cache_backend.h" #include "cache_backend.h"
void *vrt_magic_string_end = &vrt_magic_string_end; void *vrt_magic_string_end = &vrt_magic_string_end;
......
...@@ -40,23 +40,14 @@ ...@@ -40,23 +40,14 @@
#include "shmlog.h" #include "shmlog.h"
#include "cache.h" #include "cache.h"
#include "hash_slinger.h"
/*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------*/
struct hcl_entry {
unsigned magic;
#define HCL_ENTRY_MAGIC 0x0ba707bf
VTAILQ_ENTRY(hcl_entry) list;
struct hcl_hd *head;
struct objhead *oh;
unsigned digest;
unsigned hash;
};
struct hcl_hd { struct hcl_hd {
unsigned magic; unsigned magic;
#define HCL_HEAD_MAGIC 0x0f327016 #define HCL_HEAD_MAGIC 0x0f327016
VTAILQ_HEAD(, hcl_entry) head; VTAILQ_HEAD(, objhead) head;
struct lock mtx; struct lock mtx;
}; };
...@@ -126,16 +117,13 @@ hcl_start(void) ...@@ -126,16 +117,13 @@ hcl_start(void)
static struct objhead * static struct objhead *
hcl_lookup(const struct sess *sp, struct objhead *noh) hcl_lookup(const struct sess *sp, struct objhead *noh)
{ {
struct objhead *roh; struct objhead *oh;
struct hcl_entry *he, *he2;
struct hcl_hd *hp; struct hcl_hd *hp;
unsigned u1, digest, r; unsigned u1, digest;
unsigned u, v; unsigned u, v;
int i; int i;
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
CHECK_OBJ_NOTNULL(sp->wrk, WORKER_MAGIC);
CHECK_OBJ_NOTNULL(sp->http, HTTP_MAGIC);
CHECK_OBJ_ORNULL(noh, OBJHEAD_MAGIC); CHECK_OBJ_ORNULL(noh, OBJHEAD_MAGIC);
digest = ~0U; digest = ~0U;
...@@ -147,73 +135,39 @@ hcl_lookup(const struct sess *sp, struct objhead *noh) ...@@ -147,73 +135,39 @@ hcl_lookup(const struct sess *sp, struct objhead *noh)
u1 = digest % hcl_nhash; u1 = digest % hcl_nhash;
hp = &hcl_head[u1]; hp = &hcl_head[u1];
he2 = NULL;
for (r = 0; r < 2; r++ ) { Lck_Lock(&hp->mtx);
Lck_Lock(&hp->mtx); VTAILQ_FOREACH(oh, &hp->head, hoh_list) {
VTAILQ_FOREACH(he, &hp->head, list) { if (sp->lhashptr < oh->hashlen)
CHECK_OBJ_NOTNULL(he, HCL_ENTRY_MAGIC); continue;
if (sp->lhashptr < he->oh->hashlen) if (sp->lhashptr > oh->hashlen)
continue; break;
if (sp->lhashptr > he->oh->hashlen) if (oh->hoh_digest < digest)
break; continue;
if (he->digest < digest) if (oh->hoh_digest > digest)
continue; break;
if (he->digest > digest) i = HSH_Compare(sp, oh);
break; if (i < 0)
i = HSH_Compare(sp, he->oh); continue;
if (i < 0) if (i > 0)
continue; break;
if (i > 0) oh->refcnt++;
break;
he->oh->refcnt++;
roh = he->oh;
Lck_Unlock(&hp->mtx);
/*
* If we loose the race, we need to clean up
* the work we did for our second attempt.
*/
if (he2 != NULL)
free(he2);
if (noh != NULL && noh->hash != NULL) {
free(noh->hash);
noh->hash = NULL;
}
return (roh);
}
if (noh == NULL) {
Lck_Unlock(&hp->mtx);
return (NULL);
}
if (he2 != NULL) {
if (he != NULL)
VTAILQ_INSERT_BEFORE(he, he2, list);
else
VTAILQ_INSERT_TAIL(&hp->head, he2, list);
he2->oh->refcnt++;
noh = he2->oh;
Lck_Unlock(&hp->mtx);
return (noh);
}
Lck_Unlock(&hp->mtx); Lck_Unlock(&hp->mtx);
return (oh);
}
he2 = calloc(sizeof *he2, 1); if (oh != NULL)
XXXAN(he2); VTAILQ_INSERT_BEFORE(oh, noh, hoh_list);
he2->magic = HCL_ENTRY_MAGIC; else
he2->oh = noh; VTAILQ_INSERT_TAIL(&hp->head, noh, hoh_list);
he2->digest = digest;
he2->hash = u1;
he2->head = hp;
noh->hashpriv = he2; noh->hoh_digest = digest;
AZ(noh->hash); noh->hoh_head = hp;
noh->hash = malloc(sp->lhashptr);
XXXAN(noh->hash); HSH_Copy(sp, noh);
noh->hashlen = sp->lhashptr;
HSH_Copy(sp, noh); Lck_Unlock(&hp->mtx);
} return (noh);
assert(he2 == NULL); /* FlexeLint */
INCOMPL();
} }
/*-------------------------------------------------------------------- /*--------------------------------------------------------------------
...@@ -221,28 +175,22 @@ hcl_lookup(const struct sess *sp, struct objhead *noh) ...@@ -221,28 +175,22 @@ hcl_lookup(const struct sess *sp, struct objhead *noh)
*/ */
static int static int
hcl_deref(const struct objhead *oh) hcl_deref(struct objhead *oh)
{ {
struct hcl_entry *he;
struct hcl_hd *hp; struct hcl_hd *hp;
int ret;
CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC); CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC);
CAST_OBJ_NOTNULL(he, oh->hashpriv, HCL_ENTRY_MAGIC); CAST_OBJ_NOTNULL(hp, oh->hoh_head, HCL_HEAD_MAGIC);
hp = he->head; assert(oh->refcnt > 0);
CHECK_OBJ_NOTNULL(hp, HCL_HEAD_MAGIC);
assert(he->oh->refcnt > 0);
assert(he->hash < hcl_nhash);
assert(hp == &hcl_head[he->hash]);
Lck_Lock(&hp->mtx); Lck_Lock(&hp->mtx);
if (--he->oh->refcnt == 0) if (--oh->refcnt == 0) {
VTAILQ_REMOVE(&hp->head, he, list); VTAILQ_REMOVE(&hp->head, oh, hoh_list);
else ret = 0;
he = NULL; } else
ret = 1;
Lck_Unlock(&hp->mtx); Lck_Unlock(&hp->mtx);
if (he == NULL) return (ret);
return (1);
free(he);
return (0);
} }
/*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------*/
......
...@@ -33,23 +33,17 @@ ...@@ -33,23 +33,17 @@
#include "config.h" #include "config.h"
#include <sys/types.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "shmlog.h" #include "shmlog.h"
#include "cache.h" #include "cache.h"
#include "hash_slinger.h"
/*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------*/
struct hsl_entry { static VTAILQ_HEAD(, objhead) hsl_head = VTAILQ_HEAD_INITIALIZER(hsl_head);
VTAILQ_ENTRY(hsl_entry) list;
struct objhead *oh;
};
static VTAILQ_HEAD(, hsl_entry) hsl_head = VTAILQ_HEAD_INITIALIZER(hsl_head);
static struct lock hsl_mtx; static struct lock hsl_mtx;
/*-------------------------------------------------------------------- /*--------------------------------------------------------------------
...@@ -74,38 +68,28 @@ hsl_start(void) ...@@ -74,38 +68,28 @@ hsl_start(void)
static struct objhead * static struct objhead *
hsl_lookup(const struct sess *sp, struct objhead *noh) hsl_lookup(const struct sess *sp, struct objhead *noh)
{ {
struct hsl_entry *he, *he2; struct objhead *oh;
int i; int i;
Lck_Lock(&hsl_mtx); Lck_Lock(&hsl_mtx);
VTAILQ_FOREACH(he, &hsl_head, list) { VTAILQ_FOREACH(oh, &hsl_head, hoh_list) {
i = HSH_Compare(sp, he->oh); i = HSH_Compare(sp, oh);
if (i < 0) if (i < 0)
continue; continue;
if (i > 0) if (i > 0)
break; break;
he->oh->refcnt++; oh->refcnt++;
noh = he->oh;
Lck_Unlock(&hsl_mtx); Lck_Unlock(&hsl_mtx);
return (noh); return (oh);
}
if (noh != NULL) {
he2 = calloc(sizeof *he2, 1);
XXXAN(he2);
he2->oh = noh;
he2->oh->refcnt = 1;
noh->hashpriv = he2;
noh->hash = malloc(sp->lhashptr);
XXXAN(noh->hash);
noh->hashlen = sp->lhashptr;
HSH_Copy(sp, noh);
if (he != NULL)
VTAILQ_INSERT_BEFORE(he, he2, list);
else
VTAILQ_INSERT_TAIL(&hsl_head, he2, list);
} }
if (oh != NULL)
VTAILQ_INSERT_BEFORE(oh, noh, hoh_list);
else
VTAILQ_INSERT_TAIL(&hsl_head, noh, hoh_list);
HSH_Copy(sp, noh);
Lck_Unlock(&hsl_mtx); Lck_Unlock(&hsl_mtx);
return (noh); return (noh);
} }
...@@ -115,17 +99,13 @@ hsl_lookup(const struct sess *sp, struct objhead *noh) ...@@ -115,17 +99,13 @@ hsl_lookup(const struct sess *sp, struct objhead *noh)
*/ */
static int static int
hsl_deref(const struct objhead *oh) hsl_deref(struct objhead *oh)
{ {
struct hsl_entry *he;
int ret; int ret;
AN(oh->hashpriv);
he = oh->hashpriv;
Lck_Lock(&hsl_mtx); Lck_Lock(&hsl_mtx);
if (--he->oh->refcnt == 0) { if (--oh->refcnt == 0) {
VTAILQ_REMOVE(&hsl_head, he, list); VTAILQ_REMOVE(&hsl_head, oh, hoh_list);
free(he);
ret = 0; ret = 0;
} else } else
ret = 1; ret = 1;
......
...@@ -30,12 +30,13 @@ ...@@ -30,12 +30,13 @@
*/ */
struct sess; struct sess;
struct object;
typedef void hash_init_f(int ac, char * const *av); typedef void hash_init_f(int ac, char * const *av);
typedef void hash_start_f(void); typedef void hash_start_f(void);
typedef struct objhead * typedef struct objhead *
hash_lookup_f(const struct sess *sp, struct objhead *nobj); hash_lookup_f(const struct sess *sp, struct objhead *nobj);
typedef int hash_deref_f(const struct objhead *obj); typedef int hash_deref_f(struct objhead *obj);
struct hash_slinger { struct hash_slinger {
unsigned magic; unsigned magic;
...@@ -46,3 +47,38 @@ struct hash_slinger { ...@@ -46,3 +47,38 @@ struct hash_slinger {
hash_lookup_f *lookup; hash_lookup_f *lookup;
hash_deref_f *deref; hash_deref_f *deref;
}; };
/* cache_hash.c */
void HSH_Prealloc(struct sess *sp);
void HSH_Freestore(struct object *o);
int HSH_Compare(const struct sess *sp, const struct objhead *o);
void HSH_Copy(const struct sess *sp, struct objhead *o);
struct object *HSH_Lookup(struct sess *sp);
void HSH_Unbusy(const struct sess *sp);
void HSH_Ref(struct object *o);
void HSH_Deref(struct object *o);
double HSH_Grace(double g);
void HSH_Init(void);
#ifdef VARNISH_CACHE_CHILD
struct objhead {
unsigned magic;
#define OBJHEAD_MAGIC 0x1b96615d
struct lock mtx;
unsigned refcnt;
VTAILQ_HEAD(,object) objects;
char *hash;
unsigned hashlen;
VTAILQ_HEAD(, sess) waitinglist;
/*------------------------------------------------------------
* The fields below are for the sole private use of the hash
* implementation.
*/
VTAILQ_ENTRY(objhead) hoh_list;
void *hoh_head;
unsigned hoh_digest;
};
#endif /* VARNISH_CACHE_CHILD */
...@@ -42,6 +42,7 @@ ...@@ -42,6 +42,7 @@
#include "cache.h" #include "cache.h"
#include "vsb.h" #include "vsb.h"
#include "stevedore.h" #include "stevedore.h"
#include "hash_slinger.h"
static struct lock sms_mtx; static struct lock sms_mtx;
......
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