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