Hashing
All values in a dependency graph must provide a hash (a unique identifier) for their state, or indicate they can't be hashed. This is used to determine if whether a value has changed since the last time it was observed.
There are three ways to define a value's hashing behaviour:
1. Default: Requires the type to implement the Hash trait.
// This type implements `Hash`, therefore it can use the default behaviour.
#[derive(Value, Hash)]
struct DefaultBehaviour {
data: i32,
}
2. Custom Hash: Annotate a field with the #[depends(hash)]
attribute to manually manage the hashing behaviour.
// This node manually manages its hash value.
#[derive(Value)]
struct CustomHashStruct {
// You could increment a counter here, for example.
#[depends(hash)]
hash_value: usize,
// ... other fields go here.
}
3. Unhashable: Mark values that can't be hashed with the #[depends(unhashable)]
attribute. This type will always
appear dirty to any dependents, causing them to always recalculate their own state.
// This node will _always_ be considered dirty to its dependents.
#[derive(Value)]
#[depends(unhashable)]
struct UnhashableStruct {
// ... your fields go here.
}
It's unlikely you'll need to use the
unhashable
attribute and this can greatly reduce the efficiency of computations. Most nodes can use a custom hash field instead.