def testDigraphEmptyGraph(self):
		g = digraph()
		f = g.clone()
		for x in g, f:
			self.assertEqual(bool(x), False)
			self.assertEqual(x.contains("A"), False)
			self.assertEqual(x.firstzero(), None)
			self.assertRaises(KeyError, x.remove, "A")
			x.delnode("A")
			self.assertEqual(list(x), [])
			self.assertEqual(x.get("A"), None)
			self.assertEqual(x.get("A", "default"), "default")
			self.assertEqual(x.all_nodes(), [])
			self.assertEqual(x.leaf_nodes(), [])
			self.assertEqual(x.root_nodes(), [])
			self.assertRaises(KeyError, x.child_nodes, "A")
			self.assertRaises(KeyError, x.parent_nodes, "A")
			self.assertEqual(x.hasallzeros(), True)
			self.assertRaises(KeyError, list, x.bfs("A"))
			self.assertRaises(KeyError, x.shortest_path, "A", "B")
			self.assertRaises(KeyError, x.remove_edge, "A", "B")
			self.assertEqual(x.get_cycles(), [])
			x.difference_update("A")
			portage.util.noiselimit = -2
			x.debug_print()
			portage.util.noiselimit = 0
Esempio n. 2
0
 def testDigraphEmptyGraph(self):
     g = digraph()
     f = g.clone()
     for x in g, f:
         self.assertEqual(bool(x), False)
         self.assertEqual(x.contains("A"), False)
         self.assertEqual(x.firstzero(), None)
         self.assertRaises(KeyError, x.remove, "A")
         x.delnode("A")
         self.assertEqual(list(x), [])
         self.assertEqual(x.get("A"), None)
         self.assertEqual(x.get("A", "default"), "default")
         self.assertEqual(x.all_nodes(), [])
         self.assertEqual(x.leaf_nodes(), [])
         self.assertEqual(x.root_nodes(), [])
         self.assertRaises(KeyError, x.child_nodes, "A")
         self.assertRaises(KeyError, x.parent_nodes, "A")
         self.assertEqual(x.hasallzeros(), True)
         self.assertRaises(KeyError, list, x.bfs("A"))
         self.assertRaises(KeyError, x.shortest_path, "A", "B")
         self.assertRaises(KeyError, x.remove_edge, "A", "B")
         self.assertEqual(x.get_cycles(), [])
         x.difference_update("A")
         portage.util.noiselimit = -2
         x.debug_print()
         portage.util.noiselimit = 0
Esempio n. 3
0
    def testDigraphIgnorePriority(self):
        def always_true(dummy):
            return True

        def always_false(dummy):
            return False

        g = digraph()
        g.add("A", "B")

        self.assertEqual(g.parent_nodes("A"), ["B"])
        self.assertEqual(g.parent_nodes("A", ignore_priority=always_false),
                         ["B"])
        self.assertEqual(g.parent_nodes("A", ignore_priority=always_true), [])

        self.assertEqual(g.child_nodes("B"), ["A"])
        self.assertEqual(g.child_nodes("B", ignore_priority=always_false),
                         ["A"])
        self.assertEqual(g.child_nodes("B", ignore_priority=always_true), [])

        self.assertEqual(g.leaf_nodes(), ["A"])
        self.assertEqual(g.leaf_nodes(ignore_priority=always_false), ["A"])
        self.assertEqual(g.leaf_nodes(ignore_priority=always_true), ["A", "B"])

        self.assertEqual(g.root_nodes(), ["B"])
        self.assertEqual(g.root_nodes(ignore_priority=always_false), ["B"])
        self.assertEqual(g.root_nodes(ignore_priority=always_true), ["A", "B"])
	def testDigraphIgnorePriority(self):

		def always_true(dummy):
			return True

		def always_false(dummy):
			return False

		g = digraph()
		g.add("A", "B")

		self.assertEqual(g.parent_nodes("A"), ["B"])
		self.assertEqual(g.parent_nodes("A", ignore_priority=always_false), ["B"])
		self.assertEqual(g.parent_nodes("A", ignore_priority=always_true), [])

		self.assertEqual(g.child_nodes("B"), ["A"])
		self.assertEqual(g.child_nodes("B", ignore_priority=always_false), ["A"])
		self.assertEqual(g.child_nodes("B", ignore_priority=always_true), [])

		self.assertEqual(g.leaf_nodes(), ["A"])
		self.assertEqual(g.leaf_nodes(ignore_priority=always_false), ["A"])
		self.assertEqual(g.leaf_nodes(ignore_priority=always_true), ["A", "B"])

		self.assertEqual(g.root_nodes(), ["B"])
		self.assertEqual(g.root_nodes(ignore_priority=always_false), ["B"])
		self.assertEqual(g.root_nodes(ignore_priority=always_true), ["A", "B"])
