[experimental-ims] 12a3f19 Polish up the unit-test case for the binheap, looking for #967

Geoff Simmons geoff at varnish-cache.org
Wed Aug 31 16:00:26 CEST 2011


commit 12a3f19d8d2bbbde3797e621fc6a46e1c4f5cd1c
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Thu Aug 11 08:40:01 2011 +0000

    Polish up the unit-test case for the binheap, looking for #967

diff --git a/lib/libvarnish/binary_heap.c b/lib/libvarnish/binary_heap.c
index e6a00e7..6eb454b 100644
--- a/lib/libvarnish/binary_heap.c
+++ b/lib/libvarnish/binary_heap.c
@@ -28,8 +28,9 @@
  *
  * Implementation of a binary heap API
  *
- * We use a malloc(3)/realloc(3) array to store the pointers using the
- * classical FORTRAN strategy.
+ * See also:
+ *	http://portal.acm.org/citation.cfm?doid=1785414.1785434
+ *	(or: http://queue.acm.org/detail.cfm?id=1814327)
  */
 
 #include "config.h"
@@ -392,25 +393,45 @@ binheap_reorder(const struct binheap *bh, unsigned idx)
 #ifdef TEST_DRIVER
 /* Test driver -------------------------------------------------------*/
 #include <stdio.h>
+#include <miniobj.h>
+
+static void
+vasfail(const char *func, const char *file, int line,
+    const char *cond, int err, int xxx)
+{
+	fprintf(stderr, "PANIC: %s %s %d %s %d %d\n",
+		func, file, line, cond, err, xxx);
+	abort();
+}
+
+vas_f *VAS_Fail = vasfail;
 
 struct foo {
+	unsigned	magic;
+#define FOO_MAGIC	0x23239823
 	unsigned	idx;
 	unsigned	key;
+	unsigned	n;
 };
 
+#if 1
 #define M 31011091	/* Number of operations */
-#define N 10313102		/* Number of items */
+#define N 10313102	/* Number of items */
+#else
+#define M 3401		/* Number of operations */
+#define N 1131		/* Number of items */
+#endif
 #define R -1		/* Random modulus */
 
-struct foo ff[N];
+struct foo *ff[N];
 
 static int
 cmp(void *priv, void *a, void *b)
 {
 	struct foo *fa, *fb;
 
-	fa = a;
-	fb = b;
+	CAST_OBJ_NOTNULL(fa, a, FOO_MAGIC);
+	CAST_OBJ_NOTNULL(fb, b, FOO_MAGIC);
 	return (fa->key < fb->key);
 }
 
@@ -419,12 +440,12 @@ update(void *priv, void *a, unsigned u)
 {
 	struct foo *fa;
 
-	fa = a;
+	CAST_OBJ_NOTNULL(fa, a, FOO_MAGIC);
 	fa->idx = u;
 }
 
 void
-chk(struct binheap *bh)
+chk2(struct binheap *bh)
 {
 	unsigned u, v;
 	struct foo *fa, *fb;
@@ -441,7 +462,7 @@ int
 main(int argc, char **argv)
 {
 	struct binheap *bh;
-	unsigned u, v, lr;
+	unsigned u, v, lr, n;
 	struct foo *fp;
 
 	if (0) {
@@ -452,58 +473,80 @@ main(int argc, char **argv)
 	}
 	bh = binheap_new(NULL, cmp, update);
 
-	/* First insert our N elements */
-	for (u = 0; u < N; u++) {
-		lr = random() % R;
-		ff[u].key = lr;
-		binheap_insert(bh, &ff[u]);
-
-		fp = binheap_root(bh);
-		assert(fp->idx == 1);
-		assert(fp->key <= lr);
-	}
-	fprintf(stderr, "%d inserts OK\n", N);
-	/* For M cycles, pick the root, insert new */
-	for (u = 0; u < M; u++) {
-		fp = binheap_root(bh);
-		assert(fp->idx == 1);
-
-		/* It cannot possibly be larger than the last value we added */
-		assert(fp->key <= lr);
-		binheap_delete(bh, fp->idx);
-
-		lr = random() % R;
-		fp->key = lr;
-		binheap_insert(bh, fp);
-	}
-	fprintf(stderr, "%d replacements OK\n", M);
-	/* The remove everything */
-	lr = 0;
-	for (u = 0; u < N; u++) {
-		fp = binheap_root(bh);
-		assert(fp->idx == 1);
-		assert(fp->key >= lr);
-		lr = fp->key;
-		binheap_delete(bh, fp->idx);
-	}
-	fprintf(stderr, "%d removes OK\n", N);
-
-	for (u = 0; u < M; u++) {
-		v = random() % N;
-		if (ff[v].idx > 0) {
-			assert(ff[v].idx != 0);
-			binheap_delete(bh, ff[v].idx);
-			assert(ff[v].idx == 0);
-		} else {
-			assert(ff[v].idx == 0);
-			ff[v].key = random() % R;
-			binheap_insert(bh, &ff[v]);
-			assert(ff[v].idx != 0);
+	while (1) {
+		/* First insert our N elements */
+		for (u = 0; u < N; u++) {
+			lr = random() % R;
+			ALLOC_OBJ(ff[u], FOO_MAGIC);
+			assert(ff[u] != NULL);
+			ff[u]->key = lr;
+			ff[u]->n = u;
+			binheap_insert(bh, ff[u]);
+
+			fp = binheap_root(bh);
+			assert(fp->idx == 1);
+			assert(fp->key <= lr);
+		}
+		fprintf(stderr, "%d inserts OK\n", N);
+		/* For M cycles, pick the root, insert new */
+		for (u = 0; u < M; u++) {
+			fp = binheap_root(bh);
+			CHECK_OBJ_NOTNULL(fp, FOO_MAGIC);
+			assert(fp->idx == 1);
+
+			/* It cannot possibly be larger than the last value we added */
+			assert(fp->key <= lr);
+			binheap_delete(bh, fp->idx);
+			
+			
+			n = fp->n;
+			ALLOC_OBJ(ff[n], FOO_MAGIC);
+			assert(ff[n] != NULL);
+			FREE_OBJ(fp);
+			fp = ff[n];
+			fp->n = n;
+
+			lr = random() % R;
+			fp->key = lr;
+			binheap_insert(bh, fp);
+		}
+		fprintf(stderr, "%d replacements OK\n", M);
+		/* The remove everything */
+		lr = 0;
+		for (u = 0; u < N; u++) {
+			fp = binheap_root(bh);
+			CHECK_OBJ_NOTNULL(fp, FOO_MAGIC);
+			assert(fp->idx == 1);
+			assert(fp->key >= lr);
+			lr = fp->key;
+			binheap_delete(bh, fp->idx);
+			ff[fp->n] = NULL;
+			FREE_OBJ(fp);
+		}
+		fprintf(stderr, "%d removes OK\n", N);
+
+		for (u = 0; u < M; u++) {
+			v = random() % N;
+			if (ff[v] != NULL) {
+				CHECK_OBJ_NOTNULL(ff[v], FOO_MAGIC);
+				assert(ff[v]->idx != 0);
+				binheap_delete(bh, ff[v]->idx);
+				assert(ff[v]->idx == 0);
+				FREE_OBJ(ff[v]);
+				ff[v] = NULL;
+			} else {
+				ALLOC_OBJ(ff[v], FOO_MAGIC);
+				assert(ff[v] != NULL);
+				ff[v]->key = random() % R;
+				binheap_insert(bh, ff[v]);
+				CHECK_OBJ_NOTNULL(ff[v], FOO_MAGIC);
+				assert(ff[v]->idx != 0);
+			}
+			if (0)
+				chk2(bh);
 		}
-		if (0)
-			chk(bh);
+		fprintf(stderr, "%d updates OK\n", M);
 	}
-	fprintf(stderr, "%d updates OK\n", M);
 	return (0);
 }
 #endif



More information about the varnish-commit mailing list