Drake
Drake C++ Documentation
CacheEntryValue Class Reference

Detailed Description

(Advanced) This is the representation in the Context for the value of one of a System's CacheEntry objects.

Most users will not use this class directly – System and CacheEntry provide the most common APIs, and Context provides additional useful methods.

See also
System, CacheEntry, Context for user-facing APIs.

A CacheEntryValue consists of a single type-erased value, a serial number, an out_of_date flag, and a DependencyTracker ticket. Details:

  • "Out of date" means that some prerequisite of this cache entry's computation has been changed in the current Context since the stored value was last computed, and thus must be recomputed prior to use. On the other hand, if the entry is not out of date, then it is "up to date" meaning that if you were to recompute it using the current Context values you would get the identical result (so don't bother!).
  • The "serial number" is an integer that is incremented whenever the value is modified, or made available for mutable access. You can use it to recognize that you are looking at the same value as you saw at some earlier time. It is also useful for performance studies since it is a count of how many times this value was recomputed. Note that marking the value "out of date" is not a modification; that does not change the serial number. The serial number is maintained internally and cannot be user-modified.
  • The DependencyTicket ("ticket") stored here identifies the DependencyTracker ("tracker") associated with this cache entry. The tracker maintains lists of all upstream prerequisites and downstream dependents of the value stored here, and also has a pointer to this CacheEntryValue that it uses for invalidation. Upstream modifications cause the tracker to set the out_of_date flag here, and mark all downstream dependents out of date also. The tracker lives in the same subcontext that owns the Cache that owns this CacheEntryValue.

We sometimes use the terms "invalid" and "invalidate" as synonyms for "out of date" and "mark out of date".

For debugging purposes, caching may be disabled for an entire Context or for particular cache entry values. This is independent of the out_of_date flag described above, which is still expected to be operational when caching is disabled. However, when caching is disabled the Eval() methods will recompute the contained value even if it is not marked out of date. That should have no effect other than to slow computation; if results change, something is wrong. There could be a problem with the specification of dependencies, a bug in user code such as improper retention of a stale reference, or a bug in the caching system.

#include <drake/systems/framework/cache.h>

Public Member Functions

 ~CacheEntryValue ()=default
 Destructs the cache value, but does not issue any notifications to downstream dependents. More...
 
void SetInitialValue (std::unique_ptr< AbstractValue > init_value)
 Defines the concrete value type by providing an initial AbstractValue object containing an object of the appropriate concrete type. More...
 
Does not allow move or assignment; copy constructor is private.
 CacheEntryValue (CacheEntryValue &&)=delete
 
void operator= (const CacheEntryValue &)=delete
 
void operator= (CacheEntryValue &&)=delete
 
Safe methods for value access and modification

These are the recommended methods for accessing and modifying the cache entry value.

They unconditionally check all the relevant preconditions to catch usage errors. In particular, access is prevented when the value is out of date, and modification is permitted only when (a) the value is already out of date (typically because a prerequisite changed), or (b) caching is disabled for this entry. For performance-sensitive code, you may need to use the parallel set of methods below that check preconditions only in Debug builds, but be sure you are gaining significant performance before giving up on Release-build validation.

const AbstractValueGetAbstractValueOrThrow () const
 Returns a const reference to the contained abstract value, which must not be out of date with respect to any of its prerequisites. More...
 
template<typename V >
const V & GetValueOrThrow () const
 Returns a const reference to the contained value of known type V. More...
 
template<typename V >
void SetValueOrThrow (const V &new_value)
 Assigns a new value to a cache entry and marks it up to date. More...
 
AbstractValueGetMutableAbstractValueOrThrow ()
 (Advanced) Returns a mutable reference to the contained value after incrementing the serial number. More...
 
template<typename V >
V & GetMutableValueOrThrow ()
 (Advanced) Convenience method that returns a mutable reference to the contained value downcast to its known concrete type. More...
 
const AbstractValuePeekAbstractValueOrThrow () const
 (Advanced) Returns a reference to the contained value without checking whether the value is out of date. More...
 
template<typename V >
const V & PeekValueOrThrow () const
 (Advanced) Convenience method that provides access to the contained value downcast to its known concrete type, without checking whether the value is out of date. More...
 
Fast-but-dangerous methods for highest performance

These methods check for errors only in Debug builds, but plunge blindly onward in Release builds so that they will execute as fast as possible.

You should use them only in places where performance requirements preclude Release-build checks. The best way to determine that is to time the code using the always-checked methods vs. these ones. If that's not practical, use these only when the containing code is in a very high-rate loop, and is a substantial fraction of the total code being executed there.

const AbstractValueget_abstract_value () const
 Returns a const reference to the contained abstract value, which must not be out of date with respect to any of its prerequisites. More...
 
