""" GraphProperties() Create an empty [`GraphProperties`](@ref) object. """ function GraphProperties() return ( data = 0.0, computeEffort = 0.0, computeIntensity = 0.0, cost = 0.0, noNodes = 0, noEdges = 0, )::GraphProperties end """ GraphProperties(graph::DAG) Calculate the graph's properties and return the constructed [`GraphProperties`](@ref) object. """ function GraphProperties(graph::DAG) # make sure the graph is fully generated apply_all!(graph) d = 0.0 ce = 0.0 ed = 0 for node in graph.nodes d += data(node.task) * length(node.parents) ce += compute_effort(node.task) ed += length(node.parents) end return ( data = d, computeEffort = ce, computeIntensity = (d == 0) ? 0.0 : ce / d, cost = 0.0, # TODO noNodes = length(graph.nodes), noEdges = ed, )::GraphProperties end """ GraphProperties(diff::Diff) Create the graph properties difference from a given [`Diff`](@ref). The graph's properties after applying the [`Diff`](@ref) will be `get_properties(graph) + GraphProperties(diff)`. For reverting a diff, it's `get_properties(graph) - GraphProperties(diff)`. """ function GraphProperties(diff::Diff) d = 0.0 ce = 0.0 c = 0.0 # TODO ce = reduce(+, compute_effort(n.task) for n in diff.addedNodes; init = 0.0) - reduce(+, compute_effort(n.task) for n in diff.removedNodes; init = 0.0) d = reduce(+, data(e) for e in diff.addedEdges; init = 0.0) - reduce(+, data(e) for e in diff.removedEdges; init = 0.0) return ( data = d, computeEffort = ce, computeIntensity = (d == 0) ? 0.0 : ce / d, cost = c, noNodes = length(diff.addedNodes) - length(diff.removedNodes), noEdges = length(diff.addedEdges) - length(diff.removedEdges), )::GraphProperties end