2022-10-13 19:13:39 +09:00
|
|
|
from collections import namedtuple
|
|
|
|
|
|
|
|
|
2022-12-29 15:09:59 +09:00
|
|
|
# Representation of the smallest unit in E2E calculations (e.g. a DDS time, a calculation time, an idle time)
|
2022-10-13 19:13:39 +09:00
|
|
|
E2EBreakdownItem = namedtuple("E2EBreakdownItem", ("type", "duration", "location"))
|
2022-12-29 15:09:59 +09:00
|
|
|
# A recursive tree structure used to represent dependencies
|
2022-10-13 19:13:39 +09:00
|
|
|
DepTree = namedtuple("DepTree", ("head", "deps"))
|
|
|
|
|
|
|
|
|
2022-10-14 00:15:33 +09:00
|
|
|
def depth(tree: DepTree, lvl=0):
|
2022-12-29 15:09:59 +09:00
|
|
|
"""
|
|
|
|
The depth of `tree` (the length of the longest path from root to any leaf).
|
|
|
|
Capped at 1000.
|
|
|
|
:param tree: The tree
|
|
|
|
:param lvl: Internal, leave at 0; Used for recursion threshold
|
|
|
|
:return: The depth
|
|
|
|
"""
|
2022-10-14 00:15:33 +09:00
|
|
|
if lvl > 1000:
|
|
|
|
return 0
|
|
|
|
return 1 + max(map(lambda d: depth(d, lvl + 1), tree.deps), default=0)
|
2022-10-13 19:13:39 +09:00
|
|
|
|
|
|
|
|
2022-10-14 00:15:33 +09:00
|
|
|
def size(tree: DepTree, lvl=0):
|
2022-12-29 15:09:59 +09:00
|
|
|
"""
|
|
|
|
The number of nodes (including root, inner and leaf nodes) of `tree`
|
|
|
|
:param tree: The tree
|
|
|
|
:param lvl: Internal, leave at 0; Used for recursion threshold for trees over 1000 entries deep.
|
|
|
|
:return: The number of nodes in `tree`
|
|
|
|
"""
|
2022-10-14 00:15:33 +09:00
|
|
|
if lvl > 1000:
|
|
|
|
return 0
|
|
|
|
return 1 + sum(map(lambda d: size(d, lvl + 1), tree.deps))
|
2022-10-13 19:13:39 +09:00
|
|
|
|
|
|
|
|
|
|
|
def fanout(tree: DepTree):
|
2022-12-29 15:09:59 +09:00
|
|
|
"""
|
|
|
|
The number of leaves of `tree`.
|
|
|
|
:param tree: The tree
|
|
|
|
:return: The number of leaves
|
|
|
|
"""
|
2022-10-13 19:13:39 +09:00
|
|
|
if not tree.deps:
|
|
|
|
return 1
|
|
|
|
|
|
|
|
return sum(map(fanout, tree.deps))
|