3 * Searching splay trees
5 * (c) 2024 Straylight/Edgeware
8 /*----- Licensing notice --------------------------------------------------*
10 * This file is part of Xyla, a library of binary trees.
12 * Xyla is free software: you can redistribute it and/or modify it under
13 * the terms of the GNU Lesser General Public License as published by the
14 * Free Software Foundation; either version 3 of the License, or (at your
15 * option) any later version.
17 * Xyla is distributed in the hope that it will be useful, but WITHOUT
18 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
20 * License for more details.
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with Xyla. If not, see <https://www.gnu.org/licenses/>.
26 /*----- Header files ------------------------------------------------------*/
31 /*----- Main code ---------------------------------------------------------*/
33 void *xyla_splay_lookup(struct xyla_bt_nodecls *cls,
34 struct xyla_bt_node **root,
35 xyla_bt_navfn *navfn, void *arg)
37 /* Search for a node within the tree rooted at ROOT. The search is guided
38 * by NAVFN, passing it ARG at each node. Return the node that the
39 * function matches, or null if no matching node exists.
42 xyla_bt_updfn *updfn = cls ? cls->ops->upd : 0;
43 struct xyla_bt_node *node;
44 struct xyla_splay_path path;
46 /* Find the node and splay the tree. */
47 node = xyla_splay_probe(cls, root, navfn, arg, &path);
49 xyla__splay_splay(cls, path.node); *root = &path.node->bt;
50 if (updfn) updfn(cls, &path.node->bt);
55 void *xyla_splay_probe(struct xyla_bt_nodecls *cls,
56 struct xyla_bt_node **root,
57 xyla_bt_navfn *navfn, void *arg,
58 struct xyla_splay_path *path)
60 /* Search for a node within the tree rooted at ROOT. The search is
61 * guided by NAVFN, passing it ARG at each node. Record the search
62 * path in PATH. This can be used later, e.g., by
63 * `xyla_splay_insert' to insert a new node if none was found, or by
64 * `xyla_splay_remove' to remove the node that was found. Return
65 * the node that the function matches, or null if no matching node
69 const struct xyla_bt_ordops *ops;
70 struct xyla_splay_node *node, *next;
73 /* If no NAVFN is provided, then see if there's one in the node class. */
74 if (!navfn) { ops = ORDER_OPS(cls->ops); navfn = ops->ord.nav; }
76 /* Unsurprisingly, start at the root. */
77 path->root = root; node = SPLAY_NODE(*root);
80 /* If the tree is empty then we have no hope. */
82 path->node = 0; path->f = 0;
84 /* Descend the tree. If we reach the end, then leave an empty path
85 * identifying the appropriate null link.
89 dir = navfn(cls, &node->bt, arg);
91 next = SPLAY_NODE(node->bt.left);
93 { path->node = node; path->f = XYLA_SPF_LEFT; node = 0; break; }
95 next = SPLAY_NODE(node->bt.right);
97 { path->node = node; path->f = XYLA_SPF_RIGHT; node = 0; break; }
99 { path->node = node; path->f = 0; break; }
108 /*----- That's all, folks -------------------------------------------------*/