xref: /freebsd/sys/netpfil/ipfw/test/test_dn_heap.c (revision 3b3a8eb937bf8045231e8364bfd1b94cd4a95979)
1*3b3a8eb9SGleb Smirnoff /*-
2*3b3a8eb9SGleb Smirnoff  * Copyright (c) 1998-2002,2010 Luigi Rizzo, Universita` di Pisa
3*3b3a8eb9SGleb Smirnoff  * All rights reserved
4*3b3a8eb9SGleb Smirnoff  *
5*3b3a8eb9SGleb Smirnoff  * Redistribution and use in source and binary forms, with or without
6*3b3a8eb9SGleb Smirnoff  * modification, are permitted provided that the following conditions
7*3b3a8eb9SGleb Smirnoff  * are met:
8*3b3a8eb9SGleb Smirnoff  * 1. Redistributions of source code must retain the above copyright
9*3b3a8eb9SGleb Smirnoff  *    notice, this list of conditions and the following disclaimer.
10*3b3a8eb9SGleb Smirnoff  * 2. Redistributions in binary form must reproduce the above copyright
11*3b3a8eb9SGleb Smirnoff  *    notice, this list of conditions and the following disclaimer in the
12*3b3a8eb9SGleb Smirnoff  *    documentation and/or other materials provided with the distribution.
13*3b3a8eb9SGleb Smirnoff  *
14*3b3a8eb9SGleb Smirnoff  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15*3b3a8eb9SGleb Smirnoff  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16*3b3a8eb9SGleb Smirnoff  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17*3b3a8eb9SGleb Smirnoff  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18*3b3a8eb9SGleb Smirnoff  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19*3b3a8eb9SGleb Smirnoff  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20*3b3a8eb9SGleb Smirnoff  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21*3b3a8eb9SGleb Smirnoff  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22*3b3a8eb9SGleb Smirnoff  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23*3b3a8eb9SGleb Smirnoff  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24*3b3a8eb9SGleb Smirnoff  * SUCH DAMAGE.
25*3b3a8eb9SGleb Smirnoff  */
26*3b3a8eb9SGleb Smirnoff 
27*3b3a8eb9SGleb Smirnoff /*
28*3b3a8eb9SGleb Smirnoff  * Userland code for testing binary heaps and hash tables
29*3b3a8eb9SGleb Smirnoff  *
30*3b3a8eb9SGleb Smirnoff  * $FreeBSD$
31*3b3a8eb9SGleb Smirnoff  */
32*3b3a8eb9SGleb Smirnoff 
33*3b3a8eb9SGleb Smirnoff #include <sys/cdefs.h>
34*3b3a8eb9SGleb Smirnoff #include <sys/param.h>
35*3b3a8eb9SGleb Smirnoff 
36*3b3a8eb9SGleb Smirnoff #include <stdio.h>
37*3b3a8eb9SGleb Smirnoff #include <strings.h>
38*3b3a8eb9SGleb Smirnoff #include <stdlib.h>
39*3b3a8eb9SGleb Smirnoff 
40*3b3a8eb9SGleb Smirnoff #include  "dn_heap.h"
41*3b3a8eb9SGleb Smirnoff #define log(x, arg...)	fprintf(stderr, ## arg)
42*3b3a8eb9SGleb Smirnoff #define panic(x...)	fprintf(stderr, ## x), exit(1)
43*3b3a8eb9SGleb Smirnoff 
44*3b3a8eb9SGleb Smirnoff #include <string.h>
45*3b3a8eb9SGleb Smirnoff 
46*3b3a8eb9SGleb Smirnoff struct x {
47*3b3a8eb9SGleb Smirnoff 	struct x *ht_link;
48*3b3a8eb9SGleb Smirnoff 	char buf[0];
49*3b3a8eb9SGleb Smirnoff };
50*3b3a8eb9SGleb Smirnoff 
51*3b3a8eb9SGleb Smirnoff uint32_t hf(uintptr_t key, int flags, void *arg)
52*3b3a8eb9SGleb Smirnoff {
53*3b3a8eb9SGleb Smirnoff 	return (flags & DNHT_KEY_IS_OBJ) ?
54*3b3a8eb9SGleb Smirnoff 		((struct x *)key)->buf[0] : *(char *)key;
55*3b3a8eb9SGleb Smirnoff }
56*3b3a8eb9SGleb Smirnoff 
57*3b3a8eb9SGleb Smirnoff int matchf(void *obj, uintptr_t key, int flags, void *arg)
58*3b3a8eb9SGleb Smirnoff {
59*3b3a8eb9SGleb Smirnoff 	char *s = (flags & DNHT_KEY_IS_OBJ) ?
60*3b3a8eb9SGleb Smirnoff 		((struct x *)key)->buf : (char *)key;
61*3b3a8eb9SGleb Smirnoff 	return (strcmp(((struct x *)obj)->buf, s) == 0);
62*3b3a8eb9SGleb Smirnoff }
63*3b3a8eb9SGleb Smirnoff 
64*3b3a8eb9SGleb Smirnoff void *newfn(uintptr_t key, int flags, void *arg)
65*3b3a8eb9SGleb Smirnoff {
66*3b3a8eb9SGleb Smirnoff 	char *s = (char *)key;
67*3b3a8eb9SGleb Smirnoff 	struct x *p = malloc(sizeof(*p) + 1 + strlen(s));
68*3b3a8eb9SGleb Smirnoff 	if (p)
69*3b3a8eb9SGleb Smirnoff 		strcpy(p->buf, s);
70*3b3a8eb9SGleb Smirnoff 	return p;
71*3b3a8eb9SGleb Smirnoff }
72*3b3a8eb9SGleb Smirnoff 
73*3b3a8eb9SGleb Smirnoff char *strings[] = {
74*3b3a8eb9SGleb Smirnoff 	"undici", "unico", "doppio", "devoto",
75*3b3a8eb9SGleb Smirnoff 	"uno", "due", "tre", "quattro", "cinque", "sei",
76*3b3a8eb9SGleb Smirnoff 	"uno", "due", "tre", "quattro", "cinque", "sei",
77*3b3a8eb9SGleb Smirnoff 	NULL,
78*3b3a8eb9SGleb Smirnoff };
79*3b3a8eb9SGleb Smirnoff 
80*3b3a8eb9SGleb Smirnoff int doprint(void *_x, void *arg)
81*3b3a8eb9SGleb Smirnoff {
82*3b3a8eb9SGleb Smirnoff 	struct x *x = _x;
83*3b3a8eb9SGleb Smirnoff 	printf("found element <%s>\n", x->buf);
84*3b3a8eb9SGleb Smirnoff 	return (int)arg;
85*3b3a8eb9SGleb Smirnoff }
86*3b3a8eb9SGleb Smirnoff 
87*3b3a8eb9SGleb Smirnoff static void
88*3b3a8eb9SGleb Smirnoff test_hash()
89*3b3a8eb9SGleb Smirnoff {
90*3b3a8eb9SGleb Smirnoff 	char **p;
91*3b3a8eb9SGleb Smirnoff 	struct dn_ht *h;
92*3b3a8eb9SGleb Smirnoff 	uintptr_t x = 0;
93*3b3a8eb9SGleb Smirnoff 	uintptr_t x1 = 0;
94*3b3a8eb9SGleb Smirnoff 
95*3b3a8eb9SGleb Smirnoff 	/* first, find and allocate */
96*3b3a8eb9SGleb Smirnoff 	h = dn_ht_init(NULL, 10, 0, hf, matchf, newfn);
97*3b3a8eb9SGleb Smirnoff 
98*3b3a8eb9SGleb Smirnoff 	for (p = strings; *p; p++) {
99*3b3a8eb9SGleb Smirnoff 		dn_ht_find(h, (uintptr_t)*p, DNHT_INSERT, NULL);
100*3b3a8eb9SGleb Smirnoff 	}
101*3b3a8eb9SGleb Smirnoff 	dn_ht_scan(h, doprint, 0);
102*3b3a8eb9SGleb Smirnoff 	printf("/* second -- find without allocate */\n");
103*3b3a8eb9SGleb Smirnoff 	h = dn_ht_init(NULL, 10, 0, hf, matchf, NULL);
104*3b3a8eb9SGleb Smirnoff 	for (p = strings; *p; p++) {
105*3b3a8eb9SGleb Smirnoff 		void **y = newfn((uintptr_t)*p, 0, NULL);
106*3b3a8eb9SGleb Smirnoff 		if (x == 0)
107*3b3a8eb9SGleb Smirnoff 			x = (uintptr_t)y;
108*3b3a8eb9SGleb Smirnoff 		else {
109*3b3a8eb9SGleb Smirnoff 			if (x1 == 0)
110*3b3a8eb9SGleb Smirnoff 				x1 = (uintptr_t)*p;
111*3b3a8eb9SGleb Smirnoff 		}
112*3b3a8eb9SGleb Smirnoff 		dn_ht_find(h, (uintptr_t)y, DNHT_INSERT | DNHT_KEY_IS_OBJ, NULL);
113*3b3a8eb9SGleb Smirnoff 	}
114*3b3a8eb9SGleb Smirnoff 	dn_ht_scan(h, doprint, 0);
115*3b3a8eb9SGleb Smirnoff 	printf("remove %p gives %p\n", (void *)x,
116*3b3a8eb9SGleb Smirnoff 		dn_ht_find(h, x, DNHT_KEY_IS_OBJ | DNHT_REMOVE, NULL));
117*3b3a8eb9SGleb Smirnoff 	printf("remove %p gives %p\n", (void *)x,
118*3b3a8eb9SGleb Smirnoff 		dn_ht_find(h, x, DNHT_KEY_IS_OBJ | DNHT_REMOVE, NULL));
119*3b3a8eb9SGleb Smirnoff 	printf("remove %p gives %p\n", (void *)x,
120*3b3a8eb9SGleb Smirnoff 		dn_ht_find(h, x1, DNHT_REMOVE, NULL));
121*3b3a8eb9SGleb Smirnoff 	printf("remove %p gives %p\n", (void *)x,
122*3b3a8eb9SGleb Smirnoff 		dn_ht_find(h, x1, DNHT_REMOVE, NULL));
123*3b3a8eb9SGleb Smirnoff 	dn_ht_scan(h, doprint, 0);
124*3b3a8eb9SGleb Smirnoff }
125*3b3a8eb9SGleb Smirnoff 
126*3b3a8eb9SGleb Smirnoff int
127*3b3a8eb9SGleb Smirnoff main(int argc, char *argv[])
128*3b3a8eb9SGleb Smirnoff {
129*3b3a8eb9SGleb Smirnoff 	struct dn_heap h;
130*3b3a8eb9SGleb Smirnoff 	int i, n, n2, n3;
131*3b3a8eb9SGleb Smirnoff 
132*3b3a8eb9SGleb Smirnoff 	test_hash();
133*3b3a8eb9SGleb Smirnoff 	return 0;
134*3b3a8eb9SGleb Smirnoff 
135*3b3a8eb9SGleb Smirnoff 	/* n = elements, n2 = cycles */
136*3b3a8eb9SGleb Smirnoff 	n = (argc > 1) ? atoi(argv[1]) : 0;
137*3b3a8eb9SGleb Smirnoff 	if (n <= 0 || n > 1000000)
138*3b3a8eb9SGleb Smirnoff 		n = 100;
139*3b3a8eb9SGleb Smirnoff 	n2 = (argc > 2) ? atoi(argv[2]) : 0;
140*3b3a8eb9SGleb Smirnoff 	if (n2 <= 0)
141*3b3a8eb9SGleb Smirnoff 		n = 1000000;
142*3b3a8eb9SGleb Smirnoff 	n3 = (argc > 3) ? atoi(argv[3]) : 0;
143*3b3a8eb9SGleb Smirnoff 	bzero(&h, sizeof(h));
144*3b3a8eb9SGleb Smirnoff 	heap_init(&h, n, -1);
145*3b3a8eb9SGleb Smirnoff 	while (n2-- > 0) {
146*3b3a8eb9SGleb Smirnoff 		uint64_t prevk = 0;
147*3b3a8eb9SGleb Smirnoff 		for (i=0; i < n; i++)
148*3b3a8eb9SGleb Smirnoff 			heap_insert(&h, n3 ? n-i: random(), (void *)(100+i));
149*3b3a8eb9SGleb Smirnoff 
150*3b3a8eb9SGleb Smirnoff 		for (i=0; h.elements > 0; i++) {
151*3b3a8eb9SGleb Smirnoff 			uint64_t k = h.p[0].key;
152*3b3a8eb9SGleb Smirnoff 			if (k < prevk)
153*3b3a8eb9SGleb Smirnoff 				panic("wrong sequence\n");
154*3b3a8eb9SGleb Smirnoff 			prevk = k;
155*3b3a8eb9SGleb Smirnoff 			if (0)
156*3b3a8eb9SGleb Smirnoff 			printf("%d key %llu, val %p\n",
157*3b3a8eb9SGleb Smirnoff 				i, h.p[0].key, h.p[0].object);
158*3b3a8eb9SGleb Smirnoff 			heap_extract(&h, NULL);
159*3b3a8eb9SGleb Smirnoff 		}
160*3b3a8eb9SGleb Smirnoff 	}
161*3b3a8eb9SGleb Smirnoff 	return 0;
162*3b3a8eb9SGleb Smirnoff }
163