Main Page | Namespace List | Class Hierarchy | Class List | File List | Namespace Members | Class Members | File Members

PkgDep.h

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------\
00002 |                                                                      |
00003 |                      __   __    ____ _____ ____                      |
00004 |                      \ \ / /_ _/ ___|_   _|___ \                     |
00005 |                       \ V / _` \___ \ | |   __) |                    |
00006 |                        | | (_| |___) || |  / __/                     |
00007 |                        |_|\__,_|____/ |_| |_____|                    |
00008 |                                                                      |
00009 |                               core system                            |
00010 |                                                     (C) 2002 SuSE AG |
00011 \----------------------------------------------------------------------/
00012 
00013    File:       PkgDep.h
00014    Purpose:    All functions for solving dependences
00015    Author:     Ludwig Nussel <lnussel@suse.de>
00016    Maintainer: Ludwig Nussel <lnussel@suse.de>
00017 
00018    copied and modified from phi
00019 /-*/
00020 
00021 #ifndef _PkgDep_h
00022 #define _PkgDep_h
00023 
00024 #include <iostream>
00025 #include <list>
00026 #include <deque>
00027 
00028 #include <y2util/hash.h>
00029 
00030 #include <y2pm/PkgName.h>
00031 #include <y2pm/PkgEdition.h>
00032 #include <y2pm/PkgRevRel.h>
00033 #include <y2pm/PkgSet.h>
00034 #include <y2pm/Alternatives.h>
00035 
00039 class PkgDep {
00040 
00041         // ------------------------------ types ------------------------------
00042 
00043   public:
00044         enum alternative_kind {
00045                 SIMPLE, REQUIRES_MORE, CONFLICT
00046         };
00047         enum alternatives_mode {
00048                 ASK_ALWAYS, ASK_IF_NO_DEFAULT, AUTO_IF_NO_DEFAULT, AUTO_ALWAYS
00049         };
00050 
00052         struct RelInfo {
00053 
00054                 enum Kind {
00055                         REQUIREMENT = 0, CONFLICT, OBSOLETION
00056                 };
00057 
00061                 PkgName name;
00066                 PkgRelation rel;
00067 
00072                 Kind kind;
00073 
00077                 PMSolvablePtr solvable;
00078 
00079                 RelInfo( PMSolvablePtr s, PkgRelation r, Kind k = REQUIREMENT )
00080                         : name(s->name()), rel(r),
00081                         kind(k), solvable(s)
00082                         {}
00083                 RelInfo( PkgName n, PkgRelation r, Kind k = REQUIREMENT, PMSolvablePtr s = NULL )
00084                         : name(n), rel(r), kind(k), solvable(s)
00085                         {}
00086                 RelInfo( PkgRevRelation r, Kind k = REQUIREMENT )
00087                         : name(r.pkg()->name()), rel(r.relation()),
00088                         kind(k), solvable(r.pkg())
00089                         {}
00090         };
00091 
00092         struct Alternative {
00093                 PMSolvablePtr solvable;
00094                 alternative_kind kind;
00095 
00096                 Alternative( PMSolvablePtr p, alternative_kind k )
00097                         : solvable(p), kind(k) {}
00098         };
00099 
00100         typedef Alternatives::AltDefaultList (*AlternativesCallback)( PkgName name );
00101 
00113         struct NeededEditionRange {
00114                 PkgEdition greater;
00115                 PkgEdition less;
00116                 bool less_incl : 1;
00117                 bool greater_incl : 1;
00118 
00119                 NeededEditionRange()
00120                         : greater(PkgEdition::UNSPEC), less(PkgEdition::UNSPEC),
00121                           less_incl(false), greater_incl(false) {}
00122                 bool allows_any() const {
00123                         return greater.is_unspecified() && less.is_unspecified();
00124                 }
00125                 bool impossible() const {
00126                         return( (less < greater) ||
00127                                         (less == greater && (!less_incl || !greater_incl)) );
00128                 }
00129                 void merge( const PkgRelation& rel );
00130         };
00131 
00132         typedef std::list<PkgName> NameList;
00133         typedef NameList::iterator NameList_iterator;
00134         typedef NameList::const_iterator NameList_const_iterator;
00135 
00136         typedef std::list<RelInfo> RelInfoList;
00137         typedef RelInfoList::iterator RelInfoList_iterator;
00138         typedef RelInfoList::const_iterator RelInfoList_const_iterator;
00139 
00140         typedef std::list<PMSolvablePtr> SolvableList;
00141 
00142         struct Notes;
00143 
00148         struct Result
00149         {
00151                 PkgName name;
00153                 PkgEdition edition;
00154 
00158                 PMSolvablePtr solvable;
00159 
00167                 RelInfoList referers;
00174                 PkgEdition is_upgrade_from;
00181                 PkgEdition is_downgrade_from;
00186                 bool from_input_list : 1;
00192                 bool upgrade_to_remove_conflict : 1;
00197                 bool install_to_avoid_break : 1;
00198 
00203                 bool was_inconsistent : 1;
00204 
00209                 Result(const PkgDep& pkgdep, PMSolvablePtr pkg);
00210 
00212                 Result(const PkgDep& pkgdep, const PkgName& name);
00213                 void add_notes( const Notes& notes );
00214         };
00215 
00221         struct ErrorResult : public Result {
00226                 bool not_available;
00235                 NeededEditionRange not_avail_range;
00243                 RelInfoList unresolvable;
00253                 std::list<Alternative> alternatives;
00254 
00285                 RelInfoList conflicts_with;
00295                 SolvableList remove_to_solve_conflict;
00296 
00302                 SolvableList remove_referers;
00303 
00304                 ErrorResult(const PkgDep& pkgdep, PMSolvablePtr pkg)
00305                         : Result(pkgdep,pkg), not_available(false), state_change_not_possible(false) {}
00306                 ErrorResult(const PkgDep& pkgdep, const PkgName& name)
00307                         : Result(pkgdep,name), not_available(false), state_change_not_possible(false) {}
00308                 ErrorResult(const Result& res)
00309                         : Result(res), not_available(false), state_change_not_possible(false) {}
00310 
00311                 void add_unresolvable( PMSolvablePtr s, const PkgRelation& rel );
00312                 void add_conflict( const PkgRevRelation& rrel,
00313                                                    const PkgDep& dep,
00314                                                    PMSolvablePtr to_remove,
00315                                                    PMSolvablePtr assume_instd,
00316                                                    RelInfo::Kind kind = RelInfo::CONFLICT );
00322                 void add_conflict( PMSolvablePtr s, const PkgRelation& rel,
00323                                                    const PkgDep& dep,
00324                                                    PMSolvablePtr to_remove,
00325                                                    PMSolvablePtr assume_instd,
00326                                                    RelInfo::Kind kind = RelInfo::CONFLICT );
00327                 void add_alternative( PMSolvablePtr p, alternative_kind k );
00328                 void add_notes( const Notes& notes );
00329 
00334                 bool state_change_not_possible;
00335         };
00336 
00337         friend class Result;
00338         friend class ErrorResult;
00339         typedef std::list<Result> ResultList;
00340         typedef std::list<ErrorResult> ErrorResultList;
00341         
00342         enum WhatToDoWithUnresolvable {
00343             UNRES_IGNORE = 0, // just ignore this dependence
00344             UNRES_TAKETHIS,   // use suggested PMSolvable (has to be returned/filled by function)
00345             UNRES_FAIL        // Relation is indeed unresolvable
00346         };
00347         
00359         typedef WhatToDoWithUnresolvable(*DealWithUnresolvable_callback)(
00360             PkgDep* solver, const PkgRelation& rel, PMSolvablePtr& ptr);
00361         //FIXME make PkgDep* const, requires lots of constPMSolvablePtr everywhere
00362 
00363         DealWithUnresolvable_callback _unresolvable_callback;
00364 
00365   private:
00366 
00367         typedef std::list<PkgRevRelation> RevRelList;
00368         typedef RevRelList::iterator RevRelList_iterator;
00369         typedef RevRelList::const_iterator RevRelList_const_iterator;
00370 
00371         enum search_result { NONE, ONE, MULTI };
00372 
00373         struct IRelInfo {
00374                 PMSolvablePtr pkg;
00375                 PkgRelation rel;
00376 
00377                 IRelInfo( PMSolvablePtr p, PkgRelation r ) : pkg(p), rel(r) {}
00378         };
00379 
00380         typedef std::list<IRelInfo> IRelInfoList;
00381         typedef IRelInfoList::iterator IRelInfoList_iterator;
00382         typedef IRelInfoList::const_iterator IRelInfoList_const_iterator;
00383 
00385         struct Notes {
00386                 bool from_input : 1;
00387                 bool upgrade_to_solve_conflict : 1;
00388                 bool install_to_avoid_break : 1;
00389                 bool not_available : 1;
00390                 bool was_inconsistent : 1;
00391                 IRelInfoList referers;
00392                 NeededEditionRange not_avail_range;
00393 
00394                 Notes() : from_input(false), upgrade_to_solve_conflict(false),
00395                         install_to_avoid_break(false),
00396                         not_available(false),
00397                         was_inconsistent(false)
00398                         {}
00399         };
00400 
00401         typedef hash<PkgName,Notes> Notes_type;
00402         typedef Notes_type::iterator Notes_iterator;
00403         typedef Notes_type::const_iterator Notes_const_iterator;
00404 
00405         struct AltInfo {
00406                 PMSolvablePtr pkg;
00407                 PkgRelation req;
00408                 RevRelList providers;
00409                 ErrorResult result;
00410                 
00411                 AltInfo( PMSolvablePtr p, const PkgRelation& r, const RevRelList& l,
00412                                  const ErrorResult& rs )
00413                         : pkg(p), req(r), providers(l), result(rs) {}
00414         };
00415 
00416         typedef std::deque<AltInfo> AltInfoList;
00417         typedef AltInfoList::iterator AltInfo_iterator;
00418         typedef AltInfoList::const_iterator AltInfo_const_iterator;
00419         
00420         // ---------------------------- static vars ----------------------------
00421 //      static const PkgSet *default_avail;
00422 
00423         // initialisation in utils.cc
00424         static alternatives_mode default_alternatives_mode;
00425         static unsigned default_max_remove;
00426 
00427         // --------------------------- instance vars ---------------------------
00428         alternatives_mode alt_mode;
00429         PkgSet installed;
00430         const PkgSet& available;
00431 
00432         AlternativesCallback _alternatives_callback;
00433 
00434         // --------------------- used during an install run --------------------
00435         PkgSet vinstalled;
00436         PkgSet *candidates;
00437         Notes_type notes;
00438         std::deque<PMSolvablePtr > to_check;
00439         AltInfoList alts_to_check;
00440         noval_hash<PkgName> alts_handled;
00441         ErrorResultList* i_obsoleted; // obsolete packages
00442         ResultList *good;
00443         ErrorResultList *bad;
00444 
00445         bool _install_installed;
00446 
00447         // -------------------------- private methods --------------------------
00448         // install.cc
00449         void add_package( PMSolvablePtr cand );
00450         search_result search_for_provider( const PkgRelation& req,
00451                                                                            PMSolvablePtr referer,
00452                                                                            ErrorResult *res );
00453         bool check_for_broken_reqs( PMSolvablePtr oldpkg, PMSolvablePtr newpkg,
00454                                                                 ErrorResult &res );
00455         bool req_ok_after_upgrade( const PkgRelation& rel, PMSolvablePtr oldpkg,
00456                                                            PMSolvablePtr newpkg );
00457         // alternatives.cc
00458         void handle_alternative( const AltInfo& alt_info );
00459         // consistency.cc
00460         bool pkg_consistent( PMSolvablePtr pkg, ErrorResult *err );
00461         // remove.cc
00462         void virtual_remove_package( PMSolvablePtr pkg, SolvableList& to_remove,
00463                                                                  PMSolvablePtr assume_instd = NULL ) const;
00464         // utils.cc
00465         bool also_provided_by_installed( const PkgRelation& rel );
00466         PMSolvablePtr upgrade_solves_conflict( PMSolvablePtr pkg,
00467                                                                                         const PkgRelation& confl );
00468         PMSolvablePtr try_upgrade_conflictor( PMSolvablePtr pkg,
00469                                                                                    const PkgRelation& provides );
00470         PMSolvablePtr try_upgrade_conflicted( PMSolvablePtr pkg,
00471                                                                                    const PkgRelation& confl );
00472         PMSolvablePtr try_upgrade_requirerer( PMSolvablePtr pkg,
00473                                                                                    PMSolvablePtr oldpkg,
00474                                                                                    PMSolvablePtr newpkg );
00475         PMSolvablePtr available_upgrade( PMSolvablePtr pkg );
00476         void do_upgrade_for_conflict( PMSolvablePtr upgrade );
00477         bool has_conflict_with( const PkgRelation& confl, PMSolvablePtr pkg );
00478         void add_referer( const PkgName& name, PMSolvablePtr referer,
00479                                           const PkgRelation& rel );
00480         void add_referer( PMSolvablePtr pkg, PMSolvablePtr referer,
00481                                           const PkgRelation& rel ) {
00482                 add_referer( pkg->name(), referer, rel );
00483         }
00484         void add_not_available( PMSolvablePtr referer, const PkgRelation& rel );
00485 
00486         // return empty list
00487         static Alternatives::AltDefaultList default_alternatives_callback( PkgName name )
00488         {
00489                 return Alternatives::AltDefaultList();
00490         }
00491 
00495         static WhatToDoWithUnresolvable default_unresolvable_callback(
00496             PkgDep* solver, const PkgRelation& rel, PMSolvablePtr& p);
00497 
00498 
00501         void inconsistent_to_candidates(PkgSet& candidates);
00502         
00503 public:
00504         PkgDep( PkgSet& instd, const PkgSet& avail,
00505                         AlternativesCallback alternatives_callback = default_alternatives_callback,
00506                         alternatives_mode m = default_alternatives_mode );
00507                 
00508 //      PkgDep(  const PkgSet& instd, alternatives_mode m=default_alternatives_mode)
00509 //              : alt_mode(m), installed(instd), available(*default_avail), _pool(pool) {}
00510 /*      PkgDep( alternatives_mode m = default_alternatives_mode )
00511                 : alt_mode(m), installed(PkgSet(DTagListI0())),
00512                   available(*default_avail) {}
00513 */
00517         bool install( PkgSet& candidates,
00518                           ResultList& good,
00519                           ErrorResultList& bad,
00520                           ErrorResultList& out_obsoleted,
00521                           bool commit_to_installed = true,
00522                           bool check_inconsistent = false);
00526         void remove( SolvableList& pkgs );
00528         bool consistent( ErrorResultList& failures );
00542         /*
00543         bool upgrade(   PkgSet&candidates, ResultList& out_good,
00544                         ErrorResultList& out_bad, SolvableList& to_remove,
00545                         bool all = false, bool none = false,
00546                         unsigned max_remove = default_max_remove );
00547         */
00548 
00553         bool solvesystemnoauto(
00554                 PkgSet &candidates,
00555                 ResultList& out_good,
00556                 ErrorResultList& out_bad,
00557                 ErrorResultList& out_obsoleted);
00558 
00559 
00561         const PkgSet& current_installed() { return installed; }
00562         
00564         const PkgSet& current_available() { return available; }
00565 
00566         // set defaults
00567 /*
00568         static void set_default_available( const PkgSet& av ) {
00569                 default_avail = &av;
00570         }
00571 */
00572         void set_alternatives_mode(alternatives_mode mode)
00573         {
00574                 alt_mode = mode;
00575         }
00576         
00577         void set_alternatives_callback(Alternatives::AltDefaultList (*alternatives_callback)( PkgName name ))
00578         {
00579                 _alternatives_callback = alternatives_callback;
00580         }
00581 
00587         void set_unresolvable_callback(DealWithUnresolvable_callback callback)
00588         {
00589             _unresolvable_callback = callback;
00590         }
00591 
00596         void install_installed(bool yes)
00597             { _install_installed = yes; }
00598 
00599         static void set_default_alternatives_mode( alternatives_mode m ) {
00600                 default_alternatives_mode = m;
00601         }
00602 
00603         static void set_default_max_remove( unsigned mr ) {
00604                 default_max_remove = mr;
00605         }
00606 
00607     public: // static members
00608 
00611         static void remove_package( PkgSet *set, PMSolvablePtr pkg,
00612                                                  SolvableList& to_remove);
00613 
00617         static unsigned count_providers_for( const PkgSet* set, const PkgRelation& req );
00618 };
00619 
00620 // output.cc
00621 std::ostream& operator<<( std::ostream& os, const PkgDep::Result& res );
00622 std::ostream& operator<<( std::ostream& os, const PkgDep::ErrorResult& res );
00623 std::ostream& operator<<( std::ostream& os, const PkgDep::RelInfoList& rl );
00624 std::ostream& operator<<( std::ostream& os, const std::list<PkgDep::Alternative>& al );
00625 std::ostream& operator<<( std::ostream& os, const PkgDep::NameList& nl );
00626 std::ostream& operator<<( std::ostream& os, const PkgDep::NeededEditionRange& range );
00627 
00628 #endif  /* _PkgDep_h */
00629 
00630 // Local Variables:
00631 // tab-width: 4
00632 // End:

Generated on Fri Nov 9 14:30:31 2007 for yast2-packagemanager by doxygen 1.3.6