MySQL 8.1.0
Source Code Documentation
pfs_buffer_container.h
Go to the documentation of this file.
1/* Copyright (c) 2014, 2023, Oracle and/or its affiliates.
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License, version 2.0,
5 as published by the Free Software Foundation.
6
7 This program is also distributed with certain software (including
8 but not limited to OpenSSL) that is licensed under separate terms,
9 as designated in a particular file or component or in included license
10 documentation. The authors of MySQL hereby grant you an additional
11 permission to link the program and your derivative works with the
12 separately licensed software that they have included with MySQL.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License, version 2.0, for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
22
23#ifndef PFS_BUFFER_CONTAINER_H
24#define PFS_BUFFER_CONTAINER_H
25
26/**
27 @file storage/perfschema/pfs_buffer_container.h
28 Generic buffer container.
29*/
30
31#include <assert.h>
32#include <stddef.h>
33#include <sys/types.h>
34#include <atomic>
35
36#include "my_inttypes.h"
47
48#define USE_SCALABLE
49
50class PFS_opaque_container_page;
51class PFS_opaque_container;
52
54
55template <class T>
57
58template <class T>
60
61template <class T, class U, class V>
63
64template <class T, int PFS_PAGE_SIZE, int PFS_PAGE_COUNT, class U, class V>
66
67template <class T>
69
70template <class T>
72
73template <class T, class U, class V>
75
76template <class T, int PFS_PAGE_SIZE, int PFS_PAGE_COUNT, class U, class V>
78
79template <class B, int COUNT>
81
82template <class B, int COUNT>
84
85template <class T>
87 public:
88 typedef T value_type;
89
91 size_t index;
92 size_t monotonic;
93 size_t monotonic_max;
95
96 if (m_full) {
97 return nullptr;
98 }
99
100 monotonic = m_monotonic.m_size_t++;
101 monotonic_max = monotonic + m_max;
102
103 if (unlikely(monotonic >= monotonic_max)) {
104 /*
105 This will happen once every 2^64 - m_max calls.
106 Computation of monotonic_max just overflowed,
107 so reset monotonic counters and start again from the beginning.
108 */
109 m_monotonic.m_size_t.store(0);
110 monotonic = 0;
111 monotonic_max = m_max;
112 }
113
114 while (monotonic < monotonic_max) {
115 index = monotonic % m_max;
116 pfs = m_ptr + index;
117
118 if (pfs->m_lock.free_to_dirty(dirty_state)) {
119 return pfs;
120 }
121 monotonic = m_monotonic.m_size_t++;
122 }
123
124 m_full = true;
125 return nullptr;
126 }
127
129 pfs->m_lock.allocated_to_free();
130 m_full = false;
131 }
132
133 T *get_first() { return m_ptr; }
134
135 T *get_last() { return m_ptr + m_max; }
136
137 bool m_full;
140 size_t m_max;
141 /** Container. */
142 PFS_opaque_container *m_container;
143};
144
145template <class T>
147 public:
149
151 : m_builtin_class(klass) {}
152
154 array->m_ptr = nullptr;
155 array->m_full = true;
156 array->m_monotonic.m_size_t.store(0);
157
158 if (array->m_max > 0) {
159 array->m_ptr = PFS_MALLOC_ARRAY(m_builtin_class, array->m_max, sizeof(T),
160 T, MYF(MY_ZEROFILL));
161 if (array->m_ptr == nullptr) {
162 return 1;
163 }
164 array->m_full = false;
165 }
166 return 0;
167 }
168
169 void free_array(array_type *array) {
170 assert(array->m_max > 0);
171
172 PFS_FREE_ARRAY(m_builtin_class, array->m_max, sizeof(T), array->m_ptr);
173 array->m_ptr = nullptr;
174 }
175
176 private:
178};
179
180template <class T, class U = PFS_buffer_default_array<T>,
181 class V = PFS_buffer_default_allocator<T>>
183 public:
184 friend class PFS_buffer_iterator<T, U, V>;
185
186 typedef T value_type;
187 typedef U array_type;
188 typedef V allocator_type;
192 typedef void (*function_type)(value_type *);
193
195 m_array.m_full = true;
196 m_array.m_ptr = NULL;
197 m_array.m_max = 0;
198 m_array.m_monotonic.m_size_t = 0;
199 m_lost = 0;
200 m_max = 0;
201 m_allocator = allocator;
202 }
203
204 int init(size_t max_size) {
205 if (max_size > 0) {
206 m_array.m_max = max_size;
207 int rc = m_allocator->alloc_array(&m_array);
208 if (rc != 0) {
209 m_allocator->free_array(&m_array);
210 return 1;
211 }
212 m_max = max_size;
213 m_array.m_full = false;
214 }
215 return 0;
216 }
217
218 void cleanup() { m_allocator->free_array(&m_array); }
219
220 size_t get_row_count() const { return m_max; }
221
222 size_t get_row_size() const { return sizeof(value_type); }
223
224 size_t get_memory() const { return get_row_count() * get_row_size(); }
225
228
229 pfs = m_array.allocate(dirty_state, m_max);
230 if (pfs == NULL) {
231 m_lost++;
232 }
233
234 return pfs;
235 }
236
237 void deallocate(value_type *pfs) { m_array.deallocate(pfs); }
238
240
241 iterator_type iterate(uint index) {
242 assert(index <= m_max);
243 return PFS_buffer_iterator<T, U, V>(this, index);
244 }
245
247 value_type *pfs = m_array.get_first();
248 value_type *pfs_last = m_array.get_last();
249
250 while (pfs < pfs_last) {
251 if (pfs->m_lock.is_populated()) {
252 fct(pfs);
253 }
254 pfs++;
255 }
256 }
257
259 value_type *pfs = m_array.get_first();
260 value_type *pfs_last = m_array.get_last();
261
262 while (pfs < pfs_last) {
263 fct(pfs);
264 pfs++;
265 }
266 }
267
268 void apply(processor_type &proc) {
269 value_type *pfs = m_array.get_first();
270 value_type *pfs_last = m_array.get_last();
271
272 while (pfs < pfs_last) {
273 if (pfs->m_lock.is_populated()) {
274 proc(pfs);
275 }
276 pfs++;
277 }
278 }
279
281 value_type *pfs = m_array.get_first();
282 value_type *pfs_last = m_array.get_last();
283
284 while (pfs < pfs_last) {
285 proc(pfs);
286 pfs++;
287 }
288 }
289
290 inline value_type *get(uint index) {
291 assert(index < m_max);
292
293 value_type *pfs = m_array.m_ptr + index;
294 if (pfs->m_lock.is_populated()) {
295 return pfs;
296 }
297
298 return NULL;
299 }
300
301 value_type *get(uint index, bool *has_more) {
302 if (index >= m_max) {
303 *has_more = false;
304 return NULL;
305 }
306
307 *has_more = true;
308 return get(index);
309 }
310
312 intptr offset;
313 value_type *pfs = m_array.get_first();
314 value_type *pfs_last = m_array.get_last();
315
316 if ((pfs <= unsafe) && (unsafe < pfs_last)) {
317 offset = ((intptr)unsafe - (intptr)pfs) % sizeof(value_type);
318 if (offset == 0) {
319 return unsafe;
320 }
321 }
322
323 return NULL;
324 }
325
326 ulong m_lost;
327
328 private:
329 value_type *scan_next(uint &index, uint *found_index) {
330 assert(index <= m_max);
331
332 value_type *pfs_first = m_array.get_first();
333 value_type *pfs = pfs_first + index;
334 value_type *pfs_last = m_array.get_last();
335
336 while (pfs < pfs_last) {
337 if (pfs->m_lock.is_populated()) {
338 uint found = pfs - pfs_first;
339 *found_index = found;
340 index = found + 1;
341 return pfs;
342 }
343 pfs++;
344 }
345
346 index = m_max;
347 return NULL;
348 }
349
350 size_t m_max;
353};
354
355template <class T, int PFS_PAGE_SIZE, int PFS_PAGE_COUNT,
359 public:
360 friend class PFS_buffer_scalable_iterator<T, PFS_PAGE_SIZE, PFS_PAGE_COUNT, U,
361 V>;
362
363 /**
364 Type of elements in the buffer.
365 The following attributes are required:
366 - @code pfs_lock m_lock @endcode
367 - @code PFS_opaque_container_page *m_page @endcode
368 */
369 typedef T value_type;
370 /**
371 Type of pages in the buffer.
372 The following attributes are required:
373 - @code PFS_opaque_container *m_container @endcode
374 */
375 typedef U array_type;
376 typedef V allocator_type;
377 /** This container type */
384 typedef void (*function_type)(value_type *);
385
386 static const size_t MAX_SIZE = PFS_PAGE_SIZE * PFS_PAGE_COUNT;
387
389 m_allocator = allocator;
390 m_initialized = false;
391 }
392
393 int init(long max_size) {
394 int i;
395
396 m_initialized = true;
397 m_full = true;
398 m_max = PFS_PAGE_COUNT * PFS_PAGE_SIZE;
399 m_max_page_count = PFS_PAGE_COUNT;
400 m_last_page_size = PFS_PAGE_SIZE;
401 m_lost = 0;
402 m_monotonic.m_size_t.store(0);
403 m_max_page_index.m_size_t.store(0);
404
405 for (i = 0; i < PFS_PAGE_COUNT; i++) {
406 m_pages[i] = nullptr;
407 }
408
409 if (max_size == 0) {
410 /* No allocation. */
412 } else if (max_size > 0) {
413 if (max_size % PFS_PAGE_SIZE == 0) {
414 m_max_page_count = max_size / PFS_PAGE_SIZE;
415 } else {
416 m_max_page_count = max_size / PFS_PAGE_SIZE + 1;
417 m_last_page_size = max_size % PFS_PAGE_SIZE;
418 }
419 /* Bounded allocation. */
420 m_full = false;
421
422 if (m_max_page_count > PFS_PAGE_COUNT) {
423 m_max_page_count = PFS_PAGE_COUNT;
424 m_last_page_size = PFS_PAGE_SIZE;
425 }
426 } else {
427 /* max_size = -1 means unbounded allocation */
428 m_full = false;
429 }
430
431 assert(m_max_page_count <= PFS_PAGE_COUNT);
432 assert(0 < m_last_page_size);
433 assert(m_last_page_size <= PFS_PAGE_SIZE);
434
436 return 0;
437 }
438
439 void cleanup() {
440 int i;
442
443 if (!m_initialized) {
444 return;
445 }
446
448
449 for (i = 0; i < PFS_PAGE_COUNT; i++) {
450 page = m_pages[i];
451 if (page != nullptr) {
452 m_allocator->free_array(page);
453 delete page;
454 m_pages[i] = nullptr;
455 }
456 }
458
460
461 m_initialized = false;
462 }
463
464 size_t get_row_count() {
465 size_t page_count = m_max_page_index.m_size_t.load();
466 size_t result = page_count * PFS_PAGE_SIZE;
467
468 if ((page_count > 0) && (m_last_page_size != PFS_PAGE_SIZE)) {
469 /* Bounded allocation, the last page may be incomplete. */
470 result = result - PFS_PAGE_SIZE + m_last_page_size;
471 }
472 return result;
473 }
474
475 size_t get_row_size() const { return sizeof(value_type); }
476
477 size_t get_memory() { return get_row_count() * get_row_size(); }
478
480 if (m_full) {
481 m_lost++;
482 return nullptr;
483 }
484
485 size_t index;
486 size_t monotonic;
487 size_t monotonic_max;
488 size_t current_page_count;
490 array_type *array;
491
492 /*
493 1: Try to find an available record within the existing pages
494 */
495 current_page_count = m_max_page_index.m_size_t.load();
496
497 if (current_page_count != 0) {
498 monotonic = m_monotonic.m_size_t.load();
499 monotonic_max = monotonic + current_page_count;
500
501 if (unlikely(monotonic >= monotonic_max)) {
502 /*
503 This will happen once every 2^64 - current_page_count calls.
504 Computation of monotonic_max just overflowed,
505 so reset monotonic counters and start again from the beginning.
506 */
507 m_monotonic.m_size_t.store(0);
508 monotonic = 0;
509 monotonic_max = current_page_count;
510 }
511
512 while (monotonic < monotonic_max) {
513 /*
514 Scan in the [0 .. current_page_count - 1] range,
515 in parallel with m_monotonic (see below)
516 */
517 index = monotonic % current_page_count;
518
519 /* Atomic Load, array= m_pages[index] */
520 array = m_pages[index].load();
521
522 if (array != nullptr) {
523 pfs = array->allocate(dirty_state);
524 if (pfs != nullptr) {
525 /* Keep a pointer to the parent page, for deallocate(). */
526 pfs->m_page = reinterpret_cast<PFS_opaque_container_page *>(array);
527 return pfs;
528 }
529 }
530
531 /*
532 Parallel scans collaborate to increase
533 the common monotonic scan counter.
534
535 Note that when all the existing page are full,
536 one thread will eventually add a new page,
537 and cause m_max_page_index to increase,
538 which fools all the modulo logic for scans already in progress,
539 because the monotonic counter is not folded to the same place
540 (sometime modulo N, sometime modulo N+1).
541
542 This is actually ok: since all the pages are full anyway,
543 there is nothing to miss, so better increase the monotonic
544 counter faster and then move on to the detection of new pages,
545 in part 2: below.
546 */
547 monotonic = m_monotonic.m_size_t++;
548 };
549 }
550
551 /*
552 2: Try to add a new page, beyond the m_max_page_index limit
553 */
554 while (current_page_count < m_max_page_count) {
555 /* Peek for pages added by collaborating threads */
556
557 /* (2-a) Atomic Load, array= m_pages[current_page_count] */
558 array = m_pages[current_page_count].load();
559
560 if (array == nullptr) {
561 // ==================================================================
562 // BEGIN CRITICAL SECTION -- buffer expand
563 // ==================================================================
564
565 /*
566 On a fresh started server, buffers are typically empty.
567 When a sudden load spike is seen by the server,
568 multiple threads may want to expand the buffer at the same time.
569
570 Using a compare and swap to allow multiple pages to be added,
571 possibly freeing duplicate pages on collisions,
572 does not work well because the amount of code involved
573 when creating a new page can be significant (PFS_thread),
574 causing MANY collisions between (2-b) and (2-d).
575
576 A huge number of collisions (which can happen when thousands
577 of new connections hits the server after a restart)
578 leads to a huge memory consumption, and to OOM.
579
580 To mitigate this, we use here a mutex,
581 to enforce that only ONE page is added at a time,
582 so that scaling the buffer happens in a predictable
583 and controlled manner.
584 */
586
587 /*
588 Peek again for pages added by collaborating threads,
589 this time as the only thread allowed to expand the buffer
590 */
591
592 /* (2-b) Atomic Load, array= m_pages[current_page_count] */
593
594 array = m_pages[current_page_count].load();
595
596 if (array == nullptr) {
597 /* (2-c) Found no page, allocate a new one */
598 array = new array_type();
600
601 array->m_max = get_page_logical_size(current_page_count);
602 int rc = m_allocator->alloc_array(array);
603 if (rc != 0) {
604 m_allocator->free_array(array);
605 delete array;
607 m_lost++;
609 return nullptr;
610 }
611
612 /* Keep a pointer to this container, for static_deallocate(). */
613 array->m_container = reinterpret_cast<PFS_opaque_container *>(this);
614
615 /* (2-d) Atomic STORE, m_pages[current_page_count] = array */
616 m_pages[current_page_count].store(array);
617
618 /* Advertise the new page */
620 }
621
623
624 // ==================================================================
625 // END CRITICAL SECTION -- buffer expand
626 // ==================================================================
627 }
628
629 assert(array != nullptr);
630 pfs = array->allocate(dirty_state);
631 if (pfs != nullptr) {
632 /* Keep a pointer to the parent page, for deallocate(). */
633 pfs->m_page = reinterpret_cast<PFS_opaque_container_page *>(array);
634 return pfs;
635 }
636
637 current_page_count++;
638 }
639
640 m_lost++;
641 m_full = true;
642 return nullptr;
643 }
644
645 void deallocate(value_type *safe_pfs) {
646 /* Find the containing page */
647 PFS_opaque_container_page *opaque_page = safe_pfs->m_page;
648 auto *page = reinterpret_cast<array_type *>(opaque_page);
649
650 /* Mark the object free */
651 safe_pfs->m_lock.allocated_to_free();
652
653 /* Flag the containing page as not full. */
654 page->m_full = false;
655
656 /* Flag the overall container as not full. */
657 m_full = false;
658 }
659
660 static void static_deallocate(value_type *safe_pfs) {
661 /* Find the containing page */
662 PFS_opaque_container_page *opaque_page = safe_pfs->m_page;
663 auto *page = reinterpret_cast<array_type *>(opaque_page);
664
665 /* Mark the object free */
666 safe_pfs->m_lock.allocated_to_free();
667
668 /* Flag the containing page as not full. */
669 page->m_full = false;
670
671 /* Find the containing buffer */
672 PFS_opaque_container *opaque_container = page->m_container;
674 container = reinterpret_cast<container_type *>(opaque_container);
675
676 /* Flag the overall container as not full. */
677 container->m_full = false;
678 }
679
682 this, 0);
683 }
684
685 iterator_type iterate(uint index) {
686 assert(index <= m_max);
688 this, index);
689 }
690
692 uint i;
695 value_type *pfs_last;
696
697 for (i = 0; i < PFS_PAGE_COUNT; i++) {
698 page = m_pages[i];
699 if (page != nullptr) {
700 pfs = page->get_first();
701 pfs_last = page->get_last();
702
703 while (pfs < pfs_last) {
704 if (pfs->m_lock.is_populated()) {
705 fct(pfs);
706 }
707 pfs++;
708 }
709 }
710 }
711 }
712
714 uint i;
717 value_type *pfs_last;
718
719 for (i = 0; i < PFS_PAGE_COUNT; i++) {
720 page = m_pages[i];
721 if (page != nullptr) {
722 pfs = page->get_first();
723 pfs_last = page->get_last();
724
725 while (pfs < pfs_last) {
726 fct(pfs);
727 pfs++;
728 }
729 }
730 }
731 }
732
733 void apply(processor_type &proc) {
734 uint i;
737 value_type *pfs_last;
738
739 for (i = 0; i < PFS_PAGE_COUNT; i++) {
740 page = m_pages[i];
741 if (page != nullptr) {
742 pfs = page->get_first();
743 pfs_last = page->get_last();
744
745 while (pfs < pfs_last) {
746 if (pfs->m_lock.is_populated()) {
747 proc(pfs);
748 }
749 pfs++;
750 }
751 }
752 }
753 }
754
756 uint i;
759 value_type *pfs_last;
760
761 for (i = 0; i < PFS_PAGE_COUNT; i++) {
762 page = m_pages[i];
763 if (page != NULL) {
764 pfs = page->get_first();
765 pfs_last = page->get_last();
766
767 while (pfs < pfs_last) {
768 proc(pfs);
769 pfs++;
770 }
771 }
772 }
773 }
774
775 value_type *get(uint index) {
776 assert(index < m_max);
777
778 uint index_1 = index / PFS_PAGE_SIZE;
779 array_type *page = m_pages[index_1];
780 if (page != nullptr) {
781 uint index_2 = index % PFS_PAGE_SIZE;
782
783 if (index_2 >= page->m_max) {
784 return nullptr;
785 }
786
787 value_type *pfs = page->m_ptr + index_2;
788
789 if (pfs->m_lock.is_populated()) {
790 return pfs;
791 }
792 }
793
794 return nullptr;
795 }
796
797 value_type *get(uint index, bool *has_more) {
798 if (index >= m_max) {
799 *has_more = false;
800 return nullptr;
801 }
802
803 uint index_1 = index / PFS_PAGE_SIZE;
804 array_type *page = m_pages[index_1];
805
806 if (page == nullptr) {
807 *has_more = false;
808 return nullptr;
809 }
810
811 uint index_2 = index % PFS_PAGE_SIZE;
812
813 if (index_2 >= page->m_max) {
814 *has_more = false;
815 return nullptr;
816 }
817
818 *has_more = true;
819 value_type *pfs = page->m_ptr + index_2;
820
821 if (pfs->m_lock.is_populated()) {
822 return pfs;
823 }
824
825 return nullptr;
826 }
827
829 intptr offset;
830 uint i;
833 value_type *pfs_last;
834
835 for (i = 0; i < PFS_PAGE_COUNT; i++) {
836 page = m_pages[i];
837 if (page != nullptr) {
838 pfs = page->get_first();
839 pfs_last = page->get_last();
840
841 if ((pfs <= unsafe) && (unsafe < pfs_last)) {
842 offset = ((intptr)unsafe - (intptr)pfs) % sizeof(value_type);
843 if (offset == 0) {
844 return unsafe;
845 }
846 }
847 }
848 }
849
850 return nullptr;
851 }
852
853 ulong m_lost;
854
855 private:
856 uint get_page_logical_size(uint page_index) {
857 if (page_index + 1 < m_max_page_count) {
858 return PFS_PAGE_SIZE;
859 }
860 assert(page_index + 1 == m_max_page_count);
861 return m_last_page_size;
862 }
863
864 value_type *scan_next(uint &index, uint *found_index) {
865 assert(index <= m_max);
866
867 uint index_1 = index / PFS_PAGE_SIZE;
868 uint index_2 = index % PFS_PAGE_SIZE;
870 value_type *pfs_first;
872 value_type *pfs_last;
873
874 while (index_1 < PFS_PAGE_COUNT) {
875 page = m_pages[index_1];
876
877 if (page == nullptr) {
878 index = static_cast<uint>(m_max);
879 return nullptr;
880 }
881
882 pfs_first = page->get_first();
883 pfs = pfs_first + index_2;
884 pfs_last = page->get_last();
885
886 while (pfs < pfs_last) {
887 if (pfs->m_lock.is_populated()) {
888 uint found =
889 index_1 * PFS_PAGE_SIZE + static_cast<uint>(pfs - pfs_first);
890 *found_index = found;
891 index = found + 1;
892 return pfs;
893 }
894 pfs++;
895 }
896
897 index_1++;
898 index_2 = 0;
899 }
900
901 index = static_cast<uint>(m_max);
902 return nullptr;
903 }
904
906 bool m_full;
907 size_t m_max;
912 std::atomic<array_type *> m_pages[PFS_PAGE_COUNT];
915};
916
917template <class T, class U, class V>
919 friend class PFS_buffer_container<T, U, V>;
920
921 typedef T value_type;
923
924 public:
926 uint unused;
927 return m_container->scan_next(m_index, &unused);
928 }
929
930 value_type *scan_next(uint *found_index) {
931 return m_container->scan_next(m_index, found_index);
932 }
933
934 private:
936 : m_container(container), m_index(index) {}
937
940};
941
942template <class T, int page_size, int page_count, class U, class V>
944 friend class PFS_buffer_scalable_container<T, page_size, page_count, U, V>;
945
946 typedef T value_type;
949
950 public:
952 uint unused;
953 return m_container->scan_next(m_index, &unused);
954 }
955
956 value_type *scan_next(uint *found_index) {
957 return m_container->scan_next(m_index, found_index);
958 }
959
960 private:
962 : m_container(container), m_index(index) {}
963
966};
967
968template <class T>
970 public:
971 virtual ~PFS_buffer_processor<T>() = default;
972 virtual void operator()(T *element) = 0;
973};
974
975template <class B, int PFS_PARTITION_COUNT>
977 public:
978 friend class PFS_partitioned_buffer_scalable_iterator<B, PFS_PARTITION_COUNT>;
979
980 typedef typename B::value_type value_type;
981 typedef typename B::allocator_type allocator_type;
984 typedef typename B::iterator_type sub_iterator_type;
985 typedef typename B::processor_type processor_type;
986 typedef typename B::function_type function_type;
987
989 allocator_type *allocator) {
990 for (int i = 0; i < PFS_PARTITION_COUNT; i++) {
991 m_partitions[i] = new B(allocator);
992 }
993 }
994
996 for (int i = 0; i < PFS_PARTITION_COUNT; i++) {
997 delete m_partitions[i];
998 }
999 }
1000
1001 int init(long max_size) {
1002 int rc = 0;
1003 // FIXME: we have max_size * PFS_PARTITION_COUNT here
1004 for (int i = 0; i < PFS_PARTITION_COUNT; i++) {
1005 rc |= m_partitions[i]->init(max_size);
1006 }
1007 return rc;
1008 }
1009
1010 void cleanup() {
1011 for (int i = 0; i < PFS_PARTITION_COUNT; i++) {
1012 m_partitions[i]->cleanup();
1013 }
1014 }
1015
1016 size_t get_row_count() const {
1017 size_t sum = 0;
1018
1019 for (int i = 0; i < PFS_PARTITION_COUNT; i++) {
1020 sum += m_partitions[i]->get_row_count();
1021 }
1022
1023 return sum;
1024 }
1025
1026 size_t get_row_size() const { return sizeof(value_type); }
1027
1028 size_t get_memory() const {
1029 size_t sum = 0;
1030
1031 for (int i = 0; i < PFS_PARTITION_COUNT; i++) {
1032 sum += m_partitions[i]->get_memory();
1033 }
1034
1035 return sum;
1036 }
1037
1039 long sum = 0;
1040
1041 for (int i = 0; i < PFS_PARTITION_COUNT; i++) {
1042 sum += m_partitions[i]->m_lost;
1043 }
1044
1045 return sum;
1046 }
1047
1048 value_type *allocate(pfs_dirty_state *dirty_state, uint partition) {
1049 assert(partition < PFS_PARTITION_COUNT);
1050
1051 return m_partitions[partition]->allocate(dirty_state);
1052 }
1053
1054 void deallocate(value_type *safe_pfs) {
1055 /*
1056 One issue here is that we do not know which partition
1057 the record belongs to.
1058 Each record points to the parent page,
1059 and each page points to the parent buffer,
1060 so using static_deallocate here,
1061 which will find the correct partition by itself.
1062 */
1063 B::static_deallocate(safe_pfs);
1064 }
1065
1066 iterator_type iterate() { return iterator_type(this, 0, 0); }
1067
1068 iterator_type iterate(uint user_index) {
1069 uint partition_index;
1070 uint sub_index;
1071 unpack_index(user_index, &partition_index, &sub_index);
1072 return iterator_type(this, partition_index, sub_index);
1073 }
1074
1076 for (int i = 0; i < PFS_PARTITION_COUNT; i++) {
1077 m_partitions[i]->apply(fct);
1078 }
1079 }
1080
1082 for (int i = 0; i < PFS_PARTITION_COUNT; i++) {
1083 m_partitions[i]->apply_all(fct);
1084 }
1085 }
1086
1087 void apply(processor_type &proc) {
1088 for (int i = 0; i < PFS_PARTITION_COUNT; i++) {
1089 m_partitions[i]->apply(proc);
1090 }
1091 }
1092
1094 for (int i = 0; i < PFS_PARTITION_COUNT; i++) {
1095 m_partitions[i]->apply_all(proc);
1096 }
1097 }
1098
1099 value_type *get(uint user_index) {
1100 uint partition_index;
1101 uint sub_index;
1102 unpack_index(user_index, &partition_index, &sub_index);
1103
1104 if (partition_index >= PFS_PARTITION_COUNT) {
1105 return nullptr;
1106 }
1107
1108 return m_partitions[partition_index]->get(sub_index);
1109 }
1110
1111 value_type *get(uint user_index, bool *has_more) {
1112 uint partition_index;
1113 uint sub_index;
1114 unpack_index(user_index, &partition_index, &sub_index);
1115
1116 if (partition_index >= PFS_PARTITION_COUNT) {
1117 *has_more = false;
1118 return NULL;
1119 }
1120
1121 *has_more = true;
1122 return m_partitions[partition_index]->get(sub_index);
1123 }
1124
1126 value_type *safe = nullptr;
1127
1128 for (int i = 0; i < PFS_PARTITION_COUNT; i++) {
1129 safe = m_partitions[i]->sanitize(unsafe);
1130 if (safe != nullptr) {
1131 return safe;
1132 }
1133 }
1134
1135 return safe;
1136 }
1137
1138 private:
1139 static void pack_index(uint partition_index, uint sub_index,
1140 uint *user_index) {
1141 static_assert(PFS_PARTITION_COUNT <= (1 << 8), "2^8 = 256 partitions max.");
1142 static_assert((B::MAX_SIZE) <= (1 << 24),
1143 "2^24 = 16777216 max per partitioned buffer.");
1144
1145 *user_index = (partition_index << 24) + sub_index;
1146 }
1147
1148 static void unpack_index(uint user_index, uint *partition_index,
1149 uint *sub_index) {
1150 *partition_index = user_index >> 24;
1151 *sub_index = user_index & 0x00FFFFFF;
1152 }
1153
1154 value_type *scan_next(uint &partition_index, uint &sub_index,
1155 uint *found_partition, uint *found_sub_index) {
1156 value_type *record = nullptr;
1157 assert(partition_index < PFS_PARTITION_COUNT);
1158
1159 while (partition_index < PFS_PARTITION_COUNT) {
1160 sub_iterator_type sub_iterator =
1161 m_partitions[partition_index]->iterate(sub_index);
1162 record = sub_iterator.scan_next(found_sub_index);
1163 if (record != nullptr) {
1164 *found_partition = partition_index;
1165 sub_index = *found_sub_index + 1;
1166 return record;
1167 }
1168
1169 partition_index++;
1170 sub_index = 0;
1171 }
1172
1173 *found_partition = PFS_PARTITION_COUNT;
1174 *found_sub_index = 0;
1175 sub_index = 0;
1176 return nullptr;
1177 }
1178
1179 B *m_partitions[PFS_PARTITION_COUNT];
1180};
1181
1182template <class B, int PFS_PARTITION_COUNT>
1184 public:
1186 PFS_PARTITION_COUNT>;
1187
1188 typedef typename B::value_type value_type;
1191
1193 uint unused_partition;
1194 uint unused_sub_index;
1195 return m_container->scan_next(m_partition, m_sub_index, &unused_partition,
1196 &unused_sub_index);
1197 }
1198
1199 value_type *scan_next(uint *found_user_index) {
1200 uint found_partition;
1201 uint found_sub_index;
1203 record = m_container->scan_next(m_partition, m_sub_index, &found_partition,
1204 &found_sub_index);
1205 container_type::pack_index(found_partition, found_sub_index,
1206 found_user_index);
1207 return record;
1208 }
1209
1210 private:
1212 uint partition, uint sub_index)
1214 m_partition(partition),
1215 m_sub_index(sub_index) {}
1216
1220};
1221
1222#ifdef USE_SCALABLE
1228#else
1230#endif
1233
1234#ifdef USE_SCALABLE
1237#else
1239#endif
1242
1243#ifdef USE_SCALABLE
1245#else
1247#endif
1250
1251#ifdef USE_SCALABLE
1254#else
1256#endif
1259
1260#ifdef USE_SCALABLE
1263#else
1265#endif
1268
1269#ifdef USE_SCALABLE
1272#else
1274#endif
1277
1278#ifdef USE_SCALABLE
1281#else
1283#endif
1286
1287#ifdef USE_SCALABLE
1290#else
1292#endif
1295
1296#ifdef USE_SCALABLE
1299#else
1301#endif
1304
1305#ifdef USE_SCALABLE
1308#else
1310#endif
1313
1314#ifdef USE_SCALABLE
1317#else
1320#endif
1324
1325#ifdef USE_SCALABLE
1328#else
1331#endif
1335
1336#ifdef USE_SCALABLE
1339#else
1341#endif
1344
1345#ifdef USE_SCALABLE
1348#else
1350#endif
1353
1354class PFS_account_array : public PFS_buffer_default_array<PFS_account> {
1355 public:
1362};
1363
1365 public:
1366 int alloc_array(PFS_account_array *array);
1367 void free_array(PFS_account_array *array);
1368};
1369
1370#ifdef USE_SCALABLE
1374#else
1378#endif
1381
1383 public:
1390};
1391
1393 public:
1394 int alloc_array(PFS_host_array *array);
1395 void free_array(PFS_host_array *array);
1396};
1397
1398#ifdef USE_SCALABLE
1402#else
1405#endif
1408
1409class PFS_thread_array : public PFS_buffer_default_array<PFS_thread> {
1410 public:
1417
1424
1429};
1430
1432 public:
1433 int alloc_array(PFS_thread_array *array);
1434 void free_array(PFS_thread_array *array);
1435};
1436
1437#ifdef USE_SCALABLE
1441#else
1444#endif
1447
1449 public:
1456};
1457
1459 public:
1460 int alloc_array(PFS_user_array *array);
1461 void free_array(PFS_user_array *array);
1462};
1463
1464#ifdef USE_SCALABLE
1468#else
1471#endif
1474
1475#endif
Definition: pfs_buffer_container.h:1364
void free_array(PFS_account_array *array)
Definition: pfs_buffer_container.cc:234
int alloc_array(PFS_account_array *array)
Definition: pfs_buffer_container.cc:101
Definition: pfs_buffer_container.h:1354
PFS_stage_stat * m_instr_class_stages_array
Definition: pfs_buffer_container.h:1357
PFS_memory_shared_stat * m_instr_class_memory_array
Definition: pfs_buffer_container.h:1361
PFS_error_stat * m_instr_class_errors_array
Definition: pfs_buffer_container.h:1360
PFS_single_stat * m_instr_class_waits_array
Definition: pfs_buffer_container.h:1356
PFS_transaction_stat * m_instr_class_transactions_array
Definition: pfs_buffer_container.h:1359
PFS_statement_stat * m_instr_class_statements_array
Definition: pfs_buffer_container.h:1358
Definition: pfs_buffer_container.h:56
Definition: pfs_buffer_container.h:182
PFS_buffer_processor< T > processor_type
Definition: pfs_buffer_container.h:191
void apply(function_type fct)
Definition: pfs_buffer_container.h:246
void cleanup()
Definition: pfs_buffer_container.h:218
size_t get_memory() const
Definition: pfs_buffer_container.h:224
size_t get_row_count() const
Definition: pfs_buffer_container.h:220
size_t m_max
Definition: pfs_buffer_container.h:350
value_type * get(uint index)
Definition: pfs_buffer_container.h:290
size_t get_row_size() const
Definition: pfs_buffer_container.h:222
U array_type
Definition: pfs_buffer_container.h:187
int init(size_t max_size)
Definition: pfs_buffer_container.h:204
void apply(processor_type &proc)
Definition: pfs_buffer_container.h:268
value_type * get(uint index, bool *has_more)
Definition: pfs_buffer_container.h:301
PFS_buffer_const_iterator< T > const_iterator_type
Definition: pfs_buffer_container.h:189
void apply_all(function_type fct)
Definition: pfs_buffer_container.h:258
void(* function_type)(value_type *)
Definition: pfs_buffer_container.h:192
iterator_type iterate()
Definition: pfs_buffer_container.h:239
ulong m_lost
Definition: pfs_buffer_container.h:326
value_type * allocate(pfs_dirty_state *dirty_state)
Definition: pfs_buffer_container.h:226
void apply_all(processor_type &proc)
Definition: pfs_buffer_container.h:280
value_type * sanitize(value_type *unsafe)
Definition: pfs_buffer_container.h:311
V allocator_type
Definition: pfs_buffer_container.h:188
PFS_buffer_container(allocator_type *allocator)
Definition: pfs_buffer_container.h:194
PFS_buffer_iterator< T, U, V > iterator_type
Definition: pfs_buffer_container.h:190
void deallocate(value_type *pfs)
Definition: pfs_buffer_container.h:237
iterator_type iterate(uint index)
Definition: pfs_buffer_container.h:241
friend class PFS_buffer_iterator< T, U, V >
Definition: pfs_buffer_container.h:184
value_type * scan_next(uint &index, uint *found_index)
Definition: pfs_buffer_container.h:329
allocator_type * m_allocator
Definition: pfs_buffer_container.h:352
array_type m_array
Definition: pfs_buffer_container.h:351
T value_type
Definition: pfs_buffer_container.h:186
Definition: pfs_buffer_container.h:146
PFS_buffer_default_array< T > array_type
Definition: pfs_buffer_container.h:148
PFS_buffer_default_allocator(PFS_builtin_memory_class *klass)
Definition: pfs_buffer_container.h:150
int alloc_array(array_type *array)
Definition: pfs_buffer_container.h:153
void free_array(array_type *array)
Definition: pfs_buffer_container.h:169
PFS_builtin_memory_class * m_builtin_class
Definition: pfs_buffer_container.h:177
Definition: pfs_buffer_container.h:86
bool m_full
Definition: pfs_buffer_container.h:137
T * get_last()
Definition: pfs_buffer_container.h:135
size_t m_max
Definition: pfs_buffer_container.h:140
PFS_cacheline_atomic_size_t m_monotonic
Definition: pfs_buffer_container.h:138
T * m_ptr
Definition: pfs_buffer_container.h:139
value_type * allocate(pfs_dirty_state *dirty_state)
Definition: pfs_buffer_container.h:90
T value_type
Definition: pfs_buffer_container.h:88
T * get_first()
Definition: pfs_buffer_container.h:133
PFS_opaque_container * m_container
Container.
Definition: pfs_buffer_container.h:142
void deallocate(value_type *pfs)
Definition: pfs_buffer_container.h:128
Definition: pfs_buffer_container.h:918
T value_type
Definition: pfs_buffer_container.h:921
PFS_buffer_container< T, U, V > container_type
Definition: pfs_buffer_container.h:922
container_type * m_container
Definition: pfs_buffer_container.h:938
value_type * scan_next()
Definition: pfs_buffer_container.h:925
value_type * scan_next(uint *found_index)
Definition: pfs_buffer_container.h:930
PFS_buffer_iterator(container_type *container, uint index)
Definition: pfs_buffer_container.h:935
uint m_index
Definition: pfs_buffer_container.h:939
Definition: pfs_buffer_container.h:969
virtual void operator()(T *element)=0
Definition: pfs_buffer_container.h:358
void(* function_type)(value_type *)
Definition: pfs_buffer_container.h:384
static const size_t MAX_SIZE
Definition: pfs_buffer_container.h:386
int init(long max_size)
Definition: pfs_buffer_container.h:393
size_t get_row_size() const
Definition: pfs_buffer_container.h:475
friend class PFS_buffer_scalable_iterator< T, PFS_PAGE_SIZE, PFS_PAGE_COUNT, U, V >
Definition: pfs_buffer_container.h:361
void apply(processor_type &proc)
Definition: pfs_buffer_container.h:733
bool m_initialized
Definition: pfs_buffer_container.h:905
void apply_all(function_type fct)
Definition: pfs_buffer_container.h:713
void apply_all(processor_type &proc)
Definition: pfs_buffer_container.h:755
PFS_buffer_scalable_container< T, PFS_PAGE_SIZE, PFS_PAGE_COUNT, U, V > container_type
This container type.
Definition: pfs_buffer_container.h:379
size_t m_max_page_count
Definition: pfs_buffer_container.h:910
value_type * sanitize(value_type *unsafe)
Definition: pfs_buffer_container.h:828
PFS_buffer_scalable_iterator< T, PFS_PAGE_SIZE, PFS_PAGE_COUNT, U, V > iterator_type
Definition: pfs_buffer_container.h:382
value_type * allocate(pfs_dirty_state *dirty_state)
Definition: pfs_buffer_container.h:479
native_mutex_t m_critical_section
Definition: pfs_buffer_container.h:914
PFS_cacheline_atomic_size_t m_max_page_index
Definition: pfs_buffer_container.h:909
size_t get_memory()
Definition: pfs_buffer_container.h:477
iterator_type iterate()
Definition: pfs_buffer_container.h:680
uint get_page_logical_size(uint page_index)
Definition: pfs_buffer_container.h:856
void apply(function_type fct)
Definition: pfs_buffer_container.h:691
iterator_type iterate(uint index)
Definition: pfs_buffer_container.h:685
V allocator_type
Definition: pfs_buffer_container.h:376
size_t m_last_page_size
Definition: pfs_buffer_container.h:911
U array_type
Type of pages in the buffer.
Definition: pfs_buffer_container.h:375
PFS_buffer_processor< T > processor_type
Definition: pfs_buffer_container.h:383
value_type * get(uint index, bool *has_more)
Definition: pfs_buffer_container.h:797
PFS_cacheline_atomic_size_t m_monotonic
Definition: pfs_buffer_container.h:908
void cleanup()
Definition: pfs_buffer_container.h:439
size_t get_row_count()
Definition: pfs_buffer_container.h:464
PFS_buffer_const_iterator< T > const_iterator_type
Definition: pfs_buffer_container.h:380
allocator_type * m_allocator
Definition: pfs_buffer_container.h:913
size_t m_max
Definition: pfs_buffer_container.h:907
value_type * get(uint index)
Definition: pfs_buffer_container.h:775
static void static_deallocate(value_type *safe_pfs)
Definition: pfs_buffer_container.h:660
T value_type
Type of elements in the buffer.
Definition: pfs_buffer_container.h:369
PFS_buffer_scalable_container(allocator_type *allocator)
Definition: pfs_buffer_container.h:388
value_type * scan_next(uint &index, uint *found_index)
Definition: pfs_buffer_container.h:864
void deallocate(value_type *safe_pfs)
Definition: pfs_buffer_container.h:645
bool m_full
Definition: pfs_buffer_container.h:906
ulong m_lost
Definition: pfs_buffer_container.h:853
std::atomic< array_type * > m_pages[PFS_PAGE_COUNT]
Definition: pfs_buffer_container.h:912
Definition: pfs_buffer_container.h:943
T value_type
Definition: pfs_buffer_container.h:946
uint m_index
Definition: pfs_buffer_container.h:965
value_type * scan_next(uint *found_index)
Definition: pfs_buffer_container.h:956
value_type * scan_next()
Definition: pfs_buffer_container.h:951
PFS_buffer_scalable_container< T, page_size, page_count, U, V > container_type
Definition: pfs_buffer_container.h:948
PFS_buffer_scalable_iterator(container_type *container, uint index)
Definition: pfs_buffer_container.h:961
container_type * m_container
Definition: pfs_buffer_container.h:964
Definition: pfs_buffer_container.h:1392
int alloc_array(PFS_host_array *array)
Definition: pfs_buffer_container.cc:284
void free_array(PFS_host_array *array)
Definition: pfs_buffer_container.cc:417
Definition: pfs_buffer_container.h:1382
PFS_transaction_stat * m_instr_class_transactions_array
Definition: pfs_buffer_container.h:1387
PFS_memory_shared_stat * m_instr_class_memory_array
Definition: pfs_buffer_container.h:1389
PFS_error_stat * m_instr_class_errors_array
Definition: pfs_buffer_container.h:1388
PFS_single_stat * m_instr_class_waits_array
Definition: pfs_buffer_container.h:1384
PFS_stage_stat * m_instr_class_stages_array
Definition: pfs_buffer_container.h:1385
PFS_statement_stat * m_instr_class_statements_array
Definition: pfs_buffer_container.h:1386
Definition: pfs_buffer_container.h:976
B::function_type function_type
Definition: pfs_buffer_container.h:986
value_type * get(uint user_index, bool *has_more)
Definition: pfs_buffer_container.h:1111
B::allocator_type allocator_type
Definition: pfs_buffer_container.h:981
void apply(processor_type &proc)
Definition: pfs_buffer_container.h:1087
void apply(function_type fct)
Definition: pfs_buffer_container.h:1075
B * m_partitions[PFS_PARTITION_COUNT]
Definition: pfs_buffer_container.h:1179
value_type * scan_next(uint &partition_index, uint &sub_index, uint *found_partition, uint *found_sub_index)
Definition: pfs_buffer_container.h:1154
iterator_type iterate()
Definition: pfs_buffer_container.h:1066
PFS_partitioned_buffer_scalable_iterator< B, PFS_PARTITION_COUNT > iterator_type
Definition: pfs_buffer_container.h:983
size_t get_row_count() const
Definition: pfs_buffer_container.h:1016
void apply_all(function_type fct)
Definition: pfs_buffer_container.h:1081
value_type * sanitize(value_type *unsafe)
Definition: pfs_buffer_container.h:1125
B::value_type value_type
Definition: pfs_buffer_container.h:980
static void unpack_index(uint user_index, uint *partition_index, uint *sub_index)
Definition: pfs_buffer_container.h:1148
PFS_partitioned_buffer_scalable_container(allocator_type *allocator)
Definition: pfs_buffer_container.h:988
void deallocate(value_type *safe_pfs)
Definition: pfs_buffer_container.h:1054
int init(long max_size)
Definition: pfs_buffer_container.h:1001
~PFS_partitioned_buffer_scalable_container()
Definition: pfs_buffer_container.h:995
B::iterator_type sub_iterator_type
Definition: pfs_buffer_container.h:984
size_t get_memory() const
Definition: pfs_buffer_container.h:1028
iterator_type iterate(uint user_index)
Definition: pfs_buffer_container.h:1068
size_t get_row_size() const
Definition: pfs_buffer_container.h:1026
B::processor_type processor_type
Definition: pfs_buffer_container.h:985
void apply_all(processor_type &proc)
Definition: pfs_buffer_container.h:1093
value_type * get(uint user_index)
Definition: pfs_buffer_container.h:1099
value_type * allocate(pfs_dirty_state *dirty_state, uint partition)
Definition: pfs_buffer_container.h:1048
void cleanup()
Definition: pfs_buffer_container.h:1010
long get_lost_counter()
Definition: pfs_buffer_container.h:1038
static void pack_index(uint partition_index, uint sub_index, uint *user_index)
Definition: pfs_buffer_container.h:1139
Definition: pfs_buffer_container.h:1183
uint m_sub_index
Definition: pfs_buffer_container.h:1219
PFS_partitioned_buffer_scalable_container< B, PFS_PARTITION_COUNT > container_type
Definition: pfs_buffer_container.h:1190
container_type * m_container
Definition: pfs_buffer_container.h:1217
B::value_type value_type
Definition: pfs_buffer_container.h:1188
value_type * scan_next(uint *found_user_index)
Definition: pfs_buffer_container.h:1199
value_type * scan_next()
Definition: pfs_buffer_container.h:1192
PFS_partitioned_buffer_scalable_iterator(container_type *container, uint partition, uint sub_index)
Definition: pfs_buffer_container.h:1211
uint m_partition
Definition: pfs_buffer_container.h:1218
Definition: pfs_buffer_container.h:1431
void free_array(PFS_thread_array *array)
Definition: pfs_buffer_container.cc:765
int alloc_array(PFS_thread_array *array)
Definition: pfs_buffer_container.cc:466
Definition: pfs_buffer_container.h:1409
PFS_statement_stat * m_instr_class_statements_array
Definition: pfs_buffer_container.h:1413
PFS_single_stat * m_instr_class_waits_array
Definition: pfs_buffer_container.h:1411
PFS_error_stat * m_instr_class_errors_array
Definition: pfs_buffer_container.h:1415
PFS_events_statements * m_statements_stack_array
Definition: pfs_buffer_container.h:1421
PFS_events_statements * m_statements_history_array
Definition: pfs_buffer_container.h:1420
PFS_stage_stat * m_instr_class_stages_array
Definition: pfs_buffer_container.h:1412
unsigned char * m_current_stmts_digest_token_array
Definition: pfs_buffer_container.h:1427
PFS_events_stages * m_stages_history_array
Definition: pfs_buffer_container.h:1419
char * m_current_stmts_text_array
Definition: pfs_buffer_container.h:1425
PFS_memory_safe_stat * m_instr_class_memory_array
Definition: pfs_buffer_container.h:1416
unsigned char * m_history_stmts_digest_token_array
Definition: pfs_buffer_container.h:1428
PFS_transaction_stat * m_instr_class_transactions_array
Definition: pfs_buffer_container.h:1414
char * m_session_connect_attrs_array
Definition: pfs_buffer_container.h:1423
PFS_events_waits * m_waits_history_array
Definition: pfs_buffer_container.h:1418
PFS_events_transactions * m_transactions_history_array
Definition: pfs_buffer_container.h:1422
char * m_history_stmts_text_array
Definition: pfs_buffer_container.h:1426
Definition: pfs_buffer_container.h:1458
void free_array(PFS_user_array *array)
Definition: pfs_buffer_container.cc:1012
int alloc_array(PFS_user_array *array)
Definition: pfs_buffer_container.cc:879
Definition: pfs_buffer_container.h:1448
PFS_statement_stat * m_instr_class_statements_array
Definition: pfs_buffer_container.h:1452
PFS_transaction_stat * m_instr_class_transactions_array
Definition: pfs_buffer_container.h:1453
PFS_stage_stat * m_instr_class_stages_array
Definition: pfs_buffer_container.h:1451
PFS_single_stat * m_instr_class_waits_array
Definition: pfs_buffer_container.h:1450
PFS_error_stat * m_instr_class_errors_array
Definition: pfs_buffer_container.h:1454
PFS_memory_shared_stat * m_instr_class_memory_array
Definition: pfs_buffer_container.h:1455
int page
Definition: ctype-mb.cc:1233
#define MY_ZEROFILL
Definition: my_sys.h:138
#define PFS_MUTEX_PARTITIONS
Definition: pfs_instr_class.h:314
constexpr bool unlikely(bool expr)
Definition: my_compiler.h:57
Some integer typedefs for easier portability.
intptr_t intptr
Definition: my_inttypes.h:69
#define MYF(v)
Definition: my_inttypes.h:96
static int record
Definition: mysqltest.cc:194
uint16_t value_type
Definition: vt100.h:183
Definition: atomics_array.h:38
const ulint MAX_SIZE
The maximum size possible for an LOB.
Definition: lob0lob.h:83
Performance schema account (declarations).
PFS_file_container global_file_container
PFS_buffer_scalable_container< PFS_mutex, 1024, 1024 > PFS_mutex_basic_container
Definition: pfs_buffer_container.h:1224
PFS_host_container global_host_container
PFS_buffer_scalable_container< PFS_socket, 256, 256 > PFS_socket_container
Definition: pfs_buffer_container.h:1262
PFS_thread_container global_thread_container
PFS_table_share_index_container global_table_share_index_container
PFS_cond_container::iterator_type PFS_cond_iterator
Definition: pfs_buffer_container.h:1248
PFS_buffer_scalable_container< PFS_table, 1024, 1024 > PFS_table_container
Definition: pfs_buffer_container.h:1298
PFS_file_container::iterator_type PFS_file_iterator
Definition: pfs_buffer_container.h:1257
PFS_user_container::iterator_type PFS_user_iterator
Definition: pfs_buffer_container.h:1472
PFS_mutex_container::iterator_type PFS_mutex_iterator
Definition: pfs_buffer_container.h:1231
PFS_prepared_stmt_container::iterator_type PFS_prepared_stmt_iterator
Definition: pfs_buffer_container.h:1351
PFS_buffer_scalable_container< PFS_table_share, 4 *1024, 4 *1024 > PFS_table_share_container
Definition: pfs_buffer_container.h:1307
PFS_setup_object_container::iterator_type PFS_setup_object_iterator
Definition: pfs_buffer_container.h:1293
PFS_cond_container global_cond_container
PFS_buffer_scalable_container< PFS_prepared_stmt, 1024, 1024 > PFS_prepared_stmt_container
Definition: pfs_buffer_container.h:1347
PFS_buffer_scalable_container< PFS_table_share_lock, 4 *1024, 4 *1024 > PFS_table_share_lock_container
Definition: pfs_buffer_container.h:1327
PFS_socket_container::iterator_type PFS_socket_iterator
Definition: pfs_buffer_container.h:1266
PFS_table_share_container global_table_share_container
PFS_rwlock_container::iterator_type PFS_rwlock_iterator
Definition: pfs_buffer_container.h:1240
PFS_program_container global_program_container
PFS_buffer_scalable_container< PFS_thread, 256, 256, PFS_thread_array, PFS_thread_allocator > PFS_thread_container
Definition: pfs_buffer_container.h:1440
PFS_host_container::iterator_type PFS_host_iterator
Definition: pfs_buffer_container.h:1406
PFS_socket_container global_socket_container
PFS_partitioned_buffer_scalable_container< PFS_mutex_basic_container, PFS_MUTEX_PARTITIONS > PFS_mutex_container
Definition: pfs_buffer_container.h:1227
PFS_table_share_lock_container::iterator_type PFS_table_share_lock_iterator
Definition: pfs_buffer_container.h:1333
PFS_buffer_scalable_container< PFS_program, 1024, 1024 > PFS_program_container
Definition: pfs_buffer_container.h:1338
PFS_account_container::iterator_type PFS_account_iterator
Definition: pfs_buffer_container.h:1379
PFS_buffer_scalable_container< PFS_file, 4 *1024, 4 *1024 > PFS_file_container
Definition: pfs_buffer_container.h:1253
PFS_setup_object_container global_setup_object_container
PFS_table_share_index_container::iterator_type PFS_table_share_index_iterator
Definition: pfs_buffer_container.h:1322
PFS_mdl_container global_mdl_container
PFS_buffer_scalable_container< PFS_setup_actor, 128, 1024 > PFS_setup_actor_container
Definition: pfs_buffer_container.h:1280
PFS_rwlock_container global_rwlock_container
PFS_thread_container::iterator_type PFS_thread_iterator
Definition: pfs_buffer_container.h:1445
PFS_mdl_container::iterator_type PFS_mdl_iterator
Definition: pfs_buffer_container.h:1275
PFS_table_share_lock_container global_table_share_lock_container
PFS_table_container global_table_container
PFS_table_container::iterator_type PFS_table_iterator
Definition: pfs_buffer_container.h:1302
PFS_buffer_scalable_container< PFS_host, 128, 128, PFS_host_array, PFS_host_allocator > PFS_host_container
Definition: pfs_buffer_container.h:1401
PFS_account_container global_account_container
PFS_buffer_scalable_container< PFS_cond, 256, 256 > PFS_cond_container
Definition: pfs_buffer_container.h:1244
PFS_setup_actor_container::iterator_type PFS_setup_actor_iterator
Definition: pfs_buffer_container.h:1284
PFS_program_container::iterator_type PFS_program_iterator
Definition: pfs_buffer_container.h:1342
PFS_prepared_stmt_container global_prepared_stmt_container
PFS_buffer_scalable_container< PFS_user, 128, 128, PFS_user_array, PFS_user_allocator > PFS_user_container
Definition: pfs_buffer_container.h:1467
PFS_buffer_scalable_container< PFS_table_share_index, 8 *1024, 8 *1024 > PFS_table_share_index_container
Definition: pfs_buffer_container.h:1316
PFS_buffer_scalable_container< PFS_setup_object, 128, 1024 > PFS_setup_object_container
Definition: pfs_buffer_container.h:1289
PFS_table_share_container::iterator_type PFS_table_share_iterator
Definition: pfs_buffer_container.h:1311
PFS_setup_actor_container global_setup_actor_container
PFS_mutex_container global_mutex_container
PFS_buffer_scalable_container< PFS_metadata_lock, 1024, 1024 > PFS_mdl_container
Definition: pfs_buffer_container.h:1271
PFS_buffer_scalable_container< PFS_rwlock, 1024, 1024 > PFS_rwlock_container
Definition: pfs_buffer_container.h:1236
PFS_user_container global_user_container
PFS_buffer_scalable_container< PFS_account, 128, 128, PFS_account_array, PFS_account_allocator > PFS_account_container
Definition: pfs_buffer_container.h:1373
PFS_builtin_memory_class builtin_memory_scalable_buffer
Definition: pfs_builtin_memory.cc:122
Performance schema instruments metadata (declarations).
#define PFS_MALLOC_ARRAY(k, n, s, T, f)
Helper, to allocate an array of structures.
Definition: pfs_global.h:122
#define PFS_FREE_ARRAY(k, n, s, p)
Helper, to free an array of structures.
Definition: pfs_global.h:139
Performance schema host (declarations).
Performance schema instruments (declarations).
Performance schema internal locks (declarations).
Stored Program data structures (declarations).
Stored Program data structures (declarations).
Performance schema setup actors (declarations).
Performance schema setup object (declarations).
Performance schema user (declarations).
struct result result
Definition: result.h:33
static const LEX_CSTRING pfs
Definition: sql_show_processlist.cc:65
Per account statistics.
Definition: pfs_account.h:66
Definition: pfs_builtin_memory.h:38
void count_alloc(size_t size)
Definition: pfs_builtin_memory.h:42
void count_free(size_t size)
Definition: pfs_builtin_memory.h:44
An atomic size_t variable, guaranteed to be alone in a CPU cache line.
Definition: pfs_global.h:98
std::atomic< size_t > m_size_t
Definition: pfs_global.h:99
Statistics for all server errors.
Definition: pfs_stat.h:556
A stage record.
Definition: pfs_events_stages.h:44
A statement record.
Definition: pfs_events_statements.h:46
A transaction record.
Definition: pfs_events_transactions.h:84
A wait event record.
Definition: pfs_events_waits.h:68
Per host statistics.
Definition: pfs_host.h:63
Memory statistics.
Definition: pfs_stat.h:912
Definition: pfs_stat.h:936
Single statistic.
Definition: pfs_stat.h:51
Statistics for stage usage.
Definition: pfs_stat.h:322
Statistics for statement usage.
Definition: pfs_stat.h:375
Instrumented thread implementation.
Definition: pfs_instr.h:374
Statistics for transaction usage.
Definition: pfs_stat.h:458
Per user statistics.
Definition: pfs_user.h:62
Definition: pfs_lock.h:76
Definition: result.h:29
static int native_mutex_unlock(native_mutex_t *mutex)
Definition: thr_mutex.h:114
static int native_mutex_destroy(native_mutex_t *mutex)
Definition: thr_mutex.h:123
static int native_mutex_lock(native_mutex_t *mutex)
Definition: thr_mutex.h:89
static int native_mutex_init(native_mutex_t *mutex, const native_mutexattr_t *attr)
Definition: thr_mutex.h:78
pthread_mutex_t native_mutex_t
Definition: thr_mutex_bits.h:54
#define NULL
Definition: types.h:54
Definition: dtoa.cc:588