File: lob0ins.h

package info (click to toggle)
mysql-8.0 8.0.44-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 1,272,892 kB
  • sloc: cpp: 4,685,345; ansic: 412,712; pascal: 108,395; java: 83,641; perl: 30,221; cs: 27,067; sql: 26,594; python: 21,816; sh: 17,285; yacc: 17,169; php: 11,522; xml: 7,388; javascript: 7,083; makefile: 1,793; lex: 1,075; awk: 670; asm: 520; objc: 183; ruby: 97; lisp: 86
file content (184 lines) | stat: -rw-r--r-- 6,277 bytes parent folder | download
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
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
/*****************************************************************************

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 lob0ins_h
#define lob0ins_h

#include "lob0lob.h"

namespace lob {

/** This struct can hold BLOB routines/functions, and state variables,
that are common for compressed and uncompressed BLOB. */
struct BaseInserter {
  /** Constructor.
  @param[in]    ctx     blob operation context. */
  BaseInserter(InsertContext *ctx)
      : m_ctx(ctx),
        m_err(DB_SUCCESS),
        m_prev_page_no(ctx->get_page_no()),
        m_cur_blob_block(nullptr),
        m_cur_blob_page_no(FIL_NULL) {}

  /** Start the BLOB mtr.
  @return pointer to the BLOB mtr. */
  mtr_t *start_blob_mtr() {
    mtr_start(&m_blob_mtr);
    m_blob_mtr.set_log_mode(m_ctx->get_log_mode());
    m_blob_mtr.set_flush_observer(m_ctx->get_flush_observer());
    return (&m_blob_mtr);
  }

  /** Allocate one BLOB page.
  @return the allocated block of the BLOB page. */
  buf_block_t *alloc_blob_page();

  /** Get the previous BLOB page frame.  This will return a BLOB page.
  It should not be called for the first BLOB page, because it will not
  have a previous BLOB page.
  @return       the previous BLOB page frame. */
  page_t *get_previous_blob_page();

  /** Get the previous BLOB page block.  This will return a BLOB block.
  It should not be called for the first BLOB page, because it will not
  have a previous BLOB page.
  @return       the previous BLOB block. */
  buf_block_t *get_previous_blob_block();

  /** Check if the index is SDI index
  @return true if index is SDI index else false */
  bool is_index_sdi() { return (dict_index_is_sdi(m_ctx->index())); }

  /** Get the current BLOB page frame.
  @return the current BLOB page frame. */
  page_t *cur_page() const { return (buf_block_get_frame(m_cur_blob_block)); }

 protected:
  /** The BLOB operation context */
  InsertContext *m_ctx;

  /** Success or failure status of the operation so far. */
  dberr_t m_err;

  /** The mini trx used to write into blob pages */
  mtr_t m_blob_mtr;

  /** The previous BLOB page number.  This is needed to maintain
  the linked list of BLOB pages. */
  page_no_t m_prev_page_no;

  /** The current BLOB buf_block_t object. */
  buf_block_t *m_cur_blob_block;

  /** The current BLOB page number. */
  page_no_t m_cur_blob_page_no;
};

/** Insert or write an uncompressed BLOB */
class Inserter : private BaseInserter {
 public:
  /** Constructor.
  @param[in]    ctx     blob operation context. */
  Inserter(InsertContext *ctx) : BaseInserter(ctx) {}

  /** Destructor. */
  ~Inserter() = default;

  /** Write all the BLOBs of the clustered index record.
  @return DB_SUCCESS on success, error code on failure. */
  dberr_t write();

  /** Write one blob field data.
  @param[in]    blob_j  the blob field number
  @return DB_SUCCESS on success, error code on failure. */
  dberr_t write_one_blob(size_t blob_j);

  /** Write one blob field data.
  @param[in]    blob_j  the blob field number
  @return DB_SUCCESS on success, error code on failure. */
  dberr_t write_one_small_blob(size_t blob_j);

  /** Write one blob page.  This function will be repeatedly called
  with an increasing nth_blob_page to completely write a BLOB.
  @param[in]    field           the big record field.
  @param[in]    nth_blob_page   count of the BLOB page (starting from 1).
  @return DB_SUCCESS or DB_FAIL. */
  dberr_t write_single_blob_page(big_rec_field_t &field, ulint nth_blob_page);

  /** Check if the BLOB operation has reported any errors.
  @return       true if BLOB operation is successful, false otherwise. */
  bool is_ok() const { return (m_err == DB_SUCCESS); }

  /** Make the current page as next page of previous page.  In other
  words, make the page m_cur_blob_page_no as the next page of page
  m_prev_page_no. */
  void set_page_next();

  /** Write the page type of the current BLOB page and also generate the
  redo log record. */
  void log_page_type() {
    page_type_t page_type;
    page_t *blob_page = cur_page();

    if (is_index_sdi()) {
      page_type = FIL_PAGE_SDI_BLOB;
    } else {
      page_type = FIL_PAGE_TYPE_BLOB;
    }

    mlog_write_ulint(blob_page + FIL_PAGE_TYPE, page_type, MLOG_2BYTES,
                     &m_blob_mtr);
  }

  /** Calculate the payload size of the BLOB page.
  @return       payload size in bytes. */
  ulint payload() const {
    const page_size_t page_size = m_ctx->page_size();
    const ulint payload_size =
        page_size.physical() - FIL_PAGE_DATA - LOB_HDR_SIZE - FIL_PAGE_DATA_END;
    return (payload_size);
  }

  /** Write contents into a single BLOB page.
  @param[in]    field           the big record field. */
  void write_into_single_page(big_rec_field_t &field);

  /** Write first blob page.
  @param[in]    field   the big record field.
  @return DB_SUCCESS on success. */
  dberr_t write_first_page(big_rec_field_t &field);

 private:
  /** The BLOB directory information. */
  blob_dir_t m_dir;

  /** Data remaining to be written. */
  ulint m_remaining;
};

}  // namespace lob

#endif /* lob0ins_h */