template<typename V >
const V & get_value () const
 Returns a const reference to the contained value of known type V. More...
 
template<typename V >
void set_value (const V &new_value)
 Assigns a new value to a cache entry and marks it up to date. More...
 
void swap_value (std::unique_ptr< AbstractValue > *other_value)
 (Advanced) Swaps ownership of the stored value object with the given one. More...
 
Dependency management

Methods here deal with management of the out_of_date flag and determining whether the contained value must be recomputed before use.

bool is_out_of_date () const
 Returns true if the current value is out of date with respect to any of its prerequisites. More...
 
bool needs_recomputation () const
 Returns true if either (a) the value is out of date, or (b) caching is disabled for this entry. More...
 
void mark_up_to_date ()
 (Advanced) Marks the cache entry value as up to date with respect to its prerequisites, with no other effects. More...
 
void mark_out_of_date ()
 (Advanced) Marks the cache entry value as out-of-date with respect to its prerequisites, with no other effects. More...
 
int64_t serial_number () const
 Returns the serial number of the contained value. More...
 
Bookkeeping methods

Miscellaneous methods of limited use to most users.

const std::string & description () const
 Returns the human-readable description for this CacheEntryValue. More...
 
std::string GetPathDescription () const
 Returns the description, preceded by the full pathname of the subsystem associated with the owning subcontext. More...
 
bool has_value () const
 Returns true if this CacheEntryValue currently contains a value object at all, regardless of whether it is up to date. More...
 
CacheIndex cache_index () const
 Returns the CacheIndex used to locate this CacheEntryValue within its containing subcontext. More...
 
DependencyTicket ticket () const
 Returns the DependencyTicket used to locate the DependencyTracker that manages dependencies for this CacheEntryValue. More...
 
Testing/debugging utilities

These are used for disabling and re-enabling caching to determine correctness and effectiveness of caching.

Usually all cache entries are disabled or enabled together using higher-level methods that invoke these ones, but you can disable just a single entry if necessary.

void ThrowIfBadCacheEntryValue (const internal::ContextMessageInterface *owning_subcontext=nullptr) const
 Throws an std::exception if there is something clearly wrong with this CacheEntryValue object. More...
 
void disable_caching ()
 (Advanced) Disables caching for just this cache entry value. More...
 
void enable_caching ()
 (Advanced) Enables caching for this cache entry value if it was previously disabled. More...
 
bool is_cache_entry_disabled () const
 (Advanced) Returns true if caching is disabled for this cache entry. More...
 

Friends

class Cache
 
class copyable_unique_ptr< CacheEntryValue >
 

Constructor & Destructor Documentation

◆ CacheEntryValue()

◆ ~CacheEntryValue()

~CacheEntryValue ( )
default

Destructs the cache value, but does not issue any notifications to downstream dependents.

Member Function Documentation

◆ cache_index()

CacheIndex cache_index ( ) const

Returns the CacheIndex used to locate this CacheEntryValue within its containing subcontext.

◆ description()

const std::string& description ( ) const

Returns the human-readable description for this CacheEntryValue.

◆ disable_caching()

void disable_caching ( )

(Advanced) Disables caching for just this cache entry value.

When disabled, the corresponding entry's Eval() method will unconditionally invoke Calc() to recompute the value, regardless of the setting of the out_of_date flag. The disabled flag is independent of the out_of_date flag, which will continue to be managed even if caching is disabled. It is also independent of whether the cache is frozen, although in that case any cache access will fail since recomputation is not permitted in a frozen cache. Once unfrozen, caching will remain disabled unless enable_caching() is called.

◆ enable_caching()

void enable_caching ( )

(Advanced) Enables caching for this cache entry value if it was previously disabled.

When enabled (the default condition) the corresponding entry's Eval() method will check the out_of_date flag and invoke Calc() only if the entry is marked out of date. It is also independent of whether the cache is frozen; in that case caching will be enabled once the cache is unfrozen.

◆ get_abstract_value()

const AbstractValue& get_abstract_value ( ) const

Returns a const reference to the contained abstract value, which must not be out of date with respect to any of its prerequisites.

It is an error to call this if there is no stored value, or it is out of date. Because this is used in performance-critical contexts, these requirements will be checked only in Debug builds. If you are not in a performance-critical situation (and you probably are not!), use GetAbstractValueOrThrow() instead.

◆ get_value()

const V& get_value ( ) const

Returns a const reference to the contained value of known type V.

It is an error to call this if there is no stored value, or the value is out of date, or the value doesn't actually have type V. Because this is expected to be used in performance-critical, inner-loop circumstances, these requirements will be checked only in Debug builds. If you are not in a performance-critical situation (and you probably are not!), use GetValueOrThrow<V>() instead.

Template Parameters
VThe known actual value type.

◆ GetAbstractValueOrThrow()

