6 * PCB, interactive printed circuit board design
7 * Copyright (C) 1994,1995,1996 Thomas Nau
8 * Copyright (C) 1998,1999,2000,2001,2002,2003,2004 harry eaton
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 * Contact addresses for paper mail and Email:
25 * harry eaton, 6697 Buttonhole Ct, Columbia, MD 21044 USA
26 * haceaton@aplcomm.jhuapl.edu
30 /* this file, rtree.c, was written and is
31 * Copyright (c) 2004, harry eaton
34 /* implements r-tree structures.
35 * these should be much faster for the auto-router
36 * because the recursive search is much more efficient
37 * and that's where the auto-router spends all its time.
52 #ifdef HAVE_LIBDMALLOC
60 /* All rectangles are closed on the bottom left and open on the
61 * top right. i.e. they contain one corner point, but not the other.
62 * This requires that the corner points not be equal!
65 /* the number of entries in each rtree node
66 * 4 - 7 seem to be pretty good settings
70 /* it seems that sorting the leaf order slows us down
71 * but sometimes gives better routes
76 #define DELETE_BY_POINTER
80 const BoxType
*bptr
; /* pointer to the box */
81 BoxType bounds
; /* copy of the box for locality of reference */
86 BoxType box
; /* bounds rectangle of this node */
87 struct rtree_node
*parent
; /* parent of this node, NULL = root */
90 unsigned is_leaf
:1; /* this is a leaf node */
91 unsigned manage
:31; /* true==should free 'rect.bptr' if node is destroyed */
96 struct rtree_node
*kids
[M_SIZE
+ 1]; /* when not leaf */
97 Rentry rects
[M_SIZE
+ 1]; /* when leaf */
104 __r_node_is_good (struct rtree_node
*node
)
112 for (i
= 0; i
< M_SIZE
; i
++)
114 if (node
->flags
.is_leaf
)
116 if (!node
->u
.rects
[i
].bptr
)
121 /* check that once one entry is empty, all the rest are too */
122 if (node
->u
.rects
[i
].bptr
&& last
)
124 /* check that the box makes sense */
125 if (node
->box
.X1
> node
->box
.X2
)
127 if (node
->box
.Y1
> node
->box
.Y2
)
129 /* check that bounds is the same as the pointer */
130 if (node
->u
.rects
[i
].bounds
.X1
!= node
->u
.rects
[i
].bptr
->X1
)
132 if (node
->u
.rects
[i
].bounds
.Y1
!= node
->u
.rects
[i
].bptr
->Y1
)
134 if (node
->u
.rects
[i
].bounds
.X2
!= node
->u
.rects
[i
].bptr
->X2
)
136 if (node
->u
.rects
[i
].bounds
.Y2
!= node
->u
.rects
[i
].bptr
->Y2
)
138 /* check that entries are within node bounds */
139 if (node
->u
.rects
[i
].bounds
.X1
< node
->box
.X1
)
141 if (node
->u
.rects
[i
].bounds
.X2
> node
->box
.X2
)
143 if (node
->u
.rects
[i
].bounds
.Y1
< node
->box
.Y1
)
145 if (node
->u
.rects
[i
].bounds
.Y2
> node
->box
.Y2
)
150 if (!node
->u
.kids
[i
])
155 /* make sure all children are the same type */
157 kind
= node
->u
.kids
[i
]->flags
.is_leaf
;
158 else if (kind
!= node
->u
.kids
[i
]->flags
.is_leaf
)
160 /* check that once one entry is empty, all the rest are too */
161 if (node
->u
.kids
[i
] && last
)
163 /* check that entries are within node bounds */
164 if (node
->u
.kids
[i
]->box
.X1
< node
->box
.X1
)
166 if (node
->u
.kids
[i
]->box
.X2
> node
->box
.X2
)
168 if (node
->u
.kids
[i
]->box
.Y1
< node
->box
.Y1
)
170 if (node
->u
.kids
[i
]->box
.Y2
> node
->box
.Y2
)
175 /* check that we're completely in the parent's bounds */
178 if (node
->parent
->box
.X1
> node
->box
.X1
)
180 if (node
->parent
->box
.X2
< node
->box
.X2
)
182 if (node
->parent
->box
.Y1
> node
->box
.Y1
)
184 if (node
->parent
->box
.Y2
< node
->box
.Y2
)
187 /* make sure overflow is empty */
188 if (!node
->flags
.is_leaf
&& node
->u
.kids
[i
])
190 if (node
->flags
.is_leaf
&& node
->u
.rects
[i
].bptr
)
195 /* check the whole tree from this node down for consistency */
197 __r_tree_is_good (struct rtree_node
*node
)
203 if (!__r_node_is_good (node
))
205 if (node
->flags
.is_leaf
)
207 for (i
= 0; i
< M_SIZE
; i
++)
209 if (!__r_tree_is_good (node
->u
.kids
[i
]))
218 /* print out the tree */
220 __r_dump_tree (struct rtree_node
*node
, int depth
)
232 (node
->box
.X2
- node
->box
.X1
) * (double) (node
->box
.Y2
- node
->box
.Y1
);
234 for (i
= 0; i
< depth
; i
++)
236 if (!node
->flags
.is_leaf
)
238 printf ("p=0x%p node X(%d, %d) Y(%d, %d)\n", (void *) node
,
239 node
->box
.X1
, node
->box
.X2
, node
->box
.Y1
, node
->box
.Y2
);
243 printf ("p=0x%p leaf manage(%02x) X(%d, %d) Y(%d, %d)\n", (void *) node
,
244 node
->flags
.manage
, node
->box
.X1
, node
->box
.X2
, node
->box
.Y1
,
246 for (j
= 0; j
< M_SIZE
; j
++)
248 if (!node
->u
.rects
[j
].bptr
)
251 (node
->u
.rects
[j
].bounds
.X2
-
252 node
->u
.rects
[j
].bounds
.X1
) *
253 (double) (node
->u
.rects
[j
].bounds
.Y2
-
254 node
->u
.rects
[j
].bounds
.Y1
);
256 for (i
= 0; i
< depth
+ 1; i
++)
258 printf ("entry 0x%p X(%d, %d) Y(%d, %d)\n",
259 (void *) (node
->u
.rects
[j
].bptr
),
260 node
->u
.rects
[j
].bounds
.X1
, node
->u
.rects
[j
].bounds
.X2
,
261 node
->u
.rects
[j
].bounds
.Y1
, node
->u
.rects
[j
].bounds
.Y2
);
265 for (i
= 0; i
< M_SIZE
; i
++)
267 __r_dump_tree (node
->u
.kids
[i
], depth
+ 1);
269 printf ("average box area is %g\n", area
/ count
);
273 /* Sort the children or entries of a node
274 * according to the largest side.
278 cmp_box (const BoxType
* a
, const BoxType
* b
)
280 /* compare two box coordinates so that the __r_search
281 * will fail at the earliest comparison possible.
282 * It needs to see the biggest X1 first, then the
283 * smallest X2, the biggest Y1 and smallest Y2
303 sort_node (struct rtree_node
*node
)
305 if (node
->flags
.is_leaf
)
307 register Rentry
*r
, *i
, temp
;
309 for (r
= &node
->u
.rects
[1]; r
->bptr
; r
++)
313 while (i
>= &node
->u
.rects
[0])
315 if (cmp_box (&i
->bounds
, &r
->bounds
))
326 register struct rtree_node
**r
, **i
, *temp
;
328 for (r
= &node
->u
.kids
[1]; *r
; r
++)
332 while (i
>= &node
->u
.kids
[0])
334 if (cmp_box (&(*i
)->box
, &(*r
)->box
))
348 /* set the node bounds large enough to encompass all
349 * of the children's rectangles
352 adjust_bounds (struct rtree_node
*node
)
357 assert (node
->u
.kids
[0]);
358 if (node
->flags
.is_leaf
)
360 node
->box
= node
->u
.rects
[0].bounds
;
361 for (i
= 1; i
< M_SIZE
+ 1; i
++)
363 if (!node
->u
.rects
[i
].bptr
)
365 MAKEMIN (node
->box
.X1
, node
->u
.rects
[i
].bounds
.X1
);
366 MAKEMAX (node
->box
.X2
, node
->u
.rects
[i
].bounds
.X2
);
367 MAKEMIN (node
->box
.Y1
, node
->u
.rects
[i
].bounds
.Y1
);
368 MAKEMAX (node
->box
.Y2
, node
->u
.rects
[i
].bounds
.Y2
);
373 node
->box
= node
->u
.kids
[0]->box
;
374 for (i
= 1; i
< M_SIZE
+ 1; i
++)
376 if (!node
->u
.kids
[i
])
378 MAKEMIN (node
->box
.X1
, node
->u
.kids
[i
]->box
.X1
);
379 MAKEMAX (node
->box
.X2
, node
->u
.kids
[i
]->box
.X2
);
380 MAKEMIN (node
->box
.Y1
, node
->u
.kids
[i
]->box
.Y1
);
381 MAKEMAX (node
->box
.Y2
, node
->u
.kids
[i
]->box
.Y2
);
386 /* create an r-tree from an unsorted list of boxes.
387 * the r-tree will keep pointers into
388 * it, so don't free the box list until you've called r_destroy_tree.
389 * if you set 'manage' to true, r_destroy_tree will free your boxlist.
392 r_create_tree (const BoxType
* boxlist
[], int N
, int manage
)
395 struct rtree_node
*node
;
399 rtree
= (rtree_t
*)calloc (1, sizeof (*rtree
));
400 /* start with a single empty leaf node */
401 node
= (struct rtree_node
*)calloc (1, sizeof (*node
));
402 node
->flags
.is_leaf
= 1;
405 /* simple, just insert all of the boxes! */
406 for (i
= 0; i
< N
; i
++)
409 r_insert_entry (rtree
, boxlist
[i
], manage
);
412 assert (__r_tree_is_good (rtree
->root
));
418 __r_destroy_tree (struct rtree_node
*node
)
422 if (node
->flags
.is_leaf
)
423 for (i
= 0; i
< M_SIZE
; i
++)
425 if (!node
->u
.rects
[i
].bptr
)
427 if (node
->flags
.manage
& flag
)
428 free ((void *) node
->u
.rects
[i
].bptr
);
432 for (i
= 0; i
< M_SIZE
; i
++)
434 if (!node
->u
.kids
[i
])
436 __r_destroy_tree (node
->u
.kids
[i
]);
441 /* free the memory associated with an rtree. */
443 r_destroy_tree (rtree_t
** rtree
)
446 __r_destroy_tree ((*rtree
)->root
);
453 int (*check_it
) (const BoxType
* region
, void *cl
);
454 int (*found_it
) (const BoxType
* box
, void *cl
);
458 /* most of the auto-routing time is spent in this routine
459 * so some careful thought has been given to maximizing the speed
463 __r_search (struct rtree_node
*node
, const BoxType
* query
, r_arg
* arg
)
466 /** assert that starting_region is well formed */
467 assert (query
->X1
< query
->X2
&& query
->Y1
< query
->Y2
);
468 assert (node
->box
.X1
< query
->X2
&& node
->box
.X2
> query
->X1
&&
469 node
->box
.Y1
< query
->Y2
&& node
->box
.Y2
> query
->Y1
);
471 /** assert that node is well formed */
472 assert (__r_node_is_good (node
));
474 /* the check for bounds is done before entry. This saves the overhead
475 * of building/destroying the stack frame for each bounds that fails
476 * to intersect, which is the most common condition.
478 if (node
->flags
.is_leaf
)
481 if (arg
->found_it
) /* test this once outside of loop */
483 register int seen
= 0;
484 for (i
= 0; node
->u
.rects
[i
].bptr
; i
++)
486 if ((node
->u
.rects
[i
].bounds
.X1
< query
->X2
) &&
487 (node
->u
.rects
[i
].bounds
.X2
> query
->X1
) &&
488 (node
->u
.rects
[i
].bounds
.Y1
< query
->Y2
) &&
489 (node
->u
.rects
[i
].bounds
.Y2
> query
->Y1
) &&
490 arg
->found_it (node
->u
.rects
[i
].bptr
, arg
->closure
))
497 register int seen
= 0;
498 for (i
= 0; node
->u
.rects
[i
].bptr
; i
++)
500 if ((node
->u
.rects
[i
].bounds
.X1
< query
->X2
) &&
501 (node
->u
.rects
[i
].bounds
.X2
> query
->X1
) &&
502 (node
->u
.rects
[i
].bounds
.Y1
< query
->Y2
) &&
503 (node
->u
.rects
[i
].bounds
.Y2
> query
->Y1
))
510 /* not a leaf, recurse on lower nodes */
514 struct rtree_node
**n
;
515 for (n
= &node
->u
.kids
[0]; *n
; n
++)
517 if ((*n
)->box
.X1
>= query
->X2
||
518 (*n
)->box
.X2
<= query
->X1
||
519 (*n
)->box
.Y1
>= query
->Y2
|| (*n
)->box
.Y2
<= query
->Y1
||
520 !arg
->check_it (&(*n
)->box
, arg
->closure
))
522 seen
+= __r_search (*n
, query
, arg
);
529 struct rtree_node
**n
;
530 for (n
= &node
->u
.kids
[0]; *n
; n
++)
532 if ((*n
)->box
.X1
>= query
->X2
||
533 (*n
)->box
.X2
<= query
->X1
||
534 (*n
)->box
.Y1
>= query
->Y2
|| (*n
)->box
.Y2
<= query
->Y1
)
536 seen
+= __r_search (*n
, query
, arg
);
542 /* Parameterized search in the rtree.
543 * Returns the number of rectangles found.
544 * calls found_rectangle for each intersection seen
545 * and calls check_region with the current sub-region
546 * to see whether deeper searching is desired
549 r_search (rtree_t
* rtree
, const BoxType
* query
,
550 int (*check_region
) (const BoxType
* region
, void *cl
),
551 int (*found_rectangle
) (const BoxType
* box
, void *cl
), void *cl
)
555 if (!rtree
|| rtree
->size
< 1)
560 assert (__r_tree_is_good (rtree
->root
));
563 if (query
->X2
<= query
->X1
|| query
->Y2
<= query
->Y1
)
566 /* check this box. If it's not touched we're done here */
567 if (rtree
->root
->box
.X1
>= query
->X2
||
568 rtree
->root
->box
.X2
<= query
->X1
||
569 rtree
->root
->box
.Y1
>= query
->Y2
570 || rtree
->root
->box
.Y2
<= query
->Y1
)
572 arg
.check_it
= check_region
;
573 arg
.found_it
= found_rectangle
;
575 return __r_search (rtree
->root
, query
, &arg
);
579 arg
.check_it
= check_region
;
580 arg
.found_it
= found_rectangle
;
582 return __r_search (rtree
->root
, &rtree
->root
->box
, &arg
);
586 /*------ r_region_is_empty ------*/
588 __r_region_is_empty_rect_in_reg (const BoxType
* box
, void *cl
)
590 jmp_buf *envp
= (jmp_buf *) cl
;
591 longjmp (*envp
, 1); /* found one! */
594 /* return 0 if there are any rectangles in the given region. */
596 r_region_is_empty (rtree_t
* rtree
, const BoxType
* region
)
608 r_search (rtree
, region
, NULL
, __r_region_is_empty_rect_in_reg
, &env
);
610 assert (r
== 0); /* otherwise longjmp would have been called */
612 return 1; /* no rectangles found */
620 /* split the node into two nodes putting clusters in each
621 * use the k-means clustering algorithm
624 find_clusters (struct rtree_node
*node
)
626 float total_a
, total_b
;
627 float a_X
, a_Y
, b_X
, b_Y
;
628 bool belong
[M_SIZE
+ 1];
629 struct centroid center
[M_SIZE
+ 1];
630 int clust_a
, clust_b
, tries
;
631 int a_manage
= 0, b_manage
= 0;
632 int i
, old_ax
, old_ay
, old_bx
, old_by
;
633 struct rtree_node
*new_node
;
636 for (i
= 0; i
< M_SIZE
+ 1; i
++)
638 if (node
->flags
.is_leaf
)
639 b
= &(node
->u
.rects
[i
].bounds
);
641 b
= &(node
->u
.kids
[i
]->box
);
642 center
[i
].x
= 0.5 * (b
->X1
+ b
->X2
);
643 center
[i
].y
= 0.5 * (b
->Y1
+ b
->Y2
);
644 /* adding 1 prevents zero area */
645 center
[i
].area
= 1. + (float) (b
->X2
- b
->X1
) * (float) (b
->Y2
- b
->Y1
);
647 /* starting 'A' cluster center */
650 /* starting 'B' cluster center */
651 b_X
= center
[M_SIZE
].x
;
652 b_Y
= center
[M_SIZE
].y
;
653 /* don't allow the same cluster centers */
654 if (b_X
== a_X
&& b_Y
== a_Y
)
659 for (tries
= 0; tries
< M_SIZE
; tries
++)
665 clust_a
= clust_b
= 0;
666 for (i
= 0; i
< M_SIZE
+ 1; i
++)
670 dist1
= SQUARE (a_X
- center
[i
].x
) + SQUARE (a_Y
- center
[i
].y
);
671 dist2
= SQUARE (b_X
- center
[i
].x
) + SQUARE (b_Y
- center
[i
].y
);
672 if (dist1
* (clust_a
+ M_SIZE
/ 2) < dist2
* (clust_b
+ M_SIZE
/ 2))
683 /* kludge to fix degenerate cases */
684 if (clust_a
== M_SIZE
+ 1)
685 belong
[M_SIZE
/ 2] = false;
686 else if (clust_b
== M_SIZE
+ 1)
687 belong
[M_SIZE
/ 2] = true;
688 /* compute new center of gravity of clusters */
689 total_a
= total_b
= 0;
690 a_X
= a_Y
= b_X
= b_Y
= 0;
691 for (i
= 0; i
< M_SIZE
+ 1; i
++)
695 a_X
+= center
[i
].x
* center
[i
].area
;
696 a_Y
+= center
[i
].y
* center
[i
].area
;
697 total_a
+= center
[i
].area
;
701 b_X
+= center
[i
].x
* center
[i
].area
;
702 b_Y
+= center
[i
].y
* center
[i
].area
;
703 total_b
+= center
[i
].area
;
710 if (old_ax
== (int) a_X
&& old_ay
== (int) a_Y
&&
711 old_bx
== (int) b_X
&& old_by
== (int) b_Y
)
714 /* Now 'belong' has the partition map */
715 new_node
= (struct rtree_node
*)calloc (1, sizeof (*new_node
));
716 new_node
->parent
= node
->parent
;
717 new_node
->flags
.is_leaf
= node
->flags
.is_leaf
;
718 clust_a
= clust_b
= 0;
719 if (node
->flags
.is_leaf
)
721 int flag
, a_flag
, b_flag
;
722 flag
= a_flag
= b_flag
= 1;
723 for (i
= 0; i
< M_SIZE
+ 1; i
++)
727 node
->u
.rects
[clust_a
++] = node
->u
.rects
[i
];
728 if (node
->flags
.manage
& flag
)
734 new_node
->u
.rects
[clust_b
++] = node
->u
.rects
[i
];
735 if (node
->flags
.manage
& flag
)
744 for (i
= 0; i
< M_SIZE
+ 1; i
++)
747 node
->u
.kids
[clust_a
++] = node
->u
.kids
[i
];
750 node
->u
.kids
[i
]->parent
= new_node
;
751 new_node
->u
.kids
[clust_b
++] = node
->u
.kids
[i
];
755 node
->flags
.manage
= a_manage
;
756 new_node
->flags
.manage
= b_manage
;
757 assert (clust_a
!= 0);
758 assert (clust_b
!= 0);
759 if (node
->flags
.is_leaf
)
760 for (; clust_a
< M_SIZE
+ 1; clust_a
++)
761 node
->u
.rects
[clust_a
].bptr
= NULL
;
763 for (; clust_a
< M_SIZE
+ 1; clust_a
++)
764 node
->u
.kids
[clust_a
] = NULL
;
765 adjust_bounds (node
);
767 adjust_bounds (new_node
);
768 sort_node (new_node
);
772 /* split a node according to clusters
775 split_node (struct rtree_node
*node
)
778 struct rtree_node
*new_node
;
781 assert (node
->flags
.is_leaf
? (void *) node
->u
.rects
[M_SIZE
].
782 bptr
: (void *) node
->u
.kids
[M_SIZE
]);
783 new_node
= find_clusters (node
);
784 if (node
->parent
== NULL
) /* split root node */
786 struct rtree_node
*second
;
788 second
= (struct rtree_node
*)calloc (1, sizeof (*second
));
790 if (!second
->flags
.is_leaf
)
791 for (i
= 0; i
< M_SIZE
; i
++)
792 if (second
->u
.kids
[i
])
793 second
->u
.kids
[i
]->parent
= second
;
794 node
->flags
.is_leaf
= 0;
795 node
->flags
.manage
= 0;
796 second
->parent
= new_node
->parent
= node
;
797 node
->u
.kids
[0] = new_node
;
798 node
->u
.kids
[1] = second
;
799 for (i
= 2; i
< M_SIZE
+ 1; i
++)
800 node
->u
.kids
[i
] = NULL
;
801 adjust_bounds (node
);
804 assert (__r_tree_is_good (node
));
808 for (i
= 0; i
< M_SIZE
; i
++)
809 if (!node
->parent
->u
.kids
[i
])
811 node
->parent
->u
.kids
[i
] = new_node
;
813 assert (__r_node_is_good (node
));
814 assert (__r_node_is_good (new_node
));
819 assert (__r_node_is_good (node
->parent
));
821 sort_node (node
->parent
);
824 split_node (node
->parent
);
828 contained (struct rtree_node
*node
, const BoxType
* query
)
830 if (node
->box
.X1
> query
->X1
|| node
->box
.X2
< query
->X2
||
831 node
->box
.Y1
> query
->Y1
|| node
->box
.Y2
< query
->Y2
)
838 penalty (struct rtree_node
*node
, const BoxType
* query
)
842 /* Compute the area penalty for inserting here and return.
843 * The penalty is the increase in area necessary
844 * to include the query->
846 score
= (MAX (node
->box
.X2
, query
->X2
) - MIN (node
->box
.X1
, query
->X1
));
847 score
*= (MAX (node
->box
.Y2
, query
->Y2
) - MIN (node
->box
.Y1
, query
->Y1
));
849 (double)(node
->box
.X2
- node
->box
.X1
) *
850 (double)(node
->box
.Y2
- node
->box
.Y1
);
855 __r_insert_node (struct rtree_node
*node
, const BoxType
* query
,
856 int manage
, bool force
)
860 assert (__r_node_is_good (node
));
862 /* Ok, at this point we must already enclose the query or we're forcing
863 * this node to expand to enclose it, so if we're a leaf, simply store
867 if (node
->flags
.is_leaf
)
871 if (UNLIKELY (manage
))
873 register int flag
= 1;
875 for (i
= 0; i
< M_SIZE
; i
++)
877 if (!node
->u
.rects
[i
].bptr
)
881 node
->flags
.manage
|= flag
;
885 for (i
= 0; i
< M_SIZE
; i
++)
886 if (!node
->u
.rects
[i
].bptr
)
889 /* the node always has an extra space available */
890 node
->u
.rects
[i
].bptr
= query
;
891 node
->u
.rects
[i
].bounds
= *query
;
892 /* first entry in node determines initial bounding box */
897 MAKEMIN (node
->box
.X1
, query
->X1
);
898 MAKEMAX (node
->box
.X2
, query
->X2
);
899 MAKEMIN (node
->box
.Y1
, query
->Y1
);
900 MAKEMAX (node
->box
.Y2
, query
->Y2
);
907 /* we must split the node */
914 struct rtree_node
*best_node
;
915 double score
, best_score
;
919 MAKEMIN (node
->box
.X1
, query
->X1
);
920 MAKEMAX (node
->box
.X2
, query
->X2
);
921 MAKEMIN (node
->box
.Y1
, query
->Y1
);
922 MAKEMAX (node
->box
.Y2
, query
->Y2
);
925 /* this node encloses it, but it's not a leaf, so descend the tree */
927 /* First check if any children actually encloses it */
928 assert (node
->u
.kids
[0]);
929 for (i
= 0; i
< M_SIZE
; i
++)
931 if (!node
->u
.kids
[i
])
933 if (contained (node
->u
.kids
[i
], query
))
935 __r_insert_node (node
->u
.kids
[i
], query
, manage
, false);
941 /* see if there is room for a new leaf node */
942 if (node
->u
.kids
[0]->flags
.is_leaf
&& i
< M_SIZE
)
944 struct rtree_node
*new_node
;
945 new_node
= (struct rtree_node
*)calloc (1, sizeof (*new_node
));
946 new_node
->parent
= node
;
947 new_node
->flags
.is_leaf
= true;
948 node
->u
.kids
[i
] = new_node
;
949 new_node
->u
.rects
[0].bptr
= query
;
950 new_node
->u
.rects
[0].bounds
= *query
;
951 new_node
->box
= *query
;
952 if (UNLIKELY (manage
))
953 new_node
->flags
.manage
= 1;
958 /* Ok, so we're still here - look for the best child to push it into */
959 best_score
= penalty (node
->u
.kids
[0], query
);
960 best_node
= node
->u
.kids
[0];
961 for (i
= 1; i
< M_SIZE
; i
++)
963 if (!node
->u
.kids
[i
])
965 score
= penalty (node
->u
.kids
[i
], query
);
966 if (score
< best_score
)
969 best_node
= node
->u
.kids
[i
];
972 __r_insert_node (best_node
, query
, manage
, true);
979 r_insert_entry (rtree_t
* rtree
, const BoxType
* which
, int man
)
982 assert (which
->X1
<= which
->X2
);
983 assert (which
->Y1
<= which
->Y2
);
984 /* recursively search the tree for the best leaf node */
985 assert (rtree
->root
);
986 __r_insert_node (rtree
->root
, which
, man
,
987 rtree
->root
->box
.X1
> which
->X1
988 || rtree
->root
->box
.X2
< which
->X2
989 || rtree
->root
->box
.Y1
> which
->Y1
990 || rtree
->root
->box
.Y2
< which
->Y2
);
995 __r_delete (struct rtree_node
*node
, const BoxType
* query
)
997 int i
, flag
, mask
, a
;
999 /* the tree might be inconsistent during delete */
1000 if (query
->X1
< node
->box
.X1
|| query
->Y1
< node
->box
.Y1
1001 || query
->X2
> node
->box
.X2
|| query
->Y2
> node
->box
.Y2
)
1003 if (!node
->flags
.is_leaf
)
1005 for (i
= 0; i
< M_SIZE
; i
++)
1007 /* if this is us being removed, free and copy over */
1008 if (node
->u
.kids
[i
] == (struct rtree_node
*) query
)
1010 free ((void *) query
);
1011 for (; i
< M_SIZE
; i
++)
1013 node
->u
.kids
[i
] = node
->u
.kids
[i
+ 1];
1014 if (!node
->u
.kids
[i
])
1017 /* nobody home here now ? */
1018 if (!node
->u
.kids
[0])
1022 /* wow, the root is empty! */
1023 node
->flags
.is_leaf
= 1;
1024 /* changing type of node, be sure it's all zero */
1025 for (i
= 1; i
< M_SIZE
+ 1; i
++)
1026 node
->u
.rects
[i
].bptr
= NULL
;
1029 return (__r_delete (node
->parent
, &node
->box
));
1032 /* propegate boundary adjust upward */
1035 adjust_bounds (node
);
1036 node
= node
->parent
;
1040 if (node
->u
.kids
[i
])
1042 if (__r_delete (node
->u
.kids
[i
], query
))
1050 /* leaf node here */
1053 for (i
= 0; i
< M_SIZE
; i
++)
1055 #ifdef DELETE_BY_POINTER
1056 if (!node
->u
.rects
[i
].bptr
|| node
->u
.rects
[i
].bptr
== query
)
1058 if (node
->u
.rects
[i
].bounds
.X1
== query
->X1
&&
1059 node
->u
.rects
[i
].bounds
.X2
== query
->X2
&&
1060 node
->u
.rects
[i
].bounds
.Y1
== query
->Y1
&&
1061 node
->u
.rects
[i
].bounds
.Y2
== query
->Y2
)
1067 if (!node
->u
.rects
[i
].bptr
)
1068 return false; /* not at this leaf */
1069 if (node
->flags
.manage
& a
)
1071 free ((void *) node
->u
.rects
[i
].bptr
);
1072 node
->u
.rects
[i
].bptr
= NULL
;
1074 /* squeeze the manage flags together */
1075 flag
= node
->flags
.manage
& mask
;
1076 mask
= (~mask
) << 1;
1077 node
->flags
.manage
= flag
| ((node
->flags
.manage
& mask
) >> 1);
1078 /* remove the entry */
1079 for (; i
< M_SIZE
; i
++)
1081 node
->u
.rects
[i
] = node
->u
.rects
[i
+ 1];
1082 if (!node
->u
.rects
[i
].bptr
)
1085 if (!node
->u
.rects
[0].bptr
)
1088 __r_delete (node
->parent
, &node
->box
);
1092 /* propagate boundary adjustment upward */
1095 adjust_bounds (node
);
1096 node
= node
->parent
;
1102 r_delete_entry (rtree_t
* rtree
, const BoxType
* box
)
1108 r
= __r_delete (rtree
->root
, box
);
1112 assert (__r_tree_is_good (rtree
->root
));