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