1 |
Jason Stubbs wrote: |
2 |
> On Thursday 08 December 2005 16:44, Zac Medico wrote: |
3 |
> |
4 |
>>The middle hunk fixes a problem with block atoms that do not match any |
5 |
>>packages. Previously, these atoms would not make it into the okay_atoms set |
6 |
>>which caused unresolved dependencies. |
7 |
> |
8 |
> |
9 |
> Are you sure about this? |
10 |
|
11 |
Well, I'm pretty sure. You're analysis seems to be perfectly correct except for 2 points that you haven't accounted for: |
12 |
|
13 |
1) The atom.key != child.key optimization prevents the atom.match(child) ^ atom.blocks bit from working in the case that my patch handles (block atom that does not match any package). |
14 |
|
15 |
2) Without the atom.key != child.key optimization, the original algorithm would bail out early, before all packages have been checked. We need to ensure that the atom does not block _any_ of the packages before we add it to okay_atoms, otherwise, we risk choosing the wrong atomset/combination. Note that checking all the packages _does_ introduce a performance penalty for block atoms. |
16 |
|
17 |
> For reference: |
18 |
> |
19 |
> @@ -58,12 +58,19 @@ |
20 |
> all_atoms.union_update(atomset) |
21 |
> okay_atoms = sets.Set() |
22 |
> for atom in all_atoms: |
23 |
> + have_blocker=False |
24 |
> for child in self.pkgs: |
25 |
> if atom.key != child.key: |
26 |
> continue |
27 |
> - if atom.match(child) ^ atom.blocks: |
28 |
> - okay_atoms.add(atom) |
29 |
> + if atom.match(child): |
30 |
> + if atom.blocks: |
31 |
> + have_blocker=True |
32 |
> + else: |
33 |
> + okay_atoms.add(atom) |
34 |
> break |
35 |
> + if atom.blocks and not have_blocker: |
36 |
> + # block atom that does not match any |
37 |
> packages |
38 |
> + okay_atoms.add(atom) |
39 |
> for choice in self.pkgs[pkg][0]: |
40 |
> if choice.issubset(okay_atoms): |
41 |
> break |
42 |
> |
43 |
> |
44 |
> if atom.match(child) ^ atom.blocks: |
45 |
> okay_atoms.add(atom) |
46 |
> break |
47 |
> |
48 |
> is the same as: |
49 |
> |
50 |
> if (atom.match(child) and not atom.blocks) or \ |
51 |
> (not atom.match(child) or atom.blocks): |
52 |
> okay_atoms.add(atom) |
53 |
> break |
54 |
> |
55 |
> |
56 |
> have_blocker = False |
57 |
> ... |
58 |
> if atom.match(child): |
59 |
> if atom.blocks: |
60 |
> have_blocker=True |
61 |
> else: |
62 |
> okay_atoms.add(atom) |
63 |
> break |
64 |
> if atom.blocks and not have_blocker: |
65 |
> okay_atoms.add(atom) |
66 |
> |
67 |
> Therefore: |
68 |
> |
69 |
> have_blocker = atom.blocks and atom.match(child) |
70 |
> |
71 |
> which makes the last check: |
72 |
> |
73 |
> if atom.blocks and not (atom.blocks and atom.match(child)): |
74 |
> okay_atoms.add(atom) |
75 |
> |
76 |
> which is equivalent to: |
77 |
> |
78 |
> if atom.blocks and (not atom.blocks or not atom.match(child)): |
79 |
> okay_atoms.add(atom) |
80 |
> |
81 |
> Removing the impossibility of "atom.blocks and not atom.blocks": |
82 |
> |
83 |
> if atom.blocks and not atom.match(child): |
84 |
> okay_atoms.add(atom) |
85 |
> |
86 |
> Within the loop you have: |
87 |
> |
88 |
> if atom.match(child): |
89 |
> if atom.blocks: |
90 |
> ... |
91 |
> else: |
92 |
> okay_atoms.add(atom) |
93 |
> break |
94 |
> |
95 |
> Which could be represented as: |
96 |
> |
97 |
> if atom.match(child) and not atom.blocks: |
98 |
> okay_atoms.add(atom) |
99 |
> |
100 |
> Combining those two gives: |
101 |
> |
102 |
> if atom.blocks and not atom.match(child) or \ |
103 |
> atom.match(child) and not atom.blocks: |
104 |
> okay_atoms.add(atom) |
105 |
> |
106 |
> Which is exactly the same thing as the original except seven lines longer... |
107 |
|
108 |
As I've noted above, not quite the same, due to the atom.key != child.key optimization and checking of _all_ packages for block atoms (without bailing out early). |
109 |
|
110 |
Zac |
111 |
-- |
112 |
gentoo-portage-dev@g.o mailing list |