]>
git.saurik.com Git - apt.git/blob - apt-pkg/algorithms.cc
e3012489d376878cf2f80b837d948c75d25db44b
   1 // -*- mode: cpp; mode: fold -*- 
   3 // $Id: algorithms.cc,v 1.1 1998/07/07 04:17:00 jgg Exp $ 
   4 /* ###################################################################### 
   6    Algorithms - A set of misc algorithms 
   8    ##################################################################### */ 
  10 // Include Files                                                        /*{{{*/ 
  12 #pragma implementation "pkglib/algorithms.h" 
  14 #include <pkglib/algorithms.h> 
  15 #include <pkglib/error.h> 
  16 #include <pkglib/pkgelement.h> 
  20 pkgProblemResolver 
*pkgProblemResolver::This 
= 0; 
  22 // Simulate::Simulate - Constructor                                     /*{{{*/ 
  23 // --------------------------------------------------------------------- 
  25 pkgSimulate::pkgSimulate(pkgDepCache 
&Cache
) : pkgPackageManager(Cache
),  
  28    Flags 
= new unsigned char[Cache
.HeaderP
->PackageCount
]; 
  29    memset(Flags
,0,sizeof(*Flags
)*Cache
.HeaderP
->PackageCount
); 
  32 // Simulate::Install - Simulate unpacking of a package                  /*{{{*/ 
  33 // --------------------------------------------------------------------- 
  35 bool pkgSimulate::Install(PkgIterator iPkg
,string 
/*File*/) 
  38    PkgIterator Pkg 
= Sim
.FindPkg(iPkg
.Name()); 
  41    cout 
<< "Inst " << Pkg
.Name(); 
  42    Sim
.MarkInstall(Pkg
,false); 
  44    // Look for broken conflicts+predepends. 
  45    for (PkgIterator I 
= Sim
.PkgBegin(); I
.end() == false; I
++) 
  47       if (Sim
[I
].InstallVer 
== 0) 
  50       for (DepIterator D 
= Sim
[I
].InstVerIter(Sim
).DependsList(); D
.end() == false; D
++) 
  51          if (D
->Type 
== pkgDEP_Conflicts 
|| D
->Type 
== pkgDEP_PreDepends
) 
  53             if ((Sim
[D
] & pkgDepCache::DepInstall
) == 0) 
  55                cout 
<< " [" << I
.Name() << " on " << D
.TargetPkg().Name() << ']'; 
  56                if (D
->Type 
== pkgDEP_Conflicts
) 
  57                   _error
->Error("Fatal, conflicts violated %s",I
.Name()); 
  62    if (Sim
.BrokenCount() != 0) 
  69 // Simulate::Configure - Simulate configuration of a Package            /*{{{*/ 
  70 // --------------------------------------------------------------------- 
  71 /* This is not an acurate simulation of relatity, we should really not 
  72    install the package.. For some investigations it may be necessary  
  74 bool pkgSimulate::Configure(PkgIterator iPkg
) 
  77    PkgIterator Pkg 
= Sim
.FindPkg(iPkg
.Name()); 
  80 //   Sim.MarkInstall(Pkg,false); 
  81    if (Sim
[Pkg
].InstBroken() == true) 
  83       cout 
<< "Conf " << Pkg
.Name() << " broken" << endl
; 
  87       // Print out each package and the failed dependencies 
  88       for (pkgCache::DepIterator D 
= Sim
[Pkg
].InstVerIter(Sim
).DependsList(); D
.end() == false; D
++) 
  90          if (Sim
.IsImportantDep(D
) == false ||  
  91              (Sim
[D
] & pkgDepCache::DepInstall
) != 0) 
  94          if (D
->Type 
== pkgDEP_Conflicts
) 
  95             cout 
<< " Conflicts:" << D
.TargetPkg().Name(); 
  97             cout 
<< " Depends:" << D
.TargetPkg().Name(); 
 101       _error
->Error("Conf Broken %s",Pkg
.Name()); 
 104       cout 
<< "Conf " <<  Pkg
.Name(); 
 106    if (Sim
.BrokenCount() != 0) 
 114 // Simulate::Remove - Simulate the removal of a package                 /*{{{*/ 
 115 // --------------------------------------------------------------------- 
 117 bool pkgSimulate::Remove(PkgIterator iPkg
) 
 119    // Adapt the iterator 
 120    PkgIterator Pkg 
