| 1 | /***************************************************************************** |
| 2 | |
| 3 | Copyright (c) 2014, 2016, Oracle and/or its affiliates. All Rights Reserved. |
| 4 | Copyright (c) 2017, 2018, MariaDB Corporation. |
| 5 | |
| 6 | This program is free software; you can redistribute it and/or modify it under |
| 7 | the terms of the GNU General Public License as published by the Free Software |
| 8 | Foundation; version 2 of the License. |
| 9 | |
| 10 | This program is distributed in the hope that it will be useful, but WITHOUT |
| 11 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
| 12 | FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. |
| 13 | |
| 14 | You should have received a copy of the GNU General Public License along with |
| 15 | this program; if not, write to the Free Software Foundation, Inc., |
| 16 | 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA |
| 17 | |
| 18 | *****************************************************************************/ |
| 19 | |
| 20 | /******************************************************************//** |
| 21 | @file include gis0rtree.h |
| 22 | R-tree header file |
| 23 | |
| 24 | Created 2013/03/27 Jimmy Yang and Allen Lai |
| 25 | ***********************************************************************/ |
| 26 | |
| 27 | #ifndef gis0rtree_h |
| 28 | #define gis0rtree_h |
| 29 | |
| 30 | #include "univ.i" |
| 31 | #include "my_base.h" |
| 32 | |
| 33 | #include "data0type.h" |
| 34 | #include "data0types.h" |
| 35 | #include "dict0types.h" |
| 36 | #include "hash0hash.h" |
| 37 | #include "mem0mem.h" |
| 38 | #include "page0page.h" |
| 39 | #include "rem0types.h" |
| 40 | #include "row0types.h" |
| 41 | #include "trx0types.h" |
| 42 | #include "ut0vec.h" |
| 43 | #include "ut0wqueue.h" |
| 44 | #include "que0types.h" |
| 45 | #include "gis0geo.h" |
| 46 | #include "gis0type.h" |
| 47 | #include "btr0types.h" |
| 48 | #include "btr0cur.h" |
| 49 | |
| 50 | /* Whether MBR 'a' contains 'b' */ |
| 51 | #define MBR_CONTAIN_CMP(a, b) \ |
| 52 | ((((b)->xmin >= (a)->xmin) && ((b)->xmax <= (a)->xmax) \ |
| 53 | && ((b)->ymin >= (a)->ymin) && ((b)->ymax <= (a)->ymax))) |
| 54 | |
| 55 | /* Whether MBR 'a' equals to 'b' */ |
| 56 | #define MBR_EQUAL_CMP(a, b) \ |
| 57 | ((((b)->xmin == (a)->xmin) && ((b)->xmax == (a)->xmax)) \ |
| 58 | && (((b)->ymin == (a)->ymin) && ((b)->ymax == (a)->ymax))) |
| 59 | |
| 60 | /* Whether MBR 'a' intersects 'b' */ |
| 61 | #define MBR_INTERSECT_CMP(a, b) \ |
| 62 | ((((b)->xmin <= (a)->xmax) || ((b)->xmax >= (a)->xmin)) \ |
| 63 | && (((b)->ymin <= (a)->ymax) || ((b)->ymax >= (a)->ymin))) |
| 64 | |
| 65 | /* Whether MBR 'a' and 'b' disjoint */ |
| 66 | #define MBR_DISJOINT_CMP(a, b) (!MBR_INTERSECT_CMP(a, b)) |
| 67 | |
| 68 | /* Whether MBR 'a' within 'b' */ |
| 69 | #define MBR_WITHIN_CMP(a, b) \ |
| 70 | ((((b)->xmin <= (a)->xmin) && ((b)->xmax >= (a)->xmax)) \ |
| 71 | && (((b)->ymin <= (a)->ymin) && ((b)->ymax >= (a)->ymax))) |
| 72 | |
| 73 | /* Define it for rtree search mode checking. */ |
| 74 | #define RTREE_SEARCH_MODE(mode) \ |
| 75 | (((mode) >= PAGE_CUR_CONTAIN) && ((mode <= PAGE_CUR_RTREE_GET_FATHER))) |
| 76 | |
| 77 | /* Geometry data header */ |
| 78 | #define 4 |
| 79 | /**********************************************************************//** |
| 80 | Builds a Rtree node pointer out of a physical record and a page number. |
| 81 | @return own: node pointer */ |
| 82 | dtuple_t* |
| 83 | rtr_index_build_node_ptr( |
| 84 | /*=====================*/ |
| 85 | const dict_index_t* index, /*!< in: index */ |
| 86 | const rtr_mbr_t* mbr, /*!< in: mbr of lower page */ |
| 87 | const rec_t* rec, /*!< in: record for which to build node |
| 88 | pointer */ |
| 89 | ulint page_no,/*!< in: page number to put in node |
| 90 | pointer */ |
| 91 | mem_heap_t* heap); /*!< in: memory heap where pointer |
| 92 | created */ |
| 93 | |
| 94 | /*************************************************************//** |
| 95 | Splits an R-tree index page to halves and inserts the tuple. It is assumed |
| 96 | that mtr holds an x-latch to the index tree. NOTE: the tree x-latch is |
| 97 | released within this function! NOTE that the operation of this |
| 98 | function must always succeed, we cannot reverse it: therefore enough |
| 99 | free disk space (2 pages) must be guaranteed to be available before |
| 100 | this function is called. |
| 101 | @return inserted record */ |
| 102 | rec_t* |
| 103 | rtr_page_split_and_insert( |
| 104 | /*======================*/ |
| 105 | ulint flags, /*!< in: undo logging and locking flags */ |
| 106 | btr_cur_t* cursor, /*!< in/out: cursor at which to insert; when the |
| 107 | function returns, the cursor is positioned |
| 108 | on the predecessor of the inserted record */ |
| 109 | ulint** offsets,/*!< out: offsets on inserted record */ |
| 110 | mem_heap_t** heap, /*!< in/out: pointer to memory heap, or NULL */ |
| 111 | const dtuple_t* tuple, /*!< in: tuple to insert */ |
| 112 | ulint n_ext, /*!< in: number of externally stored columns */ |
| 113 | mtr_t* mtr); /*!< in: mtr */ |
| 114 | |
| 115 | /**************************************************************//** |
| 116 | Sets the child node mbr in a node pointer. */ |
| 117 | UNIV_INLINE |
| 118 | void |
| 119 | rtr_page_cal_mbr( |
| 120 | /*=============*/ |
| 121 | const dict_index_t* index, /*!< in: index */ |
| 122 | const buf_block_t* block, /*!< in: buffer block */ |
| 123 | rtr_mbr_t* mbr, /*!< out: MBR encapsulates the page */ |
| 124 | mem_heap_t* heap); /*!< in: heap for the memory |
| 125 | allocation */ |
| 126 | /*************************************************************//** |
| 127 | Find the next matching record. This function will first exhaust |
| 128 | the copied record listed in the rtr_info->matches vector before |
| 129 | moving to next page |
| 130 | @return true if there is next qualified record found, otherwise(if |
| 131 | exhausted) false */ |
| 132 | bool |
| 133 | rtr_pcur_move_to_next( |
| 134 | /*==================*/ |
| 135 | const dtuple_t* tuple, /*!< in: data tuple; NOTE: n_fields_cmp in |
| 136 | tuple must be set so that it cannot get |
| 137 | compared to the node ptr page number field! */ |
| 138 | page_cur_mode_t mode, /*!< in: cursor search mode */ |
| 139 | btr_pcur_t* cursor, /*!< in: persistent cursor; NOTE that the |
| 140 | function may release the page latch */ |
| 141 | ulint cur_level, |
| 142 | /*!< in: current level */ |
| 143 | mtr_t* mtr); /*!< in: mtr */ |
| 144 | |
| 145 | /****************************************************************//** |
| 146 | Searches the right position in rtree for a page cursor. */ |
| 147 | bool |
| 148 | rtr_cur_search_with_match( |
| 149 | /*======================*/ |
| 150 | const buf_block_t* block, /*!< in: buffer block */ |
| 151 | dict_index_t* index, /*!< in: index descriptor */ |
| 152 | const dtuple_t* tuple, /*!< in: data tuple */ |
| 153 | page_cur_mode_t mode, /*!< in: PAGE_CUR_L, |
| 154 | PAGE_CUR_LE, PAGE_CUR_G, or |
| 155 | PAGE_CUR_GE */ |
| 156 | page_cur_t* cursor, /*!< in/out: page cursor */ |
| 157 | rtr_info_t* rtr_info);/*!< in/out: search stack */ |
| 158 | |
| 159 | /****************************************************************//** |
| 160 | Calculate the area increased for a new record |
| 161 | @return area increased */ |
| 162 | double |
| 163 | rtr_rec_cal_increase( |
| 164 | /*=================*/ |
| 165 | const dtuple_t* dtuple, /*!< in: data tuple to insert, which |
| 166 | cause area increase */ |
| 167 | const rec_t* rec, /*!< in: physical record which differs from |
| 168 | dtuple in some of the common fields, or which |
| 169 | has an equal number or more fields than |
| 170 | dtuple */ |
| 171 | const ulint* offsets,/*!< in: array returned by rec_get_offsets() */ |
| 172 | double* area); /*!< out: increased area */ |
| 173 | |
| 174 | /****************************************************************//** |
| 175 | Following the right link to find the proper block for insert. |
| 176 | @return the proper block.*/ |
| 177 | dberr_t |
| 178 | rtr_ins_enlarge_mbr( |
| 179 | /*=================*/ |
| 180 | btr_cur_t* cursor, /*!< in: btr cursor */ |
| 181 | mtr_t* mtr); /*!< in: mtr */ |
| 182 | |
| 183 | /********************************************************************//** |
| 184 | */ |
| 185 | void |
| 186 | rtr_get_father_node( |
| 187 | /*================*/ |
| 188 | dict_index_t* index, /*!< in: index */ |
| 189 | ulint level, /*!< in: the tree level of search */ |
| 190 | const dtuple_t* tuple, /*!< in: data tuple; NOTE: n_fields_cmp in |
| 191 | tuple must be set so that it cannot get |
| 192 | compared to the node ptr page number field! */ |
| 193 | btr_cur_t* sea_cur,/*!< in: search cursor */ |
| 194 | btr_cur_t* cursor, /*!< in/out: tree cursor; the cursor page is |
| 195 | s- or x-latched */ |
| 196 | ulint page_no,/*!< in: current page no */ |
| 197 | mtr_t* mtr); /*!< in: mtr */ |
| 198 | |
| 199 | /**************************************************************//** |
| 200 | push a nonleaf index node to the search path */ |
| 201 | UNIV_INLINE |
| 202 | void |
| 203 | rtr_non_leaf_stack_push( |
| 204 | /*====================*/ |
| 205 | rtr_node_path_t* path, /*!< in/out: search path */ |
| 206 | ulint pageno, /*!< in: pageno to insert */ |
| 207 | node_seq_t seq_no, /*!< in: Node sequence num */ |
| 208 | ulint level, /*!< in: index level */ |
| 209 | ulint child_no, /*!< in: child page no */ |
| 210 | btr_pcur_t* cursor, /*!< in: position cursor */ |
| 211 | double mbr_inc); /*!< in: MBR needs to be |
| 212 | enlarged */ |
| 213 | |
| 214 | /**************************************************************//** |
| 215 | push a nonleaf index node to the search path for insertion */ |
| 216 | void |
| 217 | rtr_non_leaf_insert_stack_push( |
| 218 | /*===========================*/ |
| 219 | dict_index_t* index, /*!< in: index descriptor */ |
| 220 | rtr_node_path_t* path, /*!< in/out: search path */ |
| 221 | ulint level, /*!< in: index level */ |
| 222 | const buf_block_t* block, /*!< in: block of the page */ |
| 223 | const rec_t* rec, /*!< in: positioned record */ |
| 224 | double mbr_inc); /*!< in: MBR needs to be |
| 225 | enlarged */ |
| 226 | |
| 227 | /*****************************************************************//** |
| 228 | Allocates a new Split Sequence Number. |
| 229 | @return new SSN id */ |
| 230 | UNIV_INLINE |
| 231 | node_seq_t |
| 232 | rtr_get_new_ssn_id( |
| 233 | /*===============*/ |
| 234 | dict_index_t* index); /*!< in: the index struct */ |
| 235 | |
| 236 | /*****************************************************************//** |
| 237 | Get the current Split Sequence Number. |
| 238 | @return current SSN id */ |
| 239 | UNIV_INLINE |
| 240 | node_seq_t |
| 241 | rtr_get_current_ssn_id( |
| 242 | /*===================*/ |
| 243 | dict_index_t* index); /*!< in/out: the index struct */ |
| 244 | |
| 245 | /********************************************************************//** |
| 246 | Create a RTree search info structure */ |
| 247 | rtr_info_t* |
| 248 | rtr_create_rtr_info( |
| 249 | /******************/ |
| 250 | bool need_prdt, /*!< in: Whether predicate lock is |
| 251 | needed */ |
| 252 | bool init_matches, /*!< in: Whether to initiate the |
| 253 | "matches" structure for collecting |
| 254 | matched leaf records */ |
| 255 | btr_cur_t* cursor, /*!< in: tree search cursor */ |
| 256 | dict_index_t* index); /*!< in: index struct */ |
| 257 | |
| 258 | /********************************************************************//** |
| 259 | Update a btr_cur_t with rtr_info */ |
| 260 | void |
| 261 | rtr_info_update_btr( |
| 262 | /******************/ |
| 263 | btr_cur_t* cursor, /*!< in/out: tree cursor */ |
| 264 | rtr_info_t* rtr_info); /*!< in: rtr_info to set to the |
| 265 | cursor */ |
| 266 | |
| 267 | /********************************************************************//** |
| 268 | Update a btr_cur_t with rtr_info */ |
| 269 | void |
| 270 | rtr_init_rtr_info( |
| 271 | /****************/ |
| 272 | rtr_info_t* rtr_info, /*!< in: rtr_info to set to the |
| 273 | cursor */ |
| 274 | bool need_prdt, /*!< in: Whether predicate lock is |
| 275 | needed */ |
| 276 | btr_cur_t* cursor, /*!< in: tree search cursor */ |
| 277 | dict_index_t* index, /*!< in: index structure */ |
| 278 | bool reinit); /*!< in: Whether this is a reinit */ |
| 279 | |
| 280 | /**************************************************************//** |
| 281 | Clean up Rtree cursor */ |
| 282 | void |
| 283 | rtr_clean_rtr_info( |
| 284 | /*===============*/ |
| 285 | rtr_info_t* rtr_info, /*!< in: RTree search info */ |
| 286 | bool free_all); /*!< in: need to free rtr_info itself */ |
| 287 | |
| 288 | /****************************************************************//** |
| 289 | Get the bounding box content from an index record*/ |
| 290 | void |
| 291 | rtr_get_mbr_from_rec( |
| 292 | /*=================*/ |
| 293 | const rec_t* rec, /*!< in: data tuple */ |
| 294 | const ulint* offsets,/*!< in: offsets array */ |
| 295 | rtr_mbr_t* mbr); /*!< out MBR */ |
| 296 | |
| 297 | /****************************************************************//** |
| 298 | Get the bounding box content from a MBR data record */ |
| 299 | void |
| 300 | rtr_get_mbr_from_tuple( |
| 301 | /*===================*/ |
| 302 | const dtuple_t* dtuple, /*!< in: data tuple */ |
| 303 | rtr_mbr* mbr); /*!< out: mbr to fill */ |
| 304 | |
| 305 | /* Get the rtree page father. |
| 306 | @param[in] offsets work area for the return value |
| 307 | @param[in] index rtree index |
| 308 | @param[in] block child page in the index |
| 309 | @param[in] mtr mtr |
| 310 | @param[in] sea_cur search cursor, contains information |
| 311 | about parent nodes in search |
| 312 | @param[in] cursor cursor on node pointer record, |
| 313 | its page x-latched */ |
| 314 | void |
| 315 | rtr_page_get_father( |
| 316 | dict_index_t* index, |
| 317 | buf_block_t* block, |
| 318 | mtr_t* mtr, |
| 319 | btr_cur_t* sea_cur, |
| 320 | btr_cur_t* cursor); |
| 321 | |
| 322 | /************************************************************//** |
| 323 | Returns the father block to a page. It is assumed that mtr holds |
| 324 | an X or SX latch on the tree. |
| 325 | @return rec_get_offsets() of the node pointer record */ |
| 326 | ulint* |
| 327 | rtr_page_get_father_block( |
| 328 | /*======================*/ |
| 329 | ulint* offsets,/*!< in: work area for the return value */ |
| 330 | mem_heap_t* heap, /*!< in: memory heap to use */ |
| 331 | dict_index_t* index, /*!< in: b-tree index */ |
| 332 | buf_block_t* block, /*!< in: child page in the index */ |
| 333 | mtr_t* mtr, /*!< in: mtr */ |
| 334 | btr_cur_t* sea_cur,/*!< in: search cursor, contains information |
| 335 | about parent nodes in search */ |
| 336 | btr_cur_t* cursor);/*!< out: cursor on node pointer record, |
| 337 | its page x-latched */ |
| 338 | /**************************************************************//** |
| 339 | Store the parent path cursor |
| 340 | @return number of cursor stored */ |
| 341 | ulint |
| 342 | rtr_store_parent_path( |
| 343 | /*==================*/ |
| 344 | const buf_block_t* block, /*!< in: block of the page */ |
| 345 | btr_cur_t* btr_cur,/*!< in/out: persistent cursor */ |
| 346 | ulint latch_mode, |
| 347 | /*!< in: latch_mode */ |
| 348 | ulint level, /*!< in: index level */ |
| 349 | mtr_t* mtr); /*!< in: mtr */ |
| 350 | |
| 351 | /**************************************************************//** |
| 352 | Initializes and opens a persistent cursor to an index tree. It should be |
| 353 | closed with btr_pcur_close. */ |
| 354 | void |
| 355 | rtr_pcur_open_low( |
| 356 | /*==============*/ |
| 357 | dict_index_t* index, /*!< in: index */ |
| 358 | ulint level, /*!< in: level in the btree */ |
| 359 | const dtuple_t* tuple, /*!< in: tuple on which search done */ |
| 360 | page_cur_mode_t mode, /*!< in: PAGE_CUR_L, ...; |
| 361 | NOTE that if the search is made using a unique |
| 362 | prefix of a record, mode should be |
| 363 | PAGE_CUR_LE, not PAGE_CUR_GE, as the latter |
| 364 | may end up on the previous page from the |
| 365 | record! */ |
| 366 | ulint latch_mode,/*!< in: BTR_SEARCH_LEAF, ... */ |
| 367 | btr_pcur_t* cursor, /*!< in: memory buffer for persistent cursor */ |
| 368 | const char* file, /*!< in: file name */ |
| 369 | unsigned line, /*!< in: line where called */ |
| 370 | mtr_t* mtr); /*!< in: mtr */ |
| 371 | |
| 372 | #define rtr_pcur_open(i,t,md,l,c,m) \ |
| 373 | rtr_pcur_open_low(i,0,t,md,l,c,__FILE__,__LINE__,m) |
| 374 | |
| 375 | struct btr_cur_t; |
| 376 | |
| 377 | /*********************************************************//** |
| 378 | Returns the R-Tree node stored in the parent search path |
| 379 | @return pointer to R-Tree cursor component */ |
| 380 | UNIV_INLINE |
| 381 | node_visit_t* |
| 382 | rtr_get_parent_node( |
| 383 | /*================*/ |
| 384 | btr_cur_t* btr_cur, /*!< in: persistent cursor */ |
| 385 | ulint level, /*!< in: index level of buffer page */ |
| 386 | ulint is_insert); /*!< in: whether it is insert */ |
| 387 | |
| 388 | /*********************************************************//** |
| 389 | Returns the R-Tree cursor stored in the parent search path |
| 390 | @return pointer to R-Tree cursor component */ |
| 391 | UNIV_INLINE |
| 392 | btr_pcur_t* |
| 393 | rtr_get_parent_cursor( |
| 394 | /*==================*/ |
| 395 | btr_cur_t* btr_cur, /*!< in: persistent cursor */ |
| 396 | ulint level, /*!< in: index level of buffer page */ |
| 397 | ulint is_insert); /*!< in: whether insert operation */ |
| 398 | |
| 399 | /*************************************************************//** |
| 400 | Copy recs from a page to new_block of rtree. */ |
| 401 | void |
| 402 | rtr_page_copy_rec_list_end_no_locks( |
| 403 | /*================================*/ |
| 404 | buf_block_t* new_block, /*!< in: index page to copy to */ |
| 405 | buf_block_t* block, /*!< in: index page of rec */ |
| 406 | rec_t* rec, /*!< in: record on page */ |
| 407 | dict_index_t* index, /*!< in: record descriptor */ |
| 408 | mem_heap_t* heap, /*!< in/out: heap memory */ |
| 409 | rtr_rec_move_t* rec_move, /*!< in: recording records moved */ |
| 410 | ulint max_move, /*!< in: num of rec to move */ |
| 411 | ulint* num_moved, /*!< out: num of rec to move */ |
| 412 | mtr_t* mtr); /*!< in: mtr */ |
| 413 | |
| 414 | /*************************************************************//** |
| 415 | Copy recs till a specified rec from a page to new_block of rtree. */ |
| 416 | void |
| 417 | rtr_page_copy_rec_list_start_no_locks( |
| 418 | /*==================================*/ |
| 419 | buf_block_t* new_block, /*!< in: index page to copy to */ |
| 420 | buf_block_t* block, /*!< in: index page of rec */ |
| 421 | rec_t* rec, /*!< in: record on page */ |
| 422 | dict_index_t* index, /*!< in: record descriptor */ |
| 423 | mem_heap_t* heap, /*!< in/out: heap memory */ |
| 424 | rtr_rec_move_t* rec_move, /*!< in: recording records moved */ |
| 425 | ulint max_move, /*!< in: num of rec to move */ |
| 426 | ulint* num_moved, /*!< out: num of rec to move */ |
| 427 | mtr_t* mtr); /*!< in: mtr */ |
| 428 | |
| 429 | /****************************************************************//** |
| 430 | Merge 2 mbrs and update the the mbr that cursor is on. */ |
| 431 | dberr_t |
| 432 | rtr_merge_and_update_mbr( |
| 433 | /*=====================*/ |
| 434 | btr_cur_t* cursor, /*!< in/out: cursor */ |
| 435 | btr_cur_t* cursor2, /*!< in: the other cursor */ |
| 436 | ulint* offsets, /*!< in: rec offsets */ |
| 437 | ulint* offsets2, /*!< in: rec offsets */ |
| 438 | page_t* child_page, /*!< in: the child page. */ |
| 439 | mtr_t* mtr); /*!< in: mtr */ |
| 440 | |
| 441 | /*************************************************************//** |
| 442 | Deletes on the upper level the node pointer to a page. */ |
| 443 | void |
| 444 | rtr_node_ptr_delete( |
| 445 | /*================*/ |
| 446 | btr_cur_t* cursor, /*!< in: search cursor, contains information |
| 447 | about parent nodes in search */ |
| 448 | mtr_t* mtr); /*!< in: mtr */ |
| 449 | |
| 450 | /****************************************************************//** |
| 451 | Check two MBRs are identical or need to be merged */ |
| 452 | bool |
| 453 | rtr_merge_mbr_changed( |
| 454 | /*==================*/ |
| 455 | btr_cur_t* cursor, /*!< in: cursor */ |
| 456 | btr_cur_t* cursor2, /*!< in: the other cursor */ |
| 457 | ulint* offsets, /*!< in: rec offsets */ |
| 458 | ulint* offsets2, /*!< in: rec offsets */ |
| 459 | rtr_mbr_t* new_mbr); /*!< out: MBR to update */ |
| 460 | |
| 461 | |
| 462 | /**************************************************************//** |
| 463 | Update the mbr field of a spatial index row. |
| 464 | @return true if successful */ |
| 465 | bool |
| 466 | rtr_update_mbr_field( |
| 467 | /*=================*/ |
| 468 | btr_cur_t* cursor, /*!< in: cursor pointed to rec.*/ |
| 469 | ulint* offsets, /*!< in: offsets on rec. */ |
| 470 | btr_cur_t* cursor2, /*!< in/out: cursor pointed to rec |
| 471 | that should be deleted. |
| 472 | this cursor is for btr_compress to |
| 473 | delete the merged page's father rec.*/ |
| 474 | page_t* child_page, /*!< in: child page. */ |
| 475 | rtr_mbr_t* new_mbr, /*!< in: the new mbr. */ |
| 476 | rec_t* new_rec, /*!< in: rec to use */ |
| 477 | mtr_t* mtr); /*!< in: mtr */ |
| 478 | |
| 479 | /**************************************************************//** |
| 480 | Check whether a Rtree page is child of a parent page |
| 481 | @return true if there is child/parent relationship */ |
| 482 | bool |
| 483 | rtr_check_same_block( |
| 484 | /*=================*/ |
| 485 | dict_index_t* index, /*!< in: index tree */ |
| 486 | btr_cur_t* cur, /*!< in/out: position at the parent entry |
| 487 | pointing to the child if successful */ |
| 488 | buf_block_t* parentb,/*!< in: parent page to check */ |
| 489 | buf_block_t* childb, /*!< in: child Page */ |
| 490 | mem_heap_t* heap); /*!< in: memory heap */ |
| 491 | |
| 492 | /*********************************************************************//** |
| 493 | Sets pointer to the data and length in a field. */ |
| 494 | UNIV_INLINE |
| 495 | void |
| 496 | rtr_write_mbr( |
| 497 | /*==========*/ |
| 498 | byte* data, /*!< out: data */ |
| 499 | const rtr_mbr_t* mbr); /*!< in: data */ |
| 500 | |
| 501 | /*********************************************************************//** |
| 502 | Sets pointer to the data and length in a field. */ |
| 503 | UNIV_INLINE |
| 504 | void |
| 505 | rtr_read_mbr( |
| 506 | /*==========*/ |
| 507 | const byte* data, /*!< in: data */ |
| 508 | rtr_mbr_t* mbr); /*!< out: data */ |
| 509 | |
| 510 | /**************************************************************//** |
| 511 | Check whether a discarding page is in anyone's search path */ |
| 512 | void |
| 513 | rtr_check_discard_page( |
| 514 | /*===================*/ |
| 515 | dict_index_t* index, /*!< in: index */ |
| 516 | btr_cur_t* cursor, /*!< in: cursor on the page to discard: not on |
| 517 | the root page */ |
| 518 | buf_block_t* block); /*!< in: block of page to be discarded */ |
| 519 | |
| 520 | /********************************************************************//** |
| 521 | Reinitialize a RTree search info */ |
| 522 | UNIV_INLINE |
| 523 | void |
| 524 | rtr_info_reinit_in_cursor( |
| 525 | /************************/ |
| 526 | btr_cur_t* cursor, /*!< in/out: tree cursor */ |
| 527 | dict_index_t* index, /*!< in: index struct */ |
| 528 | bool need_prdt); /*!< in: Whether predicate lock is |
| 529 | needed */ |
| 530 | |
| 531 | /** Estimates the number of rows in a given area. |
| 532 | @param[in] index index |
| 533 | @param[in] tuple range tuple containing mbr, may also be empty tuple |
| 534 | @param[in] mode search mode |
| 535 | @return estimated number of rows */ |
| 536 | ha_rows |
| 537 | rtr_estimate_n_rows_in_range( |
| 538 | dict_index_t* index, |
| 539 | const dtuple_t* tuple, |
| 540 | page_cur_mode_t mode); |
| 541 | |
| 542 | #include "gis0rtree.ic" |
| 543 | #endif /*!< gis0rtree.h */ |
| 544 | |