[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: Returns:
OrderedDict[Node, Node]: the source->duplicate map 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 # use OrderedDict to keep duplicated nodes creation order
duplicates = OrderedDict() duplicates = OrderedDict()
@ -714,6 +714,35 @@ class Graph(BaseObject):
self.dfs(visitor=visitor, startNodes=startNodes) self.dfs(visitor=visitor, startNodes=startNodes)
return nodes, edges 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): def dfsToProcess(self, startNodes=None):
""" """
Return the full list of predecessor nodes to process in order to compute the given nodes. 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) flowEdges.append(link)
return flowEdges 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): def getInputNodes(self, node, recursive=False):
""" Return either the first level input nodes of a node or the whole chain. """ """ Return either the first level input nodes of a node or the whole chain. """
if not recursive: if not recursive:
return set([edge.src.node for edge in self.edges if edge.dst.node is node]) 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 return inputNodes[1:] # exclude current node
def getOutputNodes(self, node, recursive=False): def getOutputNodes(self, node, recursive=False):
@ -918,7 +918,7 @@ class Graph(BaseObject):
if not recursive: if not recursive:
return set([edge.dst.node for edge in self.edges if edge.src.node is node]) 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 return outputNodes[1:] # exclude current node
@Slot(Node, result=int) @Slot(Node, result=int)
@ -1074,7 +1074,7 @@ class Graph(BaseObject):
See Also: See Also:
Graph.update, Graph.updateInternals, Graph.updateStatusFromCache Graph.update, Graph.updateInternals, Graph.updateStatusFromCache
""" """
nodes, edges = self.nodesFromNode(fromNode) nodes, edges = self.dfsOnDiscover(fromNode)
for node in nodes: for node in nodes:
node.dirty = True node.dirty = True
@ -1098,7 +1098,7 @@ class Graph(BaseObject):
@Slot(Node) @Slot(Node)
def clearDataFrom(self, startNode): def clearDataFrom(self, startNode):
for node in self.nodesFromNode(startNode)[0]: for node in self.dfsOnDiscover(startNode)[0]:
node.clearData() node.clearData()
def iterChunksByStatus(self, status): def iterChunksByStatus(self, status):

View file

@ -69,7 +69,7 @@ class TaskThread(Thread):
break break
else: else:
logging.error("Error on node computation: {}".format(e)) 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 # remove following nodes from the task queue
for n in nodesToRemove[1:]: # exclude current node for n in nodesToRemove[1:]: # exclude current node
try: try:

View file

@ -526,7 +526,7 @@ class UIGraph(QObject):
with self.groupedGraphModification("Remove Nodes from {}".format(startNode.name)): with self.groupedGraphModification("Remove Nodes from {}".format(startNode.name)):
# Perform nodes removal from leaves to start node so that edges # Perform nodes removal from leaves to start node so that edges
# can be re-created in correct order on redo. # 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) @Slot(Attribute, Attribute)
def addEdge(self, src, dst): def addEdge(self, src, dst):

View file

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

View file

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