LTP GCOV extension - code coverage report
Current view: | directory - usr/include/apt-pkg - depcache.h
Test: | lcov.info
Date: | 2008-08-14 |  | Instrumented lines: | 6
Code covered: | 100.0 % |  | Executed lines: | 6

           1                 : // -*- mode: c++; mode: fold -*-
           2                 : // Description                                                          /*{{{*/
           3                 : // $Id: depcache.h,v 1.14 2001/02/20 07:03:17 jgg Exp $
           4                 : /* ######################################################################
           5                 :
           6                 :    DepCache - Dependency Extension data for the cache
           7                 :
           8                 :    This class stores the cache data and a set of extension structures for
           9                 :    monitoring the current state of all the packages. It also generates and
          10                 :    caches the 'install' state of many things. This refers to the state of the
          11                 :    package after an install has been run.
          12                 :
          13                 :    The StateCache::State field can be -1,0,1,2 which is <,=,>,no current.
          14                 :    StateCache::Mode is which of the 3 fields is active.
          15                 :
          16                 :    This structure is important to support the readonly status of the cache
          17                 :    file. When the data is saved the cache will be refereshed from our
          18                 :    internal rep and written to disk. Then the actual persistant data
          19                 :    files will be put on the disk.
          20                 :
          21                 :    Each dependency is compared against 3 target versions to produce to
          22                 :    3 dependency results.
          23                 :      Now - Compared using the Currently install version
          24                 :      Install - Compared using the install version (final state)
          25                 :      CVer - (Candidate Verion) Compared using the Candidate Version
          26                 :    The candidate and now results are used to decide wheather a package
          27                 :    should be automatically installed or if it should be left alone.
          28                 :
          29                 :    Remember, the Candidate Version is selected based on the distribution
          30                 :    settings for the Package. The Install Version is selected based on the
          31                 :    state (Delete, Keep, Install) field and can be either the Current Version
          32                 :    or the Candidate version.
          33                 :
          34                 :    The Candidate version is what is shown the 'Install Version' field.
          35                 :
          36                 :    ##################################################################### */
          37                 :                                                                         /*}}}*/
          38                 : #ifndef PKGLIB_DEPCACHE_H
          39                 : #define PKGLIB_DEPCACHE_H
          40                 :
          41                 :
          42                 : #include <apt-pkg/pkgcache.h>
          43                 : #include <apt-pkg/progress.h>
          44                 :
          45                 : #include <regex.h>
          46                 :
          47                 : #include <vector>
          48                 : #include <memory>
          49                 :
          50                 : class pkgDepCache : protected pkgCache::Namespace
          51                 : {
          52                 :    public:
          53                 :
          54                 :    /** \brief An arbitrary predicate on packages. */
          55                 :    class InRootSetFunc
          56                 :    {
          57                 :    public:
          58                 :      virtual bool InRootSet(const pkgCache::PkgIterator &pkg) {return false;};
          59                 :      virtual ~InRootSetFunc() {};
          60                 :    };
          61                 :
          62                 :    private:
          63                 :    /** \brief Mark a single package and all its unmarked important
          64                 :     *  dependencies during mark-and-sweep.
          65                 :     *
          66                 :     *  Recursively invokes itself to mark all dependencies of the
          67                 :     *  package.
          68                 :     *
          69                 :     *  \param pkg The package to mark.
          70                 :     *
          71                 :     *  \param ver The version of the package that is to be marked.
          72                 :     *
          73                 :     *  \param follow_recommends If \b true, recommendations of the
          74                 :     *  package will be recursively marked.
          75                 :     *
          76                 :     *  \param follow_suggests If \b true, suggestions of the package
          77                 :     *  will be recursively marked.
          78                 :     */
          79                 :    void MarkPackage(const pkgCache::PkgIterator &pkg,
          80                 :                     const pkgCache::VerIterator &ver,
          81                 :                     bool follow_recommends,
          82                 :                     bool follow_suggests);
          83                 :
          84                 :    /** \brief Update the Marked field of all packages.
          85                 :     *
          86                 :     *  Each package's StateCache::Marked field will be set to \b true
          87                 :     *  if and only if it can be reached from the root set.  By
          88                 :     *  default, the root set consists of the set of manually installed
          89                 :     *  or essential packages, but it can be extended using the
          90                 :     *  parameter #rootFunc.
          91                 :     *
          92                 :     *  \param rootFunc A callback that can be used to add extra
          93                 :     *  packages to the root set.
          94                 :     *
          95                 :     *  \return \b false if an error occurred.
          96                 :     */
          97                 :    bool MarkRequired(InRootSetFunc &rootFunc);
          98                 :
          99                 :    /** \brief Set the StateCache::Garbage flag on all packages that
         100                 :     *  should be removed.
         101                 :     *
         102                 :     *  Packages that were not marked by the last call to #MarkRequired
         103                 :     *  are tested to see whether they are actually garbage.  If so,
         104                 :     *  they are marked as such.
         105                 :     *
         106                 :     *  \return \b false if an error occurred.
         107                 :     */
         108                 :    bool Sweep();
         109                 :
         110                 :    public:
         111                 :
         112                 :    // These flags are used in DepState
         113                 :    enum DepFlags {DepNow = (1 << 0),DepInstall = (1 << 1),DepCVer = (1 << 2),
         114                 :                   DepGNow = (1 << 3),DepGInstall = (1 << 4),DepGCVer = (1 << 5)};
         115                 :
         116                 :    // These flags are used in StateCache::DepState
         117                 :    enum DepStateFlags {DepNowPolicy = (1 << 0), DepNowMin = (1 << 1),
         118                 :                        DepInstPolicy = (1 << 2), DepInstMin = (1 << 3),
         119                 :                        DepCandPolicy = (1 << 4), DepCandMin = (1 << 5)};
         120                 :
         121                 :    // These flags are used in StateCache::iFlags
         122                 :    enum InternalFlags {AutoKept = (1 << 0), Purge = (1 << 1), ReInstall = (1 << 2)};
         123                 :
         124                 :    enum VersionTypes {NowVersion, InstallVersion, CandidateVersion};
         125                 :    enum ModeList {ModeDelete = 0, ModeKeep = 1, ModeInstall = 2};
         126                 :
         127                 :    /** \brief Represents an active action group.
         128                 :     *
         129                 :     *  An action group is a group of actions that are currently being
         130                 :     *  performed.  While an active group is active, certain routine
         131                 :     *  clean-up actions that would normally be performed after every
         132                 :     *  cache operation are delayed until the action group is
         133                 :     *  completed.  This is necessary primarily to avoid inefficiencies
         134                 :     *  when modifying a large number of packages at once.
         135                 :     *
         136                 :     *  This class represents an active action group.  Creating an
         137                 :     *  instance will create an action group; destroying one will
         138                 :     *  destroy the corresponding action group.
         139                 :     *
         140                 :     *  The following operations are suppressed by this class:
         141                 :     *
         142                 :     *    - Keeping the Marked and Garbage flags up to date.
         143                 :     *
         144                 :     *  \note This can be used in the future to easily accumulate
         145                 :     *  atomic actions for undo or to display "what apt did anyway";
         146                 :     *  e.g., change the counter of how many action groups are active
         147                 :     *  to a std::set of pointers to them and use those to store
         148                 :     *  information about what happened in a group in the group.
         149                 :     */
         150                 :    class ActionGroup
         151                 :    {
         152                 :        pkgDepCache &cache;
         153                 :
         154                 :        bool released;
         155                 :
         156                 :        /** Action groups are noncopyable. */
         157                 :        ActionGroup(const ActionGroup &other);
         158                 :    public:
         159                 :        /** \brief Create a new ActionGroup.
         160                 :         *
         161                 :         *  \param cache The cache that this ActionGroup should
         162                 :         *  manipulate.
         163                 :         *
         164                 :         *  As long as this object exists, no automatic cleanup
         165                 :         *  operations will be undertaken.
         166                 :         */
         167                 :        ActionGroup(pkgDepCache &cache);
         168                 :
         169                 :        /** \brief Clean up the action group before it is destroyed.
         170                 :         *
         171                 :         *  If it is destroyed later, no second cleanup wil be run.
         172                 :         */
         173                 :        void release();
         174                 :
         175                 :        /** \brief Destroy the action group.
         176                 :         *
         177                 :         *  If this is the last action group, the automatic cache
         178                 :         *  cleanup operations will be undertaken.
         179                 :         */
         180                 :        ~ActionGroup();
         181                 :    };
         182                 :
         183                 :    /** \brief Returns \b true for packages matching a regular
         184                 :     *  expression in APT::NeverAutoRemove.
         185                 :     */
         186                 :    class DefaultRootSetFunc : public InRootSetFunc
         187                 :    {
         188                 :      std::vector<regex_t *> rootSetRegexp;
         189                 :      bool constructedSuccessfully;
         190                 :
         191                 :    public:
         192                 :      DefaultRootSetFunc();
         193                 :      ~DefaultRootSetFunc();
         194                 :
         195                 :      /** \return \b true if the class initialized successfully, \b
         196                 :       *  false otherwise.  Used to avoid throwing an exception, since
         197                 :       *  APT classes generally don't.
         198                 :       */
         199                 :      bool wasConstructedSuccessfully() const { return constructedSuccessfully; }
         200                 :
         201                 :      bool InRootSet(const pkgCache::PkgIterator &pkg);
         202                 :    };
         203                 :
         204                 :    struct StateCache
         205                 :    {
         206                 :       // Epoch stripped text versions of the two version fields
         207                 :       const char *CandVersion;
         208                 :       const char *CurVersion;
         209                 :
         210                 :       // Pointer to the candidate install version.
         211                 :       Version *CandidateVer;
         212                 :
         213                 :       // Pointer to the install version.
         214                 :       Version *InstallVer;
         215                 :
         216                 :       // Copy of Package::Flags
         217                 :       unsigned short Flags;
         218                 :       unsigned short iFlags;           // Internal flags
         219                 :
         220                 :       /** \brief \b true if this package can be reached from the root set. */
         221                 :       bool Marked;
         222                 :
         223                 :       /** \brief \b true if this package is unused and should be removed.
         224                 :        *
         225                 :        *  This differs from !#Marked, because it is possible that some
         226                 :        *  unreachable packages will be protected from becoming
         227                 :        *  garbage.
         228                 :        */
         229                 :       bool Garbage;
         230                 :
         231                 :       // Various tree indicators
         232                 :       signed char Status;              // -1,0,1,2
         233                 :       unsigned char Mode;              // ModeList
         234                 :       unsigned char DepState;          // DepState Flags
         235                 :
         236                 :       // Update of candidate version
         237                 :       const char *StripEpoch(const char *Ver);
         238                 :       void Update(PkgIterator Pkg,pkgCache &Cache);
         239                 :
         240                 :       // Various test members for the current status of the package
         241                 :       inline bool NewInstall() const {return Status == 2 && Mode == ModeInstall;};
         242            3785 :       inline bool Delete() const {return Mode == ModeDelete;};
         243            3785 :       inline bool Keep() const {return Mode == ModeKeep;};
         244                 :       inline bool Upgrade() const {return Status > 0 && Mode == ModeInstall;};
         245                 :       inline bool Upgradable() const {return Status >= 1;};
         246                 :       inline bool Downgrade() const {return Status < 0 && Mode == ModeInstall;};
         247                 :       inline bool Held() const {return Status != 0 && Keep();};
         248            3785 :       inline bool NowBroken() const {return (DepState & DepNowMin) != DepNowMin;};
         249                 :       inline bool NowPolicyBroken() const {return (DepState & DepNowPolicy) != DepNowPolicy;};
         250            3785 :       inline bool InstBroken() const {return (DepState & DepInstMin) != DepInstMin;};
         251                 :       inline bool InstPolicyBroken() const {return (DepState & DepInstPolicy) != DepInstPolicy;};
         252            3785 :       inline bool Install() const {return Mode == ModeInstall;};
         253                 :       inline VerIterator InstVerIter(pkgCache &Cache)
         254                 :                 {return VerIterator(Cache,InstallVer);};
         255                 :       inline VerIterator CandidateVerIter(pkgCache &Cache)
         256                 :                 {return VerIterator(Cache,CandidateVer);};
         257                 :    };
         258                 :
         259                 :    // Helper functions
         260                 :    void BuildGroupOrs(VerIterator const &V);
         261                 :    void UpdateVerState(PkgIterator Pkg);
         262                 :
         263                 :    // User Policy control
         264                 :    class Policy
         265                 :    {
         266                 :       public:
         267                 :
         268                 :       virtual VerIterator GetCandidateVer(PkgIterator Pkg);
         269                 :       virtual bool IsImportantDep(DepIterator Dep);
         270                 :
         271                 :       virtual ~Policy() {};
         272                 :    };
         273                 :
         274                 :    private:
         275                 :    /** The number of open "action groups"; certain post-action
         276                 :     *  operations are suppressed if this number is > 0.
         277                 :     */
         278                 :    int group_level;
         279                 :
         280                 :    friend class ActionGroup;
         281                 :
         282                 :    protected:
         283                 :
         284                 :    // State information
         285                 :    pkgCache *Cache;
         286                 :    StateCache *PkgState;
         287                 :    unsigned char *DepState;
         288                 :
         289                 :    double iUsrSize;
         290                 :    double iDownloadSize;
         291                 :    unsigned long iInstCount;
         292                 :    unsigned long iDelCount;
         293                 :    unsigned long iKeepCount;
         294                 :    unsigned long iBrokenCount;
         295                 :    unsigned long iPolicyBrokenCount;
         296                 :    unsigned long iBadCount;
         297                 :
         298                 :    Policy *delLocalPolicy;           // For memory clean up..
         299                 :    Policy *LocalPolicy;
         300                 :
         301                 :    // Check for a matching provides
         302                 :    bool CheckDep(DepIterator Dep,int Type,PkgIterator &Res);
         303                 :    inline bool CheckDep(DepIterator Dep,int Type)
         304                 :    {
         305                 :       PkgIterator Res(*this,0);
         306                 :       return CheckDep(Dep,Type,Res);
         307                 :    }
         308                 :
         309                 :    // Computes state information for deps and versions (w/o storing)
         310                 :    unsigned char DependencyState(DepIterator &D);
         311                 :    unsigned char VersionState(DepIterator D,unsigned char Check,
         312                 :                               unsigned char SetMin,
         313                 :                               unsigned char SetPolicy);
         314                 :
         315                 :    // Recalculates various portions of the cache, call after changing something
         316                 :    void Update(DepIterator Dep);           // Mostly internal
         317                 :    void Update(PkgIterator const &P);
         318                 :
         319                 :    // Count manipulators
         320                 :    void AddSizes(const PkgIterator &Pkg,signed long Mult = 1);
         321                 :    inline void RemoveSizes(const PkgIterator &Pkg) {AddSizes(Pkg,-1);};
         322                 :    void AddStates(const PkgIterator &Pkg,int Add = 1);
         323                 :    inline void RemoveStates(const PkgIterator &Pkg) {AddStates(Pkg,-1);};
         324                 :
         325                 :    public:
         326                 :
         327                 :    // Legacy.. We look like a pkgCache
         328                 :    inline operator pkgCache &() {return *Cache;};
         329                 :    inline Header &Head() {return *Cache->HeaderP;};
         330                 :    inline PkgIterator PkgBegin() {return Cache->PkgBegin();};
         331                 :    inline PkgIterator FindPkg(string const &Name) {return Cache->FindPkg(Name);};
         332                 :
         333                 :    inline pkgCache &GetCache() {return *Cache;};
         334                 :    inline pkgVersioningSystem &VS() {return *Cache->VS;};
         335                 :
         336                 :    // Policy implementation
         337                 :    inline VerIterator GetCandidateVer(PkgIterator Pkg) {return LocalPolicy->GetCandidateVer(Pkg);};
         338                 :    inline bool IsImportantDep(DepIterator Dep) {return LocalPolicy->IsImportantDep(Dep);};
         339                 :    inline Policy &GetPolicy() {return *LocalPolicy;};
         340                 :
         341                 :    // Accessors
         342            3787 :    inline StateCache &operator [](PkgIterator const &I) {return PkgState[I->ID];};
         343                 :    inline unsigned char &operator [](DepIterator const &I) {return DepState[I->ID];};
         344                 :
         345                 :    /** \return A function identifying packages in the root set other
         346                 :     *  than manually installed packages and essential packages, or \b
         347                 :     *  NULL if an error occurs.
         348                 :     *
         349                 :     *  \todo Is this the best place for this function?  Perhaps the
         350                 :     *  settings for mark-and-sweep should be stored in a single
         351                 :     *  external class?
         352                 :     */
         353                 :    virtual InRootSetFunc *GetRootSetFunc();
         354                 :
         355                 :    /** \return \b true if the garbage collector should follow recommendations.
         356                 :     */
         357                 :    virtual bool MarkFollowsRecommends();
         358                 :
         359                 :    /** \return \b true if the garbage collector should follow suggestions.
         360                 :     */
         361                 :    virtual bool MarkFollowsSuggests();
         362                 :
         363                 :    /** \brief Update the Marked and Garbage fields of all packages.
         364                 :     *
         365                 :     *  This routine is implicitly invoked after all state manipulators
         366                 :     *  and when an ActionGroup is destroyed.  It invokes #MarkRequired
         367                 :     *  and #Sweep to do its dirty work.
         368                 :     *
         369                 :     *  \param rootFunc A predicate that returns \b true for packages
         370                 :     *  that should be added to the root set.
         371                 :     */
         372                 :    bool MarkAndSweep(InRootSetFunc &rootFunc)
         373                 :    {
         374                 :      return MarkRequired(rootFunc) && Sweep();
         375                 :    }
         376                 :
         377                 :    bool MarkAndSweep()
         378                 :    {
         379                 :      std::auto_ptr<InRootSetFunc> f(GetRootSetFunc());
         380                 :      if(f.get() != NULL)
         381                 :        return MarkAndSweep(*f.get());
         382                 :      else
         383                 :        return false;
         384                 :    }
         385                 :
         386                 :    /** \name State Manipulators
         387                 :     */
         388                 :    // @{
         389                 :    void MarkKeep(PkgIterator const &Pkg, bool Soft = false,
         390                 :                  bool FromUser = true);
         391                 :    void MarkDelete(PkgIterator const &Pkg,bool Purge = false);
         392                 :    void MarkInstall(PkgIterator const &Pkg,bool AutoInst = true,
         393                 :                     unsigned long Depth = 0, bool FromUser = true,
         394                 :                     bool ForceImportantDeps = false);
         395                 :    void SetReInstall(PkgIterator const &Pkg,bool To);
         396                 :    void SetCandidateVersion(VerIterator TargetVer);
         397                 :
         398                 :    /** Set the "is automatically installed" flag of Pkg. */
         399                 :    void MarkAuto(const PkgIterator &Pkg, bool Auto);
         400                 :    // @}
         401                 :
         402                 :    // This is for debuging
         403                 :    void Update(OpProgress *Prog = 0);
         404                 :
         405                 :    // read persistent states
         406                 :    bool readStateFile(OpProgress *prog);
         407                 :    bool writeStateFile(OpProgress *prog, bool InstalledOnly=false);
         408                 :
         409                 :    // Size queries
         410                 :    inline double UsrSize() {return iUsrSize;};
         411                 :    inline double DebSize() {return iDownloadSize;};
         412                 :    inline unsigned long DelCount() {return iDelCount;};
         413                 :    inline unsigned long KeepCount() {return iKeepCount;};
         414                 :    inline unsigned long InstCount() {return iInstCount;};
         415                 :    inline unsigned long BrokenCount() {return iBrokenCount;};
         416                 :    inline unsigned long PolicyBrokenCount() {return iPolicyBrokenCount;};
         417                 :    inline unsigned long BadCount() {return iBadCount;};
         418                 :
         419                 :    bool Init(OpProgress *Prog);
         420                 :
         421                 :    pkgDepCache(pkgCache *Cache,Policy *Plcy = 0);
         422                 :    virtual ~pkgDepCache();
         423                 : };
         424                 :
         425                 : #endif

Generated by: LTP GCOV extension version 1.6