snarled/snarl/tracker.py
2022-03-27 23:43:52 -07:00

51 lines
1.8 KiB
Python

from typing import List, Set
from collections import defaultdict
from .types import layer_t, net_name_t, contour_t
class NetsInfo:
nets: defaultdict[net_name_t, defaultdict[layer_t, List]]
net_aliases: defaultdict[net_name_t, net_name_t]
def __init__(self) -> None:
self.nets = defaultdict(lambda: defaultdict(list))
self.net_aliases = defaultdict(list)
def resolve_name(self, net_name: net_name_t) -> net_name_t:
while net_name in self.net_aliases:
net_name = self.net_aliases[net_name]
return net_name
def merge(self, net_a: net_name_t, net_b: net_name_t) -> None:
net_a = self.resolve_name(net_a)
net_b = self.resolve_name(net_b)
# Always keep named nets if the other is anonymous
if not isinstance(net_a, str) and isinstance(net_b, str):
keep_net, old_net = net_b, net_a
else:
keep_net, old_net = net_a, net_b
#logger.info(f'merging {old_net} into {keep_net}')
self.net_aliases[old_net] = keep_net
if old_net in self.nets:
for layer in self.nets[old_net]:
self.nets[keep_net][layer] += self.nets[old_net][layer]
del self.nets[old_net]
def get(self, net: net_name_t, layer: layer_t) -> List[contour_t]:
return self.nets[self.resolve_name(net)][layer]
def get_shorted_nets(self) -> List[Set[str]]:
shorts = defaultdict(list)
for kk in self.net_aliases:
if isinstance(kk, str):
base_name = self.resolve_name(kk)
assert(isinstance(base_name, str))
shorts[base_name].append(kk)
shorted_sets = [set([kk] + others)
for kk, others in shorts.items()]
return shorted_sets