r3918 - in trunk/varnish-cache/bin: varnishd varnishtest/tests

phk at projects.linpro.no phk at projects.linpro.no
Thu Mar 12 11:08:44 CET 2009


Author: phk
Date: 2009-03-12 11:08:44 +0100 (Thu, 12 Mar 2009)
New Revision: 3918

Added:
   trunk/varnish-cache/bin/varnishtest/tests/p0001.vtc
Modified:
   trunk/varnish-cache/bin/varnishd/cache.h
   trunk/varnish-cache/bin/varnishd/cache_ban.c
   trunk/varnish-cache/bin/varnishd/cache_expire.c
   trunk/varnish-cache/bin/varnishd/cache_hash.c
   trunk/varnish-cache/bin/varnishd/storage_persistent.c
Log:
Break down and give the objcore a back pointer to the SMP segment,
we cannot do the accounting without it in a reasonably fast manner.

Keep track of how many fixed and unfixed objects we have in a segment.

Update the object directory when TTL or BAN pointer changes.

Add a testcase for TTL changes.

Don't walk the storage list when we delete a persistent object, just
decrement the segments object count.




Modified: trunk/varnish-cache/bin/varnishd/cache.h
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache.h	2009-03-12 09:03:06 UTC (rev 3917)
+++ trunk/varnish-cache/bin/varnishd/cache.h	2009-03-12 10:08:44 UTC (rev 3918)
@@ -93,7 +93,9 @@
 struct cli_proto;
 struct ban;
 struct SHA256Context;
+
 struct smp_object;
+struct smp_seg;
 
 struct lock { void *priv; };		// Opaque
 
@@ -287,6 +289,7 @@
 	unsigned		timer_idx;
 	VTAILQ_ENTRY(objcore)	list;
 	VTAILQ_ENTRY(objcore)	lru_list;
+	struct smp_seg		*smp_seg;
 };
 
 /* Object structure --------------------------------------------------*/
@@ -300,7 +303,7 @@
 	struct storage		*objstore;
 	struct objcore		*objcore;
 
-	struct smp_object	*smp;
+	struct smp_object	*smp_object;
 
 	struct ws		ws_o[1];
 	unsigned char		*vary;
@@ -664,8 +667,9 @@
 
 /* storage_persistent.c */
 void SMP_Fixup(struct sess *sp, struct objhead *oh, struct objcore *oc);
-void SMP_BANchanged(const struct object *o);
+void SMP_BANchanged(const struct object *o, double t);
 void SMP_TTLchanged(const struct object *o);
+void SMP_FreeObj(struct object *o);
 
 /*
  * A normal pointer difference is signed, but we never want a negative value

Modified: trunk/varnish-cache/bin/varnishd/cache_ban.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_ban.c	2009-03-12 09:03:06 UTC (rev 3917)
+++ trunk/varnish-cache/bin/varnishd/cache_ban.c	2009-03-12 10:08:44 UTC (rev 3918)
@@ -528,13 +528,13 @@
 
 	if (b == o->ban) {	/* not banned */
 		o->ban = b0;
-		if (o->smp != NULL)
-			SMP_BANchanged(o);
+		if (o->smp_object != NULL)
+			SMP_BANchanged(o, b0->t0);
 		return (0);
 	} else {
 		o->ttl = 0;
 		o->ban = NULL;
-		if (o->smp != NULL)
+		if (o->smp_object != NULL)
 			SMP_TTLchanged(o);
 		/* BAN also changed, but that is not important any more */
 		WSP(sp, SLT_ExpBan, "%u was banned", o->xid);

Modified: trunk/varnish-cache/bin/varnishd/cache_expire.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_expire.c	2009-03-12 09:03:06 UTC (rev 3917)
+++ trunk/varnish-cache/bin/varnishd/cache_expire.c	2009-03-12 10:08:44 UTC (rev 3918)
@@ -127,7 +127,7 @@
 	VTAILQ_INSERT_TAIL(&lru, oc, lru_list);
 	oc->flags |= OC_F_ONLRU;
 	Lck_Unlock(&exp_mtx);
-	if (o->smp != NULL)
+	if (o->smp_object != NULL)
 		SMP_TTLchanged(o);
 }
 
@@ -201,7 +201,7 @@
 		assert(oc->timer_idx != BINHEAP_NOIDX);
 	}
 	Lck_Unlock(&exp_mtx);
-	if (o->smp != NULL)
+	if (o->smp_object != NULL)
 		SMP_TTLchanged(o);
 }
 

