mirror of
https://git.launchpad.net/~ubuntu-release/britney/+git/britney2-ubuntu
synced 2025-02-13 15:37:02 +00:00
Exploit equivalency to skip unneeded computation
Signed-off-by: Niels Thykier <niels@thykier.net>
This commit is contained in:
parent
6f24be9954
commit
ddf52bc7ca
70
britney.py
70
britney.py
@ -1950,28 +1950,50 @@ class Britney(object):
|
||||
sources = self.sources
|
||||
packages_t = self.binaries['testing']
|
||||
get_reverse_tree = partial(compute_reverse_tree, packages_t)
|
||||
inst_tester = self._inst_tester
|
||||
eqv_set = set()
|
||||
|
||||
# remove all binary packages (if the source already exists)
|
||||
if item.architecture == 'source' or not item.is_removal:
|
||||
if item.package in sources['testing']:
|
||||
source = sources['testing'][item.package]
|
||||
|
||||
_, bins, _ = self._compute_groups(item.package,
|
||||
item.suite,
|
||||
item.architecture,
|
||||
item.is_removal,
|
||||
removals=removals)
|
||||
updates, rms, _ = self._compute_groups(item.package,
|
||||
item.suite,
|
||||
item.architecture,
|
||||
item.is_removal,
|
||||
removals=removals)
|
||||
|
||||
eqv_table = {}
|
||||
|
||||
for binary, version, parch in rms:
|
||||
key = (binary, parch)
|
||||
eqv_table[key] = version
|
||||
|
||||
for p1 in updates:
|
||||
binary, _, parch = p1
|
||||
key = (binary, parch)
|
||||
old_version = eqv_table.get(key)
|
||||
if old_version is not None:
|
||||
p2 = (binary, old_version, parch)
|
||||
if inst_tester.are_equivalent(p1, p2):
|
||||
eqv_set.add(key)
|
||||
|
||||
# remove all the binaries which aren't being smooth updated
|
||||
for rm_tuple in bins:
|
||||
for rm_tuple in rms:
|
||||
binary, version, parch = rm_tuple
|
||||
p = binary + "/" + parch
|
||||
binaries_t_a, provides_t_a = packages_t[parch]
|
||||
pkey = (binary, parch)
|
||||
|
||||
pkg_data = binaries_t_a[binary]
|
||||
# save the old binary for undo
|
||||
undo['binaries'][p] = pkg_data
|
||||
# all the reverse dependencies are affected by the change
|
||||
affected.update(get_reverse_tree(binary, parch))
|
||||
if pkey not in eqv_set:
|
||||
# all the reverse dependencies are affected by
|
||||
# the change
|
||||
affected.update(get_reverse_tree(binary, parch))
|
||||
|
||||
# remove the provided virtual packages
|
||||
for j in pkg_data[PROVIDES]:
|
||||
key = j + "/" + parch
|
||||
@ -1982,7 +2004,7 @@ class Britney(object):
|
||||
del provides_t_a[j]
|
||||
# finally, remove the binary package
|
||||
del binaries_t_a[binary]
|
||||
self._inst_tester.remove_testing_binary(binary, version, parch)
|
||||
inst_tester.remove_testing_binary(binary, version, parch)
|
||||
# remove the source package
|
||||
if item.architecture == 'source':
|
||||
undo['sources'][item.package] = source
|
||||
@ -1999,7 +2021,7 @@ class Britney(object):
|
||||
affected.update(get_reverse_tree(item.package, item.architecture))
|
||||
version = binaries_t_a[item.package][VERSION]
|
||||
del binaries_t_a[item.package]
|
||||
self._inst_tester.remove_testing_binary(item.package, version, item.architecture)
|
||||
inst_tester.remove_testing_binary(item.package, version, item.architecture)
|
||||
|
||||
|
||||
# add the new binary packages (if we are not removing)
|
||||
@ -2011,8 +2033,11 @@ class Britney(object):
|
||||
if item.architecture not in ['source', parch]: continue
|
||||
key = (binary, parch)
|
||||
binaries_t_a, provides_t_a = packages_t[parch]
|
||||
equivalent_replacement = key in eqv_set
|
||||
|
||||
# obviously, added/modified packages are affected
|
||||
if key not in affected: affected.add(key)
|
||||
if not equivalent_replacement and key not in affected:
|
||||
affected.add(key)
|
||||
# if the binary already exists in testing, it is currently
|
||||
# built by another source package. we therefore remove the
|
||||
# version built by the other source package, after marking
|
||||
@ -2021,13 +2046,16 @@ class Britney(object):
|
||||
old_pkg_data = binaries_t_a[binary]
|
||||
# save the old binary package
|
||||
undo['binaries'][p] = old_pkg_data
|
||||
# all the reverse dependencies are affected by the change
|
||||
affected.update(get_reverse_tree(binary, parch))
|
||||
# all the reverse conflicts and their dependency tree are affected by the change
|
||||
for j in old_pkg_data[RCONFLICTS]:
|
||||
affected.update(get_reverse_tree(j, parch))
|
||||
if not equivalent_replacement:
|
||||
# all the reverse dependencies are affected by
|
||||
# the change
|
||||
affected.update(get_reverse_tree(binary, parch))
|
||||
# all the reverse conflicts and their
|
||||
# dependency tree are affected by the change
|
||||
for j in old_pkg_data[RCONFLICTS]:
|
||||
affected.update(get_reverse_tree(j, parch))
|
||||
old_version = old_pkg_data[VERSION]
|
||||
self._inst_tester.remove_testing_binary(binary, old_version, parch)
|
||||
inst_tester.remove_testing_binary(binary, old_version, parch)
|
||||
else:
|
||||
# the binary isn't in testing, but it may have been at
|
||||
# the start of the current hint and have been removed
|
||||
@ -2045,11 +2073,12 @@ class Britney(object):
|
||||
for rdep in tundo['binaries'][p][RDEPENDS]:
|
||||
if rdep in binaries_t_a and rdep not in source[BINARIES]:
|
||||
affected.update(get_reverse_tree(rdep, parch))
|
||||
|
||||
# add/update the binary package from the source suite
|
||||
new_pkg_data = packages_s[parch][0][binary]
|
||||
new_version = new_pkg_data[VERSION]
|
||||
binaries_t_a[binary] = new_pkg_data
|
||||
self._inst_tester.add_testing_binary(binary, new_version, parch)
|
||||
inst_tester.add_testing_binary(binary, new_version, parch)
|
||||
# register new provided packages
|
||||
for j in new_pkg_data[PROVIDES]:
|
||||
key = j + "/" + parch
|
||||
@ -2059,8 +2088,9 @@ class Britney(object):
|
||||
elif key not in undo['virtual']:
|
||||
undo['virtual'][key] = provides_t_a[j][:]
|
||||
provides_t_a[j].append(binary)
|
||||
# all the reverse dependencies are affected by the change
|
||||
affected.update(get_reverse_tree(binary, parch))
|
||||
if not equivalent_replacement:
|
||||
# all the reverse dependencies are affected by the change
|
||||
affected.update(get_reverse_tree(binary, parch))
|
||||
|
||||
# register reverse dependencies and conflicts for the new binary packages
|
||||
if item.architecture == 'source':
|
||||
|
@ -391,14 +391,7 @@ class InstallabilityTesterBuilder(object):
|
||||
for pkg_list in find_eqv_table.itervalues():
|
||||
if len(pkg_list) < 2:
|
||||
continue
|
||||
if (len(pkg_list) == 2 and pkg_list[0][0] == pkg_list[1][0]
|
||||
and pkg_list[0][2] == pkg_list[1][2]):
|
||||
# This is a (most likely) common and boring case. It
|
||||
# is when pkgA depends on pkgB and is satisfied with
|
||||
# any version available. However, at most one version
|
||||
# of pkgB will be available in testing, so other
|
||||
# filters will make this case redundant.
|
||||
continue
|
||||
|
||||
eqv_set = frozenset(pkg_list)
|
||||
for pkg in pkg_list:
|
||||
eqv_table[pkg] = eqv_set
|
||||
|
@ -98,6 +98,17 @@ class InstallabilityTester(object):
|
||||
cbroken |= eqv_set
|
||||
|
||||
|
||||
def are_equivalent(self, p1, p2):
|
||||
"""Test if p1 and p2 are equivalent
|
||||
|
||||
Returns True if p1 and p2 have the same "signature" in
|
||||
the package dependency graph (i.e. relations can not tell
|
||||
them appart sematically except for their name)
|
||||
"""
|
||||
eqv_table = self._eqv_table
|
||||
return p1 in eqv_table and p2 in eqv_table[p1]
|
||||
|
||||
|
||||
def add_testing_binary(self, pkg_name, pkg_version, pkg_arch):
|
||||
"""Add a binary package to "testing"
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user