From 93558b6bc99c00b2fd25a3f5231cb46d5d658ecf Mon Sep 17 00:00:00 2001 From: Karsten Hopp Date: May 22 2018 08:50:05 +0000 Subject: [PATCH 1/2] Build an in-memory cache for whatprovides, issue #51 --- diff --git a/src/_fedmod/_depchase.py b/src/_fedmod/_depchase.py index dc69031..ef73b53 100644 --- a/src/_fedmod/_depchase.py +++ b/src/_fedmod/_depchase.py @@ -2,6 +2,7 @@ import collections import configparser +import functools import itertools import logging import os @@ -78,26 +79,32 @@ def _iterate_all_requires(package): for dep in package.lookup_deparray(solv.SOLVABLE_REQUIRES, -1): # requires yield dep + +@functools.lru_cache(maxsize=None) +def whatprovides(pool, dep): + sel = pool.matchdepid(dep, solv.Selection.SELECTION_PROVIDES, solv.SOLVABLE_PROVIDES) + if sel.isempty() and str(dep).startswith("/"): + # TODO: use Dataiterator for getting filelist + sel = pool.select(str(dep), solv.Selection.SELECTION_FILELIST) + return set(sel.solvables()) + + def _get_dependency_details(pool, transaction): candq = transaction.newpackages() result = {} for p in candq: pkg_details = {} for dep in _iterate_all_requires(p): - matches = set(s for s in candq if s.matchesdep(solv.SOLVABLE_PROVIDES, dep)) - if not matches and str(dep).startswith("/"): - # Append provides by files - # TODO: use Dataiterator for getting filelist - matches = set(s for s in pool.select(str(dep), solv.Selection.SELECTION_FILELIST).solvables() if s in candq) + matches = whatprovides(pool, dep) # It was possible to resolve set, so something is wrong here assert matches + matches = set(s for s in matches if s in candq) # While multiple packages providing the same thing is rare, it's # the kind of duplication we want fedmod to be able to help find. # So we always return a list here, even though it will normally # only have one entry in it pkg_details[str(dep)] = sorted(str(m) for m in matches) result[str(p)] = pkg_details - return result def print_transaction(details): From d212dd2241ed343c35cd3b908df6f49e62db0ae9 Mon Sep 17 00:00:00 2001 From: Karsten Hopp Date: May 23 2018 12:46:17 +0000 Subject: [PATCH 2/2] use local cache (otaylor) --- diff --git a/src/_fedmod/_depchase.py b/src/_fedmod/_depchase.py index ef73b53..420ee2d 100644 --- a/src/_fedmod/_depchase.py +++ b/src/_fedmod/_depchase.py @@ -2,7 +2,6 @@ import collections import configparser -import functools import itertools import logging import os @@ -79,32 +78,31 @@ def _iterate_all_requires(package): for dep in package.lookup_deparray(solv.SOLVABLE_REQUIRES, -1): # requires yield dep - -@functools.lru_cache(maxsize=None) -def whatprovides(pool, dep): - sel = pool.matchdepid(dep, solv.Selection.SELECTION_PROVIDES, solv.SOLVABLE_PROVIDES) - if sel.isempty() and str(dep).startswith("/"): - # TODO: use Dataiterator for getting filelist - sel = pool.select(str(dep), solv.Selection.SELECTION_FILELIST) - return set(sel.solvables()) - - def _get_dependency_details(pool, transaction): candq = transaction.newpackages() result = {} + cache = {} for p in candq: pkg_details = {} for dep in _iterate_all_requires(p): - matches = whatprovides(pool, dep) - # It was possible to resolve set, so something is wrong here - assert matches - matches = set(s for s in matches if s in candq) - # While multiple packages providing the same thing is rare, it's - # the kind of duplication we want fedmod to be able to help find. - # So we always return a list here, even though it will normally - # only have one entry in it - pkg_details[str(dep)] = sorted(str(m) for m in matches) + if dep in cache: + matches = cache[dep] + else: + matches = set(s for s in candq if s.matchesdep(solv.SOLVABLE_PROVIDES, dep)) + if not matches and str(dep).startswith("/"): + # Append provides by files + # TODO: use Dataiterator for getting filelist + matches = set(s for s in pool.select(str(dep), solv.Selection.SELECTION_FILELIST).solvables() if s in candq) + # It was possible to resolve set, so something is wrong here + assert matches + cache[dep] = matches + # While multiple packages providing the same thing is rare, it's + # the kind of duplication we want fedmod to be able to help find. + # So we always return a list here, even though it will normally + # only have one entry in it + pkg_details[str(dep)] = sorted(str(m) for m in matches) result[str(p)] = pkg_details + return result def print_transaction(details):