File: shared_dictionary_cache.h

package info (click to toggle)
mysql-8.0 8.0.43-3
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 1,273,924 kB
  • sloc: cpp: 4,684,605; ansic: 412,450; pascal: 108,398; java: 83,641; perl: 30,221; cs: 27,067; sql: 26,594; sh: 24,181; python: 21,816; yacc: 17,169; php: 11,522; xml: 7,388; javascript: 7,076; makefile: 2,194; lex: 1,075; awk: 670; asm: 520; objc: 183; ruby: 97; lisp: 86
file content (372 lines) | stat: -rw-r--r-- 13,076 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
/* Copyright (c) 2015, 2025, Oracle and/or its affiliates.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License, version 2.0,
   as published by the Free Software Foundation.

   This program is designed to work with certain software (including
   but not limited to OpenSSL) that is licensed under separate terms,
   as designated in a particular file or component or in included license
   documentation.  The authors of MySQL hereby grant you an additional
   permission to link the program and your derivative works with the
   separately licensed software that they have either included with
   the program or referenced in the documentation.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License, version 2.0, for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA */

#ifndef DD_CACHE__SHARED_DICTIONARY_CACHE_INCLUDED
#define DD_CACHE__SHARED_DICTIONARY_CACHE_INCLUDED

#include <stdio.h>

#include "sql/dd/impl/cache/shared_multi_map.h"  // Shared_multi_map
#include "sql/dd/types/abstract_table.h"
#include "sql/dd/types/charset.h"                   // Charset
#include "sql/dd/types/collation.h"                 // Collation
#include "sql/dd/types/column_statistics.h"         // Column_statistics
#include "sql/dd/types/event.h"                     // Event
#include "sql/dd/types/routine.h"                   // Routine
#include "sql/dd/types/schema.h"                    // Schema
#include "sql/dd/types/spatial_reference_system.h"  // Spatial_reference_system
#include "sql/dd/types/table.h"                     // IWYU pragma: keep
#include "sql/dd/types/tablespace.h"                // Tablespace
#include "sql/handler.h"                            // enum_tx_isolation

class THD;

namespace dd {
namespace cache {

/**
  Shared dictionary cache containing several maps.

  The dictionary cache is mainly a collection of shared maps for the
  object types supported. The functions dispatch to the appropriate
  map based on the key and object type parameter. Cache misses are handled
  by retrieving the object from the storage adapter singleton.

  The shared dictionary cache itself does not handle concurrency at this
  outer layer. Concurrency is handled by the various instances of the
  shared multi map.
*/

template <typename T>
class Cache_element;

class Shared_dictionary_cache {
 private:
  // Collation and character set cache sizes are chosen so that they can hold
  // all collations and character sets built into the server. The spatial
  // reference system cache size is chosen to hold a reasonable number of SRSs
  // for normal server use.
  static const size_t collation_capacity = 256;
  static const size_t column_statistics_capacity = 32;
  static const size_t charset_capacity = 64;
  static const size_t event_capacity = 256;
  static const size_t spatial_reference_system_capacity = 256;
  /**
    Maximum number of DD resource group objects to be kept in
    cache. We use value of 32 which is a fairly reasonable upper limit
    of resource group configurations that may be in use.
  */
  static const size_t resource_group_capacity = 32;

  Shared_multi_map<Abstract_table> m_abstract_table_map;
  Shared_multi_map<Charset> m_charset_map;
  Shared_multi_map<Collation> m_collation_map;
  Shared_multi_map<Column_statistics> m_column_stat_map;
  Shared_multi_map<Event> m_event_map;
  Shared_multi_map<Resource_group> m_resource_group_map;
  Shared_multi_map<Routine> m_routine_map;
  Shared_multi_map<Schema> m_schema_map;
  Shared_multi_map<Spatial_reference_system> m_spatial_reference_system_map;
  Shared_multi_map<Tablespace> m_tablespace_map;

  template <typename T>
  struct Type_selector {};  // Dummy type to use for
                            // selecting map instance.

  /**
    Overloaded functions to use for selecting map instance based
    on a key type. Const and non-const variants.
  */

