def get_exec_order(self, start_path): if start_path == nxt_path.WORLD: return [] start_root_path = nxt_path.get_root_path(start_path) exec_order = [] start_found = False root_exec_order = self.get_root_exec_order(start_root_path) for root_path in root_exec_order: if not start_found and root_path == start_path: start_found = True node = self.lookup(root_path) enabled = nxt_node.get_node_enabled(node) if enabled is None: enabled = True if not enabled: continue if start_found: exec_order += [root_path] path_rt_type = LayerReturnTypes.Path disabled_desc = [] for desc_path in self.descendants(node_path=root_path, ordered=True, return_type=path_rt_type): if not start_found and desc_path == start_path: start_found = True desc_node = self.lookup(desc_path) enabled = nxt_node.get_node_enabled(desc_node) if enabled is None: enabled = True if enabled: for potential_ancestor in disabled_desc: if nxt_path.is_ancestor(desc_path, potential_ancestor): enabled = False break if not enabled: disabled_desc += [desc_path] continue if start_found: exec_order += [desc_path] return exec_order
def children(self, node_path=nxt_path.WORLD, return_type=LayerReturnTypes.Node, ordered=False, include_implied=False): if include_implied and return_type != LayerReturnTypes.Path: raise ValueError('When including implied, can only return path. ' 'Nothing else exists for implicit nodes.') children_nodes = [] children_paths = [] node_table = [] name_dict = {} if not node_path: if return_type in (LayerReturnTypes.Node, LayerReturnTypes.Path, LayerReturnTypes.NodeTable): return [] elif return_type == LayerReturnTypes.NameDict: return {} elif return_type == LayerReturnTypes.Boolean: return False else: logger.error('Invalid return type provided') return None child_order = [] implied_children = [] # Look up real children cache children_cache = self._cached_children.get(node_path) if node_path == nxt_path.WORLD: children_cache = None if children_cache is not None: children_nodes = children_cache[LayerReturnTypes.Node][:] children_paths = children_cache[LayerReturnTypes.Path][:] node_table = children_cache[LayerReturnTypes.NodeTable][:] name_dict = copy.copy(children_cache[LayerReturnTypes.NameDict]) cache_real = False else: self._cached_children[node_path] = { LayerReturnTypes.Node: children_nodes, LayerReturnTypes.Path: children_paths, LayerReturnTypes.NodeTable: node_table, LayerReturnTypes.NameDict: name_dict } cache_real = True # Lookup implied cache cache_implied = False if include_implied: implied_c_cache = self._cached_implied_children.get(node_path) if node_path == nxt_path.WORLD: implied_c_cache = None if implied_c_cache is not None: implied_children = implied_c_cache[LayerReturnTypes.Path][:] if return_type == LayerReturnTypes.Boolean and not cache_real: return bool(implied_children + children_paths) else: path_implied = {LayerReturnTypes.Path: implied_children} self._cached_implied_children[node_path] = path_implied cache_implied = True re_cache = cache_implied or cache_real if re_cache: for path, node in self._nodes_path_as_key.items(): if cache_real: parent_path = getattr(node, nxt_node.INTERNAL_ATTRS.PARENT_PATH) if parent_path == node_path: children_nodes += [node] children_paths += [path] node_table += [[path, node]] key = getattr(node, nxt_node.INTERNAL_ATTRS.NAME) name_dict[key] = node if not include_implied or not cache_implied: continue if nxt_path.is_ancestor(path, node_path): trim_depth = nxt_path.get_path_depth(node_path) + 1 trimmed = nxt_path.trim_to_depth(path, trim_depth) if trimmed not in implied_children: implied_children += [trimmed] if cache_real: k = LayerReturnTypes.Path self._cached_children[node_path][k] = children_paths[:] if include_implied: for imp in implied_children: if imp not in children_paths: children_paths += [imp] if return_type == LayerReturnTypes.Boolean: return bool(children_paths) if ordered: node = self.lookup(node_path) if include_implied and not node: child_order = [] else: co_attr = nxt_node.INTERNAL_ATTRS.CHILD_ORDER child_order = getattr(node, co_attr) if child_order: ordered_child_nodes = [] ordered_child_paths = [] ordered_node_table = [] for child_name in child_order: # return type NODE for n in children_nodes: c_name = getattr(n, nxt_node.INTERNAL_ATTRS.NAME) if c_name == child_name: ordered_child_nodes += [n] # return type PATH for p in children_paths: if nxt_path.node_name_from_node_path(p) == child_name: ordered_child_paths += [p] # return type TABLE for item in node_table: p, n = item if nxt_path.node_name_from_node_path(p) == child_name: ordered_node_table += [item] # return type NODE for n in children_nodes: if n not in ordered_child_nodes: ordered_child_nodes += [n] children_nodes = ordered_child_nodes # return type PATH for p in children_paths: if p not in ordered_child_paths: ordered_child_paths += [p] children_paths = ordered_child_paths # return type TABLE for item in node_table: p, n = item if p not in ordered_node_table: ordered_node_table += [item] node_table = ordered_node_table if return_type == LayerReturnTypes.Node: return children_nodes elif return_type == LayerReturnTypes.Path: return children_paths elif return_type == LayerReturnTypes.NodeTable: return node_table elif return_type == LayerReturnTypes.NameDict: return name_dict elif return_type == LayerReturnTypes.Boolean: return False else: logger.error('Invalid return type provided') return None