From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: <gentoo-commits+bounces-753964-garchives=archives.gentoo.org@lists.gentoo.org> Received: from lists.gentoo.org (pigeon.gentoo.org [208.92.234.80]) by finch.gentoo.org (Postfix) with ESMTP id 427F11389E2 for <garchives@archives.gentoo.org>; Sun, 7 Dec 2014 23:14:08 +0000 (UTC) Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id 387FDE0C69; Sun, 7 Dec 2014 23:14:06 +0000 (UTC) Received: from smtp.gentoo.org (smtp.gentoo.org [140.211.166.183]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by pigeon.gentoo.org (Postfix) with ESMTPS id 523DAE0C4A for <gentoo-commits@lists.gentoo.org>; Sun, 7 Dec 2014 23:14:05 +0000 (UTC) Received: from oystercatcher.gentoo.org (oystercatcher.gentoo.org [148.251.78.52]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by smtp.gentoo.org (Postfix) with ESMTPS id 5DFC6340542 for <gentoo-commits@lists.gentoo.org>; Sun, 7 Dec 2014 23:14:04 +0000 (UTC) Received: from localhost.localdomain (localhost [127.0.0.1]) by oystercatcher.gentoo.org (Postfix) with ESMTP id 8919EBD57 for <gentoo-commits@lists.gentoo.org>; Sun, 7 Dec 2014 23:14:02 +0000 (UTC) From: "Zac Medico" <zmedico@gentoo.org> To: gentoo-commits@lists.gentoo.org Content-Transfer-Encoding: 8bit Content-type: text/plain; charset=UTF-8 Reply-To: gentoo-dev@lists.gentoo.org, "Zac Medico" <zmedico@gentoo.org> Message-ID: <1417993848.5424b91133b3b155b0e6ddc08fb46ba301d971f8.zmedico@gentoo> Subject: [gentoo-commits] proj/portage:master commit in: pym/portage/dbapi/ X-VCS-Repository: proj/portage X-VCS-Files: pym/portage/dbapi/IndexedVardb.py pym/portage/dbapi/vartree.py X-VCS-Directories: pym/portage/dbapi/ X-VCS-Committer: zmedico X-VCS-Committer-Name: Zac Medico X-VCS-Revision: 5424b91133b3b155b0e6ddc08fb46ba301d971f8 X-VCS-Branch: master Date: Sun, 7 Dec 2014 23:14:02 +0000 (UTC) Precedence: bulk List-Post: <mailto:gentoo-commits@lists.gentoo.org> List-Help: <mailto:gentoo-commits+help@lists.gentoo.org> List-Unsubscribe: <mailto:gentoo-commits+unsubscribe@lists.gentoo.org> List-Subscribe: <mailto:gentoo-commits+subscribe@lists.gentoo.org> List-Id: Gentoo Linux mail <gentoo-commits.gentoo.org> X-BeenThere: gentoo-commits@lists.gentoo.org X-Archives-Salt: c219c45e-2fea-48ae-9b13-611298d8aaed X-Archives-Hash: e1a6fb95667ad301f56f97fee8f31c59 commit: 5424b91133b3b155b0e6ddc08fb46ba301d971f8 Author: Zac Medico <zmedico <AT> gentoo <DOT> org> AuthorDate: Sat Nov 1 15:06:01 2014 +0000 Commit: Zac Medico <zmedico <AT> gentoo <DOT> org> CommitDate: Sun Dec 7 23:10:48 2014 +0000 URL: http://sources.gentoo.org/gitweb/?p=proj/portage.git;a=commit;h=5424b911 Add IndexedVardb class. Searching of installed packages is optimized to take advantage of vardbdbapi._aux_cache, which is backed by vdb_metadata.pickle. This class only implements a subset of vardbapi functionality that is useful for searching incrementally. For this reason, the cp_all method returns an ordered iterator instead of a list, so that search results can be displayed incrementally. X-Gentoo-Bug: 525718 X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=525718 --- pym/portage/dbapi/IndexedVardb.py | 94 +++++++++++++++++++++++++++++++++++++++ pym/portage/dbapi/vartree.py | 23 +++++++--- 2 files changed, 110 insertions(+), 7 deletions(-) diff --git a/pym/portage/dbapi/IndexedVardb.py b/pym/portage/dbapi/IndexedVardb.py new file mode 100644 index 0000000..424defc --- /dev/null +++ b/pym/portage/dbapi/IndexedVardb.py @@ -0,0 +1,94 @@ +# Copyright 2014 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +import portage +from portage.dep import Atom +from portage.versions import _pkg_str + +class IndexedVardb(object): + """ + A vardbapi interface that sacrifices validation in order to + improve performance. It takes advantage of vardbdbapi._aux_cache, + which is backed by vdb_metadata.pickle. Since _aux_cache is + not updated for every single merge/unmerge (see + _aux_cache_threshold), the list of packages is obtained directly + from the real vardbapi instance. If a package is missing from + _aux_cache, then its metadata is obtained using the normal + (validated) vardbapi.aux_get method. + + For performance reasons, the match method only supports package + name and version constraints. + """ + + # Match returns unordered results. + match_unordered = True + + _copy_attrs = ('cpv_exists', + '_aux_cache_keys', '_cpv_sort_ascending') + + def __init__(self, vardb): + self._vardb = vardb + + for k in self._copy_attrs: + setattr(self, k, getattr(vardb, k)) + + self._cp_map = None + + def cp_all(self): + """ + Returns an ordered iterator instead of a list, so that search + results can be displayed incrementally. + """ + if self._cp_map is not None: + return iter(sorted(self._cp_map)) + + return self._iter_cp_all() + + def _iter_cp_all(self): + self._cp_map = cp_map = {} + previous_cp = None + for cpv in self._vardb._iter_cpv_all(sort = True): + cp = portage.cpv_getkey(cpv) + if cp is not None: + cp_list = cp_map.get(cp) + if cp_list is None: + cp_list = [] + cp_map[cp] = cp_list + cp_list.append(cpv) + if previous_cp is not None and \ + previous_cp != cp: + yield previous_cp + previous_cp = cp + + if previous_cp is not None: + yield previous_cp + + def match(self, atom): + """ + For performance reasons, only package name and version + constraints are supported, and the returned list is + unordered. + """ + if not isinstance(atom, Atom): + atom = Atom(atom) + cp_list = self._cp_map.get(atom.cp) + if cp_list is None: + return [] + + if atom == atom.cp: + return cp_list[:] + else: + return portage.match_from_list(atom, cp_list) + + def aux_get(self, cpv, attrs, myrepo=None): + pkg_data = self._vardb._aux_cache["packages"].get(cpv) + if not isinstance(pkg_data, tuple) or \ + len(pkg_data) != 2 or \ + not isinstance(pkg_data[1], dict): + pkg_data = None + if pkg_data is None: + # It may be missing from _aux_cache due to + # _aux_cache_threshold. + return self._vardb.aux_get(cpv, attrs) + metadata = pkg_data[1] + return [metadata.get(k, "") for k in attrs] diff --git a/pym/portage/dbapi/vartree.py b/pym/portage/dbapi/vartree.py index 4840492..9c8b276 100644 --- a/pym/portage/dbapi/vartree.py +++ b/pym/portage/dbapi/vartree.py @@ -435,6 +435,9 @@ class vardbapi(dbapi): (generally this is only necessary in critical sections that involve merge or unmerge of packages). """ + return list(self._iter_cpv_all(use_cache=use_cache)) + + def _iter_cpv_all(self, use_cache=True, sort=False): returnme = [] basepath = os.path.join(self._eroot, VDB_PATH) + os.path.sep @@ -451,26 +454,32 @@ class vardbapi(dbapi): del e return [] - for x in listdir(basepath, EmptyOnError=1, ignorecvs=1, dirsonly=1): + catdirs = listdir(basepath, EmptyOnError=1, ignorecvs=1, dirsonly=1) + if sort: + catdirs.sort() + + for x in catdirs: if self._excluded_dirs.match(x) is not None: continue if not self._category_re.match(x): continue - for y in listdir(basepath + x, EmptyOnError=1, dirsonly=1): + + pkgdirs = listdir(basepath + x, EmptyOnError=1, dirsonly=1) + if sort: + pkgdirs.sort() + + for y in pkgdirs: if self._excluded_dirs.match(y) is not None: continue subpath = x + "/" + y # -MERGING- should never be a cpv, nor should files. try: - if catpkgsplit(subpath) is None: - self.invalidentry(self.getpath(subpath)) - continue + subpath = _pkg_str(subpath) except InvalidData: self.invalidentry(self.getpath(subpath)) continue - returnme.append(subpath) - return returnme + yield subpath def cp_all(self, use_cache=1): mylist = self.cpv_all(use_cache=use_cache)