= Sim
.FindPkg(iPkg
.Name()); 
 124    cout 
<< "Remv " << Pkg
.Name(); 
 126    if (Sim
.BrokenCount() != 0) 
 134 // Simulate::ShortBreaks - Print out a short line describing all breaks /*{{{*/ 
 135 // --------------------------------------------------------------------- 
 137 void pkgSimulate::ShortBreaks() 
 140    for (PkgIterator I 
= Sim
.PkgBegin(); I
.end() == false; I
++) 
 142       if (Sim
[I
].InstBroken() == true) 
 144          if (Flags
[I
->ID
] == 0) 
 145             cout 
<< I
.Name() << ' '; 
 147             cout << I.Name() << "! ";*/ 
 153 // ApplyStatus - Adjust for non-ok packages                             /*{{{*/ 
 154 // --------------------------------------------------------------------- 
 155 /* We attempt to change the state of the all packages that have failed 
 156    installation toward their real state. The ordering code will perform  
 157    the necessary calculations to deal with the problems. */ 
 158 bool pkgApplyStatus(pkgDepCache 
&Cache
) 
 160    for (pkgCache::PkgIterator I 
= Cache
.PkgBegin(); I
.end() == false; I
++) 
 162       switch (I
->CurrentState
) 
 164          // This means installation failed somehow 
 165          case pkgSTATE_UnPacked
: 
 166          case pkgSTATE_HalfConfigured
: 
 170          // This means removal failed 
 171          case pkgSTATE_HalfInstalled
: 
 176          if (I
->InstState 
!= pkgSTATE_Ok
) 
 177             return _error
->Error("The package %s is not ok and I " 
 178                                  "don't know how to fix it!",I
.Name()); 
 184 // FixBroken - Fix broken packages                                      /*{{{*/ 
 185 // --------------------------------------------------------------------- 
 186 /* This autoinstalls every broken package and then runs ScoredFix on the  
 188 bool pkgFixBroken(pkgDepCache 
&Cache
) 
 190    // Auto upgrade all broken packages 
 191    for (pkgCache::PkgIterator I 
= Cache
.PkgBegin(); I
.end() == false; I
++) 
 192       if (Cache
[I
].NowBroken() == true) 
 193          Cache
.MarkInstall(I
,true); 
 195    /* Fix packages that are in a NeedArchive state but don't have a 
 196       downloadable install version */ 
 197    for (pkgCache::PkgIterator I 
= Cache
.PkgBegin(); I
.end() == false; I
++) 
 199       if (I
.State() != pkgCache::PkgIterator::NeedsUnpack 
|| 
 200           Cache
[I
].Delete() == true) 
 203       if ((Cache
[I
].InstVerIter(Cache
).File()->Flags 
& pkgFLAG_NotSource
) == 0) 
 206       Cache
.MarkInstall(I
,true); 
 209    pkgProblemResolver 
Fix(Cache
); 
 210    return Fix
.Resolve(true); 
 213 // DistUpgrade - Distribution upgrade                                   /*{{{*/ 
 214 // --------------------------------------------------------------------- 
 215 /* This autoinstalls every package and then force installs every  
 216    pre-existing package. This creates the initial set of conditions which  
 217    most likely contain problems because too many things were installed. 
 219    ScoredFix is used to resolve the problems. 
 221 bool pkgDistUpgrade(pkgDepCache 
&Cache
) 
 223    /* Auto upgrade all installed packages, this provides the basis  
 224       for the installation */ 
 225    for (pkgCache::PkgIterator I 
= Cache
.PkgBegin(); I
.end() == false; I
++) 
 226       if (I
->CurrentVer 
!= 0) 
 227          Cache
.MarkInstall(I
,true); 
 229    /* Now, auto upgrade all essential packages - this ensures that 
 230       the essential packages are present and working */ 
 231    for (pkgCache::PkgIterator I 
= Cache
.PkgBegin(); I
.end() == false; I
++) 
 232       if ((I
->Flags 
& pkgFLAG_Essential
) == pkgFLAG_Essential
) 
 233          Cache
.MarkInstall(I
,true); 
 235    /* We do it again over all previously installed packages to force  
 236       conflict resolution on them all. */ 
 237    for (pkgCache::PkgIterator I 
= Cache
.PkgBegin(); I
.end() == false; I
++) 
 238       if (I
->CurrentVer 
!= 0) 
 239          Cache
