Contexts

It is often necessary for an application to associate certain information with a given registry key. To assist developers in doing so in a convenient and performant manner, the CBRegistry class provides context parameters in a number of events.

A context carries an application-defined value that identifies or points to some application-defined data, and registry key has a separate context associated with it. The CBRegistry class treats context values as opaque; it stores the context values passed to it by the application, and ensures that the correct values are exposed again whenever some event fires for a particular registry key; but does not otherwise attempt to use said values in any way.

Context Lifetimes

Contexts in CBRegistry are available in all events that correspond to registry key operations. They are created before the BeforeCreateKey or BeforeOpenKey event fires, and are deleted after the AfterCloseKey event fires (or, more accurately, after the CleanupKeyContext event fires).

Context Use-Cases

Contexts are most helpful when used to store information associated with a registry key that can be used to speed up later events. For example, the only time the CBRegistry class exposes the name of a registry key is during the BeforeCreateKey and BeforeOpenKey events. Applications that wish to use the key name in later events can store it in the key context and then access it in the desired events later. A similar strategy can also be applied for events related to registry key values.

More generally, applications are free to obtain and store whatever information they wish using contexts, so long as their event handlers comply with the restrictions described by the Recursive Calls topic.

Using Contexts

In Java, there is no completely safe way to store object references in contexts either directly or indirectly, which is why all context parameters are long-typed. To emulate such capabilities, the following approach is recommended:

  1. Create a global ConcurrentHashMap instance for the application (i.e., a singleton), with keys of type long and values of whatever type is desired.
  2. When the application needs to create a context object in an event handler, a "key" can be created using the hash of the full file/directory name (including path), potentially mixed with additional information.
    • For file contexts, a hash of the full file/directory name is sufficiently unique since the context is exposed in all events pertaining to that file/directory.
    • For handle and enumeration contexts, additional information must be mixed in since multiple handle and/or enumeration contexts may be present at once for any given file/directory.
  3. Using the created key, add the object to the ConcurrentHashMap. (Using the ConcurrentHashMap.putIfAbsent() method to do this is highly recommended since it will, atomically, check to see if the given key is already in use first.)
  4. Set the Context parameter to the key used in the previous step.
  5. To access the object in a later event, use the key stored by the context to retrieve the object from the ConcurrentHashMap.

Notes:

  • ConcurrentHashMap is recommended because it's the most performant thread-safe data structure available in JDK 1.5+. Applications are free to use some other data structure instead, but must take care to enforce proper thread synchronization when accessing it since events are always fired using worker threads. Please refer to the Threading and Concurrency topic for more information.
  • In 32-bit applications, contexts are stored in 32-bit variables internally, thus the higher 32 bits of 64-bit values are lost.

Copyright (c) 2022 Callback Technologies, Inc. - All rights reserved.
CBFS Filter 2020 Java Edition - Version 20.0 [Build 8317]