index.c 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  1. /****************************************************************************
  2. * MODULE: R-Tree library
  3. *
  4. * AUTHOR(S): Antonin Guttman - original code
  5. * Daniel Green (green@superliminal.com) - major clean-up
  6. * and implementation of bounding spheres
  7. *
  8. * PURPOSE: Multidimensional index
  9. *
  10. * COPYRIGHT: (C) 2001 by the GRASS Development Team
  11. *
  12. * This program is free software under the GNU General Public
  13. * License (>=v2). Read the file COPYING that comes with GRASS
  14. * for details.
  15. *****************************************************************************/
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include "assert.h"
  19. #include "index.h"
  20. #include "card.h"
  21. /* Make a new index, empty. Consists of a single node. */
  22. struct Node *RTreeNewIndex(void)
  23. {
  24. struct Node *x;
  25. x = RTreeNewNode();
  26. x->level = 0; /* leaf */
  27. return x;
  28. }
  29. /*
  30. * Search in an index tree or subtree for all data retangles that
  31. * overlap the argument rectangle.
  32. * Return the number of qualifying data rects.
  33. */
  34. int RTreeSearch(struct Node *N, struct Rect *R, SearchHitCallback shcb,
  35. void *cbarg)
  36. {
  37. register struct Node *n = N;
  38. register struct Rect *r = R; /* NOTE: Suspected bug was R sent in as Node* and cast to Rect* here. */
  39. /* Fix not yet tested. */
  40. register int hitCount = 0;
  41. register int i;
  42. assert(n);
  43. assert(n->level >= 0);
  44. assert(r);
  45. if (n->level > 0) { /* this is an internal node in the tree */
  46. for (i = 0; i < NODECARD; i++)
  47. if (n->branch[i].child && RTreeOverlap(r, &n->branch[i].rect)) {
  48. hitCount += RTreeSearch(n->branch[i].child, r, shcb, cbarg);
  49. }
  50. }
  51. else { /* this is a leaf node */
  52. for (i = 0; i < LEAFCARD; i++)
  53. if (n->branch[i].child && RTreeOverlap(r, &n->branch[i].rect)) {
  54. hitCount++;
  55. if (shcb) /* call the user-provided callback */
  56. if (!shcb((int)n->branch[i].child, cbarg))
  57. return hitCount; /* callback wants to terminate search early */
  58. }
  59. }
  60. return hitCount;
  61. }
  62. /*
  63. * Inserts a new data rectangle into the index structure.
  64. * Recursively descends tree, propagates splits back up.
  65. * Returns 0 if node was not split. Old node updated.
  66. * If node was split, returns 1 and sets the pointer pointed to by
  67. * new_node to point to the new node. Old node updated to become one of two.
  68. * The level argument specifies the number of steps up from the leaf
  69. * level to insert; e.g. a data rectangle goes in at level = 0.
  70. */
  71. static int RTreeInsertRect2(struct Rect *r,
  72. struct Node *child, struct Node *n, struct Node **new_node,
  73. int level)
  74. {
  75. /*
  76. register struct Rect *r = R;
  77. register int tid = Tid;
  78. register struct Node *n = N, **new_node = New_node;
  79. register int level = Level;
  80. */
  81. register int i;
  82. struct Branch b;
  83. struct Node *n2;
  84. assert(r && n && new_node);
  85. assert(level >= 0 && level <= n->level);
  86. /* Still above level for insertion, go down tree recursively */
  87. if (n->level > level) {
  88. i = RTreePickBranch(r, n);
  89. if (!RTreeInsertRect2(r, child, n->branch[i].child, &n2, level)) {
  90. /* child was not split */
  91. n->branch[i].rect = RTreeCombineRect(r, &(n->branch[i].rect));
  92. return 0;
  93. }
  94. else { /* child was split */
  95. n->branch[i].rect = RTreeNodeCover(n->branch[i].child);
  96. b.child = n2;
  97. b.rect = RTreeNodeCover(n2);
  98. return RTreeAddBranch(&b, n, new_node);
  99. }
  100. }
  101. /* Have reached level for insertion. Add rect, split if necessary */
  102. else if (n->level == level) {
  103. b.rect = *r;
  104. b.child = child;
  105. /* child field of leaves contains tid of data record */
  106. return RTreeAddBranch(&b, n, new_node);
  107. }
  108. else {
  109. /* Not supposed to happen */
  110. assert(FALSE);
  111. return 0;
  112. }
  113. }
  114. /*
  115. * Insert a data rectangle into an index structure.
  116. * RTreeInsertRect provides for splitting the root;
  117. * returns 1 if root was split, 0 if it was not.
  118. * The level argument specifies the number of steps up from the leaf
  119. * level to insert; e.g. a data rectangle goes in at level = 0.
  120. * RTreeInsertRect2 does the recursion.
  121. */
  122. int RTreeInsertRect(struct Rect *R, int Tid, struct Node **Root, int Level)
  123. {
  124. assert(Level == 0);
  125. return RTreeInsertRect1(R, (struct Node *) Tid, Root, Level);
  126. }
  127. int RTreeInsertRect1(struct Rect *R, struct Node *Child, struct Node **Root, int Level)
  128. {
  129. register struct Rect *r = R;
  130. register struct Node *child = Child;
  131. register struct Node **root = Root;
  132. register int level = Level;
  133. register int i;
  134. register struct Node *newroot;
  135. struct Node *newnode;
  136. struct Branch b;
  137. int result;
  138. assert(r && root);
  139. assert(level >= 0 && level <= (*root)->level);
  140. for (i = 0; i < NUMDIMS; i++) {
  141. assert(r->boundary[i] <= r->boundary[NUMDIMS + i]);
  142. }
  143. if (RTreeInsertRect2(r, child, *root, &newnode, level)) { /* root split */
  144. newroot = RTreeNewNode(); /* grow a new root, & tree taller */
  145. newroot->level = (*root)->level + 1;
  146. b.rect = RTreeNodeCover(*root);
  147. b.child = *root;
  148. RTreeAddBranch(&b, newroot, NULL);
  149. b.rect = RTreeNodeCover(newnode);
  150. b.child = newnode;
  151. RTreeAddBranch(&b, newroot, NULL);
  152. *root = newroot;
  153. result = 1;
  154. }
  155. else
  156. result = 0;
  157. return result;
  158. }
  159. /*
  160. * Allocate space for a node in the list used in DeletRect to
  161. * store Nodes that are too empty.
  162. */
  163. static struct ListNode *RTreeNewListNode(void)
  164. {
  165. return (struct ListNode *)malloc(sizeof(struct ListNode));
  166. /* return new ListNode; */
  167. }
  168. static void RTreeFreeListNode(struct ListNode *p)
  169. {
  170. free(p);
  171. /* delete(p); */
  172. }
  173. /*
  174. * Add a node to the reinsertion list. All its branches will later
  175. * be reinserted into the index structure.
  176. */
  177. static void RTreeReInsert(struct Node *n, struct ListNode **ee)
  178. {
  179. register struct ListNode *l;
  180. l = RTreeNewListNode();
  181. l->node = n;
  182. l->next = *ee;
  183. *ee = l;
  184. }
  185. /*
  186. * Delete a rectangle from non-root part of an index structure.
  187. * Called by RTreeDeleteRect. Descends tree recursively,
  188. * merges branches on the way back up.
  189. * Returns 1 if record not found, 0 if success.
  190. */
  191. static int
  192. RTreeDeleteRect2(struct Rect *R, struct Node *Child, struct Node *N,
  193. struct ListNode **Ee)
  194. {
  195. register struct Rect *r = R;
  196. register struct Node *child = Child;
  197. register struct Node *n = N;
  198. register struct ListNode **ee = Ee;
  199. register int i;
  200. assert(r && n && ee);
  201. assert(child);
  202. assert(n->level >= 0);
  203. if (n->level > 0) { /* not a leaf node */
  204. for (i = 0; i < NODECARD; i++) {
  205. if (n->branch[i].child && RTreeOverlap(r, &(n->branch[i].rect))) {
  206. if (!RTreeDeleteRect2(r, child, n->branch[i].child, ee)) {
  207. if (n->branch[i].child->count >= MinNodeFill) {
  208. n->branch[i].rect =
  209. RTreeNodeCover(n->branch[i].child);
  210. }
  211. else {
  212. /* not enough entries in child, eliminate child node */
  213. RTreeReInsert(n->branch[i].child, ee);
  214. RTreeDisconnectBranch(n, i);
  215. }
  216. return 0;
  217. }
  218. }
  219. }
  220. return 1;
  221. }
  222. else { /* a leaf node */
  223. for (i = 0; i < LEAFCARD; i++) {
  224. if (n->branch[i].child &&
  225. n->branch[i].child == child) {
  226. RTreeDisconnectBranch(n, i);
  227. return 0;
  228. }
  229. }
  230. return 1;
  231. }
  232. }
  233. /*
  234. * Delete a data rectangle from an index structure.
  235. * Pass in a pointer to a Rect, the tid of the record, ptr to ptr to root node.
  236. * Returns 1 if record not found, 0 if success.
  237. * RTreeDeleteRect provides for eliminating the root.
  238. */
  239. int RTreeDeleteRect(struct Rect *R, int Tid, struct Node **Nn)
  240. {
  241. /* wrapper not really needed, but restricts compile warnings to rtree lib */
  242. /* this way it's easier to fix if necessary? */
  243. return RTreeDeleteRect1(R, (struct Node *) Tid, Nn);
  244. }
  245. int RTreeDeleteRect1(struct Rect *R, struct Node *Child, struct Node **Nn)
  246. {
  247. register struct Rect *r = R;
  248. register struct Node *child = Child;
  249. register struct Node **nn = Nn;
  250. register int i;
  251. struct Node *tmp_nptr = NULL;
  252. struct ListNode *reInsertList = NULL;
  253. register struct ListNode *e;
  254. assert(r && nn);
  255. assert(*nn);
  256. assert(child);
  257. if (!RTreeDeleteRect2(r, child, *nn, &reInsertList)) {
  258. /* found and deleted a data item */
  259. /* reinsert any branches from eliminated nodes */
  260. while (reInsertList) {
  261. tmp_nptr = reInsertList->node;
  262. for (i = 0; i < MAXKIDS(tmp_nptr); i++) {
  263. if (tmp_nptr->branch[i].child) {
  264. RTreeInsertRect1(&(tmp_nptr->branch[i].rect),
  265. tmp_nptr->branch[i].child,
  266. nn, tmp_nptr->level);
  267. }
  268. }
  269. e = reInsertList;
  270. reInsertList = reInsertList->next;
  271. RTreeFreeNode(e->node);
  272. RTreeFreeListNode(e);
  273. }
  274. /* check for redundant root (not leaf, 1 child) and eliminate */
  275. if ((*nn)->count == 1 && (*nn)->level > 0) {
  276. for (i = 0; i < NODECARD; i++) {
  277. tmp_nptr = (*nn)->branch[i].child;
  278. if (tmp_nptr)
  279. break;
  280. }
  281. assert(tmp_nptr);
  282. RTreeFreeNode(*nn);
  283. *nn = tmp_nptr;
  284. }
  285. return 0;
  286. }
  287. else {
  288. return 1;
  289. }
  290. }