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,11 +473,15 @@ main(int argc, char **argv) ...@@ -452,11 +473,15 @@ main(int argc, char **argv)
} }
bh = binheap_new(NULL, cmp, update); bh = binheap_new(NULL, cmp, update);
while (1) {
/* First insert our N elements */ /* First insert our N elements */
for (u = 0; u < N; u++) { for (u = 0; u < N; u++) {
lr = random() % R; lr = random() % R;
ff[u].key = lr; ALLOC_OBJ(ff[u], FOO_MAGIC);
binheap_insert(bh, &ff[u]); assert(ff[u] != NULL);
ff[u]->key = lr;
ff[u]->n = u;
binheap_insert(bh, ff[u]);
fp = binheap_root(bh); fp = binheap_root(bh);
assert(fp->idx == 1); assert(fp->idx == 1);
...@@ -466,12 +491,21 @@ main(int argc, char **argv) ...@@ -466,12 +491,21 @@ main(int argc, char **argv)
/* For M cycles, pick the root, insert new */ /* For M cycles, pick the root, insert new */
for (u = 0; u < M; u++) { for (u = 0; u < M; u++) {
fp = binheap_root(bh); fp = binheap_root(bh);
CHECK_OBJ_NOTNULL(fp, FOO_MAGIC);
assert(fp->idx == 1); assert(fp->idx == 1);
/* It cannot possibly be larger than the last value we added */ /* It cannot possibly be larger than the last value we added */
assert(fp->key <= lr); assert(fp->key <= lr);
binheap_delete(bh, fp->idx); 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; lr = random() % R;
fp->key = lr; fp->key = lr;
binheap_insert(bh, fp); binheap_insert(bh, fp);
...@@ -481,29 +515,38 @@ main(int argc, char **argv) ...@@ -481,29 +515,38 @@ main(int argc, char **argv)
lr = 0; lr = 0;
for (u = 0; u < N; u++) { for (u = 0; u < N; u++) {
fp = binheap_root(bh); fp = binheap_root(bh);
CHECK_OBJ_NOTNULL(fp, FOO_MAGIC);
assert(fp->idx == 1); assert(fp->idx == 1);
assert(fp->key >= lr); assert(fp->key >= lr);
lr = fp->key; lr = fp->key;
binheap_delete(bh, fp->idx); binheap_delete(bh, fp->idx);
ff[fp->n] = NULL;
FREE_OBJ(fp);
} }
fprintf(stderr, "%d removes OK\n", N); fprintf(stderr, "%d removes OK\n", N);
for (u = 0; u < M; u++) { for (u = 0; u < M; u++) {
v = random() % N; v = random() % N;
if (ff[v].idx > 0) { if (ff[v] != NULL) {
assert(ff[v].idx != 0); CHECK_OBJ_NOTNULL(ff[v], FOO_MAGIC);
binheap_delete(bh, ff[v].idx); assert(ff[v]->idx != 0);
assert(ff[v].idx == 0); binheap_delete(bh, ff[v]->idx);
assert(ff[v]->idx == 0);
FREE_OBJ(ff[v]);
ff[v] = NULL;
} else { } else {
assert(ff[v].idx == 0); ALLOC_OBJ(ff[v], FOO_MAGIC);
ff[v].key = random() % R; assert(ff[v] != NULL);
binheap_insert(bh, &ff[v]); ff[v]->key = random() % R;
assert(ff[v].idx != 0); binheap_insert(bh, ff[v]);
CHECK_OBJ_NOTNULL(ff[v], FOO_MAGIC);
assert(ff[v]->idx != 0);
} }
if (0) if (0)
chk(bh); chk2(bh);
} }
fprintf(stderr, "%d updates OK\n", M); 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