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