r2388 - trunk/varnish-cache/bin/varnishd

phk at projects.linpro.no phk at projects.linpro.no
Mon Jan 28 09:46:15 CET 2008


Author: phk
Date: 2008-01-28 09:46:15 +0100 (Mon, 28 Jan 2008)
New Revision: 2388

Modified:
   trunk/varnish-cache/bin/varnishd/cache_hash.c
Log:
Deoptimize the central object matching loop in the hash code:

With the advent of prefetch and degraded mode, the invariants of
objectheads change so that more than one object can be busy at any
one time.

Thus we can no longer assume that the busy object or one subsequent to
it, is the one we eventually desire, and we must start our search from
the front of the list again.

As an amusing sidenote: this eliminates the only "goto" in all of varnishd.



Modified: trunk/varnish-cache/bin/varnishd/cache_hash.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_hash.c	2008-01-25 16:00:42 UTC (rev 2387)
+++ trunk/varnish-cache/bin/varnishd/cache_hash.c	2008-01-28 08:46:15 UTC (rev 2388)
@@ -185,44 +185,44 @@
 	HSH_Prealloc(sp);
 	if (sp->obj != NULL) {
 		CHECK_OBJ_NOTNULL(sp->obj, OBJECT_MAGIC);
-		o = sp->obj;
-		oh = o->objhead;
+		oh = sp->obj->objhead;
+		HSH_Deref(sp->obj);
 		CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC);
 		LOCK(&oh->mtx);
-		goto were_back;
+	} else {
+		oh = hash->lookup(sp, w->nobjhead);
+		CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC);
+		if (oh == w->nobjhead)
+			w->nobjhead = NULL;
+		LOCK(&oh->mtx);
 	}
 
-	oh = hash->lookup(sp, w->nobjhead);
-	CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC);
-	if (oh == w->nobjhead)
-		w->nobjhead = NULL;
-	LOCK(&oh->mtx);
 	VTAILQ_FOREACH(o, &oh->objects, list) {
-		o->refcnt++;
 		if (o->busy) {
 			VTAILQ_INSERT_TAIL(&o->waitinglist, sp, list);
 			sp->obj = o;
+			o->refcnt++;
 			UNLOCK(&oh->mtx);
 			return (NULL);
 		}
-	were_back:
-		if (!o->cacheable) {
-			/* ignore */
-		} else if (o->ttl == 0) {
-			/* Object banned but not reaped yet */
-		} else if (o->ttl <= sp->t_req) {
-			/* Object expired */
-		} else if (BAN_CheckObject(o,
-		    h->hd[HTTP_HDR_URL].b, oh->hash)) {
+		if (!o->cacheable)
+			continue;
+		if (o->ttl == 0) 
+			continue;
+		if (o->ttl <= sp->t_req) 
+			continue;
+		if (BAN_CheckObject(o, h->hd[HTTP_HDR_URL].b, oh->hash)) {
 			o->ttl = 0;
 			WSP(sp, SLT_ExpBan, "%u was banned", o->xid);
 			if (o->timer_idx != 0)
 				EXP_TTLchange(o);
-		} else if (o->vary == NULL || VRY_Match(sp, o->vary))
+			continue;
+		}
+		if (o->vary == NULL || VRY_Match(sp, o->vary))
 			break;
-		o->refcnt--;
 	}
 	if (o != NULL) {
+		o->refcnt++;
 		UNLOCK(&oh->mtx);
 		(void)hash->deref(oh);
 		return (o);




More information about the varnish-commit mailing list