| 3676 | |
| 3677 | |
| 3678 | static void delete_tree(thread_db* tdbb, |
| 3679 | USHORT rel_id, USHORT idx_id, PageNumber next, PageNumber prior) |
| 3680 | { |
| 3681 | /************************************** |
| 3682 | * |
| 3683 | * d e l e t e _ t r e e |
| 3684 | * |
| 3685 | ************************************** |
| 3686 | * |
| 3687 | * Functional description |
| 3688 | * Release index pages back to free list. |
| 3689 | * |
| 3690 | **************************************/ |
| 3691 | |
| 3692 | SET_TDBB(tdbb); |
| 3693 | WIN window(next.getPageSpaceID(), -1); |
| 3694 | window.win_flags = WIN_large_scan; |
| 3695 | window.win_scans = 1; |
| 3696 | |
| 3697 | ULONG down = next.getPageNum(); |
| 3698 | // Delete the index tree from the top down. |
| 3699 | while (next.getPageNum()) |
| 3700 | { |
| 3701 | window.win_page = next; |
| 3702 | btree_page* page = (btree_page*) CCH_FETCH(tdbb, &window, LCK_write, 0); |
| 3703 | |
| 3704 | // do a little defensive programming--if any of these conditions |
| 3705 | // are true we have a damaged pointer, so just stop deleting. At |
| 3706 | // the same time, allow updates of indexes with id > 255 even though |
| 3707 | // the page header uses a byte for its index id. This requires relaxing |
| 3708 | // the check slightly introducing a risk that we'll pick up a page belonging |
| 3709 | // to some other index that is ours +/- (256*n). On the whole, unlikely. |
| 3710 | if (page->btr_header.pag_type != pag_index || |
| 3711 | page->btr_id != (UCHAR)(idx_id % 256) || page->btr_relation != rel_id) |
| 3712 | { |
| 3713 | CCH_RELEASE(tdbb, &window); |
| 3714 | return; |
| 3715 | } |
| 3716 | |
| 3717 | // if we are at the beginning of a non-leaf level, position |
| 3718 | // "down" to the beginning of the next level down |
| 3719 | if (next.getPageNum() == down) |
| 3720 | { |
| 3721 | if (page->btr_level) |
| 3722 | { |
| 3723 | UCHAR* pointer = page->btr_nodes + page->btr_jump_size; |
| 3724 | IndexNode pageNode; |
| 3725 | pageNode.readNode(pointer, false); |
| 3726 | down = pageNode.pageNumber; |
| 3727 | } |
| 3728 | else |
| 3729 | down = 0; |
| 3730 | } |
| 3731 | |
| 3732 | // go through all the sibling pages on this level and release them |
| 3733 | next = page->btr_sibling; |
| 3734 | CCH_RELEASE_TAIL(tdbb, &window); |
| 3735 | PAG_release_page(tdbb, window.win_page, prior); |
no test coverage detected