const AbstractValue& GetAbstractValueOrThrow ( ) const

Returns a const reference to the contained abstract value, which must not be out of date with respect to any of its prerequisites.

It is an error to call this if there is no stored value object, or if the value is out of date.

Exceptions
std::exceptionif there is no value or it is out of date.
See also
get_abstract_value()

◆ GetMutableAbstractValueOrThrow()

AbstractValue& GetMutableAbstractValueOrThrow ( )

(Advanced) Returns a mutable reference to the contained value after incrementing the serial number.

This is for the purpose of performing an update or extended computation in place. If possible, use the safer and more straightforward method SetValueOrThrow() rather than this method. Mutable access is only permitted if the value is already marked out of date (meaning that all downstream dependents have already been notified). It is an error to call this if there is no stored value, or it is already up to date. Since this is intended for relatively expensive computations, these preconditions are checked even in Release builds. If you have a small, fast computation to perform, use set_value() instead. If your computation completes successfully, you must mark the entry up to date yourself using mark_up_to_date() if you want anyone to be able to use the new value.

Exceptions
std::exceptionif there is no value, or if the value is already up to date.
std::exceptionif the cache is frozen.
See also
SetValueOrThrow(), set_value(), mark_up_to_date()

◆ GetMutableValueOrThrow()

V& GetMutableValueOrThrow ( )

(Advanced) Convenience method that returns a mutable reference to the contained value downcast to its known concrete type.

Throws an exception if the contained value does not have the indicated concrete type. Note that you must call mark_up_to_date() after modifying the value through the returned reference. See GetMutableAbstractValueOrThrow() above for more information.

Exceptions
std::exceptionif there is no value, or if the value is already up to date, of it doesn't actually have type V.
std::exceptionif the cache is frozen.
See also
SetValueOrThrow(), set_value(), mark_up_to_date()
Template Parameters
VThe known actual value type.

◆ GetPathDescription()

std::string GetPathDescription ( ) const

Returns the description, preceded by the full pathname of the subsystem associated with the owning subcontext.

◆ GetValueOrThrow()

const V& GetValueOrThrow ( ) const

Returns a const reference to the contained value of known type V.

It is an error to call this if there is no stored value, or the value is out of date, or the value doesn't actually have type V.

Exceptions
std::exceptionif there is no stored value, or if it is out of date, or it doesn't actually have type V.
See also
get_value()

◆ has_value()

bool has_value ( ) const

Returns true if this CacheEntryValue currently contains a value object at all, regardless of whether it is up to date.

There will be no value object after default construction, prior to SetInitialValue().

◆ is_cache_entry_disabled()

bool is_cache_entry_disabled ( ) const

(Advanced) Returns true if caching is disabled for this cache entry.

This is independent of the out_of_date flag, and independent of whether the cache is currently frozen.

◆ is_out_of_date()

bool is_out_of_date ( ) const

Returns true if the current value is out of date with respect to any of its prerequisites.

This refers only to the out_of_date flag and is independent of whether caching is enabled or disabled. Don't call this if there is no value here; use has_value() if you aren't sure.

See also
needs_recomputation()

◆ mark_out_of_date()

void mark_out_of_date ( )

(Advanced) Marks the cache entry value as out-of-date with respect to its prerequisites, with no other effects.

In particular, it does not modify the value, does not change the serial number, and does not notify downstream dependents. You should not call this method unless you know that dependent notification has already been taken care of. There are no error conditions; even an empty cache entry can be marked out of date.

Note
Operation of this method is unaffected by whether the cache is frozen. If you call it in that case the corresponding value will become inaccessible since it would require recomputation.

◆ mark_up_to_date()

void mark_up_to_date ( )

(Advanced) Marks the cache entry value as up to date with respect to its prerequisites, with no other effects.

That is, this method clears the out_of_date flag. In particular, this method does not modify the value, does not change the serial number, and does not notify downstream dependents of anything. This is a very dangerous method since it enables access to the value but can't independently determine whether it is really up to date. You should not call it unless you really know what you're doing, or have a death wish. Do not call this method if there is no stored value object; use has_value() if you aren't sure. This is intended to be very fast so doesn't check for a value object except in Debug builds.

Note
Operation of this method is unaffected by whether the cache is frozen. It may be useful for testing and debugging in that case but you should be very careful if you use it – once you call this the value will be accessible in the frozen cache, regardless of whether it is any good!

◆ needs_recomputation()

bool needs_recomputation ( ) const

Returns true if either (a) the value is out of date, or (b) caching is disabled for this entry.

This is a very fast inline method intended to be called every time a cache value is obtained with Eval(). This is equivalent to is_out_of_date() || is_entry_disabled() but faster. Don't call this if there is no value here; use has_value() if you aren't sure. Note that if this returns true while the cache is frozen, any attempt to access the value will fail since recomputation is forbidden in that case. However, operation of this method is unaffected by whether the cache is frozen.