Modified: trunk/varnish-cache/bin/varnishd/cache_hash.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_hash.c	2009-03-12 09:03:06 UTC (rev 3917)
+++ trunk/varnish-cache/bin/varnishd/cache_hash.c	2009-03-12 10:08:44 UTC (rev 3918)
@@ -406,6 +406,8 @@
 	VTAILQ_INSERT_TAIL(&oh->objcs, oc, list);
 	/* NB: do not deref objhead the new object inherits our reference */
 	Lck_Unlock(&oh->mtx);
+
+	/* XXX: Insert in EXP */
 	return (oc);
 }
 
@@ -690,11 +692,15 @@
 		free(o->vary);
 
 	ESI_Destroy(o);
-	HSH_Freestore(o);
-	if (o->objstore != NULL)
-		STV_free(o->objstore);
-	else
-		FREE_OBJ(o);
+	if (o->smp_object != NULL) {
+		SMP_FreeObj(o);
+	} else {
+		HSH_Freestore(o);
+		if (o->objstore != NULL)
+			STV_free(o->objstore);
+		else
+			FREE_OBJ(o);
+	}
 	o = NULL;
 	w->stats->n_object--;
 

Modified: trunk/varnish-cache/bin/varnishd/storage_persistent.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/storage_persistent.c	2009-03-12 09:03:06 UTC (rev 3917)
+++ trunk/varnish-cache/bin/varnishd/storage_persistent.c	2009-03-12 10:08:44 UTC (rev 3918)
@@ -58,18 +58,29 @@
 #define MAP_NOSYNC 0 /* XXX Linux */
 #endif
 
+struct smp_sc;
+
 /* XXX: name confusion with on-media version ? */
 struct smp_seg {
 	unsigned		magic;
 #define SMP_SEG_MAGIC		0x45c61895
-	VTAILQ_ENTRY(smp_seg)	list;
-	uint64_t		offset;
+
+	struct smp_sc		*sc;
+
+	VTAILQ_ENTRY(smp_seg)	list;		/* on smp_sc.smp_segments */
+
+	uint64_t		offset;		/* coordinates in silo */
 	uint64_t		length;
-	struct smp_segment	segment;
-	uint32_t		nalloc;
-	uint32_t		maxobj;
-	struct smp_object	*objs;
-	uint64_t		next_addr;
+
+	struct smp_segment	segment;	/* Copy of on-disk desc. */
+
+	uint32_t		nalloc;		/* How many live objects */
+	uint32_t		nfixed;		/* How many fixed objects */
+
+	/* Only for open segment */
+	uint32_t		maxobj;		/* Max number of objects */
+	struct smp_object	*objs;		/* objdesc copy */
+	uint64_t		next_addr;	/* next write address */
 };
 
 VTAILQ_HEAD(smp_seghead, smp_seg);
@@ -420,18 +431,23 @@
 void
 SMP_Fixup(struct sess *sp, struct objhead *oh, struct objcore *oc)
 {
+	struct smp_seg *sg;
 	struct smp_object *so;
 
+	sg = oc->smp_seg;
+	CHECK_OBJ_NOTNULL(sg, SMP_SEG_MAGIC);
+
 fprintf(stderr, "Fixup %p %p\n", sp, oc);
 
 	so = (void*)oc->obj;
 	oc->obj = so->ptr;
 
-	/* XXX: This should fail gracefully */
+	/* XXX: This check should fail gracefully */
 	CHECK_OBJ_NOTNULL(oc->obj, OBJECT_MAGIC);
 
-	oc->obj->smp = so;
+	oc->obj->smp_object = so;
 
+	AN(oc->flags & OC_F_PERSISTENT);
 	oc->flags &= ~OC_F_PERSISTENT;
 
 	oc->obj->refcnt = 0;
@@ -441,6 +457,8 @@
 	/* XXX: Placeholder for persistent bans */
 	oc->obj->ban = NULL;
 	BAN_NewObj(oc->obj);
+
+	sg->nfixed++;
 }
 
 /*--------------------------------------------------------------------
@@ -448,16 +466,50 @@
  */
 
 void
-SMP_BANchanged(const struct object *o)
+SMP_FreeObj(struct object *o)
 {
-	assert(o->smp != NULL);
+	struct smp_seg *sg;
+
+	AN(o->smp_object);
+	CHECK_OBJ_NOTNULL(o->objcore, OBJCORE_MAGIC);
+	AZ(o->objcore->flags & OC_F_PERSISTENT);
+	sg = o->objcore->smp_seg;
+	CHECK_OBJ_NOTNULL(sg, SMP_SEG_MAGIC);
+
+	o->smp_object->ttl = 0;
+	assert(sg->nalloc > 0);
+	sg->nalloc--;
+	sg->nfixed--;
+
+	/* XXX: check if seg is empty, or leave to thread ? */
 }
 
 void
