| 1 | /***************************************************************************** |
| 2 | |
| 3 | Copyright (c) 1996, 2015, 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/lock0lock.ic |
| 22 | The transaction lock system |
| 23 | |
| 24 | Created 5/7/1996 Heikki Tuuri |
| 25 | *******************************************************/ |
| 26 | |
| 27 | #include "dict0dict.h" |
| 28 | #include "buf0buf.h" |
| 29 | #include "page0page.h" |
| 30 | |
| 31 | /*********************************************************************//** |
| 32 | Calculates the fold value of a page file address: used in inserting or |
| 33 | searching for a lock in the hash table. |
| 34 | @return folded value */ |
| 35 | UNIV_INLINE |
| 36 | ulint |
| 37 | lock_rec_fold( |
| 38 | /*==========*/ |
| 39 | ulint space, /*!< in: space */ |
| 40 | ulint page_no)/*!< in: page number */ |
| 41 | { |
| 42 | return(ut_fold_ulint_pair(space, page_no)); |
| 43 | } |
| 44 | |
| 45 | /*********************************************************************//** |
| 46 | Calculates the hash value of a page file address: used in inserting or |
| 47 | searching for a lock in the hash table. |
| 48 | @return hashed value */ |
| 49 | UNIV_INLINE |
| 50 | unsigned |
| 51 | lock_rec_hash( |
| 52 | /*==========*/ |
| 53 | ulint space, /*!< in: space */ |
| 54 | ulint page_no)/*!< in: page number */ |
| 55 | { |
| 56 | return(unsigned(hash_calc_hash(lock_rec_fold(space, page_no), |
| 57 | lock_sys.rec_hash))); |
| 58 | } |
| 59 | |
| 60 | /*********************************************************************//** |
| 61 | Gets the heap_no of the smallest user record on a page. |
| 62 | @return heap_no of smallest user record, or PAGE_HEAP_NO_SUPREMUM */ |
| 63 | UNIV_INLINE |
| 64 | ulint |
| 65 | lock_get_min_heap_no( |
| 66 | /*=================*/ |
| 67 | const buf_block_t* block) /*!< in: buffer block */ |
| 68 | { |
| 69 | const page_t* page = block->frame; |
| 70 | |
| 71 | if (page_is_comp(page)) { |
| 72 | return(rec_get_heap_no_new( |
| 73 | page |
| 74 | + rec_get_next_offs(page + PAGE_NEW_INFIMUM, |
| 75 | TRUE))); |
| 76 | } else { |
| 77 | return(rec_get_heap_no_old( |
| 78 | page |
| 79 | + rec_get_next_offs(page + PAGE_OLD_INFIMUM, |
| 80 | FALSE))); |
| 81 | } |
| 82 | } |
| 83 | |
| 84 | /*************************************************************//** |
| 85 | Get the lock hash table */ |
| 86 | UNIV_INLINE |
| 87 | hash_table_t* |
| 88 | lock_hash_get( |
| 89 | /*==========*/ |
| 90 | ulint mode) /*!< in: lock mode */ |
| 91 | { |
| 92 | if (mode & LOCK_PREDICATE) { |
| 93 | return(lock_sys.prdt_hash); |
| 94 | } else if (mode & LOCK_PRDT_PAGE) { |
| 95 | return(lock_sys.prdt_page_hash); |
| 96 | } else { |
| 97 | return(lock_sys.rec_hash); |
| 98 | } |
| 99 | } |
| 100 | |
| 101 | /*********************************************************************//** |
| 102 | Creates a new record lock and inserts it to the lock queue. Does NOT check |
| 103 | for deadlocks or lock compatibility! |
| 104 | @return created lock */ |
| 105 | UNIV_INLINE |
| 106 | lock_t* |
| 107 | lock_rec_create( |
| 108 | /*============*/ |
| 109 | #ifdef WITH_WSREP |
| 110 | lock_t* c_lock, /*!< conflicting lock */ |
| 111 | que_thr_t* thr, /*!< thread owning trx */ |
| 112 | #endif |
| 113 | ulint type_mode,/*!< in: lock mode and wait |
| 114 | flag, type is ignored and |
| 115 | replaced by LOCK_REC */ |
| 116 | const buf_block_t* block, /*!< in: buffer block containing |
| 117 | the record */ |
| 118 | ulint heap_no,/*!< in: heap number of the record */ |
| 119 | dict_index_t* index, /*!< in: index of record */ |
| 120 | trx_t* trx, /*!< in,out: transaction */ |
| 121 | bool caller_owns_trx_mutex) |
| 122 | /*!< in: TRUE if caller owns |
| 123 | trx mutex */ |
| 124 | { |
| 125 | btr_assert_not_corrupted(block, index); |
| 126 | return lock_rec_create_low( |
| 127 | #ifdef WITH_WSREP |
| 128 | c_lock, thr, |
| 129 | #endif |
| 130 | type_mode, |
| 131 | block->page.id.space(), block->page.id.page_no(), |
| 132 | block->frame, heap_no, |
| 133 | index, trx, caller_owns_trx_mutex); |
| 134 | } |
| 135 | |