xref: /aosp_15_r20/external/jemalloc_new/test/unit/ph.c (revision 1208bc7e437ced7eb82efac44ba17e3beba411da)
1*1208bc7eSAndroid Build Coastguard Worker #include "test/jemalloc_test.h"
2*1208bc7eSAndroid Build Coastguard Worker 
3*1208bc7eSAndroid Build Coastguard Worker #include "jemalloc/internal/ph.h"
4*1208bc7eSAndroid Build Coastguard Worker 
5*1208bc7eSAndroid Build Coastguard Worker typedef struct node_s node_t;
6*1208bc7eSAndroid Build Coastguard Worker 
7*1208bc7eSAndroid Build Coastguard Worker struct node_s {
8*1208bc7eSAndroid Build Coastguard Worker #define NODE_MAGIC 0x9823af7e
9*1208bc7eSAndroid Build Coastguard Worker 	uint32_t magic;
10*1208bc7eSAndroid Build Coastguard Worker 	phn(node_t) link;
11*1208bc7eSAndroid Build Coastguard Worker 	uint64_t key;
12*1208bc7eSAndroid Build Coastguard Worker };
13*1208bc7eSAndroid Build Coastguard Worker 
14*1208bc7eSAndroid Build Coastguard Worker static int
node_cmp(const node_t * a,const node_t * b)15*1208bc7eSAndroid Build Coastguard Worker node_cmp(const node_t *a, const node_t *b) {
16*1208bc7eSAndroid Build Coastguard Worker 	int ret;
17*1208bc7eSAndroid Build Coastguard Worker 
18*1208bc7eSAndroid Build Coastguard Worker 	ret = (a->key > b->key) - (a->key < b->key);
19*1208bc7eSAndroid Build Coastguard Worker 	if (ret == 0) {
20*1208bc7eSAndroid Build Coastguard Worker 		/*
21*1208bc7eSAndroid Build Coastguard Worker 		 * Duplicates are not allowed in the heap, so force an
22*1208bc7eSAndroid Build Coastguard Worker 		 * arbitrary ordering for non-identical items with equal keys.
23*1208bc7eSAndroid Build Coastguard Worker 		 */
24*1208bc7eSAndroid Build Coastguard Worker 		ret = (((uintptr_t)a) > ((uintptr_t)b))
25*1208bc7eSAndroid Build Coastguard Worker 		    - (((uintptr_t)a) < ((uintptr_t)b));
26*1208bc7eSAndroid Build Coastguard Worker 	}
27*1208bc7eSAndroid Build Coastguard Worker 	return ret;
28*1208bc7eSAndroid Build Coastguard Worker }
29*1208bc7eSAndroid Build Coastguard Worker 
30*1208bc7eSAndroid Build Coastguard Worker static int
node_cmp_magic(const node_t * a,const node_t * b)31*1208bc7eSAndroid Build Coastguard Worker node_cmp_magic(const node_t *a, const node_t *b) {
32*1208bc7eSAndroid Build Coastguard Worker 
33*1208bc7eSAndroid Build Coastguard Worker 	assert_u32_eq(a->magic, NODE_MAGIC, "Bad magic");
34*1208bc7eSAndroid Build Coastguard Worker 	assert_u32_eq(b->magic, NODE_MAGIC, "Bad magic");
35*1208bc7eSAndroid Build Coastguard Worker 
36*1208bc7eSAndroid Build Coastguard Worker 	return node_cmp(a, b);
37*1208bc7eSAndroid Build Coastguard Worker }
38*1208bc7eSAndroid Build Coastguard Worker 
39*1208bc7eSAndroid Build Coastguard Worker typedef ph(node_t) heap_t;
40*1208bc7eSAndroid Build Coastguard Worker ph_gen(static, heap_, heap_t, node_t, link, node_cmp_magic);
41*1208bc7eSAndroid Build Coastguard Worker 
42*1208bc7eSAndroid Build Coastguard Worker static void
node_print(const node_t * node,unsigned depth)43*1208bc7eSAndroid Build Coastguard Worker node_print(const node_t *node, unsigned depth) {
44*1208bc7eSAndroid Build Coastguard Worker 	unsigned i;
45*1208bc7eSAndroid Build Coastguard Worker 	node_t *leftmost_child, *sibling;
46*1208bc7eSAndroid Build Coastguard Worker 
47*1208bc7eSAndroid Build Coastguard Worker 	for (i = 0; i < depth; i++) {
48*1208bc7eSAndroid Build Coastguard Worker 		malloc_printf("\t");
49*1208bc7eSAndroid Build Coastguard Worker 	}
50*1208bc7eSAndroid Build Coastguard Worker 	malloc_printf("%2"FMTu64"\n", node->key);
51*1208bc7eSAndroid Build Coastguard Worker 
52*1208bc7eSAndroid Build Coastguard Worker 	leftmost_child = phn_lchild_get(node_t, link, node);
53*1208bc7eSAndroid Build Coastguard Worker 	if (leftmost_child == NULL) {
54*1208bc7eSAndroid Build Coastguard Worker 		return;
55*1208bc7eSAndroid Build Coastguard Worker 	}
56*1208bc7eSAndroid Build Coastguard Worker 	node_print(leftmost_child, depth + 1);
57*1208bc7eSAndroid Build Coastguard Worker 
58*1208bc7eSAndroid Build Coastguard Worker 	for (sibling = phn_next_get(node_t, link, leftmost_child); sibling !=
59*1208bc7eSAndroid Build Coastguard Worker 	    NULL; sibling = phn_next_get(node_t, link, sibling)) {
60*1208bc7eSAndroid Build Coastguard Worker 		node_print(sibling, depth + 1);
61*1208bc7eSAndroid Build Coastguard Worker 	}
62*1208bc7eSAndroid Build Coastguard Worker }
63*1208bc7eSAndroid Build Coastguard Worker 
64*1208bc7eSAndroid Build Coastguard Worker static void
heap_print(const heap_t * heap)65*1208bc7eSAndroid Build Coastguard Worker heap_print(const heap_t *heap) {
66*1208bc7eSAndroid Build Coastguard Worker 	node_t *auxelm;
67*1208bc7eSAndroid Build Coastguard Worker 
68*1208bc7eSAndroid Build Coastguard Worker 	malloc_printf("vvv heap %p vvv\n", heap);
69*1208bc7eSAndroid Build Coastguard Worker 	if (heap->ph_root == NULL) {
70*1208bc7eSAndroid Build Coastguard Worker 		goto label_return;
71*1208bc7eSAndroid Build Coastguard Worker 	}
72*1208bc7eSAndroid Build Coastguard Worker 
73*1208bc7eSAndroid Build Coastguard Worker 	node_print(heap->ph_root, 0);
74*1208bc7eSAndroid Build Coastguard Worker 
75*1208bc7eSAndroid Build Coastguard Worker 	for (auxelm = phn_next_get(node_t, link, heap->ph_root); auxelm != NULL;
76*1208bc7eSAndroid Build Coastguard Worker 	    auxelm = phn_next_get(node_t, link, auxelm)) {
77*1208bc7eSAndroid Build Coastguard Worker 		assert_ptr_eq(phn_next_get(node_t, link, phn_prev_get(node_t,
78*1208bc7eSAndroid Build Coastguard Worker 		    link, auxelm)), auxelm,
79*1208bc7eSAndroid Build Coastguard Worker 		    "auxelm's prev doesn't link to auxelm");
80*1208bc7eSAndroid Build Coastguard Worker 		node_print(auxelm, 0);
81*1208bc7eSAndroid Build Coastguard Worker 	}
82*1208bc7eSAndroid Build Coastguard Worker 
83*1208bc7eSAndroid Build Coastguard Worker label_return:
84*1208bc7eSAndroid Build Coastguard Worker 	malloc_printf("^^^ heap %p ^^^\n", heap);
85*1208bc7eSAndroid Build Coastguard Worker }
86*1208bc7eSAndroid Build Coastguard Worker 
87*1208bc7eSAndroid Build Coastguard Worker static unsigned
node_validate(const node_t * node,const node_t * parent)88*1208bc7eSAndroid Build Coastguard Worker node_validate(const node_t *node, const node_t *parent) {
89*1208bc7eSAndroid Build Coastguard Worker 	unsigned nnodes = 1;
90*1208bc7eSAndroid Build Coastguard Worker 	node_t *leftmost_child, *sibling;
91*1208bc7eSAndroid Build Coastguard Worker 
92*1208bc7eSAndroid Build Coastguard Worker 	if (parent != NULL) {
93*1208bc7eSAndroid Build Coastguard Worker 		assert_d_ge(node_cmp_magic(node, parent), 0,
94*1208bc7eSAndroid Build Coastguard Worker 		    "Child is less than parent");
95*1208bc7eSAndroid Build Coastguard Worker 	}
96*1208bc7eSAndroid Build Coastguard Worker 
97*1208bc7eSAndroid Build Coastguard Worker 	leftmost_child = phn_lchild_get(node_t, link, node);
98*1208bc7eSAndroid Build Coastguard Worker 	if (leftmost_child == NULL) {
99*1208bc7eSAndroid Build Coastguard Worker 		return nnodes;
100*1208bc7eSAndroid Build Coastguard Worker 	}
101*1208bc7eSAndroid Build Coastguard Worker 	assert_ptr_eq((void *)phn_prev_get(node_t, link, leftmost_child),
102*1208bc7eSAndroid Build Coastguard Worker 	    (void *)node, "Leftmost child does not link to node");
103*1208bc7eSAndroid Build Coastguard Worker 	nnodes += node_validate(leftmost_child, node);
104*1208bc7eSAndroid Build Coastguard Worker 
105*1208bc7eSAndroid Build Coastguard Worker 	for (sibling = phn_next_get(node_t, link, leftmost_child); sibling !=
106*1208bc7eSAndroid Build Coastguard Worker 	    NULL; sibling = phn_next_get(node_t, link, sibling)) {
107*1208bc7eSAndroid Build Coastguard Worker 		assert_ptr_eq(phn_next_get(node_t, link, phn_prev_get(node_t,
108*1208bc7eSAndroid Build Coastguard Worker 		    link, sibling)), sibling,
109*1208bc7eSAndroid Build Coastguard Worker 		    "sibling's prev doesn't link to sibling");
110*1208bc7eSAndroid Build Coastguard Worker 		nnodes += node_validate(sibling, node);
111*1208bc7eSAndroid Build Coastguard Worker 	}
112*1208bc7eSAndroid Build Coastguard Worker 	return nnodes;
113*1208bc7eSAndroid Build Coastguard Worker }
114*1208bc7eSAndroid Build Coastguard Worker 
115*1208bc7eSAndroid Build Coastguard Worker static unsigned
heap_validate(const heap_t * heap)116*1208bc7eSAndroid Build Coastguard Worker heap_validate(const heap_t *heap) {
117*1208bc7eSAndroid Build Coastguard Worker 	unsigned nnodes = 0;
118*1208bc7eSAndroid Build Coastguard Worker 	node_t *auxelm;
119*1208bc7eSAndroid Build Coastguard Worker 
120*1208bc7eSAndroid Build Coastguard Worker 	if (heap->ph_root == NULL) {
121*1208bc7eSAndroid Build Coastguard Worker 		goto label_return;
122*1208bc7eSAndroid Build Coastguard Worker 	}
123*1208bc7eSAndroid Build Coastguard Worker 
124*1208bc7eSAndroid Build Coastguard Worker 	nnodes += node_validate(heap->ph_root, NULL);
125*1208bc7eSAndroid Build Coastguard Worker 
126*1208bc7eSAndroid Build Coastguard Worker 	for (auxelm = phn_next_get(node_t, link, heap->ph_root); auxelm != NULL;
127*1208bc7eSAndroid Build Coastguard Worker 	    auxelm = phn_next_get(node_t, link, auxelm)) {
128*1208bc7eSAndroid Build Coastguard Worker 		assert_ptr_eq(phn_next_get(node_t, link, phn_prev_get(node_t,
129*1208bc7eSAndroid Build Coastguard Worker 		    link, auxelm)), auxelm,
130*1208bc7eSAndroid Build Coastguard Worker 		    "auxelm's prev doesn't link to auxelm");
131*1208bc7eSAndroid Build Coastguard Worker 		nnodes += node_validate(auxelm, NULL);
132*1208bc7eSAndroid Build Coastguard Worker 	}
133*1208bc7eSAndroid Build Coastguard Worker 
134*1208bc7eSAndroid Build Coastguard Worker label_return:
135*1208bc7eSAndroid Build Coastguard Worker 	if (false) {
136*1208bc7eSAndroid Build Coastguard Worker 		heap_print(heap);
137*1208bc7eSAndroid Build Coastguard Worker 	}
138*1208bc7eSAndroid Build Coastguard Worker 	return nnodes;
139*1208bc7eSAndroid Build Coastguard Worker }
140*1208bc7eSAndroid Build Coastguard Worker 
TEST_BEGIN(test_ph_empty)141*1208bc7eSAndroid Build Coastguard Worker TEST_BEGIN(test_ph_empty) {
142*1208bc7eSAndroid Build Coastguard Worker 	heap_t heap;
143*1208bc7eSAndroid Build Coastguard Worker 
144*1208bc7eSAndroid Build Coastguard Worker 	heap_new(&heap);
145*1208bc7eSAndroid Build Coastguard Worker 	assert_true(heap_empty(&heap), "Heap should be empty");
146*1208bc7eSAndroid Build Coastguard Worker 	assert_ptr_null(heap_first(&heap), "Unexpected node");
147*1208bc7eSAndroid Build Coastguard Worker 	assert_ptr_null(heap_any(&heap), "Unexpected node");
148*1208bc7eSAndroid Build Coastguard Worker }
149*1208bc7eSAndroid Build Coastguard Worker TEST_END
150*1208bc7eSAndroid Build Coastguard Worker 
151*1208bc7eSAndroid Build Coastguard Worker static void
node_remove(heap_t * heap,node_t * node)152*1208bc7eSAndroid Build Coastguard Worker node_remove(heap_t *heap, node_t *node) {
153*1208bc7eSAndroid Build Coastguard Worker 	heap_remove(heap, node);
154*1208bc7eSAndroid Build Coastguard Worker 
155*1208bc7eSAndroid Build Coastguard Worker 	node->magic = 0;
156*1208bc7eSAndroid Build Coastguard Worker }
157*1208bc7eSAndroid Build Coastguard Worker 
158*1208bc7eSAndroid Build Coastguard Worker static node_t *
node_remove_first(heap_t * heap)159*1208bc7eSAndroid Build Coastguard Worker node_remove_first(heap_t *heap) {
160*1208bc7eSAndroid Build Coastguard Worker 	node_t *node = heap_remove_first(heap);
161*1208bc7eSAndroid Build Coastguard Worker 	node->magic = 0;
162*1208bc7eSAndroid Build Coastguard Worker 	return node;
163*1208bc7eSAndroid Build Coastguard Worker }
164*1208bc7eSAndroid Build Coastguard Worker 
165*1208bc7eSAndroid Build Coastguard Worker static node_t *
node_remove_any(heap_t * heap)166*1208bc7eSAndroid Build Coastguard Worker node_remove_any(heap_t *heap) {
167*1208bc7eSAndroid Build Coastguard Worker 	node_t *node = heap_remove_any(heap);
168*1208bc7eSAndroid Build Coastguard Worker 	node->magic = 0;
169*1208bc7eSAndroid Build Coastguard Worker 	return node;
170*1208bc7eSAndroid Build Coastguard Worker }
171*1208bc7eSAndroid Build Coastguard Worker 
TEST_BEGIN(test_ph_random)172*1208bc7eSAndroid Build Coastguard Worker TEST_BEGIN(test_ph_random) {
173*1208bc7eSAndroid Build Coastguard Worker #define NNODES 25
174*1208bc7eSAndroid Build Coastguard Worker #define NBAGS 250
175*1208bc7eSAndroid Build Coastguard Worker #define SEED 42
176*1208bc7eSAndroid Build Coastguard Worker 	sfmt_t *sfmt;
177*1208bc7eSAndroid Build Coastguard Worker 	uint64_t bag[NNODES];
178*1208bc7eSAndroid Build Coastguard Worker 	heap_t heap;
179*1208bc7eSAndroid Build Coastguard Worker 	node_t nodes[NNODES];
180*1208bc7eSAndroid Build Coastguard Worker 	unsigned i, j, k;
181*1208bc7eSAndroid Build Coastguard Worker 
182*1208bc7eSAndroid Build Coastguard Worker 	sfmt = init_gen_rand(SEED);
183*1208bc7eSAndroid Build Coastguard Worker 	for (i = 0; i < NBAGS; i++) {
184*1208bc7eSAndroid Build Coastguard Worker 		switch (i) {
185*1208bc7eSAndroid Build Coastguard Worker 		case 0:
186*1208bc7eSAndroid Build Coastguard Worker 			/* Insert in order. */
187*1208bc7eSAndroid Build Coastguard Worker 			for (j = 0; j < NNODES; j++) {
188*1208bc7eSAndroid Build Coastguard Worker 				bag[j] = j;
189*1208bc7eSAndroid Build Coastguard Worker 			}
190*1208bc7eSAndroid Build Coastguard Worker 			break;
191*1208bc7eSAndroid Build Coastguard Worker 		case 1:
192*1208bc7eSAndroid Build Coastguard Worker 			/* Insert in reverse order. */
193*1208bc7eSAndroid Build Coastguard Worker 			for (j = 0; j < NNODES; j++) {
194*1208bc7eSAndroid Build Coastguard Worker 				bag[j] = NNODES - j - 1;
195*1208bc7eSAndroid Build Coastguard Worker 			}
196*1208bc7eSAndroid Build Coastguard Worker 			break;
197*1208bc7eSAndroid Build Coastguard Worker 		default:
198*1208bc7eSAndroid Build Coastguard Worker 			for (j = 0; j < NNODES; j++) {
199*1208bc7eSAndroid Build Coastguard Worker 				bag[j] = gen_rand64_range(sfmt, NNODES);
200*1208bc7eSAndroid Build Coastguard Worker 			}
201*1208bc7eSAndroid Build Coastguard Worker 		}
202*1208bc7eSAndroid Build Coastguard Worker 
203*1208bc7eSAndroid Build Coastguard Worker 		for (j = 1; j <= NNODES; j++) {
204*1208bc7eSAndroid Build Coastguard Worker 			/* Initialize heap and nodes. */
205*1208bc7eSAndroid Build Coastguard Worker 			heap_new(&heap);
206*1208bc7eSAndroid Build Coastguard Worker 			assert_u_eq(heap_validate(&heap), 0,
207*1208bc7eSAndroid Build Coastguard Worker 			    "Incorrect node count");
208*1208bc7eSAndroid Build Coastguard Worker 			for (k = 0; k < j; k++) {
209*1208bc7eSAndroid Build Coastguard Worker 				nodes[k].magic = NODE_MAGIC;
210*1208bc7eSAndroid Build Coastguard Worker 				nodes[k].key = bag[k];
211*1208bc7eSAndroid Build Coastguard Worker 			}
212*1208bc7eSAndroid Build Coastguard Worker 
213*1208bc7eSAndroid Build Coastguard Worker 			/* Insert nodes. */
214*1208bc7eSAndroid Build Coastguard Worker 			for (k = 0; k < j; k++) {
215*1208bc7eSAndroid Build Coastguard Worker 				heap_insert(&heap, &nodes[k]);
216*1208bc7eSAndroid Build Coastguard Worker 				if (i % 13 == 12) {
217*1208bc7eSAndroid Build Coastguard Worker 					assert_ptr_not_null(heap_any(&heap),
218*1208bc7eSAndroid Build Coastguard Worker 					    "Heap should not be empty");
219*1208bc7eSAndroid Build Coastguard Worker 					/* Trigger merging. */
220*1208bc7eSAndroid Build Coastguard Worker 					assert_ptr_not_null(heap_first(&heap),
221*1208bc7eSAndroid Build Coastguard Worker 					    "Heap should not be empty");
222*1208bc7eSAndroid Build Coastguard Worker 				}
223*1208bc7eSAndroid Build Coastguard Worker 				assert_u_eq(heap_validate(&heap), k + 1,
224*1208bc7eSAndroid Build Coastguard Worker 				    "Incorrect node count");
225*1208bc7eSAndroid Build Coastguard Worker 			}
226*1208bc7eSAndroid Build Coastguard Worker 
227*1208bc7eSAndroid Build Coastguard Worker 			assert_false(heap_empty(&heap),
228*1208bc7eSAndroid Build Coastguard Worker 			    "Heap should not be empty");
229*1208bc7eSAndroid Build Coastguard Worker 
230*1208bc7eSAndroid Build Coastguard Worker 			/* Remove nodes. */
231*1208bc7eSAndroid Build Coastguard Worker 			switch (i % 6) {
232*1208bc7eSAndroid Build Coastguard Worker 			case 0:
233*1208bc7eSAndroid Build Coastguard Worker 				for (k = 0; k < j; k++) {
234*1208bc7eSAndroid Build Coastguard Worker 					assert_u_eq(heap_validate(&heap), j - k,
235*1208bc7eSAndroid Build Coastguard Worker 					    "Incorrect node count");
236*1208bc7eSAndroid Build Coastguard Worker 					node_remove(&heap, &nodes[k]);
237*1208bc7eSAndroid Build Coastguard Worker 					assert_u_eq(heap_validate(&heap), j - k
238*1208bc7eSAndroid Build Coastguard Worker 					    - 1, "Incorrect node count");
239*1208bc7eSAndroid Build Coastguard Worker 				}
240*1208bc7eSAndroid Build Coastguard Worker 				break;
241*1208bc7eSAndroid Build Coastguard Worker 			case 1:
242*1208bc7eSAndroid Build Coastguard Worker 				for (k = j; k > 0; k--) {
243*1208bc7eSAndroid Build Coastguard Worker 					node_remove(&heap, &nodes[k-1]);
244*1208bc7eSAndroid Build Coastguard Worker 					assert_u_eq(heap_validate(&heap), k - 1,
245*1208bc7eSAndroid Build Coastguard Worker 					    "Incorrect node count");
246*1208bc7eSAndroid Build Coastguard Worker 				}
247*1208bc7eSAndroid Build Coastguard Worker 				break;
248*1208bc7eSAndroid Build Coastguard Worker 			case 2: {
249*1208bc7eSAndroid Build Coastguard Worker 				node_t *prev = NULL;
250*1208bc7eSAndroid Build Coastguard Worker 				for (k = 0; k < j; k++) {
251*1208bc7eSAndroid Build Coastguard Worker 					node_t *node = node_remove_first(&heap);
252*1208bc7eSAndroid Build Coastguard Worker 					assert_u_eq(heap_validate(&heap), j - k
253*1208bc7eSAndroid Build Coastguard Worker 					    - 1, "Incorrect node count");
254*1208bc7eSAndroid Build Coastguard Worker 					if (prev != NULL) {
255*1208bc7eSAndroid Build Coastguard Worker 						assert_d_ge(node_cmp(node,
256*1208bc7eSAndroid Build Coastguard Worker 						    prev), 0,
257*1208bc7eSAndroid Build Coastguard Worker 						    "Bad removal order");
258*1208bc7eSAndroid Build Coastguard Worker 					}
259*1208bc7eSAndroid Build Coastguard Worker 					prev = node;
260*1208bc7eSAndroid Build Coastguard Worker 				}
261*1208bc7eSAndroid Build Coastguard Worker 				break;
262*1208bc7eSAndroid Build Coastguard Worker 			} case 3: {
263*1208bc7eSAndroid Build Coastguard Worker 				node_t *prev = NULL;
264*1208bc7eSAndroid Build Coastguard Worker 				for (k = 0; k < j; k++) {
265*1208bc7eSAndroid Build Coastguard Worker 					node_t *node = heap_first(&heap);
266*1208bc7eSAndroid Build Coastguard Worker 					assert_u_eq(heap_validate(&heap), j - k,
267*1208bc7eSAndroid Build Coastguard Worker 					    "Incorrect node count");
268*1208bc7eSAndroid Build Coastguard Worker 					if (prev != NULL) {
269*1208bc7eSAndroid Build Coastguard Worker 						assert_d_ge(node_cmp(node,
270*1208bc7eSAndroid Build Coastguard Worker 						    prev), 0,
271*1208bc7eSAndroid Build Coastguard Worker 						    "Bad removal order");
272*1208bc7eSAndroid Build Coastguard Worker 					}
273*1208bc7eSAndroid Build Coastguard Worker 					node_remove(&heap, node);
274*1208bc7eSAndroid Build Coastguard Worker 					assert_u_eq(heap_validate(&heap), j - k
275*1208bc7eSAndroid Build Coastguard Worker 					    - 1, "Incorrect node count");
276*1208bc7eSAndroid Build Coastguard Worker 					prev = node;
277*1208bc7eSAndroid Build Coastguard Worker 				}
278*1208bc7eSAndroid Build Coastguard Worker 				break;
279*1208bc7eSAndroid Build Coastguard Worker 			} case 4: {
280*1208bc7eSAndroid Build Coastguard Worker 				for (k = 0; k < j; k++) {
281*1208bc7eSAndroid Build Coastguard Worker 					node_remove_any(&heap);
282*1208bc7eSAndroid Build Coastguard Worker 					assert_u_eq(heap_validate(&heap), j - k
283*1208bc7eSAndroid Build Coastguard Worker 					    - 1, "Incorrect node count");
284*1208bc7eSAndroid Build Coastguard Worker 				}
285*1208bc7eSAndroid Build Coastguard Worker 				break;
286*1208bc7eSAndroid Build Coastguard Worker 			} case 5: {
287*1208bc7eSAndroid Build Coastguard Worker 				for (k = 0; k < j; k++) {
288*1208bc7eSAndroid Build Coastguard Worker 					node_t *node = heap_any(&heap);
289*1208bc7eSAndroid Build Coastguard Worker 					assert_u_eq(heap_validate(&heap), j - k,
290*1208bc7eSAndroid Build Coastguard Worker 					    "Incorrect node count");
291*1208bc7eSAndroid Build Coastguard Worker 					node_remove(&heap, node);
292*1208bc7eSAndroid Build Coastguard Worker 					assert_u_eq(heap_validate(&heap), j - k
293*1208bc7eSAndroid Build Coastguard Worker 					    - 1, "Incorrect node count");
294*1208bc7eSAndroid Build Coastguard Worker 				}
295*1208bc7eSAndroid Build Coastguard Worker 				break;
296*1208bc7eSAndroid Build Coastguard Worker 			} default:
297*1208bc7eSAndroid Build Coastguard Worker 				not_reached();
298*1208bc7eSAndroid Build Coastguard Worker 			}
299*1208bc7eSAndroid Build Coastguard Worker 
300*1208bc7eSAndroid Build Coastguard Worker 			assert_ptr_null(heap_first(&heap),
301*1208bc7eSAndroid Build Coastguard Worker 			    "Heap should be empty");
302*1208bc7eSAndroid Build Coastguard Worker 			assert_ptr_null(heap_any(&heap),
303*1208bc7eSAndroid Build Coastguard Worker 			    "Heap should be empty");
304*1208bc7eSAndroid Build Coastguard Worker 			assert_true(heap_empty(&heap), "Heap should be empty");
305*1208bc7eSAndroid Build Coastguard Worker 		}
306*1208bc7eSAndroid Build Coastguard Worker 	}
307*1208bc7eSAndroid Build Coastguard Worker 	fini_gen_rand(sfmt);
308*1208bc7eSAndroid Build Coastguard Worker #undef NNODES
309*1208bc7eSAndroid Build Coastguard Worker #undef SEED
310*1208bc7eSAndroid Build Coastguard Worker }
311*1208bc7eSAndroid Build Coastguard Worker TEST_END
312*1208bc7eSAndroid Build Coastguard Worker 
313*1208bc7eSAndroid Build Coastguard Worker int
main(void)314*1208bc7eSAndroid Build Coastguard Worker main(void) {
315*1208bc7eSAndroid Build Coastguard Worker 	return test(
316*1208bc7eSAndroid Build Coastguard Worker 	    test_ph_empty,
317*1208bc7eSAndroid Build Coastguard Worker 	    test_ph_random);
318*1208bc7eSAndroid Build Coastguard Worker }
319