[core] Graph: rename nodesFromNode() to dfsOnDiscover()

This commit is contained in:
Julien-Haudegond 2020-09-04 11:49:45 +02:00
parent 49e33fb9ba
commit f8bd40ad38
5 changed files with 52 additions and 52 deletions

View file

@ -380,7 +380,7 @@ class Graph(BaseObject):
Returns:
OrderedDict[Node, Node]: the source->duplicate map
"""
srcNodes, srcEdges = self.nodesFromNode(fromNode)
srcNodes, srcEdges = self.dfsOnDiscover(fromNode)
# use OrderedDict to keep duplicated nodes creation order
duplicates = OrderedDict()
@ -714,6 +714,35 @@ class Graph(BaseObject):
self.dfs(visitor=visitor, startNodes=startNodes)
return nodes, edges
def dfsOnDiscover(self, startNode, filterTypes=None, longestPathFirst=False, reverse=True):
"""
Return the node chain from startNode to the graph leaves.
Args:
startNode (Node): the node to start the visit from.
filterTypes (str list): (optional) only return the nodes of the given types
(does not stop the visit, this is a post-process only)
longestPathFirst (bool): (optional) if multiple paths, nodes belonging to
the longest one will be visited first.
reverse (bool): (optional) direction of visit.
True is for getting nodes depending on the startNode.
False is for getting nodes required for the startNode.
Returns:
The list of nodes and edges, from startNode to the graph leaves following edges.
"""
nodes = []
edges = []
visitor = Visitor()
def discoverVertex(vertex, graph):
if not filterTypes or vertex.nodeType in filterTypes:
nodes.append(vertex)
visitor.discoverVertex = discoverVertex
visitor.examineEdge = lambda edge, graph: edges.append(edge)
self.dfs(visitor=visitor, startNodes=[startNode], longestPathFirst=longestPathFirst, reverse=reverse)
return nodes, edges
def dfsToProcess(self, startNodes=None):
"""
Return the full list of predecessor nodes to process in order to compute the given nodes.
@ -876,41 +905,12 @@ class Graph(BaseObject):
flowEdges.append(link)
return flowEdges
def nodesFromNode(self, startNode, filterTypes=None, longestPathFirst=False, reverse=True):
"""
Return the node chain from startNode to the graph leaves.
Args:
startNode (Node): the node to start the visit from.
filterTypes (str list): (optional) only return the nodes of the given types
(does not stop the visit, this is a post-process only)
longestPathFirst (bool): (optional) if multiple paths, nodes belonging to
the longest one will be visited first.
reverse (bool): (optional) direction of visit.
True is for getting nodes depending on the startNode.
False is for getting nodes required for the startNode.
Returns:
The list of nodes and edges, from startNode to the graph leaves following edges.
"""
nodes = []
edges = []
visitor = Visitor()
def discoverVertex(vertex, graph):
if not filterTypes or vertex.nodeType in filterTypes:
nodes.append(vertex)
visitor.discoverVertex = discoverVertex
visitor.examineEdge = lambda edge, graph: edges.append(edge)
self.dfs(visitor=visitor, startNodes=[startNode], longestPathFirst=longestPathFirst, reverse=reverse)
return nodes, edges
def getInputNodes(self, node, recursive=False):
""" Return either the first level input nodes of a node or the whole chain. """
if not recursive:
return set([edge.src.node for edge in self.edges if edge.dst.node is node])
inputNodes, edges = self.nodesFromNode(node, filterTypes=None, reverse=False)
inputNodes, edges = self.dfsOnDiscover(node, filterTypes=None, reverse=False)
return inputNodes[1:] # exclude current node
def getOutputNodes(self, node, recursive=False):
@ -918,7 +918,7 @@ class Graph(BaseObject):
if not recursive:
return set([edge.dst.node for edge in self.edges if edge.src.node is node])
outputNodes, edges = self.nodesFromNode(node, filterTypes=None, reverse=True)
outputNodes, edges = self.dfsOnDiscover(node, filterTypes=None, reverse=True)
return outputNodes[1:] # exclude current node
@Slot(Node, result=int)
@ -1074,7 +1074,7 @@ class Graph(BaseObject):
See Also:
Graph.update, Graph.updateInternals, Graph.updateStatusFromCache
"""
nodes, edges = self.nodesFromNode(fromNode)
nodes, edges = self.dfsOnDiscover(fromNode)
for node in nodes:
node.dirty = True
@ -1098,7 +1098,7 @@ class Graph(BaseObject):
@Slot(Node)
def clearDataFrom(self, startNode):
for node in self.nodesFromNode(startNode)[0]:
for node in self.dfsOnDiscover(startNode)[0]:
node.clearData()
def iterChunksByStatus(self, status):

View file

@ -69,7 +69,7 @@ class TaskThread(Thread):
break
else:
logging.error("Error on node computation: {}".format(e))
nodesToRemove, _ = self._manager._graph.nodesFromNode(node)
nodesToRemove, _ = self._manager._graph.dfsOnDiscover(node)
# remove following nodes from the task queue
for n in nodesToRemove[1:]: # exclude current node
try:

View file

@ -526,7 +526,7 @@ class UIGraph(QObject):
with self.groupedGraphModification("Remove Nodes from {}".format(startNode.name)):
# Perform nodes removal from leaves to start node so that edges
# can be re-created in correct order on redo.
[self.removeNode(node) for node in reversed(self._graph.nodesFromNode(startNode)[0])]
[self.removeNode(node) for node in reversed(self._graph.dfsOnDiscover(startNode)[0])]
@Slot(Attribute, Attribute)
def addEdge(self, src, dst):

View file

@ -473,7 +473,7 @@ class Reconstruction(UIGraph):
def onCameraInitChanged(self):
# Update active nodes when CameraInit changes
nodes = self._graph.nodesFromNode(self._cameraInit)[0]
nodes = self._graph.dfsOnDiscover(self._cameraInit)[0]
self.setActiveNodes(nodes)
@Slot()
@ -651,7 +651,7 @@ class Reconstruction(UIGraph):
"""
if not startNode:
return None
nodes = self._graph.nodesFromNode(startNode, nodeTypes)[0]
nodes = self._graph.dfsOnDiscover(startNode, nodeTypes)[0]
if not nodes:
return None
node = nodes[-1]

