1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164
|
/*****************************************************************************
Copyright (c) 2016, 2025, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License, version 2.0, as published by the
Free Software Foundation.
This program is designed to work with certain software (including
but not limited to OpenSSL) that is licensed under separate terms,
as designated in a particular file or component or in included license
documentation. The authors of MySQL hereby grant you an additional
permission to link the program and your derivative works with the
separately licensed software that they have either included with
the program or referenced in the documentation.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License, version 2.0,
for more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*****************************************************************************/
#ifndef lob0pages_h
#define lob0pages_h
#include "lob0first.h"
namespace lob {
/** The LOB data page carrying the user data. */
struct data_page_t : public basic_page_t {
static const ulint OFFSET_VERSION = FIL_PAGE_DATA;
static const ulint OFFSET_DATA_LEN = OFFSET_VERSION + 1;
static const ulint OFFSET_TRX_ID = OFFSET_DATA_LEN + 4;
static const ulint LOB_PAGE_DATA = OFFSET_TRX_ID + 6;
data_page_t() = default;
/** Constructor. */
data_page_t(buf_block_t *block, mtr_t *mtr) : basic_page_t(block, mtr) {
page_type_t type = get_page_type();
ut_a(type == FIL_PAGE_TYPE_LOB_DATA);
}
data_page_t(buf_block_t *block, mtr_t *mtr, dict_index_t *index)
: basic_page_t(block, mtr, index) {}
data_page_t(mtr_t *mtr, dict_index_t *index)
: basic_page_t(nullptr, mtr, index) {}
/** Constructor.
@param[in] block the buffer block.*/
data_page_t(buf_block_t *block) : basic_page_t(block, nullptr, nullptr) {}
/** Allocate a LOB data page.
@param[in] alloc_mtr Mini-transaction to be used for allocation of LOB page.
@param[in] is_bulk true if bulk operation.
@return allocated buffer block or nullptr */
buf_block_t *alloc(mtr_t *alloc_mtr, bool is_bulk);
buf_block_t *load_x(page_no_t page_no);
void set_version_0() {
mlog_write_ulint(frame() + OFFSET_VERSION, 0, MLOG_1BYTE, m_mtr);
}
void dealloc() {
btr_page_free_low(m_index, m_block, ULINT_UNDEFINED, m_mtr);
m_block = nullptr;
}
void set_page_type() {
ut_ad(m_mtr != nullptr);
mlog_write_ulint(frame() + FIL_PAGE_TYPE, FIL_PAGE_TYPE_LOB_DATA,
MLOG_2BYTES, m_mtr);
}
void set_trx_id(trx_id_t id) {
byte *ptr = frame() + OFFSET_TRX_ID;
mach_write_to_6(ptr, id);
mlog_log_string(ptr, 6, m_mtr);
}
/** Write the trx identifier to the header, without
generating redo log.
@param[in] id the transaction identifier.*/
void set_trx_id_no_redo(trx_id_t id) {
byte *ptr = frame() + OFFSET_TRX_ID;
mach_write_to_6(ptr, id);
}
static ulint payload() {
return (UNIV_PAGE_SIZE - LOB_PAGE_DATA - FIL_PAGE_DATA_END);
}
byte *data_begin() const { return (frame() + LOB_PAGE_DATA); }
/** Create a new data page and replace some or all parts of the old data
with data.
@param[in] trx Current transaction.
@param[in] offset Offset where replace begins.
@param[in,out] ptr Pointer to new data.
@param[in] want Amount of data the caller wants to replace.
@param[in] mtr Mini-transaction context.
@return the buffer block of the new data page. */
buf_block_t *replace(trx_t *trx, ulint offset, const byte *&ptr, ulint &want,
mtr_t *mtr);
/** Replace some or all parts of the data inline.
@param[in] offset Offset where replace begins.
@param[in,out] ptr Pointer to new data.
@param[in] want Amount of data the caller wants to replace.
@param[in] mtr Mini-transaction context. */
void replace_inline(ulint offset, const byte *&ptr, ulint &want, mtr_t *mtr);
ulint get_data_len() const {
return (mach_read_from_4(frame() + OFFSET_DATA_LEN));
}
void set_data_len(ulint len) {
ut_ad(m_mtr != nullptr);
mlog_write_ulint(frame() + OFFSET_DATA_LEN, len, MLOG_4BYTES, m_mtr);
}
/** Read data from the data page.
@param[in] offset read begins at this offset.
@param[out] ptr the output buffer.
@param[in] want bytes to read
@return bytes actually read. */
ulint read(ulint offset, byte *ptr, ulint want);
/** Write data into a data page.
@param[in,out] data the data to be written. it will be updated to
point to the byte not yet written.
@param[in,out] len length of data to be written.
@return amount of data actually written into the page. */
ulint write(const byte *&data, ulint &len);
/** Append given data in data page.
@param[in] trxid transaction doing append.
@param[in,out] data data to be appended.
@param[in,out] len length of data.
@return number of bytes appended. */
ulint append(trx_id_t trxid, byte *&data, ulint &len);
std::pair<ulint, byte *> insert_middle(trx_t *trx, ulint offset, byte *&data,
ulint &len, buf_block_t *&new_block);
buf_block_t *remove_middle(trx_t *trx, ulint offset, ulint &len);
ulint max_space_available() const { return (payload()); }
ulint space_left() const;
};
} /* namespace lob */
#endif /* lob0pages_h */
|