Commit 12a3f19d authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

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

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