Source code for mojo.jobManagement.graph.node
"""
Node
====
The class Node serves as nodes in the dependency-graph. A node owns a id,
a list of its parents, a list of its childs, its weight, its status and
a flag if the weight was already calculated. It offers a method to add a
child to the list of childs and a method to delete a parent from the list of
parents. Calculate weight calculates recursive the weight of the node.
Furthermore five int-constants for the statuses and a dictionary to print
a string instead of the value of the constant are offered
.. attention::
Node is not intended to be used without graph!
"""
from ...jobManagement import jobManagementData as jobConsts
[docs]class Node:
"""Node is a class which serves as node in a graph of dependencies between jobs.
As instancevariables it saves its own id, its parents which are not done, its
childs, its weight and calculated weight and its status.
:param id: id of the node
:param parents: list of the parentsIds
:param weight: weight of the node
:type id: int
:type parents: list of int
:type weight: int
"""
def __init__(self, nodeId, parents, priority=1):
"""A new node gets as instancevariables a nodeId, its parents, a priority,
a calculated priority initialized with None and the status WAITING
:param nodeId: nodeId of the node
:param parents: list of the parentsIds
:param priority: weight of the node
:type nodeId: int
:type parents: list of Node
:type priority: int
"""
self.__id = nodeId
self.__pendingParents = parents
self._processedParents = []
self._childs = list()
self.__priority = priority
self.__calculatedPriority = 0
self.__status = jobConsts.WAITING
@property
def id(self):
return self.__id
@property
def priority(self):
return self.__priority
@property
def calculatedPriority(self):
"""Weight of critical path
"""
return self.__calculatedPriority
@property
def childs(self):
return self._childs
def getParents(self):
return self.__pendingParents
def setParents(self, ListOfParents):
self.__pendingParents = ListOfParents
parents = property(getParents, setParents)
[docs] def markParentProcessed(self, parent):
"""Marks the parent as processed
:param parent: parent to mark
:type parent: Node
"""
try:
self.__pendingParents.remove(parent)
except ValueError:
pass # happens when a node was removed due to a circular dependency
else:
self._processedParents.append(parent)
[docs] def addChild(self, newChild):
"""Adds a child to the list of childs
:param newChild: child to add
:type newChild: Node
"""
self._childs.append(newChild)
[docs] def addParent(self, newParent):
"""Appends a new parent to the list of parents
:param newParent: parent to append
:type newParent: Node
"""
self.__pendingParents.append(newParent)
def getStatus(self):
return self.__status
[docs] def setStatus(self, newStatus):
"""Sets a new status. The children will get the status DEAD_PARENT if the status is ERROR
or DEAD_PARENT. If the status is DONE the node will delete itself from the children
list of parents.
:param newStatus: new status to set
:type newStatus: int-const
"""
self.__status = newStatus
if newStatus == jobConsts.ERROR or newStatus == jobConsts.DEAD_PARENT:
for child in self._childs:
try:
child.status = jobConsts.DEAD_PARENT
except RuntimeError:
pass # happens when a circular dependency occurred
elif newStatus == jobConsts.DONE:
for child in self._childs:
child.markParentProcessed(self)
status = property(getStatus, setStatus)
[docs] def calculatePriority(self):
"""Calculates the weight of the node and all of its children
:return: the own calculated weight
:rtype: int
"""
priorities = [x.calculatePriority() for x in self._childs]
self.__calculatedPriority = (max(priorities) if priorities else 0) + self.__priority
return self.__calculatedPriority