|
1 | 1 | /*****************************************************************************
|
2 | 2 |
|
3 | 3 | Copyright (c) 2016, 2018, Oracle and/or its affiliates. All Rights Reserved.
|
4 |
| -Copyright (c) 2017, 2018, MariaDB Corporation. |
| 4 | +Copyright (c) 2017, 2020, MariaDB Corporation. |
5 | 5 |
|
6 | 6 | This program is free software; you can redistribute it and/or modify it under
|
7 | 7 | the terms of the GNU General Public License as published by the Free Software
|
@@ -686,6 +686,121 @@ rtr_page_get_father(
|
686 | 686 | mem_heap_free(heap);
|
687 | 687 | }
|
688 | 688 |
|
| 689 | +/********************************************************************//** |
| 690 | +Returns the upper level node pointer to a R-Tree page. It is assumed |
| 691 | +that mtr holds an x-latch on the tree. */ |
| 692 | +static void rtr_get_father_node( |
| 693 | + dict_index_t* index, /*!< in: index */ |
| 694 | + ulint level, /*!< in: the tree level of search */ |
| 695 | + const dtuple_t* tuple, /*!< in: data tuple; NOTE: n_fields_cmp in |
| 696 | + tuple must be set so that it cannot get |
| 697 | + compared to the node ptr page number field! */ |
| 698 | + btr_cur_t* sea_cur,/*!< in: search cursor */ |
| 699 | + btr_cur_t* btr_cur,/*!< in/out: tree cursor; the cursor page is |
| 700 | + s- or x-latched, but see also above! */ |
| 701 | + ulint page_no,/*!< Current page no */ |
| 702 | + mtr_t* mtr) /*!< in: mtr */ |
| 703 | +{ |
| 704 | + mem_heap_t* heap = NULL; |
| 705 | + bool ret = false; |
| 706 | + const rec_t* rec; |
| 707 | + ulint n_fields; |
| 708 | + bool new_rtr = false; |
| 709 | + |
| 710 | + /* Try to optimally locate the parent node. Level should always |
| 711 | + less than sea_cur->tree_height unless the root is splitting */ |
| 712 | + if (sea_cur && sea_cur->tree_height > level) { |
| 713 | + |
| 714 | + ut_ad(mtr_memo_contains_flagged(mtr, |
| 715 | + dict_index_get_lock(index), |
| 716 | + MTR_MEMO_X_LOCK |
| 717 | + | MTR_MEMO_SX_LOCK)); |
| 718 | + ret = rtr_cur_restore_position( |
| 719 | + BTR_CONT_MODIFY_TREE, sea_cur, level, mtr); |
| 720 | + |
| 721 | + /* Once we block shrink tree nodes while there are |
| 722 | + active search on it, this optimal locating should always |
| 723 | + succeeds */ |
| 724 | + ut_ad(ret); |
| 725 | + |
| 726 | + if (ret) { |
| 727 | + btr_pcur_t* r_cursor = rtr_get_parent_cursor( |
| 728 | + sea_cur, level, false); |
| 729 | + |
| 730 | + rec = btr_pcur_get_rec(r_cursor); |
| 731 | + |
| 732 | + ut_ad(r_cursor->rel_pos == BTR_PCUR_ON); |
| 733 | + page_cur_position(rec, |
| 734 | + btr_pcur_get_block(r_cursor), |
| 735 | + btr_cur_get_page_cur(btr_cur)); |
| 736 | + btr_cur->rtr_info = sea_cur->rtr_info; |
| 737 | + btr_cur->tree_height = sea_cur->tree_height; |
| 738 | + ut_ad(rtr_compare_cursor_rec( |
| 739 | + index, btr_cur, page_no, &heap)); |
| 740 | + goto func_exit; |
| 741 | + } |
| 742 | + } |
| 743 | + |
| 744 | + /* We arrive here in one of two scenario |
| 745 | + 1) check table and btr_valide |
| 746 | + 2) index root page being raised */ |
| 747 | + ut_ad(!sea_cur || sea_cur->tree_height == level); |
| 748 | + |
| 749 | + if (btr_cur->rtr_info) { |
| 750 | + rtr_clean_rtr_info(btr_cur->rtr_info, true); |
| 751 | + } else { |
| 752 | + new_rtr = true; |
| 753 | + } |
| 754 | + |
| 755 | + btr_cur->rtr_info = rtr_create_rtr_info(false, false, btr_cur, index); |
| 756 | + |
| 757 | + if (sea_cur && sea_cur->tree_height == level) { |
| 758 | + /* root split, and search the new root */ |
| 759 | + btr_cur_search_to_nth_level( |
| 760 | + index, level, tuple, PAGE_CUR_RTREE_LOCATE, |
| 761 | + BTR_CONT_MODIFY_TREE, btr_cur, 0, |
| 762 | + __FILE__, __LINE__, mtr); |
| 763 | + |
| 764 | + } else { |
| 765 | + /* btr_validate */ |
| 766 | + ut_ad(level >= 1); |
| 767 | + ut_ad(!sea_cur); |
| 768 | + |
| 769 | + btr_cur_search_to_nth_level( |
| 770 | + index, level, tuple, PAGE_CUR_RTREE_LOCATE, |
| 771 | + BTR_CONT_MODIFY_TREE, btr_cur, 0, |
| 772 | + __FILE__, __LINE__, mtr); |
| 773 | + |
| 774 | + rec = btr_cur_get_rec(btr_cur); |
| 775 | + n_fields = dtuple_get_n_fields_cmp(tuple); |
| 776 | + |
| 777 | + if (page_rec_is_infimum(rec) |
| 778 | + || (btr_cur->low_match != n_fields)) { |
| 779 | + ret = rtr_pcur_getnext_from_path( |
| 780 | + tuple, PAGE_CUR_RTREE_LOCATE, btr_cur, |
| 781 | + level, BTR_CONT_MODIFY_TREE, |
| 782 | + true, mtr); |
| 783 | + |
| 784 | + ut_ad(ret && btr_cur->low_match == n_fields); |
| 785 | + } |
| 786 | + } |
| 787 | + |
| 788 | + ret = rtr_compare_cursor_rec( |
| 789 | + index, btr_cur, page_no, &heap); |
| 790 | + |
| 791 | + ut_ad(ret); |
| 792 | + |
| 793 | +func_exit: |
| 794 | + if (heap) { |
| 795 | + mem_heap_free(heap); |
| 796 | + } |
| 797 | + |
| 798 | + if (new_rtr && btr_cur->rtr_info) { |
| 799 | + rtr_clean_rtr_info(btr_cur->rtr_info, true); |
| 800 | + btr_cur->rtr_info = NULL; |
| 801 | + } |
| 802 | +} |
| 803 | + |
689 | 804 | /** Returns the upper level node pointer to a R-Tree page. It is assumed
|
690 | 805 | that mtr holds an SX-latch or X-latch on the tree.
|
691 | 806 | @return rec_get_offsets() of the node pointer record */
|
@@ -806,123 +921,6 @@ rtr_page_get_father_block(
|
806 | 921 | cursor, mtr));
|
807 | 922 | }
|
808 | 923 |
|
809 |
| -/********************************************************************//** |
810 |
| -Returns the upper level node pointer to a R-Tree page. It is assumed |
811 |
| -that mtr holds an x-latch on the tree. */ |
812 |
| -void |
813 |
| -rtr_get_father_node( |
814 |
| -/*================*/ |
815 |
| - dict_index_t* index, /*!< in: index */ |
816 |
| - ulint level, /*!< in: the tree level of search */ |
817 |
| - const dtuple_t* tuple, /*!< in: data tuple; NOTE: n_fields_cmp in |
818 |
| - tuple must be set so that it cannot get |
819 |
| - compared to the node ptr page number field! */ |
820 |
| - btr_cur_t* sea_cur,/*!< in: search cursor */ |
821 |
| - btr_cur_t* btr_cur,/*!< in/out: tree cursor; the cursor page is |
822 |
| - s- or x-latched, but see also above! */ |
823 |
| - ulint page_no,/*!< Current page no */ |
824 |
| - mtr_t* mtr) /*!< in: mtr */ |
825 |
| -{ |
826 |
| - mem_heap_t* heap = NULL; |
827 |
| - bool ret = false; |
828 |
| - const rec_t* rec; |
829 |
| - ulint n_fields; |
830 |
| - bool new_rtr = false; |
831 |
| - |
832 |
| - /* Try to optimally locate the parent node. Level should always |
833 |
| - less than sea_cur->tree_height unless the root is splitting */ |
834 |
| - if (sea_cur && sea_cur->tree_height > level) { |
835 |
| - |
836 |
| - ut_ad(mtr_memo_contains_flagged(mtr, |
837 |
| - dict_index_get_lock(index), |
838 |
| - MTR_MEMO_X_LOCK |
839 |
| - | MTR_MEMO_SX_LOCK)); |
840 |
| - ret = rtr_cur_restore_position( |
841 |
| - BTR_CONT_MODIFY_TREE, sea_cur, level, mtr); |
842 |
| - |
843 |
| - /* Once we block shrink tree nodes while there are |
844 |
| - active search on it, this optimal locating should always |
845 |
| - succeeds */ |
846 |
| - ut_ad(ret); |
847 |
| - |
848 |
| - if (ret) { |
849 |
| - btr_pcur_t* r_cursor = rtr_get_parent_cursor( |
850 |
| - sea_cur, level, false); |
851 |
| - |
852 |
| - rec = btr_pcur_get_rec(r_cursor); |
853 |
| - |
854 |
| - ut_ad(r_cursor->rel_pos == BTR_PCUR_ON); |
855 |
| - page_cur_position(rec, |
856 |
| - btr_pcur_get_block(r_cursor), |
857 |
| - btr_cur_get_page_cur(btr_cur)); |
858 |
| - btr_cur->rtr_info = sea_cur->rtr_info; |
859 |
| - btr_cur->tree_height = sea_cur->tree_height; |
860 |
| - ut_ad(rtr_compare_cursor_rec( |
861 |
| - index, btr_cur, page_no, &heap)); |
862 |
| - goto func_exit; |
863 |
| - } |
864 |
| - } |
865 |
| - |
866 |
| - /* We arrive here in one of two scenario |
867 |
| - 1) check table and btr_valide |
868 |
| - 2) index root page being raised */ |
869 |
| - ut_ad(!sea_cur || sea_cur->tree_height == level); |
870 |
| - |
871 |
| - if (btr_cur->rtr_info) { |
872 |
| - rtr_clean_rtr_info(btr_cur->rtr_info, true); |
873 |
| - } else { |
874 |
| - new_rtr = true; |
875 |
| - } |
876 |
| - |
877 |
| - btr_cur->rtr_info = rtr_create_rtr_info(false, false, btr_cur, index); |
878 |
| - |
879 |
| - if (sea_cur && sea_cur->tree_height == level) { |
880 |
| - /* root split, and search the new root */ |
881 |
| - btr_cur_search_to_nth_level( |
882 |
| - index, level, tuple, PAGE_CUR_RTREE_LOCATE, |
883 |
| - BTR_CONT_MODIFY_TREE, btr_cur, 0, |
884 |
| - __FILE__, __LINE__, mtr); |
885 |
| - |
886 |
| - } else { |
887 |
| - /* btr_validate */ |
888 |
| - ut_ad(level >= 1); |
889 |
| - ut_ad(!sea_cur); |
890 |
| - |
891 |
| - btr_cur_search_to_nth_level( |
892 |
| - index, level, tuple, PAGE_CUR_RTREE_LOCATE, |
893 |
| - BTR_CONT_MODIFY_TREE, btr_cur, 0, |
894 |
| - __FILE__, __LINE__, mtr); |
895 |
| - |
896 |
| - rec = btr_cur_get_rec(btr_cur); |
897 |
| - n_fields = dtuple_get_n_fields_cmp(tuple); |
898 |
| - |
899 |
| - if (page_rec_is_infimum(rec) |
900 |
| - || (btr_cur->low_match != n_fields)) { |
901 |
| - ret = rtr_pcur_getnext_from_path( |
902 |
| - tuple, PAGE_CUR_RTREE_LOCATE, btr_cur, |
903 |
| - level, BTR_CONT_MODIFY_TREE, |
904 |
| - true, mtr); |
905 |
| - |
906 |
| - ut_ad(ret && btr_cur->low_match == n_fields); |
907 |
| - } |
908 |
| - } |
909 |
| - |
910 |
| - ret = rtr_compare_cursor_rec( |
911 |
| - index, btr_cur, page_no, &heap); |
912 |
| - |
913 |
| - ut_ad(ret); |
914 |
| - |
915 |
| -func_exit: |
916 |
| - if (heap) { |
917 |
| - mem_heap_free(heap); |
918 |
| - } |
919 |
| - |
920 |
| - if (new_rtr && btr_cur->rtr_info) { |
921 |
| - rtr_clean_rtr_info(btr_cur->rtr_info, true); |
922 |
| - btr_cur->rtr_info = NULL; |
923 |
| - } |
924 |
| -} |
925 |
| - |
926 | 924 | /*******************************************************************//**
|
927 | 925 | Create a RTree search info structure */
|
928 | 926 | rtr_info_t*
|
|
0 commit comments