1 |
Here is another one. This is the first patch mentioned here that touches |
2 |
the dependency resolver. I'd be nice if we had more people with the |
3 |
ability to work on it. So if you're interested in that, take a look. |
4 |
|
5 |
Bug 498122 - portage-2.2.8 takes nearly twice as long to calculate |
6 |
dependencies for world update |
7 |
|
8 |
The problem with the patch mentioned in that bug is, that from there on |
9 |
metadata access (specifically USE needs to be computed) is required to |
10 |
search for slot operator rebuilds. |
11 |
|
12 |
I expect that the metadata access can be avoided in most cases. To fix |
13 |
this bug, I suggest to implement a check that decides if the metadata |
14 |
access is required. |
15 |
|
16 |
Here are some hints. |
17 |
|
18 |
Take a look at the first block of the patch. It's about computing the |
19 |
'atoms' variable. This variable is a set of all atoms in all *DEPEND |
20 |
strings of some package ('replacement_parent'). |
21 |
|
22 |
This list is later searched for atoms for which atom.cp is equal to |
23 |
dep.atom.cp (and which aren't blockers). |
24 |
|
25 |
Before this patch the whole content of the *DEPEND string was added to |
26 |
'atoms'. An example: |
27 |
DEPEND="x? ( cat/foo )" would always result in atoms = {"cat/foo"}, even |
28 |
if the use flag 'x' was disabled for the package. |
29 |
|
30 |
The leads to problems in the following case: |
31 |
DEPEND="x? ( =cat/foo-1 ) !x? ( =cat/foo-2 )". |
32 |
|
33 |
The code later in the function tries to find a package that matches all |
34 |
atoms in 'atoms'. Obviously there cannot be any package that satisfies |
35 |
both =cat/foo-1 and =cat/foo-2 at the same time. |
36 |
|
37 |
And this is not necessary at all here, because of the way the DEPEND is |
38 |
written. After evaluating the use conditionals there is always one atom |
39 |
left. But to figure this out, you need to know USE (the set of enabled |
40 |
use flags). |
41 |
|
42 |
Since computing USE is expansive, we'd like to avoid computing it. |
43 |
Consider the following example: |
44 |
We're searching for atoms with atom.cp == "cat/foo": |
45 |
DEPEND="cat/foo x? ( cat/bar )" |
46 |
No use conditional influences the set of atoms in this DEPEND for which |
47 |
atom.cp == "cat/foo". There's no point in evaluation them and in |
48 |
consequence there's no point of computing USE. |
49 |
|
50 |
I propose to implement a function* that maps (package, cp) to the set of |
51 |
atoms in the *DEPEND of package for which atom.cp == cp (and which |
52 |
aren't blockers). |
53 |
|
54 |
This function should: |
55 |
* First decide if evaluating USE is necessary or not |
56 |
* Then evaluate the conditionals if required |
57 |
* Compute and return the set of atoms with atom.cp == cp. |
58 |
|
59 |
This function should cache its results. For the case without USE, the |
60 |
cache should be part of self._frozen_config (contains stuff that never |
61 |
changes). For the case that needs USE, it should be in |
62 |
self._dynamic_config (contains stuff that may change between |
63 |
backtracking steps). |
64 |
|
65 |
For the implementation of the check you'll want to look at the functions |
66 |
in portage.dep, specifically paren_reduce (ignore the deprecation |
67 |
warning, we may have to remove that). |
68 |
|
69 |
Feel free to ask questions here or on IRC. |
70 |
|
71 |
hf :) |