splay-tree.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703
  1. /*
  2. * This program is free software: you can redistribute it and/or modify
  3. * it under the terms of the GNU General Public License as published by
  4. * the Free Software Foundation, either version 3 of the License, or
  5. * (at your option) any later version.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. *
  12. * You should have received a copy of the GNU General Public License
  13. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. *
  15. * SPDX-License-Identifier: GPL-3.0+
  16. * License-Filename: LICENSE
  17. *
  18. */
  19. /* A splay-tree datatype.
  20. Copyright (C) 1998-2021 Free Software Foundation, Inc.
  21. Contributed by Mark Mitchell (mark@markmitchell.com).
  22. This file is part of GNU CC.
  23. GNU CC is free software; you can redistribute it and/or modify it
  24. under the terms of the GNU General Public License as published by
  25. the Free Software Foundation; either version 2, or (at your option)
  26. any later version.
  27. GNU CC is distributed in the hope that it will be useful, but
  28. WITHOUT ANY WARRANTY; without even the implied warranty of
  29. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  30. General Public License for more details.
  31. You should have received a copy of the GNU General Public License
  32. along with GNU CC; see the file COPYING. If not, write to
  33. the Free Software Foundation, 51 Franklin Street - Fifth Floor,
  34. Boston, MA 02110-1301, USA. */
  35. /* For an easily readable description of splay-trees, see:
  36. Lewis, Harry R. and Denenberg, Larry. Data Structures and Their
  37. Algorithms. Harper-Collins, Inc. 1991. */
  38. /**
  39. * @file: splay-tree.c
  40. */
  41. #include "config.h"
  42. #include <stdio.h>
  43. #include <stdlib.h>
  44. #include <string.h>
  45. #include "splay-tree.h"
  46. #include "dpmem.h"
  47. /* here wrapping to custom malloc/free can be set */
  48. static inline void *splay_tree_malloc(size_t n)
  49. {
  50. return (dp_calloc(1, n));
  51. }
  52. static inline void *splay_tree_free(void *ptr)
  53. {
  54. void *p2 = NULL;
  55. if (ptr) {
  56. p2 = dp_free(ptr);
  57. if (p2) {
  58. }
  59. }
  60. return ((void *)0);
  61. }
  62. /* forward decl. */
  63. static struct splay_tree_node_n *splay(splay_tree sp, splay_tree_key key);
  64. /* delete whole sp tree */
  65. splay_tree splay_tree_delete(splay_tree sp)
  66. {
  67. splay_tree_node spn = (splay_tree_node) 0;
  68. splay_tree_key *keys = (splay_tree_key *) 0;
  69. int count = 0;
  70. int i = 0;
  71. if (sp == (splay_tree) 0) {
  72. return ((splay_tree) 0);
  73. }
  74. /* if there is data */
  75. if (sp->root) {
  76. /* for every node, this can not cause stack smashing.
  77. * this is slowest way possible but splay_tree_delete() does almost never happen.
  78. * gcc realloc()'s array with pointers to free() but using realloc()
  79. * may cause unexpected high memory usage, thats why avoiding realloc() use.
  80. */
  81. /* first count how many entries */
  82. spn = splay_tree_min(sp);
  83. while (spn) {
  84. count++;
  85. spn = splay_tree_successor(sp, spn->key);
  86. }
  87. /* one extra for safety */
  88. count++;
  89. /* get buffer to hold keys */
  90. keys = (splay_tree_key *) splay_tree_malloc(count * sizeof(splay_tree_key));
  91. /* copy keys into buffer */
  92. spn = splay_tree_min(sp);
  93. i = 0;
  94. while (spn) {
  95. keys[i] = (splay_tree_key) spn->key;
  96. i++;
  97. spn = splay_tree_successor(sp, spn->key);
  98. }
  99. /* remove every key in buffer */
  100. for (i = 0; i < count; i++) {
  101. splay_tree_remove(sp, (splay_tree_key) keys[i]);
  102. keys[i] = (splay_tree_key) 0;
  103. }
  104. /* ready. */
  105. keys = (splay_tree_key *) splay_tree_free(keys);
  106. if (keys) {
  107. }
  108. keys = (splay_tree_key *) 0;
  109. }
  110. /* wipe the pointers in the struct to make valgrind happy */
  111. sp->root = (splay_tree_node) 0;
  112. /* The comparision function. */
  113. sp->comp = (splay_tree_compare_fn) 0;
  114. /* The deallocate-key function. NULL if no cleanup is necessary. */
  115. sp->delete_key = (splay_tree_delete_key_fn) 0;
  116. /* The deallocate-value function. NULL if no cleanup is necessary. */
  117. sp->delete_value = (splay_tree_delete_value_fn) 0;
  118. return ((splay_tree) splay_tree_free((void *)sp));
  119. }
  120. /* Allocate a new splay tree, using COMPARE_FN to compare nodes,
  121. DELETE_KEY_FN to deallocate keys, and DELETE_VALUE_FN to deallocate
  122. values. */
  123. splay_tree
  124. splay_tree_new(splay_tree_compare_fn compare_fn, splay_tree_delete_key_fn delete_key_fn, splay_tree_delete_value_fn delete_value_fn)
  125. {
  126. splay_tree sp = (splay_tree) 0;
  127. /* there must be a compare function, the free() functions are optional */
  128. if (compare_fn == (splay_tree_compare_fn) 0) {
  129. return ((splay_tree) 0);
  130. }
  131. sp = (splay_tree) splay_tree_malloc(sizeof(struct splay_tree_t));
  132. /* set root node to use and the functions */
  133. sp->root = (splay_tree_node) 0;
  134. sp->comp = compare_fn;
  135. sp->delete_key = delete_key_fn;
  136. sp->delete_value = delete_value_fn;
  137. return ((splay_tree) sp);
  138. }
  139. /* Insert a new node (associating KEY with DATA) into SP. If a
  140. previous node with the indicated KEY exists, its data is not replaced
  141. with the new value. */
  142. void splay_tree_insert(splay_tree sp, splay_tree_key key, splay_tree_value value)
  143. {
  144. splay_tree_node spn = (splay_tree_node) 0;
  145. int comparison = 0;
  146. if (sp == (splay_tree) 0) {
  147. /* no tree */
  148. return;
  149. }
  150. spn = splay_tree_lookup(sp, key);
  151. if (spn != (splay_tree_node) 0) {
  152. /* did already exist */
  153. return;
  154. }
  155. /* Create a new node, and insert it at the root. */
  156. spn = (splay_tree_node) splay_tree_malloc(sizeof(struct splay_tree_node_n));
  157. /* set node data */
  158. spn->key = key;
  159. spn->value = value;
  160. if (sp->root == (splay_tree_node) 0) {
  161. /* first entry */
  162. sp->root = spn;
  163. return;
  164. }
  165. /* add in tree */
  166. comparison = (*sp->comp) (sp->root->key, key);
  167. if (comparison < 0) {
  168. spn->left = sp->root;
  169. spn->right = spn->left->right;
  170. spn->left->right = (splay_tree_node) 0;
  171. } else {
  172. /* > or == */
  173. spn->right = sp->root;
  174. spn->left = spn->right->left;
  175. spn->right->left = (splay_tree_node) 0;
  176. }
  177. sp->root = spn;
  178. return;
  179. }
  180. /* Remove KEY from SP. It is not an error if it did not exist. */
  181. void splay_tree_remove(splay_tree sp, splay_tree_key key)
  182. {
  183. splay_tree_node spn = (splay_tree_node) 0;
  184. splay_tree_node node = (splay_tree_node) 0;
  185. splay_tree_node left = (splay_tree_node) 0;
  186. splay_tree_node right = (splay_tree_node) 0;
  187. if (sp == (splay_tree) 0) {
  188. /* no tree */
  189. return;
  190. }
  191. if (sp->root == (splay_tree_node) 0) {
  192. /* no data */
  193. return;
  194. }
  195. spn = splay_tree_lookup(sp, key);
  196. if (spn == (splay_tree_node) 0) {
  197. return;
  198. }
  199. /* found entry to delete now in spn */
  200. node = sp->root;
  201. left = sp->root->left;
  202. right = sp->root->right;
  203. /* One of the children is now the root. Doesn't matter much
  204. which, so long as we preserve the properties of the tree. */
  205. if (left) {
  206. sp->root = left;
  207. /* If there was a right child as well, hang it off the
  208. right-most leaf of the left child. */
  209. if (right) {
  210. while (left->right) {
  211. left = left->right;
  212. }
  213. left->right = right;
  214. }
  215. } else {
  216. sp->root = right;
  217. }
  218. /* free() key if needed */
  219. if (sp->delete_key) {
  220. /* avoid free(0) */
  221. if (node->key) {
  222. (*sp->delete_key) (node->key);
  223. }
  224. node->key = (splay_tree_key) 0;
  225. }
  226. /* free() value if needed */
  227. if (sp->delete_value) {
  228. /* avoid free(0) */
  229. if (node->value) {
  230. (*sp->delete_value) (node->value);
  231. }
  232. node->value = (splay_tree_value) 0;
  233. }
  234. /* free() node itself and wipe the pointers */
  235. node->left = (splay_tree_node) 0;
  236. node->right = (splay_tree_node) 0;
  237. node = (splay_tree_node) splay_tree_free((void *)node);
  238. if (node) {
  239. }
  240. node = (splay_tree_node) 0;
  241. return;
  242. }
  243. /* Lookup KEY in SP, returning VALUE if present, and NULL
  244. otherwise. */
  245. splay_tree_node splay_tree_lookup(splay_tree sp, splay_tree_key key)
  246. {
  247. splay_tree_node spn = (splay_tree_node) 0;
  248. if (sp == (splay_tree) 0) {
  249. /* no tree */
  250. return ((splay_tree_node) 0);
  251. }
  252. if (sp->root == (splay_tree_node) 0) {
  253. /* no data */
  254. return ((splay_tree_node) 0);
  255. }
  256. if ((*sp->comp) (sp->root->key, key) == 0) {
  257. /* found */
  258. return ((splay_tree_node) sp->root);
  259. }
  260. spn = splay(sp, key);
  261. if (spn) {
  262. if ((*sp->comp) (sp->root->key, key) == 0) {
  263. /* found */
  264. return ((splay_tree_node) sp->root);
  265. }
  266. }
  267. /* not found */
  268. return ((splay_tree_node) 0);
  269. }
  270. /* Call FN, passing it the DATA, for every node in SP, following an
  271. in-order traversal. If FN every returns a non-zero value, the
  272. iteration ceases immediately, and the value is returned.
  273. Otherwise, this function returns 0.
  274. */
  275. int splay_tree_foreach(splay_tree sp, splay_tree_foreach_fn fn, void *data)
  276. {
  277. splay_tree_node spn = (splay_tree_node) 0;
  278. splay_tree_key spnkey = (splay_tree_key) 0;
  279. int status = 0;
  280. /* <nil> splaytree */
  281. if (sp == (splay_tree) 0) {
  282. return (0);
  283. }
  284. /* no data */
  285. if (sp->root == (splay_tree_node) 0) {
  286. return (0);
  287. }
  288. /* no routine() to run */
  289. if (fn == (splay_tree_foreach_fn) 0) {
  290. return (0);
  291. }
  292. /* */
  293. status = 0;
  294. spn = splay_tree_min(sp);
  295. while (spn) {
  296. /* save key if spn disappears */
  297. spnkey = spn->key;
  298. status = (*fn) (spn, data);
  299. if (status) {
  300. break;
  301. }
  302. spn = splay_tree_successor(sp, spnkey);
  303. }
  304. /* set if callback() routine set it otherwise 0 */
  305. return (status);
  306. }
  307. /* Return the node in SP with the smallest key. */
  308. splay_tree_node splay_tree_min(splay_tree sp)
  309. {
  310. splay_tree_node n = (splay_tree_node) 0;
  311. /* <nil> splaytree */
  312. if (sp == (splay_tree) 0) {
  313. return ((splay_tree_node) 0);
  314. }
  315. /* no data */
  316. if (sp->root == (splay_tree_node) 0) {
  317. return ((splay_tree_node) 0);
  318. }
  319. n = sp->root;
  320. /* scan l */
  321. while (n->left) {
  322. n = n->left;
  323. }
  324. return ((splay_tree_node) n);
  325. }
  326. /* Return the node in SP with the highest key. */
  327. splay_tree_node splay_tree_max(splay_tree sp)
  328. {
  329. splay_tree_node n = (splay_tree_node) 0;
  330. /* <nil> splaytree */
  331. if (sp == (splay_tree) 0) {
  332. return ((splay_tree_node) 0);
  333. }
  334. /* no data */
  335. if (sp->root == (splay_tree_node) 0) {
  336. return ((splay_tree_node) 0);
  337. }
  338. n = sp->root;
  339. /* scan l */
  340. while (n->right) {
  341. n = n->right;
  342. }
  343. return ((splay_tree_node) n);
  344. }
  345. /* return 1 if splay tree has data, otherwise 0 */
  346. int splay_tree_has_data(splay_tree sp)
  347. {
  348. if (sp == (splay_tree) 0) {
  349. return (0);
  350. }
  351. if (sp->root) {
  352. return (1);
  353. } else {
  354. return (0);
  355. }
  356. }
  357. /* Return the immediate successor KEY, or NULL if there is no
  358. successor. KEY need not be present in the tree. */
  359. splay_tree_node splay_tree_successor(splay_tree sp, splay_tree_key key)
  360. {
  361. int comparison = 0;
  362. splay_tree_node node = (splay_tree_node) 0;
  363. if (sp == (splay_tree) 0) {
  364. /* no tree */
  365. return ((splay_tree_node) 0);
  366. }
  367. /* If the tree is empty, there is certainly no successor. */
  368. if (sp->root == (splay_tree_node) 0) {
  369. return ((splay_tree_node) 0);
  370. }
  371. /* Splay the tree around KEY. That will leave either the KEY
  372. itself, its predecessor, or its successor at the root. */
  373. node = splay(sp, key);
  374. if (node == (splay_tree_node) 0) {
  375. return ((splay_tree_node) 0);
  376. }
  377. /* */
  378. comparison = (*sp->comp) (sp->root->key, key);
  379. /* If the successor is at the root, just return it. */
  380. if (comparison > 0) {
  381. return ((splay_tree_node) sp->root);
  382. }
  383. /* Otherwise, find the leftmost element of the right subtree. */
  384. node = sp->root->right;
  385. if (node) {
  386. while (node->left) {
  387. node = node->left;
  388. }
  389. }
  390. return ((splay_tree_node) node);
  391. }
  392. /* free() wrappers to free key/value */
  393. void splay_tree_free_value(splay_tree_value value)
  394. {
  395. void *v = NULL;
  396. if (value) {
  397. v = splay_tree_free((void *)value);
  398. if (v) {
  399. }
  400. }
  401. return;
  402. }
  403. void splay_tree_free_key(splay_tree_key key)
  404. {
  405. void *k = NULL;
  406. if (key) {
  407. k = splay_tree_free((void *)key);
  408. if (k) {
  409. }
  410. }
  411. return;
  412. }
  413. /* Splay-tree comparison function, treating the keys as ints. */
  414. int splay_tree_compare_ints(splay_tree_key k1, splay_tree_key k2)
  415. {
  416. if ((int)k1 < (int)k2) {
  417. return ((int)-1);
  418. } else if ((int)k1 > (int)k2) {
  419. return (1);
  420. } else {
  421. return (0);
  422. }
  423. }
  424. /* Splay-tree comparison function, treating the keys as pointers.
  425. Note this is possibly not portable on all systems according to standards
  426. and may have undefined results. there seems no good solution for this.
  427. (a char datatype does not have to be a single byte in c for example)
  428. */
  429. int splay_tree_compare_pointers(splay_tree_key k1, splay_tree_key k2)
  430. {
  431. /* 0==0 */
  432. if ((k1 == (splay_tree_key) 0) && (k2 == (splay_tree_key) 0)) {
  433. return (0);
  434. }
  435. /* possible undefined results at this, says the c standard. has to be understood as (signed char *) */
  436. if ((char *)k1 < (char *)k2) {
  437. return ((int)-1);
  438. } else if ((char *)k1 > (char *)k2) {
  439. return (1);
  440. } else {
  441. return (0);
  442. }
  443. }
  444. /* Comparison function for a splay tree in which the keys are strings.
  445. K1 and K2 have the dynamic type "const char *". Returns <0, 0, or
  446. >0 to indicate whether K1 is less than, equal to, or greater than
  447. K2, respectively.
  448. similar issues here when as compare pointers and c portable src.
  449. */
  450. int splay_tree_compare_strings(splay_tree_key k1, splay_tree_key k2)
  451. {
  452. const char *s1 = (const char *)k1;
  453. const char *s2 = (const char *)k2;
  454. int ret = 0;
  455. if ((k1 == (splay_tree_key) 0) && (k2 == (splay_tree_key) 0)) {
  456. return (0);
  457. }
  458. if (s1 == (const char *)0) {
  459. /* to avoid crashes only */
  460. return (0);
  461. }
  462. if (s2 == (const char *)0) {
  463. /* to avoid crashes only */
  464. return (0);
  465. }
  466. /* check if same pointer. possible not portable c. */
  467. if (s1 == s2) {
  468. return (0);
  469. }
  470. ret = strcmp(s1, s2);
  471. return ((int)ret);
  472. }
  473. /* */
  474. static struct splay_tree_node_n *splay(splay_tree sp, splay_tree_key key)
  475. {
  476. struct splay_tree_node_n *t = (struct splay_tree_node_n *)0;
  477. struct splay_tree_node_n *l = (struct splay_tree_node_n *)0;
  478. struct splay_tree_node_n *r = (struct splay_tree_node_n *)0;
  479. struct splay_tree_node_n *y = (struct splay_tree_node_n *)0;
  480. int comparevalue = 0;
  481. int comparevalue2 = 0;
  482. struct splay_tree_node_n tmp = {
  483. /* The key. */
  484. (splay_tree_key) 0,
  485. /* The value. */
  486. (splay_tree_value) 0,
  487. /* The left and right children, respectively. */
  488. (struct splay_tree_node_n *)0, /* left */
  489. (struct splay_tree_node_n *)0 /* right */
  490. };
  491. /* no tree */
  492. if (sp == (splay_tree) 0) {
  493. return ((struct splay_tree_node_n *)0);
  494. }
  495. /* no data in root. return 0 */
  496. if (sp->root == (struct splay_tree_node_n *)0) {
  497. return ((struct splay_tree_node_n *)0);
  498. }
  499. /* current root */
  500. t = sp->root;
  501. tmp.left = (struct splay_tree_node_n *)0;
  502. tmp.right = (struct splay_tree_node_n *)0;
  503. l = &tmp;
  504. r = &tmp;
  505. labelstart:
  506. /* */
  507. comparevalue = (*sp->comp) (key, t->key);
  508. if (comparevalue < 0) {
  509. if (t->left == (struct splay_tree_node_n *)0) {
  510. goto labelend;
  511. }
  512. /* */
  513. comparevalue2 = (*sp->comp) (key, t->left->key);
  514. if (comparevalue2 < 0) {
  515. y = t->left;
  516. t->left = y->right;
  517. y->right = t;
  518. t = y;
  519. if (t->left == (struct splay_tree_node_n *)0) {
  520. goto labelend;
  521. }
  522. }
  523. /* */
  524. r->left = t;
  525. r = t;
  526. t = t->left;
  527. } else if (comparevalue > 0) {
  528. if (t->right == (struct splay_tree_node_n *)0) {
  529. goto labelend;
  530. }
  531. /* */
  532. comparevalue2 = (*sp->comp) (key, t->right->key);
  533. if (comparevalue2 > 0) {
  534. /* */
  535. y = t->right;
  536. t->right = y->left;
  537. y->left = t;
  538. t = y;
  539. if (t->right == (struct splay_tree_node_n *)0) {
  540. goto labelend;
  541. }
  542. }
  543. /* */
  544. l->right = t;
  545. l = t;
  546. t = t->right;
  547. } else {
  548. /* here if (comparevalue == 0) */
  549. goto labelend;
  550. }
  551. goto labelstart;
  552. labelend:
  553. l->right = t->left;
  554. r->left = t->right;
  555. t->left = tmp.right;
  556. t->right = tmp.left;
  557. sp->root = t;
  558. return ((struct splay_tree_node_n *)t);
  559. }
  560. /* end. */