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 #include <apt-pkg/progress.h>
00044 #include <apt-pkg/error.h>
00045 
00046 #include <vector>
00047 #include <memory>
00048 #include <set>
00049 
00050 class pkgDepCache : protected pkgCache::Namespace
00051 {
00052    public:
00053 
00055    class InRootSetFunc
00056    {
00057    public:
00058      virtual bool InRootSet(const pkgCache::PkgIterator &pkg) {return false;};
00059      virtual ~InRootSetFunc() {};
00060    };
00061 
00062    private:
00079    void MarkPackage(const pkgCache::PkgIterator &pkg,
00080                     const pkgCache::VerIterator &ver,
00081                     bool const &follow_recommends,
00082                     bool const &follow_suggests);
00083 
00097    bool MarkRequired(InRootSetFunc &rootFunc);
00098 
00108    bool Sweep();
00109 
00110    public:
00111    
00112    // These flags are used in DepState
00113    enum DepFlags {DepNow = (1 << 0),DepInstall = (1 << 1),DepCVer = (1 << 2),
00114                   DepGNow = (1 << 3),DepGInstall = (1 << 4),DepGCVer = (1 << 5)};
00115 
00116    // These flags are used in StateCache::DepState
00117    enum DepStateFlags {DepNowPolicy = (1 << 0), DepNowMin = (1 << 1),
00118                        DepInstPolicy = (1 << 2), DepInstMin = (1 << 3),
00119                        DepCandPolicy = (1 << 4), DepCandMin = (1 << 5)};
00120    
00121    // These flags are used in StateCache::iFlags
00122    enum InternalFlags {AutoKept = (1 << 0), Purge = (1 << 1), ReInstall = (1 << 2), Protected = (1 << 3)};
00123       
00124    enum VersionTypes {NowVersion, InstallVersion, CandidateVersion};
00125    enum ModeList {ModeDelete = 0, ModeKeep = 1, ModeInstall = 2};
00126 
00150    class ActionGroup
00151    {
00152        pkgDepCache &cache;
00153 
00154        bool released;
00155 
00157        ActionGroup(const ActionGroup &other);
00158    public:
00167        ActionGroup(pkgDepCache &cache);
00168 
00173        void release();
00174 
00180        ~ActionGroup();
00181    };
00182 
00186    class DefaultRootSetFunc : public InRootSetFunc, public Configuration::MatchAgainstConfig
00187    {
00188    public:
00189      DefaultRootSetFunc() : Configuration::MatchAgainstConfig("APT::NeverAutoRemove") {};
00190      virtual ~DefaultRootSetFunc() {};
00191 
00192      bool InRootSet(const pkgCache::PkgIterator &pkg) { return pkg.end() == false && Match(pkg.Name()); };
00193    };
00194 
00195    struct StateCache
00196    {
00197       // Epoch stripped text versions of the two version fields
00198       const char *CandVersion;
00199       const char *CurVersion;
00200 
00201       // Pointer to the candidate install version. 
00202       Version *CandidateVer;
00203 
00204       // Pointer to the install version.
00205       Version *InstallVer;
00206       
00207       // Copy of Package::Flags
00208       unsigned short Flags;
00209       unsigned short iFlags;           // Internal flags
00210 
00212       bool Marked;
00213 
00220       bool Garbage;
00221 
00222       // Various tree indicators
00223       signed char Status;              // -1,0,1,2
00224       unsigned char Mode;              // ModeList
00225       unsigned char DepState;          // DepState Flags
00226 
00227       // Update of candidate version
00228       const char *StripEpoch(const char *Ver);
00229       void Update(PkgIterator Pkg,pkgCache &Cache);
00230       
00231       // Various test members for the current status of the package
00232       inline bool NewInstall() const {return Status == 2 && Mode == ModeInstall;};
00233       inline bool Delete() const {return Mode == ModeDelete;};
00234       inline bool Purge() const {return Delete() == true && (iFlags & pkgDepCache::Purge) == pkgDepCache::Purge; };
00235       inline bool Keep() const {return Mode == ModeKeep;};
00236       inline bool Upgrade() const {return Status > 0 && Mode == ModeInstall;};
00237       inline bool Upgradable() const {return Status >= 1;};
00238       inline bool Downgrade() const {return Status < 0 && Mode == ModeInstall;};
00239       inline bool Held() const {return Status != 0 && Keep();};
00240       inline bool NowBroken() const {return (DepState & DepNowMin) != DepNowMin;};
00241       inline bool NowPolicyBroken() const {return (DepState & DepNowPolicy) != DepNowPolicy;};
00242       inline bool InstBroken() const {return (DepState & DepInstMin) != DepInstMin;};
00243       inline bool InstPolicyBroken() const {return (DepState & DepInstPolicy) != DepInstPolicy;};
00244       inline bool Install() const {return Mode == ModeInstall;};
00245       inline bool ReInstall() const {return Delete() == false && (iFlags & pkgDepCache::ReInstall) == pkgDepCache::ReInstall;};
00246       inline VerIterator InstVerIter(pkgCache &Cache)
00247                 {return VerIterator(Cache,InstallVer);};
00248       inline VerIterator CandidateVerIter(pkgCache &Cache)
00249                 {return VerIterator(Cache,CandidateVer);};
00250    };
00251    
00252    // Helper functions
00253    void BuildGroupOrs(VerIterator const &V);
00254    void UpdateVerState(PkgIterator Pkg);
00255 
00256    // User Policy control
00257    class Policy
00258    {
00259       public:
00260       
00261       virtual VerIterator GetCandidateVer(PkgIterator const &Pkg);
00262       virtual bool IsImportantDep(DepIterator const &Dep);
00263       
00264       virtual ~Policy() {};
00265    };
00266 
00267    private:
00271    int group_level;
00272 
00273    friend class ActionGroup;
00274      
00275    protected:
00276 
00277    // State information
00278    pkgCache *Cache;
00279    StateCache *PkgState;
00280    unsigned char *DepState;
00281 
00283    signed long long iUsrSize;
00285    unsigned long long iDownloadSize;
00286    unsigned long iInstCount;
00287    unsigned long iDelCount;
00288    unsigned long iKeepCount;
00289    unsigned long iBrokenCount;
00290    unsigned long iPolicyBrokenCount;
00291    unsigned long iBadCount;
00292 
00293    bool DebugMarker;
00294    bool DebugAutoInstall;
00295 
00296    Policy *delLocalPolicy;           // For memory clean up..
00297    Policy *LocalPolicy;
00298    
00299    // Check for a matching provides
00300    bool CheckDep(DepIterator Dep,int Type,PkgIterator &Res);
00301    inline bool CheckDep(DepIterator Dep,int Type)
00302    {
00303       PkgIterator Res(*this,0);
00304       return CheckDep(Dep,Type,Res);
00305    }
00306    
00307    // Computes state information for deps and versions (w/o storing)
00308    unsigned char DependencyState(DepIterator &D);
00309    unsigned char VersionState(DepIterator D,unsigned char Check,
00310                               unsigned char SetMin,
00311                               unsigned char SetPolicy);
00312 
00313    // Recalculates various portions of the cache, call after changing something
00314    void Update(DepIterator Dep);           // Mostly internal
00315    void Update(PkgIterator const &P);
00316    
00317    // Count manipulators
00318    void AddSizes(const PkgIterator &Pkg, bool const &Invert = false);
00319    inline void RemoveSizes(const PkgIterator &Pkg) {AddSizes(Pkg, true);};
00320    void AddSizes(const PkgIterator &Pkg,signed long Mult) __deprecated;
00321    void AddStates(const PkgIterator &Pkg,int Add = 1);
00322    inline void RemoveStates(const PkgIterator &Pkg) {AddStates(Pkg,-1);};
00323    
00324    public:
00325 
00326    // Legacy.. We look like a pkgCache
00327    inline operator pkgCache &() {return *Cache;};
00328    inline Header &Head() {return *Cache->HeaderP;};
00329    inline GrpIterator GrpBegin() {return Cache->GrpBegin();};
00330    inline PkgIterator PkgBegin() {return Cache->PkgBegin();};
00331    inline GrpIterator FindGrp(string const &Name) {return Cache->FindGrp(Name);};
00332    inline PkgIterator FindPkg(string const &Name) {return Cache->FindPkg(Name);};
00333    inline PkgIterator FindPkg(string const &Name, string const &Arch) {return Cache->FindPkg(Name, Arch);};
00334 
00335    inline pkgCache &GetCache() {return *Cache;};
00336    inline pkgVersioningSystem &VS() {return *Cache->VS;};
00337    
00338    // Policy implementation
00339    inline VerIterator GetCandidateVer(PkgIterator const &Pkg) {return LocalPolicy->GetCandidateVer(Pkg);};
00340    inline bool IsImportantDep(DepIterator Dep) {return LocalPolicy->IsImportantDep(Dep);};
00341    inline Policy &GetPolicy() {return *LocalPolicy;};
00342    
00343    // Accessors
00344    inline StateCache &operator [](PkgIterator const &I) {return PkgState[I->ID];};
00345    inline unsigned char &operator [](DepIterator const &I) {return DepState[I->ID];};
00346 
00355    virtual InRootSetFunc *GetRootSetFunc();
00356 
00359    virtual bool MarkFollowsRecommends();
00360 
00363    virtual bool MarkFollowsSuggests();
00364 
00374    bool MarkAndSweep(InRootSetFunc &rootFunc)
00375    {
00376      return MarkRequired(rootFunc) && Sweep();
00377    }
00378 
00379    bool MarkAndSweep()
00380    {
00381      std::auto_ptr<InRootSetFunc> f(GetRootSetFunc());
00382      if(f.get() != NULL)
00383        return MarkAndSweep(*f.get());
00384      else
00385        return false;
00386    }
00387 
00390    // @{
00391    void MarkKeep(PkgIterator const &Pkg, bool Soft = false,
00392                  bool FromUser = true, unsigned long Depth = 0);
00393    void MarkDelete(PkgIterator const &Pkg, bool MarkPurge = false,
00394                    unsigned long Depth = 0, bool FromUser = true);
00395    void MarkInstall(PkgIterator const &Pkg,bool AutoInst = true,
00396                     unsigned long Depth = 0, bool FromUser = true,
00397                     bool ForceImportantDeps = false);
00398    void MarkProtected(PkgIterator const &Pkg) { PkgState[Pkg->ID].iFlags |= Protected; };
00399 
00400    void SetReInstall(PkgIterator const &Pkg,bool To);
00401    // FIXME: Remove the unused boolean parameter on abi break
00402    void SetCandidateVersion(VerIterator TargetVer, bool const &Pseudo = true);
00403    bool SetCandidateRelease(pkgCache::VerIterator TargetVer,
00404                                 std::string const &TargetRel);
00419    bool SetCandidateRelease(pkgCache::VerIterator TargetVer,
00420                             std::string const &TargetRel,
00421                             std::list<std::pair<pkgCache::VerIterator, pkgCache::VerIterator> > &Changed);
00422 
00424    void MarkAuto(const PkgIterator &Pkg, bool Auto);
00425    // @}
00426 
00443    virtual bool IsInstallOk(const PkgIterator &Pkg,bool AutoInst = true,
00444                             unsigned long Depth = 0, bool FromUser = true);
00445 
00462    virtual bool IsDeleteOk(const PkgIterator &Pkg,bool MarkPurge = false,
00463                             unsigned long Depth = 0, bool FromUser = true);
00464 
00465    // read persistent states
00466    bool readStateFile(OpProgress *prog);
00467    bool writeStateFile(OpProgress *prog, bool InstalledOnly=true);
00468    
00469    // Size queries
00470    inline signed long long UsrSize() {return iUsrSize;};
00471    inline unsigned long long DebSize() {return iDownloadSize;};
00472    inline unsigned long DelCount() {return iDelCount;};
00473    inline unsigned long KeepCount() {return iKeepCount;};
00474    inline unsigned long InstCount() {return iInstCount;};
00475    inline unsigned long BrokenCount() {return iBrokenCount;};
00476    inline unsigned long PolicyBrokenCount() {return iPolicyBrokenCount;};
00477    inline unsigned long BadCount() {return iBadCount;};
00478 
00479    bool Init(OpProgress *Prog);
00480    // Generate all state information
00481    void Update(OpProgress *Prog = 0);
00482 
00483    pkgDepCache(pkgCache *Cache,Policy *Plcy = 0);
00484    virtual ~pkgDepCache();
00485 
00486    private:
00487    // Helper for Update(OpProgress) to remove pseudoinstalled arch all packages
00488    // FIXME: they are private so shouldn't affect abi, but just in case…
00489    __deprecated bool RemovePseudoInstalledPkg(PkgIterator &Pkg, std::set<unsigned long> &recheck) { return true; };
00490    __deprecated bool ReInstallPseudoForGroup(unsigned long const &Grp, std::set<unsigned long> &recheck) { return true; };
00491    __deprecated bool ReInstallPseudoForGroup(pkgCache::PkgIterator const &P, std::set<unsigned long> &recheck) { return true; };
00492 
00493 
00494    bool IsModeChangeOk(ModeList const mode, PkgIterator const &Pkg,
00495                         unsigned long const Depth, bool const FromUser);
00496 };
00497 
00498 #endif