  Shared_multi_map<Abstract_table> *m_map(Type_selector<Abstract_table>) {
    return &m_abstract_table_map;
  }
  Shared_multi_map<Charset> *m_map(Type_selector<Charset>) {
    return &m_charset_map;
  }
  Shared_multi_map<Collation> *m_map(Type_selector<Collation>) {
    return &m_collation_map;
  }
  Shared_multi_map<Column_statistics> *m_map(Type_selector<Column_statistics>) {
    return &m_column_stat_map;
  }
  Shared_multi_map<Event> *m_map(Type_selector<Event>) { return &m_event_map; }
  Shared_multi_map<Resource_group> *m_map(Type_selector<Resource_group>) {
    return &m_resource_group_map;
  }
  Shared_multi_map<Routine> *m_map(Type_selector<Routine>) {
    return &m_routine_map;
  }
  Shared_multi_map<Schema> *m_map(Type_selector<Schema>) {
    return &m_schema_map;
  }
  Shared_multi_map<Spatial_reference_system> *m_map(
      Type_selector<Spatial_reference_system>) {
    return &m_spatial_reference_system_map;
  }
  Shared_multi_map<Tablespace> *m_map(Type_selector<Tablespace>) {
    return &m_tablespace_map;
  }

  const Shared_multi_map<Abstract_table> *m_map(
      Type_selector<Abstract_table>) const {
    return &m_abstract_table_map;
  }
  const Shared_multi_map<Charset> *m_map(Type_selector<Charset>) const {
    return &m_charset_map;
  }
  const Shared_multi_map<Collation> *m_map(Type_selector<Collation>) const {
    return &m_collation_map;
  }
  const Shared_multi_map<Column_statistics> *m_map(
      Type_selector<Column_statistics>) const {
    return &m_column_stat_map;
  }
  const Shared_multi_map<Schema> *m_map(Type_selector<Schema>) const {
    return &m_schema_map;
  }
  const Shared_multi_map<Spatial_reference_system> *m_map(
      Type_selector<Spatial_reference_system>) const {
    return &m_spatial_reference_system_map;
  }
  const Shared_multi_map<Tablespace> *m_map(Type_selector<Tablespace>) const {
    return &m_tablespace_map;
  }
  const Shared_multi_map<Resource_group> *m_map(
      Type_selector<Resource_group>) const {
    return &m_resource_group_map;
  }

  /**
    Template function to get a map instance.

    To support generic code, the map instances are available through
    template function instances. This allows looking up the
    appropriate instance based on the key type. We must use
    overloading to accomplish this (see above). Const and non-const
    variants.

    @tparam  T  Dictionary object type.

    @return  The shared map handling objects of type T.
  */

  template <typename T>
  Shared_multi_map<T> *m_map() {
    return m_map(Type_selector<T>());
  }

  template <typename T>
  const Shared_multi_map<T> *m_map() const {
    return m_map(Type_selector<T>());
  }

  Shared_dictionary_cache() = default;

 public:
  static Shared_dictionary_cache *instance();

  // Set capacity of the shared maps.
  static void init();

  // Shutdown the shared maps.
  static void shutdown();

  // Reset the shared cache. Optionally keep the core DD table meta data.
  static void reset(bool keep_dd_entities);

  // Reset the table and tablespace partitions.
  static bool reset_tables_and_tablespaces(THD *thd);

  /**
    Check if an element with the given key is available.

    @param key   Key to check for presence.

    @retval true   The key exist.
    @retval false  The key does not exist.
  */

  template <typename K, typename T>
  bool available(const K &key) {
    return m_map<T>()->available(key);
  }

  /**
    Get an element from the cache, given the key.

    The operation retrieves an element by one of its keys from the cache
    (possibly involving a cache miss, which will need the thd to handle the
    miss) and returns it through the parameter. If there is no element for
    the given key, NULL is returned. The cache owns the returned element,
    i.e., the caller must not delete it. After using the element, release()
    must be called for every element received via get(). The reference
    counter for the element is incremented if the element is retrieved from
    the shared cache.

    @tparam      K       Key type.
    @tparam      T       Dictionary object type.
    @param       thd     Thread context.
    @param       key     Key to use for looking up the object.
    @param [out] element Element pointer, if present. NULL if not present.

    @retval      false   No error.
    @retval      true    Error (from handling a cache miss).
  */

