apt  @VERSION@
depcache.h
00001 // -*- mode: c++; mode: fold -*-
00002 // Description                                                          /*{{{*/
00003 // $Id: depcache.h,v 1.14 2001/02/20 07:03:17 jgg Exp $
00004 /* ######################################################################
00005 
00006    DepCache - Dependency Extension data for the cache
00007    
00008    This class stores the cache data and a set of extension structures for
00009    monitoring the current state of all the packages. It also generates and
00010    caches the 'install' state of many things. This refers to the state of the
00011    package after an install has been run.
00012 
00013    The StateCache::State field can be -1,0,1,2 which is <,=,>,no current.
00014    StateCache::Mode is which of the 3 fields is active.
00015    
00016    This structure is important to support the readonly status of the cache 
00017    file. When the data is saved the cache will be refereshed from our 
00018    internal rep and written to disk. Then the actual persistant data 
00019    files will be put on the disk.
00020 
00021    Each dependency is compared against 3 target versions to produce to
00022    3 dependency results.
00023      Now - Compared using the Currently install version
00024      Install - Compared using the install version (final state)
00025      CVer - (Candidate Verion) Compared using the Candidate Version
00026    The candidate and now results are used to decide wheather a package
00027    should be automatically installed or if it should be left alone.
00028    
00029    Remember, the Candidate Version is selected based on the distribution
00030    settings for the Package. The Install Version is selected based on the
00031    state (Delete, Keep, Install) field and can be either the Current Version
00032    or the Candidate version.
00033    
00034    The Candidate version is what is shown the 'Install Version' field.
00035    
00036    ##################################################################### */
00037                                                                         /*}}}*/
00038 #ifndef PKGLIB_DEPCACHE_H
00039 #define PKGLIB_DEPCACHE_H
00040 
00041 #include <apt-pkg/configuration.h>
00042 #include <apt-pkg/pkgcache.h>
00043 
00044 #include <vector>
00045 #include <memory>
00046 #include <set>
00047 #include <list>
00048 
00049 #ifndef APT_8_CLEANER_HEADERS
00050 #include <apt-pkg/progress.h>
00051 #include <apt-pkg/error.h>
00052 #endif
00053 
00054 class OpProgress;
00055 
00056 class pkgDepCache : protected pkgCache::Namespace
00057 {
00058    public:
00059 
00061    class InRootSetFunc
00062    {
00063    public:
00064      virtual bool InRootSet(const pkgCache::PkgIterator &pkg) {return false;};
00065      virtual ~InRootSetFunc() {};
00066    };
00067 
00068    private:
00085    void MarkPackage(const pkgCache::PkgIterator &pkg,
00086                     const pkgCache::VerIterator &ver,
00087                     bool const &follow_recommends,
00088                     bool const &follow_suggests);
00089 
00103    bool MarkRequired(InRootSetFunc &rootFunc);
00104 
00114    bool Sweep();
00115 
00116    public:
00117    
00118    // These flags are used in DepState
00119    enum DepFlags {DepNow = (1 << 0),DepInstall = (1 << 1),DepCVer = (1 << 2),
00120                   DepGNow = (1 << 3),DepGInstall = (1 << 4),DepGCVer = (1 << 5)};
00121 
00122    // These flags are used in StateCache::DepState
00123    enum DepStateFlags {DepNowPolicy = (1 << 0), DepNowMin = (1 << 1),
00124                        DepInstPolicy = (1 << 2), DepInstMin = (1 << 3),
00125                        DepCandPolicy = (1 << 4), DepCandMin = (1 << 5)};
00126    
00127    // These flags are used in StateCache::iFlags
00128    enum InternalFlags {AutoKept = (1 << 0), Purge = (1 << 1), ReInstall = (1 << 2), Protected = (1 << 3)};
00129       
00130    enum VersionTypes {NowVersion, InstallVersion, CandidateVersion};
00131    enum ModeList {ModeDelete = 0, ModeKeep = 1, ModeInstall = 2};
00132 
00156    class ActionGroup
00157    {
00158        pkgDepCache &cache;
00159 
00160        bool released;
00161 
00163        ActionGroup(const ActionGroup &other);
00164    public:
00173        ActionGroup(pkgDepCache &cache);
00174 
00179        void release();
00180 
00186        ~ActionGroup();
00187    };
00188 
00192    class DefaultRootSetFunc : public InRootSetFunc, public Configuration::MatchAgainstConfig
00193    {
00194    public:
00195      DefaultRootSetFunc() : Configuration::MatchAgainstConfig("APT::NeverAutoRemove") {};
00196      virtual ~DefaultRootSetFunc() {};
00197 
00198      bool InRootSet(const pkgCache::PkgIterator &pkg) { return pkg.end() == false && Match(pkg.Name()); };
00199    };
00200 
00201    struct StateCache
00202    {
00203       // Epoch stripped text versions of the two version fields
00204       const char *CandVersion;
00205       const char *CurVersion;
00206 
00207       // Pointer to the candidate install version. 
00208       Version *CandidateVer;
00209 
00210       // Pointer to the install version.
00211       Version *InstallVer;
00212       
00213       // Copy of Package::Flags
00214       unsigned short Flags;
00215       unsigned short iFlags;           // Internal flags
00216 
00218       bool Marked;
00219 
00226       bool Garbage;
00227 
00228       // Various tree indicators
00229       signed char Status;              // -1,0,1,2
00230       unsigned char Mode;              // ModeList
00231       unsigned char DepState;          // DepState Flags
00232 
00233       // Update of candidate version
00234       const char *StripEpoch(const char *Ver);
00235       void Update(PkgIterator Pkg,pkgCache &Cache);
00236       
00237       // Various test members for the current status of the package
00238       inline bool NewInstall() const {return Status == 2 && Mode == ModeInstall;};
00239       inline bool Delete() const {return Mode == ModeDelete;};
00240       inline bool Purge() const {return Delete() == true && (iFlags & pkgDepCache::Purge) == pkgDepCache::Purge; };
00241       inline bool Keep() const {return Mode == ModeKeep;};
00242       inline bool Protect() const {return (iFlags & Protected) == Protected;};
00243       inline bool Upgrade() const {return Status > 0 && Mode == ModeInstall;};
00244       inline bool Upgradable() const {return Status >= 1;};
00245       inline bool Downgrade() const {return Status < 0 && Mode == ModeInstall;};
00246       inline bool Held() const {return Status != 0 && Keep();};
00247       inline bool NowBroken() const {return (DepState & DepNowMin) != DepNowMin;};
00248       inline bool NowPolicyBroken() const {return (DepState & DepNowPolicy) != DepNowPolicy;};
00249       inline bool InstBroken() const {return (DepState & DepInstMin) != DepInstMin;};
00250       inline bool InstPolicyBroken() const {return (DepState & DepInstPolicy) != DepInstPolicy;};
00251       inline bool Install() const {return Mode == ModeInstall;};
00252       inline bool ReInstall() const {return Delete() == false && (iFlags & pkgDepCache::ReInstall) == pkgDepCache::ReInstall;};
00253       inline VerIterator InstVerIter(pkgCache &Cache)
00254                 {return VerIterator(Cache,InstallVer);};
00255       inline VerIterator CandidateVerIter(pkgCache &Cache)
00256                 {return VerIterator(Cache,CandidateVer);};
00257    };
00258    
00259    // Helper functions
00260    void BuildGroupOrs(VerIterator const &V);
00261    void UpdateVerState(PkgIterator Pkg);
00262 
00263    // User Policy control
00264    class Policy
00265    {
00266       public:
00267       Policy() {
00268          InstallRecommends = _config->FindB("APT::Install-Recommends", false);
00269          InstallSuggests = _config->FindB("APT::Install-Suggests", false);
00270       }
00271 
00272       virtual VerIterator GetCandidateVer(PkgIterator const &Pkg);
00273       virtual bool IsImportantDep(DepIterator const &Dep);
00274       virtual signed short GetPriority(PkgIterator const &Pkg);
00275       virtual signed short GetPriority(PkgFileIterator const &File);
00276 
00277       virtual ~Policy() {};
00278 
00279       private:
00280       bool InstallRecommends;
00281       bool InstallSuggests;
00282    };
00283 
00284    private:
00288    int group_level;
00289 
00290    friend class ActionGroup;
00291      
00292    protected:
00293 
00294    // State information
00295    pkgCache *Cache;
00296    StateCache *PkgState;
00297    unsigned char *DepState;
00298 
00300    signed long long iUsrSize;
00302    unsigned long long iDownloadSize;
00303    unsigned long iInstCount;
00304    unsigned long iDelCount;
00305    unsigned long iKeepCount;
00306    unsigned long iBrokenCount;
00307    unsigned long iPolicyBrokenCount;
00308    unsigned long iBadCount;
00309 
00310    bool DebugMarker;
00311    bool DebugAutoInstall;
00312 
00313    Policy *delLocalPolicy;           // For memory clean up..
00314    Policy *LocalPolicy;
00315    
00316    // Check for a matching provides
00317    bool CheckDep(DepIterator Dep,int Type,PkgIterator &Res);
00318    inline bool CheckDep(DepIterator Dep,int Type)
00319    {
00320       PkgIterator Res(*this,0);
00321       return CheckDep(Dep,Type,Res);
00322    }
00323    
00324    // Computes state information for deps and versions (w/o storing)
00325    unsigned char DependencyState(DepIterator &D);
00326    unsigned char VersionState(DepIterator D,unsigned char Check,
00327                               unsigned char SetMin,
00328                               unsigned char SetPolicy);
00329 
00330    // Recalculates various portions of the cache, call after changing something
00331    void Update(DepIterator Dep);           // Mostly internal
00332    void Update(PkgIterator const &P);
00333    
00334    // Count manipulators
00335    void AddSizes(const PkgIterator &Pkg, bool const Invert = false);
00336    inline void RemoveSizes(const PkgIterator &Pkg) {AddSizes(Pkg, true);};
00337    void AddStates(const PkgIterator &Pkg, bool const Invert = false);
00338    inline void RemoveStates(const PkgIterator &Pkg) {AddStates(Pkg,true);};
00339    
00340    public:
00341 
00342    // Legacy.. We look like a pkgCache
00343    inline operator pkgCache &() {return *Cache;};
00344    inline Header &Head() {return *Cache->HeaderP;};
00345    inline GrpIterator GrpBegin() {return Cache->GrpBegin();};
00346    inline PkgIterator PkgBegin() {return Cache->PkgBegin();};
00347    inline GrpIterator FindGrp(std::string const &Name) {return Cache->FindGrp(Name);};
00348    inline PkgIterator FindPkg(std::string const &Name) {return Cache->FindPkg(Name);};
00349    inline PkgIterator FindPkg(std::string const &Name, std::string const &Arch) {return Cache->FindPkg(Name, Arch);};
00350 
00351    inline pkgCache &GetCache() {return *Cache;};
00352    inline pkgVersioningSystem &VS() {return *Cache->VS;};
00353    
00354    // Policy implementation
00355    inline VerIterator GetCandidateVer(PkgIterator const &Pkg) {return LocalPolicy->GetCandidateVer(Pkg);};
00356    inline bool IsImportantDep(DepIterator Dep) {return LocalPolicy->IsImportantDep(Dep);};
00357    inline Policy &GetPolicy() {return *LocalPolicy;};
00358    
00359    // Accessors
00360    inline StateCache &operator [](PkgIterator const &I) {return PkgState[I->ID];};
00361    inline unsigned char &operator [](DepIterator const &I) {return DepState[I->ID];};
00362 
00371    virtual InRootSetFunc *GetRootSetFunc();
00372 
00375    virtual bool MarkFollowsRecommends();
00376 
00379    virtual bool MarkFollowsSuggests();
00380 
00390    bool MarkAndSweep(InRootSetFunc &rootFunc)
00391    {
00392      return MarkRequired(rootFunc) && Sweep();
00393    }
00394 
00395    bool MarkAndSweep()
00396    {
00397      std::auto_ptr<InRootSetFunc> f(GetRootSetFunc());
00398      if(f.get() != NULL)
00399        return MarkAndSweep(*f.get());
00400      else
00401        return false;
00402    }
00403 
00406    // @{
00407    bool MarkKeep(PkgIterator const &Pkg, bool Soft = false,
00408                  bool FromUser = true, unsigned long Depth = 0);
00409    bool MarkDelete(PkgIterator const &Pkg, bool MarkPurge = false,
00410                    unsigned long Depth = 0, bool FromUser = true);
00411    bool MarkInstall(PkgIterator const &Pkg,bool AutoInst = true,
00412                     unsigned long Depth = 0, bool FromUser = true,
00413                     bool ForceImportantDeps = false);
00414    void MarkProtected(PkgIterator const &Pkg) { PkgState[Pkg->ID].iFlags |= Protected; };
00415 
00416    void SetReInstall(PkgIterator const &Pkg,bool To);
00417    void SetCandidateVersion(VerIterator TargetVer);
00418    bool SetCandidateRelease(pkgCache::VerIterator TargetVer,
00419                                 std::string const &TargetRel);
00434    bool SetCandidateRelease(pkgCache::VerIterator TargetVer,
00435                             std::string const &TargetRel,
00436                             std::list<std::pair<pkgCache::VerIterator, pkgCache::VerIterator> > &Changed);
00437 
00439    void MarkAuto(const PkgIterator &Pkg, bool Auto);
00440    // @}
00441 
00458    virtual bool IsInstallOk(const PkgIterator &Pkg,bool AutoInst = true,
00459                             unsigned long Depth = 0, bool FromUser = true);
00460 
00477    virtual bool IsDeleteOk(const PkgIterator &Pkg,bool MarkPurge = false,
00478                             unsigned long Depth = 0, bool FromUser = true);
00479 
00480    // read persistent states
00481    bool readStateFile(OpProgress *prog);
00482    bool writeStateFile(OpProgress *prog, bool InstalledOnly=true);
00483    
00484    // Size queries
00485    inline signed long long UsrSize() {return iUsrSize;};
00486    inline unsigned long long DebSize() {return iDownloadSize;};
00487    inline unsigned long DelCount() {return iDelCount;};
00488    inline unsigned long KeepCount() {return iKeepCount;};
00489    inline unsigned long InstCount() {return iInstCount;};
00490    inline unsigned long BrokenCount() {return iBrokenCount;};
00491    inline unsigned long PolicyBrokenCount() {return iPolicyBrokenCount;};
00492    inline unsigned long BadCount() {return iBadCount;};
00493 
00494    bool Init(OpProgress *Prog);
00495    // Generate all state information
00496    void Update(OpProgress *Prog = 0);
00497 
00498    pkgDepCache(pkgCache *Cache,Policy *Plcy = 0);
00499    virtual ~pkgDepCache();
00500 
00501    private:
00502    bool IsModeChangeOk(ModeList const mode, PkgIterator const &Pkg,
00503                         unsigned long const Depth, bool const FromUser);
00504 };
00505 
00506 #endif