On 07/14/2018 09:42 PM, Brian Dolbec wrote:
> On Sat, 14 Jul 2018 21:05:39 -0700
> Zac Medico <zmed...@gentoo.org> wrote:
> 
>> Make portdbapi.cp_list return _pkg_str instances that have a 'repo'
>> attribute (bindbapi.cp_list already does this), with results
>> in ascending order by (pkg.version, repo.priority). Optimize
>> portdbapi.findname2 to use the 'repo' attribute to enable cached
>> results for files previously found by the portdbapi.cp_list
>> method, avoiding filesystem access when possible. Optimize the
>> depgraph._iter_match_pkgs_atom method by elimination of the repo
>> loop, since portdbapi.cp_list now returns separate items when the
>> same package version is found in multiple repos.
>>
>> Bug: https://bugs.gentoo.org/650814
>> ---
>>  pym/_emerge/depgraph.py       | 12 +++---------
>>  pym/portage/dbapi/porttree.py | 41
>> +++++++++++++++++++++++++++++------------ 2 files changed, 32
>> insertions(+), 21 deletions(-)
>>
>> diff --git a/pym/_emerge/depgraph.py b/pym/_emerge/depgraph.py
>> index 42857c1a5..b63d4f242 100644
>> --- a/pym/_emerge/depgraph.py
>> +++ b/pym/_emerge/depgraph.py
>> @@ -5613,10 +5613,6 @@ class depgraph(object):
>>              if cp_list:
>>                      atom_set =
>> InternalPackageSet(initial_atoms=(atom,), allow_repo=True)
>> -                    if atom.repo is None and hasattr(db,
>> "getRepositories"):
>> -                            repo_list =
>> db.getRepositories(catpkg=atom_exp.cp)
>> -                    else:
>> -                            repo_list = [atom.repo]
>>  
>>                      # descending order
>>                      cp_list.reverse()
>> @@ -5624,13 +5620,11 @@ class depgraph(object):
>>                              # Call match_from_list on one cpv at
>> a time, in order # to avoid unnecessary match_from_list comparisons on
>>                              # versions that are never yielded
>> from this method.
>> -                            if not match_from_list(atom_exp,
>> [cpv]):
>> -                                    continue
>> -                            for repo in repo_list:
>> -
>> +                            if match_from_list(atom_exp, [cpv]):
>>                                      try:
>>                                              pkg = self._pkg(cpv,
>> pkg_type, root_config,
>> -
>> installed=installed, onlydeps=onlydeps, myrepo=repo)
>> +
>> installed=installed, onlydeps=onlydeps,
>> +
>> myrepo=getattr(cpv, 'repo', None)) except
>> portage.exception.PackageNotFound: pass
>>                                      else:
>> diff --git a/pym/portage/dbapi/porttree.py
>> b/pym/portage/dbapi/porttree.py index 3e36024ff..f6076ee2b 100644
>> --- a/pym/portage/dbapi/porttree.py
>> +++ b/pym/portage/dbapi/porttree.py
>> @@ -459,6 +459,9 @@ class portdbapi(dbapi):
>>                      mytree = self.treemap.get(myrepo)
>>                      if mytree is None:
>>                              return (None, 0)
>> +            elif mytree is not None:
>> +                    # myrepo enables cached results when
>> available
>> +                    myrepo =
>> self.repositories.location_map.get(mytree) 
>>              mysplit = mycpv.split("/")
>>              psplit = pkgsplit(mysplit[1])
>> @@ -495,6 +498,14 @@ class portdbapi(dbapi):
>>              relative_path = mysplit[0] + _os.sep + psplit[0] +
>> _os.sep + \ mysplit[1] + ".ebuild"
>>  
>> +            # There is no need to access the filesystem when the
>> package
>> +            # comes from this db and the package repo attribute
>> corresponds
>> +            # to the desired repo, since the file was previously
>> found by
>> +            # the cp_list method.
>> +            if (myrepo is not None and myrepo == getattr(mycpv,
>> 'repo', None)
>> +                    and self is getattr(mycpv, '_db', None)):
>> +                    return (mytree + _os.sep + relative_path,
>> mytree) +
>>              for x in mytrees:
>>                      filename = x + _os.sep + relative_path
>>                      if _os.access(_unicode_encode(filename,
>> @@ -950,18 +961,23 @@ class portdbapi(dbapi):
>>                              return cachelist[:]
>>              mysplit = mycp.split("/")
>>              invalid_category = mysplit[0] not in self._categories
>> -            d={}
>> +            # Process repos in ascending order by repo.priority,
>> so that
>> +            # stable sort by version produces results ordered by
>> +            # (pkg.version, repo.priority).
>>              if mytree is not None:
>>                      if isinstance(mytree, basestring):
>> -                            mytrees = [mytree]
>> +                            repos =
>> [self.repositories.get_repo_for_location(mytree)] else:
>>                              # assume it's iterable
>> -                            mytrees = mytree
>> +                            repos =
>> [self.repositories.get_repo_for_location(location)
>> +                                    for location in mytree]
>>              elif self._better_cache is None:
>> -                    mytrees = self.porttrees
>> +                    repos = list(self.repositories)
>>              else:
>> -                    mytrees = [repo.location for repo in
>> self._better_cache[mycp]]
>> -            for oroot in mytrees:
>> +                    repos = reversed(self._better_cache[mycp])
>> +            mylist = []
>> +            for repo in repos:
>> +                    oroot = repo.location
>>                      try:
>>                              file_list =
>> os.listdir(os.path.join(oroot, mycp)) except OSError:
>> @@ -986,16 +1002,17 @@ class portdbapi(dbapi):
>>                                              writemsg(_("\nInvalid
>> ebuild version: %s\n") % \ os.path.join(oroot, mycp, x),
>> noiselevel=-1) continue
>> -
>> d[_pkg_str(mysplit[0]+"/"+pf, db=self)] = None
>> -            if invalid_category and d:
>> +
>> mylist.append(_pkg_str(mysplit[0]+"/"+pf, db=self, repo=repo.name))
>> +            if invalid_category and mylist:
>>                      writemsg(_("\n!!! '%s' has a category that
>> is not listed in " \ "%setc/portage/categories\n") % \
>>                              (mycp,
>> self.settings["PORTAGE_CONFIGROOT"]), noiselevel=-1) mylist = []
>> -            else:
>> -                    mylist = list(d)
>> -            # Always sort in ascending order here since it's
>> handy
>> -            # and the result can be easily cached and reused.
>> +            # Always sort in ascending order here since it's
>> handy and
>> +            # the result can be easily cached and reused. Since
>> mylist
>> +            # is initially in ascending order by repo.priority,
>> stable
>> +            # sort by version produces results in ascending
>> order by
>> +            # (pkg.version, repo.priority).
>>              self._cpv_sort_ascending(mylist)
>>              if self.frozen and mytree is None:
>>                      cachelist = mylist[:]
> 
> looks fine

Thanks, merged:

https://gitweb.gentoo.org/proj/portage.git/commit/?id=27eeeb6e4fc8e68efa003b2db5bbd8cc4afe336a

-- 
Thanks,
Zac

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to