test_min_heap.c revision 9a690580
1/* Copyright (c) 2017 - 2020 LiteSpeed Technologies Inc.  See LICENSE. */
2/* Test min heap or benchmark heap creation */
3
4/* Floyd mechanism has been removed.  It's not faster. */
5#define FLOYD 0
6
7#include <assert.h>
8#include <stddef.h>
9#include <stdint.h>
10#include <stdio.h>
11#include <stdlib.h>
12
13#include "lsquic_min_heap.h"
14
15static void
16verify_min_heap (const struct min_heap *heap)
17{
18    unsigned i;
19
20    for (i = 0; i < heap->mh_nelem; ++i)
21    {
22        if (MHE_LCHILD(i) < heap->mh_nelem)
23            assert(heap->mh_elems[i].mhe_val <=
24                        heap->mh_elems[MHE_LCHILD(i)].mhe_val);
25        if (MHE_RCHILD(i) < heap->mh_nelem)
26            assert(heap->mh_elems[i].mhe_val <=
27                        heap->mh_elems[MHE_RCHILD(i)].mhe_val);
28    }
29}
30
31
32#define MAX_ELEMS 1000
33
34static void
35test_min_heap (void)
36{
37    struct min_heap heap;
38    uint64_t i, prev_val;
39    void *p;
40    struct min_heap_elem els[MAX_ELEMS];
41
42    heap.mh_elems = els;
43    heap.mh_nalloc = MAX_ELEMS;
44
45    heap.mh_nelem = 0;
46    for (i = 0; i < MAX_ELEMS; ++i)
47        lsquic_mh_insert(&heap, (void *) i, i);
48    verify_min_heap(&heap);
49    for (i = 0; i < MAX_ELEMS; ++i)
50    {
51        p = lsquic_mh_pop(&heap);
52        if (i)
53            assert((uintptr_t) p >= prev_val);
54        prev_val = (uintptr_t) p;
55    }
56
57    heap.mh_nelem = 0;
58    for (i = MAX_ELEMS; i > 0; --i)
59        lsquic_mh_insert(&heap, (void *) i, i);
60    verify_min_heap(&heap);
61    for (i = 0; i < MAX_ELEMS; ++i)
62    {
63        p = lsquic_mh_pop(&heap);
64        if (i)
65            assert((uintptr_t) p >= prev_val);
66        prev_val = (uintptr_t) p;
67    }
68
69    heap.mh_nelem = 0;
70
71#if FLOYD
72    /* Now use Floyd method */
73    heap.mh_nelem = 0;
74    for (i = 0; i < MAX_ELEMS; ++i)
75        lsquic_mh_push(&heap, NULL, i);
76    lsquic_mh_heapify(&heap);
77    verify_min_heap(&heap);
78
79    heap.mh_nelem = 0;
80    for (i = MAX_ELEMS; i > 0; --i)
81        lsquic_mh_push(&heap, NULL, i);
82    lsquic_mh_heapify(&heap);
83    verify_min_heap(&heap);
84#endif
85}
86
87
88int
89main (int argc, char **argv)
90{
91    if (argc == 1)
92    {
93        test_min_heap();
94        return 0;
95    }
96
97    if (argc != 4)
98    {
99        fprintf(stderr, "usage: %s nelems iters method\n"
100                        "  method is 0: insert; 1: floyd\n", argv[0]);
101        return 1;
102    }
103
104    unsigned i, j, n_iters, nelems;
105    struct min_heap_elem *els;
106    unsigned *vals;
107    struct min_heap heap;
108
109    nelems = atoi(argv[1]);
110    n_iters = atoi(argv[2]);
111#if FLOYD
112    const int floyd = atoi(argv[3]);
113#endif
114
115    vals = malloc(sizeof(vals[0]) * nelems);
116    assert(vals);
117    for (i = 0; i < nelems; ++i)
118        vals[i] = rand();
119    els = malloc(sizeof(els[0]) * nelems);
120    assert(els);
121    heap.mh_elems = els;
122    heap.mh_nalloc = nelems;
123    heap.mh_nelem = 0;
124#if FLOYD
125    if (floyd)
126    {
127        for (i = 0; i < nelems; ++i)
128            lsquic_mh_push(&heap, NULL, vals[i]);
129        lsquic_mh_heapify(&heap);
130    }
131    else
132#endif
133        for (i = 0; i < nelems; ++i)
134            lsquic_mh_insert(&heap, NULL, vals[i]);
135    verify_min_heap(&heap);
136
137#if FLOYD
138    if (floyd)
139    {
140        for (j = 0; j < n_iters; ++j)
141        {
142            heap.mh_nelem = 0;
143            for (i = 0; i < nelems; ++i)
144                lsquic_mh_push(&heap, NULL, vals[i]);
145            lsquic_mh_heapify(&heap);
146        }
147    }
148    else
149#endif
150    {
151        for (j = 0; j < n_iters; ++j)
152        {
153            heap.mh_nelem = 0;
154            for (i = 0; i < nelems; ++i)
155                lsquic_mh_insert(&heap, NULL, vals[i]);
156        }
157    }
158
159    free(els);
160    free(vals);
161    return 0;
162}
163