int RTreeInsert(RTree_t * rtp, Rect_t * r, void *data, Node_t ** n, int level) { /* RTreeInsert(RTree_t*rtp, Rect_t*r, int data, Node_t**n, int level) { */ register int i; register Node_t *newroot; Node_t *newnode=0; Branch_t b; int result = 0; assert(r && n); assert(level >= 0 && level <= (*n)->level); for (i = 0; i < NUMDIMS; i++) assert(r->boundary[i] <= r->boundary[NUMDIMS + i]); # ifdef RTDEBUG fprintf(stderr, "RTreeInsert level=%d\n", level); # endif if (rtp->StatFlag) { if (rtp->Deleting) rtp->ReInsertCount++; else rtp->InsertCount++; } if (!rtp->Deleting) rtp->RectCount++; if (RTreeInsert2(rtp, r, data, *n, &newnode, level)) { /* root was split */ if (rtp->StatFlag) { if (rtp->Deleting) rtp->DeTouchCount++; else rtp->InTouchCount++; } newroot = RTreeNewNode(rtp); /* grow a new root, make tree taller */ rtp->NonLeafCount++; newroot->level = (*n)->level + 1; b.rect = NodeCover(*n); b.child = *n; AddBranch(rtp, &b, newroot, NULL); b.rect = NodeCover(newnode); b.child = newnode; AddBranch(rtp, &b, newroot, NULL); *n = newroot; // rtp->root = newroot; rtp->EntryCount += 2; result = 1; } return result; }
RTREE_TEMPLATE bool RTREE_QUAL::RemoveRectRec(Rect* a_rect, const DATATYPE& a_id, Node* a_node, ListNode** a_listNode) { ASSERT(a_rect && a_node && a_listNode); ASSERT(a_node->m_level >= 0); if (a_node->IsInternalNode()) // not a leaf node { for (int index = 0; index < a_node->m_count; ++index) { if (Overlap(a_rect, &(a_node->m_branch[index].m_rect))) { if (!RemoveRectRec(a_rect, a_id, a_node->m_branch[index].m_child, a_listNode)) { if (a_node->m_branch[index].m_child->m_count >= MINNODES) { // child removed, just resize parent rect a_node->m_branch[index].m_rect = NodeCover(a_node->m_branch[index].m_child); } else { // child removed, not enough entries in node, eliminate node ReInsert(a_node->m_branch[index].m_child, a_listNode); DisconnectBranch(a_node, index); // Must return after this call as count has changed } return false; } } } return true; } else // A leaf node { for (int index = 0; index < a_node->m_count; ++index) { if (a_node->m_branch[index].m_data == a_id) { DisconnectBranch(a_node, index); // Must return after this call as count has changed return false; } } return true; } }
RTREE_TEMPLATE bool RTREE_QUAL::InsertRectRec(const Branch& a_branch, Node* a_node, Node** a_newNode, int a_level) { ASSERT(a_node && a_newNode); ASSERT(a_level >= 0 && a_level <= a_node->m_level); // recurse until we reach the correct level for the new record. data records // will always be called with a_level == 0 (leaf) if (a_node->m_level > a_level) { // Still above level for insertion, go down tree recursively Node* otherNode; // find the optimal branch for this record int index = PickBranch(&a_branch.m_rect, a_node); // recursively insert this record into the picked branch bool childWasSplit = InsertRectRec(a_branch, a_node->m_branch[index].m_child, &otherNode, a_level); if (!childWasSplit) { // Child was not split. Merge the bounding box of the new record with the // existing bounding box a_node->m_branch[index].m_rect = CombineRect(&a_branch.m_rect, &(a_node->m_branch[index].m_rect)); return false; } else { // Child was split. The old branches are now re-partitioned to two nodes // so we have to re-calculate the bounding boxes of each node a_node->m_branch[index].m_rect = NodeCover(a_node->m_branch[index].m_child); Branch branch; branch.m_child = otherNode; branch.m_rect = NodeCover(otherNode); // The old node is already a child of a_node. Now add the newly-created // node to a_node as well. a_node might be split because of that. return AddBranch(&branch, a_node, a_newNode); } } else if (a_node->m_level == a_level) { // We have reached level for insertion. Add rect, split if necessary return AddBranch(&a_branch, a_node, a_newNode); } else { // Should never occur ASSERT(0); return false; } }
RTREE_TEMPLATE bool RTREE_QUAL::InsertRect(const Branch& a_branch, Node** a_root, int a_level) { ASSERT(a_root); ASSERT(a_level >= 0 && a_level <= (*a_root)->m_level); #ifdef _DEBUG for (int index = 0; index < NUMDIMS; ++index) { ASSERT(a_branch.m_rect.m_min[index] <= a_branch.m_rect.m_max[index]); } #endif //_DEBUG Node* newNode; if (InsertRectRec(a_branch, *a_root, &newNode, a_level)) // Root split { // Grow tree taller and new root Node* newRoot = AllocNode(); newRoot->m_level = (*a_root)->m_level + 1; Branch branch; // add old root node as a child of the new root branch.m_rect = NodeCover(*a_root); branch.m_child = *a_root; AddBranch(&branch, newRoot, NULL); // add the split node as a child of the new root branch.m_rect = NodeCover(newNode); branch.m_child = newNode; AddBranch(&branch, newRoot, NULL); // set the new root as the root node *a_root = newRoot; return true; } return false; }