MySQL 8.0.40
Source Code Documentation
chunk.h
Go to the documentation of this file.
1/* Copyright (c) 2019, 2024, Oracle and/or its affiliates.
2
3This program is free software; you can redistribute it and/or modify it under
4the terms of the GNU General Public License, version 2.0, as published by the
5Free Software Foundation.
6
7This program is designed to work with certain software (including
8but not limited to OpenSSL) that is licensed under separate terms,
9as designated in a particular file or component or in included license
10documentation. The authors of MySQL hereby grant you an additional
11permission to link the program and your derivative works with the
12separately licensed software that they have either included with
13the program or referenced in the documentation.
14
15This program is distributed in the hope that it will be useful, but WITHOUT
16ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17FOR A PARTICULAR PURPOSE. See the GNU General Public License, version 2.0,
18for more details.
19
20You should have received a copy of the GNU General Public License along with
21this program; if not, write to the Free Software Foundation, Inc.,
2251 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
23
24/** @file storage/temptable/include/temptable/chunk.h
25Chunk abstraction for temptable Block allocator. Block consists of 1..N
26chunks.*/
27
28#ifndef TEMPTABLE_CHUNK_H
29#define TEMPTABLE_CHUNK_H
30
31#include <assert.h>
32#include <cstddef> // size_t
33#include <cstdint> // uint8_t, uintptr_t
34#include <type_traits> // std::alignment_of
35
36namespace temptable {
37
38/** Chunk is an abstraction with the purpose of representing a smallest logical
39 * memory-unit within the Block. Block allocations and deallocations are
40 * served in Chunks.
41 *
42 * Chunk structure is:
43 * - bytes [0, 7]: 8 bytes that designate the relative offset of the chunk from
44 * the start of the belonging block. This is used in order to be able to
45 * deduce the block start from a given chunk.
46 * - bytes [8, chunk size): actual user data, pointer to this is returned to the
47 * user after a successful allocation request.
48 *
49 * As it can be seen, Chunk doesn't hold almost any information (e.g. its size)
50 * but merely an offset relative to the Block address it belongs to. That's
51 * what it enables Block to implement allocations and deallocations in
52 * constant-time.
53 *
54 * Part of the Chunk contract is to have its metadata properly aligned in
55 * memory. Given that this memory is provided by the Block, Chunk
56 * implements debug-asserts to actually check if this condition has been met.
57 * If that was not the case, then accessing unaligned memory addresses would:
58 * 1. Incur performance penalty cost on architectures which can
59 * handle misaligned memory access (e.g. x86).
60 * 2. Result with a CPU trap (exception) on architectures which
61 * cannot handle misaligned memory access (e.g. SPARC).
62 *
63 * OTOH, checking if Chunk user data is properly aligned is not possible from
64 * this context because actual data-type is not known to a Chunk. This check
65 * however shall be implemented in the context where the type is known (e.g.
66 * Allocator)
67 * */
68class Chunk {
69 public:
70 /** Type that we will be using for storing metadata information. */
71 using metadata_type = uintptr_t;
72
73 /** Chunk metadata size. As described, there is only 1 element. */
74 static constexpr size_t METADATA_SIZE = sizeof(Chunk::metadata_type);
75
76 public:
77 /** Constructor which Block will use to create a fresh Chunk object at the
78 * given memory-offset.
79 *
80 * [in] Pointer to the actual memory-location where Chunk will be located at.
81 * [in] Offset relative to address of a Block that is creating this Chunk. */
82 Chunk(uint8_t *offset, size_t new_offset) noexcept;
83
84 /** Constructor which Block will use to re-create Chunk object from
85 * user-provided pointer which points to the data section of already existing
86 * Chunk in memory. This pointer is returned to the user upon every Chunk
87 * allocation.
88 *
89 * [in] Pointer to the data section of existing Chunk. */
90 explicit Chunk(void *data) noexcept;
91
92 /** Deduce the memory-address of belonging Block.
93 *
94 * @return Memory-address of a Block this Chunk belongs to. */
95 uint8_t *block() const;
96
97 /** Get the Chunk offset relative to the start of belonging Block.
98 *
99 * @return Offset relative to the start of belonging Block. */
100 size_t offset() const;
101
102 /** Get the pointer to the data section which will be provided to the
103 * end-user.
104 *
105 * @return Pointer to memory which will be used by the end-user. */
106 uint8_t *data() const;
107
108 /** For given size, how much memory will be occupied by the Chunk.
109 * This calculation takes into account both the metadata and data payload.
110 *
111 * [in] Data payload size in bytes.
112 * @return Size Chunk will occupy for given n_bytes. */
113 static size_t size_hint(size_t n_bytes);
114
115 private:
116 /** Deduce a pointer to the offset of given Chunk.
117 *
118 * [in] Pointer to the first memory location (m_offset) which represents the
119 * chunk.
120 * @return Pointer to the memory location which represents the chunk offset.
121 */
122 static Chunk::metadata_type *chunk_offset_ptr(uint8_t *chunk);
123 /** Deduce a pointer to the data payload of given Chunk.
124 *
125 * [in] Pointer to the first memory location (m_offset) which represents the
126 * chunk.
127 * @return Pointer to the memory location which represents the chunk data
128 * (payload). */
129 static uint8_t *chunk_data_ptr(uint8_t *chunk);
130
131 private:
132 /** A pointer to the actual memory-location where Chunk is located at. */
133 uint8_t *m_offset;
134};
135
136inline Chunk::Chunk(void *data) noexcept
137 : m_offset(reinterpret_cast<uint8_t *>(data) -
138 sizeof(Chunk::metadata_type)) {
139 assert(reinterpret_cast<Chunk::metadata_type>(m_offset) %
140 alignof(Chunk::metadata_type) ==
141 0);
142}
143
144inline Chunk::Chunk(uint8_t *offset, size_t new_offset) noexcept
145 : m_offset(offset) {
146 assert(reinterpret_cast<Chunk::metadata_type>(m_offset) %
147 alignof(Chunk::metadata_type) ==
148 0);
149 *chunk_offset_ptr(m_offset) = new_offset;
150}
151
152inline uint8_t *Chunk::block() const { return m_offset - offset(); }
153
154inline size_t Chunk::offset() const {
155 return static_cast<size_t>(*chunk_offset_ptr(m_offset));
156}
157
158inline uint8_t *Chunk::data() const { return chunk_data_ptr(m_offset); }
159
160inline size_t Chunk::size_hint(size_t n_bytes) {
161 return Chunk::METADATA_SIZE + n_bytes;
162}
163
165 return reinterpret_cast<Chunk::metadata_type *>(chunk);
166}
167
168inline uint8_t *Chunk::chunk_data_ptr(uint8_t *chunk) {
169 return chunk + sizeof(Chunk::metadata_type);
170}
171
172} /* namespace temptable */
173
174#endif /* TEMPTABLE_CHUNK_H */
Chunk is an abstraction with the purpose of representing a smallest logical memory-unit within the Bl...
Definition: chunk.h:68
static Chunk::metadata_type * chunk_offset_ptr(uint8_t *chunk)
Deduce a pointer to the offset of given Chunk.
Definition: chunk.h:164
size_t offset() const
Get the Chunk offset relative to the start of belonging Block.
Definition: chunk.h:154
static constexpr size_t METADATA_SIZE
Chunk metadata size.
Definition: chunk.h:74
Chunk(uint8_t *offset, size_t new_offset) noexcept
Constructor which Block will use to create a fresh Chunk object at the given memory-offset.
Definition: chunk.h:144
static uint8_t * chunk_data_ptr(uint8_t *chunk)
Deduce a pointer to the data payload of given Chunk.
Definition: chunk.h:168
uintptr_t metadata_type
Type that we will be using for storing metadata information.
Definition: chunk.h:71
uint8_t * data() const
Get the pointer to the data section which will be provided to the end-user.
Definition: chunk.h:158
static size_t size_hint(size_t n_bytes)
For given size, how much memory will be occupied by the Chunk.
Definition: chunk.h:160
uint8_t * m_offset
A pointer to the actual memory-location where Chunk is located at.
Definition: chunk.h:133
uint8_t * block() const
Deduce the memory-address of belonging Block.
Definition: chunk.h:152
Definition: allocator.h:45