mirror of
https://git.launchpad.net/~ubuntu-release/britney/+git/britney2-ubuntu
synced 2025-02-23 11:21:13 +00:00
BinaryPackageUniverse: Provde equivalent_packages
Signed-off-by: Niels Thykier <niels@thykier.net>
This commit is contained in:
parent
ef813bf0d8
commit
0eb8b5a201
@ -308,11 +308,12 @@ class InstallabilityTesterBuilder(object):
|
||||
|
||||
relations, eqv_table = self._build_eqv_packages_table(package_table, reverse_package_table)
|
||||
|
||||
universe = BinaryPackageUniverse(relations, intern_set(self._essentials), intern_set(broken))
|
||||
universe = BinaryPackageUniverse(relations,
|
||||
intern_set(self._essentials),
|
||||
intern_set(broken),
|
||||
intern_set(eqv_table))
|
||||
|
||||
solver = InstallabilityTester(universe,
|
||||
self._testing,
|
||||
eqv_table)
|
||||
solver = InstallabilityTester(universe, self._testing)
|
||||
|
||||
return universe, solver
|
||||
|
||||
|
@ -22,7 +22,7 @@ from britney2.utils import iter_except
|
||||
|
||||
class InstallabilityTester(object):
|
||||
|
||||
def __init__(self, universe, testing, eqv_table):
|
||||
def __init__(self, universe, testing):
|
||||
"""Create a new installability tester
|
||||
|
||||
universe is a BinaryPackageUniverse
|
||||
@ -37,7 +37,6 @@ class InstallabilityTester(object):
|
||||
|
||||
self._universe = universe
|
||||
self._testing = testing
|
||||
self._eqv_table = eqv_table
|
||||
self._stats = InstallabilityStats()
|
||||
logger_name = ".".join((self.__class__.__module__, self.__class__.__name__))
|
||||
self.logger = logging.getLogger(logger_name)
|
||||
@ -67,18 +66,18 @@ class InstallabilityTester(object):
|
||||
in testing.
|
||||
"""
|
||||
|
||||
universe = self._universe
|
||||
check_inst = self._check_inst
|
||||
cbroken = self._cache_broken
|
||||
cache_inst = self._cache_inst
|
||||
eqv_table = self._eqv_table
|
||||
testing = self._testing
|
||||
tcopy = [x for x in testing]
|
||||
for t in filterfalse(cache_inst.__contains__, tcopy):
|
||||
if t in cbroken:
|
||||
continue
|
||||
res = check_inst(t)
|
||||
if t in eqv_table:
|
||||
eqv = (x for x in eqv_table[t] if x in testing)
|
||||
if t in universe.equivalent_packages:
|
||||
eqv = (x for x in universe.packages_equivalent_to(t) if x in testing)
|
||||
if res:
|
||||
cache_inst.update(eqv)
|
||||
else:
|
||||
@ -198,7 +197,6 @@ class InstallabilityTester(object):
|
||||
universe = self._universe
|
||||
testing = self._testing
|
||||
cbroken = self._cache_broken
|
||||
eqv_table = self._eqv_table
|
||||
|
||||
# Our installability verdict - start with "yes" and change if
|
||||
# prove otherwise.
|
||||
@ -242,7 +240,7 @@ class InstallabilityTester(object):
|
||||
|
||||
# curry check_loop
|
||||
check_loop = partial(self._check_loop, universe, testing,
|
||||
eqv_table, stats, musts, never, cbroken)
|
||||
stats, musts, never, cbroken)
|
||||
|
||||
# Useful things to remember:
|
||||
#
|
||||
@ -340,7 +338,6 @@ class InstallabilityTester(object):
|
||||
def resolve_choices(self, check, musts, never, choices):
|
||||
universe = self._universe
|
||||
testing = self._testing
|
||||
eqv_table = self._eqv_table
|
||||
stats = self._stats
|
||||
cbroken = self._cache_broken
|
||||
|
||||
@ -357,7 +354,7 @@ class InstallabilityTester(object):
|
||||
check_tmp = [p]
|
||||
# _check_loop assumes that "musts" is up to date
|
||||
musts_copy.add(p)
|
||||
if not self._check_loop(universe, testing, eqv_table,
|
||||
if not self._check_loop(universe, testing,
|
||||
stats, musts_copy, never_tmp,
|
||||
cbroken, choices_tmp,
|
||||
check_tmp):
|
||||
@ -409,7 +406,7 @@ class InstallabilityTester(object):
|
||||
stats.backtrace_last_option += 1
|
||||
return False
|
||||
|
||||
def _check_loop(self, universe, testing, eqv_table, stats, musts, never,
|
||||
def _check_loop(self, universe, testing, stats, musts, never,
|
||||
cbroken, choices, check, len=len,
|
||||
frozenset=frozenset):
|
||||
"""Finds all guaranteed dependencies via "check".
|
||||
@ -468,7 +465,7 @@ class InstallabilityTester(object):
|
||||
check.extend(candidates)
|
||||
musts.update(candidates)
|
||||
else:
|
||||
possible_eqv = set(x for x in candidates if x in eqv_table)
|
||||
possible_eqv = set(x for x in candidates if x in universe.equivalent_packages)
|
||||
if len(possible_eqv) > 1:
|
||||
# Exploit equivalency to reduce the number of
|
||||
# candidates if possible. Basically, this
|
||||
@ -484,7 +481,7 @@ class InstallabilityTester(object):
|
||||
|
||||
for chosen in iter_except(possible_eqv.pop, KeyError):
|
||||
new_cand.add(chosen)
|
||||
possible_eqv -= eqv_table[chosen]
|
||||
possible_eqv -= universe.packages_equivalent_to(chosen)
|
||||
stats.eqv_table_total_number_of_alternatives_eliminated += len(candidates) - len(new_cand)
|
||||
if len(new_cand) == 1:
|
||||
check.extend(new_cand)
|
||||
@ -507,7 +504,6 @@ class InstallabilityTester(object):
|
||||
# The minimal essential set cache is not present -
|
||||
# compute it now.
|
||||
testing = self._testing
|
||||
eqv_table = self._eqv_table
|
||||
cbroken = self._cache_broken
|
||||
universe = self._universe
|
||||
stats = self._stats
|
||||
@ -519,7 +515,7 @@ class InstallabilityTester(object):
|
||||
not_satisfied = partial(filter, start.isdisjoint)
|
||||
|
||||
while ess_base:
|
||||
self._check_loop(universe, testing, eqv_table, stats,
|
||||
self._check_loop(universe, testing, stats,
|
||||
start, ess_never, cbroken,
|
||||
ess_choices, ess_base)
|
||||
if ess_choices:
|
||||
@ -548,7 +544,6 @@ class InstallabilityTester(object):
|
||||
|
||||
def compute_stats(self):
|
||||
universe = self._universe
|
||||
eqv_table = self._eqv_table
|
||||
graph_stats = defaultdict(ArchStats)
|
||||
seen_eqv = defaultdict(set)
|
||||
|
||||
@ -559,8 +554,8 @@ class InstallabilityTester(object):
|
||||
|
||||
arch_stats.nodes += 1
|
||||
|
||||
if pkg in eqv_table and pkg not in seen_eqv[pkg_arch]:
|
||||
eqv = [e for e in eqv_table[pkg] if e.architecture == pkg_arch]
|
||||
if pkg in universe.equivalent_packages and pkg not in seen_eqv[pkg_arch]:
|
||||
eqv = [e for e in universe.packages_equivalent_to(pkg) if e.architecture == pkg_arch]
|
||||
arch_stats.eqv_nodes += len(eqv)
|
||||
|
||||
arch_stats.add_dep_edges(relations.dependencies)
|
||||
|
@ -51,10 +51,11 @@ class BinaryPackageUniverse(object):
|
||||
of a "minor" lie about the "broken" packages.
|
||||
"""
|
||||
|
||||
def __init__(self, relations, essential_packages, broken_packages):
|
||||
def __init__(self, relations, essential_packages, broken_packages, equivalent_packages):
|
||||
self._relations = relations
|
||||
self._essential_packages = essential_packages
|
||||
self._broken_packages = broken_packages
|
||||
self._equivalent_packages = equivalent_packages
|
||||
|
||||
def dependencies_of(self, pkg_id):
|
||||
"""Returns the set of dependencies of a given package
|
||||
@ -141,6 +142,17 @@ class BinaryPackageUniverse(object):
|
||||
"""
|
||||
return self._broken_packages
|
||||
|
||||
@property
|
||||
def equivalent_packages(self):
|
||||
"""A frozenset of all binary packages that are equivalent to at least one other package
|
||||
|
||||
The binary packages in this set has the property that "universe.packages_equivalent_to(pkg_id)"
|
||||
will return a set of at least 2 or more elements for each of them.
|
||||
|
||||
:return A frozenset of BinaryPackageIds of packages that are equivalent to other packages.
|
||||
"""
|
||||
return self._equivalent_packages
|
||||
|
||||
def __contains__(self, pkg_id):
|
||||
return pkg_id in self._relations
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user