Index: trunk/src/rtree.c =================================================================== --- trunk/src/rtree.c (revision 13906) +++ trunk/src/rtree.c (revision 13907) @@ -373,8 +373,6 @@ for (i = 0; i < M_SIZE; i++) { if (!node->u.rects[i].bptr) break; - if (node->flags.manage & flag) - free((void *) node->u.rects[i].bptr); flag = flag << 1; } else @@ -387,14 +385,39 @@ } /* free the memory associated with an rtree. */ -void pcb_r_destroy_tree(pcb_rtree_t ** rtree) +void pcb_r_destroy_tree(pcb_rtree_t **rtree) { - __r_destroy_tree((*rtree)->root); free(*rtree); *rtree = NULL; } +static void pcb_r_free_tree_data_(struct rtree_node *node, void (*free)(void *ptr)) +{ + int i; + + if (node->flags.is_leaf) { + for (i = 0; i < M_SIZE; i++) { + if (!node->u.rects[i].bptr) + break; + free((void *) node->u.rects[i].bptr); + node->u.rects[i].bptr = NULL; + } + } + else { + for (i = 0; i < M_SIZE; i++) { + if (!node->u.kids[i]) + break; + pcb_r_free_tree_data_(node->u.kids[i], free); + } + } +} + +void pcb_r_free_tree_data(pcb_rtree_t *rtree, void (*free)(void *ptr)) +{ + pcb_r_free_tree_data_(rtree->root, free); +} + typedef struct { pcb_r_dir_t (*check_it) (const pcb_box_t * region, void *cl); pcb_r_dir_t (*found_it) (const pcb_box_t * box, void *cl); @@ -898,7 +921,7 @@ rtree->size++; } -pcb_bool __r_delete(struct rtree_node *node, const pcb_box_t * query) +pcb_bool __r_delete_free_data(struct rtree_node *node, const pcb_box_t * query, void (*free_data)(void *data)) { int i, flag, mask, a; @@ -925,7 +948,7 @@ node->u.rects[i].bptr = NULL; return pcb_true; } - return (__r_delete(node->parent, &node->box)); + return __r_delete_free_data(node->parent, &node->box, free_data); } else /* propagate boundary adjust upward */ @@ -936,7 +959,7 @@ return pcb_true; } if (node->u.kids[i]) { - if (__r_delete(node->u.kids[i], query)) + if (__r_delete_free_data(node->u.kids[i], query, free_data)) return pcb_true; } else @@ -961,8 +984,8 @@ } if (!node->u.rects[i].bptr) return pcb_false; /* not at this leaf */ - if (node->flags.manage & a) { - free((void *) node->u.rects[i].bptr); + if (free_data != NULL) { + free_data((void *) node->u.rects[i].bptr); node->u.rects[i].bptr = NULL; } /* squeeze the manage flags together */ @@ -977,7 +1000,7 @@ } if (!node->u.rects[0].bptr) { if (node->parent) - __r_delete(node->parent, &node->box); + __r_delete_free_data(node->parent, &node->box, free_data); return pcb_true; } else @@ -989,13 +1012,18 @@ return pcb_true; } -pcb_bool pcb_r_delete_entry(pcb_rtree_t * rtree, const pcb_box_t * box) +pcb_bool __r_delete(struct rtree_node *node, const pcb_box_t * query) { + return __r_delete_free_data(node, query, NULL); +} + +pcb_bool pcb_r_delete_entry_free_data(pcb_rtree_t * rtree, const pcb_box_t * box, void (*free_data)(void *d)) +{ pcb_bool r; assert(box); assert(rtree); - r = __r_delete(rtree->root, box); + r = __r_delete_free_data(rtree->root, box, free_data); if (r) rtree->size--; #ifdef SLOW_ASSERTS @@ -1004,7 +1032,12 @@ return r; } +pcb_bool pcb_r_delete_entry(pcb_rtree_t * rtree, const pcb_box_t * box) +{ + return pcb_r_delete_entry_free_data(rtree, box, NULL); +} + static pcb_box_t *pcb_r_next_(pcb_rtree_it_t *it, struct rtree_node *curr) { int n; Index: trunk/src/rtree.h =================================================================== --- trunk/src/rtree.h (revision 13906) +++ trunk/src/rtree.h (revision 13907) @@ -70,8 +70,15 @@ void pcb_r_create_insert_array(pcb_rtree_t *rtree, const pcb_box_t *boxlist[], int N, int manage); pcb_bool pcb_r_delete_entry(pcb_rtree_t * rtree, const pcb_box_t * which); + +/* also free leaf data using free_data() */ +pcb_bool __r_delete_free_data(struct rtree_node *node, const pcb_box_t * query, void (*free_data)(void *data)); +pcb_bool pcb_r_delete_entry_free_data(pcb_rtree_t * rtree, const pcb_box_t * box, void (*free_data)(void *d)); + + void pcb_r_insert_entry(pcb_rtree_t * rtree, const pcb_box_t * which, int manage); + /* generic search routine */ /* region_in_search should return pcb_true if "what you're looking for" is * within the specified region; regions, like rectangles, are closed on @@ -111,5 +118,7 @@ /* Free fields of the iterator */ void pcb_r_end(pcb_rtree_it_t *it); +/* Recursively call free() on all leaf data */ +void pcb_r_free_tree_data(pcb_rtree_t *rtree, void (*free)(void *ptr)); #endif Index: trunk/src_plugins/autoplace/autoplace.c =================================================================== --- trunk/src_plugins/autoplace/autoplace.c (revision 13906) +++ trunk/src_plugins/autoplace/autoplace.c (revision 13907) @@ -610,9 +610,9 @@ PCB_END_LOOP; rt_s = pcb_r_create_tree(); - pcb_r_create_insert_array(rt_s, (const pcb_box_t **) seboxes.array, vtp0_len(&seboxes), 1); + pcb_r_create_insert_array(rt_s, (const pcb_box_t **) seboxes.array, vtp0_len(&seboxes), 0); rt_c = pcb_r_create_tree(); - pcb_r_create_insert_array(rt_c, (const pcb_box_t **) ceboxes.array, vtp0_len(&ceboxes), 1); + pcb_r_create_insert_array(rt_c, (const pcb_box_t **) ceboxes.array, vtp0_len(&ceboxes), 0); vtp0_uninit(&seboxes); vtp0_uninit(&ceboxes); /* now, for each element, find its neighbor on all four sides */ @@ -676,6 +676,8 @@ PCB_END_LOOP; } /* free k-d tree memory */ + pcb_r_free_tree_data(rt_s, free); + pcb_r_free_tree_data(rt_c, free); pcb_r_destroy_tree(&rt_s); pcb_r_destroy_tree(&rt_c); } Index: trunk/src_plugins/autoroute/autoroute.c =================================================================== --- trunk/src_plugins/autoroute/autoroute.c (revision 13906) +++ trunk/src_plugins/autoroute/autoroute.c (revision 13907) @@ -1277,7 +1277,7 @@ for (i = 0; i < pcb_max_group(PCB); i++) { /* create the r-tree */ rd->layergrouptree[i] = pcb_r_create_tree(); - pcb_r_create_insert_array(rd->layergrouptree[i], (const pcb_box_t **) layergroupboxes[i].array, vtp0_len(&layergroupboxes[i]), 1); + pcb_r_create_insert_array(rd->layergrouptree[i], (const pcb_box_t **) layergroupboxes[i].array, vtp0_len(&layergroupboxes[i]), 0); } if (AutoRouteParameters.use_vias) { @@ -1305,8 +1305,10 @@ void DestroyRouteData(routedata_t ** rd) { int i; - for (i = 0; i < pcb_max_group(PCB); i++) + for (i = 0; i < pcb_max_group(PCB); i++) { + pcb_r_free_tree_data((*rd)->layergrouptree[i], free); pcb_r_destroy_tree(&(*rd)->layergrouptree[i]); + } if (AutoRouteParameters.use_vias) mtspace_destroy(&(*rd)->mtspace); /* free((*rd)->layergrouptree);*/ @@ -3002,7 +3004,7 @@ MergeNets(rb, subnet, NET); MergeNets(rb, subnet, SUBNET); /* add it to the r-tree, this may be the whole route! */ - pcb_r_insert_entry(rd->layergrouptree[rb->group], &rb->box, 1); + pcb_r_insert_entry(rd->layergrouptree[rb->group], &rb->box, 0); rb->flags.homeless = 0; } @@ -3054,7 +3056,7 @@ MergeNets(rb, subnet, SUBNET); assert(__routepcb_box_is_good(rb)); /* and add it to the r-tree! */ - pcb_r_insert_entry(rd->layergrouptree[rb->group], &rb->box, 1); + pcb_r_insert_entry(rd->layergrouptree[rb->group], &rb->box, 0); rb->flags.homeless = 0; /* not homeless anymore */ rb->livedraw_obj.via = live_via; } @@ -3138,7 +3140,7 @@ MergeNets(rb, qsn, SUBNET); assert(__routepcb_box_is_good(rb)); /* and add it to the r-tree! */ - pcb_r_insert_entry(rd->layergrouptree[rb->group], &rb->box, 1); + pcb_r_insert_entry(rd->layergrouptree[rb->group], &rb->box, 0); if (conf_core.editor.live_routing) { pcb_layer_t *layer = LAYER_PTR(PCB->LayerGroups.grp[rb->group].lid[0]); @@ -3951,7 +3953,7 @@ /*assert (!pcb_r_search(rd->layergrouptree[e->rb->group], &e->rb->box, NULL, no_planes,0)); */ - pcb_r_insert_entry(rd->layergrouptree[e->rb->group], &e->rb->box, 1); + pcb_r_insert_entry(rd->layergrouptree[e->rb->group], &e->rb->box, 0); e->rb->flags.homeless = 0; /* not homeless any more */ /* add to vector of all expansion areas in r-tree */ vector_append(area_vec, e->rb); @@ -4088,7 +4090,7 @@ if (!pcb_box_is_good(&ans->inflated)) goto dontexpand; nrb = CreateExpansionArea(&ans->inflated, e->rb->group, e->rb, pcb_true, e); - pcb_r_insert_entry(rd->layergrouptree[nrb->group], &nrb->box, 1); + pcb_r_insert_entry(rd->layergrouptree[nrb->group], &nrb->box, 0); vector_append(area_vec, nrb); nrb->flags.homeless = 0; /* not homeless any more */ broken = BreakManyEdges(&s, targets, rd->layergrouptree[nrb->group], area_vec, ans, nrb, e); @@ -4161,7 +4163,7 @@ assert(!rb->flags.homeless); if (rb->conflicts_with && rb->parent.expansion_area->conflicts_with != rb->conflicts_with) vector_destroy(&rb->conflicts_with); - pcb_r_delete_entry(rd->layergrouptree[rb->group], &rb->box); + pcb_r_delete_entry_free_data(rd->layergrouptree[rb->group], &rb->box, free); } vector_destroy(&area_vec); /* clean up; remove all 'source', 'target', and 'nobloat' flags */ @@ -4377,7 +4379,7 @@ #ifndef NDEBUG del = #endif - pcb_r_delete_entry(rd->layergrouptree[p->group], &p->box); + pcb_r_delete_entry_free_data(rd->layergrouptree[p->group], &p->box, free); #ifndef NDEBUG assert(del); #endif