◆ operator=() [1/2]

void operator= ( const CacheEntryValue )
delete

◆ operator=() [2/2]

void operator= ( CacheEntryValue &&  )
delete

◆ PeekAbstractValueOrThrow()

const AbstractValue& PeekAbstractValueOrThrow ( ) const

(Advanced) Returns a reference to the contained value without checking whether the value is out of date.

This can be used to check type and size information but should not be used to look at the value unless you really know what you're doing.

Exceptions
std::exceptionif there is no contained value.

◆ PeekValueOrThrow()

const V& PeekValueOrThrow ( ) const

(Advanced) Convenience method that provides access to the contained value downcast to its known concrete type, without checking whether the value is out of date.

This can be used to check type and size information but should not be used to look at the value unless you really know what you're doing.

Exceptions
std::exceptionif there is no contained value, or if the contained value does not actually have type V.
Template Parameters
VThe known actual value type.

◆ serial_number()

int64_t serial_number ( ) const

Returns the serial number of the contained value.

This counts up every time the contained value changes, or whenever mutable access is granted.

◆ set_value()

void set_value ( const V &  new_value)

Assigns a new value to a cache entry and marks it up to date.

The cache value must already have a value object of type V to which the new value is assigned, and that value must not already be up to date. The new value is assumed to be up to date with its prerequisites, so the out_of_date flag is cleared. No out-of-date notifications are issued by this method; we assume downstream dependents were marked out of date at the time this value went out of date. The serial number is incremented. If you are not in a performance-critical situation (and you probably are not!), use SetValueOrThrow<V>() instead.

Exceptions
std::exceptionif the cache is frozen.
Template Parameters
VThe known actual value type.

◆ SetInitialValue()

void SetInitialValue ( std::unique_ptr< AbstractValue init_value)

Defines the concrete value type by providing an initial AbstractValue object containing an object of the appropriate concrete type.

This value is marked out of date. It is an error to call this if there is already a value here; use has_value() if you want to check first. Also, the given initial value may not be null. The serial number is set to 1. No out-of-date notifications are sent to downstream dependents. Operation of this initialization method is not affected by whether the cache is currently frozen. However, the corresponding value won't be accessible while the cache remains frozen (since it is out of date).

Exceptions
std::exceptionif the given value is null or if there is already a value, or if this CacheEntryValue is malformed in some detectable way.

◆ SetValueOrThrow()

void SetValueOrThrow ( const V &  new_value)

Assigns a new value to a cache entry and marks it up to date.

The cache entry must already contain a value object of type V to which the new value is assigned, and that value must currently be marked out of date. The supplied new value must have been calculated using the current values in the owning Context, and we assume that here although this method cannot check that assumption. Consequently, this method clears the out_of_date flag. No out-of-date notifications are issued by this method; we assume downstream dependents were marked out of date at the time this value went out of date. The serial number is incremented.

This method is the safest and most convenient way to assign a new value. However it requires that a new value be computed and then copied into the cache entry, which is fine for small types V but may be too expensive for large ones. You can alternatively obtain a mutable reference to the value already contained in the cache entry and update it in place via GetMutableValueOrThrow().

Exceptions
std::exceptionif there is no value, or the value is already up to date, of it doesn't actually have type V.
std::exceptionif the cache is frozen.
See also
set_value(), GetMutableValueOrThrow()

◆ swap_value()

void swap_value ( std::unique_ptr< AbstractValue > *  other_value)

(Advanced) Swaps ownership of the stored value object with the given one.

The value is marked out of date and the serial number is incremented. This is useful for discrete updates of abstract state variables that contain large objects. Both values must be non-null and of the same concrete type but we won't check for errors except in Debug builds.

Exceptions
std::exceptionif the cache is frozen.

◆ ThrowIfBadCacheEntryValue()

void ThrowIfBadCacheEntryValue ( const internal::ContextMessageInterface *  owning_subcontext = nullptr) const

Throws an std::exception if there is something clearly wrong with this CacheEntryValue object.

If the owning subcontext is known, provide a pointer to it here and we'll check that this cache entry agrees. In addition we check for other internal inconsistencies.

Exceptions
std::exceptionfor anything that goes wrong, with an appropriate explanatory message.

◆ ticket()

DependencyTicket ticket ( ) const

Returns the DependencyTicket used to locate the DependencyTracker that manages dependencies for this CacheEntryValue.

The ticket refers to a tracker that is owned by the same subcontext that owns this CacheEntryValue.

Friends And Related Function Documentation

◆ Cache

friend class Cache
friend

◆ copyable_unique_ptr< CacheEntryValue >

friend class copyable_unique_ptr< CacheEntryValue >
friend

The documentation for this class was generated from the following file: