/* * Delete a data rectangle from an index structure. * Pass in a pointer to a Rect, the tid of the record, ptr to ptr to root node. * Returns 1 if record not found, 0 if success. * RTreeDeleteRect provides for eliminating the root. */ int RTreeDeleteRect(struct Rect *R, long Tid, struct Node**Nn) { register struct Rect *r = R; register long tid = Tid; register struct Node **nn = Nn; register int i; struct Node *tmp_nptr = NULL; struct ListNode *reInsertList = NULL; register struct ListNode *e; assert(r && nn); assert(*nn); assert(tid >= 0); if (!RTreeDeleteRect2(r, tid, *nn, &reInsertList)) { /* found and deleted a data item */ /* reinsert any branches from eliminated nodes */ while (reInsertList) { tmp_nptr = reInsertList->node; for (i = 0; i < MAXKIDS(tmp_nptr); i++) { if (tmp_nptr->branch[i].child) { RTreeInsertRect( &(tmp_nptr->branch[i].rect), (long)(tmp_nptr->branch[i].child), nn, tmp_nptr->level); } } e = reInsertList; reInsertList = reInsertList->next; RTreeFreeNode(e->node); RTreeFreeListNode(e); } /* check for redundant root (not leaf, 1 child) and eliminate */ if ((*nn)->count == 1 && (*nn)->level > 0) { for (i = 0; i < NODECARD; i++) { tmp_nptr = (*nn)->branch[i].child; if(tmp_nptr) break; } assert(tmp_nptr); RTreeFreeNode(*nn); *nn = tmp_nptr; } return 0; } else { return 1; } }
/* * should be called by RTreeDeleteRect() only * * Delete a data rectangle from an index structure. * Pass in a pointer to a Rect, the tid of the record, ptr RTree. * Returns 1 if record not found, 0 if success. * RTreeDeleteRect1 provides for eliminating the root. */ int RTreeDeleteRectF(struct RTree_Rect *r, union RTree_Child child, struct RTree *t) { int i; struct RTree_Node *n; struct RTree_ListNode *e, *reInsertList = NULL; if (!RTreeDeleteRect2F(r, child, t, &reInsertList)) { /* found and deleted a data item */ /* reinsert any branches from eliminated nodes */ while (reInsertList) { t->n_nodes--; n = reInsertList->node; if (n->level > 0) { /* reinsert node branches */ for (i = 0; i < t->nodecard; i++) { if (n->branch[i].child.pos > -1) { RTreeInsertRectF(&(n->branch[i].rect), n->branch[i].child, n->level, t); } } } else { /* reinsert leaf branches */ for (i = 0; i < t->leafcard; i++) { if (n->branch[i].child.id) { RTreeInsertRectF(&(n->branch[i].rect), n->branch[i].child, n->level, t); } } } e = reInsertList; reInsertList = reInsertList->next; RTreeFreeNode(e->node); RTreeFreeListNode(e); } /* check for redundant root (not leaf, 1 child) and eliminate */ n = RTreeGetNode(t->rootpos, t->rootlevel, t); if (n->count == 1 && n->level > 0) { for (i = 0; i < t->nodecard; i++) { if (n->branch[i].child.pos > -1) break; } RTreeAddNodePos(t->rootpos, t->rootlevel, t); t->rootpos = n->branch[i].child.pos; t->rootlevel--; t->n_nodes--; } return 0; } return 1; }
/* NOTE: only needed for memory based index */ void RTreeDestroyNode(struct RTree_Node *n, int nodes) { int i; if (n->level > 0) { /* it is not leaf -> destroy childs */ for (i = 0; i < nodes; i++) { if (n->branch[i].child.ptr) { RTreeDestroyNode(n->branch[i].child.ptr, nodes); } } } /* Free this node */ RTreeFreeNode(n); return; }