Gentoo Archives: gentoo-portage-dev

From: Zac Medico <zmedico@g.o>
To: gentoo-portage-dev@l.g.o
Cc: Zac Medico <zmedico@g.o>
Subject: [gentoo-portage-dev] [PATCH 4/5] Add IndexedVardb class.
Date: Sat, 01 Nov 2014 22:46:55
Message-Id: 1414881983-19877-5-git-send-email-zmedico@gentoo.org
In Reply to: [gentoo-portage-dev] by Zac Medico
1 Searching of installed packages is optimized to take advantage of
2 vardbdbapi._aux_cache, which is backed by vdb_metadata.pickle.
3 This class only implements a subset of vardbapi functionality that is
4 useful for searching incrementally. For this reason, the cp_all method
5 returns an ordered iterator instead of a list, so that search results
6 can be displayed incrementally.
7
8 X-Gentoo-Bug: 525718
9 X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=525718
10 ---
11 pym/portage/dbapi/IndexedVardb.py | 87 +++++++++++++++++++++++++++++++++++++++
12 pym/portage/dbapi/vartree.py | 19 +++++++--
13 2 files changed, 102 insertions(+), 4 deletions(-)
14 create mode 100644 pym/portage/dbapi/IndexedVardb.py
15
16 diff --git a/pym/portage/dbapi/IndexedVardb.py b/pym/portage/dbapi/IndexedVardb.py
17 new file mode 100644
18 index 0000000..b2d894b
19 --- /dev/null
20 +++ b/pym/portage/dbapi/IndexedVardb.py
21 @@ -0,0 +1,87 @@
22 +# Copyright 2014 Gentoo Foundation
23 +# Distributed under the terms of the GNU General Public License v2
24 +
25 +import portage
26 +from portage.dep import Atom
27 +from portage.versions import _pkg_str
28 +
29 +class IndexedVardb(object):
30 + """
31 + A vardbapi interface that sacrifices validation in order to
32 + improve performance. It takes advantage of vardbdbapi._aux_cache,
33 + which is backed by vdb_metadata.pickle. Since _aux_cache is
34 + not updated for every single merge/unmerge (see
35 + _aux_cache_threshold), the list of packages is obtained directly
36 + from the real vardbapi instance. If a package is missing from
37 + _aux_cache, then its metadata is obtained using the normal
38 + (validated) vardbapi.aux_get method.
39 +
40 + For performance reasons, the match method only supports package
41 + name and version constraints.
42 + """
43 +
44 + _copy_attrs = ('cpv_exists',
45 + '_aux_cache_keys', '_cpv_sort_ascending')
46 +
47 + def __init__(self, vardb):
48 + self._vardb = vardb
49 +
50 + for k in self._copy_attrs:
51 + setattr(self, k, getattr(vardb, k))
52 +
53 + self._cp_map = None
54 +
55 + def cp_all(self):
56 + """
57 + Returns an ordered iterator instead of a list, so that search
58 + results can be displayed incrementally.
59 + """
60 + if self._cp_map is not None:
61 + return iter(sorted(self._cp_map))
62 +
63 + return self._iter_cp_all()
64 +
65 + def _iter_cp_all(self):
66 + self._cp_map = cp_map = {}
67 + previous_cp = None
68 + for cpv in self._vardb._iter_cpv_all(sort = True):
69 + cp = portage.cpv_getkey(cpv)
70 + if cp is not None:
71 + cp_list = cp_map.get(cp)
72 + if cp_list is None:
73 + cp_list = []
74 + cp_map[cp] = cp_list
75 + cp_list.append(_pkg_str(cpv))
76 + if previous_cp is not None and \
77 + previous_cp != cp:
78 + yield previous_cp
79 + previous_cp = cp
80 +
81 + if previous_cp is not None:
82 + yield previous_cp
83 +
84 + def match(self, atom):
85 + """
86 + For performance reasons, only package name and version
87 + constraints are supported.
88 + """
89 + if not isinstance(atom, Atom):
90 + atom = Atom(atom)
91 + cp_list = self._cp_map.get(atom.cp)
92 + if cp_list is None:
93 + return []
94 + self._vardb._cpv_sort_ascending(cp_list)
95 + return portage.match_from_list(atom, cp_list)
96 +
97 + def aux_get(self, cpv, attrs, myrepo = None):
98 + pkg_data = self._vardb._aux_cache["packages"].get(cpv)
99 + if not isinstance(pkg_data, tuple) or \
100 + len(pkg_data) != 2 or \
101 + not isinstance(pkg_data[1], dict):
102 + pkg_data = None
103 + if pkg_data is None:
104 + # It may be missing from _aux_cache due to
105 + # _aux_cache_threshold.
106 + return self._vardb.aux_get(cpv, attrs)
107 + metadata = pkg_data[1]
108 + return [metadata.get(k, "") for k in attrs]
109 diff --git a/pym/portage/dbapi/vartree.py b/pym/portage/dbapi/vartree.py
110 index e21135a..37504e8 100644
111 --- a/pym/portage/dbapi/vartree.py
112 +++ b/pym/portage/dbapi/vartree.py
113 @@ -422,6 +422,9 @@ class vardbapi(dbapi):
114 (generally this is only necessary in critical sections that
115 involve merge or unmerge of packages).
116 """
117 + return list(self._iter_cpv_all(use_cache=use_cache))
118 +
119 + def _iter_cpv_all(self, use_cache = True, sort = False):
120 returnme = []
121 basepath = os.path.join(self._eroot, VDB_PATH) + os.path.sep
122
123 @@ -438,12 +441,21 @@ class vardbapi(dbapi):
124 del e
125 return []
126
127 - for x in listdir(basepath, EmptyOnError=1, ignorecvs=1, dirsonly=1):
128 + catdirs = listdir(basepath, EmptyOnError=1, ignorecvs=1, dirsonly=1)
129 + if sort:
130 + catdirs.sort()
131 +
132 + for x in catdirs:
133 if self._excluded_dirs.match(x) is not None:
134 continue
135 if not self._category_re.match(x):
136 continue
137 - for y in listdir(basepath + x, EmptyOnError=1, dirsonly=1):
138 +
139 + pkgdirs = listdir(basepath + x, EmptyOnError=1, dirsonly=1)
140 + if sort:
141 + pkgdirs.sort()
142 +
143 + for y in pkgdirs:
144 if self._excluded_dirs.match(y) is not None:
145 continue
146 subpath = x + "/" + y
147 @@ -455,9 +467,8 @@ class vardbapi(dbapi):
148 except InvalidData:
149 self.invalidentry(self.getpath(subpath))
150 continue
151 - returnme.append(subpath)
152
153 - return returnme
154 + yield subpath
155
156 def cp_all(self, use_cache=1):
157 mylist = self.cpv_all(use_cache=use_cache)
158 --
159 2.0.4

Replies

Subject Author
[gentoo-portage-dev] Re: [PATCH 4/5] Add IndexedVardb class. Zac Medico <zmedico@g.o>