| 6522 | |
| 6523 | |
| 6524 | static contents remove_node(thread_db* tdbb, index_insertion* insertion, WIN* window) |
| 6525 | { |
| 6526 | /************************************** |
| 6527 | * |
| 6528 | * r e m o v e _ n o d e |
| 6529 | * |
| 6530 | ************************************** |
| 6531 | * |
| 6532 | * Functional description |
| 6533 | * Remove an index node from a b-tree, |
| 6534 | * recursing down through the levels in case |
| 6535 | * we need to garbage collect pages. |
| 6536 | * |
| 6537 | **************************************/ |
| 6538 | |
| 6539 | SET_TDBB(tdbb); |
| 6540 | //const Database* dbb = tdbb->getDatabase(); |
| 6541 | index_desc* idx = insertion->iib_descriptor; |
| 6542 | btree_page* page = (btree_page*) window->win_buffer; |
| 6543 | |
| 6544 | // if we are on a leaf page, remove the leaf node |
| 6545 | if (page->btr_level == 0) { |
| 6546 | return remove_leaf_node(tdbb, insertion, window); |
| 6547 | } |
| 6548 | |
| 6549 | while (true) |
| 6550 | { |
| 6551 | const ULONG number = find_page(page, insertion->iib_key, idx, insertion->iib_number); |
| 6552 | |
| 6553 | // we should always find the node, but let's make sure |
| 6554 | if (number == END_LEVEL) |
| 6555 | { |
| 6556 | CCH_RELEASE(tdbb, window); |
| 6557 | #ifdef DEBUG_BTR |
| 6558 | CORRUPT(204); // msg 204 index inconsistent |
| 6559 | #endif |
| 6560 | return contents_above_threshold; |
| 6561 | } |
| 6562 | |
| 6563 | // recurse to the next level down; if we are about to fetch a |
| 6564 | // level 0 page, make sure we fetch it for write |
| 6565 | if (number != END_BUCKET) |
| 6566 | { |
| 6567 | |
| 6568 | // handoff down to the next level, retaining the parent page number |
| 6569 | const ULONG parent_number = window->win_page.getPageNum(); |
| 6570 | page = (btree_page*) CCH_HANDOFF(tdbb, window, number, (SSHORT) |
| 6571 | ((page->btr_level == 1) ? LCK_write : LCK_read), pag_index); |
| 6572 | |
| 6573 | // if the removed node caused the page to go below the garbage collection |
| 6574 | // threshold, and the database was created by a version of the engine greater |
| 6575 | // than 8.2, then we can garbage-collect the page |
| 6576 | const contents result = remove_node(tdbb, insertion, window); |
| 6577 | |
| 6578 | if (result != contents_above_threshold) |
| 6579 | return garbage_collect(tdbb, window, parent_number); |
| 6580 | |
| 6581 | if (window->win_bdb) |
no test coverage detected