  template <typename K, typename T>
  bool get(THD *thd, const K &key, Cache_element<T> **element);

  MY_COMPILER_DIAGNOSTIC_PUSH()
  MY_COMPILER_CLANG_WORKAROUND_TPARAM_DOCBUG()
  /**
    Read an object directly from disk, given the key.

    The operation retrieves an object by one of its keys from the persistent
    dd tables. The object is returned without being added to the shared
    cache. The object returned is owned by the caller, who thus becomes
    responsible of deleting it.

    @tparam      K         Key type.
    @tparam      T         Dictionary object type.
    @param       thd       Thread context.
    @param       key       Key to use for looking up the object.
    @param       isolation Isolation level to use.
    @param [out] object    Object pointer, if present. NULL if not present.

    @retval      false   No error.
    @retval      true    Error (from reading from the DD tables).
  */
  MY_COMPILER_DIAGNOSTIC_POP()

  template <typename K, typename T>
  bool get_uncached(THD *thd, const K &key, enum_tx_isolation isolation,
                    const T **object) const;

  /**
    Add an object to the shared cache.

    The object may not be present already. The object is added to the cache,
    the use counter of its element wrapper in incremented, and the element
    pointer is returned. The user must release the object afterwards. The
    cache is the owner of the returned element and object.

    @tparam  T        Dictionary object type.
    @param   object   Object pointer to be added. May not be NULL.
    @param   element  Element pointer, if present. NULL if not present.
  */

  template <typename T>
  void put(const T *object, Cache_element<T> **element);

  /**
    Release an element used by a client.

    The element must be present and in use. If the element becomes unused,
    it is added to the free list, which is then rectified to enforce
    its capacity constraints.

    @tparam  T         Dictionary object type.
    @param   e         Element pointer.
  */

  template <typename T>
  void release(Cache_element<T> *e) {
    m_map<T>()->release(e);
  }

  /**
    Delete an element from the cache.

    This function will remove the element from the cache and delete the
    object pointed to. This means that all keys associated with the element
    will be removed from the maps, and the cache element wrapper will be
    deleted. The object may not be accessed after calling this function.

    @tparam  T         Dictionary object type.
    @param   element   Element pointer.
  */

  template <typename T>
  void drop(Cache_element<T> *element) {
    m_map<T>()->drop(element);
  }

  /**
    Delete an element corresponding to the key from the cache if exists.

    This function will find the element corresponding to the key if
    it exists. After that it will remove the element from the cache
    i.e. all maps, and delete the object pointed to. This means that
    all keys associated with the element will be removed from the maps,
    and the cache element wrapper will be deleted.

    @tparam  K         Key type.
    @tparam  T         Dictionary object type.
    @param   key       Key to be checked.
  */

  template <typename K, typename T>
  void drop_if_present(const K &key) {
    m_map<T>()->drop_if_present(key);
  }

  /**
    Replace the object and re-create the keys for an element.

    The operation removes the current keys from the internal maps in the
    cache, assigns the new object to the element, generates new keys based
    on the new object, and inserts the new keys into the internal maps in the
    cache. The old object is deleted.

    @tparam  T         Dictionary object type.
    @param   element   Element pointer.
    @param   object    New object to replace the old one.
  */

  template <typename T>
  void replace(Cache_element<T> *element, const T *object) {
    m_map<T>()->replace(element, object);
  }

  /**
    Debug dump of a shared cache partition to stderr.

    @tparam  T         Dictionary object type.
  */

  template <typename T>
  void dump() const {
#ifndef NDEBUG
    fprintf(stderr, "================================\n");
    fprintf(stderr, "Shared dictionary cache\n");
    m_map<T>()->dump();
    fprintf(stderr, "================================\n");
#endif
  }
};

}  // namespace cache
}  // namespace dd

#endif  // DD_CACHE__SHARED_DICTIONARY_CACHE_INCLUDED