Esempio n. 5
0
    def testDigraphCircle(self):
        g = digraph()
        g.add("A", "B", -1)
        g.add("B", "C", 0)
        g.add("C", "D", 1)
        g.add("D", "A", 2)

        f = g.clone()
        h = digraph()
        h.update(f)
        for x in g, f, h:
            self.assertEqual(bool(x), True)
            self.assertEqual(x.contains("A"), True)
            self.assertEqual(x.firstzero(), None)
            self.assertRaises(KeyError, x.remove, "Z")
            x.delnode("Z")
            self.assertEqual(list(x), ["A", "B", "C", "D"])
            self.assertEqual(x.get("A"), "A")
            self.assertEqual(x.get("A", "default"), "A")
            self.assertEqual(x.all_nodes(), ["A", "B", "C", "D"])
            self.assertEqual(x.leaf_nodes(), [])
            self.assertEqual(x.root_nodes(), [])
            self.assertEqual(x.child_nodes("A"), ["D"])
            self.assertEqual(x.child_nodes("A", ignore_priority=2), [])
            self.assertEqual(x.parent_nodes("A"), ["B"])
            self.assertEqual(x.parent_nodes("A", ignore_priority=-2), ["B"])
            self.assertEqual(x.parent_nodes("A", ignore_priority=-1), [])
            self.assertEqual(x.hasallzeros(), False)
            self._assertBFSEqual(x.bfs("A"), [(None, "A"), ("A", "D"),
                                              ("D", "C"), ("C", "B")])
            self.assertEqual(x.shortest_path("A", "D"), ["A", "D"])
            self.assertEqual(x.shortest_path("D", "A"), ["D", "C", "B", "A"])
            self.assertEqual(x.shortest_path("A", "D", ignore_priority=2),
                             None)
            self.assertEqual(x.shortest_path("D", "A", ignore_priority=-2),
                             ["D", "C", "B", "A"])
            cycles = set(tuple(y) for y in x.get_cycles())
            self.assertEqual(cycles, set([("D", "C", "B", "A"), ("C", "B", "A", "D"), ("B", "A", "D", "C"), \
             ("A", "D", "C", "B")]))
            x.remove_edge("A", "B")
            self.assertEqual(x.get_cycles(), [])
            x.difference_update(["D"])
            self.assertEqual(x.all_nodes(), ["A", "B", "C"])
            portage.util.noiselimit = -2
            x.debug_print()
            portage.util.noiselimit = 0
Esempio n. 6
0
 def testBackwardCompatibility(self):
     g = digraph()
     f = g.copy()
     g.addnode("A", None)
     self.assertEqual("A" in g, True)
     self.assertEqual(bool(g), True)
     self.assertEqual(g.allnodes(), ["A"])
     self.assertEqual(g.allzeros(), ["A"])
     self.assertEqual(g.hasnode("A"), True)
	def testBackwardCompatibility(self):
		g = digraph()
		f = g.copy()
		g.addnode("A", None)
		self.assertEqual("A" in g, True)
		self.assertEqual(bool(g), True)
		self.assertEqual(g.allnodes(), ["A"])
		self.assertEqual(g.allzeros(), ["A"])
		self.assertEqual(g.hasnode("A"), True)
