1*eabc0478Schristos /* $NetBSD: regress_minheap.c,v 1.8 2024/08/18 20:47:23 christos Exp $ */ 28585484eSchristos 38585484eSchristos /* 48585484eSchristos * Copyright (c) 2009-2012 Niels Provos and Nick Mathewson 58585484eSchristos * 68585484eSchristos * Redistribution and use in source and binary forms, with or without 78585484eSchristos * modification, are permitted provided that the following conditions 88585484eSchristos * are met: 98585484eSchristos * 1. Redistributions of source code must retain the above copyright 108585484eSchristos * notice, this list of conditions and the following disclaimer. 118585484eSchristos * 2. Redistributions in binary form must reproduce the above copyright 128585484eSchristos * notice, this list of conditions and the following disclaimer in the 138585484eSchristos * documentation and/or other materials provided with the distribution. 148585484eSchristos * 3. The name of the author may not be used to endorse or promote products 158585484eSchristos * derived from this software without specific prior written permission. 168585484eSchristos * 178585484eSchristos * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 188585484eSchristos * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 198585484eSchristos * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 208585484eSchristos * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 218585484eSchristos * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 228585484eSchristos * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 238585484eSchristos * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 248585484eSchristos * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 258585484eSchristos * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 268585484eSchristos * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 278585484eSchristos */ 288585484eSchristos #include "../minheap-internal.h" 298585484eSchristos 308585484eSchristos #include <stdlib.h> 318585484eSchristos #include "event2/event_struct.h" 328585484eSchristos 338585484eSchristos #include "tinytest.h" 348585484eSchristos #include "tinytest_macros.h" 357476e6e4Schristos #include "regress.h" 368585484eSchristos 378585484eSchristos static void 388585484eSchristos set_random_timeout(struct event *ev) 398585484eSchristos { 407476e6e4Schristos ev->ev_timeout.tv_sec = test_weakrand(); 417476e6e4Schristos ev->ev_timeout.tv_usec = test_weakrand() & 0xfffff; 428585484eSchristos ev->ev_timeout_pos.min_heap_idx = -1; 438585484eSchristos } 448585484eSchristos 458585484eSchristos static void 468585484eSchristos check_heap(struct min_heap *heap) 478585484eSchristos { 488585484eSchristos unsigned i; 498585484eSchristos for (i = 1; i < heap->n; ++i) { 508585484eSchristos unsigned parent_idx = (i-1)/2; 518585484eSchristos tt_want(evutil_timercmp(&heap->p[i]->ev_timeout, 528585484eSchristos &heap->p[parent_idx]->ev_timeout, >=)); 538585484eSchristos } 548585484eSchristos } 558585484eSchristos 568585484eSchristos static void 578585484eSchristos test_heap_randomized(void *ptr) 588585484eSchristos { 598585484eSchristos struct min_heap heap; 608585484eSchristos struct event *inserted[1024]; 618585484eSchristos struct event *e, *last_e; 628585484eSchristos int i; 638585484eSchristos 648585484eSchristos min_heap_ctor_(&heap); 658585484eSchristos 668585484eSchristos for (i = 0; i < 1024; ++i) { 678585484eSchristos inserted[i] = malloc(sizeof(struct event)); 688585484eSchristos set_random_timeout(inserted[i]); 698585484eSchristos min_heap_push_(&heap, inserted[i]); 708585484eSchristos } 718585484eSchristos check_heap(&heap); 728585484eSchristos 738585484eSchristos tt_assert(min_heap_size_(&heap) == 1024); 748585484eSchristos 758585484eSchristos for (i = 0; i < 512; ++i) { 768585484eSchristos min_heap_erase_(&heap, inserted[i]); 778585484eSchristos if (0 == (i % 32)) 788585484eSchristos check_heap(&heap); 798585484eSchristos } 808585484eSchristos tt_assert(min_heap_size_(&heap) == 512); 818585484eSchristos 828585484eSchristos last_e = min_heap_pop_(&heap); 838585484eSchristos while (1) { 848585484eSchristos e = min_heap_pop_(&heap); 858585484eSchristos if (!e) 868585484eSchristos break; 878585484eSchristos tt_want(evutil_timercmp(&last_e->ev_timeout, 888585484eSchristos &e->ev_timeout, <=)); 898585484eSchristos } 908585484eSchristos tt_assert(min_heap_size_(&heap) == 0); 918585484eSchristos end: 928585484eSchristos for (i = 0; i < 1024; ++i) 938585484eSchristos free(inserted[i]); 948585484eSchristos 958585484eSchristos min_heap_dtor_(&heap); 968585484eSchristos } 978585484eSchristos 988585484eSchristos struct testcase_t minheap_testcases[] = { 998585484eSchristos { "randomized", test_heap_randomized, 0, NULL, NULL }, 1008585484eSchristos END_OF_TESTCASES 1018585484eSchristos }; 102