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 Keep() const {return Mode == ModeKeep;};
00235       inline bool Upgrade() const {return Status > 0 && Mode == ModeInstall;};
00236       inline bool Upgradable() const {return Status >= 1;};
00237       inline bool Downgrade() const {return Status < 0 && Mode == ModeInstall;};
00238       inline bool Held() const {return Status != 0 && Keep();};
00239       inline bool NowBroken() const {return (DepState & DepNowMin) != DepNowMin;};
00240       inline bool NowPolicyBroken() const {return (DepState & DepNowPolicy) != DepNowPolicy;};
00241       inline bool InstBroken() const {return (DepState & DepInstMin) != DepInstMin;};
00242       inline bool InstPolicyBroken() const {return (DepState & DepInstPolicy) != DepInstPolicy;};
00243       inline bool Install() const {return Mode == ModeInstall;};
00244       inline VerIterator InstVerIter(pkgCache &Cache)
00245                 {return VerIterator(Cache,InstallVer);};
00246       inline VerIterator CandidateVerIter(pkgCache &Cache)
00247                 {return VerIterator(Cache,CandidateVer);};
00248    };
00249    
00250    // Helper functions
00251    void BuildGroupOrs(VerIterator const &V);
00252    void UpdateVerState(PkgIterator Pkg);
00253 
00254    // User Policy control
00255    class Policy
00256    {
00257       public:
00258       
00259       virtual VerIterator GetCandidateVer(PkgIterator const &Pkg);
00260       virtual bool IsImportantDep(DepIterator const &Dep);
00261       
00262       virtual ~Policy() {};
00263    };
00264 
00265    private:
00269    int group_level;
00270 
00271    friend class ActionGroup;
00272      
00273    protected:
00274 
00275    // State information
00276    pkgCache *Cache;
00277    StateCache *PkgState;
00278    unsigned char *DepState;
00279 
00281    signed long long iUsrSize;
00283    unsigned long long iDownloadSize;
00284    unsigned long iInstCount;
00285    unsigned long iDelCount;
00286    unsigned long iKeepCount;
00287    unsigned long iBrokenCount;
00288    unsigned long iPolicyBrokenCount;
00289    unsigned long iBadCount;
00290 
00291    bool DebugMarker;
00292    bool DebugAutoInstall;
00293 
00294    Policy *delLocalPolicy;           // For memory clean up..
00295    Policy *LocalPolicy;
00296    
00297    // Check for a matching provides
00298    bool CheckDep(DepIterator Dep,int Type,PkgIterator &Res);
00299    inline bool CheckDep(DepIterator Dep,int Type)
00300    {
00301       PkgIterator Res(*this,0);
00302       return CheckDep(Dep,Type,Res);
00303    }
00304    
00305    // Computes state information for deps and versions (w/o storing)
00306    unsigned char DependencyState(DepIterator &D);
00307    unsigned char VersionState(DepIterator D,unsigned char Check,
00308                               unsigned char SetMin,
00309                               unsigned char SetPolicy);
00310 
00311    // Recalculates various portions of the cache, call after changing something
00312    void Update(DepIterator Dep);           // Mostly internal
00313    void Update(PkgIterator const &P);
00314    
00315    // Count manipulators
00316    void AddSizes(const PkgIterator &Pkg, bool const &Invert = false);
00317    inline void RemoveSizes(const PkgIterator &Pkg) {AddSizes(Pkg, true);};
00318    void AddSizes(const PkgIterator &Pkg,signed long Mult) __deprecated;
00319    void AddStates(const PkgIterator &Pkg,int Add = 1);
00320    inline void RemoveStates(const PkgIterator &Pkg) {AddStates(Pkg,-1);};
00321    
00322    public:
00323 
00324    // Legacy.. We look like a pkgCache
00325    inline operator pkgCache &() {return *Cache;};
00326    inline Header &Head() {return *Cache->HeaderP;};
00327    inline GrpIterator GrpBegin() {return Cache->GrpBegin();};
00328    inline PkgIterator PkgBegin() {return Cache->PkgBegin();};
00329    inline GrpIterator FindGrp(string const &Name) {return Cache->FindGrp(Name);};
00330    inline PkgIterator FindPkg(string const &Name) {return Cache->FindPkg(Name);};
00331    inline PkgIterator FindPkg(string const &Name, string const &Arch) {return Cache->FindPkg(Name, Arch);};
00332 
00333    inline pkgCache &GetCache() {return *Cache;};
00334    inline pkgVersioningSystem &VS() {return *Cache->VS;};
00335    
00336    // Policy implementation
00337    inline VerIterator GetCandidateVer(PkgIterator const &Pkg) {return LocalPolicy->GetCandidateVer(Pkg);};
00338    inline bool IsImportantDep(DepIterator Dep) {return LocalPolicy->IsImportantDep(Dep);};
00339    inline Policy &GetPolicy() {return *LocalPolicy;};
00340    
00341    // Accessors
00342    inline StateCache &operator [](PkgIterator const &I) {return PkgState[I->ID];};
00343    inline unsigned char &operator [](DepIterator const &I) {return DepState[I->ID];};
00344 
00353    virtual InRootSetFunc *GetRootSetFunc();
00354 
00357    virtual bool MarkFollowsRecommends();
00358 
00361    virtual bool MarkFollowsSuggests();
00362 
00372    bool MarkAndSweep(InRootSetFunc &rootFunc)
00373    {
00374      return MarkRequired(rootFunc) && Sweep();
00375    }
00376 
00377    bool MarkAndSweep()
00378    {
00379      std::auto_ptr<InRootSetFunc> f(GetRootSetFunc());
00380      if(f.get() != NULL)
00381        return MarkAndSweep(*f.get());
00382      else
00383        return false;
00384    }
00385 
00388    // @{
00389    void MarkKeep(PkgIterator const &Pkg, bool Soft = false,
00390                  bool FromUser = true, unsigned long Depth = 0);
00391    void MarkDelete(PkgIterator const &Pkg, bool Purge = false,
00392                    unsigned long Depth = 0, bool FromUser = true);
00393    void MarkInstall(PkgIterator const &Pkg,bool AutoInst = true,
00394                     unsigned long Depth = 0, bool FromUser = true,
00395                     bool ForceImportantDeps = false);
00396    void MarkProtected(PkgIterator const &Pkg) { PkgState[Pkg->ID].iFlags |= Protected; };
00397 
00398    void SetReInstall(PkgIterator const &Pkg,bool To);
00399    // FIXME: Remove the unused boolean parameter on abi break
00400    void SetCandidateVersion(VerIterator TargetVer, bool const &Pseudo = true);
00401    bool SetCandidateRelease(pkgCache::VerIterator TargetVer,
00402                                 std::string const &TargetRel);
00417    bool SetCandidateRelease(pkgCache::VerIterator TargetVer,
00418                             std::string const &TargetRel,
00419                             std::list<std::pair<pkgCache::VerIterator, pkgCache::VerIterator> > &Changed);
00420 
00422    void MarkAuto(const PkgIterator &Pkg, bool Auto);
00423    // @}
00424 
00441    virtual bool IsInstallOk(const PkgIterator &Pkg,bool AutoInst = true,
00442                             unsigned long Depth = 0, bool FromUser = true);
00443 
00460    virtual bool IsDeleteOk(const PkgIterator &Pkg,bool Purge = false,
00461                             unsigned long Depth = 0, bool FromUser = true);
00462 
00463    // read persistent states
00464    bool readStateFile(OpProgress *prog);
00465    bool writeStateFile(OpProgress *prog, bool InstalledOnly=true);
00466    
00467    // Size queries
00468    inline signed long long UsrSize() {return iUsrSize;};
00469    inline unsigned long long DebSize() {return iDownloadSize;};
00470    inline unsigned long DelCount() {return iDelCount;};
00471    inline unsigned long KeepCount() {return iKeepCount;};
00472    inline unsigned long InstCount() {return iInstCount;};
00473    inline unsigned long BrokenCount() {return iBrokenCount;};
00474    inline unsigned long PolicyBrokenCount() {return iPolicyBrokenCount;};
00475    inline unsigned long BadCount() {return iBadCount;};
00476 
00477    bool Init(OpProgress *Prog);
00478    // Generate all state information
00479    void Update(OpProgress *Prog = 0);
00480 
00481    pkgDepCache(pkgCache *Cache,Policy *Plcy = 0);
00482    virtual ~pkgDepCache();
00483 
00484    private:
00485    // Helper for Update(OpProgress) to remove pseudoinstalled arch all packages
00486    // FIXME: they are private so shouldn't affect abi, but just in case…
00487    __deprecated bool RemovePseudoInstalledPkg(PkgIterator &Pkg, std::set<unsigned long> &recheck) { return true; };
00488    __deprecated bool ReInstallPseudoForGroup(unsigned long const &Grp, std::set<unsigned long> &recheck) { return true; };
00489    __deprecated bool ReInstallPseudoForGroup(pkgCache::PkgIterator const &P, std::set<unsigned long> &recheck) { return true; };
00490 
00491 
00492    bool IsModeChangeOk(ModeList const mode, PkgIterator const &Pkg,
00493                         unsigned long const Depth, bool const FromUser);
00494 };
00495 
00496 #endif