summaryrefslogtreecommitdiff
path: root/storage/innobase/include/buf0types.h
blob: c69c07d66e12a90c224151626cb48cf2f731d193 (plain)
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
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
/*****************************************************************************

Copyright (c) 1995, 2015, Oracle and/or its affiliates. All rights reserved.
Copyright (c) 2019, 2022, MariaDB Corporation.

This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; version 2 of the License.

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 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 Street, Fifth Floor, Boston, MA 02110-1335 USA

*****************************************************************************/

/**************************************************//**
@file include/buf0types.h
The database buffer pool global types for the directory

Created 11/17/1995 Heikki Tuuri
*******************************************************/

#pragma once
#include "univ.i"

/** Buffer page (uncompressed or compressed) */
class buf_page_t;
/** Buffer block for which an uncompressed page exists */
struct buf_block_t;
/** Buffer pool statistics struct */
struct buf_pool_stat_t;
/** Buffer pool buddy statistics struct */
struct buf_buddy_stat_t;

/** A buffer frame. @see page_t */
typedef	byte	buf_frame_t;

/** Alternatives for srv_checksum_algorithm, which can be changed by
setting innodb_checksum_algorithm */
enum srv_checksum_algorithm_t {
  /** Write crc32; allow full_crc32,crc32,innodb,none when reading */
  SRV_CHECKSUM_ALGORITHM_CRC32,
  /** Write crc32; allow full_crc23,crc32 when reading */
  SRV_CHECKSUM_ALGORITHM_STRICT_CRC32,
  /** For new files, always compute CRC-32C for the whole page.
  For old files, allow crc32, innodb or none when reading. */
  SRV_CHECKSUM_ALGORITHM_FULL_CRC32,
  /** For new files, always compute CRC-32C for the whole page.
  For old files, allow crc32 when reading. */
  SRV_CHECKSUM_ALGORITHM_STRICT_FULL_CRC32
};

inline bool is_checksum_strict(srv_checksum_algorithm_t algo)
{
  return algo == SRV_CHECKSUM_ALGORITHM_STRICT_CRC32;
}

inline bool is_checksum_strict(ulint algo)
{
  return algo == SRV_CHECKSUM_ALGORITHM_STRICT_CRC32;
}

/** Parameters of binary buddy system for compressed pages (buf0buddy.h) */
/* @{ */
/** Zip shift value for the smallest page size */
#define BUF_BUDDY_LOW_SHIFT	UNIV_ZIP_SIZE_SHIFT_MIN

/** Smallest buddy page size */
#define BUF_BUDDY_LOW		(1U << BUF_BUDDY_LOW_SHIFT)

/** Actual number of buddy sizes based on current page size */
#define BUF_BUDDY_SIZES		(srv_page_size_shift - BUF_BUDDY_LOW_SHIFT)

/** Maximum number of buddy sizes based on the max page size */
#define BUF_BUDDY_SIZES_MAX	(UNIV_PAGE_SIZE_SHIFT_MAX	\
				- BUF_BUDDY_LOW_SHIFT)

/** twice the maximum block size of the buddy system;
the underlying memory is aligned by this amount:
this must be equal to srv_page_size */
#define BUF_BUDDY_HIGH	(BUF_BUDDY_LOW << BUF_BUDDY_SIZES)
/* @} */

/** Page identifier. */
class page_id_t
{
public:
  /** Constructor from (space, page_no).
  @param[in]	space	tablespace id
  @param[in]	page_no	page number */
  constexpr page_id_t(ulint space, uint32_t page_no) :
    m_id(uint64_t{space} << 32 | page_no) {}