Esempio n. 8
0
	def testDigraphCircle(self):
		g = digraph()
		g.add("A", "B", -1)
		g.add("B", "C", 0)
		g.add("C", "D", 1)
		g.add("D", "A", 2)

		f = g.clone()
		h = digraph()
		h.update(f)
		for x in g, f, h:
			self.assertEqual(bool(x), True)
			self.assertEqual(x.contains("A"), True)
			self.assertEqual(x.firstzero(), None)
			self.assertRaises(KeyError, x.remove, "Z")
			x.delnode("Z")
			self.assertEqual(list(x), ["A", "B", "C", "D"])
			self.assertEqual(x.get("A"), "A")
			self.assertEqual(x.get("A", "default"), "A")
			self.assertEqual(x.all_nodes(), ["A", "B", "C", "D"])
			self.assertEqual(x.leaf_nodes(), [])
			self.assertEqual(x.root_nodes(), [])
			self.assertEqual(x.child_nodes("A"), ["D"])
			self.assertEqual(x.child_nodes("A", ignore_priority=2), [])
			self.assertEqual(x.parent_nodes("A"), ["B"])
			self.assertEqual(x.parent_nodes("A", ignore_priority=-2), ["B"])
			self.assertEqual(x.parent_nodes("A", ignore_priority=-1), [])
			self.assertEqual(x.hasallzeros(), False)
			self._assertBFSEqual(x.bfs("A"), [(None, "A"), ("A", "D"), ("D", "C"), ("C", "B")])
			self.assertEqual(x.shortest_path("A", "D"), ["A", "D"])
			self.assertEqual(x.shortest_path("D", "A"), ["D", "C", "B", "A"])
			self.assertEqual(x.shortest_path("A", "D", ignore_priority=2), None)
			self.assertEqual(x.shortest_path("D", "A", ignore_priority=-2), ["D", "C", "B", "A"])
			cycles = set(tuple(y) for y in x.get_cycles())
			self.assertEqual(cycles, set([("D", "C", "B", "A"), ("C", "B", "A", "D"), ("B", "A", "D", "C"), \
				("A", "D", "C", "B")]))
			x.remove_edge("A", "B")
			self.assertEqual(x.get_cycles(), [])
			x.difference_update(["D"])
			self.assertEqual(x.all_nodes(), ["A", "B", "C"])
			portage.util.noiselimit = -2
			x.debug_print()
			portage.util.noiselimit = 0
