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