.MarkInstall(I
,false); 
 241    pkgProblemResolver 
Fix(Cache
); 
 243    // Hold back held packages. 
 244    for (pkgCache::PkgIterator I 
= Cache
.PkgBegin(); I
.end() == false; I
++) 
 246       if (I
->SelectedState 
== pkgSTATE_Hold
) 
 253    return Fix
.Resolve(); 
 257 // ProblemResolver::pkgProblemResolver - Constructor                    /*{{{*/ 
 258 // --------------------------------------------------------------------- 
 260 pkgProblemResolver::pkgProblemResolver(pkgDepCache 
&Cache
) : Cache(Cache
) 
 263    unsigned long Size 
= Cache
.HeaderP
->PackageCount
; 
 264    Scores 
= new signed short[Size
]; 
 265    Flags 
= new unsigned char[Size
]; 
 266    memset(Flags
,0,sizeof(*Flags
)*Size
); 
 268    // Set debug to true to see its decision logic 
 272 // ProblemResolver::ScoreSort - Sort the list by score                  /*{{{*/ 
 273 // --------------------------------------------------------------------- 
 275 int pkgProblemResolver::ScoreSort(const void *a
,const void *b
) 
 277    Package 
const **A 
= (Package 
const **)a
; 
 278    Package 
const **B 
= (Package 
const **)b
; 
 279    if (This
->Scores
[(*A
)->ID
] > This
->Scores
[(*B
)->ID
]) 
 281    if (This
->Scores
[(*A
)->ID
] < This
->Scores
[(*B
)->ID
]) 
 286 // ProblemResolver::MakeScores - Make the score table                   /*{{{*/ 
 287 // --------------------------------------------------------------------- 
 289 void pkgProblemResolver::MakeScores() 
 291    unsigned long Size 
= Cache
.HeaderP
->PackageCount
; 
 292    memset(Scores
,0,sizeof(*Scores
)*Size
); 
 294    // Generate the base scores for a package based on its properties 
 295    for (pkgCache::PkgIterator I 
= Cache
.PkgBegin(); I
.end() == false; I
++) 
 297       if (Cache
[I
].InstallVer 
== 0) 
 300       signed short &Score 
= Scores
[I
->ID
]; 
 302       /* This is arbitary, it should be high enough to elevate an 
 303          essantial package above most other packages but low enough 
 304          to allow an obsolete essential packages to be removed by 
 305          a conflicts on a powerfull normal package (ie libc6) */ 
 306       if ((I
->Flags 
& pkgFLAG_Essential
) == pkgFLAG_Essential
) 
 309       // We transform the priority 
 310       // Important Required Standard Optional Extra 
 311       signed short PrioMap
[] = {0,3,2,1,-1,-2}; 
 312       if (Cache
[I
].InstVerIter(Cache
)->Priority 
<= 5) 
 313          Score 
+= PrioMap
[Cache
[I
].InstVerIter(Cache
)->Priority
]; 
 315       /* This helps to fix oddball problems with conflicting packages 
 316          on the same level. We enhance the score of installed packages */ 
 317       if (I
->CurrentVer 
!= 0) 
 321    // Now that we have the base scores we go and propogate dependencies 
 322    for (pkgCache::PkgIterator I 
= Cache
.PkgBegin(); I
.end() == false; I
++) 
 324       if (Cache
[I
].InstallVer 
== 0) 
 327       for (pkgCache::DepIterator D 
= Cache
[I
].InstVerIter(Cache
).DependsList(); D
.end() == false; D
++) 
 329          if (D
->Type 
== pkgDEP_Depends 
|| D
->Type 
== pkgDEP_PreDepends
) 
 330             Scores
[D
.TargetPkg()->ID
]++; 
 334    // Copy the scores to advoid additive looping 
 335    signed short *OldScores 
= new signed short[Size
]; 
 336    memcpy(OldScores
,Scores
,sizeof(*Scores
)*Size
); 
 338    /* Now we cause 1 level of dependency inheritance, that is we add the  
 339       score of the packages that depend on the target Package. This  
 340       fortifies high scoring packages */ 
 341    for (pkgCache::PkgIterator I 
= Cache
.PkgBegin(); I
.end() == false; I
++) 
 343       if (Cache
[I
].InstallVer 
== 0) 
 346       for (pkgCache::DepIterator D 
= I
.RevDependsList(); D
.end() == false; D
++) 
 348          // Only do it for the install version 
 349          if ((pkgCache::Version 
*)D
.ParentVer() != Cache
[D
.ParentPkg()].InstallVer 
|| 
 350              (D
->Type 
!= pkgDEP_Depends 
&& D
->Type 
!= pkgDEP_PreDepends
)) 
 353          Scores
