Handling dynamic referencesAdded by IBM on October 10, 2012 | Version 1 (Original)
|A dynamic reference is a compute that includes the use of the arrow operator to obtain a value by dereferencing other values in the form.
Dynamic references imply changes to the dependency lists during run-time. A number of enhancements are required to solve this problem efficiently.
The dependency list of each form node will be segregated into normal dependencies and dereference dependencies. The form node's UsedToDeref flag will be set if and only if its dependency list contains dereference dependencies. After changing the literal value of a form node whose UsedToDeref flag is set, certain dependencies will need to be re-evaluated (described below).
For each form node f containing a compute, we store a ReferenceList containing all form nodes referred to within the compute. Again, the list will be segregated into normal and dereference references. All subreferences in a dynamic reference except for the rightmost reference are classified as dereference dependencies. For example, in a compute containing popup.value->value, if the popup's value is "cell1", then the literal of popup.value is dereferenced, but cell1.value is not. This distinction is important because a change to popup.value will cause dependency changes whereas changing cell1.value will not.
Actually, the reference list of each compute must already be built as part of setting up the dependency lists. The reference lists are required since, for each form node FP in f.ReferenceList, we must add f to FP.DependencyList. Now we are simply deciding to retain the list for use in solving problems introduced by dynamic references. So, while building dependency lists, if FP is classified as a dereference in f.ReferenceList, then f will be classified added a dereference dependency in FP.DependencyList.
The ProcessDependencyChanges() function mentioned in Figure 1 can then rebuild the dependency lists efficiently. When processing a stack entry FP, if the UsedToDeref flag is set, then some dependency lists may need to be changed. A form node f is considered to be in the 'dereference' portion of FP.DependencyList. Begin by creating a new reference list for f. Any form node FP in f.ReferenceList but not in the new reference list implies the removal of the dependency entry f from FP.DependencyList. Any form node FP not in f. ReferenceList but in the new reference list implies the addition of the dependency entry f to FP.DependencyList. Finally, the new reference list is assigned to f.ReferenceList.
Note that most of the dependency changes involve the addition and deletion of 'normal' references and dependencies. For example, given a form node f with a compute of popup.value->value, if popup.value were to change from "cell1" to "cell2", then the 'normal' entry of "cell1" in the
Note: f.ReferenceList would be deleted, and a 'normal' entry of "cell2" would be added. Furthermore, the normal dependency on f would be removed from in cell1.DependencyList and added to cell2.DependencyList. It is possible that reference list and dependency list entries of type 'dereference' can also be modified. An example would be a double dereference; in other words, the change of x.value in a form containing the compute x.value->value->value. Thus, an entry f in FP.DependencyList is a dereference if changing node FP implies the need to rebuild f.ReferenceList (which in turn implies changes to other dependency lists, possibly including FP.DependencyList).
The statements above assert that the algorithm will only rebuild the references lists of nodes marked as 'dereference' dependencies in FP.DependencyList. Due to the high cost of calling UFLDereference(), the algorithm should not rebuild reference list entries that result from static references. Static reference nodes are distinguished from dynamic reference nodes in the compute tree. Note that the leftmost subreference of a dynamic reference is also static, so it will also not be recomputed. Instead, the value in the reference cache will be used (see section Reference caching).