| 2639 | |
| 2640 | |
| 2641 | static ULONG add_node(thread_db* tdbb, |
| 2642 | WIN* window, |
| 2643 | index_insertion* insertion, |
| 2644 | temporary_key* new_key, |
| 2645 | RecordNumber* new_record_number, |
| 2646 | ULONG* original_page, |
| 2647 | ULONG* sibling_page) |
| 2648 | { |
| 2649 | /************************************** |
| 2650 | * |
| 2651 | * a d d _ n o d e |
| 2652 | * |
| 2653 | ************************************** |
| 2654 | * |
| 2655 | * Functional description |
| 2656 | * Insert a node in an index. This recurses to the leaf level. |
| 2657 | * If a split occurs, return the new index page number and its |
| 2658 | * leading string. |
| 2659 | * |
| 2660 | **************************************/ |
| 2661 | |
| 2662 | SET_TDBB(tdbb); |
| 2663 | btree_page* bucket = (btree_page*) window->win_buffer; |
| 2664 | |
| 2665 | // For leaf level guys, loop thru the leaf buckets until insertion |
| 2666 | // point is found (should be instant) |
| 2667 | if (bucket->btr_level == insertion->iib_btr_level) |
| 2668 | { |
| 2669 | while (true) |
| 2670 | { |
| 2671 | const ULONG split = insert_node(tdbb, window, insertion, new_key, |
| 2672 | new_record_number, original_page, sibling_page); |
| 2673 | |
| 2674 | if (split != NO_VALUE_PAGE) |
| 2675 | return split; |
| 2676 | |
| 2677 | bucket = (btree_page*) CCH_HANDOFF(tdbb, window, bucket->btr_sibling, LCK_write, pag_index); |
| 2678 | } |
| 2679 | } |
| 2680 | |
| 2681 | // If we're above the leaf level, find the appropriate node in the chain of sibling pages. |
| 2682 | // Hold on to this position while we recurse down to the next level, in case there's a |
| 2683 | // split at the lower level, in which case we need to insert the new page at this level. |
| 2684 | ULONG page; |
| 2685 | while (true) |
| 2686 | { |
| 2687 | page = find_page(bucket, insertion->iib_key, insertion->iib_descriptor, |
| 2688 | insertion->iib_number); |
| 2689 | |
| 2690 | if (page != END_BUCKET) |
| 2691 | break; |
| 2692 | |
| 2693 | bucket = (btree_page*) CCH_HANDOFF(tdbb, window, bucket->btr_sibling, LCK_read, pag_index); |
| 2694 | } |
| 2695 | |
| 2696 | BtrPageGCLock lockCurrent(tdbb); |
| 2697 | lockCurrent.disablePageGC(tdbb, window->win_page); |
| 2698 |
no test coverage detected