[I
->ID
] += abs(OldScores
[D
.ParentPkg()->ID
]); 
 357    /* Now we propogate along provides. This makes the packages that  
 358       provide important packages extremely important */ 
 359    for (pkgCache::PkgIterator I 
= Cache
.PkgBegin(); I
.end() == false; I
++) 
 361       for (pkgCache::PrvIterator P 
= I
.ProvidesList(); P
.end() == false; P
++) 
 363          // Only do it once per package 
 364          if ((pkgCache::Version 
*)P
.OwnerVer() != Cache
[P
.OwnerPkg()].InstallVer
) 
 366          Scores
[P
.OwnerPkg()->ID
] += abs(Scores
[I
->ID
] - OldScores
[I
->ID
]); 
 370    /* Protected things are pushed really high up. This number should put them 
 371       ahead of everything */ 
 372    for (pkgCache::PkgIterator I 
= Cache
.PkgBegin(); I
.end() == false; I
++) 
 373       if ((Flags
[I
->ID
] & Protected
) != 0) 
 374          Scores
[I
->ID
] += 10000; 
 379 // ProblemResolver::DoUpgrade - Attempt to upgrade this package         /*{{{*/ 
 380 // --------------------------------------------------------------------- 
 381 /* This goes through and tries to reinstall packages to make this package 
 383 bool pkgProblemResolver::DoUpgrade(pkgCache::PkgIterator Pkg
) 
 385    if ((Flags
[Pkg
->ID
] & Upgradable
) == 0 || Cache
[Pkg
].Upgradable() == false) 
 387    Flags
[Pkg
->ID
] &= ~Upgradable
; 
 389    bool WasKept 
= Cache
[Pkg
].Keep(); 
 390    Cache
.MarkInstall(Pkg
,false); 
 392    // Isolate the problem dependency 
 394    for (pkgCache::DepIterator D 
= Cache
[Pkg
].InstVerIter(Cache
).DependsList(); D
.end() == false;) 
 396       // Compute a single dependency element (glob or) 
 397       pkgCache::DepIterator Start 
= D
; 
 398       pkgCache::DepIterator End 
= D
; 
 399       unsigned char State 
= 0; 
 400       for (bool LastOR 
= true; D
.end() == false && LastOR 
== true; D
++) 
 403          LastOR 
= (D
->CompareOp 
& pkgOP_OR
) == pkgOP_OR
; 
 408       // We only worry about critical deps. 
 409       if (End
.IsCritical() != true) 
 413       if ((Cache
[End
] & pkgDepCache::DepGInstall
) == pkgDepCache::DepGInstall
) 
 416       // Hm, the group is broken.. I have no idea how to handle this 
 419          cout 
<< "Note, a broken or group was found in " << Pkg
.Name() << "." << endl
; 
 424       // Upgrade the package if the candidate version will fix the problem. 
 425       if ((Cache
[Start
] & pkgDepCache::DepCVer
) == pkgDepCache::DepCVer
) 
 427          PkgIterator P 
= Start
.SmartTargetPkg(); 
 428          if (DoUpgrade(P
) == false) 
 431                cout 
<< "    Reinst Failed because of " << P
.Name() << endl
; 
 438          /* We let the algorithm deal with conflicts on its next iteration, 
 439             it is much smarter than us */ 
 440          if (End
->Type 
== pkgDEP_Conflicts
) 
 444             cout 
<< "    Reinst Failed early because of " << Start
.TargetPkg().Name() << endl
; 
 450    // Undo our operations - it might be smart to undo everything this did.. 
 456          Cache
.MarkDelete(Pkg
); 
 461       cout 
