MySQL
8.1.0
Source Code Documentation
header.h
Go to the documentation of this file.
1
/* Copyright (c) 2019, 2023, Oracle and/or its affiliates.
2
3
This program is free software; you can redistribute it and/or modify it under
4
the terms of the GNU General Public License, version 2.0, as published by the
5
Free Software Foundation.
6
7
This program is also distributed with certain software (including but not
8
limited to OpenSSL) that is licensed under separate terms, as designated in a
9
particular file or component or in included license documentation. The authors
10
of MySQL hereby grant you an additional permission to link the program and
11
your derivative works with the separately licensed software that they have
12
included with MySQL.
13
14
This program is distributed in the hope that it will be useful, but WITHOUT
15
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16
FOR A PARTICULAR PURPOSE. See the GNU General Public License, version 2.0,
17
for more details.
18
19
You should have received a copy of the GNU General Public License along with
20
this program; if not, write to the Free Software Foundation, Inc.,
21
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
22
23
/** @file storage/temptable/include/temptable/header.h
24
Header abstraction for temptable Block allocator. Each Block is described by
25
header. */
26
27
#ifndef TEMPTABLE_HEADER_H
28
#define TEMPTABLE_HEADER_H
29
30
#include <assert.h>
31
#include <cstddef>
// size_t
32
#include <cstdint>
// uint8_t, uintptr_t
33
34
#include "
storage/temptable/include/temptable/memutils.h
"
// Source
35
36
namespace
temptable
{
37
38
/** Header is an abstraction with the purpose of holding and maintaining
39
* the Block metadata.
40
*
41
* Block metadata has the following structure:
42
* - N bytes for the block type which indicates where the block
43
* memory was allocated from.
44
* - N bytes for the block size (set at block creation and never
45
* changed later).
46
* - N bytes for the number of used/allocated chunks from this
47
* block (set to 0 at block creation).
48
* - N bytes for the offset of the first byte relative to the
49
* block start that is free and can be used by the next allocation request
50
* (set to 4 * N at block creation). We call this first pristine offset.
51
*
52
* That implies Chunks occupy the following range in memory:
53
* - bytes [4 * N, block size) a sequence of chunks appended to each other.
54
*
55
* 1st byte of [0, N) region is an actual pointer returned by memory
56
* allocation functions (e.g. malloc/new/mmap/etc.). Given that we are working
57
* with contiguous memory, storing that byte (offset) is just enough to be
58
* able to build-up and deduce Header metadata structure.
59
*
60
* Part of the Header contract is to have its metadata properly aligned in
61
* memory. Given that this memory is provided by the Block, Header
62
* implements debug-asserts to actually check if this condition has been met.
63
* If that was not the case, then accessing unaligned memory addresses would:
64
* 1. Incur performance penalty cost on architectures which can
65
* handle misaligned memory access (e.g. x86).
66
* 2. Result with a CPU trap (exception) on architectures which
67
* cannot handle misaligned memory access (e.g. SPARC).
68
*
69
* In order to maintain proper memory alignment of the whole metadata structure,
70
* CPU word-size data-type is used. Our N is defined by the size of that type
71
* (Header::metadata_type).
72
* */
73
class
Header
{
74
public
:
75
/** Type that we will be using for storing metadata information. */
76
using
metadata_type
= uintptr_t;
77
78
/** Block header (metadata) size. As described, there are 4 elements. */
79
static
constexpr
size_t
SIZE
= 4 *
sizeof
(
Header::metadata_type
);
80
81
public
:
82
/** Get the Block Source type (memory where it resides).
83
*
84
* @return One of Source values */
85
Source
memory_source_type
()
const
;
86
87
/** Get the Block size.
88
*
89
* @return Size of the Block */
90
size_t
block_size
()
const
;
91
92
/** Get current number of Chunks allocated by the Block.
93
*
94
* @return Number of Chunks allocated by this Block */
95
size_t
number_of_used_chunks
()
const
;
96
97
/** Get current first-pristine-offset. This offset is always relative to the
98
* block start (block-address).
99
*
100
* @return Offset relative to the block start */
101
size_t
first_pristine_offset
()
const
;
102
103
protected
:
104
/** Default constructor which creates an empty Header. */
105
Header
() noexcept;
106
107
/** Constructor which initializes the Header metadata when
108
* constructing fresh Blocks.
109
*
110
* [in] Pointer to the allocated Block memory.
111
* [in] Source where Block has allocated actual memory from.
112
* [in] Size of the Block */
113
Header
(uint8_t *block_memory,
Source
block_memory_type,
114
size_t
block_size
) noexcept;
115
116
/** Constructor which initializes the Header metadata from
117
* already existing Blocks in memory (e.g. ones that are
118
* deduced from Chunks).
119
*
120
* [in] Pointer to the existing Block. */
121
explicit
Header
(uint8_t *block_memory) noexcept;
122
123
/** Enable Block to get the next available slot that it can use for next
124
* Chunk allocation.
125
*
126
* @return An absolute memory-location offset */
127
uint8_t *
next_available_slot
() const;
128
129
/** Enable Block to get its memory address.
130
*
131
* @return An address where Block was allocated from. */
132
uint8_t *
block_address
() const;
133
134
/** Enable Block to increment the reference-count when (logically)
135
* allocating new Chunks.
136
*
137
* [in] Size of the Chunk.
138
* @return New number of Chunks used/allocated by the Block after this
139
* operation. */
140
size_t
increment_number_of_used_chunks
(
size_t
chunk_size);
141
142
/** Enable Block to decrement the reference-count when (logically)
143
* deallocating existing Chunks.
144
*
145
* [in] Size of the Chunk.
146
* [in] Boolean which denotes if Chunk being deallocated is the
147
* last (rightmost) one.
148
* @return New number of Chunks used/allocated by the Block after this
149
* operation. */
150
size_t
decrement_number_of_used_chunks
(
size_t
chunk_size,
151
bool
rightmost_chunk);
152
153
/** Enable Block to reset the Header metadata upon Block destruction. */
154
void
reset
();
155
156
private:
157
/** Deduce a pointer to the memory type of given Block. */
158
static
Header
::
metadata_type
*
block_memory_type_ptr
(uint8_t *block);
159
/** Deduce a pointer to the size of given Block. */
160
static
Header
::
metadata_type
*
block_size_ptr
(uint8_t *block);
161
/** Deduce a pointer to the number of used/allocated Chunks of given Block. */
162
static
Header
::
metadata_type
*
block_number_of_used_chunks_ptr
(uint8_t *block);
163
/** Deduce a pointer to the first-pristine-offset of given Block. */
164
static
Header
::
metadata_type
*
block_first_pristine_offset_ptr
(uint8_t *block);
165
166
private:
167
/** A pointer to the allocated Block memory which is used to deduce all
168
* of the other remaining metadata structure. */
169
uint8_t *
m_offset
;
170
};
171
172
inline
Header
::
Header
() noexcept :
Header
(
nullptr
) {}
173
174
inline
Header::Header
(uint8_t *block_memory) noexcept :
m_offset
(block_memory) {
175
assert(
reinterpret_cast<
Header::metadata_type
>
(
m_offset
) %
176
alignof
(
Header::metadata_type
) ==
177
0);
178
}
179
180
inline
Header::Header
(uint8_t *block_memory,
Source
block_memory_type,
181
size_t
block_size
) noexcept
182
:
Header
(block_memory) {
183
*
block_memory_type_ptr
(
m_offset
) =
184
static_cast<
Header::metadata_type
>
(block_memory_type);
185
*
block_size_ptr
(
m_offset
) =
block_size
;
186
*
block_number_of_used_chunks_ptr
(
m_offset
) = 0;
187
*
block_first_pristine_offset_ptr
(
m_offset
) =
Header::SIZE
;
188
}
189
190
inline
uint8_t *
Header::next_available_slot
()
const
{
191
return
block_address
() + *
block_first_pristine_offset_ptr
(
m_offset
);
192
}
193
194
inline
uint8_t *
Header::block_address
()
const
{
return
m_offset
; }
195
196
inline
Source
Header::memory_source_type
()
const
{
197
return
static_cast<
Source
>
(*
block_memory_type_ptr
(
m_offset
));
198
}
199
200
inline
size_t
Header::block_size
()
const
{
201
return
static_cast<
size_t
>
(*
block_size_ptr
(
m_offset
));
202
}
203
204
inline
size_t
Header::number_of_used_chunks
()
const
{
205
return
static_cast<
size_t
>
(*
block_number_of_used_chunks_ptr
(
m_offset
));
206
}
207
208
inline
size_t
Header::first_pristine_offset
()
const
{
209
return
static_cast<
size_t
>
(*
block_first_pristine_offset_ptr
(
m_offset
));
210
}
211
212
inline
size_t
Header::increment_number_of_used_chunks
(
size_t
chunk_size) {
213
*
block_first_pristine_offset_ptr
(
m_offset
) += chunk_size;
214
return
++*
block_number_of_used_chunks_ptr
(
m_offset
);
215
}
216
217
inline
size_t
Header::decrement_number_of_used_chunks
(
size_t
chunk_size,
218
bool
rightmost_chunk) {
219
assert(*
block_number_of_used_chunks_ptr
(
m_offset
) > 0);
220
if
(--*
block_number_of_used_chunks_ptr
(
m_offset
) == 0) {
221
/* If we are freeing the leftmost chunk in this block, then
222
* first_pristine_offset mark can be reset, so that the memory region
223
* can be reused.
224
*/
225
*
block_first_pristine_offset_ptr
(
m_offset
) =
Header::SIZE
;
226
}
else
if
(rightmost_chunk) {
227
/* If we are freeing the rightmost chunk in this block, then lower the
228
* first_pristine_offset mark, so that the memory region can be reused.
229
*/
230
*
block_first_pristine_offset_ptr
(
m_offset
) -= chunk_size;
231
}
232
return
*
block_number_of_used_chunks_ptr
(
m_offset
);
233
}
234
235
inline
void
Header::reset
() {
m_offset
=
nullptr
; }
236
237
inline
Header::metadata_type
*
Header::block_memory_type_ptr
(uint8_t *block) {
238
return
reinterpret_cast<
Header::metadata_type
*
>
(block);
239
}
240
241
inline
Header::metadata_type
*
Header::block_size_ptr
(uint8_t *block) {
242
return
reinterpret_cast<
Header::metadata_type
*
>
(
243
block + 1 *
sizeof
(
Header::metadata_type
));
244
}
245
246
inline
Header::metadata_type
*
Header::block_number_of_used_chunks_ptr
(
247
uint8_t *block) {
248
return
reinterpret_cast<
Header::metadata_type
*
>
(
249
block + 2 *
sizeof
(
Header::metadata_type
));
250
}
251
252
inline
Header::metadata_type
*
Header::block_first_pristine_offset_ptr
(
253
uint8_t *block) {
254
return
reinterpret_cast<
Header::metadata_type
*
>
(
255
block + 3 *
sizeof
(
Header::metadata_type
));
256
}
257
258
}
/* namespace temptable */
259
260
#endif
/* TEMPTABLE_HEADER_H */
temptable::Header
Header is an abstraction with the purpose of holding and maintaining the Block metadata.
Definition:
header.h:73
temptable::Header::block_size_ptr
static Header::metadata_type * block_size_ptr(uint8_t *block)
Deduce a pointer to the size of given Block.
Definition:
header.h:241
temptable::Header::next_available_slot
uint8_t * next_available_slot() const
Enable Block to get the next available slot that it can use for next Chunk allocation.
Definition:
header.h:190
temptable::Header::metadata_type
uintptr_t metadata_type
Type that we will be using for storing metadata information.
Definition:
header.h:76
temptable::Header::block_size
size_t block_size() const
Get the Block size.
Definition:
header.h:200
temptable::Header::reset
void reset()
Enable Block to reset the Header metadata upon Block destruction.
Definition:
header.h:235
temptable::Header::memory_source_type
Source memory_source_type() const
Get the Block Source type (memory where it resides).
Definition:
header.h:196
temptable::Header::Header
Header() noexcept
Default constructor which creates an empty Header.
Definition:
header.h:172
temptable::Header::block_number_of_used_chunks_ptr
static Header::metadata_type * block_number_of_used_chunks_ptr(uint8_t *block)
Deduce a pointer to the number of used/allocated Chunks of given Block.
Definition:
header.h:246
temptable::Header::block_address
uint8_t * block_address() const
Enable Block to get its memory address.
Definition:
header.h:194
temptable::Header::increment_number_of_used_chunks
size_t increment_number_of_used_chunks(size_t chunk_size)
Enable Block to increment the reference-count when (logically) allocating new Chunks.
Definition:
header.h:212
temptable::Header::block_memory_type_ptr
static Header::metadata_type * block_memory_type_ptr(uint8_t *block)
Deduce a pointer to the memory type of given Block.
Definition:
header.h:237
temptable::Header::m_offset
uint8_t * m_offset
A pointer to the allocated Block memory which is used to deduce all of the other remaining metadata s...
Definition:
header.h:169
temptable::Header::block_first_pristine_offset_ptr
static Header::metadata_type * block_first_pristine_offset_ptr(uint8_t *block)
Deduce a pointer to the first-pristine-offset of given Block.
Definition:
header.h:252
temptable::Header::SIZE
static constexpr size_t SIZE
Block header (metadata) size.
Definition:
header.h:79
temptable::Header::decrement_number_of_used_chunks
size_t decrement_number_of_used_chunks(size_t chunk_size, bool rightmost_chunk)
Enable Block to decrement the reference-count when (logically) deallocating existing Chunks.
Definition:
header.h:217
temptable::Header::first_pristine_offset
size_t first_pristine_offset() const
Get current first-pristine-offset.
Definition:
header.h:208
temptable::Header::number_of_used_chunks
size_t number_of_used_chunks() const
Get current number of Chunks allocated by the Block.
Definition:
header.h:204
memutils.h
Memory utilities for temptable-allocator.
temptable
Definition:
allocator.h:44
temptable::Source
Source
Type of memory allocated.
Definition:
memutils.h:67
storage
temptable
include
temptable
header.h
Generated by
1.9.2