index.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. /*************************************************************************
  2. * Copyright (c) 2011 AT&T Intellectual Property
  3. * All rights reserved. This program and the accompanying materials
  4. * are made available under the terms of the Eclipse Public License v1.0
  5. * which accompanies this distribution, and is available at
  6. * https://www.eclipse.org/legal/epl-v10.html
  7. *
  8. * Contributors: Details at https://graphviz.org
  9. *************************************************************************/
  10. #include <stdlib.h>
  11. #include <label/index.h>
  12. #include <stddef.h>
  13. #include <stdio.h>
  14. #include <assert.h>
  15. #include <stdbool.h>
  16. LeafList_t *RTreeNewLeafList(Leaf_t * lp)
  17. {
  18. LeafList_t *llp;
  19. if ((llp = calloc(1, sizeof(LeafList_t)))) {
  20. llp->leaf = lp;
  21. llp->next = 0;
  22. }
  23. return llp;
  24. }
  25. LeafList_t *RTreeLeafListAdd(LeafList_t * llp, Leaf_t * lp)
  26. {
  27. if (!lp)
  28. return llp;
  29. LeafList_t *nlp = RTreeNewLeafList(lp);
  30. nlp->next = llp;
  31. return nlp;
  32. }
  33. void RTreeLeafListFree(LeafList_t * llp)
  34. {
  35. while (llp->next) {
  36. LeafList_t *tlp = llp->next;
  37. free(llp);
  38. llp = tlp;
  39. }
  40. free(llp);
  41. return;
  42. }
  43. RTree_t *RTreeOpen(void)
  44. {
  45. RTree_t *rtp;
  46. if ((rtp = calloc(1, sizeof(RTree_t))))
  47. rtp->root = RTreeNewIndex();
  48. return rtp;
  49. }
  50. /* Make a new index, empty. Consists of a single node. */
  51. Node_t *RTreeNewIndex(void ) {
  52. Node_t *x = RTreeNewNode();
  53. x->level = 0; /* leaf */
  54. return x;
  55. }
  56. static int RTreeClose2(RTree_t * rtp, Node_t * n)
  57. {
  58. if (n->level > 0) {
  59. for (int i = 0; i < NODECARD; i++) {
  60. if (!n->branch[i].child)
  61. continue;
  62. if (!RTreeClose2(rtp, n->branch[i].child)) {
  63. free(n->branch[i].child);
  64. DisconBranch(n, i);
  65. }
  66. }
  67. } else {
  68. for (int i = 0; i < NODECARD; i++) {
  69. if (!n->branch[i].child)
  70. continue;
  71. DisconBranch(n, i);
  72. }
  73. }
  74. return 0;
  75. }
  76. int RTreeClose(RTree_t * rtp)
  77. {
  78. RTreeClose2(rtp, rtp->root);
  79. free(rtp->root);
  80. free(rtp);
  81. return 0;
  82. }
  83. #ifdef RTDEBUG
  84. /* Print out all the nodes in an index.
  85. ** Prints from root downward.
  86. */
  87. void PrintIndex(Node_t * n)
  88. {
  89. Node_t *nn;
  90. assert(n);
  91. assert(n->level >= 0);
  92. if (n->level > 0) {
  93. for (size_t i = 0; i < NODECARD; i++) {
  94. if ((nn = n->branch[i].child) != NULL)
  95. PrintIndex(nn);
  96. }
  97. }
  98. PrintNode(n);
  99. }
  100. /* Print out all the data rectangles in an index.
  101. */
  102. void PrintData(Node_t * n)
  103. {
  104. Node_t *nn;
  105. assert(n);
  106. assert(n->level >= 0);
  107. if (n->level == 0)
  108. PrintNode(n);
  109. else {
  110. for (size_t i = 0; i < NODECARD; i++) {
  111. if ((nn = n->branch[i].child) != NULL)
  112. PrintData(nn);
  113. }
  114. }
  115. }
  116. #endif
  117. /* RTreeSearch in an index tree or subtree for all data retangles that
  118. ** overlap the argument rectangle.
  119. ** Returns the number of qualifying data rects.
  120. */
  121. LeafList_t *RTreeSearch(RTree_t * rtp, Node_t * n, Rect_t * r)
  122. {
  123. LeafList_t *llp = 0;
  124. assert(n);
  125. assert(n->level >= 0);
  126. assert(r);
  127. if (n->level > 0) { /* this is an internal node in the tree */
  128. for (size_t i = 0; i < NODECARD; i++)
  129. if (n->branch[i].child && Overlap(r, &n->branch[i].rect)) {
  130. LeafList_t *tlp = RTreeSearch(rtp, n->branch[i].child, r);
  131. if (llp) {
  132. LeafList_t *xlp = llp;
  133. while (xlp->next)
  134. xlp = xlp->next;
  135. xlp->next = tlp;
  136. } else
  137. llp = tlp;
  138. }
  139. } else { /* this is a leaf node */
  140. for (size_t i = 0; i < NODECARD; i++) {
  141. if (n->branch[i].child && Overlap(r, &n->branch[i].rect)) {
  142. llp = RTreeLeafListAdd(llp, (Leaf_t *) & n->branch[i]);
  143. # ifdef RTDEBUG
  144. PrintRect(&n->branch[i].rect);
  145. # endif
  146. }
  147. }
  148. }
  149. return llp;
  150. }
  151. /* Insert a data rectangle into an index structure.
  152. ** RTreeInsert provides for splitting the root;
  153. ** returns 1 if root was split, 0 if it was not.
  154. ** The level argument specifies the number of steps up from the leaf
  155. ** level to insert; e.g. a data rectangle goes in at level = 0.
  156. ** RTreeInsert2 does the recursion.
  157. */
  158. static int RTreeInsert2(RTree_t *, Rect_t *, void *, Node_t *, Node_t **, int);
  159. int RTreeInsert(RTree_t * rtp, Rect_t * r, void *data, Node_t ** n, int level)
  160. {
  161. Node_t *newnode=0;
  162. Branch_t b;
  163. int result = 0;
  164. assert(r && n);
  165. assert(level >= 0 && level <= (*n)->level);
  166. for (size_t i = 0; i < NUMDIMS; i++)
  167. assert(r->boundary[i] <= r->boundary[NUMDIMS + i]);
  168. # ifdef RTDEBUG
  169. fprintf(stderr, "RTreeInsert level=%d\n", level);
  170. # endif
  171. if (RTreeInsert2(rtp, r, data, *n, &newnode, level)) { /* root was split */
  172. Node_t *newroot = RTreeNewNode(); /* grow a new root, make tree taller */
  173. newroot->level = (*n)->level + 1;
  174. b.rect = NodeCover(*n);
  175. b.child = *n;
  176. AddBranch(rtp, &b, newroot, NULL);
  177. b.rect = NodeCover(newnode);
  178. b.child = newnode;
  179. AddBranch(rtp, &b, newroot, NULL);
  180. *n = newroot;
  181. result = 1;
  182. }
  183. return result;
  184. }
  185. /* Inserts a new data rectangle into the index structure.
  186. ** Recursively descends tree, propagates splits back up.
  187. ** Returns 0 if node was not split. Old node updated.
  188. ** If node was split, returns 1 and sets the pointer pointed to by
  189. ** new to point to the new node. Old node updated to become one of two.
  190. ** The level argument specifies the number of steps up from the leaf
  191. ** level to insert; e.g. a data rectangle goes in at level = 0.
  192. */
  193. static int
  194. RTreeInsert2(RTree_t * rtp, Rect_t * r, void *data,
  195. Node_t * n, Node_t ** new, int level)
  196. {
  197. Branch_t b;
  198. Node_t *n2=0;
  199. assert(r && n && new);
  200. assert(level >= 0 && level <= n->level);
  201. /* Still above level for insertion, go down tree recursively */
  202. if (n->level > level) {
  203. int i = PickBranch(r, n);
  204. if (!RTreeInsert2(rtp, r, data, n->branch[i].child, &n2, level)) { /* recurse: child was not split */
  205. n->branch[i].rect = CombineRect(r, &(n->branch[i].rect));
  206. return 0;
  207. } else { /* child was split */
  208. n->branch[i].rect = NodeCover(n->branch[i].child);
  209. b.child = n2;
  210. b.rect = NodeCover(n2);
  211. return AddBranch(rtp, &b, n, new);
  212. }
  213. } else if (n->level == level) { /* at level for insertion. */
  214. /*Add rect, split if necessary */
  215. b.rect = *r;
  216. b.child = data;
  217. return AddBranch(rtp, &b, n, new);
  218. } else { /* Not supposed to happen */
  219. assert(false);
  220. return 0;
  221. }
  222. }