+SMP_BANchanged(const struct object *o, double t)
+{
+	struct smp_seg *sg;
+
+	AN(o->smp_object);
+	CHECK_OBJ_NOTNULL(o->objcore, OBJCORE_MAGIC);
+	sg = o->objcore->smp_seg;
+	CHECK_OBJ_NOTNULL(sg, SMP_SEG_MAGIC);
+	CHECK_OBJ_NOTNULL(sg->sc, SMP_SC_MAGIC);
+
+	o->smp_object->ban = t;
+}
+
+void
 SMP_TTLchanged(const struct object *o)
 {
+	struct smp_seg *sg;
 
-	assert(o->smp != NULL);
+	AN(o->smp_object);
+	CHECK_OBJ_NOTNULL(o->objcore, OBJCORE_MAGIC);
+	sg = o->objcore->smp_seg;
+	CHECK_OBJ_NOTNULL(sg, SMP_SEG_MAGIC);
+	CHECK_OBJ_NOTNULL(sg->sc, SMP_SC_MAGIC);
+
+	o->smp_object->ttl = o->ttl;
 }
 
 /*--------------------------------------------------------------------
@@ -493,6 +545,7 @@
 	so = (void*)(sc->ptr + ss->objlist);
 	no = ss->nalloc;
 	for (;no > 0; so++,no--) {
+fprintf(stderr, "TTL: %g %g (%g)\n", so->ttl, t_now, so->ttl - t_now);
 		if (so->ttl < t_now)
 			continue;
 		fprintf(stderr, "OBJ %p dTTL: %g PTR %p\n",
@@ -501,9 +554,12 @@
 		sp->wrk->nobjcore->flags |= OC_F_PERSISTENT;
 		sp->wrk->nobjcore->flags &= ~OC_F_BUSY;
 		sp->wrk->nobjcore->obj = (void*)so;
+		sp->wrk->nobjcore->smp_seg = sg;
 		memcpy(sp->wrk->nobjhead->digest, so->hash, SHA256_LEN);
 		(void)HSH_Insert(sp);
+		sg->nalloc++;
 	}
+fprintf(stderr, "Got %u objects in seg %p\n", sg->nalloc, sg);
 }
 
 /*--------------------------------------------------------------------
@@ -527,6 +583,7 @@
 		AN(sg);
 		sg->offset = ss->offset;
 		sg->length = ss->length;
+		sg->sc = sc;
 		VTAILQ_INSERT_TAIL(&sc->segments, sg, list);
 fprintf(stderr, "RD SEG %jx %jx\n", sg->offset, sg->length);
 	}

Added: trunk/varnish-cache/bin/varnishtest/tests/p0001.vtc
===================================================================
--- trunk/varnish-cache/bin/varnishtest/tests/p0001.vtc	                        (rev 0)
+++ trunk/varnish-cache/bin/varnishtest/tests/p0001.vtc	2009-03-12 10:08:44 UTC (rev 3918)
@@ -0,0 +1,63 @@
+# $Id$
+
+test "Change TTL on persistent object"
+
+shell "rm -f /tmp/__v1/_.per"
+
+server s1 {
+	rxreq 
+	txresp -hdr "Foo: foo"
+} -start
+
+varnish v1 \
+	-arg "-spersistent,/tmp/__v1/_.per,10m" -vcl+backend { } -start 
+
+client c1 {
+	txreq -url "/"
+	rxresp
+	expect resp.status == 200
+	expect resp.http.X-Varnish == "1001"
+	expect resp.http.foo == "foo"
+} -run
+
+varnish v1 -stop
+server s1 -wait
+
+varnish v1 -vcl+backend {
+	sub vcl_hit {
+		set obj.ttl = 1 s;
+	}
+}
+
+varnish v1 -start
+
+client c1 {
+	txreq -url "/"
+	rxresp
+	expect resp.status == 200
+	expect resp.http.X-Varnish == "1001"
+	expect resp.http.foo == "foo"
+} -run
+
+varnish v1 -stop
+
+varnish v1 -vcl+backend { }
+
+delay 2
+
+varnish v1 -start
+
+server s1 {
+	rxreq 
+	txresp -hdr "Foo: bar"
+} -start
+
+client c1 {
+	txreq -url "/"
+	rxresp
+	expect resp.status == 200
+	expect resp.http.X-Varnish == "1001"
+	expect resp.http.foo == "bar"
+} -run
+
+# shell "rm -f /tmp/__v1/_.per"



More information about the varnish-commit mailing list