View file

@ -158,8 +158,8 @@ def test_transitive_reduction():
assert node.depth == maxDepth
def test_graph_reverse_nodesFromNode():
graph = Graph('Test nodesFromNode(reverse=True)')
def test_graph_reverse_dfsOnDiscover():
graph = Graph('Test dfsOnDiscover(reverse=True)')
# ------------\
# / ~ C - E - F
@ -174,21 +174,21 @@ def test_graph_reverse_nodesFromNode():
F = graph.addNewNode('AppendText', input=A.output, inputText=E.output)
# Get all nodes from A (use set, order not guaranteed)
nodes = graph.nodesFromNode(A)[0]
nodes = graph.dfsOnDiscover(A)[0]
assert set(nodes) == {A, B, D, C, E, F}
# Get all nodes from B
nodes = graph.nodesFromNode(B)[0]
nodes = graph.dfsOnDiscover(B)[0]
assert set(nodes) == {B, D, C, E, F}
# Get all nodes of type AppendText from B
nodes = graph.nodesFromNode(B, filterTypes=['AppendText'])[0]
nodes = graph.dfsOnDiscover(B, filterTypes=['AppendText'])[0]
assert set(nodes) == {B, D, C, F}
# Get all nodes from C (order guaranteed)
nodes = graph.nodesFromNode(C)[0]
nodes = graph.dfsOnDiscover(C)[0]
assert nodes == [C, E, F]
def test_graph_nodesFromNode():
graph = Graph('Test nodesFromNode(reverse=False)')
def test_graph_dfsOnDiscover():
graph = Graph('Test dfsOnDiscover(reverse=False)')
# ------------\
# / ~ C - E - F
@ -205,22 +205,22 @@ def test_graph_nodesFromNode():
F = graph.addNewNode('AppendText', input=A.output, inputText=E.output)
# Get all nodes from A (use set, order not guaranteed)
nodes = graph.nodesFromNode(A, reverse=False)[0]
nodes = graph.dfsOnDiscover(A, reverse=False)[0]
assert set(nodes) == {A}
# Get all nodes from D
nodes = graph.nodesFromNode(D, reverse=False)[0]
nodes = graph.dfsOnDiscover(D, reverse=False)[0]
assert set(nodes) == {A, B, D, G}
# Get all nodes from E
nodes = graph.nodesFromNode(E, reverse=False)[0]
nodes = graph.dfsOnDiscover(E, reverse=False)[0]
assert set(nodes) == {A, B, C, E}
# Get all nodes from F
nodes = graph.nodesFromNode(F, reverse=False)[0]
nodes = graph.dfsOnDiscover(F, reverse=False)[0]
assert set(nodes) == {A, B, C, E, F}
# Get all nodes of type AppendText from C
nodes = graph.nodesFromNode(C, filterTypes=['AppendText'], reverse=False)[0]
nodes = graph.dfsOnDiscover(C, filterTypes=['AppendText'], reverse=False)[0]
assert set(nodes) == {B, C}
# Get all nodes from D (order guaranteed)
nodes = graph.nodesFromNode(D, longestPathFirst=True, reverse=False)[0]
nodes = graph.dfsOnDiscover(D, longestPathFirst=True, reverse=False)[0]
assert nodes == [D, B, A, G]