Esempio n. 9
0
    def testDigraphTree(self):
        g = digraph()
        g.add("B", "A", -1)
        g.add("C", "A", 0)
        g.add("D", "C", 1)
        g.add("E", "C", 2)

        f = g.clone()
        for x in g, f:
            self.assertEqual(x.is_empty(), False)
            self.assertEqual(x.contains("A"), True)
            self.assertEqual(x.firstzero(), "B")
            self.assertRaises(KeyError, x.remove, "Z")
            x.delnode("Z")
            self.assertEqual(set(x), set(["A", "B", "C", "D", "E"]))
            self.assertEqual(x.get("A"), "A")
            self.assertEqual(x.get("A", "default"), "A")
            self.assertEqual(set(x.all_nodes()), set(["A", "B", "C", "D",
                                                      "E"]))
            self.assertEqual(set(x.leaf_nodes()), set(["B", "D", "E"]))
            self.assertEqual(set(x.leaf_nodes(ignore_priority=0)),
                             set(["A", "B", "D", "E"]))
            self.assertEqual(x.root_nodes(), ["A"])
            self.assertEqual(set(x.root_nodes(ignore_priority=0)),
                             set(["A", "B", "C"]))
            self.assertEqual(set(x.child_nodes("A")), set(["B", "C"]))
            self.assertEqual(x.child_nodes("A", ignore_priority=2), [])
            self.assertEqual(x.parent_nodes("B"), ["A"])
            self.assertEqual(x.parent_nodes("B", ignore_priority=-2), ["A"])
            self.assertEqual(x.parent_nodes("B", ignore_priority=-1), [])
            self.assertEqual(x.hasallzeros(), False)
            self.assertEqual(list(x.bfs("A")), [(None, "A"), ("A", "C"),
                                                ("A", "B"), ("C", "E"),
                                                ("C", "D")])
            self.assertEqual(x.shortest_path("A", "D"), ["A", "C", "D"])
            self.assertEqual(x.shortest_path("D", "A"), None)
            self.assertEqual(x.shortest_path("A", "D", ignore_priority=2),
                             None)
            cycles = set(tuple(y) for y in x.get_cycles())
            self.assertEqual(cycles, set())
            x.remove("D")
            self.assertEqual(set(x.all_nodes()), set(["A", "B", "C", "E"]))
            x.remove("C")
            self.assertEqual(set(x.all_nodes()), set(["A", "B", "E"]))
            portage.util.noiselimit = -2
            x.debug_print()
            portage.util.noiselimit = 0
            self.assertRaises(KeyError, x.remove_edge, "A", "E")
Esempio n. 10
0
File: sync.py Progetto: helb/portage
	def _init_graph(self):
		'''
		Graph relationships between repos and their masters.
		'''
		self._sync_graph = digraph()
		self._leaf_nodes = []
		self._repo_map = {}
		self._running_repos = set()
		selected_repo_names = frozenset(repo.name
			for repo in self._selected_repos)
		for repo in self._selected_repos:
			self._repo_map[repo.name] = repo
			self._sync_graph.add(repo.name, None)
			for master in repo.masters:
				if master.name in selected_repo_names:
					self._repo_map[master.name] = master
					self._sync_graph.add(master.name, repo.name)
		self._update_leaf_nodes()
Esempio n. 11
0
    def _init_graph(self):
        '''
		Graph relationships between repos and their masters.
		'''
        self._sync_graph = digraph()
        self._leaf_nodes = []
        self._repo_map = {}
        self._running_repos = set()
        selected_repo_names = frozenset(repo.name
                                        for repo in self._selected_repos)
        for repo in self._selected_repos:
            self._repo_map[repo.name] = repo
            self._sync_graph.add(repo.name, None)
            for master in repo.masters:
                if master.name in selected_repo_names:
                    self._repo_map[master.name] = master
                    self._sync_graph.add(master.name, repo.name)
        self._update_leaf_nodes()
