template<typename T>
class dd::cache::Cache_element< T >
Implementation of a dictionary client.
Shared dictionary cache containing several maps.
Implementation of a cache element.
The dictionary client provides a unified interface to accessing dictionary objects. The client is a member of the THD, and is typically used in server code to access the dictionary. When we refer to "the user" below, we mean the server code using the dictionary client.
The main task of the client is to access a shared cache to retrieve dictionary objects. The shared cache, in its turn, will access the dictionary tables if there is a cache miss.
To support cache eviction, the shared cache must keep track of which clients that have acquired an object. When a client acquires an object from the shared cache for the first time, it is added to a client local object registry. Further acquisition of the same object from the client will get the object from the client's registry. Thus, the usage tracking in the shared cache only keep track of the number of clients currently using the object, and hence, there must be an operation that complements acquisition, to inform the shared cache that the object is not used anymore. This complementing operation is called releasing the object.
To manage releasing objects, the Auto_releaser class provides some support. When an auto releaser is instantiated, it will keep track of the objects that are acquired from the shared cache in its lifetime. Auto releasers may be nested or stacked, and the current releaser is the one at the top of the stack. The auto releaser stack is associated with a dictionary client instance. When the auto releaser goes out of scope, it will release all objects that have been acquired from the shared cache in its lifetime. Objects retrieved earlier than that will be automatically released by a releaser further down the auto releaser stack. For more coarse grained control, there is a release method that will release all objects acquired by the client.
In addition to the auto releasers, the client has an object registry. The registry holds pointers to all currently acquired objects. Thus, the object registry is the union of the registers in the stack of auto releasers. The client's object registry is used for looking up objects, while the registers in the auto releasers are used for releasing objects.
The client also has a second registry of objects with uncommitted changes. These are objects acquired by acquire_for_modification() or registered with register_uncommitted_object(). These objects are only present in the local registry and not in the shared cache. Once registered, the objects can also be retrieved with normal acquire(). This means that a given client has a view which includes uncommitted changes made using the same client, while other clients do not see these changes.
- Note
- We must handle situations where an object is actually acquired from the shared cache, while the dynamic cast to a subtype fails. We use the auto release mechanism to achieve that.
-
When a dictionary client method returns true, indicating that an error has occurred, the error has been reported, either by the client itself, or by the dictionary subsystem.
This template class implements a wrapper to support caching of arbitrary objects. The wrapper provides support for reference counting, but does not make any assumptions regarding the semantics of this functionality. The enforcement of such assumptions must be built into the layer using the cache element implementation.
The cache element stores copies of the keys that are used for looking up the object in the cache. This is needed to support fast reverse lookup of keys, given the object instance, e.g. to enable removing old keys when new keys must be created. The keys are stored in pre-allocated memory.
- Note
- The usage of the reference counter is not implemented by means of atomic operations. Locking at an outer level takes care of race conditions.
- Template Parameters
-
T | Dictionary object type being wrapped. |
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.