  constexpr page_id_t(uint64_t id) : m_id(id) {}
  constexpr bool operator==(const page_id_t& rhs) const
  { return m_id == rhs.m_id; }
  constexpr bool operator!=(const page_id_t& rhs) const
  { return m_id != rhs.m_id; }
  constexpr bool operator<(const page_id_t& rhs) const
  { return m_id < rhs.m_id; }
  constexpr bool operator>(const page_id_t& rhs) const
  { return m_id > rhs.m_id; }
  constexpr bool operator<=(const page_id_t& rhs) const
  { return m_id <= rhs.m_id; }
  constexpr bool operator>=(const page_id_t& rhs) const
  { return m_id >= rhs.m_id; }
  page_id_t &operator--() { ut_ad(page_no()); m_id--; return *this; }
  page_id_t &operator++()
  {
    ut_ad(page_no() < 0xFFFFFFFFU);
    m_id++;
    return *this;
  }
  page_id_t operator-(uint32_t i) const
  {
    ut_ad(page_no() >= i);
    return page_id_t(m_id - i);
  }
  page_id_t operator+(uint32_t i) const
  {
    ut_ad(page_no() < ~i);
    return page_id_t(m_id + i);
  }

  /** Retrieve the tablespace id.
  @return tablespace id */
  constexpr uint32_t space() const { return static_cast<uint32_t>(m_id >> 32); }

  /** Retrieve the page number.
  @return page number */
  constexpr uint32_t page_no() const { return static_cast<uint32_t>(m_id); }

  /** Retrieve the fold value.
  @return fold value */
  constexpr ulint fold() const
  { return (ulint{space()} << 20) + space() + page_no(); }

  /** Reset the page number only.
  @param[in]	page_no	page number */
  void set_page_no(uint32_t page_no)
  {
    m_id= (m_id & ~uint64_t{0} << 32) | page_no;
  }

  constexpr ulonglong raw() const { return m_id; }

  /** Flag the page identifier as corrupted. */
  void set_corrupted() { m_id= ~0ULL; }

  /** @return whether the page identifier belongs to a corrupted page */
  constexpr bool is_corrupted() const { return m_id == ~0ULL; }

private:
  /** The page identifier */
  uint64_t m_id;
};

/** A 64KiB buffer of NUL bytes, for use in assertions and checks,
and dummy default values of instantly dropped columns.
Initially, BLOB field references are set to NUL bytes, in
dtuple_convert_big_rec(). */
extern const byte *field_ref_zero;

#ifndef UNIV_INNOCHECKSUM

/** Latch types */
enum rw_lock_type_t
{
  RW_S_LATCH= 1 << 0,
  RW_X_LATCH= 1 << 1,
  RW_SX_LATCH= 1 << 2,
  RW_NO_LATCH= 1 << 3
};

#include "sux_lock.h"

#ifdef SUX_LOCK_GENERIC
class page_hash_latch : private rw_lock
{
  /** Wait for a shared lock */
  void read_lock_wait();
  /** Wait for an exclusive lock */
  void write_lock_wait();
public:
  /** Acquire a shared lock */
  inline void lock_shared();
  /** Acquire an exclusive lock */
  inline void lock();

  /** @return whether an exclusive lock is being held by any thread */
  bool is_write_locked() const { return rw_lock::is_write_locked(); }

  /** @return whether any lock is being held by any thread */
  bool is_locked() const { return rw_lock::is_locked(); }
  /** @return whether any lock is being held or waited for by any thread */
  bool is_locked_or_waiting() const { return rw_lock::is_locked_or_waiting(); }

  /** Release a shared lock */
  void unlock_shared() { read_unlock(); }
  /** Release an exclusive lock */
  void unlock() { write_unlock(); }
};
#elif defined _WIN32 || SIZEOF_SIZE_T >= 8
class page_hash_latch
{
  srw_spin_lock_low lk;
public:
  void lock_shared() { lk.rd_lock(); }
  void unlock_shared() { lk.rd_unlock(); }
  void lock() { lk.wr_lock(); }
  void unlock() { lk.wr_unlock(); }
  bool is_write_locked() const { return lk.is_write_locked(); }
  bool is_locked() const { return lk.is_locked(); }
  bool is_locked_or_waiting() const { return lk.is_locked_or_waiting(); }
};
#else
class page_hash_latch
{
  srw_spin_mutex lk;
public:
  void lock_shared() { lock(); }
  void unlock_shared() { unlock(); }
  void lock() { lk.wr_lock(); }
  void unlock() { lk.wr_unlock(); }
  bool is_locked() const { return lk.is_locked(); }
  bool is_write_locked() const { return is_locked(); }
  bool is_locked_or_waiting() const { return is_locked(); }
};
#endif

#endif /* !UNIV_INNOCHECKSUM */