MySQL 8.4.2
Source Code Documentation
allocator.h
Go to the documentation of this file.
1/* Copyright (c) 2016, 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/allocator.h
25TempTable custom allocator. */
26
27#ifndef TEMPTABLE_ALLOCATOR_H
28#define TEMPTABLE_ALLOCATOR_H
29
30#include <algorithm> // std::max
31#include <cstddef> // size_t
32#include <limits> // std::numeric_limits
33#include <memory> // std::shared_ptr
34#include <new> // new
35#include <utility> // std::forward
36
37#include "my_dbug.h"
38#include "my_sys.h"
39#include "sql/mysqld.h" // temptable_max_ram, temptable_max_mmap
44
45namespace temptable {
46
47/* Thin abstraction which enables logging of memory operations.
48 *
49 * Used by the Allocator to implement switching from RAM to MMAP-backed
50 * allocations and vice-versa. E.g. Allocator will switch to MMAP-backed
51 * allocation strategy once temptable RAM-consumption threshold, which is
52 * defined by temptable_max_ram user-modifiable variable, is reached.
53 **/
55 struct RAM {
56 /** Log increments of heap-memory consumption.
57 *
58 * [in] Number of bytes.
59 * @return Heap-memory consumption after increase. */
60 static size_t increase(size_t bytes) {
61 assert(ram <= std::numeric_limits<decltype(bytes)>::max() - bytes);
62 return ram.fetch_add(bytes) + bytes;
63 }
64 /** Log decrements of heap-memory consumption.
65 *
66 * [in] Number of bytes.
67 * @return Heap-memory consumption after decrease. */
68 static size_t decrease(size_t bytes) {
69 assert(ram >= bytes);
70 return ram.fetch_sub(bytes) - bytes;
71 }
72 /** Get heap-memory threshold level. Level is defined by this Allocator.
73 *
74 * @return Heap-memory threshold. */
75 static size_t threshold() { return temptable_max_ram; }
76 /** Get current level of heap-memory consumption.
77 *
78 * @return Current level of heap-memory consumption (in bytes). */
79 static size_t consumption() { return ram; }
80 };
81
82 struct MMAP {
83 /** Log increments of MMAP-backed memory consumption.
84 *
85 * [in] Number of bytes.
86 * @return MMAP-memory consumption after increase. */
87 static size_t increase(size_t bytes) {
88 assert(mmap <= std::numeric_limits<decltype(bytes)>::max() - bytes);
89 return mmap.fetch_add(bytes) + bytes;
90 }
91 /** Log decrements of MMAP-backed memory consumption.
92 *
93 * [in] Number of bytes.
94 * @return MMAP-memory consumption after decrease. */
95 static size_t decrease(size_t bytes) {
96 assert(mmap >= bytes);
97 return mmap.fetch_sub(bytes) - bytes;
98 }
99 /** Get MMAP-backed memory threshold level. Level is defined by this
100 * Allocator.
101 *
102 * @return MMAP-memory threshold. */
103 static size_t threshold() {
104 if (temptable_use_mmap) {
105 return temptable_max_mmap;
106 } else {
107 return 0;
108 }
109 }
110 /** Get current level of MMAP-backed memory consumption.
111 *
112 * @return Current level of MMAP-backed memory consumption (in bytes). */
113 static size_t consumption() { return mmap; }
114 };
115
116 private:
117 /** Total bytes allocated so far by all threads in RAM/MMAP. */
118 static std::atomic<size_t> ram;
119 static std::atomic<size_t> mmap;
120};
121
122/* Thin abstraction which enables logging of how much resources have been
123 * consumed at the per-table level. Each temptable::Table will be composed
124 * of this type so that the temptable::Allocator through its policies can
125 * monitor its memory consumption and act appropriately when threshold
126 * is reached.
127 **/
129 public:
132
133 size_t increase(size_t bytes) {
134 assert(m_total_bytes <=
135 std::numeric_limits<decltype(bytes)>::max() - bytes);
136 m_total_bytes += bytes;
137 return m_total_bytes;
138 }
139 size_t decrease(size_t bytes) {
140 assert(m_total_bytes >= bytes);
141 m_total_bytes -= bytes;
142 return m_total_bytes;
143 }
144 size_t threshold() { return m_threshold; }
145 size_t consumption() { return m_total_bytes; }
146
147 private:
150};
151
152/* Allocation scheme, a type which controls allocation patterns in TempTable
153 * allocator.
154 *
155 * In particular, allocation scheme can define the behavior of TempTable
156 * allocator allocations with respect to the following:
157 * 1. Where each consecutive Block of memory is going to be allocated from
158 * (e.g. RAM vs MMAP vs etc.)
159 * 2. How big each consecutive Block of memory is going to be
160 * (e.g. monotonic growth, exponential growth, no growth, etc.)
161 *
162 * Concrete implementations of previous points must be provided through
163 * customization points, namely Block_size_policy and Block_source_policy,
164 * template type parameters. Whatever these types are, they must provide
165 * conforming interface implementations.
166 *
167 * Block_size_policy customization point must provide concrete implementation
168 * with the following signature:
169 * static size_t block_size(size_t, size_t);
170 * Similarly, concrete implementations of Block_source_policy must provide:
171 * static Source block_source(size_t);
172 *
173 * That allows us to build different concrete allocation schemes by simply
174 * composing different customization points. For example:
175 *
176 * using Monotonic_growth_RAM_only =
177 * Allocation_scheme<Monotonic_policy, RAM_only_policy>;
178 *
179 * using Exponential_growth_RAM_only =
180 * Allocation_scheme<Exponential_policy, RAM_only_policy>;
181 *
182 * using Exponential_growth_preferring_RAM_over_MMAP =
183 * Allocation_scheme<Exponential_policy, Prefer_RAM_over_MMAP_policy>;
184 *
185 * using No_growth_RAM_only =
186 * Allocation_scheme<No_growth_policy, RAM_only_policy>;
187 *
188 * etc. etc.
189 *
190 */
191template <typename Block_size_policy, typename Block_source_policy>
194 return Block_source_policy::block_source(block_size);
195 }
196 static size_t block_size(size_t number_of_blocks, size_t n_bytes_requested) {
197 return Block_size_policy::block_size(number_of_blocks, n_bytes_requested);
198 }
199 static void block_freed(uint32_t block_size, Source block_source) {
200 Block_source_policy::block_freed(block_size, block_source);
201 }
202};
203
204/* Concrete implementation of Block_source_policy, a type which controls where
205 * TempTable allocator is going to be allocating next Block of memory from.
206 *
207 * In particular, this policy will make TempTable allocator:
208 * 1. Use RAM as long as temptable_max_ram threshold is not reached.
209 * 2. Start using MMAP when temptable_max_ram threshold is reached.
210 * 3. Go back using RAM as soon as RAM consumption drops below the
211 * temptable_max_ram threshold and there is enough space to accommodate the
212 * new block given the size.
213 * 4. Not take into account per-table memory limits defined through
214 * tmp_table_size SYSVAR.
215 * */
217 static Source block_source(uint32_t block_size) {
219 if (MemoryMonitor::RAM::increase(block_size) <=
221 return Source::RAM;
222 } else {
224 }
225 }
227 if (MemoryMonitor::MMAP::increase(block_size) <=
229 return Source::MMAP_FILE;
230 } else {
232 }
233 }
235 }
236
237 static void block_freed(uint32_t block_size, Source block_source) {
238 if (block_source == Source::RAM) {
240 } else {
242 }
243 }
244};
245
246/* Concrete implementation of Block_size_policy, a type which controls how big
247 * next Block of memory is going to be allocated by TempTable allocator.
248 *
249 * In particular, this policy will make TempTable allocator to grow the
250 * block-size at exponential rate with upper limit of ALLOCATOR_MAX_BLOCK_BYTES,
251 * which is 2 ^ ALLOCATOR_MAX_BLOCK_MB_EXP.
252 *
253 * E.g. allocation pattern may look like the following:
254 * 1 MiB,
255 * 2 MiB,
256 * 4 MiB,
257 * 8 MiB,
258 * 16 MiB,
259 * 32 MiB,
260 * ...,
261 * ALLOCATOR_MAX_BLOCK_BYTES,
262 * ALLOCATOR_MAX_BLOCK_BYTES
263 *
264 * In cases when block size that is being requested is bigger than the one which
265 * is calculated by this policy, requested block size will be returned (even if
266 * it grows beyond ALLOCATOR_MAX_BLOCK_BYTES).
267 * */
269 /** Given the current number of allocated blocks by the allocator, and number
270 * of bytes actually requested by the client code, calculate the new block
271 * size.
272 *
273 * [in] Current number of allocated blocks.
274 * [in] Number of bytes requested by the client code.
275 * @return New block size. */
276 static size_t block_size(size_t number_of_blocks, size_t n_bytes_requested) {
277 size_t block_size_hint;
278 if (number_of_blocks < ALLOCATOR_MAX_BLOCK_MB_EXP) {
279 block_size_hint = (1ULL << number_of_blocks) * 1_MiB;
280 } else {
281 block_size_hint = ALLOCATOR_MAX_BLOCK_BYTES;
282 }
283 return std::max(block_size_hint, Block::size_hint(n_bytes_requested));
284 }
285};
286
287/* This is a concrete allocation scheme which is going to be default one for
288 * TempTable allocator.
289 *
290 * It uses exponential growth policy and policy which prefers RAM allocations
291 * over MMAP allocations.
292 */
295
296/**
297 Shared state between all instances of a given allocator.
298
299 STL allocators can (since C++11) carry state; however, that state should
300 never be mutable, as the allocator can be copy-constructed and rebound
301 without further notice, so e.g. deallocating memory in one allocator could
302 mean freeing a block that an earlier copy of the allocator still thinks is
303 valid.
304
305 Usually, mutable state will be external to the allocator (e.g.
306 Mem_root_allocator will point to a MEM_ROOT, but it won't own the MEM_ROOT);
307 however, TempTable was never written this way, and doesn't have a natural
308 place to stick the allocator state. Thus, we need a kludge where the
309 allocator's state is held in a shared_ptr, owned by all the instances
310 together. This is suboptimal for performance, and also is against the style
311 guide's recommendation to have clear ownership of objects, but at least it
312 avoids the use-after-free.
313 */
314template <class AllocationScheme>
316 public:
317 /**
318 * Destroys the state, deallocate the current_block if it was left empty.
319 */
320 ~AllocatorState() noexcept {
321 if (!current_block.is_empty()) {
323 }
324 /* User must deallocate all data from all blocks, otherwise the memory will
325 * be leaked.
326 */
327 assert(number_of_blocks == 0);
328 }
329
330 /**
331 * Gets a Block from which a new allocation of the specified size should be
332 * performed. It will use the current Block or create a new one if it is too
333 * small.
334 * [in] Number of bytes that will be allocated from the returned block.
335 */
336 Block *get_block_for_new_allocation(size_t n_bytes_requested) {
337 if (current_block.is_empty() ||
338 !current_block.can_accommodate(n_bytes_requested)) {
339 /* The current_block may have been left empty during some deallocate()
340 * call. It is the last opportunity to free it before we lose reference to
341 * it.
342 */
343 if (!current_block.is_empty() &&
346 }
347
348 const size_t block_size =
349 AllocationScheme::block_size(number_of_blocks, n_bytes_requested);
351 Block(block_size, AllocationScheme::block_source(block_size));
353 }
354 return &current_block;
355 }
356
357 /**
358 * Informs the state object of a block that has no data allocated inside of it
359 * anymore for garbage collection.
360 * [in] The empty block to manage and possibly free.
361 */
362 void block_is_not_used_anymore(Block block) noexcept {
363 if (block == current_block) {
364 /* Do nothing. Keep the last block alive. Some queries are repeatedly
365 * allocating one Row and freeing it, leading to constant allocation and
366 * deallocation of 1MB of memory for the current_block. Let's keep this
367 * block empty ready for a future use.
368 */
369 } else {
370 free_block(block);
371 }
372 }
373
374 private:
375 /**
376 * Frees the specified block and takes care of all accounting.
377 * [in] The empty block to free.
378 */
379 void free_block(Block &block) noexcept {
380 AllocationScheme::block_freed(block.size(), block.type());
381 block.destroy();
383 }
384
385 /** Current not-yet-full block to feed allocations from. */
387
388 /**
389 * Number of created blocks so far (by this Allocator object).
390 * We use this number only as a hint as to how big block to create when a
391 * new block needs to be created.
392 */
394};
395
396/** Custom memory allocator. All dynamic memory used by the TempTable engine
397 * is allocated through this allocator.
398 *
399 * The purpose of this allocator is to minimize the number of calls to the OS
400 * for allocating new memory (e.g. malloc()) and to improve the spatial
401 * locality of reference. It is able to do so quite easily thanks to the
402 * Block/Chunk entities it is implemented in terms of. Due to the design of
403 * these entities, it is also able to feed allocations and deallocations in
404 * (amortized) constant-time and keep being CPU memory-access friendly because
405 * of the internal self-adjustment to word-size memory alignment. To learn even
406 * more about specifics and more properties please have a look at the respective
407 * header files of Header/Block/Chunk class declarations.
408 *
409 * The most common use case, for which it is optimized,
410 * is to have the following performed by a single thread:
411 * - allocate many times (creation of a temp table and inserting data into it).
412 * - use the allocated memory (selects on the temp table).
413 * - free all the pieces (drop of the temp table).
414 *
415 * The allocator allocates memory from the OS in large blocks (e.g. a few MiB)
416 * whose size also increases progressively by the increasing number of
417 * allocation requests. Exact block-size increase progress is defined by the
418 * block allocation scheme which, by default, is set to
419 * AllocationScheme::Exponential.
420 *
421 * Allocator does not store a list of all allocated blocks but only keeps track
422 * of the current block which has not yet been entirely filled up and the
423 * overall number of allocated blocks. When current block gets filled up, new
424 * one is created and immediately made current.
425 *
426 * Furthermore, it always keeps the last block alive. It cannot be deallocated
427 * by the user. Last block is automatically deallocated at the thread exit.
428 *
429 * Allocator will also keep track of RAM-consumption and in case it reaches the
430 * threshold defined by temptable_max_ram, it will switch to MMAP-backed block
431 * allocations. It will switch back once RAM consumption is again below the
432 * threshold. */
433template <class T,
434 class AllocationScheme = Exponential_growth_preferring_RAM_over_MMAP>
436 static_assert(alignof(T) <= Block::ALIGN_TO,
437 "T's with alignment-requirement larger than "
438 "Block::ALIGN_TO are not supported.");
439 static_assert(sizeof(T) > 0, "Zero sized objects are not supported");
440
441 public:
442 typedef T *pointer;
443 typedef const T *const_pointer;
444 typedef T &reference;
445 typedef const T &const_reference;
446 typedef T value_type;
447 typedef size_t size_type;
448 typedef ptrdiff_t difference_type;
449
450 template <class U>
451 struct rebind {
453 };
454
455 /** Constructor. */
456 Allocator(Block *shared_block, TableResourceMonitor &table_resource_monitor);
457
458 /** Constructor from allocator of another type. The state is copied into the
459 * new object. */
460 template <class U>
461 Allocator(
462 /** [in] Source Allocator object. */
463 const Allocator<U> &other);
464
465 /** Move constructor from allocator of another type. */
466 template <class U>
467 Allocator(
468 /** [in,out] Source Allocator object. */
469 Allocator<U> &&other) noexcept;
470
471 /** Destructor. */
473
474 Allocator(const Allocator &) = default;
475
476 /** Assignment operator, not used, thus disabled. */
477 template <class U>
478 void operator=(const Allocator<U> &) = delete;
479
480 /** Move operator, not used, thus disabled. */
481 template <class U>
482 void operator=(const Allocator<U> &&) = delete;
483
484 /** Equality operator.
485 * @return true if equal */
486 template <class U>
487 bool operator==(
488 /** [in] Object to compare with. */
489 const Allocator<U> &rhs) const;
490
491 /** Inequality operator.
492 * @return true if not equal */
493 template <class U>
494 bool operator!=(
495 /** [in] Object to compare with. */
496 const Allocator<U> &rhs) const;
497
498 /** Allocate memory for storing `n_elements` number of elements. */
499 T *allocate(
500 /** [in] Number of elements that must be allocated. */
501 size_t n_elements);
502
503 /** Free a memory allocated by allocate(). */
504 void deallocate(
505 /** [in,out] Pointer to memory to free. */
506 T *ptr,
507 /** [in] Number of elements allocated. */
508 size_t n_elements);
509
510 /** Construct one object of type `U` on an already allocated chunk of memory,
511 * which must be large enough to store it. */
512 template <class U, class... Args>
513 void construct(
514 /** [in] Memory where to create the object. */
515 U *mem,
516 /** Arguments to pass to U's constructor. */
517 Args &&... args);
518
519 /** Destroy an object of type `U`. The memory is not returned to the OS, this
520 * is the counterpart of `construct()`. */
521 template <class U>
522 void destroy(
523 /** [in, out] Object to destroy. */
524 U *p);
525
526 /** Initialize necessary structures. Called once in the OS process lifetime,
527 * before other methods. */
528 static void init();
529
530 /**
531 Shared state between all the copies and rebinds of this allocator.
532 See AllocatorState for details.
533 */
534 std::shared_ptr<AllocatorState<AllocationScheme>> m_state;
535
536 /** A block of memory which is a state external to this allocator and can be
537 * shared among different instances of the allocator (not simultaneously). In
538 * order to speed up its operations, allocator may decide to consume the
539 * memory of this shared block.
540 */
542 /** Table resource monitor control mechanism that limits the amount of
543 * resources that can be consumed at the per-table level.
544 */
546};
547
548/* Implementation of inlined methods. */
549
550template <class T, class AllocationScheme>
552 Block *shared_block, TableResourceMonitor &table_resource_monitor)
553 : m_state(std::make_shared<AllocatorState<AllocationScheme>>()),
554 m_shared_block(shared_block),
555 m_table_resource_monitor(table_resource_monitor) {}
556
557template <class T, class AllocationScheme>
558template <class U>
560 : m_state(other.m_state),
561 m_shared_block(other.m_shared_block),
562 m_table_resource_monitor(other.m_table_resource_monitor) {}
563
564template <class T, class AllocationScheme>
565template <class U>
567 : m_state(std::move(other.m_state)),
568 m_shared_block(other.m_shared_block),
569 m_table_resource_monitor(other.m_table_resource_monitor) {}
570
571template <class T, class AllocationScheme>
573
574template <class T, class AllocationScheme>
575template <class U>
577 const Allocator<U> &) const {
578 return true;
579}
580
581template <class T, class AllocationScheme>
582template <class U>
584 const Allocator<U> &rhs) const {
585 return !(*this == rhs);
586}
587
588template <class T, class AllocationScheme>
589inline T *Allocator<T, AllocationScheme>::allocate(size_t n_elements) {
590 assert(n_elements <= std::numeric_limits<size_type>::max() / sizeof(T));
591 DBUG_EXECUTE_IF("temptable_allocator_oom", throw Result::OUT_OF_MEM;);
592 DBUG_EXECUTE_IF("temptable_allocator_record_file_full",
594
595 const size_t n_bytes_requested = n_elements * sizeof(T);
596 if (n_bytes_requested == 0) {
597 return nullptr;
598 }
599
600 Block *block;
601
602 if (m_shared_block && m_shared_block->is_empty()) {
603 const size_t block_size =
604 AllocationScheme::block_size(0, n_bytes_requested);
605 *m_shared_block =
606 Block(block_size, AllocationScheme::block_source(block_size));
607 block = m_shared_block;
608 } else if (m_shared_block &&
609 m_shared_block->can_accommodate(n_bytes_requested)) {
610 block = m_shared_block;
611 } else {
612 block = m_state->get_block_for_new_allocation(n_bytes_requested);
613 }
614
615 /* temptable::Table is allowed to fit no more data than the given threshold
616 * controlled through TableResourceMonitor abstraction. TableResourceMonitor
617 * is a simple abstraction which is in its part an alias for tmp_table_size, a
618 * system variable that end MySQL users will be using to control this
619 * threshold.
620 *
621 * Updating the tmp_table_size threshold can only be done through the separate
622 * SET statement which implies that the tmp_table_size threshold cannot be
623 * updated during the duration of some query which is running within the same
624 * session. Separate sessions can still of course change this value to their
625 * liking.
626 */
627 if (m_table_resource_monitor.consumption() + n_bytes_requested >
628 m_table_resource_monitor.threshold()) {
630 }
631 m_table_resource_monitor.increase(n_bytes_requested);
632
633 T *chunk_data =
634 reinterpret_cast<T *>(block->allocate(n_bytes_requested).data());
635 assert(reinterpret_cast<uintptr_t>(chunk_data) % alignof(T) == 0);
636 return chunk_data;
637}
638
639template <class T, class AllocationScheme>
641 size_t n_elements) {
642 assert(reinterpret_cast<uintptr_t>(chunk_data) % alignof(T) == 0);
643
644 if (chunk_data == nullptr) {
645 return;
646 }
647
648 const size_t n_bytes_requested = n_elements * sizeof(T);
649
650 Block block = Block(Chunk(chunk_data));
651 const auto remaining_chunks =
652 block.deallocate(Chunk(chunk_data), n_bytes_requested);
653 if (remaining_chunks == 0) {
654 if (m_shared_block && (block == *m_shared_block)) {
655 // Do nothing. Keep the last block alive.
656 } else {
657 m_state->block_is_not_used_anymore(block);
658 }
659 }
660 m_table_resource_monitor.decrease(n_bytes_requested);
661}
662
663template <class T, class AllocationScheme>
664template <class U, class... Args>
665inline void Allocator<T, AllocationScheme>::construct(U *mem, Args &&... args) {
666 new (mem) U(std::forward<Args>(args)...);
667}
668
669template <class T, class AllocationScheme>
670template <class U>
672 p->~U();
673}
674
675template <class T, class AllocationScheme>
678}
679
680} /* namespace temptable */
681
682#endif /* TEMPTABLE_ALLOCATOR_H */
Block abstraction for temptable-allocator.
Chunk abstraction for temptable Block allocator.
Shared state between all instances of a given allocator.
Definition: allocator.h:315
Block * get_block_for_new_allocation(size_t n_bytes_requested)
Gets a Block from which a new allocation of the specified size should be performed.
Definition: allocator.h:336
void block_is_not_used_anymore(Block block) noexcept
Informs the state object of a block that has no data allocated inside of it anymore for garbage colle...
Definition: allocator.h:362
size_t number_of_blocks
Number of created blocks so far (by this Allocator object).
Definition: allocator.h:393
Block current_block
Current not-yet-full block to feed allocations from.
Definition: allocator.h:386
void free_block(Block &block) noexcept
Frees the specified block and takes care of all accounting.
Definition: allocator.h:379
~AllocatorState() noexcept
Destroys the state, deallocate the current_block if it was left empty.
Definition: allocator.h:320
Custom memory allocator.
Definition: allocator.h:435
Block * m_shared_block
A block of memory which is a state external to this allocator and can be shared among different insta...
Definition: allocator.h:541
void construct(U *mem, Args &&... args)
Construct one object of type U on an already allocated chunk of memory, which must be large enough to...
Definition: allocator.h:665
T & reference
Definition: allocator.h:444
const T * const_pointer
Definition: allocator.h:443
void deallocate(T *ptr, size_t n_elements)
Free a memory allocated by allocate().
Definition: allocator.h:640
const T & const_reference
Definition: allocator.h:445
void operator=(const Allocator< U > &&)=delete
Move operator, not used, thus disabled.
Allocator(const Allocator &)=default
~Allocator()
Destructor.
Allocator(Block *shared_block, TableResourceMonitor &table_resource_monitor)
Constructor.
Definition: allocator.h:551
T * pointer
Definition: allocator.h:438
T * allocate(size_t n_elements)
Allocate memory for storing n_elements number of elements.
Definition: allocator.h:589
size_t size_type
Definition: allocator.h:447
void destroy(U *p)
Destroy an object of type U.
Definition: allocator.h:671
static void init()
Initialize necessary structures.
Definition: allocator.h:676
bool operator!=(const Allocator< U > &rhs) const
Inequality operator.
Definition: allocator.h:583
TableResourceMonitor & m_table_resource_monitor
Table resource monitor control mechanism that limits the amount of resources that can be consumed at ...
Definition: allocator.h:545
bool operator==(const Allocator< U > &rhs) const
Equality operator.
Definition: allocator.h:576
ptrdiff_t difference_type
Definition: allocator.h:448
std::shared_ptr< AllocatorState< AllocationScheme > > m_state
Shared state between all the copies and rebinds of this allocator.
Definition: allocator.h:534
T value_type
Definition: allocator.h:446
void operator=(const Allocator< U > &)=delete
Assignment operator, not used, thus disabled.
Memory-block abstraction whose purpose is to serve as a building block for custom memory-allocator im...
Definition: block.h:163
bool is_empty() const
Check if Block is empty (not holding any data).
Definition: block.h:399
bool can_accommodate(size_t chunk_size) const
Check if Block can fit (allocate) a Chunk of given size.
Definition: block.h:403
size_t number_of_used_chunks() const
Get current number of Chunks allocated by the Block.
Definition: block.h:427
static constexpr size_t ALIGN_TO
Block will self-adjust all requested allocation-sizes to the multiple of this value.
Definition: block.h:167
Chunk allocate(size_t chunk_size) noexcept
Allocate a Chunk from a Block.
Definition: block.h:351
static size_t size_hint(size_t n_bytes)
For given size, how much memory will Block with single Chunk actually occupy.
Definition: block.h:448
Chunk is an abstraction with the purpose of representing a smallest logical memory-unit within the Bl...
Definition: chunk.h:68
uint8_t * data() const
Get the pointer to the data section which will be provided to the end-user.
Definition: chunk.h:158
Definition: allocator.h:128
TableResourceMonitor(size_t threshold)
Definition: allocator.h:130
size_t m_total_bytes
Definition: allocator.h:149
size_t increase(size_t bytes)
Definition: allocator.h:133
size_t decrease(size_t bytes)
Definition: allocator.h:139
size_t m_threshold
Definition: allocator.h:148
size_t threshold()
Definition: allocator.h:144
size_t consumption()
Definition: allocator.h:145
const char * p
Definition: ctype-mb.cc:1235
#define U
Definition: ctype-tis620.cc:74
Memory utilities for temptable-allocator.
#define DBUG_EXECUTE_IF(keyword, a1)
Definition: my_dbug.h:171
Common header for many mysys elements.
ulonglong temptable_max_ram
Definition: mysqld.cc:1184
bool temptable_use_mmap
Definition: mysqld.cc:1186
ulonglong temptable_max_mmap
Definition: mysqld.cc:1185
Definition: gcs_xcom_synode.h:64
Definition: allocator.h:45
constexpr size_t ALLOCATOR_MAX_BLOCK_MB_EXP
log2(allocator max block size in MiB).
Definition: constants.h:60
void Block_PSI_init()
Initialize the PSI memory engine.
Definition: block.cc:74
constexpr size_t ALLOCATOR_MAX_BLOCK_BYTES
Limit on the size of a block created by Allocator (in bytes).
Definition: constants.h:65
Source
Type of memory allocated.
Definition: memutils.h:68
@ MMAP_FILE
Memory is allocated on disk, using mmap()'ed file.
@ RAM
Memory is allocated from RAM, using malloc() for example.
std::enable_if_t<!std::is_array< T >::value, std::shared_ptr< T > > make_shared(Args &&... args)
Dynamically allocates storage for an object of type T.
Definition: ut0new.h:2590
static MEM_ROOT mem
Definition: sql_servers.cc:100
TempTable constants.
Definition: allocator.h:192
static size_t block_size(size_t number_of_blocks, size_t n_bytes_requested)
Definition: allocator.h:196
static Source block_source(size_t block_size)
Definition: allocator.h:193
static void block_freed(uint32_t block_size, Source block_source)
Definition: allocator.h:199
Definition: allocator.h:451
Allocator< U, AllocationScheme > other
Definition: allocator.h:452
Definition: allocator.h:268
static size_t block_size(size_t number_of_blocks, size_t n_bytes_requested)
Given the current number of allocated blocks by the allocator, and number of bytes actually requested...
Definition: allocator.h:276
Definition: allocator.h:82
static size_t increase(size_t bytes)
Log increments of MMAP-backed memory consumption.
Definition: allocator.h:87
static size_t threshold()
Get MMAP-backed memory threshold level.
Definition: allocator.h:103
static size_t decrease(size_t bytes)
Log decrements of MMAP-backed memory consumption.
Definition: allocator.h:95
static size_t consumption()
Get current level of MMAP-backed memory consumption.
Definition: allocator.h:113
Definition: allocator.h:55
static size_t consumption()
Get current level of heap-memory consumption.
Definition: allocator.h:79
static size_t decrease(size_t bytes)
Log decrements of heap-memory consumption.
Definition: allocator.h:68
static size_t increase(size_t bytes)
Log increments of heap-memory consumption.
Definition: allocator.h:60
static size_t threshold()
Get heap-memory threshold level.
Definition: allocator.h:75
Definition: allocator.h:54
static std::atomic< size_t > mmap
Definition: allocator.h:119
static std::atomic< size_t > ram
Total bytes allocated so far by all threads in RAM/MMAP.
Definition: allocator.h:118
Definition: allocator.h:216
static Source block_source(uint32_t block_size)
Definition: allocator.h:217
static void block_freed(uint32_t block_size, Source block_source)
Definition: allocator.h:237
Definition: dtoa.cc:588