mirror of https://github.com/zeldaret/tp.git
73 lines
1.8 KiB
Python
73 lines
1.8 KiB
Python
|
|
from collections import defaultdict
|
|
|
|
from . import util
|
|
from .context import Context
|
|
|
|
class Node:
|
|
def __init__(self, name):
|
|
self.name = name
|
|
self.depth = 0
|
|
self.id = name
|
|
|
|
def __eq__(self, other):
|
|
return other.id == self.id
|
|
|
|
def __hash__(self):
|
|
return hash(self.id)
|
|
|
|
def __repr__(self):
|
|
return self.__str__()
|
|
|
|
def __str__(self):
|
|
return str((self.depth, self.name))
|
|
|
|
def unique_keeporder(seq):
|
|
seen = set()
|
|
seen_add = seen.add
|
|
return [x for x in seq if not (x in seen or seen_add(x))]
|
|
|
|
def sort(context: Context, keys, order_sections):
|
|
nodes = dict([(x, Node(x)) for x in keys])
|
|
orders = []
|
|
for os, osv in order_sections.items():
|
|
orders.append([ x for x in unique_keeporder(osv)])
|
|
|
|
edges = []
|
|
graph = dict()
|
|
for node in nodes.values():
|
|
graph[node.id] = []
|
|
for order in orders:
|
|
for a, b in util.mapOverlap(order, 2):
|
|
if not a or not b:
|
|
continue
|
|
graph[a].append(b)
|
|
edges.append([a, b])
|
|
|
|
predecessor_count = defaultdict(int)
|
|
for f, t in edges:
|
|
predecessor_count[t] += 1
|
|
|
|
top_node = None
|
|
top_nodes = [x for x in nodes.keys() if predecessor_count[x] == 0]
|
|
if len(top_nodes) > 1:
|
|
pass
|
|
elif len(top_nodes) == 0:
|
|
context.error("error: found no top-level node")
|
|
|
|
def calculate_max_depth(k, depth):
|
|
node = nodes[k]
|
|
if depth <= node.depth:
|
|
return
|
|
|
|
node.depth = depth
|
|
for edge in graph[k]:
|
|
calculate_max_depth(edge, depth + 1)
|
|
|
|
for top_node in top_nodes:
|
|
calculate_max_depth(top_node, 1)
|
|
|
|
sorted_nodes = list(nodes.values())
|
|
sorted_nodes.sort(key=lambda x: x.depth)
|
|
return [x.id for x in sorted_nodes]
|