A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
at master 226 lines 7.8 kB view raw
1/* 2 * tree234.h: header defining functions in tree234.c. 3 * 4 * This file is copyright 1999-2001 Simon Tatham. 5 * 6 * Permission is hereby granted, free of charge, to any person 7 * obtaining a copy of this software and associated documentation 8 * files (the "Software"), to deal in the Software without 9 * restriction, including without limitation the rights to use, 10 * copy, modify, merge, publish, distribute, sublicense, and/or 11 * sell copies of the Software, and to permit persons to whom the 12 * Software is furnished to do so, subject to the following 13 * conditions: 14 * 15 * The above copyright notice and this permission notice shall be 16 * included in all copies or substantial portions of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 20 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 21 * NONINFRINGEMENT. IN NO EVENT SHALL SIMON TATHAM BE LIABLE FOR 22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 23 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 * SOFTWARE. 26 */ 27 28#ifndef TREE234_H 29#define TREE234_H 30 31#include <stdbool.h> 32 33/* 34 * This typedef is typically opaque outside tree234.c itself. But you 35 * can define TREE234_INTERNALS to get a definition of it and its 36 * subsidiary node structure, as long as you're prepared to commit to 37 * responding to changes in the internals (which probably means you're 38 * tree234.c itself or tree234-test.c). 39 */ 40typedef struct tree234_Tag tree234; 41 42typedef int (*cmpfn234)(void *, void *); 43 44typedef void *(*copyfn234)(void *state, void *element); 45 46#ifdef TREE234_INTERNALS 47typedef struct node234_Tag node234; 48 49struct tree234_Tag { 50 node234 *root; 51 cmpfn234 cmp; 52}; 53 54struct node234_Tag { 55 node234 *parent; 56 node234 *kids[4]; 57 int counts[4]; 58 void *elems[3]; 59}; 60 61int height234(tree234 *t); 62#endif 63 64/* 65 * Create a 2-3-4 tree. If `cmp' is NULL, the tree is unsorted, and 66 * lookups by key will fail: you can only look things up by numeric 67 * index, and you have to use addpos234() and delpos234(). 68 */ 69tree234 *newtree234(cmpfn234 cmp); 70 71/* 72 * Free a 2-3-4 tree (not including freeing the elements). 73 */ 74void freetree234(tree234 *t); 75 76/* 77 * Add an element e to a sorted 2-3-4 tree t. Returns e on success, 78 * or if an existing element compares equal, returns that. 79 */ 80void *add234(tree234 *t, void *e); 81 82/* 83 * Add an element e to an unsorted 2-3-4 tree t. Returns e on 84 * success, NULL on failure. (Failure should only occur if the 85 * index is out of range or the tree is sorted.) 86 * 87 * Index range can be from 0 to the tree's current element count, 88 * inclusive. 89 */ 90void *addpos234(tree234 *t, void *e, int index); 91 92/* 93 * Look up the element at a given numeric index in a 2-3-4 tree. 94 * Returns NULL if the index is out of range. 95 * 96 * One obvious use for this function is in iterating over the whole 97 * of a tree (sorted or unsorted): 98 * 99 * for (i = 0; (p = index234(tree, i)) != NULL; i++) consume(p); 100 * 101 * or 102 * 103 * int maxcount = count234(tree); 104 * for (i = 0; i < maxcount; i++) { 105 * p = index234(tree, i); 106 * assert(p != NULL); 107 * consume(p); 108 * } 109 */ 110void *index234(tree234 *t, int index); 111 112/* 113 * Find an element e in a sorted 2-3-4 tree t. Returns NULL if not 114 * found. e is always passed as the first argument to cmp, so cmp 115 * can be an asymmetric function if desired. cmp can also be passed 116 * as NULL, in which case the compare function from the tree proper 117 * will be used. 118 * 119 * Three of these functions are special cases of findrelpos234. The 120 * non-`pos' variants lack the `index' parameter: if the parameter 121 * is present and non-NULL, it must point to an integer variable 122 * which will be filled with the numeric index of the returned 123 * element. 124 * 125 * The non-`rel' variants lack the `relation' parameter. This 126 * parameter allows you to specify what relation the element you 127 * provide has to the element you're looking for. This parameter 128 * can be: 129 * 130 * REL234_EQ - find only an element that compares equal to e 131 * REL234_LT - find the greatest element that compares < e 132 * REL234_LE - find the greatest element that compares <= e 133 * REL234_GT - find the smallest element that compares > e 134 * REL234_GE - find the smallest element that compares >= e 135 * 136 * Non-`rel' variants assume REL234_EQ. 137 * 138 * If `rel' is REL234_GT or REL234_LT, the `e' parameter may be 139 * NULL. In this case, REL234_GT will return the smallest element 140 * in the tree, and REL234_LT will return the greatest. This gives 141 * an alternative means of iterating over a sorted tree, instead of 142 * using index234: 143 * 144 * // to loop forwards 145 * for (p = NULL; (p = findrel234(tree, p, NULL, REL234_GT)) != NULL ;) 146 * consume(p); 147 * 148 * // to loop backwards 149 * for (p = NULL; (p = findrel234(tree, p, NULL, REL234_LT)) != NULL ;) 150 * consume(p); 151 */ 152enum { 153 REL234_EQ, REL234_LT, REL234_LE, REL234_GT, REL234_GE 154}; 155void *find234(tree234 *t, void *e, cmpfn234 cmp); 156void *findrel234(tree234 *t, void *e, cmpfn234 cmp, int relation); 157void *findpos234(tree234 *t, void *e, cmpfn234 cmp, int *index); 158void *findrelpos234(tree234 *t, void *e, cmpfn234 cmp, int relation, 159 int *index); 160 161/* 162 * Delete an element e in a 2-3-4 tree. Does not free the element, 163 * merely removes all links to it from the tree nodes. 164 * 165 * delpos234 deletes the element at a particular tree index: it 166 * works on both sorted and unsorted trees. 167 * 168 * del234 deletes the element passed to it, so it only works on 169 * sorted trees. (It's equivalent to using findpos234 to determine 170 * the index of an element, and then passing that index to 171 * delpos234.) 172 * 173 * Both functions return a pointer to the element they delete, for 174 * the user to free or pass on elsewhere or whatever. If the index 175 * is out of range (delpos234) or the element is already not in the 176 * tree (del234) then they return NULL. 177 */ 178void *del234(tree234 *t, void *e); 179void *delpos234(tree234 *t, int index); 180 181/* 182 * Return the total element count of a tree234. 183 */ 184int count234(tree234 *t); 185 186/* 187 * Split a tree234 into two valid tree234s. 188 * 189 * splitpos234 splits at a given index. If `before' is true, the 190 * items at and after that index are left in t and the ones before 191 * are returned; if `before' is false, the items before that index 192 * are left in t and the rest are returned. 193 * 194 * split234 splits at a given key. You can pass any of the 195 * relations used with findrel234, except for REL234_EQ. The items 196 * in the tree that satisfy the relation are returned; the 197 * remainder are left. 198 */ 199tree234 *splitpos234(tree234 *t, int index, bool before); 200tree234 *split234(tree234 *t, void *e, cmpfn234 cmp, int rel); 201 202/* 203 * Join two tree234s together into a single one. 204 * 205 * All the elements in t1 are placed to the left of all the 206 * elements in t2. If the trees are sorted, there will be a test to 207 * ensure that this satisfies the ordering criterion, and NULL will 208 * be returned otherwise. If the trees are unsorted, there is no 209 * restriction on the use of join234. 210 * 211 * The tree returned is t1 (join234) or t2 (join234r), if the 212 * operation is successful. 213 */ 214tree234 *join234(tree234 *t1, tree234 *t2); 215tree234 *join234r(tree234 *t1, tree234 *t2); 216 217/* 218 * Make a complete copy of a tree234. Element pointers will be 219 * reused unless copyfn is non-NULL, in which case it will be used 220 * to copy each element. (copyfn takes two `void *' parameters; the 221 * first is private state and the second is the element. A simple 222 * copy routine probably won't need private state.) 223 */ 224tree234 *copytree234(tree234 *t, copyfn234 copyfn, void *copyfnstate); 225 226#endif /* TREE234_H */