MySQL 8.0.31
Source Code Documentation
cache_element.h
Go to the documentation of this file.
1/* Copyright (c) 2015, 2022, 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 DD_CACHE__CACHE_ELEMENT_INCLUDED
24#define DD_CACHE__CACHE_ELEMENT_INCLUDED
25
26#include <assert.h>
27
28#include "sql/dd/impl/raw/object_keys.h" // Primary_id_key
29#include "sql/dd/string_type.h" // dd::String_type
30
31namespace dd_cache_unittest {
32class CacheTestHelper;
33}
34
35namespace dd {
36namespace cache {
37
38// Forward declare Shared_multi_map for friend directive.
39template <typename T>
40class Shared_multi_map;
41
42// Forward declare Storage_adapter for friend directive,
43// needed for unit tests.
44class Storage_adapter;
45
46/**
47 Implementation of a cache element.
48
49 This template class implements a wrapper to support caching of
50 arbitrary objects. The wrapper provides support for reference counting,
51 but does not make any assumptions regarding the semantics of this
52 functionality. The enforcement of such assumptions must be built into
53 the layer using the cache element implementation.
54
55 The cache element stores copies of the keys that are used for looking
56 up the object in the cache. This is needed to support fast reverse lookup
57 of keys, given the object instance, e.g. to enable removing old keys when
58 new keys must be created. The keys are stored in pre-allocated memory.
59
60 @note The usage of the reference counter is not implemented by means of
61 atomic operations. Locking at an outer level takes care of race
62 conditions.
63
64 @tparam T Dictionary object type being wrapped.
65*/
66
67template <typename T>
69 friend class Storage_adapter; // Unit test access.
70 friend class dd_cache_unittest::CacheTestHelper; // Unit test access.
71 friend class Shared_multi_map<T>; // Access to changing data.
72 friend class Dictionary_client; // Access to changing data.
73
74 private:
75 const T *m_object; // Pointer to the actual object.
76 uint m_ref_counter; // Number of concurrent object usages.
77
78 /**
79 Helper class to represent a key instance. We also need to
80 represent whether the instance is NULL.
81
82 @tparam K Key type.
83 */
84
85 template <typename K>
87 public:
88 bool is_null;
89 K key;
90 Key_wrapper() : is_null(true), key() {}
91 };
92
93 Key_wrapper<typename T::Id_key> m_id_key; // The id key for the object.
94 Key_wrapper<typename T::Name_key> m_name_key; // The name key for the object.
95 Key_wrapper<typename T::Aux_key> m_aux_key; // The aux key for the object.
96
97 // Helper functions using overloading to get keys using a template.
98 template <typename K>
99 struct Type_selector {};
100
101 const T *const *get_key(Type_selector<const T *>) const {
102 return m_object ? &m_object : nullptr;
103 }
104
105 const typename T::Id_key *get_key(Type_selector<typename T::Id_key>) const {
106 return id_key();
107 }
108
109 const typename T::Name_key *get_key(
111 return name_key();
112 }
113
114 const typename T::Aux_key *get_key(Type_selector<typename T::Aux_key>) const {
115 return aux_key();
116 }
117
118 // Delete all keys.
119 void delete_keys() {
120 m_id_key.is_null = true;
121 m_name_key.is_null = true;
122 m_aux_key.is_null = true;
123 }
124
125 // Increment the reference counter associated with the object.
126 void use() { m_ref_counter++; }
127
128 // Let the cache element point to another object.
129 void set_object(const T *replacement_object) {
130 m_object = replacement_object;
131 }
132
133 // Update the keys based on the object pointed to.
135 assert(m_object);
136 m_id_key.is_null = m_object->update_id_key(&m_id_key.key);
137 m_name_key.is_null = m_object->update_name_key(&m_name_key.key);
138 m_aux_key.is_null = m_object->update_aux_key(&m_aux_key.key);
139 }
140
141 public:
142 // Initialize an instance to having NULL pointers and 0 count.
144 : m_object(nullptr),
145 m_ref_counter(0),
146 m_id_key(),
147 m_name_key(),
148 m_aux_key() {} /* purecov: tested */
149
150 // Note that the object being pointed to is not deleted implicitly.
152
153 // Initialize an existing instance.
154 void init() {
155 m_object = nullptr;
156 m_ref_counter = 0;
157 delete_keys();
158 }
159
160 // Decrement the reference counter associated with the object.
161 void release() {
162 assert(m_ref_counter > 0);
164 }
165
166 // Return current number of usages of the object.
167 uint usage() const { return m_ref_counter; }
168
169 // Return the object pointer.
170 const T *object() const { return m_object; }
171
172 // Get the id key.
173 const typename T::Id_key *id_key() const {
174 return m_id_key.is_null ? nullptr : &m_id_key.key;
175 }
176
177 // Get the name key.
178 const typename T::Name_key *name_key() const {
179 return m_name_key.is_null ? nullptr : &m_name_key.key;
180 }
181
182 // Get the aux key.
183 const typename T::Aux_key *aux_key() const {
184 return m_aux_key.is_null ? nullptr : &m_aux_key.key;
185 }
186
187 /**
188 Template function to get a pointer to a key based on the type.
189
190 @tparam K Key type.
191 */
192
193 template <typename K>
194 const K *get_key() const {
195 return get_key(Type_selector<K>());
196 }
197
198 // Debug dump of the element to stderr.
199 /* purecov: begin inspected */
200 void dump(const String_type &prefix [[maybe_unused]] = " ") const {
201#ifndef NDEBUG
202 fprintf(stderr, "%sobj: %p, id: %llu, cnt: %u", prefix.c_str(), m_object,
203 m_object ? m_object->id() : 0, m_ref_counter);
204 fprintf(stderr, ", id_k: %s",
205 m_id_key.is_null ? "NULL" : m_id_key.key.str().c_str());
206 fprintf(stderr, ", name_k: %s",
207 m_name_key.is_null ? "NULL" : m_name_key.key.str().c_str());
208 fprintf(stderr, ", aux_k: %s\n",
209 m_aux_key.is_null ? "NULL" : m_aux_key.key.str().c_str());
210#endif
211 }
212 /* purecov: end */
213};
214
215} // namespace cache
216} // namespace dd
217
218#endif // DD_CACHE__CACHE_ELEMENT_INCLUDED
Helper class to represent a key instance.
Definition: cache_element.h:86
K key
Definition: cache_element.h:89
bool is_null
Definition: cache_element.h:88
Key_wrapper()
Definition: cache_element.h:90
Implementation of a dictionary client.
Definition: cache_element.h:68
void delete_keys()
Definition: cache_element.h:119
const T::Aux_key * get_key(Type_selector< typename T::Aux_key >) const
Definition: cache_element.h:114
const T::Name_key * name_key() const
Definition: cache_element.h:178
void recreate_keys()
Definition: cache_element.h:134
void use()
Definition: cache_element.h:126
uint usage() const
Definition: cache_element.h:167
void dump(const String_type &prefix=" ") const
Definition: cache_element.h:200
const T::Name_key * get_key(Type_selector< typename T::Name_key >) const
Definition: cache_element.h:109
const T * object() const
Definition: cache_element.h:170
friend class dd_cache_unittest::CacheTestHelper
Definition: cache_element.h:70
void set_object(const T *replacement_object)
Definition: cache_element.h:129
const T::Id_key * id_key() const
Definition: cache_element.h:173
const T * m_object
Definition: cache_element.h:75
~Cache_element()
Definition: cache_element.h:151
Key_wrapper< typename T::Name_key > m_name_key
Definition: cache_element.h:94
Key_wrapper< typename T::Aux_key > m_aux_key
Definition: cache_element.h:95
void init()
Definition: cache_element.h:154
const T *const * get_key(Type_selector< const T * >) const
Definition: cache_element.h:101
void release()
Definition: cache_element.h:161
Key_wrapper< typename T::Id_key > m_id_key
Definition: cache_element.h:93
const T::Id_key * get_key(Type_selector< typename T::Id_key >) const
Definition: cache_element.h:105
const T::Aux_key * aux_key() const
Definition: cache_element.h:183
Cache_element()
Definition: cache_element.h:143
const K * get_key() const
Template function to get a pointer to a key based on the type.
Definition: cache_element.h:194
uint m_ref_counter
Definition: cache_element.h:76
Definition: dictionary_client.h:148
Implementation of a shared set of maps for a given object type.
Definition: shared_multi_map.h:117
Handling of access to persistent storage.
Definition: storage_adapter.h:59
Fido Client Authentication nullptr
Definition: fido_client_plugin.cc:221
Definition: dictionary_client.h:1273
The version of the current data dictionary table definitions.
Definition: dictionary_client.h:42
Char_string_template< String_type_allocator > String_type
Definition: string_type.h:50
Definition: cache_element.h:99
unsigned int uint
Definition: uca-dump.cc:29