4 * PCB, interactive printed circuit board design
5 * Copyright (C) 1994,1995,1996 Thomas Nau
6 * Copyright (C) 1998,1999,2000,2001,2002,2003,2004 harry eaton
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 * Contact addresses for paper mail and Email:
23 * harry eaton, 6697 Buttonhole Ct, Columbia, MD 21044 USA
24 * haceaton@aplcomm.jhuapl.edu
28 /* this file, rtree.c, was written and is
29 * Copyright (c) 2004, harry eaton
32 /* implements r-tree structures.
33 * these should be much faster for the auto-router
34 * because the recursive search is much more efficient
35 * and that's where the auto-router spends all its time.
51 #ifdef HAVE_LIBDMALLOC
56 /* All rectangles are closed on the bottom left and open on the
57 * top right. i.e. they contain one corner point, but not the other.
58 * This requires that the corner points not be equal!
61 /* the number of entries in each rtree node
62 * 4 - 7 seem to be pretty good settings
66 /* it seems that sorting the leaf order slows us down
67 * but sometimes gives better routes
72 #define DELETE_BY_POINTER
76 const BoxType
*bptr
; /* pointer to the box */
77 BoxType bounds
; /* copy of the box for locality of reference */
82 BoxType box
; /* bounds rectangle of this node */
83 struct rtree_node
*parent
; /* parent of this node, NULL = root */
86 unsigned is_leaf
:1; /* this is a leaf node */
87 unsigned manage
:31; /* true==should free 'rect.bptr' if node is destroyed */
92 struct rtree_node
*kids
[M_SIZE
+ 1]; /* when not leaf */
93 Rentry rects
[M_SIZE
+ 1]; /* when leaf */
100 __r_node_is_good (struct rtree_node
*node
)
108 for (i
= 0; i
< M_SIZE
; i
++)
110 if (node
->flags
.is_leaf
)
112 if (!node
->u
.rects
[i
].bptr
)
117 /* check that once one entry is empty, all the rest are too */
118 if (node
->u
.rects
[i
].bptr
&& last
)
120 /* check that the box makes sense */
121 if (node
->box
.X1
> node
->box
.X2
)
123 if (node
->box
.Y1
> node
->box
.Y2
)
125 /* check that bounds is the same as the pointer */
126 if (node
->u
.rects
[i
].bounds
.X1
!= node
->u
.rects
[i
].bptr
->X1
)
128 if (node
->u
.rects
[i
].bounds
.Y1
!= node
->u
.rects
[i
].bptr
->Y1
)
130 if (node
->u
.rects
[i
].bounds
.X2
!= node
->u
.rects
[i
].bptr
->X2
)
132 if (node
->u
.rects
[i
].bounds
.Y2
!= node
->u
.rects
[i
].bptr
->Y2
)
134 /* check that entries are within node bounds */
135 if (node
->u
.rects
[i
].bounds
.X1
< node
->box
.X1
)
137 if (node
->u
.rects
[i
].bounds
.X2
> node
->box
.X2
)
139 if (node
->u
.rects
[i
].bounds
.Y1
< node
->box
.Y1
)
141 if (node
->u
.rects
[i
].bounds
.Y2
> node
->box
.Y2
)
146 if (!node
->u
.kids
[i
])
151 /* make sure all children are the same type */
153 kind
= node
->u
.kids
[i
]->flags
.is_leaf
;
154 else if (kind
!= node
->u
.kids
[i
]->flags
.is_leaf
)
156 /* check that once one entry is empty, all the rest are too */
157 if (node
->u
.kids
[i
] && last
)
159 /* check that entries are within node bounds */
160 if (node
->u
.kids
[i
]->box
.X1
< node
->box
.X1
)
162 if (node
->u
.kids
[i
]->box
.X2
> node
->box
.X2
)
164 if (node
->u
.kids
[i
]->box
.Y1
< node
->box
.Y1
)
166 if (node
->u
.kids
[i
]->box
.Y2
> node
->box
.Y2
)
171 /* check that we're completely in the parent's bounds */
174 if (node
->parent
->box
.X1
> node
->box
.X1
)
176 if (node
->parent
->box
.X2
< node
->box
.X2
)
178 if (node
->parent
->box
.Y1
> node
->box
.Y1
)
180 if (node
->parent
->box
.Y2
< node
->box
.Y2
)
183 /* make sure overflow is empty */
184 if (!node
->flags
.is_leaf
&& node
->u
.kids
[i
])
186 if (node
->flags
.is_leaf
&& node
->u
.rects
[i
].bptr
)
191 /* check the whole tree from this node down for consistency */
193 __r_tree_is_good (struct rtree_node
*node
)
199 if (!__r_node_is_good (node
))
201 if (node
->flags
.is_leaf
)
203 for (i
= 0; i
< M_SIZE
; i
++)
205 if (!__r_tree_is_good (node
->u
.kids
[i
]))
214 /* print out the tree */
216 __r_dump_tree (struct rtree_node
*node
, int depth
)
228 (node
->box
.X2
- node
->box
.X1
) * (double) (node
->box
.Y2
- node
->box
.Y1
);
230 for (i
= 0; i
< depth
; i
++)
232 if (!node
->flags
.is_leaf
)
235 "p=0x%p node X(%" PRIi64
", %" PRIi64
") Y(%" PRIi64
", %" PRIi64
238 (int64_t) (node
->box
.X1
),
239 (int64_t) (node
->box
.X2
),
240 (int64_t) (node
->box
.Y1
),
241 (int64_t) (node
->box
.Y2
) );
246 "p=0x%p leaf manage(%02x) X(%" PRIi64
", %" PRIi64
") Y(%" PRIi64
250 (int64_t) (node
->box
.X1
),
251 (int64_t) (node
->box
.X2
),
252 (int64_t) (node
->box
.Y1
),
253 (int64_t) (node
->box
.Y2
) );
254 for (j
= 0; j
< M_SIZE
; j
++)
256 if (!node
->u
.rects
[j
].bptr
)
259 (node
->u
.rects
[j
].bounds
.X2
-
260 node
->u
.rects
[j
].bounds
.X1
) *
261 (double) (node
->u
.rects
[j
].bounds
.Y2
-
262 node
->u
.rects
[j
].bounds
.Y1
);
264 for (i
= 0; i
< depth
+ 1; i
++)
267 "entry 0x%p X(%" PRIi64
", %" PRIi64
") Y(%" PRIi64
", "
269 (void *) (node
->u
.rects
[j
].bptr
),
270 (int64_t) (node
->u
.rects
[j
].bounds
.X1
),
271 (int64_t) (node
->u
.rects
[j
].bounds
.X2
),
272 (int64_t) (node
->u
.rects
[j
].bounds
.Y1
),
273 (int64_t) (node
->u
.rects
[j
].bounds
.Y2
) );
277 for (i
= 0; i
< M_SIZE
; i
++)
279 __r_dump_tree (node
->u
.kids
[i
], depth
+ 1);
281 printf ("average box area is %g\n", area
/ count
);
285 /* Sort the children or entries of a node
286 * according to the largest side.
290 cmp_box (const BoxType
* a
, const BoxType
* b
)
292 /* compare two box coordinates so that the __r_search
293 * will fail at the earliest comparison possible.
294 * It needs to see the biggest X1 first, then the
295 * smallest X2, the biggest Y1 and smallest Y2
315 sort_node (struct rtree_node
*node
)
317 if (node
->flags
.is_leaf
)
319 register Rentry
*r
, *i
, temp
;
321 for (r
= &node
->u
.rects
[1]; r
->bptr
; r
++)
325 while (i
>= &node
->u
.rects
[0])
327 if (cmp_box (&i
->bounds
, &r
->bounds
))
338 register struct rtree_node
**r
, **i
, *temp
;
340 for (r
= &node
->u
.kids
[1]; *r
; r
++)
344 while (i
>= &node
->u
.kids
[0])
346 if (cmp_box (&(*i
)->box
, &(*r
)->box
))
360 /* set the node bounds large enough to encompass all
361 * of the children's rectangles
364 adjust_bounds (struct rtree_node
*node
)
369 assert (node
->u
.kids
[0]);
370 if (node
->flags
.is_leaf
)
372 node
->box
= node
->u
.rects
[0].bounds
;
373 for (i
= 1; i
< M_SIZE
+ 1; i
++)
375 if (!node
->u
.rects
[i
].bptr
)
377 MAKEMIN (node
->box
.X1
, node
->u
.rects
[i
].bounds
.X1
);
378 MAKEMAX (node
->box
.X2
, node
->u
.rects
[i
].bounds
.X2
);
379 MAKEMIN (node
->box
.Y1
, node
->u
.rects
[i
].bounds
.Y1
);
380 MAKEMAX (node
->box
.Y2
, node
->u
.rects
[i
].bounds
.Y2
);
385 node
->box
= node
->u
.kids
[0]->box
;
386 for (i
= 1; i
< M_SIZE
+ 1; i
++)
388 if (!node
->u
.kids
[i
])
390 MAKEMIN (node
->box
.X1
, node
->u
.kids
[i
]->box
.X1
);
391 MAKEMAX (node
->box
.X2
, node
->u
.kids
[i
]->box
.X2
);
392 MAKEMIN (node
->box
.Y1
, node
->u
.kids
[i
]->box
.Y1
);
393 MAKEMAX (node
->box
.Y2
, node
->u
.kids
[i
]->box
.Y2
);
398 /* create an r-tree from an unsorted list of boxes.
399 * the r-tree will keep pointers into
400 * it, so don't free the box list until you've called r_destroy_tree.
401 * if you set 'manage' to true, r_destroy_tree will free your boxlist.
404 r_create_tree (const BoxType
* boxlist
[], int N
, int manage
)
407 struct rtree_node
*node
;
411 rtree
= (rtree_t
*)calloc (1, sizeof (*rtree
));
412 /* start with a single empty leaf node */
413 node
= (struct rtree_node
*)calloc (1, sizeof (*node
));
414 node
->flags
.is_leaf
= 1;
417 /* simple, just insert all of the boxes! */
418 for (i
= 0; i
< N
; i
++)
421 r_insert_entry (rtree
, boxlist
[i
], manage
);
424 assert (__r_tree_is_good (rtree
->root
));
430 __r_destroy_tree (struct rtree_node
*node
)
434 if (node
->flags
.is_leaf
)
435 for (i
= 0; i
< M_SIZE
; i
++)
437 if (!node
->u
.rects
[i
].bptr
)
439 if (node
->flags
.manage
& flag
)
440 free ((void *) node
->u
.rects
[i
].bptr
);
444 for (i
= 0; i
< M_SIZE
; i
++)
446 if (!node
->u
.kids
[i
])
448 __r_destroy_tree (node
->u
.kids
[i
]);
453 /* free the memory associated with an rtree. */
455 r_destroy_tree (rtree_t
** rtree
)
458 __r_destroy_tree ((*rtree
)->root
);
465 int (*check_it
) (const BoxType
* region
, void *cl
);
466 int (*found_it
) (const BoxType
* box
, void *cl
);
470 /* most of the auto-routing time is spent in this routine
471 * so some careful thought has been given to maximizing the speed
475 __r_search (struct rtree_node
*node
, const BoxType
* query
, r_arg
* arg
)
478 /** assert that starting_region is well formed */
479 assert (query
->X1
< query
->X2
&& query
->Y1
< query
->Y2
);
480 assert (node
->box
.X1
< query
->X2
&& node
->box
.X2
> query
->X1
&&
481 node
->box
.Y1
< query
->Y2
&& node
->box
.Y2
> query
->Y1
);
483 /** assert that node is well formed */
484 assert (__r_node_is_good (node
));
486 /* the check for bounds is done before entry. This saves the overhead
487 * of building/destroying the stack frame for each bounds that fails
488 * to intersect, which is the most common condition.
490 if (node
->flags
.is_leaf
)
493 if (arg
->found_it
) /* test this once outside of loop */
495 register int seen
= 0;
496 for (i
= 0; node
->u
.rects
[i
].bptr
; i
++)
498 if ((node
->u
.rects
[i
].bounds
.X1
< query
->X2
) &&
499 (node
->u
.rects
[i
].bounds
.X2
> query
->X1
) &&
500 (node
->u
.rects
[i
].bounds
.Y1
< query
->Y2
) &&
501 (node
->u
.rects
[i
].bounds
.Y2
> query
->Y1
) &&
502 arg
->found_it (node
->u
.rects
[i
].bptr
, arg
->closure
))
509 register int seen
= 0;
510 for (i
= 0; node
->u
.rects
[i
].bptr
; i
++)
512 if ((node
->u
.rects
[i
].bounds
.X1
< query
->X2
) &&
513 (node
->u
.rects
[i
].bounds
.X2
> query
->X1
) &&
514 (node
->u
.rects
[i
].bounds
.Y1
< query
->Y2
) &&
515 (node
->u
.rects
[i
].bounds
.Y2
> query
->Y1
))
522 /* not a leaf, recurse on lower nodes */
526 struct rtree_node
**n
;
527 for (n
= &node
->u
.kids
[0]; *n
; n
++)
529 if ((*n
)->box
.X1
>= query
->X2
||
530 (*n
)->box
.X2
<= query
->X1
||
531 (*n
)->box
.Y1
>= query
->Y2
|| (*n
)->box
.Y2
<= query
->Y1
||
532 !arg
->check_it (&(*n
)->box
, arg
->closure
))
534 seen
+= __r_search (*n
, query
, arg
);
541 struct rtree_node
**n
;
542 for (n
= &node
->u
.kids
[0]; *n
; n
++)
544 if ((*n
)->box
.X1
>= query
->X2
||
545 (*n
)->box
.X2
<= query
->X1
||
546 (*n
)->box
.Y1
>= query
->Y2
|| (*n
)->box
.Y2
<= query
->Y1
)
548 seen
+= __r_search (*n
, query
, arg
);
554 /* Parameterized search in the rtree.
555 * Returns the number of rectangles found.
556 * calls found_rectangle for each intersection seen
557 * and calls check_region with the current sub-region
558 * to see whether deeper searching is desired
561 r_search (rtree_t
* rtree
, const BoxType
* query
,
562 int (*check_region
) (const BoxType
* region
, void *cl
),
563 int (*found_rectangle
) (const BoxType
* box
, void *cl
), void *cl
)
567 if (!rtree
|| rtree
->size
< 1)
572 assert (__r_tree_is_good (rtree
->root
));
575 if (query
->X2
<= query
->X1
|| query
->Y2
<= query
->Y1
)
578 /* check this box. If it's not touched we're done here */
579 if (rtree
->root
->box
.X1
>= query
->X2
||
580 rtree
->root
->box
.X2
<= query
->X1
||
581 rtree
->root
->box
.Y1
>= query
->Y2
582 || rtree
->root
->box
.Y2
<= query
->Y1
)
584 arg
.check_it
= check_region
;
585 arg
.found_it
= found_rectangle
;
587 return __r_search (rtree
->root
, query
, &arg
);
591 arg
.check_it
= check_region
;
592 arg
.found_it
= found_rectangle
;
594 return __r_search (rtree
->root
, &rtree
->root
->box
, &arg
);
598 /*------ r_region_is_empty ------*/
600 __r_region_is_empty_rect_in_reg (const BoxType
* box
, void *cl
)
602 jmp_buf *envp
= (jmp_buf *) cl
;
603 longjmp (*envp
, 1); /* found one! */
606 /* return 0 if there are any rectangles in the given region. */
608 r_region_is_empty (rtree_t
* rtree
, const BoxType
* region
)
620 r_search (rtree
, region
, NULL
, __r_region_is_empty_rect_in_reg
, &env
);
622 assert (r
== 0); /* otherwise longjmp would have been called */
624 return 1; /* no rectangles found */
632 /* split the node into two nodes putting clusters in each
633 * use the k-means clustering algorithm
636 find_clusters (struct rtree_node
*node
)
638 float total_a
, total_b
;
639 float a_X
, a_Y
, b_X
, b_Y
;
640 bool belong
[M_SIZE
+ 1];
641 struct centroid center
[M_SIZE
+ 1];
642 int clust_a
, clust_b
, tries
;
643 int a_manage
= 0, b_manage
= 0;
644 int i
, old_ax
, old_ay
, old_bx
, old_by
;
645 struct rtree_node
*new_node
;
648 for (i
= 0; i
< M_SIZE
+ 1; i
++)
650 if (node
->flags
.is_leaf
)
651 b
= &(node
->u
.rects
[i
].bounds
);
653 b
= &(node
->u
.kids
[i
]->box
);
654 center
[i
].x
= 0.5 * (b
->X1
+ b
->X2
);
655 center
[i
].y
= 0.5 * (b
->Y1
+ b
->Y2
);
656 /* adding 1 prevents zero area */
657 center
[i
].area
= 1. + (float) (b
->X2
- b
->X1
) * (float) (b
->Y2
- b
->Y1
);
659 /* starting 'A' cluster center */
662 /* starting 'B' cluster center */
663 b_X
= center
[M_SIZE
].x
;
664 b_Y
= center
[M_SIZE
].y
;
665 /* don't allow the same cluster centers */
666 if (b_X
== a_X
&& b_Y
== a_Y
)
671 for (tries
= 0; tries
< M_SIZE
; tries
++)
677 clust_a
= clust_b
= 0;
678 for (i
= 0; i
< M_SIZE
+ 1; i
++)
682 dist1
= SQUARE (a_X
- center
[i
].x
) + SQUARE (a_Y
- center
[i
].y
);
683 dist2
= SQUARE (b_X
- center
[i
].x
) + SQUARE (b_Y
- center
[i
].y
);
684 if (dist1
* (clust_a
+ M_SIZE
/ 2) < dist2
* (clust_b
+ M_SIZE
/ 2))
695 /* kludge to fix degenerate cases */
696 if (clust_a
== M_SIZE
+ 1)
697 belong
[M_SIZE
/ 2] = false;
698 else if (clust_b
== M_SIZE
+ 1)
699 belong
[M_SIZE
/ 2] = true;
700 /* compute new center of gravity of clusters */
701 total_a
= total_b
= 0;
702 a_X
= a_Y
= b_X
= b_Y
= 0;
703 for (i
= 0; i
< M_SIZE
+ 1; i
++)
707 a_X
+= center
[i
].x
* center
[i
].area
;
708 a_Y
+= center
[i
].y
* center
[i
].area
;
709 total_a
+= center
[i
].area
;
713 b_X
+= center
[i
].x
* center
[i
].area
;
714 b_Y
+= center
[i
].y
* center
[i
].area
;
715 total_b
+= center
[i
].area
;
722 if (old_ax
== (int) a_X
&& old_ay
== (int) a_Y
&&
723 old_bx
== (int) b_X
&& old_by
== (int) b_Y
)
726 /* Now 'belong' has the partition map */
727 new_node
= (struct rtree_node
*)calloc (1, sizeof (*new_node
));
728 new_node
->parent
= node
->parent
;
729 new_node
->flags
.is_leaf
= node
->flags
.is_leaf
;
730 clust_a
= clust_b
= 0;
731 if (node
->flags
.is_leaf
)
733 int flag
, a_flag
, b_flag
;
734 flag
= a_flag
= b_flag
= 1;
735 for (i
= 0; i
< M_SIZE
+ 1; i
++)
739 node
->u
.rects
[clust_a
++] = node
->u
.rects
[i
];
740 if (node
->flags
.manage
& flag
)
746 new_node
->u
.rects
[clust_b
++] = node
->u
.rects
[i
];
747 if (node
->flags
.manage
& flag
)
756 for (i
= 0; i
< M_SIZE
+ 1; i
++)
759 node
->u
.kids
[clust_a
++] = node
->u
.kids
[i
];
762 node
->u
.kids
[i
]->parent
= new_node
;
763 new_node
->u
.kids
[clust_b
++] = node
->u
.kids
[i
];
767 node
->flags
.manage
= a_manage
;
768 new_node
->flags
.manage
= b_manage
;
769 assert (clust_a
!= 0);
770 assert (clust_b
!= 0);
771 if (node
->flags
.is_leaf
)
772 for (; clust_a
< M_SIZE
+ 1; clust_a
++)
773 node
->u
.rects
[clust_a
].bptr
= NULL
;
775 for (; clust_a
< M_SIZE
+ 1; clust_a
++)
776 node
->u
.kids
[clust_a
] = NULL
;
777 adjust_bounds (node
);
779 adjust_bounds (new_node
);
780 sort_node (new_node
);
784 /* split a node according to clusters
787 split_node (struct rtree_node
*node
)
790 struct rtree_node
*new_node
;
793 assert (node
->flags
.is_leaf
? (void *) node
->u
.rects
[M_SIZE
].
794 bptr
: (void *) node
->u
.kids
[M_SIZE
]);
795 new_node
= find_clusters (node
);
796 if (node
->parent
== NULL
) /* split root node */
798 struct rtree_node
*second
;
800 second
= (struct rtree_node
*)calloc (1, sizeof (*second
));
802 if (!second
->flags
.is_leaf
)
803 for (i
= 0; i
< M_SIZE
; i
++)
804 if (second
->u
.kids
[i
])
805 second
->u
.kids
[i
]->parent
= second
;
806 node
->flags
.is_leaf
= 0;
807 node
->flags
.manage
= 0;
808 second
->parent
= new_node
->parent
= node
;
809 node
->u
.kids
[0] = new_node
;
810 node
->u
.kids
[1] = second
;
811 for (i
= 2; i
< M_SIZE
+ 1; i
++)
812 node
->u
.kids
[i
] = NULL
;
813 adjust_bounds (node
);
816 assert (__r_tree_is_good (node
));
820 for (i
= 0; i
< M_SIZE
; i
++)
821 if (!node
->parent
->u
.kids
[i
])
823 node
->parent
->u
.kids
[i
] = new_node
;
825 assert (__r_node_is_good (node
));
826 assert (__r_node_is_good (new_node
));
831 assert (__r_node_is_good (node
->parent
));
833 sort_node (node
->parent
);
836 split_node (node
->parent
);
840 contained (struct rtree_node
*node
, const BoxType
* query
)
842 if (node
->box
.X1
> query
->X1
|| node
->box
.X2
< query
->X2
||
843 node
->box
.Y1
> query
->Y1
|| node
->box
.Y2
< query
->Y2
)
850 penalty (struct rtree_node
*node
, const BoxType
* query
)
854 /* Compute the area penalty for inserting here and return.
855 * The penalty is the increase in area necessary
856 * to include the query->
858 score
= (MAX (node
->box
.X2
, query
->X2
) - MIN (node
->box
.X1
, query
->X1
));
859 score
*= (MAX (node
->box
.Y2
, query
->Y2
) - MIN (node
->box
.Y1
, query
->Y1
));
861 (double)(node
->box
.X2
- node
->box
.X1
) *
862 (double)(node
->box
.Y2
- node
->box
.Y1
);
867 __r_insert_node (struct rtree_node
*node
, const BoxType
* query
,
868 int manage
, bool force
)
872 assert (__r_node_is_good (node
));
874 /* Ok, at this point we must already enclose the query or we're forcing
875 * this node to expand to enclose it, so if we're a leaf, simply store
879 if (node
->flags
.is_leaf
)
883 if (UNLIKELY (manage
))
885 register int flag
= 1;
887 for (i
= 0; i
< M_SIZE
; i
++)
889 if (!node
->u
.rects
[i
].bptr
)
893 node
->flags
.manage
|= flag
;
897 for (i
= 0; i
< M_SIZE
; i
++)
898 if (!node
->u
.rects
[i
].bptr
)
901 /* the node always has an extra space available */
902 node
->u
.rects
[i
].bptr
= query
;
903 node
->u
.rects
[i
].bounds
= *query
;
904 /* first entry in node determines initial bounding box */
909 MAKEMIN (node
->box
.X1
, query
->X1
);
910 MAKEMAX (node
->box
.X2
, query
->X2
);
911 MAKEMIN (node
->box
.Y1
, query
->Y1
);
912 MAKEMAX (node
->box
.Y2
, query
->Y2
);
919 /* we must split the node */
926 struct rtree_node
*best_node
;
927 double score
, best_score
;
931 MAKEMIN (node
->box
.X1
, query
->X1
);
932 MAKEMAX (node
->box
.X2
, query
->X2
);
933 MAKEMIN (node
->box
.Y1
, query
->Y1
);
934 MAKEMAX (node
->box
.Y2
, query
->Y2
);
937 /* this node encloses it, but it's not a leaf, so descend the tree */
939 /* First check if any children actually encloses it */
940 assert (node
->u
.kids
[0]);
941 for (i
= 0; i
< M_SIZE
; i
++)
943 if (!node
->u
.kids
[i
])
945 if (contained (node
->u
.kids
[i
], query
))
947 __r_insert_node (node
->u
.kids
[i
], query
, manage
, false);
953 /* see if there is room for a new leaf node */
954 if (node
->u
.kids
[0]->flags
.is_leaf
&& i
< M_SIZE
)
956 struct rtree_node
*new_node
;
957 new_node
= (struct rtree_node
*)calloc (1, sizeof (*new_node
));
958 new_node
->parent
= node
;
959 new_node
->flags
.is_leaf
= true;
960 node
->u
.kids
[i
] = new_node
;
961 new_node
->u
.rects
[0].bptr
= query
;
962 new_node
->u
.rects
[0].bounds
= *query
;
963 new_node
->box
= *query
;
964 if (UNLIKELY (manage
))
965 new_node
->flags
.manage
= 1;
970 /* Ok, so we're still here - look for the best child to push it into */
971 best_score
= penalty (node
->u
.kids
[0], query
);
972 best_node
= node
->u
.kids
[0];
973 for (i
= 1; i
< M_SIZE
; i
++)
975 if (!node
->u
.kids
[i
])
977 score
= penalty (node
->u
.kids
[i
], query
);
978 if (score
< best_score
)
981 best_node
= node
->u
.kids
[i
];
984 __r_insert_node (best_node
, query
, manage
, true);
991 r_insert_entry (rtree_t
* rtree
, const BoxType
* which
, int man
)
994 assert (which
->X1
<= which
->X2
);
995 assert (which
->Y1
<= which
->Y2
);
996 /* recursively search the tree for the best leaf node */
997 assert (rtree
->root
);
998 __r_insert_node (rtree
->root
, which
, man
,
999 rtree
->root
->box
.X1
> which
->X1
1000 || rtree
->root
->box
.X2
< which
->X2
1001 || rtree
->root
->box
.Y1
> which
->Y1
1002 || rtree
->root
->box
.Y2
< which
->Y2
);
1007 __r_delete (struct rtree_node
*node
, const BoxType
* query
)
1009 int i
, flag
, mask
, a
;
1011 /* the tree might be inconsistent during delete */
1012 if (query
->X1
< node
->box
.X1
|| query
->Y1
< node
->box
.Y1
1013 || query
->X2
> node
->box
.X2
|| query
->Y2
> node
->box
.Y2
)
1015 if (!node
->flags
.is_leaf
)
1017 for (i
= 0; i
< M_SIZE
; i
++)
1019 /* if this is us being removed, free and copy over */
1020 if (node
->u
.kids
[i
] == (struct rtree_node
*) query
)
1022 free ((void *) query
);
1023 for (; i
< M_SIZE
; i
++)
1025 node
->u
.kids
[i
] = node
->u
.kids
[i
+ 1];
1026 if (!node
->u
.kids
[i
])
1029 /* nobody home here now ? */
1030 if (!node
->u
.kids
[0])
1034 /* wow, the root is empty! */
1035 node
->flags
.is_leaf
= 1;
1036 /* changing type of node, be sure it's all zero */
1037 for (i
= 1; i
< M_SIZE
+ 1; i
++)
1038 node
->u
.rects
[i
].bptr
= NULL
;
1041 return (__r_delete (node
->parent
, &node
->box
));
1044 /* propegate boundary adjust upward */
1047 adjust_bounds (node
);
1048 node
= node
->parent
;
1052 if (node
->u
.kids
[i
])
1054 if (__r_delete (node
->u
.kids
[i
], query
))
1062 /* leaf node here */
1065 for (i
= 0; i
< M_SIZE
; i
++)
1067 #ifdef DELETE_BY_POINTER
1068 if (!node
->u
.rects
[i
].bptr
|| node
->u
.rects
[i
].bptr
== query
)
1070 if (node
->u
.rects
[i
].bounds
.X1
== query
->X1
&&
1071 node
->u
.rects
[i
].bounds
.X2
== query
->X2
&&
1072 node
->u
.rects
[i
].bounds
.Y1
== query
->Y1
&&
1073 node
->u
.rects
[i
].bounds
.Y2
== query
->Y2
)
1079 if (!node
->u
.rects
[i
].bptr
)
1080 return false; /* not at this leaf */
1081 if (node
->flags
.manage
& a
)
1083 free ((void *) node
->u
.rects
[i
].bptr
);
1084 node
->u
.rects
[i
].bptr
= NULL
;
1086 /* squeeze the manage flags together */
1087 flag
= node
->flags
.manage
& mask
;
1088 mask
= (~mask
) << 1;
1089 node
->flags
.manage
= flag
| ((node
->flags
.manage
& mask
) >> 1);
1090 /* remove the entry */
1091 for (; i
< M_SIZE
; i
++)
1093 node
->u
.rects
[i
] = node
->u
.rects
[i
+ 1];
1094 if (!node
->u
.rects
[i
].bptr
)
1097 if (!node
->u
.rects
[0].bptr
)
1100 __r_delete (node
->parent
, &node
->box
);
1104 /* propagate boundary adjustment upward */
1107 adjust_bounds (node
);
1108 node
= node
->parent
;
1114 r_delete_entry (rtree_t
* rtree
, const BoxType
* box
)
1120 r
= __r_delete (rtree
->root
, box
);
1124 assert (__r_tree_is_good (rtree
->root
));