bubbling.c 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482
  1. /*
  2. * Copyright 2021
  3. *
  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 3 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. *
  17. * These are the four essential freedoms with GNU GPL software:
  18. * 1: freedom to run the program, for any purpose
  19. * 2: freedom to study how the program works, and change it to make it do what you wish
  20. * 3: freedom to redistribute copies to help your Free Software friends
  21. * 4: freedom to distribute copies of your modified versions to your Free Software friends
  22. * , ,
  23. * / \
  24. * ((__-^^-,-^^-__))
  25. * `-_---' `---_-'
  26. * `--|o` 'o|--'
  27. * \ ` /
  28. * ): :(
  29. * :o_o:
  30. * "-"
  31. *
  32. * SPDX-License-Identifier: GPL-3.0+
  33. * License-Filename: LICENSE
  34. */
  35. #include "config.h"
  36. #include <stdio.h>
  37. #include <stdlib.h>
  38. #include <string.h>
  39. #include "splay-tree.h"
  40. #include "main.h"
  41. #include "sugi.h"
  42. #include "bubbling.h"
  43. #include "pos.h"
  44. #include "hier.h"
  45. #include "uniqnode.h"
  46. #include "dpmem.h"
  47. /* bubbling has a mem leak and splay tree used to track and free all mem. */
  48. static splay_tree bubbling_splaytree = NULL;
  49. static void bubbling_free(void *ptr)
  50. {
  51. if (ptr) {
  52. splay_tree_remove(bubbling_splaytree, (splay_tree_value) ptr);
  53. }
  54. return;
  55. }
  56. static void *bubbling_calloc(int nn, size_t sz)
  57. {
  58. void *ret;
  59. ret = dp_calloc(nn, sz);
  60. if (bubbling_splaytree == NULL) {
  61. bubbling_splaytree = splay_tree_new(splay_tree_compare_pointers, splay_tree_free_key, NULL);
  62. }
  63. splay_tree_insert(bubbling_splaytree, (splay_tree_value) ret, 0);
  64. return (ret);
  65. }
  66. struct node_bubble {
  67. struct gml_node *node;
  68. struct node_bubble *next;
  69. };
  70. struct node_bubble *first_elem = NULL;
  71. /* init top level nodes */
  72. static int input_bubbling(struct gml_graph *g)
  73. {
  74. struct gml_nlist *nl;
  75. struct gml_node *node;
  76. int bubble = 1000000;
  77. int i = 0;
  78. /* for_all_nodes (g, node) */
  79. nl = g->nodelist;
  80. while (nl) {
  81. node = nl->node;
  82. /* select nodes at top of drawing */
  83. if (node->y == 0) {
  84. node->x = bubble;
  85. bubble = bubble + 1000000;
  86. i++;
  87. }
  88. nl = nl->next;
  89. }
  90. return (i);
  91. }
  92. static void insert_node_bubble(struct gml_node *node)
  93. {
  94. struct node_bubble *new_n;
  95. /* #warning "memleak" here */
  96. new_n = (struct node_bubble *)bubbling_calloc(1, sizeof(struct node_bubble));
  97. new_n->node = node;
  98. new_n->next = first_elem;
  99. first_elem = new_n;
  100. return;
  101. }
  102. static struct node_bubble *first_bubbling(struct gml_graph *g, int act_level)
  103. {
  104. struct gml_node *node;
  105. struct gml_node *source;
  106. struct gml_edge *edge;
  107. struct gml_elist *el;
  108. struct gml_nlist *nl;
  109. int bubble = 0;
  110. int count = 0;
  111. first_elem = NULL;
  112. /* for_all_nodes (g, node) */
  113. nl = g->nodelist;
  114. while (nl) {
  115. node = nl->node;
  116. bubble = 0;
  117. count = 0;
  118. if (node->y == act_level) {
  119. /* for_targetlist (node, edge) */
  120. el = node->incoming_e;
  121. while (el) {
  122. edge = el->edge;
  123. source = edge->from_node;
  124. if (source->y == (act_level - 1)) {
  125. bubble = bubble + source->x;
  126. count++;
  127. }
  128. el = el->next;
  129. }
  130. if (count > 0) {
  131. node->x = bubble / count;
  132. } else {
  133. node->x = 1000000;
  134. }
  135. insert_node_bubble(node);
  136. }
  137. nl = nl->next;
  138. }
  139. return (first_elem);
  140. }
  141. static void third_bubbling(struct gml_graph *g, int act_level)
  142. {
  143. struct gml_node *node;
  144. struct gml_node *source;
  145. struct gml_node *target;
  146. struct gml_edge *edge;
  147. struct gml_elist *el;
  148. struct gml_nlist *nl;
  149. int bubble = 0;
  150. int count = 0;
  151. /* for_all_nodes (g, node) */
  152. nl = g->nodelist;
  153. while (nl) {
  154. node = nl->node;
  155. bubble = 0;
  156. count = 0;
  157. if (node->y == act_level) {
  158. /* incoming edges for node */
  159. /* for_targetlist (node, edge) */
  160. el = node->incoming_e;
  161. while (el) {
  162. edge = el->edge;
  163. /* take source node of incoming edge */
  164. source = edge->from_node;
  165. if (source->y == (act_level - 1)) {
  166. bubble = bubble + source->x;
  167. count++;
  168. }
  169. el = el->next;
  170. }
  171. /* outgoing edges for node */
  172. /* for_sourcelist (node, edge) */
  173. el = node->outgoing_e;
  174. while (el) {
  175. edge = el->edge;
  176. /* take target node of outgoing edge */
  177. target = edge->to_node;
  178. if (target->y == (act_level + 1)) {
  179. bubble = bubble + target->x;
  180. count++;
  181. }
  182. el = el->next;
  183. }
  184. if (count > 0) {
  185. /* node with edges */
  186. node->x = bubble / count;
  187. } else {
  188. /* standalone node */
  189. node->x = 1000000;
  190. }
  191. }
  192. nl = nl->next;
  193. }
  194. return;
  195. }
  196. /* how many bubble nodes in list */
  197. static int count_bnodes(struct node_bubble *thelist)
  198. {
  199. struct node_bubble *ptr = NULL;
  200. int nr = 0;
  201. if (thelist == NULL) {
  202. return (0);
  203. }
  204. ptr = thelist;
  205. while (ptr) {
  206. nr++;
  207. ptr = ptr->next;
  208. }
  209. return (nr);
  210. }
  211. static void sort_levellist(struct node_bubble * *blist)
  212. {
  213. struct node_bubble *bnode;
  214. struct node_bubble *help_bnode;
  215. struct gml_node *save_node;
  216. int nr = 0;
  217. int count = 0;
  218. /* how many bubble nodes in list */
  219. count = count_bnodes(*blist);
  220. while (count - 1 >= 1) {
  221. bnode = *blist;
  222. help_bnode = bnode->next;
  223. nr = count - 1;
  224. while (nr >= 1) {
  225. if (bnode->node->x >= help_bnode->node->x) {
  226. save_node = bnode->node;
  227. bnode->node = help_bnode->node;
  228. help_bnode->node = save_node;
  229. }
  230. if (nr > 1) {
  231. bnode = help_bnode;
  232. help_bnode = help_bnode->next;
  233. }
  234. nr--;
  235. }
  236. count--;
  237. }
  238. return;
  239. }
  240. static void new_bubbles(struct node_bubble *bnodes)
  241. {
  242. int new_bub = 1;
  243. struct node_bubble *kill;
  244. while (bnodes != NULL) {
  245. bnodes->node->x = new_bub;
  246. new_bub++;
  247. kill = bnodes;
  248. bnodes = bnodes->next;
  249. bubbling_free(kill);
  250. }
  251. return;
  252. }
  253. static void new_bubble2(struct node_bubble *bnodes)
  254. {
  255. int new_bub = 1000000;
  256. struct node_bubble *ptr;
  257. struct node_bubble *ptrnext;
  258. ptr = bnodes;
  259. while (ptr) {
  260. ptr->node->x = new_bub;
  261. new_bub = new_bub + 1000000;
  262. ptrnext = ptr->next;
  263. /* mem error here free (ptr); */
  264. ptr = ptrnext;
  265. }
  266. return;
  267. }
  268. /* */
  269. void give_horizontal_place(struct gml_graph *g, int choose)
  270. {
  271. int levelnr = 0;
  272. struct gml_node *node;
  273. struct gml_nlist *nl;
  274. /* scan all levels */
  275. while (levelnr <= (g->maxlevel - 1)) {
  276. first_elem = NULL;
  277. /* for_all_nodes (g, node) */
  278. nl = g->nodelist;
  279. while (nl) {
  280. node = nl->node;
  281. if (node->y == levelnr) {
  282. insert_node_bubble(node);
  283. }
  284. nl = nl->next;
  285. }
  286. sort_levellist(&first_elem);
  287. /* update node x pos */
  288. if (choose == 1) {
  289. /* increment by 1 with choose==1 */
  290. new_bubbles(first_elem);
  291. } else {
  292. /* by 100000 with choose==2 */
  293. new_bubble2(first_elem);
  294. }
  295. levelnr++;
  296. }
  297. return;
  298. }
  299. void graph_bubbling(struct gml_graph *g)
  300. {
  301. int act_level = 0;
  302. int loops = 4; /* how many times 3rd bubbling */
  303. int help;
  304. int remember = 0;
  305. int i;
  306. struct node_bubble *blist;
  307. /* init top level nodes */
  308. i = input_bubbling(g);
  309. /* if only 1 toplevel node */
  310. if (i == 1) {
  311. remember = 1;
  312. }
  313. act_level = 1;
  314. /* scan all levels */
  315. while ((g->maxlevel - 1) >= act_level) {
  316. blist = first_bubbling(g, act_level);
  317. if (remember == 1) {
  318. new_bubble2(blist);
  319. }
  320. /* how many bubble nodes in list */
  321. if (count_bnodes(blist) == 1) {
  322. remember = 1;
  323. } else {
  324. remember = 0;
  325. }
  326. act_level++;
  327. }
  328. /*
  329. *
  330. */
  331. if (1) {
  332. act_level = 1;
  333. help = 1;
  334. while (help <= loops) {
  335. while ((g->maxlevel - 1) >= act_level) {
  336. third_bubbling(g, act_level);
  337. act_level++;
  338. }
  339. if ((help / 3) * 3 == help) {
  340. give_horizontal_place(g, 2);
  341. }
  342. help++;
  343. act_level = 1;
  344. }
  345. }
  346. /*
  347. *
  348. */
  349. if (1) {
  350. act_level = 1;
  351. while ((g->maxlevel - 1) >= act_level) {
  352. third_bubbling(g, act_level);
  353. act_level = act_level + 2;
  354. }
  355. act_level = 2;
  356. while ((g->maxlevel - 1) >= act_level) {
  357. third_bubbling(g, act_level);
  358. act_level = act_level + 2;
  359. }
  360. }
  361. /* make sure all extra memory is free'ed */
  362. bubbling_splaytree = splay_tree_delete(bubbling_splaytree);
  363. return;
  364. }
  365. void clear_bubbling(struct gml_graph *g)
  366. {
  367. if (g) {
  368. }
  369. first_elem = NULL;
  370. /* make sure all extra memory is free'ed */
  371. if (bubbling_splaytree) {
  372. bubbling_splaytree = splay_tree_delete(bubbling_splaytree);
  373. }
  374. return;
  375. }
  376. /* end */