0

Edit: I am not looking for an implementation but just for some keywords to search and methodologies to get me started.

I am struggling with generating a dependency tree where child nodes are updated by an external process and the requirement is to update all parent nodes of updated child nodes.

Example: Imagine a tree such as this: O [parent], O(l) [left child], O(r) [right child], O(ll), O(lr), O(rl), and O(rr). O(ll), O(lr), O(rl), and O(rr) have reference to a data collection that is updated at random intervals).

I want to implement a pull process, where at certain intervals a process checks whether O is updated. "Updated" is defined as being updated when all child nodes are updated, else just the cached value(result) of that node is used. The pull process's job is to ensure that O is updated when any of the child nodes is not updated. This means that the process needs to traverse the tree and check whether O(ll), O(lr), O(rl), and O(rr) are updated. If the data collection, those child nodes reference, are updated since the last update of those child nodes then those child nodes need to be updated as function of the changed data collection. If the data collection is updated and hence the child nodes O(ll), O(lr), O(rl), and O(rr) are updated as well and this means that O(l) and O(r) also need to be updated and subsequently O will also be updated. Each child node is input to its parent node.

The complexity here is that each child node is shared among different trees, meaning, a child node of one tree can also be any child node of another tree. The purpose of this structure is to avoid the re-calculation of a child node when it is already up-to-date. The child nodes are shared if different trees implement a child node with the exact same functionality (function and parameterization) as the already existing child node.

I am stuck with the design of this structure and how to go about implementing it. I have not provided code yet because I am stuck with the design thought process. Essentially each child is function and depends on dependent functions itself.

What makes me wonder is whether C# offers the ability to decorate methods and classes in order to simplify the checking of whether a node is updated or not. Also does lazy evaluation play a role in this process at all?

Matt
  • 7,004
  • 11
  • 71
  • 117
  • It's not a "tree" if there are multiple parents. What you have is a "graph". Probably a "directed acyclic graph" unless there are potentially cycles? – Enigmativity Jun 18 '19 at 03:11
  • @Enigmativity, thanks will take a look, would you stand by your statement even if each tree is completely independent of each other? I am saying independent because there is no dependency on another tree, it just happens that some child nodes are shared in that they perform the same function. – Matt Jun 18 '19 at 07:28

1 Answers1

1

I suggest defining a class that keeps track whether its children have been updated via a flag, e.g. a Boolean named Dirty. A node in the tree can tell its parents to become dirty by raising an event. When a node returns its own value, it should check the flag and recompute its own value only when needed. When recomputing, it should check the Value of each child, each of which will then check its own dirty flag, and so on, recursively.

class Node<T> 
{
    event EventHandler Changed;

    private T _value;
    private bool _dirty = true;
    private List<Node<T>> _children = new List<Node<T>>();

    public void AddChild(Node<T> child)
    {
        child.Changed += (s,e) => _dirty = true;
        _children.Add(child);
    }

    protected void OnChanged()
    {
        if (Changed != null) Changed(this, new EventArgs());
    }

    public T Value
    {
        get
        {
            if (_dirty)
            {
                this.Value = ComputeValueFromChildren();
                _dirty = false;
            }
            return _value;
        }
        set
        {
            _value = value;
            OnChanged();
        }
    }

    private T ComputeValueFromChildren()
    {
        var values = _children.Select( child => child.Value );
        //Return the new value based on the children
    }
}
John Wu
  • 50,556
  • 8
  • 44
  • 80
  • I was thinking about a solution along those lines. I am just wondering whether decorators or a more functional approach might be superior? – Matt Jun 18 '19 at 02:53
  • I really don’t see how decorators could possibly be used to solve this problem. What did you have in mind? – John Wu Jun 18 '19 at 05:31
  • I came across a comment where AOP was mentioned in regards to similar problem – Matt Jun 18 '19 at 07:26
  • C# does not support AOP without some kind of framework being built for it ([link](https://stackoverflow.com/questions/1416880/aspect-oriented-programming-in-c-sharp)) so a general C# answer is not possible. Also, I don't see why that would be the right fit for this problem. – John Wu Jun 18 '19 at 16:50