1 /***************************************************************************** 2 3 Copyright (c) 2016, 2019, Oracle and/or its affiliates. All Rights Reserved. 4 5 This program is free software; you can redistribute it and/or modify it under 6 the terms of the GNU General Public License, version 2.0, as published by the 7 Free Software Foundation. 8 9 This program is also distributed with certain software (including but not 10 limited to OpenSSL) that is licensed under separate terms, as designated in a 11 particular file or component or in included license documentation. The authors 12 of MySQL hereby grant you an additional permission to link the program and 13 your derivative works with the separately licensed software that they have 14 included with MySQL. 15 16 This program is distributed in the hope that it will be useful, but WITHOUT 17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 18 FOR A PARTICULAR PURPOSE. See the GNU General Public License, version 2.0, 19 for more details. 20 21 You should have received a copy of the GNU General Public License along with 22 this program; if not, write to the Free Software Foundation, Inc., 23 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 24 25 *****************************************************************************/ 26 #ifndef lob0util_h 27 #define lob0util_h 28 29 #include <stdint.h> 30 31 #include "buf0buf.h" 32 #include "fil0fil.h" 33 #include "fut0lst.h" 34 35 namespace lob { 36 37 /** Number of times an LOB can be partially updated. Once this limit is 38 reached, then the LOB will be fully updated. */ 39 const uint32_t MAX_PARTIAL_UPDATE_LIMIT = 1000; 40 41 struct basic_page_t { basic_page_tbasic_page_t42 basic_page_t() : m_block(nullptr), m_mtr(nullptr), m_index(nullptr) {} 43 basic_page_tbasic_page_t44 basic_page_t(buf_block_t *block, mtr_t *mtr) 45 : m_block(block), m_mtr(mtr), m_index(nullptr) {} 46 basic_page_tbasic_page_t47 basic_page_t(buf_block_t *block, mtr_t *mtr, dict_index_t *index) 48 : m_block(block), m_mtr(mtr), m_index(index) {} 49 50 /** Update the space identifier to given value without generating 51 any redo log records. 52 @param[in] space_id the space identifier. */ set_space_id_no_redobasic_page_t53 void set_space_id_no_redo(space_id_t space_id) { 54 mach_write_to_4(frame() + FIL_PAGE_SPACE_ID, space_id); 55 } 56 57 /** Get page number of the current page. 58 @return the page number of the current page. */ get_page_nobasic_page_t59 page_no_t get_page_no() const { 60 ut_ad(m_block != nullptr); 61 return (m_block->page.id.page_no()); 62 } 63 64 /** Get the page id of the current page. 65 @return the page id of current page. */ get_page_idbasic_page_t66 page_id_t get_page_id() const { 67 ut_ad(m_block != nullptr); 68 return (m_block->page.id); 69 } 70 71 /** Set the FIL_PAGE_NEXT to the given page number, using the given mini 72 transaction context. 73 @param[in] page_no The page number to set. 74 @param[in] mtr The mini transaction context. */ set_next_pagebasic_page_t75 void set_next_page(page_no_t page_no, mtr_t *mtr) { 76 mlog_write_ulint(frame() + FIL_PAGE_NEXT, page_no, MLOG_4BYTES, mtr); 77 } 78 79 /** Set the FIL_PAGE_NEXT to the given page number. 80 @param[in] page_no The page number to set. */ set_next_pagebasic_page_t81 void set_next_page(page_no_t page_no) { set_next_page(page_no, m_mtr); } 82 83 /** Set the FIL_PAGE_NEXT to FIL_NULL. */ set_next_page_nullbasic_page_t84 void set_next_page_null() { 85 ut_ad(m_mtr != nullptr); 86 87 set_next_page(FIL_NULL); 88 } 89 get_next_pagebasic_page_t90 page_no_t get_next_page() { 91 return (mach_read_from_4(frame() + FIL_PAGE_NEXT)); 92 } 93 get_page_typebasic_page_t94 page_type_t get_page_type() const { 95 return (mach_read_from_2(frame() + FIL_PAGE_TYPE)); 96 } 97 framebasic_page_t98 byte *frame() const { return (buf_block_get_frame(m_block)); } 99 get_flst_nodebasic_page_t100 flst_node_t *get_flst_node(const fil_addr_t &addr) { 101 ut_ad(!addr.is_null()); 102 103 flst_node_t *node = nullptr; 104 if (addr.page == get_page_no()) { 105 node = frame() + addr.boffset; 106 } 107 return (node); 108 } 109 110 static ulint payload(); 111 ulint max_space_available(); 112 set_blockbasic_page_t113 void set_block(buf_block_t *block) { 114 ut_ad(mtr_memo_contains(m_mtr, block, MTR_MEMO_PAGE_X_FIX) || 115 mtr_memo_contains(m_mtr, block, MTR_MEMO_PAGE_S_FIX)); 116 117 m_block = block; 118 } 119 set_mtrbasic_page_t120 void set_mtr(mtr_t *mtr) { m_mtr = mtr; } 121 122 protected: 123 buf_block_t *m_block; 124 mtr_t *m_mtr; 125 dict_index_t *m_index; 126 }; 127 128 /** Allocate one LOB page. 129 @param[in] index the index in which LOB exists. 130 @param[in] lob_mtr the mini-transaction context. 131 @param[in] hint the hint page number for allocation. 132 @param[in] bulk true if operation is OPCODE_INSERT_BULK, 133 false otherwise. 134 @return the allocated block of the BLOB page. */ 135 buf_block_t *alloc_lob_page(dict_index_t *index, mtr_t *lob_mtr, page_no_t hint, 136 bool bulk); 137 138 /** Check if the index entry is visible to the given transaction. 139 @param[in] index the index to which LOB belongs. 140 @param[in] trx the transaction reading the index entry. 141 @param[in] entry_trx_id the trx id in the index entry. */ 142 bool entry_visible_to(dict_index_t *index, trx_t *trx, trx_id_t entry_trx_id); 143 144 } /* namespace lob */ 145 146 #endif /* lob0util_h */ 147