@@ -3187,6 +3187,44 @@ solver_choicerulecheck(Solver *solv, Id pi, Rule *r, Map *m, Queue *q)
31873187 return 1 ; /* none of the new packages provided it */
31883188}
31893189
3190+ static int
3191+ solver_choicerulecheck2 (Solver * solv , Id pi , Id pt , Queue * q )
3192+ {
3193+ Pool * pool = solv -> pool ;
3194+ Rule * ur ;
3195+ Id p , pp ;
3196+ int i ;
3197+
3198+ if (!q -> count || q -> elements [0 ] != pi )
3199+ {
3200+ if (q -> count )
3201+ queue_empty (q );
3202+ ur = solv -> rules + solv -> updaterules + (pi - pool -> installed -> start );
3203+ if (!ur -> p )
3204+ ur = solv -> rules + solv -> featurerules + (pi - pool -> installed -> start );
3205+ if (!ur -> p )
3206+ return 0 ;
3207+ queue_push2 (q , pi , 0 );
3208+ FOR_RULELITERALS (p , pp , ur )
3209+ if (p > 0 && p != pi )
3210+ queue_push (q , p );
3211+ queue_push (q , pi );
3212+ }
3213+ if (q -> count <= 3 )
3214+ return q -> count == 3 && q -> elements [2 ] == pt ? 1 : 0 ;
3215+ if (!q -> elements [1 ])
3216+ {
3217+ queue_deleten (q , 0 , 2 );
3218+ policy_filter_unwanted (solv , q , POLICY_MODE_CHOOSE );
3219+ queue_unshift (q , 1 ); /* filter mark */
3220+ queue_unshift (q , pi );
3221+ }
3222+ for (i = 2 ; i < q -> count ; i ++ )
3223+ if (q -> elements [i ] == pt )
3224+ return 1 ;
3225+ return 0 ; /* not newest */
3226+ }
3227+
31903228static inline void
31913229queue_removeelement (Queue * q , Id el )
31923230{
@@ -3251,13 +3289,14 @@ solver_addchoicerules(Solver *solv)
32513289 Pool * pool = solv -> pool ;
32523290 Map m , mneg ;
32533291 Rule * r ;
3254- Queue q , qi , qcheck , infoq ;
3292+ Queue q , qi , qcheck , qcheck2 , infoq ;
32553293 int i , j , rid , havechoice , negcnt ;
32563294 Id p , d , pp , p2 ;
32573295 Solvable * s ;
32583296 Id lastaddedp , lastaddedd ;
32593297 int lastaddedcnt ;
32603298 unsigned int now ;
3299+ int isnewest = 0 ;
32613300
32623301 solv -> choicerules = solv -> nrules ;
32633302 if (!pool -> installed )
@@ -3270,6 +3309,7 @@ solver_addchoicerules(Solver *solv)
32703309 queue_init (& q );
32713310 queue_init (& qi );
32723311 queue_init (& qcheck );
3312+ queue_init (& qcheck2 );
32733313 queue_init (& infoq );
32743314 map_init (& m , pool -> nsolvables );
32753315 map_init (& mneg , pool -> nsolvables );
@@ -3301,6 +3341,7 @@ solver_addchoicerules(Solver *solv)
33013341 continue ;
33023342 if (s -> repo == pool -> installed )
33033343 {
3344+ queue_push2 (& qi , p , p );
33043345 queue_push (& q , p );
33053346 continue ;
33063347 }
@@ -3319,20 +3360,35 @@ solver_addchoicerules(Solver *solv)
33193360 /* package p is independent of the installed ones */
33203361 havechoice = 1 ;
33213362 }
3363+ #if 0
3364+ printf ("havechoice: %d qcount %d qicount %d\n" , havechoice , q .count , qi .count );
3365+ #endif
33223366 if (!havechoice || !q .count || !qi .count )
33233367 continue ; /* no choice */
33243368
33253369 FOR_RULELITERALS (p , pp , r )
33263370 if (p > 0 )
33273371 MAPSET (& m , p );
33283372
3373+ isnewest = 1 ;
3374+ FOR_RULELITERALS (p , pp , r )
3375+ {
3376+ if (p > 0 )
3377+ break ;
3378+ p2 = choicerule_find_installed (pool , - p );
3379+ if (p2 && !solver_choicerulecheck2 (solv , p2 , - p , & qcheck2 ))
3380+ {
3381+ isnewest = 0 ;
3382+ break ;
3383+ }
3384+ }
33293385 /* do extra checking */
33303386 for (i = j = 0 ; i < qi .count ; i += 2 )
33313387 {
33323388 p2 = qi .elements [i ];
33333389 if (!p2 )
33343390 continue ;
3335- if (solver_choicerulecheck (solv , p2 , r , & m , & qcheck ))
3391+ if (isnewest && solver_choicerulecheck (solv , p2 , r , & m , & qcheck ))
33363392 {
33373393 /* oops, remove element p from q */
33383394 queue_removeelement (& q , qi .elements [i + 1 ]);
@@ -3426,6 +3482,7 @@ solver_addchoicerules(Solver *solv)
34263482 queue_free (& q );
34273483 queue_free (& qi );
34283484 queue_free (& qcheck );
3485+ queue_free (& qcheck2 );
34293486 queue_free (& infoq );
34303487 map_free (& m );
34313488 map_free (& mneg );
0 commit comments