@@ -3255,6 +3255,12 @@ solver_rule2rules(Solver *solv, Id rid, Queue *q, int recursive)
32553255
32563256
32573257/* check if the newest versions of pi still provides the dependency we're looking for */
3258+ /* pi: installed package
3259+ * r: rule for the dependency
3260+ * m: map with all positive elements of r
3261+ * return 0: at least one provider
3262+ * return 1: the newest versions do not provide the dependency
3263+ */
32583264static int
32593265solver_choicerulecheck (Solver * solv , Id pi , Rule * r , Map * m , Queue * q )
32603266{
@@ -3303,94 +3309,6 @@ solver_choicerulecheck(Solver *solv, Id pi, Rule *r, Map *m, Queue *q)
33033309 return 1 ; /* none of the new packages provided it */
33043310}
33053311
3306- static int
3307- solver_choicerulecheck2 (Solver * solv , Id pi , Id pt , Queue * q )
3308- {
3309- Pool * pool = solv -> pool ;
3310- Rule * ur ;
3311- Id p , pp ;
3312- int i ;
3313-
3314- if (!q -> count || q -> elements [0 ] != pi )
3315- {
3316- if (q -> count )
3317- queue_empty (q );
3318- ur = solv -> rules + solv -> updaterules + (pi - pool -> installed -> start );
3319- if (!ur -> p )
3320- ur = solv -> rules + solv -> featurerules + (pi - pool -> installed -> start );
3321- if (!ur -> p )
3322- return 1 ; /* orphaned, thus newest */
3323- queue_push2 (q , pi , 0 );
3324- FOR_RULELITERALS (p , pp , ur )
3325- if (p > 0 && p != pi )
3326- queue_push (q , p );
3327- queue_push (q , pi );
3328- }
3329- if (q -> count <= 3 )
3330- return q -> count == 3 && q -> elements [2 ] == pt ? 1 : 0 ;
3331- if (!q -> elements [1 ])
3332- {
3333- queue_deleten (q , 0 , 2 );
3334- policy_filter_unwanted (solv , q , POLICY_MODE_CHOOSE );
3335- queue_unshift (q , 1 ); /* filter mark */
3336- queue_unshift (q , pi );
3337- }
3338- for (i = 2 ; i < q -> count ; i ++ )
3339- if (q -> elements [i ] == pt )
3340- return 1 ;
3341- return 0 ; /* not newest */
3342- }
3343-
3344- static int
3345- solver_choicerulecheck3 (Solver * solv , Id pt , Queue * q )
3346- {
3347- Pool * pool = solv -> pool ;
3348- Id p , pp ;
3349- int i ;
3350-
3351- if (!q -> count || q -> elements [0 ] != pt )
3352- {
3353- Solvable * s = pool -> solvables + pt ;
3354- if (q -> count )
3355- queue_empty (q );
3356- /* no installed package, so check all with same name */
3357- queue_push2 (q , pt , 0 );
3358- FOR_PROVIDES (p , pp , s -> name )
3359- if (pool -> solvables [p ].name == s -> name && p != pt )
3360- queue_push (q , p );
3361- queue_push (q , pt );
3362- }
3363- if (q -> count <= 3 )
3364- return q -> count == 3 && q -> elements [2 ] == pt ? 1 : 0 ;
3365- if (!q -> elements [1 ])
3366- {
3367- queue_deleten (q , 0 , 2 );
3368- policy_filter_unwanted (solv , q , POLICY_MODE_CHOOSE );
3369- queue_unshift (q , 1 ); /* filter mark */
3370- queue_unshift (q , pt );
3371- }
3372- for (i = 2 ; i < q -> count ; i ++ )
3373- if (q -> elements [i ] == pt )
3374- return 1 ;
3375- return 0 ; /* not newest */
3376- }
3377-
3378- static inline void
3379- queue_removeelement (Queue * q , Id el )
3380- {
3381- int i , j ;
3382- for (i = 0 ; i < q -> count ; i ++ )
3383- if (q -> elements [i ] == el )
3384- break ;
3385- if (i < q -> count )
3386- {
3387- for (j = i ++ ; i < q -> count ; i ++ )
3388- if (q -> elements [i ] != el )
3389- q -> elements [j ++ ] = q -> elements [i ];
3390- queue_truncate (q , j );
3391- }
3392- }
3393-
33943312static Id
33953313choicerule_find_installed (Pool * pool , Id p )
33963314{
@@ -3439,14 +3357,14 @@ solver_addchoicerules(Solver *solv)
34393357 Pool * pool = solv -> pool ;
34403358 Map m , mneg ;
34413359 Rule * r ;
3442- Queue q , qi , qcheck , qcheck2 , infoq ;
3360+ Queue q , qi , qcheck , infoq ;
34433361 int i , j , rid , havechoice , negcnt ;
34443362 Id p , d , pp , p2 ;
34453363 Solvable * s ;
34463364 Id lastaddedp , lastaddedd ;
34473365 int lastaddedcnt ;
34483366 unsigned int now ;
3449- int isnewest = 0 ;
3367+ int isinstalled ;
34503368
34513369 solv -> choicerules = solv -> nrules ;
34523370 if (!pool -> installed )
@@ -3458,7 +3376,6 @@ solver_addchoicerules(Solver *solv)
34583376 queue_init (& q );
34593377 queue_init (& qi );
34603378 queue_init (& qcheck );
3461- queue_init (& qcheck2 );
34623379 queue_init (& infoq );
34633380 map_init (& m , pool -> nsolvables );
34643381 map_init (& mneg , pool -> nsolvables );
@@ -3478,20 +3395,28 @@ solver_addchoicerules(Solver *solv)
34783395 if (r -> p >= 0 || ((r -> d == 0 || r -> d == -1 ) && r -> w2 <= 0 ))
34793396 continue ; /* only look at requires rules */
34803397 /* solver_printrule(solv, SOLV_DEBUG_RESULT, r); */
3481- queue_empty (& q );
34823398 queue_empty (& qi );
34833399 havechoice = 0 ;
3400+ isinstalled = 0 ;
34843401 FOR_RULELITERALS (p , pp , r )
34853402 {
34863403 if (p < 0 )
3487- continue ;
3404+ {
3405+ Solvable * s = pool -> solvables - p ;
3406+ p2 = s -> repo == pool -> installed ? - p : 0 ;
3407+ if (p2 )
3408+ {
3409+ if (!(solv -> updatemap_all || (solv -> updatemap .size && MAPTST (& solv -> updatemap , p2 - solv -> installed -> start ))))
3410+ isinstalled = 1 ;
3411+ }
3412+ continue ;
3413+ }
34883414 s = pool -> solvables + p ;
34893415 if (!s -> repo )
34903416 continue ;
34913417 if (s -> repo == pool -> installed )
34923418 {
34933419 queue_push2 (& qi , p , p );
3494- queue_push (& q , p );
34953420 continue ;
34963421 }
34973422 /* find an installed package p2 that we can update/downgrade to p */
@@ -3503,7 +3428,6 @@ solver_addchoicerules(Solver *solv)
35033428 if (policy_is_illegal (solv , pool -> solvables + p2 , s , 0 ))
35043429 continue ;
35053430 queue_push2 (& qi , p2 , p );
3506- queue_push (& q , p );
35073431 continue ;
35083432 }
35093433 /* package p is independent of the installed ones */
@@ -3512,54 +3436,47 @@ solver_addchoicerules(Solver *solv)
35123436#if 0
35133437 printf ("havechoice: %d qcount %d qicount %d\n" , havechoice , q .count , qi .count );
35143438#endif
3515- if (!havechoice || !q . count || ! qi .count )
3439+ if (!havechoice || !qi .count )
35163440 continue ; /* no choice */
35173441
35183442 FOR_RULELITERALS (p , pp , r )
35193443 if (p > 0 )
35203444 MAPSET (& m , p );
35213445
3522- isnewest = 1 ;
3523- FOR_RULELITERALS (p , pp , r )
3524- {
3525- if (p > 0 )
3526- break ;
3527- p2 = choicerule_find_installed (pool , - p );
3528- if (p2 && !solver_choicerulecheck2 (solv , p2 , - p , & qcheck2 ))
3529- {
3530- isnewest = 0 ;
3531- break ;
3532- }
3533- if (!p2 && !solver_choicerulecheck3 (solv , - p , & qcheck2 ))
3534- {
3535- isnewest = 0 ;
3536- break ;
3537- }
3538- }
3539- /* do extra checking */
3540- for (i = j = 0 ; i < qi .count ; i += 2 )
3446+ if (!isinstalled )
35413447 {
3542- p2 = qi .elements [i ];
3543- if (!p2 )
3544- continue ;
3545- if (isnewest && solver_choicerulecheck (solv , p2 , r , & m , & qcheck ))
3448+ /* do extra checking for packages related to installed packages */
3449+ for (i = j = 0 ; i < qi .count ; i += 2 )
35463450 {
3547- /* oops, remove element p from q */
3548- queue_removeelement (& q , qi .elements [i + 1 ]);
3549- continue ;
3451+ p2 = qi .elements [i ];
3452+ if (solv -> updatemap_all || (solv -> updatemap .size && MAPTST (& solv -> updatemap , p2 - solv -> installed -> start )))
3453+ {
3454+ if (solver_choicerulecheck (solv , p2 , r , & m , & qcheck ))
3455+ continue ;
3456+ }
3457+ qi .elements [j ++ ] = p2 ;
3458+ qi .elements [j ++ ] = qi .elements [i + 1 ];
35503459 }
3551- qi . elements [ j ++ ] = p2 ;
3460+ queue_truncate ( & qi , j ) ;
35523461 }
3553- queue_truncate (& qi , j );
35543462
3555- if (!q . count || ! qi .count )
3463+ if (!qi .count )
35563464 {
35573465 FOR_RULELITERALS (p , pp , r )
35583466 if (p > 0 )
35593467 MAPCLR (& m , p );
35603468 continue ;
35613469 }
35623470
3471+ queue_empty (& q );
3472+ /* split q from qi */
3473+ for (i = j = 0 ; i < qi .count ; i += 2 )
3474+ {
3475+ queue_push (& q , qi .elements [i + 1 ]);
3476+ qi .elements [j ++ ] = qi .elements [i ];
3477+ }
3478+ queue_truncate (& qi , j );
3479+
35633480
35643481 /* now check the update rules of the installed package.
35653482 * if all packages of the update rules are contained in
@@ -3579,6 +3496,7 @@ solver_addchoicerules(Solver *solv)
35793496 break ;
35803497 if (p )
35813498 break ;
3499+ /* speed improvement: only check each package once */
35823500 for (j = i + 1 ; j < qi .count ; j ++ )
35833501 if (qi .elements [i ] == qi .elements [j ])
35843502 qi .elements [j ] = 0 ;
@@ -3636,7 +3554,6 @@ solver_addchoicerules(Solver *solv)
36363554 queue_free (& q );
36373555 queue_free (& qi );
36383556 queue_free (& qcheck );
3639- queue_free (& qcheck2 );
36403557 queue_free (& infoq );
36413558 map_free (& m );
36423559 map_free (& mneg );
0 commit comments