rbtree.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396
  1. /* $OpenBSD: tree.h,v 1.30 2020/10/10 18:03:41 otto Exp $ */
  2. /*
  3. * Copyright 2002 Niels Provos <provos@citi.umich.edu>
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions
  8. * are met:
  9. * 1. Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. * 2. Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in the
  13. * documentation and/or other materials provided with the distribution.
  14. *
  15. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  16. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  17. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  18. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  19. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  20. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  21. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  22. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  23. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  24. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  25. */
  26. #include "rbtree.h"
  27. #define RED 1
  28. #define BLACK 0
  29. static struct rbnode *rbtree_minmax(struct rbtree *, int);
  30. void* rbtree_min(struct rbtree *head) {
  31. return rbtree_minmax(head, -1);
  32. }
  33. void* rbtree_max(struct rbtree *head) {
  34. return rbtree_minmax(head, 1);
  35. }
  36. void* rbtree_left(void *node) {
  37. struct rbnode *elm = node;
  38. if (node == NULL) return NULL;
  39. return elm->entry.rbe_left;
  40. }
  41. void* rbtree_right(void *node) {
  42. struct rbnode *elm = node;
  43. if (node == NULL) return NULL;
  44. return elm->entry.rbe_right;
  45. }
  46. void* rbtree_parent(void *node) {
  47. struct rbnode *elm = node;
  48. if (node == NULL) return NULL;
  49. return elm->entry.rbe_parent;
  50. }
  51. static void augment(struct rbtree * head, struct rbnode *elm) {
  52. if (head->augment != NULL) head->augment(elm);
  53. }
  54. static void rbtree_insert_color(struct rbtree *head, struct rbnode *elm);
  55. static void rbtree_remove_color(struct rbtree *head, struct rbnode *parent,
  56. struct rbnode *elm);
  57. static void rotate_left(struct rbtree *head, struct rbnode *elm) {
  58. struct rbnode *tmp = elm->entry.rbe_right;
  59. if ((elm->entry.rbe_right = tmp->entry.rbe_left)) {
  60. tmp->entry.rbe_left->entry.rbe_parent = elm;
  61. }
  62. augment(head, elm);
  63. if ((tmp->entry.rbe_parent = elm->entry.rbe_parent)) {
  64. if (elm == elm->entry.rbe_parent->entry.rbe_left)
  65. elm->entry.rbe_parent->entry.rbe_left = tmp;
  66. else
  67. elm->entry.rbe_parent->entry.rbe_right = tmp;
  68. } else {
  69. head->rbh_root = tmp;
  70. }
  71. tmp->entry.rbe_left = elm;
  72. elm->entry.rbe_parent = tmp;
  73. augment(head, tmp);
  74. if (tmp->entry.rbe_parent) {
  75. augment(head, tmp->entry.rbe_parent);
  76. }
  77. }
  78. static void rotate_right(struct rbtree *head, struct rbnode *elm) {
  79. struct rbnode *tmp = elm->entry.rbe_left;
  80. if ((elm->entry.rbe_left = tmp->entry.rbe_right)) {
  81. tmp->entry.rbe_right->entry.rbe_parent = elm;
  82. }
  83. augment(head, elm);
  84. if ((tmp->entry.rbe_parent = elm->entry.rbe_parent)) {
  85. if (elm == elm->entry.rbe_parent->entry.rbe_left)
  86. elm->entry.rbe_parent->entry.rbe_left = tmp;
  87. else
  88. elm->entry.rbe_parent->entry.rbe_right = tmp;
  89. } else {
  90. head->rbh_root = tmp;
  91. }
  92. tmp->entry.rbe_right = elm;
  93. elm->entry.rbe_parent = tmp;
  94. augment(head, tmp);
  95. if (tmp->entry.rbe_parent) {
  96. augment(head, tmp->entry.rbe_parent);
  97. }
  98. }
  99. static void rbtree_insert_color(struct rbtree *head, struct rbnode *elm) {
  100. struct rbnode *parent, *gparent, *tmp;
  101. while ((parent = elm->entry.rbe_parent) && parent->entry.rbe_color == 1) {
  102. gparent = parent->entry.rbe_parent;
  103. if (parent == gparent->entry.rbe_left) {
  104. tmp = gparent->entry.rbe_right;
  105. if (tmp && tmp->entry.rbe_color == 1) {
  106. tmp->entry.rbe_color = BLACK;
  107. parent->entry.rbe_color = BLACK;
  108. gparent->entry.rbe_color = RED;
  109. elm = gparent;
  110. continue;
  111. }
  112. if (parent->entry.rbe_right == elm) {
  113. rotate_left(head, parent);
  114. tmp = parent;
  115. parent = elm;
  116. elm = tmp;
  117. }
  118. parent->entry.rbe_color = BLACK;
  119. gparent->entry.rbe_color = RED;
  120. rotate_right(head, gparent);
  121. } else {
  122. tmp = gparent->entry.rbe_left;
  123. if (tmp && tmp->entry.rbe_color == 1) {
  124. tmp->entry.rbe_color = BLACK;
  125. parent->entry.rbe_color = BLACK;
  126. gparent->entry.rbe_color = RED;;
  127. elm = gparent;
  128. continue;
  129. }
  130. if (parent->entry.rbe_left == elm) {
  131. rotate_right(head, parent);
  132. tmp = parent;
  133. parent = elm;
  134. elm = tmp;
  135. }
  136. parent->entry.rbe_color = BLACK;
  137. gparent->entry.rbe_color = RED;
  138. rotate_left(head, gparent);
  139. }
  140. }
  141. head->rbh_root->entry.rbe_color = BLACK;
  142. }
  143. static void rbtree_remove_color(struct rbtree *head, struct rbnode *parent,
  144. struct rbnode *elm) {
  145. struct rbnode *tmp;
  146. while ((elm == NULL || elm->entry.rbe_color == 0) &&
  147. elm != head->rbh_root) {
  148. if (parent->entry.rbe_left == elm) {
  149. tmp = parent->entry.rbe_right;
  150. if (tmp->entry.rbe_color == 1) {
  151. tmp->entry.rbe_color = BLACK;
  152. parent->entry.rbe_color = RED;
  153. rotate_left(head, parent);
  154. tmp = parent->entry.rbe_right;
  155. }
  156. if ((tmp->entry.rbe_left == NULL ||
  157. tmp->entry.rbe_left->entry.rbe_color == 0) &&
  158. (tmp->entry.rbe_right == NULL ||
  159. tmp->entry.rbe_right->entry.rbe_color == 0)) {
  160. tmp->entry.rbe_color = RED;
  161. elm = parent;
  162. parent = elm->entry.rbe_parent;
  163. } else {
  164. if (tmp->entry.rbe_right == NULL ||
  165. tmp->entry.rbe_right->entry.rbe_color == 0) {
  166. struct rbnode *oleft;
  167. if ((oleft = tmp->entry.rbe_left))
  168. oleft->entry.rbe_color = BLACK;
  169. tmp->entry.rbe_color = RED;
  170. rotate_right(head, tmp);
  171. tmp = parent->entry.rbe_right;
  172. }
  173. tmp->entry.rbe_color = parent->entry.rbe_color;
  174. parent->entry.rbe_color = BLACK;
  175. if (tmp->entry.rbe_right)
  176. tmp->entry.rbe_right->entry.rbe_color = BLACK;
  177. rotate_left(head, parent);
  178. elm = head->rbh_root;
  179. break;
  180. }
  181. } else {
  182. tmp = parent->entry.rbe_left;
  183. if (tmp->entry.rbe_color == 1) {
  184. tmp->entry.rbe_color = BLACK;
  185. parent->entry.rbe_color = RED;
  186. rotate_right(head, parent);
  187. tmp = parent->entry.rbe_left;
  188. }
  189. if ((tmp->entry.rbe_left == NULL ||
  190. tmp->entry.rbe_left->entry.rbe_color == 0) &&
  191. (tmp->entry.rbe_right == NULL ||
  192. tmp->entry.rbe_right->entry.rbe_color == 0)) {
  193. tmp->entry.rbe_color = RED;
  194. elm = parent;
  195. parent = elm->entry.rbe_parent;
  196. } else {
  197. if (tmp->entry.rbe_left == NULL ||
  198. tmp->entry.rbe_left->entry.rbe_color == 0) {
  199. struct rbnode *oright;
  200. if ((oright = tmp->entry.rbe_right))
  201. oright->entry.rbe_color = BLACK;
  202. tmp->entry.rbe_color = RED;
  203. rotate_left(head, tmp);
  204. tmp = parent->entry.rbe_left;
  205. }
  206. tmp->entry.rbe_color = parent->entry.rbe_color;
  207. parent->entry.rbe_color = BLACK;
  208. if (tmp->entry.rbe_left)
  209. tmp->entry.rbe_left->entry.rbe_color = BLACK;
  210. rotate_right(head, parent);
  211. elm = head->rbh_root;
  212. break;
  213. }
  214. }
  215. }
  216. if (elm)
  217. elm->entry.rbe_color = BLACK;
  218. }
  219. void rbtree_remove(struct rbtree *head, void* elmv) {
  220. struct rbnode *elm = elmv;
  221. struct rbnode *child, *parent;
  222. int color;
  223. if (elm->entry.rbe_left == NULL)
  224. child = elm->entry.rbe_right;
  225. else if (elm->entry.rbe_right == NULL)
  226. child = elm->entry.rbe_left;
  227. else {
  228. struct rbnode *old = elm, *left;
  229. elm = elm->entry.rbe_right;
  230. while ((left = elm->entry.rbe_left))
  231. elm = left;
  232. child = elm->entry.rbe_right;
  233. parent = elm->entry.rbe_parent;
  234. color = elm->entry.rbe_color;
  235. if (child)
  236. child->entry.rbe_parent = parent;
  237. if (parent) {
  238. if (parent->entry.rbe_left == elm)
  239. parent->entry.rbe_left = child;
  240. else
  241. parent->entry.rbe_right = child;
  242. augment(head, parent);
  243. } else
  244. head->rbh_root = child;
  245. if (elm->entry.rbe_parent == old)
  246. parent = elm;
  247. elm->entry = old->entry;
  248. if (old->entry.rbe_parent) {
  249. if ((old->entry.rbe_parent)->entry.rbe_left == old)
  250. (old->entry.rbe_parent)->entry.rbe_left = elm;
  251. else
  252. (old->entry.rbe_parent)->entry.rbe_right = elm;
  253. augment(head, old->entry.rbe_parent);
  254. } else
  255. head->rbh_root = elm;
  256. old->entry.rbe_left->entry.rbe_parent = elm;
  257. if (old->entry.rbe_right)
  258. old->entry.rbe_right->entry.rbe_parent = elm;
  259. if (parent) {
  260. left = parent;
  261. if (head->augment != NULL) {
  262. do {
  263. augment(head, left);
  264. } while ((left = left->entry.rbe_parent));
  265. }
  266. }
  267. goto color;
  268. }
  269. parent = elm->entry.rbe_parent;
  270. color = elm->entry.rbe_color;
  271. if (child)
  272. child->entry.rbe_parent = parent;
  273. if (parent) {
  274. if (parent->entry.rbe_left == elm)
  275. parent->entry.rbe_left = child;
  276. else
  277. parent->entry.rbe_right = child;
  278. struct rbnode* goback = parent;
  279. if (head->augment != NULL) {
  280. do {
  281. augment(head, goback);
  282. } while ((goback = goback->entry.rbe_parent));
  283. }
  284. } else
  285. head->rbh_root = child;
  286. color:
  287. if (color == 0)
  288. rbtree_remove_color(head, parent, child);
  289. }
  290. void* rbtree_insert(struct rbtree *head, void *elmv) {
  291. struct rbnode *elm = elmv;
  292. struct rbnode *tmp;
  293. struct rbnode *parent = NULL;
  294. int comp = 0;
  295. tmp = head->rbh_root;
  296. while (tmp) {
  297. parent = tmp;
  298. comp = head->cmp((void*)elm->content, (void*)parent->content);
  299. if (comp < 0)
  300. tmp = tmp->entry.rbe_left;
  301. else if (comp > 0)
  302. tmp = tmp->entry.rbe_right;
  303. else
  304. return tmp;
  305. }
  306. elm->entry.rbe_parent = parent;
  307. elm->entry.rbe_left = elm->entry.rbe_right = NULL;
  308. elm->entry.rbe_color = RED;
  309. if (parent != NULL) {
  310. if (comp < 0)
  311. parent->entry.rbe_left = elm;
  312. else
  313. parent->entry.rbe_right = elm;
  314. struct rbnode* goback = parent;
  315. if (head->augment != NULL) {
  316. do {
  317. augment(head, goback);
  318. } while ((goback = goback->entry.rbe_parent));
  319. }
  320. } else
  321. head->rbh_root = elm;
  322. rbtree_insert_color(head, elm);
  323. return (NULL);
  324. }
  325. void* rbtree_find(struct rbtree *head, void *key) {
  326. struct rbnode *tmp = head->rbh_root;
  327. int comp;
  328. while (tmp) {
  329. comp = head->cmp(key, (void*)tmp->content);
  330. if (comp < 0)
  331. tmp = tmp->entry.rbe_left;
  332. else if (comp > 0)
  333. tmp = tmp->entry.rbe_right;
  334. else
  335. return tmp;
  336. }
  337. return (NULL);
  338. }
  339. void* rbtree_next(struct rbtree *head, void *elmv) {
  340. struct rbnode *elm = elmv;
  341. if (elm->entry.rbe_right) {
  342. elm = elm->entry.rbe_right;
  343. while (elm->entry.rbe_left)
  344. elm = elm->entry.rbe_left;
  345. } else {
  346. if (elm->entry.rbe_parent &&
  347. (elm == (elm->entry.rbe_parent)->entry.rbe_left))
  348. elm = elm->entry.rbe_parent;
  349. else {
  350. while (elm->entry.rbe_parent &&
  351. (elm == (elm->entry.rbe_parent)->entry.rbe_right))
  352. elm = elm->entry.rbe_parent;
  353. elm = elm->entry.rbe_parent;
  354. }
  355. }
  356. return elm;
  357. }
  358. static struct rbnode *rbtree_minmax(struct rbtree *head, int val) {
  359. struct rbnode *tmp = head->rbh_root;
  360. struct rbnode *parent = NULL;
  361. while (tmp) {
  362. parent = tmp;
  363. if (val < 0)
  364. tmp = tmp->entry.rbe_left;
  365. else
  366. tmp = tmp->entry.rbe_right;
  367. }
  368. return parent;
  369. };
  370. static void rbtree_free_impl(struct rbnode *node, void (*free_cb)(void*)) {
  371. if (node == NULL) return;
  372. if (free_cb != NULL) free_cb(node->content);
  373. rbtree_free_impl(node->entry.rbe_left, free_cb);
  374. rbtree_free_impl(node->entry.rbe_right, free_cb);
  375. free(node);
  376. }
  377. void rbtree_free(struct rbtree *head, void (*free_cb)(void*)) {
  378. rbtree_free_impl(head->rbh_root, free_cb);
  379. }