<< "  Re-Instated " << Pkg
.Name() << endl
; 
 465 // ProblemResolver::Resolve - Run the resolution pass                   /*{{{*/ 
 466 // --------------------------------------------------------------------- 
 467 /* This routines works by calculating a score for each package. The score 
 468    is derived by considering the package's priority and all reverse  
 469    dependents giving an integer that reflects the amount of breakage that 
 470    adjusting the package will inflict.  
 472    It goes from highest score to lowest and corrects all of the breaks by  
 473    keeping or removing the dependant packages. If that fails then it removes 
 474    the package itself and goes on. The routine should be able to intelligently 
 475    go from any broken state to a fixed state.  
 477    The BrokenFix flag enables a mode where the algorithm tries to  
 478    upgrade packages to advoid problems. */ 
 479 bool pkgProblemResolver::Resolve(bool BrokenFix
) 
 481  unsigned long Size 
= Cache
.HeaderP
->PackageCount
; 
 483    // Record which packages are marked for install 
 488       for (pkgCache::PkgIterator I 
= Cache
.PkgBegin(); I
.end() == false; I
++) 
 490          if (Cache
[I
].Install() == true) 
 491             Flags
[I
->ID
] |= PreInstalled
; 
 494             if (Cache
[I
].InstBroken() == true && BrokenFix 
== true) 
 496                Cache
.MarkInstall(I
,false); 
 497                if (Cache
[I
].Install() == true) 
 501             Flags
[I
->ID
] &= ~PreInstalled
; 
 503          Flags
[I
->ID
] |= Upgradable
; 
 506    while (Again 
== true); 
 509       cout 
<< "Starting" << endl
; 
 513    /* We have to order the packages so that the broken fixing pass  
 514       operates from highest score to lowest. This prevents problems when 
 515       high score packages cause the removal of lower score packages that 
 516       would cause the removal of even lower score packages. */ 
 517    pkgCache::Package 
**PList 
= new pkgCache::Package 
*[Size
]; 
 518    pkgCache::Package 
**PEnd 
= PList
; 
 519    for (pkgCache::PkgIterator I 
= Cache
.PkgBegin(); I
.end() == false; I
++) 
 522    qsort(PList
,PEnd 
- PList
,sizeof(*PList
),&ScoreSort
); 
 524 /* for (pkgCache::Package **K = PList; K != PEnd; K++) 
 525       if (Scores[(*K)->ID] != 0) 
 527          pkgCache::PkgIterator Pkg(Cache,*K); 
 528          cout << Scores[(*K)->ID] << ' ' << Pkg.Name() << 
 529             ' ' << (pkgCache::Version *)Pkg.CurrentVer() << ' ' <<  
 530             Cache[Pkg].InstallVer << ' ' << Cache[Pkg].CandidateVer << endl; 
 534       cout 
<< "Starting 2" << endl
; 
 536    /* Now consider all broken packages. For each broken package we either 
 537       remove the package or fix it's problem. We do this once, it should 
 538       not be possible for a loop to form (that is a < b < c and fixing b by 
 539       changing a breaks c) */ 
 541    for (int Counter 
= 0; Counter 
!= 10 && Change 
== true; Counter
++) 
 544       for (pkgCache::Package 
**K 
= PList
; K 
!= PEnd
; K
++) 
 546          pkgCache::PkgIterator 
I(Cache
,*K
); 
 548          /* We attempt to install this and see if any breaks result, 
 549             this takes care of some strange cases */ 
 550          if (Cache
[I
].CandidateVer 
!= Cache
[I
].InstallVer 
&& 
 551              I
->CurrentVer 
!= 0 && Cache
[I
].InstallVer 
!= 0 && 
 552              (Flags
[I
->ID
] & PreInstalled
) != 0 && 
 553              (Flags
[I
->ID
] & Protected
) == 0) 
 556                cout 
<< " Try to Re-Instate " << I
.Name() << endl
; 
 557             int OldBreaks 
= Cache
.BrokenCount(); 
 558             pkgCache::Version 
*OldVer 
= Cache
[I
].InstallVer
; 
 560             Cache
.MarkInstall(I
,false); 
 561             if (Cache
[I
].InstBroken() == true ||  
 562                 OldBreaks 
< Cache
.BrokenCount()) 
 571                   cout 
<< "Re-Instated " << I
.Name() << endl
; 
 574          if (Cache
[I
].InstallVer 
== 0 || Cache
[I
].InstBroken() == false) 
 577          // Isolate the problem dependency 
 578          PackageKill KillList
[100]; 
 579          PackageKill 
