4 * \brief Implements r-tree structures.
6 * These should be much faster for the auto-router because the recursive
7 * search is much more efficient and that's where the auto-router spends
10 * \author this file, rtree.c, was written and is Copyright (c) 2004,
15 * <h1><b>Copyright.</b></h1>\n
17 * PCB, interactive printed circuit board design
19 * Copyright (C) 1994,1995,1996 Thomas Nau
21 * Copyright (C) 1998,1999,2000,2001,2002,2003,2004 harry eaton
23 * This program is free software; you can redistribute it and/or modify
24 * it under the terms of the GNU General Public License as published by
25 * the Free Software Foundation; either version 2 of the License, or
26 * (at your option) any later version.
28 * This program is distributed in the hope that it will be useful,
29 * but WITHOUT ANY WARRANTY; without even the implied warranty of
30 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31 * GNU General Public License for more details.
33 * You should have received a copy of the GNU General Public License
34 * along with this program; if not, write to the Free Software
35 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
37 * Contact addresses for paper mail and Email:
39 * harry eaton, 6697 Buttonhole Ct, Columbia, MD 21044 USA
41 * haceaton@aplcomm.jhuapl.edu
58 #ifdef HAVE_LIBDMALLOC
63 /* All rectangles are closed on the bottom left and open on the
64 * top right. i.e. they contain one corner point, but not the other.
65 * This requires that the corner points not be equal!
68 /* the number of entries in each rtree node
69 * 4 - 7 seem to be pretty good settings
73 /* it seems that sorting the leaf order slows us down
74 * but sometimes gives better routes
79 #define DELETE_BY_POINTER
83 const BoxType
*bptr
; /* pointer to the box */
84 BoxType bounds
; /* copy of the box for locality of reference */
89 BoxType box
; /* bounds rectangle of this node */
90 struct rtree_node
*parent
; /* parent of this node, NULL = root */
93 unsigned is_leaf
:1; /* this is a leaf node */
94 unsigned manage
:31; /* true==should free 'rect.bptr' if node is destroyed */
99 struct rtree_node
*kids
[M_SIZE
+ 1]; /* when not leaf */
100 Rentry rects
[M_SIZE
+ 1]; /* when leaf */
107 __r_node_is_good (struct rtree_node
*node
)
115 for (i
= 0; i
< M_SIZE
; i
++)
117 if (node
->flags
.is_leaf
)
119 if (!node
->u
.rects
[i
].bptr
)
124 /* check that once one entry is empty, all the rest are too */
125 if (node
->u
.rects
[i
].bptr
&& last
)
127 /* check that the box makes sense */
128 if (node
->box
.X1
> node
->box
.X2
)
130 if (node
->box
.Y1
> node
->box
.Y2
)
132 /* check that bounds is the same as the pointer */
133 if (node
->u
.rects
[i
].bounds
.X1
!= node
->u
.rects
[i
].bptr
->X1
)
135 if (node
->u
.rects
[i
].bounds
.Y1
!= node
->u
.rects
[i
].bptr
->Y1
)
137 if (node
->u
.rects
[i
].bounds
.X2
!= node
->u
.rects
[i
].bptr
->X2
)
139 if (node
->u
.rects
[i
].bounds
.Y2
!= node
->u
.rects
[i
].bptr
->Y2
)
141 /* check that entries are within node bounds */
142 if (node
->u
.rects
[i
].bounds
.X1
< node
->box
.X1
)
144 if (node
->u
.rects
[i
].bounds
.X2
> node
->box
.X2
)
146 if (node
->u
.rects
[i
].bounds
.Y1
< node
->box
.Y1
)
148 if (node
->u
.rects
[i
].bounds
.Y2
> node
->box
.Y2
)
153 if (!node
->u
.kids
[i
])
158 /* make sure all children are the same type */
160 kind
= node
->u
.kids
[i
]->flags
.is_leaf
;
161 else if (kind
!= node
->u
.kids
[i
]->flags
.is_leaf
)
163 /* check that once one entry is empty, all the rest are too */
164 if (node
->u
.kids
[i
] && last
)
166 /* check that entries are within node bounds */
167 if (node
->u
.kids
[i
]->box
.X1
< node
->box
.X1
)
169 if (node
->u
.kids
[i
]->box
.X2
> node
->box
.X2
)
171 if (node
->u
.kids
[i
]->box
.Y1
< node
->box
.Y1
)
173 if (node
->u
.kids
[i
]->box
.Y2
> node
->box
.Y2
)
178 /* check that we're completely in the parent's bounds */
181 if (node
->parent
->box
.X1
> node
->box
.X1
)
183 if (node
->parent
->box
.X2
< node
->box
.X2
)
185 if (node
->parent
->box
.Y1
> node
->box
.Y1
)
187 if (node
->parent
->box
.Y2
< node
->box
.Y2
)
190 /* make sure overflow is empty */
191 if (!node
->flags
.is_leaf
&& node
->u
.kids
[i
])
193 if (node
->flags
.is_leaf
&& node
->u
.rects
[i
].bptr
)
199 * \brief Check the whole tree from this node down for consistency.
202 __r_tree_is_good (struct rtree_node
*node
)
208 if (!__r_node_is_good (node
))
210 if (node
->flags
.is_leaf
)
212 for (i
= 0; i
< M_SIZE
; i
++)
214 if (!__r_tree_is_good (node
->u
.kids
[i
]))
224 * \brief Print out the tree.
227 __r_dump_tree (struct rtree_node
*node
, int depth
)
239 (node
->box
.X2
- node
->box
.X1
) * (double) (node
->box
.Y2
- node
->box
.Y1
);
241 for (i
= 0; i
< depth
; i
++)
243 if (!node
->flags
.is_leaf
)
246 "p=0x%p node X(%" PRIi64
", %" PRIi64
") Y(%" PRIi64
", %" PRIi64
249 (int64_t) (node
->box
.X1
),
250 (int64_t) (node
->box
.X2
),
251 (int64_t) (node
->box
.Y1
),
252 (int64_t) (node
->box
.Y2
) );
257 "p=0x%p leaf manage(%02x) X(%" PRIi64
", %" PRIi64
") Y(%" PRIi64
261 (int64_t) (node
->box
.X1
),
262 (int64_t) (node
->box
.X2
),
263 (int64_t) (node
->box
.Y1
),
264 (int64_t) (node
->box
.Y2
) );
265 for (j
= 0; j
< M_SIZE
; j
++)
267 if (!node
->u
.rects
[j
].bptr
)
270 (node
->u
.rects
[j
].bounds
.X2
-
271 node
->u
.rects
[j
].bounds
.X1
) *
272 (double) (node
->u
.rects
[j
].bounds
.Y2
-
273 node
->u
.rects
[j
].bounds
.Y1
);
275 for (i
= 0; i
< depth
+ 1; i
++)
278 "entry 0x%p X(%" PRIi64
", %" PRIi64
") Y(%" PRIi64
", "
280 (void *) (node
->u
.rects
[j
].bptr
),
281 (int64_t) (node
->u
.rects
[j
].bounds
.X1
),
282 (int64_t) (node
->u
.rects
[j
].bounds
.X2
),
283 (int64_t) (node
->u
.rects
[j
].bounds
.Y1
),
284 (int64_t) (node
->u
.rects
[j
].bounds
.Y2
) );
288 for (i
= 0; i
< M_SIZE
; i
++)
290 __r_dump_tree (node
->u
.kids
[i
], depth
+ 1);
292 printf ("average box area is %g\n", area
/ count
);
298 * \brief Sort the children or entries of a node according to the
301 * Compare two box coordinates so that the __r_search will fail at the
302 * earliest comparison possible.
304 * It needs to see the biggest X1 first, then the smallest X2, the
305 * biggest Y1 and smallest Y2.
308 cmp_box (const BoxType
* a
, const BoxType
* b
)
328 sort_node (struct rtree_node
*node
)
330 if (node
->flags
.is_leaf
)
332 register Rentry
*r
, *i
, temp
;
334 for (r
= &node
->u
.rects
[1]; r
->bptr
; r
++)
338 while (i
>= &node
->u
.rects
[0])
340 if (cmp_box (&i
->bounds
, &r
->bounds
))
351 register struct rtree_node
**r
, **i
, *temp
;
353 for (r
= &node
->u
.kids
[1]; *r
; r
++)
357 while (i
>= &node
->u
.kids
[0])
359 if (cmp_box (&(*i
)->box
, &(*r
)->box
))
374 * \brief Set the node bounds large enough to encompass all of the
375 * children's rectangles.
378 adjust_bounds (struct rtree_node
*node
)
383 assert (node
->u
.kids
[0]);
384 if (node
->flags
.is_leaf
)
386 node
->box
= node
->u
.rects
[0].bounds
;
387 for (i
= 1; i
< M_SIZE
+ 1; i
++)
389 if (!node
->u
.rects
[i
].bptr
)
391 MAKEMIN (node
->box
.X1
, node
->u
.rects
[i
].bounds
.X1
);
392 MAKEMAX (node
->box
.X2
, node
->u
.rects
[i
].bounds
.X2
);
393 MAKEMIN (node
->box
.Y1
, node
->u
.rects
[i
].bounds
.Y1
);
394 MAKEMAX (node
->box
.Y2
, node
->u
.rects
[i
].bounds
.Y2
);
399 node
->box
= node
->u
.kids
[0]->box
;
400 for (i
= 1; i
< M_SIZE
+ 1; i
++)
402 if (!node
->u
.kids
[i
])
404 MAKEMIN (node
->box
.X1
, node
->u
.kids
[i
]->box
.X1
);
405 MAKEMAX (node
->box
.X2
, node
->u
.kids
[i
]->box
.X2
);
406 MAKEMIN (node
->box
.Y1
, node
->u
.kids
[i
]->box
.Y1
);
407 MAKEMAX (node
->box
.Y2
, node
->u
.kids
[i
]->box
.Y2
);
413 * \brief Create an r-tree from an unsorted list of boxes.
415 * Create an rtree from the list of boxes. If 'manage' is true, then
416 * the tree will take ownership of 'boxlist' and free it when the tree
419 * The r-tree will keep pointers into it, so don't free the box list
420 * until you've called r_destroy_tree.
422 * If you set 'manage' to true, r_destroy_tree will free your boxlist.
425 r_create_tree (const BoxType
* boxlist
[], int N
, int manage
)
428 struct rtree_node
*node
;
432 rtree
= (rtree_t
*)calloc (1, sizeof (*rtree
));
433 /* start with a single empty leaf node */
434 node
= (struct rtree_node
*)calloc (1, sizeof (*node
));
435 node
->flags
.is_leaf
= 1;
438 /* simple, just insert all of the boxes! */
439 for (i
= 0; i
< N
; i
++)
442 r_insert_entry (rtree
, boxlist
[i
], manage
);
445 assert (__r_tree_is_good (rtree
->root
));
451 * \brief Destroy an rtree.
454 __r_destroy_tree (struct rtree_node
*node
)
458 if (node
->flags
.is_leaf
)
459 for (i
= 0; i
< M_SIZE
; i
++)
461 if (!node
->u
.rects
[i
].bptr
)
463 if (node
->flags
.manage
& flag
)
464 free ((void *) node
->u
.rects
[i
].bptr
);
468 for (i
= 0; i
< M_SIZE
; i
++)
470 if (!node
->u
.kids
[i
])
472 __r_destroy_tree (node
->u
.kids
[i
]);
478 * \brief Free the memory associated with an rtree.
481 r_destroy_tree (rtree_t
** rtree
)
484 __r_destroy_tree ((*rtree
)->root
);
491 int (*check_it
) (const BoxType
* region
, void *cl
);
492 int (*found_it
) (const BoxType
* box
, void *cl
);
499 * Most of the auto-routing time is spent in this routine so some
500 * careful thought has been given to maximizing the speed.
504 __r_search (struct rtree_node
*node
, const BoxType
* query
, r_arg
* arg
)
507 /* assert that starting_region is well formed */
508 assert (query
->X1
< query
->X2
&& query
->Y1
< query
->Y2
);
509 assert (node
->box
.X1
< query
->X2
&& node
->box
.X2
> query
->X1
&&
510 node
->box
.Y1
< query
->Y2
&& node
->box
.Y2
> query
->Y1
);
512 /* assert that node is well formed */
513 assert (__r_node_is_good (node
));
515 /* the check for bounds is done before entry. This saves the overhead
516 * of building/destroying the stack frame for each bounds that fails
517 * to intersect, which is the most common condition.
519 if (node
->flags
.is_leaf
)
522 if (arg
->found_it
) /* test this once outside of loop */
524 register int seen
= 0;
525 for (i
= 0; node
->u
.rects
[i
].bptr
; i
++)
527 if ((node
->u
.rects
[i
].bounds
.X1
< query
->X2
) &&
528 (node
->u
.rects
[i
].bounds
.X2
> query
->X1
) &&
529 (node
->u
.rects
[i
].bounds
.Y1
< query
->Y2
) &&
530 (node
->u
.rects
[i
].bounds
.Y2
> query
->Y1
) &&
531 arg
->found_it (node
->u
.rects
[i
].bptr
, arg
->closure
))
538 register int seen
= 0;
539 for (i
= 0; node
->u
.rects
[i
].bptr
; i
++)
541 if ((node
->u
.rects
[i
].bounds
.X1
< query
->X2
) &&
542 (node
->u
.rects
[i
].bounds
.X2
> query
->X1
) &&
543 (node
->u
.rects
[i
].bounds
.Y1
< query
->Y2
) &&
544 (node
->u
.rects
[i
].bounds
.Y2
> query
->Y1
))
551 /* not a leaf, recurse on lower nodes */
555 struct rtree_node
**n
;
556 for (n
= &node
->u
.kids
[0]; *n
; n
++)
558 if ((*n
)->box
.X1
>= query
->X2
||
559 (*n
)->box
.X2
<= query
->X1
||
560 (*n
)->box
.Y1
>= query
->Y2
|| (*n
)->box
.Y2
<= query
->Y1
||
561 !arg
->check_it (&(*n
)->box
, arg
->closure
))
563 seen
+= __r_search (*n
, query
, arg
);
570 struct rtree_node
**n
;
571 for (n
= &node
->u
.kids
[0]; *n
; n
++)
573 if ((*n
)->box
.X1
>= query
->X2
||
574 (*n
)->box
.X2
<= query
->X1
||
575 (*n
)->box
.Y1
>= query
->Y2
|| (*n
)->box
.Y2
<= query
->Y1
)
577 seen
+= __r_search (*n
, query
, arg
);
584 * \brief Parameterized search in the rtree.
586 * Calls found_rectangle for each intersection seen and calls
587 * \c check_region with the current sub-region to see whether deeper
588 * searching is desired.
590 * Generic search routine.
592 * \c region_in_search should return true if "what you're looking for"
593 * is within the specified region; regions, like rectangles, are closed
594 * on top and left and open on bottom and right.
596 * rectangle_in_region should return true if the given rectangle is
597 * "what you're looking for".
599 * The search will find all rectangles matching the criteria given
600 * by region_in_search and rectangle_in_region and return a count of
601 * how many things rectangle_in_region returned true for.
603 * Closure is used to abort the search if desired from within
604 * rectangel_in_region.
606 * Look at the implementation of r_region_is_empty for how to abort the
607 * search if that is the desired behavior.
609 * \return the number of rectangles found.
612 r_search (rtree_t
* rtree
, const BoxType
* query
,
613 int (*check_region
) (const BoxType
* region
, void *cl
),
614 int (*found_rectangle
) (const BoxType
* box
, void *cl
), void *cl
)
618 if (!rtree
|| rtree
->size
< 1)
623 assert (__r_tree_is_good (rtree
->root
));
626 if (query
->X2
<= query
->X1
|| query
->Y2
<= query
->Y1
)
629 /* check this box. If it's not touched we're done here */
630 if (rtree
->root
->box
.X1
>= query
->X2
||
631 rtree
->root
->box
.X2
<= query
->X1
||
632 rtree
->root
->box
.Y1
>= query
->Y2
633 || rtree
->root
->box
.Y2
<= query
->Y1
)
635 arg
.check_it
= check_region
;
636 arg
.found_it
= found_rectangle
;
638 return __r_search (rtree
->root
, query
, &arg
);
642 arg
.check_it
= check_region
;
643 arg
.found_it
= found_rectangle
;
645 return __r_search (rtree
->root
, &rtree
->root
->box
, &arg
);
650 * \brief r_region_is_empty.
653 __r_region_is_empty_rect_in_reg (const BoxType
* box
, void *cl
)
655 jmp_buf *envp
= (jmp_buf *) cl
;
656 longjmp (*envp
, 1); /* found one! */
660 * \brief Special-purpose searches build upon r_search.
662 * \return 0 if there are any rectangles in the given region.
665 r_region_is_empty (rtree_t
* rtree
, const BoxType
* region
)
677 r_search (rtree
, region
, NULL
, __r_region_is_empty_rect_in_reg
, &env
);
679 assert (r
== 0); /* otherwise longjmp would have been called */
681 return 1; /* no rectangles found */
690 * \brief Split the node into two nodes putting clusters in each use the
691 * k-means clustering algorithm.
694 find_clusters (struct rtree_node
*node
)
696 float total_a
, total_b
;
697 float a_X
, a_Y
, b_X
, b_Y
;
698 bool belong
[M_SIZE
+ 1];
699 struct centroid center
[M_SIZE
+ 1];
700 int clust_a
, clust_b
, tries
;
701 int a_manage
= 0, b_manage
= 0;
702 int i
, old_ax
, old_ay
, old_bx
, old_by
;
703 struct rtree_node
*new_node
;
706 for (i
= 0; i
< M_SIZE
+ 1; i
++)
708 if (node
->flags
.is_leaf
)
709 b
= &(node
->u
.rects
[i
].bounds
);
711 b
= &(node
->u
.kids
[i
]->box
);
712 center
[i
].x
= 0.5 * (b
->X1
+ b
->X2
);
713 center
[i
].y
= 0.5 * (b
->Y1
+ b
->Y2
);
714 /* adding 1 prevents zero area */
715 center
[i
].area
= 1. + (float) (b
->X2
- b
->X1
) * (float) (b
->Y2
- b
->Y1
);
717 /* starting 'A' cluster center */
720 /* starting 'B' cluster center */
721 b_X
= center
[M_SIZE
].x
;
722 b_Y
= center
[M_SIZE
].y
;
723 /* don't allow the same cluster centers */
724 if (b_X
== a_X
&& b_Y
== a_Y
)
729 for (tries
= 0; tries
< M_SIZE
; tries
++)
735 clust_a
= clust_b
= 0;
736 for (i
= 0; i
< M_SIZE
+ 1; i
++)
740 dist1
= SQUARE (a_X
- center
[i
].x
) + SQUARE (a_Y
- center
[i
].y
);
741 dist2
= SQUARE (b_X
- center
[i
].x
) + SQUARE (b_Y
- center
[i
].y
);
742 if (dist1
* (clust_a
+ M_SIZE
/ 2) < dist2
* (clust_b
+ M_SIZE
/ 2))
753 /* kludge to fix degenerate cases */
754 if (clust_a
== M_SIZE
+ 1)
755 belong
[M_SIZE
/ 2] = false;
756 else if (clust_b
== M_SIZE
+ 1)
757 belong
[M_SIZE
/ 2] = true;
758 /* compute new center of gravity of clusters */
759 total_a
= total_b
= 0;
760 a_X
= a_Y
= b_X
= b_Y
= 0;
761 for (i
= 0; i
< M_SIZE
+ 1; i
++)
765 a_X
+= center
[i
].x
* center
[i
].area
;
766 a_Y
+= center
[i
].y
* center
[i
].area
;
767 total_a
+= center
[i
].area
;
771 b_X
+= center
[i
].x
* center
[i
].area
;
772 b_Y
+= center
[i
].y
* center
[i
].area
;
773 total_b
+= center
[i
].area
;
780 if (old_ax
== (int) a_X
&& old_ay
== (int) a_Y
&&
781 old_bx
== (int) b_X
&& old_by
== (int) b_Y
)
784 /* Now 'belong' has the partition map */
785 new_node
= (struct rtree_node
*)calloc (1, sizeof (*new_node
));
786 new_node
->parent
= node
->parent
;
787 new_node
->flags
.is_leaf
= node
->flags
.is_leaf
;
788 clust_a
= clust_b
= 0;
789 if (node
->flags
.is_leaf
)
791 int flag
, a_flag
, b_flag
;
792 flag
= a_flag
= b_flag
= 1;
793 for (i
= 0; i
< M_SIZE
+ 1; i
++)
797 node
->u
.rects
[clust_a
++] = node
->u
.rects
[i
];
798 if (node
->flags
.manage
& flag
)
804 new_node
->u
.rects
[clust_b
++] = node
->u
.rects
[i
];
805 if (node
->flags
.manage
& flag
)
814 for (i
= 0; i
< M_SIZE
+ 1; i
++)
817 node
->u
.kids
[clust_a
++] = node
->u
.kids
[i
];
820 node
->u
.kids
[i
]->parent
= new_node
;
821 new_node
->u
.kids
[clust_b
++] = node
->u
.kids
[i
];
825 node
->flags
.manage
= a_manage
;
826 new_node
->flags
.manage
= b_manage
;
827 assert (clust_a
!= 0);
828 assert (clust_b
!= 0);
829 if (node
->flags
.is_leaf
)
830 for (; clust_a
< M_SIZE
+ 1; clust_a
++)
831 node
->u
.rects
[clust_a
].bptr
= NULL
;
833 for (; clust_a
< M_SIZE
+ 1; clust_a
++)
834 node
->u
.kids
[clust_a
] = NULL
;
835 adjust_bounds (node
);
837 adjust_bounds (new_node
);
838 sort_node (new_node
);
843 * \brief Split a node according to clusters.
846 split_node (struct rtree_node
*node
)
849 struct rtree_node
*new_node
;
852 assert (node
->flags
.is_leaf
? (void *) node
->u
.rects
[M_SIZE
].
853 bptr
: (void *) node
->u
.kids
[M_SIZE
]);
854 new_node
= find_clusters (node
);
855 if (node
->parent
== NULL
) /* split root node */
857 struct rtree_node
*second
;
859 second
= (struct rtree_node
*)calloc (1, sizeof (*second
));
861 if (!second
->flags
.is_leaf
)
862 for (i
= 0; i
< M_SIZE
; i
++)
863 if (second
->u
.kids
[i
])
864 second
->u
.kids
[i
]->parent
= second
;
865 node
->flags
.is_leaf
= 0;
866 node
->flags
.manage
= 0;
867 second
->parent
= new_node
->parent
= node
;
868 node
->u
.kids
[0] = new_node
;
869 node
->u
.kids
[1] = second
;
870 for (i
= 2; i
< M_SIZE
+ 1; i
++)
871 node
->u
.kids
[i
] = NULL
;
872 adjust_bounds (node
);
875 assert (__r_tree_is_good (node
));
879 for (i
= 0; i
< M_SIZE
; i
++)
880 if (!node
->parent
->u
.kids
[i
])
882 node
->parent
->u
.kids
[i
] = new_node
;
884 assert (__r_node_is_good (node
));
885 assert (__r_node_is_good (new_node
));
890 assert (__r_node_is_good (node
->parent
));
892 sort_node (node
->parent
);
895 split_node (node
->parent
);
899 contained (struct rtree_node
*node
, const BoxType
* query
)
901 if (node
->box
.X1
> query
->X1
|| node
->box
.X2
< query
->X2
||
902 node
->box
.Y1
> query
->Y1
|| node
->box
.Y2
< query
->Y2
)
909 * \brief Compute the area penalty for inserting here and return.
911 * The penalty is the increase in area necessary to include the query.
914 penalty (struct rtree_node
*node
, const BoxType
* query
)
918 score
= (MAX (node
->box
.X2
, query
->X2
) - MIN (node
->box
.X1
, query
->X1
));
919 score
*= (MAX (node
->box
.Y2
, query
->Y2
) - MIN (node
->box
.Y1
, query
->Y1
));
921 (double)(node
->box
.X2
- node
->box
.X1
) *
922 (double)(node
->box
.Y2
- node
->box
.Y1
);
927 __r_insert_node (struct rtree_node
*node
, const BoxType
* query
,
928 int manage
, bool force
)
932 assert (__r_node_is_good (node
));
934 /* Ok, at this point we must already enclose the query or we're forcing
935 * this node to expand to enclose it, so if we're a leaf, simply store
939 if (node
->flags
.is_leaf
)
943 if (UNLIKELY (manage
))
945 register int flag
= 1;
947 for (i
= 0; i
< M_SIZE
; i
++)
949 if (!node
->u
.rects
[i
].bptr
)
953 node
->flags
.manage
|= flag
;
957 for (i
= 0; i
< M_SIZE
; i
++)
958 if (!node
->u
.rects
[i
].bptr
)
961 /* the node always has an extra space available */
962 node
->u
.rects
[i
].bptr
= query
;
963 node
->u
.rects
[i
].bounds
= *query
;
964 /* first entry in node determines initial bounding box */
969 MAKEMIN (node
->box
.X1
, query
->X1
);
970 MAKEMAX (node
->box
.X2
, query
->X2
);
971 MAKEMIN (node
->box
.Y1
, query
->Y1
);
972 MAKEMAX (node
->box
.Y2
, query
->Y2
);
979 /* we must split the node */
986 struct rtree_node
*best_node
;
987 double score
, best_score
;
991 MAKEMIN (node
->box
.X1
, query
->X1
);
992 MAKEMAX (node
->box
.X2
, query
->X2
);
993 MAKEMIN (node
->box
.Y1
, query
->Y1
);
994 MAKEMAX (node
->box
.Y2
, query
->Y2
);
997 /* this node encloses it, but it's not a leaf, so descend the tree */
999 /* First check if any children actually encloses it */
1000 assert (node
->u
.kids
[0]);
1001 for (i
= 0; i
< M_SIZE
; i
++)
1003 if (!node
->u
.kids
[i
])
1005 if (contained (node
->u
.kids
[i
], query
))
1007 __r_insert_node (node
->u
.kids
[i
], query
, manage
, false);
1013 /* see if there is room for a new leaf node */
1014 if (node
->u
.kids
[0]->flags
.is_leaf
&& i
< M_SIZE
)
1016 struct rtree_node
*new_node
;
1017 new_node
= (struct rtree_node
*)calloc (1, sizeof (*new_node
));
1018 new_node
->parent
= node
;
1019 new_node
->flags
.is_leaf
= true;
1020 node
->u
.kids
[i
] = new_node
;
1021 new_node
->u
.rects
[0].bptr
= query
;
1022 new_node
->u
.rects
[0].bounds
= *query
;
1023 new_node
->box
= *query
;
1024 if (UNLIKELY (manage
))
1025 new_node
->flags
.manage
= 1;
1030 /* Ok, so we're still here - look for the best child to push it into */
1031 best_score
= penalty (node
->u
.kids
[0], query
);
1032 best_node
= node
->u
.kids
[0];
1033 for (i
= 1; i
< M_SIZE
; i
++)
1035 if (!node
->u
.kids
[i
])
1037 score
= penalty (node
->u
.kids
[i
], query
);
1038 if (score
< best_score
)
1041 best_node
= node
->u
.kids
[i
];
1044 __r_insert_node (best_node
, query
, manage
, true);
1051 r_insert_entry (rtree_t
* rtree
, const BoxType
* which
, int man
)
1054 assert (which
->X1
<= which
->X2
);
1055 assert (which
->Y1
<= which
->Y2
);
1056 /* recursively search the tree for the best leaf node */
1057 assert (rtree
->root
);
1058 __r_insert_node (rtree
->root
, which
, man
,
1059 rtree
->root
->box
.X1
> which
->X1
1060 || rtree
->root
->box
.X2
< which
->X2
1061 || rtree
->root
->box
.Y1
> which
->Y1
1062 || rtree
->root
->box
.Y2
< which
->Y2
);
1067 __r_delete (struct rtree_node
*node
, const BoxType
* query
)
1069 int i
, flag
, mask
, a
;
1071 /* the tree might be inconsistent during delete */
1072 if (query
->X1
< node
->box
.X1
|| query
->Y1
< node
->box
.Y1
1073 || query
->X2
> node
->box
.X2
|| query
->Y2
> node
->box
.Y2
)
1075 if (!node
->flags
.is_leaf
)
1077 for (i
= 0; i
< M_SIZE
; i
++)
1079 /* if this is us being removed, free and copy over */
1080 if (node
->u
.kids
[i
] == (struct rtree_node
*) query
)
1082 free ((void *) query
);
1083 for (; i
< M_SIZE
; i
++)
1085 node
->u
.kids
[i
] = node
->u
.kids
[i
+ 1];
1086 if (!node
->u
.kids
[i
])
1089 /* nobody home here now ? */
1090 if (!node
->u
.kids
[0])
1094 /* wow, the root is empty! */
1095 node
->flags
.is_leaf
= 1;
1096 /* changing type of node, be sure it's all zero */
1097 for (i
= 1; i
< M_SIZE
+ 1; i
++)
1098 node
->u
.rects
[i
].bptr
= NULL
;
1101 return (__r_delete (node
->parent
, &node
->box
));
1104 /* propegate boundary adjust upward */
1107 adjust_bounds (node
);
1108 node
= node
->parent
;
1112 if (node
->u
.kids
[i
])
1114 if (__r_delete (node
->u
.kids
[i
], query
))
1122 /* leaf node here */
1125 for (i
= 0; i
< M_SIZE
; i
++)
1127 #ifdef DELETE_BY_POINTER
1128 if (!node
->u
.rects
[i
].bptr
|| node
->u
.rects
[i
].bptr
== query
)
1130 if (node
->u
.rects
[i
].bounds
.X1
== query
->X1
&&
1131 node
->u
.rects
[i
].bounds
.X2
== query
->X2
&&
1132 node
->u
.rects
[i
].bounds
.Y1
== query
->Y1
&&
1133 node
->u
.rects
[i
].bounds
.Y2
== query
->Y2
)
1139 if (!node
->u
.rects
[i
].bptr
)
1140 return false; /* not at this leaf */
1141 if (node
->flags
.manage
& a
)
1143 free ((void *) node
->u
.rects
[i
].bptr
);
1144 node
->u
.rects
[i
].bptr
= NULL
;
1146 /* squeeze the manage flags together */
1147 flag
= node
->flags
.manage
& mask
;
1148 mask
= (~mask
) << 1;
1149 node
->flags
.manage
= flag
| ((node
->flags
.manage
& mask
) >> 1);
1150 /* remove the entry */
1151 for (; i
< M_SIZE
; i
++)
1153 node
->u
.rects
[i
] = node
->u
.rects
[i
+ 1];
1154 if (!node
->u
.rects
[i
].bptr
)
1157 if (!node
->u
.rects
[0].bptr
)
1160 __r_delete (node
->parent
, &node
->box
);
1164 /* propagate boundary adjustment upward */
1167 adjust_bounds (node
);
1168 node
= node
->parent
;
1174 r_delete_entry (rtree_t
* rtree
, const BoxType
* box
)
1180 r
= __r_delete (rtree
->root
, box
);
1184 assert (__r_tree_is_good (rtree
->root
));