Esempio n. 12
0
def _overlap_dnf(dep_struct):
    """
	Combine overlapping || groups using disjunctive normal form (DNF), in
	order to minimize the number of packages chosen to satisfy cases like
	"|| ( foo bar ) || ( bar baz )" as in bug #632026. Non-overlapping
	groups are excluded from the conversion, since DNF leads to exponential
	explosion of the formula.

	When dep_struct does not contain any overlapping groups, no DNF
	conversion will be performed, and dep_struct will be returned as-is.
	Callers can detect this case by checking if the returned object has
	the same identity as dep_struct. If the identity is different, then
	DNF conversion was performed.
	"""
    if not _contains_disjunction(dep_struct):
        return dep_struct

    # map atom.cp to disjunctions
    cp_map = collections.defaultdict(list)
    # graph atom.cp, with edges connecting atoms in the same disjunction
    overlap_graph = digraph()
    # map id(disjunction) to index in dep_struct, for deterministic output
    order_map = {}
    order_key = lambda x: order_map[id(x)]
    result = []
    for i, x in enumerate(dep_struct):
        if isinstance(x, list):
            assert x and x[0] == '||', \
             'Normalization error, nested conjunction found in %s' % (dep_struct,)
            order_map[id(x)] = i
            prev_cp = None
            for atom in _iter_flatten(x):
                if isinstance(atom, Atom) and not atom.blocker:
                    cp_map[atom.cp].append(x)
                    overlap_graph.add(atom.cp, parent=prev_cp)
                    prev_cp = atom.cp
            if prev_cp is None:  # only contains blockers
                result.append(x)
        else:
            result.append(x)

    # group together disjunctions having atom.cp overlap
    traversed = set()
    overlap = False
    for cp in overlap_graph:
        if cp in traversed:
            continue
        disjunctions = {}
        stack = [cp]
        while stack:
            cp = stack.pop()
            traversed.add(cp)
            for x in cp_map[cp]:
                disjunctions[id(x)] = x
            for other_cp in itertools.chain(overlap_graph.child_nodes(cp),
                                            overlap_graph.parent_nodes(cp)):
                if other_cp not in traversed:
                    stack.append(other_cp)

        if len(disjunctions) > 1:
            overlap = True
            # convert overlapping disjunctions to DNF
            result.extend(
                _dnf_convert(sorted(disjunctions.values(), key=order_key)))
        else:
            # pass through non-overlapping disjunctions
            result.append(disjunctions.popitem()[1])

    return result if overlap else dep_struct
Esempio n. 13
0
def _overlap_dnf(dep_struct):
	"""
	Combine overlapping || groups using disjunctive normal form (DNF), in
	order to minimize the number of packages chosen to satisfy cases like
	"|| ( foo bar ) || ( bar baz )" as in bug #632026. Non-overlapping
	groups are excluded from the conversion, since DNF leads to exponential
	explosion of the formula.

	When dep_struct does not contain any overlapping groups, no DNF
	conversion will be performed, and dep_struct will be returned as-is.
	Callers can detect this case by checking if the returned object has
	the same identity as dep_struct. If the identity is different, then
	DNF conversion was performed.
	"""
	if not _contains_disjunction(dep_struct):
		return dep_struct

	# map atom.cp to disjunctions
	cp_map = collections.defaultdict(list)
	# graph atom.cp, with edges connecting atoms in the same disjunction
	overlap_graph = digraph()
	# map id(disjunction) to index in dep_struct, for deterministic output
	order_map = {}
	order_key = lambda x: order_map[id(x)]
	result = []
	for i, x in enumerate(dep_struct):
		if isinstance(x, list):
			assert x and x[0] == '||', \
				'Normalization error, nested conjunction found in %s' % (dep_struct,)
			order_map[id(x)] = i
			prev_cp = None
			for atom in _iter_flatten(x):
				if isinstance(atom, Atom) and not atom.blocker:
					cp_map[atom.cp].append(x)
					overlap_graph.add(atom.cp, parent=prev_cp)
					prev_cp = atom.cp
			if prev_cp is None: # only contains blockers
				result.append(x)
		else:
			result.append(x)

	# group together disjunctions having atom.cp overlap
	traversed = set()
	overlap = False
	for cp in overlap_graph:
		if cp in traversed:
			continue
		disjunctions = {}
		stack = [cp]
		while stack:
			cp = stack.pop()
			traversed.add(cp)
			for x in cp_map[cp]:
				disjunctions[id(x)] = x
			for other_cp in itertools.chain(overlap_graph.child_nodes(cp),
				overlap_graph.parent_nodes(cp)):
				if other_cp not in traversed:
					stack.append(other_cp)

		if len(disjunctions) > 1:
			overlap = True
			# convert overlapping disjunctions to DNF
			result.extend(_dnf_convert(
				sorted(disjunctions.values(), key=order_key)))
		else:
			# pass through non-overlapping disjunctions
			result.append(disjunctions.popitem()[1])

	return result if overlap else dep_struct