From 754688851a5bf6a61065016d33dd9d0374ea1d72 Mon Sep 17 00:00:00 2001 From: Niels Thykier Date: Tue, 2 Jun 2015 21:33:52 +0200 Subject: [PATCH] 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 --- britney.py | 51 +++++++++++++++++++-------------------------------- 1 file changed, 19 insertions(+), 32 deletions(-) diff --git a/britney.py b/britney.py index 1a07f50..9ad4333 100755 --- a/britney.py +++ b/britney.py @@ -2849,16 +2849,21 @@ class Britney(object): # loop on them candidates = [] mincands = [] + seen_hints = set() for e in excuses: excuse = excuses[e] if e in sources_t and sources_t[e][VERSION] == excuse.ver[1]: continue if excuse.deps: hint = find_related(e, {}, True) - if isinstance(hint, dict) and e in hint and hint not in candidates: - candidates.append(hint.items()) + if isinstance(hint, dict) and e in hint: + h = frozenset(hint.items()) + if h not in seen_hints: + candidates.append(h) + seen_hints.add(h) else: items = [ (e, excuse.ver[1]) ] + orig_size = 1 looped = False for item, ver in items: # 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) \ and (x, excuses[x].ver[1]) not in items ) 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 - if (len(items) > 1 and len(items) != len(mincands[-1]) and - frozenset(items) != frozenset(mincands[-1])): - candidates.append(items) + if len(items) != orig_size: + h = frozenset(items) + if h != mincands[-1] and h not in seen_hints: + candidates.append(h) + seen_hints.add(h) for l in [ candidates, mincands ]: - to_skip = set() - for i in range(len(l)): - 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] ]) - + for hint in l: + self.do_hint("easy", "autohinter", [ MigrationItem("%s/%s" % (x[0], x[1])) for x in sorted(hint) ]) def nuninst_arch_report(self, nuninst, arch): """Print a report of uninstallable packages for one architecture."""