splay_tree.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563
  1. /*
  2. splay_tree.c -- splay tree and linked list convenience
  3. Copyright (C) 2004-2006 Guus Sliepen <guus@tinc-vpn.org>
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. $Id: splay_tree.c 1374 2004-03-21 14:21:22Z guus $
  16. */
  17. #include "system.h"
  18. #include "splay_tree.h"
  19. #include "xalloc.h"
  20. /* Splay operation */
  21. static splay_node_t *splay_top_down(splay_tree_t *tree, const void *data, int *result) {
  22. splay_node_t left = {0}, right = {0};
  23. splay_node_t *leftbottom = &left, *rightbottom = &right, *child, *grandchild;
  24. splay_node_t *root = tree->root;
  25. int c;
  26. if(!root) {
  27. if(result)
  28. *result = 0;
  29. return NULL;
  30. }
  31. while((c = tree->compare(data, root->data))) {
  32. if(c < 0 && (child = root->left)) {
  33. c = tree->compare(data, child->data);
  34. if(c < 0 && (grandchild = child->left)) {
  35. rightbottom->left = child;
  36. child->parent = rightbottom;
  37. rightbottom = child;
  38. if((root->left = child->right))
  39. child->right->parent = root;
  40. child->right = root;
  41. root->parent = child;
  42. child->left = NULL;
  43. grandchild->parent = NULL;
  44. root = grandchild;
  45. } else if (c > 0 && (grandchild = child->right)) {
  46. leftbottom->right = child;
  47. child->parent = leftbottom;
  48. leftbottom = child;
  49. child->right = NULL;
  50. grandchild->parent = NULL;
  51. rightbottom->left = root;
  52. root->parent = rightbottom;
  53. rightbottom = root;
  54. root->left = NULL;
  55. root = grandchild;
  56. } else {
  57. rightbottom->left = root;
  58. root->parent = rightbottom;
  59. rightbottom = root;
  60. root->left = NULL;
  61. child->parent = NULL;
  62. root = child;
  63. break;
  64. }
  65. } else if(c > 0 && (child = root->right)) {
  66. c = tree->compare(data, child->data);
  67. if(c > 0 && (grandchild = child->right)) {
  68. leftbottom->right = child;
  69. child->parent = leftbottom;
  70. leftbottom = child;
  71. if((root->right = child->left))
  72. child->left->parent = root;
  73. child->left = root;
  74. root->parent = child;
  75. child->right = NULL;
  76. grandchild->parent = NULL;
  77. root = grandchild;
  78. } else if (c < 0 && (grandchild = child->left)) {
  79. rightbottom->left = child;
  80. child->parent = rightbottom;
  81. rightbottom = child;
  82. child->left = NULL;
  83. grandchild->parent = NULL;
  84. leftbottom->right = root;
  85. root->parent = leftbottom;
  86. leftbottom = root;
  87. root->right = NULL;
  88. root = grandchild;
  89. } else {
  90. leftbottom->right = root;
  91. root->parent = leftbottom;
  92. leftbottom = root;
  93. root->right = NULL;
  94. child->parent = NULL;
  95. root = child;
  96. break;
  97. }
  98. } else {
  99. break;
  100. }
  101. }
  102. /* Merge trees */
  103. if(left.right) {
  104. if(root->left) {
  105. leftbottom->right = root->left;
  106. root->left->parent = leftbottom;
  107. }
  108. root->left = left.right;
  109. left.right->parent = root;
  110. }
  111. if(right.left) {
  112. if(root->right) {
  113. rightbottom->left = root->right;
  114. root->right->parent = rightbottom;
  115. }
  116. root->right = right.left;
  117. right.left->parent = root;
  118. }
  119. /* Return result */
  120. tree->root = root;
  121. if(result)
  122. *result = c;
  123. return tree->root;
  124. }
  125. static void splay_bottom_up(splay_tree_t *tree, splay_node_t *node) {
  126. splay_node_t *parent, *grandparent, *greatgrandparent;
  127. while((parent = node->parent)) {
  128. if(!(grandparent = parent->parent)) { /* zig */
  129. if(node == parent->left) {
  130. if((parent->left = node->right))
  131. parent->left->parent = parent;
  132. node->right = parent;
  133. } else {
  134. if((parent->right = node->left))
  135. parent->right->parent = parent;
  136. node->left = parent;
  137. }
  138. parent->parent = node;
  139. node->parent = NULL;
  140. } else {
  141. greatgrandparent = grandparent->parent;
  142. if(node == parent->left && parent == grandparent->left) { /* left zig-zig */
  143. if((grandparent->left = parent->right))
  144. grandparent->left->parent = grandparent;
  145. parent->right = grandparent;
  146. grandparent->parent = parent;
  147. if((parent->left = node->right))
  148. parent->left->parent = parent;
  149. node->right = parent;
  150. parent->parent = node;
  151. } else if(node == parent->right && parent == grandparent->right) { /* right zig-zig */
  152. if((grandparent->right = parent->left))
  153. grandparent->right->parent = grandparent;
  154. parent->left = grandparent;
  155. grandparent->parent = parent;
  156. if((parent->right = node->left))
  157. parent->right->parent = parent;
  158. node->left = parent;
  159. parent->parent = node;
  160. } else if(node == parent->right && parent == grandparent->left) { /* left-right zig-zag */
  161. if((parent->right = node->left))
  162. parent->right->parent = parent;
  163. node->left = parent;
  164. parent->parent = node;
  165. if((grandparent->left = node->right))
  166. grandparent->left->parent = grandparent;
  167. node->right = grandparent;
  168. grandparent->parent = node;
  169. } else { /* right-left zig-zag */
  170. if((parent->left = node->right))
  171. parent->left->parent = parent;
  172. node->right = parent;
  173. parent->parent = node;
  174. if((grandparent->right = node->left))
  175. grandparent->right->parent = grandparent;
  176. node->left = grandparent;
  177. grandparent->parent = node;
  178. }
  179. if((node->parent = greatgrandparent)) {
  180. if(grandparent == greatgrandparent->left)
  181. greatgrandparent->left = node;
  182. else
  183. greatgrandparent->right = node;
  184. }
  185. }
  186. }
  187. tree->root = node;
  188. }
  189. /* (De)constructors */
  190. splay_tree_t *splay_alloc_tree(splay_compare_t compare, splay_action_t delete) {
  191. splay_tree_t *tree;
  192. tree = xmalloc_and_zero(sizeof(splay_tree_t));
  193. tree->compare = compare;
  194. tree->delete = delete;
  195. return tree;
  196. }
  197. void splay_free_tree(splay_tree_t *tree) {
  198. free(tree);
  199. }
  200. splay_node_t *splay_alloc_node(void) {
  201. return xmalloc_and_zero(sizeof(splay_node_t));
  202. }
  203. void splay_free_node(splay_tree_t *tree, splay_node_t *node) {
  204. if(node->data && tree->delete)
  205. tree->delete(node->data);
  206. free(node);
  207. }
  208. /* Searching */
  209. void *splay_search(splay_tree_t *tree, const void *data) {
  210. splay_node_t *node;
  211. node = splay_search_node(tree, data);
  212. return node ? node->data : NULL;
  213. }
  214. void *splay_search_closest(splay_tree_t *tree, const void *data, int *result) {
  215. splay_node_t *node;
  216. node = splay_search_closest_node(tree, data, result);
  217. return node ? node->data : NULL;
  218. }
  219. void *splay_search_closest_smaller(splay_tree_t *tree, const void *data) {
  220. splay_node_t *node;
  221. node = splay_search_closest_smaller_node(tree, data);
  222. return node ? node->data : NULL;
  223. }
  224. void *splay_search_closest_greater(splay_tree_t *tree, const void *data) {
  225. splay_node_t *node;
  226. node = splay_search_closest_greater_node(tree, data);
  227. return node ? node->data : NULL;
  228. }
  229. splay_node_t *splay_search_node(splay_tree_t *tree, const void *data) {
  230. splay_node_t *node;
  231. int result;
  232. node = splay_search_closest_node(tree, data, &result);
  233. return result ? NULL : node;
  234. }
  235. splay_node_t *splay_search_closest_node_nosplay(const splay_tree_t *tree, const void *data, int *result) {
  236. splay_node_t *node;
  237. int c;
  238. node = tree->root;
  239. if(!node) {
  240. if(result)
  241. *result = 0;
  242. return NULL;
  243. }
  244. for(;;) {
  245. c = tree->compare(data, node->data);
  246. if(c < 0) {
  247. if(node->left)
  248. node = node->left;
  249. else
  250. break;
  251. } else if(c > 0) {
  252. if(node->right)
  253. node = node->right;
  254. else
  255. break;
  256. } else {
  257. break;
  258. }
  259. }
  260. if(result)
  261. *result = c;
  262. return node;
  263. }
  264. splay_node_t *splay_search_closest_node(splay_tree_t *tree, const void *data, int *result) {
  265. return splay_top_down(tree, data, result);
  266. }
  267. splay_node_t *splay_search_closest_smaller_node(splay_tree_t *tree, const void *data) {
  268. splay_node_t *node;
  269. int result;
  270. node = splay_search_closest_node(tree, data, &result);
  271. if(result < 0)
  272. node = node->prev;
  273. return node;
  274. }
  275. splay_node_t *splay_search_closest_greater_node(splay_tree_t *tree, const void *data) {
  276. splay_node_t *node;
  277. int result;
  278. node = splay_search_closest_node(tree, data, &result);
  279. if(result > 0)
  280. node = node->next;
  281. return node;
  282. }
  283. /* Insertion and deletion */
  284. splay_node_t *splay_insert(splay_tree_t *tree, void *data) {
  285. splay_node_t *closest, *new;
  286. int result;
  287. if(!tree->root) {
  288. new = splay_alloc_node();
  289. new->data = data;
  290. splay_insert_top(tree, new);
  291. } else {
  292. closest = splay_search_closest_node(tree, data, &result);
  293. if(!result)
  294. return NULL;
  295. new = splay_alloc_node();
  296. new->data = data;
  297. if(result < 0)
  298. splay_insert_before(tree, closest, new);
  299. else
  300. splay_insert_after(tree, closest, new);
  301. }
  302. return new;
  303. }
  304. splay_node_t *splay_insert_node(splay_tree_t *tree, splay_node_t *node) {
  305. splay_node_t *closest;
  306. int result;
  307. if(!tree->root)
  308. splay_insert_top(tree, node);
  309. else {
  310. closest = splay_search_closest_node(tree, node->data, &result);
  311. if(!result)
  312. return NULL;
  313. if(result < 0)
  314. splay_insert_before(tree, closest, node);
  315. else
  316. splay_insert_after(tree, closest, node);
  317. }
  318. return node;
  319. }
  320. void splay_insert_top(splay_tree_t *tree, splay_node_t *node) {
  321. node->prev = node->next = node->left = node->right = node->parent = NULL;
  322. tree->head = tree->tail = tree->root = node;
  323. }
  324. void splay_insert_before(splay_tree_t *tree, splay_node_t *before, splay_node_t *node) {
  325. if(!before) {
  326. if(tree->tail)
  327. splay_insert_after(tree, tree->tail, node);
  328. else
  329. splay_insert_top(tree, node);
  330. return;
  331. }
  332. node->next = before;
  333. if((node->prev = before->prev))
  334. before->prev->next = node;
  335. else
  336. tree->head = node;
  337. before->prev = node;
  338. splay_bottom_up(tree, before);
  339. node->right = before;
  340. before->parent = node;
  341. if((node->left = before->left))
  342. before->left->parent = node;
  343. before->left = NULL;
  344. node->parent = NULL;
  345. tree->root = node;
  346. }
  347. void splay_insert_after(splay_tree_t *tree, splay_node_t *after, splay_node_t *node) {
  348. if(!after) {
  349. if(tree->head)
  350. splay_insert_before(tree, tree->head, node);
  351. else
  352. splay_insert_top(tree, node);
  353. return;
  354. }
  355. node->prev = after;
  356. if((node->next = after->next))
  357. after->next->prev = node;
  358. else
  359. tree->tail = node;
  360. after->next = node;
  361. splay_bottom_up(tree, after);
  362. node->left = after;
  363. after->parent = node;
  364. if((node->right = after->right))
  365. after->right->parent = node;
  366. after->right = NULL;
  367. node->parent = NULL;
  368. tree->root = node;
  369. }
  370. splay_node_t *splay_unlink(splay_tree_t *tree, void *data) {
  371. splay_node_t *node;
  372. node = splay_search_node(tree, data);
  373. if(node)
  374. splay_unlink_node(tree, node);
  375. return node;
  376. }
  377. void splay_unlink_node(splay_tree_t *tree, splay_node_t *node) {
  378. if(node->prev)
  379. node->prev->next = node->next;
  380. else
  381. tree->head = node->next;
  382. if(node->next)
  383. node->next->prev = node->prev;
  384. else
  385. tree->tail = node->prev;
  386. splay_bottom_up(tree, node);
  387. if(node->prev) {
  388. node->left->parent = NULL;
  389. tree->root = node->left;
  390. if((node->prev->right = node->right))
  391. node->right->parent = node->prev;
  392. } else if(node->next) {
  393. tree->root = node->right;
  394. node->right->parent = NULL;
  395. } else {
  396. tree->root = NULL;
  397. }
  398. }
  399. void splay_delete_node(splay_tree_t *tree, splay_node_t *node) {
  400. splay_unlink_node(tree, node);
  401. splay_free_node(tree, node);
  402. }
  403. void splay_delete(splay_tree_t *tree, void *data) {
  404. splay_node_t *node;
  405. node = splay_search_node(tree, data);
  406. if(node)
  407. splay_delete_node(tree, node);
  408. }
  409. /* Fast tree cleanup */
  410. void splay_delete_tree(splay_tree_t *tree) {
  411. splay_node_t *node, *next;
  412. for(node = tree->root; node; node = next) {
  413. next = node->next;
  414. splay_free_node(tree, node);
  415. }
  416. splay_free_tree(tree);
  417. }
  418. /* Tree walking */
  419. void splay_foreach(const splay_tree_t *tree, splay_action_t action) {
  420. splay_node_t *node, *next;
  421. for(node = tree->head; node; node = next) {
  422. next = node->next;
  423. action(node->data);
  424. }
  425. }
  426. void splay_foreach_node(const splay_tree_t *tree, splay_action_t action) {
  427. splay_node_t *node, *next;
  428. for(node = tree->head; node; node = next) {
  429. next = node->next;
  430. action(node);
  431. }
  432. }