Serenity Operating System
at master 126 lines 3.1 kB view raw
1/* 2 * Copyright (c) 2021, the SerenityOS developers. 3 * Copyright (c) 2021, Tim Schumacher <timschumi@gmx.de> 4 * 5 * SPDX-License-Identifier: BSD-2-Clause 6 */ 7 8#include <AK/Format.h> 9#include <bits/search.h> 10#include <search.h> 11 12struct search_tree_node* new_tree_node(void const* key) 13{ 14 auto* node = static_cast<struct search_tree_node*>(malloc(sizeof(struct search_tree_node))); 15 16 if (!node) 17 return nullptr; 18 19 node->key = key; 20 node->left = nullptr; 21 node->right = nullptr; 22 23 return node; 24} 25 26void delete_node_recursive(struct search_tree_node* node) 27{ 28 if (!node) 29 return; 30 31 delete_node_recursive(node->left); 32 delete_node_recursive(node->right); 33 34 free(node); 35} 36 37extern "C" { 38 39// https://pubs.opengroup.org/onlinepubs/9699919799/functions/tsearch.html 40void* tsearch(void const* key, void** rootp, int (*comparator)(void const*, void const*)) 41{ 42 if (!rootp) 43 return nullptr; 44 45 if (!*rootp) { 46 *rootp = new_tree_node(key); 47 return *rootp; 48 } 49 50 auto node = static_cast<struct search_tree_node*>(*rootp); 51 52 while (node != nullptr) { 53 auto comp = comparator(key, node->key); 54 55 if (comp < 0 && node->left) { 56 node = node->left; 57 } else if (comp < 0 && !node->left) { 58 node->left = new_tree_node(key); 59 return node->left; 60 } else if (comp > 0 && node->right) { 61 node = node->right; 62 } else if (comp > 0 && !node->right) { 63 node->right = new_tree_node(key); 64 return node->right; 65 } else { 66 return node; 67 } 68 } 69 70 VERIFY_NOT_REACHED(); 71} 72 73// https://pubs.opengroup.org/onlinepubs/9699919799/functions/tfind.html 74void* tfind(void const* key, void* const* rootp, int (*comparator)(void const*, void const*)) 75{ 76 if (!rootp) 77 return nullptr; 78 79 auto node = static_cast<struct search_tree_node*>(*rootp); 80 81 while (node != nullptr) { 82 auto comp = comparator(key, node->key); 83 84 if (comp < 0) 85 node = node->left; 86 else if (comp > 0) 87 node = node->right; 88 else 89 return node; 90 } 91 92 return nullptr; 93} 94 95// https://pubs.opengroup.org/onlinepubs/9699919799/functions/tdelete.html 96void* tdelete(void const*, void**, int (*)(void const*, void const*)) 97{ 98 dbgln("FIXME: Implement tdelete()"); 99 return nullptr; 100} 101 102static void twalk_internal(const struct search_tree_node* node, void (*action)(void const*, VISIT, int), int depth) 103{ 104 if (!node) 105 return; 106 107 if (!node->right && !node->left) { 108 action(node, leaf, depth); 109 return; 110 } 111 112 action(node, preorder, depth); 113 twalk_internal(node->left, action, depth + 1); 114 action(node, postorder, depth); 115 twalk_internal(node->right, action, depth + 1); 116 action(node, endorder, depth); 117} 118 119// https://pubs.opengroup.org/onlinepubs/9699919799/functions/twalk.html 120void twalk(void const* rootp, void (*action)(void const*, VISIT, int)) 121{ 122 auto node = static_cast<const struct search_tree_node*>(rootp); 123 124 twalk_internal(node, action, 0); 125} 126}