MySQL 8.4.0
Source Code Documentation
sql_list.h
Go to the documentation of this file.
1#ifndef INCLUDES_MYSQL_SQL_LIST_H
2#define INCLUDES_MYSQL_SQL_LIST_H
3/* Copyright (c) 2000, 2024, Oracle and/or its affiliates.
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License, version 2.0,
7 as published by the Free Software Foundation.
8
9 This program is designed to work with certain software (including
10 but not limited to OpenSSL) that is licensed under separate terms,
11 as designated in a particular file or component or in included license
12 documentation. The authors of MySQL hereby grant you an additional
13 permission to link the program and your derivative works with the
14 separately licensed software that they have either included with
15 the program or referenced in the documentation.
16
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License, version 2.0, for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
25
26#include <stddef.h>
27#include <sys/types.h>
28#include <algorithm>
29#include <iterator>
30#include <memory>
31#include <type_traits>
32
33#include "my_alloc.h"
34#include "my_compiler.h"
35#include "my_dbug.h"
36#include "my_sharedlib.h"
37#include "sql/thr_malloc.h"
38
39/**
40 Simple intrusive linked list.
41
42 @remark Similar in nature to base_list, but intrusive. It keeps a
43 a pointer to the first element in the list and a indirect
44 reference to the last element.
45*/
46template <typename T>
48 public:
50 /** The first element in the list. If empty, nullptr */
52 /**
53 A reference to the next element in the list. If empty points to
54 the head element's 'first' pointer, else to the last element's
55 next pointer.
56 */
57 T **next;
58
60
62 : elements(tmp.elements),
63 first(tmp.first),
64 next(elements ? tmp.next : &first) {}
65
66 SQL_I_List(SQL_I_List &&) = default;
67
68 inline void clear() {
69 elements = 0;
70 first = nullptr;
71 next = &first;
72 }
73
74 inline void link_in_list(T *element, T **next_ptr) {
75 elements++;
76 (*next) = element;
77 next = next_ptr;
78 *next = nullptr;
79 }
80
81 inline void save_and_clear(SQL_I_List<T> *save) {
82 *save = *this;
83 clear();
84 }
85
86 inline void push_front(SQL_I_List<T> *save) {
87 /* link current list last */
88 *save->next = first;
89 first = save->first;
90 elements += save->elements;
91 }
92
93 inline void push_back(SQL_I_List<T> *save) {
94 if (save->first) {
95 *next = save->first;
96 next = save->next;
97 elements += save->elements;
98 }
99 }
100
101 /*
102 Split list after sz elements into two: this list gets shortened, the rest
103 gets assigned into tail. If sz is larger than or equal to the number of
104 elements in this list, this list is unchanged, and tail will be empty
105
106 @param sz The number of elements to retain in this list
107 @param tail The list to hold the tail we chop off.
108 */
109 void split_after(uint sz, SQL_I_List<T> *tail) {
110 assert(this != tail);
111 if (sz >= elements) { // just put an empty list in tail
112 *tail = std::move(SQL_I_List<T>());
113 return;
114 }
115 T **o = &first;
116 for (uint i = 0; i < sz; i++) {
117 o = &(*o)->next;
118 }
119 // Save tail
120 tail->first = *o;
121 tail->next = next;
122 tail->elements = elements - sz;
123 // Shorten this
124 next = o;
125 *next = nullptr;
126 elements = sz;
127 }
128
129 inline uint size() const { return elements; }
130
133};
134
135/*
136 Basic single linked list
137 Used for item and item_buffs.
138 All list ends with a pointer to the 'end_of_list' element, which
139 data pointer is a null pointer and the next pointer points to itself.
140 This makes it very fast to traverse lists as we don't have to
141 test for a specialend condition for list that can't contain a null
142 pointer.
143*/
144
145/**
146 list_node - a node of a single-linked list.
147 @note We never call a destructor for instances of this class.
148*/
149
150struct list_node {
152 void *info;
153 list_node(void *info_par, list_node *next_par)
154 : next(next_par), info(info_par) {}
155 list_node() /* For end_of_list */
156 {
157 info = nullptr;
158 next = this;
159 }
160};
161
163
165 protected:
167
168 public:
170
171 bool operator==(const base_list &rhs) const {
172 return elements == rhs.elements && first == rhs.first && last == rhs.last;
173 }
174
175 inline void clear() {
176 elements = 0;
178 last = &first;
179 }
180 inline base_list() { clear(); }
181 /**
182 This is a shallow copy constructor that implicitly passes the ownership
183 from the source list to the new instance. The old instance is not
184 updated, so both objects end up sharing the same nodes. If one of
185 the instances then adds or removes a node, the other becomes out of
186 sync ('last' pointer), while still operational. Some old code uses and
187 relies on this behaviour. This logic is quite tricky: please do not use
188 it in any new code.
189 */
191 : first(tmp.first),
192 last(tmp.elements ? tmp.last : &first),
193 elements(tmp.elements) {}
195 elements = tmp.elements;
196 first = tmp.first;
197 last = elements ? tmp.last : &first;
198 return *this;
199 }
200 /**
201 Construct a deep copy of the argument in memory root mem_root.
202 The elements themselves are copied by pointer.
203 */
204 base_list(const base_list &rhs, MEM_ROOT *mem_root);
205 inline bool push_back(void *info) {
206 *last = new (*THR_MALLOC) list_node(info, &end_of_list);
207 if (*last) {
208 last = &(*last)->next;
209 elements++;
210 return false;
211 }
212 return true;
213 }
214 inline bool push_back(void *info, MEM_ROOT *mem_root) {
215 *last = new (mem_root) list_node(info, &end_of_list);
216 if (*last) {
217 last = &(*last)->next;
218 elements++;
219 return false;
220 }
221 return true;
222 }
223 inline bool push_front(void *info) {
224 list_node *node = new (*THR_MALLOC) list_node(info, first);
225 if (node) {
226 if (last == &first) last = &node->next;
227 first = node;
228 elements++;
229 return false;
230 }
231 return true;
232 }
233 inline bool push_front(void *info, MEM_ROOT *mem_root) {
234 list_node *node = new (mem_root) list_node(info, first);
235 if (node) {
236 if (last == &first) last = &node->next;
237 first = node;
238 elements++;
239 return false;
240 }
241 return true;
242 }
243
244 void remove(list_node **prev) {
245 list_node *node = (*prev)->next;
246 if (!--elements)
247 last = &first;
248 else if (last == &(*prev)->next)
249 last = prev;
250 ::destroy_at(*prev);
251 *prev = node;
252 }
253 inline void concat(base_list *list) {
254 if (!list->is_empty()) {
255 *last = list->first;
256 last = list->last;
257 elements += list->elements;
258 }
259 }
260 inline void *pop(void) {
261 if (first == &end_of_list) return nullptr;
262 list_node *tmp = first;
263 first = first->next;
264 if (!--elements) last = &first;
265 return tmp->info;
266 }
267 inline void disjoin(base_list *list) {
268 list_node **prev = &first;
269 list_node *node = first;
270 list_node *list_first = list->first;
271 elements = 0;
272 while (node && node != list_first) {
273 prev = &node->next;
274 node = node->next;
275 elements++;
276 }
277 *prev = *last;
278 last = prev;
279 }
280 inline void prepend(base_list *list) {
281 if (!list->is_empty()) {
282 *list->last = first;
283 if (is_empty()) last = list->last;
284 first = list->first;
285 elements += list->elements;
286 }
287 }
288 /**
289 Swap two lists.
290 */
291 inline void swap(base_list &rhs) {
292 std::swap(first, rhs.first);
293 std::swap(last, rhs.last);
295 }
296 inline list_node *last_node() { return *last; }
297 inline list_node *first_node() { return first; }
298 inline void *head() { return first->info; }
299 inline const void *head() const { return first->info; }
300 inline void **head_ref() {
301 return first != &end_of_list ? &first->info : nullptr;
302 }
303 inline bool is_empty() const { return first == &end_of_list; }
304 inline list_node *last_ref() { return &end_of_list; }
305 inline uint size() const { return elements; }
306 friend class base_list_iterator;
307 friend class error_list;
309
310#ifdef LIST_EXTRA_DEBUG
311 /*
312 Check list invariants and print results into trace. Invariants are:
313 - (*last) points to end_of_list
314 - There are no NULLs in the list.
315 - base_list::elements is the number of elements in the list.
316
317 SYNOPSIS
318 check_list()
319 name Name to print to trace file
320
321 RETURN
322 1 The list is Ok.
323 0 List invariants are not met.
324 */
325
326 bool check_list(const char *name) {
327 base_list *list = this;
328 list_node *node = first;
329 uint cnt = 0;
330
331 while (node->next != &end_of_list) {
332 if (!node->info) {
333 DBUG_PRINT("list_invariants",
334 ("%s: error: NULL element in the list", name));
335 return false;
336 }
337 node = node->next;
338 cnt++;
339 }
340 if (last != &(node->next)) {
341 DBUG_PRINT("list_invariants", ("%s: error: wrong last pointer", name));
342 return false;
343 }
344 if (cnt + 1 != elements) {
345 DBUG_PRINT("list_invariants", ("%s: error: wrong element count", name));
346 return false;
347 }
348 DBUG_PRINT("list_invariants", ("%s: list is ok", name));
349 return true;
350 }
351#endif // LIST_EXTRA_DEBUG
352
353 protected:
354 void after(void *info, list_node *node) {
355 list_node *new_node = new (*THR_MALLOC) list_node(info, node->next);
356 node->next = new_node;
357 elements++;
358 if (last == &(node->next)) last = &new_node->next;
359 }
360 bool after(void *info, list_node *node, MEM_ROOT *mem_root) {
361 list_node *new_node = new (mem_root) list_node(info, node->next);
362 if (!new_node) return true; // OOM
363
364 node->next = new_node;
365 elements++;
366 if (last == &(node->next)) last = &new_node->next;
367
368 return false;
369 }
370};
371
373 protected:
376 void sublist(base_list &ls, uint elm) {
377 ls.first = *el;
378 ls.last = list->last;
379 ls.elements = elm;
380 }
381
382 public:
385
386 base_list_iterator(base_list &list_par) { init(list_par); }
387
388 inline void init(base_list &list_par) {
389 list = &list_par;
390 el = &list_par.first;
391 prev = nullptr;
392 current = nullptr;
393 }
394
395 inline void *next(void) {
396 prev = el;
397 current = *el;
398 el = &current->next;
399 return current->info;
400 }
401 inline void *next_fast(void) {
402 list_node *tmp;
403 tmp = *el;
404 el = &tmp->next;
405 return tmp->info;
406 }
407 inline void rewind(void) { el = &list->first; }
408 inline void *replace(void *element) { // Return old element
409 void *tmp = current->info;
410 assert(current->info != nullptr);
411 current->info = element;
412 return tmp;
413 }
414 void *replace(base_list &new_list) {
415 void *ret_value = current->info;
416 if (!new_list.is_empty()) {
417 *new_list.last = current->next;
418 current->info = new_list.first->info;
419 current->next = new_list.first->next;
420 if ((list->last == &current->next) && (new_list.elements > 1))
421 list->last = new_list.last;
422 list->elements += new_list.elements - 1;
423 }
424 return ret_value; // return old element
425 }
426 inline void remove(void) // Remove current
427 {
428 list->remove(prev);
429 el = prev;
430 current = nullptr; // Safeguard
431 }
432 void after(void *element) // Insert element after current
433 {
434 list->after(element, current);
436 el = &current->next;
437 }
438 bool after(void *a, MEM_ROOT *mem_root) {
439 if (list->after(a, current, mem_root)) return true;
440
442 el = &current->next;
443 return false;
444 }
445 inline void **ref(void) // Get reference pointer
446 {
447 return &current->info;
448 }
449 inline bool is_last(void) { return el == list->last; }
450 inline bool is_before_first() const { return current == nullptr; }
451 bool prepend(void *a, MEM_ROOT *mem_root) {
452 if (list->push_front(a, mem_root)) return true;
453
454 el = &list->first;
455 prev = el;
456 el = &(*el)->next;
457
458 return false;
459 }
461};
462
463template <class T>
465
466template <class T>
467class List : public base_list {
468 public:
470 inline List(const List<T> &tmp) : base_list(tmp) {}
471 List &operator=(const List &tmp) {
472 return static_cast<List &>(base_list::operator=(tmp));
473 }
474 inline List(const List<T> &tmp, MEM_ROOT *mem_root)
475 : base_list(tmp, mem_root) {}
476 /*
477 Typecasting to (void *) it's necessary if we want to declare List<T> with
478 constant T parameter (like List<const char>), since the untyped storage
479 is "void *", and assignment of const pointer to "void *" is a syntax error.
480 */
481 inline bool push_back(T *a) {
482 return base_list::push_back(const_cast<void *>(((const void *)a)));
483 }
484 inline bool push_back(T *a, MEM_ROOT *mem_root) {
485 return base_list::push_back(const_cast<void *>((const void *)a), mem_root);
486 }
487 inline bool push_front(T *a) {
488 return base_list::push_front(const_cast<void *>((const void *)a));
489 }
490 inline bool push_front(T *a, MEM_ROOT *mem_root) {
491 return base_list::push_front(const_cast<void *>((const void *)a), mem_root);
492 }
493 inline T *head() { return static_cast<T *>(base_list::head()); }
494 inline const T *head() const {
495 return static_cast<const T *>(base_list::head());
496 }
497 inline T **head_ref() { return (T **)base_list::head_ref(); }
498 inline T *pop() { return (T *)base_list::pop(); }
502 void delete_elements(void) {
503 list_node *element, *next;
504 for (element = first; element != &end_of_list; element = next) {
505 next = element->next;
506 delete (T *)element->info;
507 }
508 clear();
509 }
510
511 void destroy_elements(void) {
512 list_node *element, *next;
513 for (element = first; element != &end_of_list; element = next) {
514 next = element->next;
515 ::destroy_at((T *)element->info);
516 }
517 clear();
518 }
519
520 T *operator[](uint index) const {
521 assert(index < elements);
522 list_node *current = first;
523 for (uint i = 0; i < index; ++i) current = current->next;
524 return static_cast<T *>(current->info);
525 }
526
527 void replace(uint index, T *new_value) {
528 assert(index < elements);
529 list_node *current = first;
530 for (uint i = 0; i < index; ++i) current = current->next;
531 current->info = new_value;
532 }
533
534 bool swap_elts(uint index1, uint index2) {
535 if (index1 == index2) return false;
536
537 if (index1 >= elements || index2 >= elements) return true; // error
538
539 if (index2 < index1) std::swap(index1, index2);
540
541 list_node *current1 = first;
542 for (uint i = 0; i < index1; ++i) current1 = current1->next;
543
544 list_node *current2 = current1;
545 for (uint i = 0; i < index2 - index1; ++i) current2 = current2->next;
546
547 std::swap(current1->info, current2->info);
548
549 return false;
550 }
551
552 /**
553 @brief
554 Sort the list
555
556 @param cmp node comparison function
557
558 @details
559 The function sorts list nodes by an exchange sort algorithm.
560 The order of list nodes isn't changed, values of info fields are
561 swapped instead. Due to this, list iterators that are initialized before
562 sort could be safely used after sort, i.e they wouldn't cause a crash.
563 As this isn't an effective algorithm the list to be sorted is supposed to
564 be short.
565 */
566 template <typename Node_cmp_func>
567 void sort(Node_cmp_func cmp) {
568 if (elements < 2) return;
569 for (list_node *n1 = first; n1 && n1 != &end_of_list; n1 = n1->next) {
570 for (list_node *n2 = n1->next; n2 && n2 != &end_of_list; n2 = n2->next) {
571 if (cmp(static_cast<T *>(n1->info), static_cast<T *>(n2->info)) > 0) {
572 void *tmp = n1->info;
573 n1->info = n2->info;
574 n2->info = tmp;
575 }
576 }
577 }
578 }
579
580 // For C++11 range-based for loops.
584 // If the list overlaps another list, last isn't actually
585 // the last element, and if so, we'd give a different result from
586 // List_iterator_fast.
587 assert((*last)->next == &end_of_list);
588
589 return iterator(*last);
590 }
591
595 assert((*last)->next == &end_of_list);
596 return const_iterator(*last);
597 }
600 assert((*last)->next == &end_of_list);
601 return const_iterator(*last);
602 }
603};
604
605template <class T>
607 public:
610 inline void init(List<T> &a) { base_list_iterator::init(a); }
611 inline T *operator++(int) { return (T *)base_list_iterator::next(); }
612 inline T *replace(T *a) { return (T *)base_list_iterator::replace(a); }
613 inline T *replace(List<T> &a) { return (T *)base_list_iterator::replace(a); }
614 inline void rewind(void) { base_list_iterator::rewind(); }
616 inline void after(T *a) { base_list_iterator::after(a); }
617 inline bool after(T *a, MEM_ROOT *mem_root) {
619 }
620 inline T **ref(void) {
621 return const_cast<T **>(
622 (std::remove_const_t<T> **)base_list_iterator::ref());
623 }
624};
625
626template <class T>
628 protected:
629 inline T *replace(T *) { return (T *)0; }
630 inline T *replace(List<T> &) { return (T *)0; }
631 inline void remove(void) {}
632 inline void after(T *) {}
633 inline T **ref(void) { return (T **)0; }
634
635 public:
638 inline void init(List<T> &a) { base_list_iterator::init(a); }
639 inline T *operator++(int) { return (T *)base_list_iterator::next_fast(); }
640 inline void rewind(void) { base_list_iterator::rewind(); }
641 void sublist(List<T> &list_arg, uint el_arg) {
642 base_list_iterator::sublist(list_arg, el_arg);
643 }
644};
645
646/*
647 Like List_iterator<T>, but with an STL-compatible interface
648 (ForwardIterator), so that you can use it in range-based for loops.
649 Prefer this to List_iterator<T> wherever possible, but also prefer
650 std::vector<T> or std::list<T> to List<T> wherever possible.
651 */
652template <class T>
654 public:
655 explicit List_STL_Iterator(list_node *node) : m_current(node) {}
656
657 // Iterator (required for InputIterator).
658 T &operator*() const { return *static_cast<T *>(m_current->info); }
659
662 return *this;
663 }
664
665 using difference_type = ptrdiff_t;
666 using value_type = T; // NOTE: std::remove_cv_t<T> from C++20.
667 using pointer = T *;
668 using reference = T &;
669 using iterator_category = std::forward_iterator_tag;
670
671 // EqualityComparable (required for InputIterator).
672 bool operator==(const List_STL_Iterator &other) const {
673 return m_current == other.m_current;
674 }
675
676 // InputIterator (required for ForwardIterator).
677 bool operator!=(const List_STL_Iterator &other) const {
678 return !(*this == other);
679 }
680
681 T *operator->() const { return static_cast<T *>(m_current->info); }
682
683 // DefaultConstructible (required for ForwardIterator).
684 List_STL_Iterator() = default;
685
686 // ForwardIterator.
688 List_STL_Iterator copy = *this;
690 return copy;
691 }
692
693 private:
695};
696
697template <typename T>
698class base_ilist;
699template <typename T>
701
702/*
703 A simple intrusive list.
704
705 NOTE: this inherently unsafe, since we rely on <T> to have
706 the same layout as ilink<T> (see base_ilist::sentinel).
707 Please consider using a different strategy for linking objects.
708*/
709
710template <typename T>
711class ilink {
712 T **prev, *next;
713
714 public:
716
717 void unlink() {
718 /* Extra tests because element doesn't have to be linked */
719 if (prev) *prev = next;
720 if (next) next->prev = prev;
721 prev = nullptr;
722 next = nullptr;
723 }
724
725 friend class base_ilist<T>;
726 friend class base_ilist_iterator<T>;
727};
728
729/* Needed to be able to have an I_List of char* strings in mysqld.cc. */
730
731class i_string : public ilink<i_string> {
732 public:
733 const char *ptr;
735 i_string(const char *s) : ptr(s) {}
736};
737
738/* needed for linked list of two strings for replicate-rewrite-db */
739class i_string_pair : public ilink<i_string_pair> {
740 public:
741 const char *key;
742 const char *val;
744 i_string_pair(const char *key_arg, const char *val_arg)
745 : key(key_arg), val(val_arg) {}
746};
747
748template <class T>
749class I_List_iterator;
750
751template <typename T>
755
756 static_assert(!std::is_polymorphic<T>::value,
757 "Do not use this for classes with virtual members");
758
759 public:
760 // The sentinel is not a T, but at least it is a POD
762 first = static_cast<T *>(&sentinel);
763 sentinel.prev = &first;
764 }
766
767 // The sentinel is not a T, but at least it is a POD
769 return first == static_cast<const T *>(&sentinel);
770 }
771
772 /// Pushes new element in front of list.
773 void push_front(T *a) {
774 first->prev = &a->next;
775 a->next = first;
776 a->prev = &first;
777 first = a;
778 }
779
780 /// Pushes new element to the end of the list, i.e. in front of the sentinel.
781 void push_back(T *a) {
782 *sentinel.prev = a;
783 a->next = static_cast<T *>(&sentinel);
784 a->prev = sentinel.prev;
785 sentinel.prev = &a->next;
786 }
787
788 // Unlink first element, and return it.
789 T *get() {
790 if (is_empty()) return nullptr;
791 T *first_link = first;
792 first_link->unlink();
793 return first_link;
794 }
795
796 T *head() { return is_empty() ? nullptr : first; }
797
798 /**
799 Moves list elements to new owner, and empties current owner (i.e. this).
800
801 @param[in,out] new_owner The new owner of the list elements.
802 Should be empty in input.
803 */
804
805 void move_elements_to(base_ilist *new_owner) {
806 assert(new_owner->is_empty());
807 new_owner->first = first;
808 new_owner->sentinel = sentinel;
809 clear();
810 }
811
812 friend class base_ilist_iterator<T>;
813
814 private:
815 /*
816 We don't want to allow copying of this class, as that would give us
817 two list heads containing the same elements.
818 So we declare, but don't define copy CTOR and assignment operator.
819 */
821 void operator=(const base_ilist &);
822};
823
824template <typename T>
827 T **el, *current;
828
829 public:
831 : list(&list_par), el(&list_par.first), current(nullptr) {}
832
833 // The sentinel is not a T, but at least it is a POD
835 /* This is coded to allow push_back() while iterating */
836 current = *el;
837 if (current == static_cast<T *>(&list->sentinel)) return nullptr;
838 el = &current->next;
839 return current;
840 }
841};
842
843template <class T>
844class I_List : private base_ilist<T> {
845 public:
848 using base_ilist<T>::get;
852 void move_elements_to(I_List<T> *new_owner) {
854 }
855 friend class I_List_iterator<T>;
856};
857
858template <class T>
860 public:
862 inline T *operator++(int) { return base_ilist_iterator<T>::next(); }
863};
864
866
867#endif // INCLUDES_MYSQL_SQL_LIST_H
Kerberos Client Authentication nullptr
Definition: auth_kerberos_client_plugin.cc:251
Definition: sql_list.h:859
I_List_iterator(I_List< T > &a)
Definition: sql_list.h:861
T * operator++(int)
Definition: sql_list.h:862
Definition: sql_list.h:844
void move_elements_to(I_List< T > *new_owner)
Definition: sql_list.h:852
Definition: sql_list.h:653
T & operator*() const
Definition: sql_list.h:658
T * operator->() const
Definition: sql_list.h:681
T value_type
Definition: sql_list.h:666
bool operator==(const List_STL_Iterator &other) const
Definition: sql_list.h:672
List_STL_Iterator()=default
std::forward_iterator_tag iterator_category
Definition: sql_list.h:669
list_node * m_current
Definition: sql_list.h:694
T * pointer
Definition: sql_list.h:667
List_STL_Iterator(list_node *node)
Definition: sql_list.h:655
T & reference
Definition: sql_list.h:668
List_STL_Iterator & operator++()
Definition: sql_list.h:660
List_STL_Iterator operator++(int)
Definition: sql_list.h:687
bool operator!=(const List_STL_Iterator &other) const
Definition: sql_list.h:677
ptrdiff_t difference_type
Definition: sql_list.h:665
Definition: sql_list.h:627
T * replace(T *)
Definition: sql_list.h:629
List_iterator_fast(List< T > &a)
Definition: sql_list.h:636
void after(T *)
Definition: sql_list.h:632
void remove(void)
Definition: sql_list.h:631
T ** ref(void)
Definition: sql_list.h:633
void sublist(List< T > &list_arg, uint el_arg)
Definition: sql_list.h:641
void init(List< T > &a)
Definition: sql_list.h:638
void rewind(void)
Definition: sql_list.h:640
T * operator++(int)
Definition: sql_list.h:639
T * replace(List< T > &)
Definition: sql_list.h:630
List_iterator_fast()
Definition: sql_list.h:637
Definition: sql_list.h:606
List_iterator()
Definition: sql_list.h:609
void init(List< T > &a)
Definition: sql_list.h:610
T ** ref(void)
Definition: sql_list.h:620
void after(T *a)
Definition: sql_list.h:616
T * replace(List< T > &a)
Definition: sql_list.h:613
T * replace(T *a)
Definition: sql_list.h:612
T * operator++(int)
Definition: sql_list.h:611
bool after(T *a, MEM_ROOT *mem_root)
Definition: sql_list.h:617
void remove()
Definition: sql_list.h:615
void rewind(void)
Definition: sql_list.h:614
List_iterator(List< T > &a)
Definition: sql_list.h:608
Definition: sql_list.h:467
bool push_back(T *a, MEM_ROOT *mem_root)
Definition: sql_list.h:484
iterator begin()
Definition: sql_list.h:582
const_iterator begin() const
Definition: sql_list.h:593
const_iterator cend() const
Definition: sql_list.h:599
void delete_elements(void)
Definition: sql_list.h:502
const T * head() const
Definition: sql_list.h:494
List_STL_Iterator< const T > const_iterator
Definition: sql_list.h:592
void destroy_elements(void)
Definition: sql_list.h:511
List()
Definition: sql_list.h:469
List(const List< T > &tmp, MEM_ROOT *mem_root)
Definition: sql_list.h:474
void sort(Node_cmp_func cmp)
Sort the list.
Definition: sql_list.h:567
bool swap_elts(uint index1, uint index2)
Definition: sql_list.h:534
T * head()
Definition: sql_list.h:493
void disjoin(List< T > *list)
Definition: sql_list.h:500
bool push_back(T *a)
Definition: sql_list.h:481
List_STL_Iterator< T > iterator
Definition: sql_list.h:581
const_iterator end() const
Definition: sql_list.h:594
bool push_front(T *a, MEM_ROOT *mem_root)
Definition: sql_list.h:490
List(const List< T > &tmp)
Definition: sql_list.h:470
List & operator=(const List &tmp)
Definition: sql_list.h:471
T ** head_ref()
Definition: sql_list.h:497
T * operator[](uint index) const
Definition: sql_list.h:520
const_iterator cbegin() const
Definition: sql_list.h:598
iterator end()
Definition: sql_list.h:583
void prepend(List< T > *list)
Definition: sql_list.h:501
T * pop()
Definition: sql_list.h:498
bool push_front(T *a)
Definition: sql_list.h:487
void replace(uint index, T *new_value)
Definition: sql_list.h:527
void concat(List< T > *list)
Definition: sql_list.h:499
Simple intrusive linked list.
Definition: sql_list.h:47
void save_and_clear(SQL_I_List< T > *save)
Definition: sql_list.h:81
T * first
The first element in the list.
Definition: sql_list.h:51
void push_front(SQL_I_List< T > *save)
Definition: sql_list.h:86
void push_back(SQL_I_List< T > *save)
Definition: sql_list.h:93
void link_in_list(T *element, T **next_ptr)
Definition: sql_list.h:74
uint elements
Definition: sql_list.h:49
SQL_I_List()
Definition: sql_list.h:59
T ** next
A reference to the next element in the list.
Definition: sql_list.h:57
void split_after(uint sz, SQL_I_List< T > *tail)
Definition: sql_list.h:109
SQL_I_List & operator=(SQL_I_List &)=default
uint size() const
Definition: sql_list.h:129
void clear()
Definition: sql_list.h:68
SQL_I_List(const SQL_I_List &tmp)
Definition: sql_list.h:61
SQL_I_List(SQL_I_List &&)=default
SQL_I_List & operator=(SQL_I_List &&)=default
Definition: sql_list.h:825
T * current
Definition: sql_list.h:827
T * next(void) SUPPRESS_UBSAN
Definition: sql_list.h:834
base_ilist_iterator(base_ilist< T > &list_par)
Definition: sql_list.h:830
base_ilist< T > * list
Definition: sql_list.h:826
T ** el
Definition: sql_list.h:827
Definition: sql_list.h:752
T * get()
Definition: sql_list.h:789
void operator=(const base_ilist &)
void move_elements_to(base_ilist *new_owner)
Moves list elements to new owner, and empties current owner (i.e.
Definition: sql_list.h:805
T * first
Definition: sql_list.h:753
bool is_empty() const SUPPRESS_UBSAN
Definition: sql_list.h:768
void clear() SUPPRESS_UBSAN
Definition: sql_list.h:761
T * head()
Definition: sql_list.h:796
base_ilist(const base_ilist &)
void push_front(T *a)
Pushes new element in front of list.
Definition: sql_list.h:773
void push_back(T *a)
Pushes new element to the end of the list, i.e. in front of the sentinel.
Definition: sql_list.h:781
ilink< T > sentinel
Definition: sql_list.h:754
base_ilist()
Definition: sql_list.h:765
Definition: sql_list.h:372
void init(base_list &list_par)
Definition: sql_list.h:388
list_node ** prev
Definition: sql_list.h:375
void * next_fast(void)
Definition: sql_list.h:401
void ** ref(void)
Definition: sql_list.h:445
bool is_last(void)
Definition: sql_list.h:449
bool is_before_first() const
Definition: sql_list.h:450
void after(void *element)
Definition: sql_list.h:432
list_node ** el
Definition: sql_list.h:375
void * replace(void *element)
Definition: sql_list.h:408
void sublist(base_list &ls, uint elm)
Definition: sql_list.h:376
base_list_iterator()
Definition: sql_list.h:383
friend class error_list_iterator
Definition: sql_list.h:460
base_list_iterator(base_list &list_par)
Definition: sql_list.h:386
void rewind(void)
Definition: sql_list.h:407
list_node * current
Definition: sql_list.h:375
base_list * list
Definition: sql_list.h:374
void remove(void)
Definition: sql_list.h:426
bool prepend(void *a, MEM_ROOT *mem_root)
Definition: sql_list.h:451
bool after(void *a, MEM_ROOT *mem_root)
Definition: sql_list.h:438
void * replace(base_list &new_list)
Definition: sql_list.h:414
void * next(void)
Definition: sql_list.h:395
Definition: sql_list.h:164
bool push_back(void *info)
Definition: sql_list.h:205
void ** head_ref()
Definition: sql_list.h:300
list_node * last_ref()
Definition: sql_list.h:304
void disjoin(base_list *list)
Definition: sql_list.h:267
base_list(const base_list &tmp)
This is a shallow copy constructor that implicitly passes the ownership from the source list to the n...
Definition: sql_list.h:190
void concat(base_list *list)
Definition: sql_list.h:253
friend class error_list
Definition: sql_list.h:307
list_node * first_node()
Definition: sql_list.h:297
bool push_front(void *info)
Definition: sql_list.h:223
void * pop(void)
Definition: sql_list.h:260
uint size() const
Definition: sql_list.h:305
base_list()
Definition: sql_list.h:180
void swap(base_list &rhs)
Swap two lists.
Definition: sql_list.h:291
bool push_back(void *info, MEM_ROOT *mem_root)
Definition: sql_list.h:214
const void * head() const
Definition: sql_list.h:299
friend class error_list_iterator
Definition: sql_list.h:308
void after(void *info, list_node *node)
Definition: sql_list.h:354
list_node * last_node()
Definition: sql_list.h:296
bool is_empty() const
Definition: sql_list.h:303
void * head()
Definition: sql_list.h:298
bool operator==(const base_list &rhs) const
Definition: sql_list.h:171
void prepend(base_list *list)
Definition: sql_list.h:280
void remove(list_node **prev)
Definition: sql_list.h:244
uint elements
Definition: sql_list.h:169
list_node ** last
Definition: sql_list.h:166
base_list & operator=(const base_list &tmp)
Definition: sql_list.h:194
bool after(void *info, list_node *node, MEM_ROOT *mem_root)
Definition: sql_list.h:360
void clear()
Definition: sql_list.h:175
list_node * first
Definition: sql_list.h:166
bool push_front(void *info, MEM_ROOT *mem_root)
Definition: sql_list.h:233
Definition: sql_list.h:739
const char * val
Definition: sql_list.h:742
i_string_pair(const char *key_arg, const char *val_arg)
Definition: sql_list.h:744
i_string_pair()
Definition: sql_list.h:743
const char * key
Definition: sql_list.h:741
Definition: sql_list.h:731
i_string(const char *s)
Definition: sql_list.h:735
const char * ptr
Definition: sql_list.h:733
i_string()
Definition: sql_list.h:734
static MEM_ROOT mem_root
Definition: client_plugin.cc:114
static int cmp(Bigint *a, Bigint *b)
Definition: dtoa.cc:1060
This file follows Google coding style, except for the name MEM_ROOT (which is kept for historical rea...
void destroy_at(T *ptr)
Definition: my_alloc.h:459
Header for compiler-dependent features.
#define SUPPRESS_UBSAN
Definition: my_compiler.h:123
#define DBUG_PRINT(keyword, arglist)
Definition: my_dbug.h:181
Functions related to handling of plugins and other dynamically loaded libraries.
#define MYSQL_PLUGIN_IMPORT
Definition: my_sharedlib.h:71
void copy(Shards< COUNT > &dst, const Shards< COUNT > &src) noexcept
Copy the counters, overwrite destination.
Definition: ut0counter.h:354
std::list< T, ut::allocator< T > > list
Specialization of list which uses ut_allocator.
Definition: ut0new.h:2878
MYSQL_PLUGIN_IMPORT list_node end_of_list
Definition: sql_list.cc:29
void free_list(I_List< i_string > *list)
Definition: sql_list.cc:31
static void swap(String &a, String &b) noexcept
Definition: sql_string.h:663
case opt name
Definition: sslopt-case.h:29
The MEM_ROOT is a simple arena, where allocations are carved out of larger blocks.
Definition: my_alloc.h:83
list_node - a node of a single-linked list.
Definition: sql_list.h:150
list_node * next
Definition: sql_list.h:151
list_node()
Definition: sql_list.h:155
list_node(void *info_par, list_node *next_par)
Definition: sql_list.h:153
void * info
Definition: sql_list.h:152