def compute_nodes_assets_amount(self, nodes_with_assets): self.stack = Stack() nodes_items = [] for key, values in nodes_with_assets.items(): nodes_items.append({ "key": key, "assets": values["assets"], "all_assets": values["all_assets"], "assets_amount": 0 }) nodes_items.sort(key=self.sorted_by) nodes_items.append({ "key": "", "assets": set(), "all_assets": set(), "assets_amount": 0 }) self.stack = Stack() for item in nodes_items: self.debug("准备: {} 栈顶: {}".format( item['key'], self.stack.top["key"] if self.stack.top else None)) # 入栈之前检查,该节点是不是栈顶节点的子节点 # 如果不是,则栈顶出栈 while self.stack.top and not self.is_children( self.stack.top, item): self.pop_from_stack_nodes_amount() self.push_to_stack_nodes_amount(item) # 出栈最后一个 self.debug("剩余: {}".format(', '.join([n["key"] for n in self.stack]))) return self._nodes
def get_nodes_family_and_system_users(self, nodes_with_system_users): """ 返回所有nodes_with_system_users中的node的家族节点的信息, 并子会继承祖先的系统用户和actions信息 :param nodes_with_system_users: {node.key: {system_user.id: actions,}, } :return: {node.key: {system_user.id: actions,}, } """ node_util = NodeUtil() _nodes_keys = nodes_with_system_users.keys() family_keys = node_util.get_some_nodes_family_keys_by_keys(_nodes_keys) nodes_items = [] for i in family_keys: system_users = nodes_with_system_users.get(i, defaultdict(int)) item = {"key": i, "system_users": system_users} nodes_items.append(item) # 按照父子关系排序 nodes_items.sort(key=self.sorted_by) nodes_items.append({"key": "", "system_users": defaultdict(int)}) self.stack = Stack() for item in nodes_items: self.debug("准备: {} 栈顶: {}".format( item['key'], self.stack.top["key"] if self.stack.top else None)) # 入栈之前检查,该节点是不是栈顶节点的子节点 # 如果不是,则栈顶出栈 while self.stack.top and not self.is_children( self.stack.top, item): # 出栈 self.pop_from_stack_system_users() # 入栈 self.push_to_stack_system_users(item) # 出栈最后一个 self.debug("剩余: {}".format(', '.join([n["key"] for n in self.stack]))) return self._nodes
def generate(self): # 准备排序好的资产信息数据 infos = [] for node in self.nodes: assets = self.nodekey_assetsid_mapper.get(node.key, set()) info = NodeAssetsInfo(key=node.key, assets_amount=0, assets=assets) infos.append(info) infos = sorted(infos, key=lambda i: [int(i) for i in i.key.split(':')]) # 这个守卫需要添加一下,避免最后一个无法出栈 guarder = NodeAssetsInfo(key='', assets_amount=0, assets=set()) infos.append(guarder) stack = Stack() for info in infos: # 如果栈顶的不是这个节点的父祖节点,那么可以出栈了,可以计算资产数量了 while stack.top and not info.key.startswith(f'{stack.top.key}:'): pop_info = stack.pop() pop_info.assets_amount = len(pop_info.assets) self.nodekey_assetsinfo_mapper[pop_info.key] = pop_info if not stack.top: continue stack.top.assets.update(pop_info.assets) stack.push(info)
def __init__(self, with_assets_amount=False, debug=False): self.stack = Stack() self._nodes = {} self.with_assets_amount = with_assets_amount self._debug = debug self.init()