rtree.h 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  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. * Markus Metz - file-based and memory-based R*-tree
  8. *
  9. * PURPOSE: Multidimensional index
  10. *
  11. * COPYRIGHT: (C) 2010-2012 by the GRASS Development Team
  12. *
  13. * This program is free software under the GNU General Public
  14. * License (>=v2). Read the file COPYING that comes with GRASS
  15. * for details.
  16. *****************************************************************************/
  17. #ifndef _R_TREE_H_
  18. #define _R_TREE_H_
  19. #include <stdio.h>
  20. #include <string.h>
  21. #include <sys/types.h>
  22. #include <grass/config.h> /* needed for LFS */
  23. typedef double RectReal;
  24. /*-----------------------------------------------------------------------------
  25. | Global definitions.
  26. -----------------------------------------------------------------------------*/
  27. #ifndef TRUE
  28. #define TRUE 1
  29. #endif
  30. #ifndef FALSE
  31. #define FALSE 0
  32. #endif
  33. /* max branching factor of a node */
  34. /* was (PGSIZE-(2 * sizeof(int))) / sizeof(struct Branch)
  35. * this is LFS dependent, not good
  36. * on 32 bit without LFS this is 9.69
  37. * on 32 bit with LFS and on 64 bit this is 9 */
  38. #define MAXCARD 9
  39. #define NODECARD MAXCARD
  40. #define LEAFCARD MAXCARD
  41. /* maximum no of levels = tree depth */
  42. #define MAXLEVEL 20 /* 8^MAXLEVEL items are guaranteed to fit into the tree */
  43. struct RTree_Rect
  44. {
  45. RectReal *boundary; /* xmin,ymin,...,xmax,ymax,... */
  46. };
  47. struct RTree_Node; /* node for spatial index */
  48. union RTree_Child
  49. {
  50. int id; /* child id */
  51. struct RTree_Node *ptr; /* pointer to child node */
  52. off_t pos; /* position of child node in file */
  53. };
  54. struct RTree_Branch /* branch for spatial index */
  55. {
  56. struct RTree_Rect rect;
  57. union RTree_Child child;
  58. };
  59. struct RTree_Node /* node for spatial index */
  60. {
  61. int count; /* number of branches */
  62. int level; /* 0 is leaf, others positive */
  63. struct RTree_Branch branch[MAXCARD];
  64. };
  65. /*
  66. * If passed to a tree search, this callback function will be called
  67. * with the ID of each data rect that overlaps the search rect
  68. * plus whatever user specific pointer was passed to the search.
  69. * It can terminate the search early by returning 0 in which case
  70. * the search will return the number of hits found up to that point.
  71. */
  72. typedef int SearchHitCallback(int id, struct RTree_Rect rect, void *arg);
  73. struct RTree;
  74. typedef int rt_search_fn(struct RTree *, struct RTree_Rect *,
  75. SearchHitCallback *, void *);
  76. typedef int rt_insert_fn(struct RTree_Rect *, union RTree_Child, int, struct RTree *);
  77. typedef int rt_delete_fn(struct RTree_Rect *, union RTree_Child, struct RTree *);
  78. typedef int rt_valid_child_fn(union RTree_Child *);
  79. /* temp vars for each tree */
  80. /* stacks used for non-recursive insertion/deletion */
  81. /* stack for file-based index */
  82. struct fstack
  83. {
  84. struct RTree_Node sn; /* stack node */
  85. int branch_id; /* branch number to follow down */
  86. off_t pos; /* file position of stack node */
  87. };
  88. /* stack for memory-based index */
  89. struct mstack
  90. {
  91. struct RTree_Node *sn; /* stack node pointer */
  92. int branch_id; /* branch number to follow down */
  93. };
  94. /* temp vars for node splitting */
  95. struct RTree_PartitionVars {
  96. int partition[MAXCARD + 1];
  97. int total, minfill;
  98. int taken[MAXCARD + 1];
  99. int count[2];
  100. struct RTree_Rect cover[2];
  101. RectReal area[2];
  102. };
  103. struct RTree
  104. {
  105. /* RTree setup info */
  106. int fd; /* file descriptor */
  107. unsigned char ndims; /* number of dimensions */
  108. unsigned char nsides; /* number of sides = 2 * ndims */
  109. unsigned char ndims_alloc; /* number of dimensions allocated */
  110. unsigned char nsides_alloc; /* number of sides allocated = 2 * ndims allocated */
  111. int nodesize; /* node size in bytes */
  112. int branchsize; /* branch size in bytes */
  113. /* RTree info, useful to calculate space requirements */
  114. int n_nodes; /* number of nodes */
  115. int n_leafs; /* number of data items (level 0 leafs) */
  116. int rootlevel; /* root level = tree depth */
  117. /* settings for RTree building */
  118. int nodecard; /* max number of childs in node */
  119. int leafcard; /* max number of childs in leaf */
  120. int min_node_fill; /* balance criteria for node removal */
  121. int min_leaf_fill; /* balance criteria for leaf removal */
  122. int minfill_node_split; /* balance criteria for splitting */
  123. int minfill_leaf_split; /* balance criteria for splitting */
  124. /* free node positions for recycling */
  125. struct _recycle {
  126. int avail; /* number of available positions */
  127. int alloc; /* number of allcoated positions in *pos */
  128. off_t *pos; /* array of available positions */
  129. } free_nodes;
  130. /* node buffer for file-based index, three nodes per level
  131. * more than three nodes per level would require too complex cache management */
  132. struct NodeBuffer
  133. {
  134. struct RTree_Node n; /* buffered node */
  135. off_t pos; /* file position of buffered node */
  136. char dirty; /* node in buffer was modified */
  137. } nb[MAXLEVEL][3];
  138. /* usage order of buffered nodes per level
  139. * used[level][0] = most recently used
  140. * used[level][2] = least recently used */
  141. char used[MAXLEVEL][3];
  142. /* insert, delete, search */
  143. rt_insert_fn *insert_rect;
  144. rt_delete_fn *delete_rect;
  145. rt_search_fn *search_rect;
  146. rt_valid_child_fn *valid_child;
  147. struct RTree_Node *root; /* pointer to root node */
  148. /* internal variables, specific for each tree,
  149. * allocated with tree initialization */
  150. /* stacks for tree traversal */
  151. struct mstack ms[MAXLEVEL];
  152. struct fstack fs[MAXLEVEL];
  153. /* variables for splitting / forced reinsertion */
  154. struct RTree_PartitionVars p;
  155. struct RTree_Branch BranchBuf[MAXCARD + 1];
  156. struct RTree_Branch tmpb1, tmpb2, c;
  157. int BranchCount;
  158. struct RTree_Rect rect_0, rect_1, upperrect, orect;
  159. RectReal *center_n;
  160. off_t rootpos; /* root node position in file */
  161. };
  162. /* RTree main functions */
  163. int RTreeSearch(struct RTree *, struct RTree_Rect *, SearchHitCallback *,
  164. void *);
  165. int RTreeInsertRect(struct RTree_Rect *, int, struct RTree *);
  166. int RTreeDeleteRect(struct RTree_Rect *, int, struct RTree *);
  167. struct RTree *RTreeNewIndex(int, off_t, int);
  168. void RTreeFreeIndex(struct RTree *);
  169. int RTreeOverlap(struct RTree_Rect *, struct RTree_Rect *, struct RTree *);
  170. /* RTree node management */
  171. struct RTree_Node *RTreeNewNode(struct RTree *, int);
  172. void RTreeInitNode(struct RTree *, struct RTree_Node *, int);
  173. void RTreeCopyNode(struct RTree_Node *, struct RTree_Node *, struct RTree *);
  174. void RTreeFreeNode(struct RTree_Node *);
  175. void RTreeDestroyNode(struct RTree_Node *, int);
  176. void RTreeNewRect(struct RTree_Rect *, struct RTree *);
  177. /* RTree IO */
  178. size_t RTreeReadNode(struct RTree_Node *, off_t, struct RTree *);
  179. size_t RTreeWriteNode(struct RTree_Node *, struct RTree *);
  180. off_t RTreeGetNodePos(struct RTree *);
  181. void RTreeFlushBuffer(struct RTree *);
  182. #endif