1b8c99e7dSKonstantin Belousov /* 2b8c99e7dSKonstantin Belousov * Copyright 2025 The FreeBSD Foundation 3b8c99e7dSKonstantin Belousov * 4b8c99e7dSKonstantin Belousov * SPDX-License-Identifier: BSD-2-Clause 5b8c99e7dSKonstantin Belousov * 6b8c99e7dSKonstantin Belousov * This software was developed by Konstantin Belousov <kib@FreeBSD.org> 7b8c99e7dSKonstantin Belousov * under sponsorship from the FreeBSD Foundation. 8b8c99e7dSKonstantin Belousov */ 9b8c99e7dSKonstantin Belousov 10b8c99e7dSKonstantin Belousov #define _SEARCH_PRIVATE 11b8c99e7dSKonstantin Belousov #include <search.h> 12b8c99e7dSKonstantin Belousov #include <stdlib.h> 13b8c99e7dSKonstantin Belousov 14b8c99e7dSKonstantin Belousov static void nul_node_free(void * node __unused)15b8c99e7dSKonstantin Belousovnul_node_free(void *node __unused) 16b8c99e7dSKonstantin Belousov { 17b8c99e7dSKonstantin Belousov } 18b8c99e7dSKonstantin Belousov 19b8c99e7dSKonstantin Belousov void tdestroy(void * rootp,void (* node_free)(void *))20b8c99e7dSKonstantin Belousovtdestroy(void *rootp, void (*node_free)(void *)) 21b8c99e7dSKonstantin Belousov { 22988555e3SDoug Moore posix_tnode *back, *curr, **front; 23b8c99e7dSKonstantin Belousov 24988555e3SDoug Moore if (rootp == NULL) 25b8c99e7dSKonstantin Belousov return; 26b8c99e7dSKonstantin Belousov if (node_free == NULL) 27b8c99e7dSKonstantin Belousov node_free = nul_node_free; 28b8c99e7dSKonstantin Belousov 29988555e3SDoug Moore back = rootp; 30988555e3SDoug Moore front = &back; 31988555e3SDoug Moore 32988555e3SDoug Moore for (;;) { 33b8c99e7dSKonstantin Belousov /* 34988555e3SDoug Moore * The sequence of nodes from back to just before *front linked 35988555e3SDoug Moore * by llink have been found to have non-NULL rlink. 36988555e3SDoug Moore * 37988555e3SDoug Moore * Extend *front to (*front)->llink, deleting *front from the 38988555e3SDoug Moore * sequence if it has a NULL rlink. 39b8c99e7dSKonstantin Belousov */ 40988555e3SDoug Moore curr = *front; 41988555e3SDoug Moore if (curr->rlink != NULL) 42988555e3SDoug Moore front = &curr->llink; 43988555e3SDoug Moore else { 44988555e3SDoug Moore *front = curr->llink; 45988555e3SDoug Moore node_free(curr->key); 46988555e3SDoug Moore free(curr); 47b8c99e7dSKonstantin Belousov } 48988555e3SDoug Moore if (*front != NULL) 49988555e3SDoug Moore continue; 50988555e3SDoug Moore if (back == NULL) 51988555e3SDoug Moore break; 52b8c99e7dSKonstantin Belousov 53b8c99e7dSKonstantin Belousov /* 54988555e3SDoug Moore * The sequence cannot be extended because *front is NULL. Make 55988555e3SDoug Moore * the rlink of the back node the new *front, the llink of the 56988555e3SDoug Moore * back node the new back, and free the old back node. 57b8c99e7dSKonstantin Belousov */ 58988555e3SDoug Moore curr = back; 59988555e3SDoug Moore back = curr->llink; 60988555e3SDoug Moore if (back == NULL) 61988555e3SDoug Moore front = &back; 62988555e3SDoug Moore *front = curr->rlink; 63988555e3SDoug Moore node_free(curr->key); 64988555e3SDoug Moore free(curr); 65b8c99e7dSKonstantin Belousov } 66b8c99e7dSKonstantin Belousov } 67