*LEnd 
= KillList
; 
 580          for (pkgCache::DepIterator D 
= Cache
[I
].InstVerIter(Cache
).DependsList(); D
.end() == false;) 
 582             // Compute a single dependency element (glob or) 
 583             pkgCache::DepIterator Start 
= D
; 
 584             pkgCache::DepIterator End 
= D
; 
 585             unsigned char State 
= 0; 
 586             for (bool LastOR 
= true; D
.end() == false && LastOR 
== true; D
++) 
 589                LastOR 
= (D
->CompareOp 
& pkgOP_OR
) == pkgOP_OR
; 
 594             // We only worry about critical deps. 
 595             if (End
.IsCritical() != true) 
 599             if ((Cache
[End
] & pkgDepCache::DepGInstall
) == pkgDepCache::DepGInstall
) 
 602             // Hm, the group is broken.. I have no idea how to handle this 
 605                cout 
<< "Note, a broken or group was found in " << I
.Name() << "." << endl
; 
 611                cout 
<< "Package " << I
.Name() << " has broken dep on " << End
.TargetPkg().Name() << endl
; 
 613             /* Conflicts is simple, decide if we should remove this package 
 614                or the conflicted one */ 
 615             pkgCache::Version 
**VList 
= End
.AllTargets(); 
 617             for (pkgCache::Version 
**V 
= VList
; *V 
!= 0; V
++) 
 619                pkgCache::VerIterator 
Ver(Cache
,*V
); 
 620                pkgCache::PkgIterator Pkg 
= Ver
.ParentPkg(); 
 623                   cout 
<< "  Considering " << Pkg
.Name() << ' ' << (int)Scores
[Pkg
->ID
] <<  
 624                   " as a solution to " << I
.Name() << ' ' << (int)Scores
[I
->ID
] << endl
; 
 625                if (Scores
[I
->ID
] <= Scores
[Pkg
->ID
] || 
 626                    ((Cache
[End
] & pkgDepCache::DepGNow
) == 0 && 
 627                     End
->Type 
!= pkgDEP_Conflicts
)) 
 629                   if ((Flags
[I
->ID
] & Protected
) != 0) 
 632                   // See if a keep will do 
 634                   if (Cache
[I
].InstBroken() == false) 
 637                         cout 
<< "  Holding Back " << I
.Name() << " rather than change " << End
.TargetPkg().Name() << endl
; 
 641                      if (BrokenFix 
== false || DoUpgrade(I
) == false) 
 644                            cout 
<< "  Removing " << I
.Name() << " rather than change " << End
.TargetPkg().Name() << endl
; 
 647                            Scores
[I
->ID
] = Scores
[Pkg
->ID
]; 
 657                   // Skip this if it is protected 
 658                   if ((Flags
[Pkg
->ID
] & Protected
) != 0) 
 664                   if (End
->Type 
!= pkgDEP_Conflicts
) 
 669             // Hm, nothing can possibly satisify this dep. Nuke it. 
 670             if (VList
[0] == 0 && End
->Type 
!= pkgDEP_Conflicts
) 
 673                if (Cache
[I
].InstBroken() == false) 
 676                      cout 
<< "  Holding Back " << I
.Name() << " because I can't find " << End
.TargetPkg().Name() << endl
; 
 681                      cout 
<< "  Removing " << I
.Name() << " because I can't find " << End
.TargetPkg().Name() << endl
; 
 694          // Apply the kill list now 
 695          if (Cache
[I
].InstallVer 
!= 0) 
 696             for (PackageKill 
*J 
= KillList
; J 
!= LEnd
; J
++) 
 699             if ((Cache
[J
->Dep
] & pkgDepCache::DepGNow
) == 0) 
 701                if (J
->Dep
->Type 
== pkgDEP_Conflicts
) 
 704                      cout 
<< "  Fixing " << I
.Name() << " via remove of " << J
->Pkg
.Name() << endl
; 
 705                   Cache
.MarkDelete(J
->Pkg
); 
 711                   cout 
<< "  Fixing " << I
.Name() << " via keep of " << J
->Pkg
.Name() << endl
; 
 712                Cache
.MarkKeep(J
->Pkg
); 
 716                Scores
[J
->Pkg
->ID
] = Scores
[I
->ID
]; 
 722       cout 
<< "Done" << endl
; 
 727    if (Cache
.BrokenCount() != 0) 
 728       return _error
->Error("Internal error, ScoredFix generated breaks.");