MySQL  8.0.27
Source Code Documentation
prealloced_array.h
Go to the documentation of this file.
1 /* Copyright (c) 2013, 2021, 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 PREALLOCED_ARRAY_INCLUDED
24 #define PREALLOCED_ARRAY_INCLUDED
25 
26 /**
27  @file include/prealloced_array.h
28 */
29 
30 #include <assert.h>
31 #include <stddef.h>
32 #include <algorithm>
33 #include <new>
34 #include <type_traits>
35 #include <utility>
36 
37 #include "my_compiler.h"
38 
39 #include "my_inttypes.h"
40 #include "my_sys.h"
41 #include "mysql/psi/psi_memory.h"
43 
44 /**
45  A typesafe replacement for DYNAMIC_ARRAY. We do our own memory management,
46  and pre-allocate space for a number of elements. The purpose is to
47  pre-allocate enough elements to cover normal use cases, thus saving
48  malloc()/free() overhead.
49  If we run out of space, we use malloc to allocate more space.
50 
51  The interface is chosen to be similar to std::vector.
52  We keep the std::vector property that storage is contiguous.
53 
54  We have fairly low overhead over the inline storage; typically 8 bytes
55  (e.g. Prealloced_array<TABLE *, 4> needs 40 bytes on 64-bit platforms).
56 
57  @remark
58  Unlike DYNAMIC_ARRAY, elements are properly copied
59  (rather than memcpy()d) if the underlying array needs to be expanded.
60 
61  @remark
62  Depending on Has_trivial_destructor, we destroy objects which are
63  removed from the array (including when the array object itself is destroyed).
64 
65  @tparam Element_type The type of the elements of the container.
66  Elements must be copyable or movable.
67  @tparam Prealloc Number of elements to pre-allocate.
68  */
69 template <typename Element_type, size_t Prealloc>
71  /**
72  Is Element_type trivially destructible? If it is, we don't destroy
73  elements when they are removed from the array or when the array is
74  destroyed.
75  */
76  static constexpr bool Has_trivial_destructor =
78 
79  bool using_inline_buffer() const { return m_inline_size >= 0; }
80 
81  /**
82  Gets the buffer in use.
83  */
84  Element_type *buffer() {
86  }
87  const Element_type *buffer() const {
89  }
90 
91  void set_size(size_t n) {
92  if (using_inline_buffer()) {
93  m_inline_size = n;
94  } else {
96  }
97  }
98  void adjust_size(int delta) {
99  if (using_inline_buffer()) {
100  m_inline_size += delta;
101  } else {
102  m_ext.m_alloced_size += delta;
103  }
104  }
105 
106  public:
107  /// Initial capacity of the array.
108  static const size_t initial_capacity = Prealloc;
109 
110  /// Standard typedefs.
111  typedef Element_type value_type;
112  typedef size_t size_type;
113  typedef ptrdiff_t difference_type;
114 
115  typedef Element_type *iterator;
116  typedef const Element_type *const_iterator;
117 
118  explicit Prealloced_array(PSI_memory_key psi_key) : m_psi_key(psi_key) {
119  static_assert(Prealloc != 0, "We do not want a zero-size array.");
120  }
121 
122  /**
123  Initializes (parts of) the array with default values.
124  Using 'Prealloc' for initial_size makes this similar to a raw C array.
125  */
126  Prealloced_array(PSI_memory_key psi_key, size_t initial_size)
127  : m_psi_key(psi_key) {
128  static_assert(Prealloc != 0, "We do not want a zero-size array.");
129 
130  if (initial_size > Prealloc) {
131  // We avoid using reserve() since it requires Element_type to be copyable.
132  void *mem =
133  my_malloc(m_psi_key, initial_size * element_size(), MYF(MY_WME));
134  if (!mem) return;
135  m_inline_size = -1;
136  m_ext.m_alloced_size = initial_size;
137  m_ext.m_array_ptr = static_cast<Element_type *>(mem);
138  m_ext.m_alloced_capacity = initial_size;
139  } else {
140  m_inline_size = initial_size;
141  }
142  for (size_t ix = 0; ix < initial_size; ++ix) {
143  Element_type *p = &buffer()[ix];
144  ::new (p) Element_type();
145  }
146  }
147 
148  /**
149  An object instance "owns" its array, so we do deep copy here.
150  */
152  if (this->reserve(that.capacity())) return;
153  for (const Element_type *p = that.begin(); p != that.end(); ++p)
154  this->push_back(*p);
155  }
156 
158  *this = std::move(that);
159  }
160 
161  /**
162  Range constructor.
163 
164  Constructs a container with as many elements as the range [first,last),
165  with each element constructed from its corresponding element in that range,
166  in the same order.
167  */
170  : m_psi_key(psi_key) {
171  if (this->reserve(last - first)) return;
172  for (; first != last; ++first) push_back(*first);
173  }
174 
175  Prealloced_array(std::initializer_list<Element_type> elems)
176  : Prealloced_array(PSI_NOT_INSTRUMENTED, elems.begin(), elems.end()) {}
177 
178  /**
179  Copies all the elements from 'that' into this container.
180  Any objects in this container are destroyed first.
181  */
183  this->clear();
184  if (this->reserve(that.capacity())) return *this;
185  for (const Element_type *p = that.begin(); p != that.end(); ++p)
186  this->push_back(*p);
187  return *this;
188  }
189 
191  this->clear();
192  if (!that.using_inline_buffer()) {
194  // The array is on the heap, so we can just grab it.
195  m_ext.m_array_ptr = that.m_ext.m_array_ptr;
196  m_inline_size = -1;
197  m_ext.m_alloced_size = that.m_ext.m_alloced_size;
198  m_ext.m_alloced_capacity = that.m_ext.m_alloced_capacity;
199  that.m_inline_size = 0;
200  } else {
201  // Move over each element.
202  if (this->reserve(that.capacity())) return *this;
203  for (Element_type *p = that.begin(); p != that.end(); ++p)
204  this->push_back(std::move(*p));
205  that.clear();
206  }
207  return *this;
208  }
209 
210  /**
211  Runs DTOR on all elements if needed.
212  Deallocates array if we exceeded the Preallocated amount.
213  */
215  if (!Has_trivial_destructor) {
216  clear();
217  }
219  }
220 
221  size_t capacity() const {
222  return using_inline_buffer() ? Prealloc : m_ext.m_alloced_capacity;
223  }
224  size_t element_size() const { return sizeof(Element_type); }
225  bool empty() const { return size() == 0; }
226  size_t size() const {
228  }
229 
230  Element_type &at(size_t n) {
231  assert(n < size());
232  return buffer()[n];
233  }
234 
235  const Element_type &at(size_t n) const {
236  assert(n < size());
237  return buffer()[n];
238  }
239 
240  Element_type &operator[](size_t n) { return at(n); }
241  const Element_type &operator[](size_t n) const { return at(n); }
242 
243  Element_type &back() { return at(size() - 1); }
244  const Element_type &back() const { return at(size() - 1); }
245 
246  Element_type &front() { return at(0); }
247  const Element_type &front() const { return at(0); }
248 
249  /**
250  begin : Returns a pointer to the first element in the array.
251  end : Returns a pointer to the past-the-end element in the array.
252  */
253  iterator begin() { return buffer(); }
254  iterator end() { return buffer() + size(); }
255  const_iterator begin() const { return buffer(); }
256  const_iterator end() const { return buffer() + size(); }
257  /// Returns a constant pointer to the first element in the array.
258  const_iterator cbegin() const { return begin(); }
259  /// Returns a constant pointer to the past-the-end element in the array.
260  const_iterator cend() const { return end(); }
261 
262  /**
263  Assigns a value to an arbitrary element, even where n >= size().
264  The array is extended with default values if necessary.
265  @retval true if out-of-memory, false otherwise.
266  */
267  bool assign_at(size_t n, const value_type &val) {
268  if (n < size()) {
269  at(n) = val;
270  return false;
271  }
272  if (reserve(n + 1)) return true;
273  resize(n);
274  return push_back(val);
275  }
276 
277  /**
278  Reserves space for array elements.
279  Copies (or moves, if possible) over existing elements, in case we
280  are re-expanding the array.
281 
282  @param n number of elements.
283  @retval true if out-of-memory, false otherwise.
284  */
285  bool reserve(size_t n) {
286  if (n <= capacity()) return false;
287 
288  void *mem = my_malloc(m_psi_key, n * element_size(), MYF(MY_WME));
289  if (!mem) return true;
290  Element_type *new_array = static_cast<Element_type *>(mem);
291 
292  // Move all the existing elements into the new array.
293  size_t old_size = size();
294  for (size_t ix = 0; ix < old_size; ++ix) {
295  Element_type *new_p = &new_array[ix];
296  Element_type &old_p = buffer()[ix];
297  ::new (new_p) Element_type(std::move(old_p)); // Move into new location.
299  old_p.~Element_type(); // Destroy the old element.
300  }
301 
303 
304  // Forget the old array;
305  m_ext.m_alloced_size = old_size;
306  m_inline_size = -1;
307  m_ext.m_array_ptr = new_array;
309  return false;
310  }
311 
312  /**
313  Copies an element into the back of the array.
314  Complexity: Constant (amortized time, reallocation may happen).
315  @return true if out-of-memory, false otherwise
316  */
317  bool push_back(const Element_type &element) { return emplace_back(element); }
318 
319  /**
320  Copies (or moves, if possible) an element into the back of the array.
321  Complexity: Constant (amortized time, reallocation may happen).
322  @return true if out-of-memory, false otherwise
323  */
324  bool push_back(Element_type &&element) {
325  return emplace_back(std::move(element));
326  }
327 
328  /**
329  Constructs an element at the back of the array.
330  Complexity: Constant (amortized time, reallocation may happen).
331  @return true if out-of-memory, false otherwise
332  */
333  template <typename... Args>
334  bool emplace_back(Args &&... args) {
335  const size_t expansion_factor = 2;
336  if (size() == capacity() && reserve(capacity() * expansion_factor))
337  return true;
338  Element_type *p = &buffer()[size()];
339  adjust_size(1);
340  ::new (p) Element_type(std::forward<Args>(args)...);
341  return false;
342  }
343 
344  /**
345  Removes the last element in the array, effectively reducing the
346  container size by one. This destroys the removed element.
347  */
348  void pop_back() {
349  assert(!empty());
350  if (!Has_trivial_destructor) back().~Element_type();
351  adjust_size(-1);
352  }
353 
354  /**
355  The array is extended by inserting a new element before the element at the
356  specified position.
357 
358  This is generally an inefficient operation, since we need to copy
359  elements to make a new "hole" in the array.
360 
361  We use std::rotate to move objects, hence Element_type must be
362  move-assignable and move-constructible.
363 
364  @return an iterator pointing to the inserted value
365  */
366  iterator insert(const_iterator position, const value_type &val) {
367  return emplace(position, val);
368  }
369 
370  /**
371  The array is extended by inserting a new element before the element at the
372  specified position. The element is moved into the array, if possible.
373 
374  This is generally an inefficient operation, since we need to copy
375  elements to make a new "hole" in the array.
376 
377  We use std::rotate to move objects, hence Element_type must be
378  move-assignable and move-constructible.
379 
380  @return an iterator pointing to the inserted value
381  */
383  return emplace(position, std::move(val));
384  }
385 
386  /**
387  The array is extended by inserting a new element before the element at the
388  specified position. The element is constructed in-place.
389 
390  This is generally an inefficient operation, since we need to copy
391  elements to make a new "hole" in the array.
392 
393  We use std::rotate to move objects, hence Element_type must be
394  move-assignable and move-constructible.
395 
396  @return an iterator pointing to the inserted value
397  */
398  template <typename... Args>
399  iterator emplace(const_iterator position, Args &&... args) {
400  const difference_type n = position - begin();
401  emplace_back(std::forward<Args>(args)...);
402  std::rotate(begin() + n, end() - 1, end());
403  return begin() + n;
404  }
405 
406  /**
407  Similar to std::set<>::insert()
408  Extends the array by inserting a new element, but only if it cannot be found
409  in the array already.
410 
411  Assumes that the array is sorted with std::less<Element_type>
412  Insertion using this function will maintain order.
413 
414  @retval A pair, with its member pair::first set an iterator pointing to
415  either the newly inserted element, or to the equivalent element
416  already in the array. The pair::second element is set to true if
417  the new element was inserted, or false if an equivalent element
418  already existed.
419  */
420  std::pair<iterator, bool> insert_unique(const value_type &val) {
421  std::pair<iterator, iterator> p = std::equal_range(begin(), end(), val);
422  // p.first == p.second means we did not find it.
423  if (p.first == p.second) return std::make_pair(insert(p.first, val), true);
424  return std::make_pair(p.first, false);
425  }
426 
427  /**
428  Similar to std::set<>::erase()
429  Removes a single element from the array by value.
430  The removed element is destroyed.
431  This effectively reduces the container size by one.
432 
433  This is generally an inefficient operation, since we need to copy
434  elements to fill the "hole" in the array.
435 
436  Assumes that the array is sorted with std::less<Element_type>.
437 
438  @retval number of elements removed, 0 or 1.
439  */
441  std::pair<iterator, iterator> p = std::equal_range(begin(), end(), val);
442  if (p.first == p.second) return 0; // Not found
443  erase(p.first);
444  return 1;
445  }
446 
447  /**
448  Similar to std::set<>::count()
449 
450  @note Assumes that array is maintained with insert_unique/erase_unique.
451 
452  @retval 1 if element is found, 0 otherwise.
453  */
454  size_type count_unique(const value_type &val) const {
455  return std::binary_search(begin(), end(), val);
456  }
457 
458  /**
459  Removes a single element from the array.
460  The removed element is destroyed.
461  This effectively reduces the container size by one.
462 
463  This is generally an inefficient operation, since we need to move
464  or copy elements to fill the "hole" in the array.
465 
466  We use std::move to move objects, hence Element_type must be
467  move-assignable.
468  */
470  assert(position != end());
471  return erase(position - begin());
472  }
473 
474  /**
475  Removes a single element from the array.
476  */
477  iterator erase(size_t ix) {
478  assert(ix < size());
479  iterator pos = begin() + ix;
480  if (pos + 1 != end()) std::move(pos + 1, end(), pos);
481  pop_back();
482  return pos;
483  }
484 
485  /**
486  Removes tail elements from the array.
487  The removed elements are destroyed.
488  This effectively reduces the containers size by 'end() - first'.
489  */
492  const difference_type diff = last - first;
493  if (!Has_trivial_destructor) {
494  for (; first != last; ++first) first->~Element_type();
495  }
496  adjust_size(-diff);
497  }
498 
499  /**
500  Removes a range of elements from the array.
501  The removed elements are destroyed.
502  This effectively reduces the containers size by 'last - first'.
503 
504  This is generally an inefficient operation, since we need to move
505  or copy elements to fill the "hole" in the array.
506 
507  We use std::move to move objects, hence Element_type must be
508  move-assignable.
509  */
511  /*
512  std::move() wants non-const input iterators, otherwise it cannot move and
513  must always copy the elements. Convert first and last from const_iterator
514  to iterator.
515  */
516  iterator start = begin() + (first - cbegin());
517  iterator stop = begin() + (last - cbegin());
518  if (first != last) erase_at_end(std::move(stop, end(), start));
519  return start;
520  }
521 
522  /**
523  Exchanges the content of the container by the content of rhs, which
524  is another vector object of the same type. Sizes may differ.
525 
526  We use std::swap to do the operation.
527  */
528  void swap(Prealloced_array &rhs) {
529  // Just swap pointers if both arrays have done malloc.
530  if (!using_inline_buffer() && !rhs.using_inline_buffer()) {
535  return;
536  }
537  std::swap(*this, rhs);
538  }
539 
540  /**
541  Requests the container to reduce its capacity to fit its size.
542  */
543  void shrink_to_fit() {
544  // Cannot shrink the pre-allocated array.
545  if (using_inline_buffer()) return;
546  // No point in swapping.
547  if (size() == capacity()) return;
548  Prealloced_array tmp(m_psi_key, begin(), end());
549  if (size() <= Prealloc) {
550  /*
551  The elements fit in the pre-allocated array. Destruct the
552  heap-allocated array in this, and copy the elements into the
553  pre-allocated array.
554  */
555  this->~Prealloced_array();
556  new (this) Prealloced_array(tmp.m_psi_key, tmp.begin(), tmp.end());
557  } else {
558  // Both this and tmp have a heap-allocated array. Swap pointers.
559  swap(tmp);
560  }
561  }
562 
563  /**
564  Resizes the container so that it contains n elements.
565 
566  If n is smaller than the current container size, the content is
567  reduced to its first n elements, removing those beyond (and
568  destroying them).
569 
570  If n is greater than the current container size, the content is
571  expanded by inserting at the end as many elements as needed to
572  reach a size of n. If val is specified, the new elements are
573  initialized as copies of val, otherwise, they are
574  value-initialized.
575 
576  If n is also greater than the current container capacity, an automatic
577  reallocation of the allocated storage space takes place.
578 
579  Notice that this function changes the actual content of the
580  container by inserting or erasing elements from it.
581  */
582  void resize(size_t n, const Element_type &val = Element_type()) {
583  if (n == size()) return;
584  if (n > size()) {
585  if (!reserve(n)) {
586  while (n != size()) push_back(val);
587  }
588  return;
589  }
590  if (!Has_trivial_destructor) {
591  while (n != size()) pop_back();
592  }
593  set_size(n);
594  }
595 
596  /**
597  Removes (and destroys) all elements.
598  Does not change capacity.
599  */
600  void clear() {
601  if (!Has_trivial_destructor) {
602  for (Element_type *p = begin(); p != end(); ++p)
603  p->~Element_type(); // Destroy discarded element.
604  }
605  set_size(0);
606  }
607 
608  private:
610 
611  // If >= 0, we're using the inline storage in m_buff, and contains the real
612  // size. If negative, we're using external storage (m_array_ptr),
613  // and m_alloced_size contains the real size.
614  int m_inline_size = 0;
615 
616  // Defined outside the union because we need an initializer to avoid
617  // "may be used uninitialized" for -flto builds, and
618  // MSVC rejects initializers for individual members of an anonymous union.
619  // (otherwise, we'd make it an anonymous struct, to avoid m_ext everywhere).
620  struct External {
621  Element_type *m_array_ptr;
624  };
625 
626  union {
628  Element_type m_buff[Prealloc];
629  };
630 };
631 static_assert(sizeof(Prealloced_array<void *, 4>) <= 40,
632  "Check for no unexpected padding");
633 
634 #endif // PREALLOCED_ARRAY_INCLUDED
A typesafe replacement for DYNAMIC_ARRAY.
Definition: prealloced_array.h:70
bool push_back(const Element_type &element)
Copies an element into the back of the array.
Definition: prealloced_array.h:317
const Element_type & operator[](size_t n) const
Definition: prealloced_array.h:241
iterator erase(const_iterator first, const_iterator last)
Removes a range of elements from the array.
Definition: prealloced_array.h:510
size_type count_unique(const value_type &val) const
Similar to std::set<>::count()
Definition: prealloced_array.h:454
Prealloced_array(PSI_memory_key psi_key, const_iterator first, const_iterator last)
Range constructor.
Definition: prealloced_array.h:168
size_type erase_unique(const value_type &val)
Similar to std::set<>::erase() Removes a single element from the array by value.
Definition: prealloced_array.h:440
bool empty() const
Definition: prealloced_array.h:225
Prealloced_array(std::initializer_list< Element_type > elems)
Definition: prealloced_array.h:175
const Element_type * buffer() const
Definition: prealloced_array.h:87
const Element_type & at(size_t n) const
Definition: prealloced_array.h:235
Prealloced_array(PSI_memory_key psi_key)
Definition: prealloced_array.h:118
Element_type & at(size_t n)
Definition: prealloced_array.h:230
Element_type value_type
Standard typedefs.
Definition: prealloced_array.h:111
Prealloced_array(const Prealloced_array &that)
An object instance "owns" its array, so we do deep copy here.
Definition: prealloced_array.h:151
bool using_inline_buffer() const
Definition: prealloced_array.h:79
iterator erase(size_t ix)
Removes a single element from the array.
Definition: prealloced_array.h:477
bool emplace_back(Args &&... args)
Constructs an element at the back of the array.
Definition: prealloced_array.h:334
Element_type & front()
Definition: prealloced_array.h:246
Element_type & operator[](size_t n)
Definition: prealloced_array.h:240
void clear()
Removes (and destroys) all elements.
Definition: prealloced_array.h:600
bool reserve(size_t n)
Reserves space for array elements.
Definition: prealloced_array.h:285
static constexpr bool Has_trivial_destructor
Is Element_type trivially destructible? If it is, we don't destroy elements when they are removed fro...
Definition: prealloced_array.h:76
Prealloced_array(Prealloced_array &&that)
Definition: prealloced_array.h:157
Prealloced_array & operator=(const Prealloced_array &that)
Copies all the elements from 'that' into this container.
Definition: prealloced_array.h:182
void resize(size_t n, const Element_type &val=Element_type())
Resizes the container so that it contains n elements.
Definition: prealloced_array.h:582
const_iterator cbegin() const
Returns a constant pointer to the first element in the array.
Definition: prealloced_array.h:258
static const size_t initial_capacity
Initial capacity of the array.
Definition: prealloced_array.h:108
void swap(Prealloced_array &rhs)
Exchanges the content of the container by the content of rhs, which is another vector object of the s...
Definition: prealloced_array.h:528
iterator insert(const_iterator position, value_type &&val)
The array is extended by inserting a new element before the element at the specified position.
Definition: prealloced_array.h:382
bool assign_at(size_t n, const value_type &val)
Assigns a value to an arbitrary element, even where n >= size().
Definition: prealloced_array.h:267
void pop_back()
Removes the last element in the array, effectively reducing the container size by one.
Definition: prealloced_array.h:348
~Prealloced_array()
Runs DTOR on all elements if needed.
Definition: prealloced_array.h:214
void set_size(size_t n)
Definition: prealloced_array.h:91
PSI_memory_key m_psi_key
Definition: prealloced_array.h:609
Element_type * iterator
Definition: prealloced_array.h:115
iterator erase(const_iterator position)
Removes a single element from the array.
Definition: prealloced_array.h:469
size_t capacity() const
Definition: prealloced_array.h:221
const Element_type & back() const
Definition: prealloced_array.h:244
const_iterator cend() const
Returns a constant pointer to the past-the-end element in the array.
Definition: prealloced_array.h:260
void shrink_to_fit()
Requests the container to reduce its capacity to fit its size.
Definition: prealloced_array.h:543
iterator emplace(const_iterator position, Args &&... args)
The array is extended by inserting a new element before the element at the specified position.
Definition: prealloced_array.h:399
size_t size() const
Definition: prealloced_array.h:226
ptrdiff_t difference_type
Definition: prealloced_array.h:113
void erase_at_end(const_iterator first)
Removes tail elements from the array.
Definition: prealloced_array.h:490
Element_type * buffer()
Gets the buffer in use.
Definition: prealloced_array.h:84
std::pair< iterator, bool > insert_unique(const value_type &val)
Similar to std::set<>::insert() Extends the array by inserting a new element, but only if it cannot b...
Definition: prealloced_array.h:420
bool push_back(Element_type &&element)
Copies (or moves, if possible) an element into the back of the array.
Definition: prealloced_array.h:324
const Element_type & front() const
Definition: prealloced_array.h:247
const_iterator begin() const
Definition: prealloced_array.h:255
Prealloced_array(PSI_memory_key psi_key, size_t initial_size)
Initializes (parts of) the array with default values.
Definition: prealloced_array.h:126
iterator begin()
begin : Returns a pointer to the first element in the array.
Definition: prealloced_array.h:253
Prealloced_array & operator=(Prealloced_array &&that)
Definition: prealloced_array.h:190
Element_type & back()
Definition: prealloced_array.h:243
iterator end()
Definition: prealloced_array.h:254
iterator insert(const_iterator position, const value_type &val)
The array is extended by inserting a new element before the element at the specified position.
Definition: prealloced_array.h:366
size_t element_size() const
Definition: prealloced_array.h:224
const_iterator end() const
Definition: prealloced_array.h:256
External m_ext
Definition: prealloced_array.h:627
int m_inline_size
Definition: prealloced_array.h:614
const Element_type * const_iterator
Definition: prealloced_array.h:116
size_t size_type
Definition: prealloced_array.h:112
void adjust_size(int delta)
Definition: prealloced_array.h:98
Element_type m_buff[Prealloc]
Definition: prealloced_array.h:628
const char * p
Definition: ctype-mb.cc:1236
char * pos
Definition: do_ctype.cc:76
static Bigint * diff(Bigint *a, Bigint *b, Stack_alloc *alloc)
Definition: dtoa.cc:1082
#define MY_WME
Definition: my_sys.h:122
unsigned int PSI_memory_key
Instrumented memory key.
Definition: psi_memory_bits.h:48
static void start(mysql_harness::PluginFuncEnv *env)
Definition: http_auth_backend_plugin.cc:165
Header for compiler-dependent features.
Some integer typedefs for easier portability.
#define MYF(v)
Definition: my_inttypes.h:96
void my_free(void *ptr)
Frees the memory pointed by the ptr.
Definition: my_memory.cc:80
void * my_malloc(PSI_memory_key key, size_t size, int flags)
Allocates size bytes of memory.
Definition: my_memory.cc:56
Common header for many mysys elements.
const string value("\"Value\"")
Performance schema instrumentation interface.
static MEM_ROOT mem
Definition: sql_servers.cc:98
static void swap(String &a, String &b) noexcept
Definition: sql_string.h:610
Definition: prealloced_array.h:620
size_t m_alloced_size
Definition: prealloced_array.h:622
size_t m_alloced_capacity
Definition: prealloced_array.h:623
Element_type * m_array_ptr
Definition: prealloced_array.h:621
#define PSI_NOT_INSTRUMENTED
Definition: validate_password_imp.cc:39
int n
Definition: xcom_base.cc:505