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