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