britney: Optimise original auto-hinter duplication handling

Britney is now smart enough to produce the same result from hints
regardless of the order of the items in the hint.  With this in mind,
we can have the original auto-hinter produce hints as sets and filter
out duplicates as we produce them.

Note that the hints are sorted to produce deterministic output (to
make it easier to compare the hints between runs and changes).

Signed-off-by: Niels Thykier <niels@thykier.net>
debian
Niels Thykier 10 years ago
parent 0b9006c36b
commit 72eb6af711

@ -2849,16 +2849,21 @@ class Britney(object):
# loop on them # loop on them
candidates = [] candidates = []
mincands = [] mincands = []
seen_hints = set()
for e in excuses: for e in excuses:
excuse = excuses[e] excuse = excuses[e]
if e in sources_t and sources_t[e][VERSION] == excuse.ver[1]: if e in sources_t and sources_t[e][VERSION] == excuse.ver[1]:
continue continue
if excuse.deps: if excuse.deps:
hint = find_related(e, {}, True) hint = find_related(e, {}, True)
if isinstance(hint, dict) and e in hint and hint not in candidates: if isinstance(hint, dict) and e in hint:
candidates.append(hint.items()) h = frozenset(hint.items())
if h not in seen_hints:
candidates.append(h)
seen_hints.add(h)
else: else:
items = [ (e, excuse.ver[1]) ] items = [ (e, excuse.ver[1]) ]
orig_size = 1
looped = False looped = False
for item, ver in items: for item, ver in items:
# excuses which depend on "item" or are depended on by it # excuses which depend on "item" or are depended on by it
@ -2866,39 +2871,21 @@ class Britney(object):
(item in excuses[x].deps or x in excuses[item].deps) \ (item in excuses[x].deps or x in excuses[item].deps) \
and (x, excuses[x].ver[1]) not in items ) and (x, excuses[x].ver[1]) not in items )
if not looped and len(items) > 1: if not looped and len(items) > 1:
mincands.append(items[:]) orig_size = len(items)
h = frozenset(items)
if h not in seen_hints:
mincands.append(h)
seen_hints.add(h)
looped = True looped = True
if (len(items) > 1 and len(items) != len(mincands[-1]) and if len(items) != orig_size:
frozenset(items) != frozenset(mincands[-1])): h = frozenset(items)
candidates.append(items) if h != mincands[-1] and h not in seen_hints:
candidates.append(h)
seen_hints.add(h)
for l in [ candidates, mincands ]: for l in [ candidates, mincands ]:
to_skip = set() for hint in l:
for i in range(len(l)): self.do_hint("easy", "autohinter", [ MigrationItem("%s/%s" % (x[0], x[1])) for x in sorted(hint) ])
if i in to_skip:
continue
l_i = None
for j in range(i+1, len(l)):
if j in to_skip:
# we already know this list isn't interesting
continue
if l_i is None:
l_i = frozenset(l[i])
l_j = frozenset(l[j])
if l_i >= l_j:
# j is a subset of i; ignore it
to_skip.add(j)
elif l_i < l_j:
# i is a subset of j; ignore it and the rest of the
# "i" series.
# NB: We use < and not <= because the "==" case is
# already covered above
to_skip.add(i)
break
for i in range(len(l)):
if i not in to_skip:
self.do_hint("easy", "autohinter", [ MigrationItem("%s/%s" % (x[0], x[1])) for x in l[i] ])
def nuninst_arch_report(self, nuninst, arch): def nuninst_arch_report(self, nuninst, arch):
"""Print a report of uninstallable packages for one architecture.""" """Print a report of uninstallable packages for one architecture."""

Loading…
Cancel
Save