Imported Upstream version 17.23.0
[platform/upstream/libzypp.git] / zypp / pool / PoolImpl.h
index 4551286..60d5cf7 100644 (file)
@@ -17,7 +17,7 @@
 #include "zypp/base/Easy.h"
 #include "zypp/base/LogTools.h"
 #include "zypp/base/SerialNumber.h"
-#include "zypp/base/Deprecated.h"
+#include "zypp/APIConfig.h"
 
 #include "zypp/pool/PoolTraits.h"
 #include "zypp/ResPoolProxy.h"
@@ -61,9 +61,10 @@ namespace zypp
       /** Test whether the lock status differs from the remembered UserLockQuery bit. */
       static int diffLock( const ResStatus & status_r )
       {
-        if ( status_r.isLocked() == status_r.isUserLockQueryMatch() )
+        bool userLock( status_r.isUserLocked() );
+        if ( userLock == status_r.isUserLockQueryMatch() )
           return 0;
-        return status_r.isLocked() ? 1 : -1;
+        return userLock ? 1 : -1;
       }
 
     };
@@ -104,6 +105,57 @@ namespace zypp
   }
 
   ///////////////////////////////////////////////////////////////////
+  namespace solver {
+    namespace detail {
+      void establish( sat::Queue & pseudoItems_r, sat::Queue & pseudoFlags_r );        // in solver/detail/SATResolver.cc
+    }
+  }
+  ///////////////////////////////////////////////////////////////////
+  /// Store initial establish status of pseudo installed items.
+  ///
+  class ResPool::EstablishedStates::Impl
+  {
+  public:
+    Impl()
+    { solver::detail::establish( _pseudoItems, _pseudoFlags ); }
+
+    /** Return all pseudo installed items whose current state differs from their initial one. */
+    ResPool::EstablishedStates::ChangedPseudoInstalled changedPseudoInstalled() const
+    {
+      ChangedPseudoInstalled ret;
+
+      if ( ! _pseudoItems.empty() )
+      {
+       for ( sat::Queue::size_type i = 0; i < _pseudoItems.size(); ++i )
+       {
+         PoolItem pi { sat::Solvable(_pseudoItems[i]) };
+         ResStatus::ValidateValue vorig { validateValue( i ) };
+         if ( pi.status().validate() != vorig )
+           ret[pi] = vorig;
+       }
+      }
+      return ret;
+    }
+
+  private:
+    ResStatus::ValidateValue validateValue( sat::Queue::size_type i ) const
+    {
+      ResStatus::ValidateValue ret { ResStatus::UNDETERMINED };
+      switch ( _pseudoFlags[i] )
+      {
+       case  0: ret = ResStatus::BROKEN      /*2*/; break;
+       case  1: ret = ResStatus::SATISFIED   /*4*/; break;
+       case -1: ret = ResStatus::NONRELEVANT /*6*/; break;
+      }
+      return ret;
+    }
+
+  private:
+    sat::Queue _pseudoItems;
+    sat::Queue _pseudoFlags;
+  };
+
+  ///////////////////////////////////////////////////////////////////
   namespace pool
   { /////////////////////////////////////////////////////////////////
 
@@ -127,6 +179,8 @@ namespace zypp
 
         typedef sat::detail::SolvableIdType            SolvableIdType;
 
+       typedef ResPool::EstablishedStates::Impl        EstablishedStatesImpl;
+
       public:
         /** Default ctor */
         PoolImpl();
@@ -178,9 +232,9 @@ namespace zypp
       public:
         /** \name Save and restore state. */
         //@{
-        void SaveState( const ResObject::Kind & kind_r );
+        void SaveState( const ResKind & kind_r );
 
-        void RestoreState( const ResObject::Kind & kind_r );
+        void RestoreState( const ResKind & kind_r );
         //@}
 
         ///////////////////////////////////////////////////////////////////
@@ -197,6 +251,14 @@ namespace zypp
           return *_poolProxy;
         }
 
+        /** True factory for \ref ResPool::EstablishedStates.
+        * Internally we maintain the ResPool::EstablishedStates::Impl
+        * reference shared_ptr. Updated whenever the pool content changes.
+        * On demand hand it out as ResPool::EstablishedStates Impl.
+        */
+        ResPool::EstablishedStates establishedStates() const
+        { store(); return ResPool::EstablishedStates( _establishedStates ); }
+
       public:
         /** Forward list of Repositories that contribute ResObjects from \ref sat::Pool */
         size_type knownRepositoriesSize() const
@@ -263,7 +325,7 @@ namespace zypp
           // Now diff to the pool collecting names only.
           // Thus added and removed locks are not necessarily
           // disjoint. Added locks win.
-          typedef std::tr1::unordered_set<IdString> IdentSet;
+          typedef std::unordered_set<IdString> IdentSet;
           IdentSet addedLocks;
           IdentSet removedLocks;
           for_( it, begin(), end() )
@@ -298,70 +360,6 @@ namespace zypp
        }
 
       public:
-        typedef PoolTraits::AutoSoftLocks          AutoSoftLocks;
-        typedef PoolTraits::autoSoftLocks_iterator autoSoftLocks_iterator;
-
-        const AutoSoftLocks & autoSoftLocks() const
-        { return _autoSoftLocks; }
-
-        bool autoSoftLockAppliesTo( sat::Solvable solv_r ) const
-        { return( _autoSoftLocks.find( solv_r.ident() ) != _autoSoftLocks.end() ); }
-
-        void setAutoSoftLocks( const AutoSoftLocks & newLocks_r )
-        {
-          MIL << "Apply " << newLocks_r.size() << " AutoSoftLocks: " << newLocks_r << endl;
-          _autoSoftLocks = newLocks_r;
-          // now adjust the pool status
-          for_( it, begin(), end() )
-          {
-            if ( ! it->status().isKept() )
-              continue;
-
-            if ( autoSoftLockAppliesTo( it->satSolvable() ) )
-              it->status().setSoftLock( ResStatus::USER );
-            else
-              it->status().resetTransact( ResStatus::USER );
-          }
-        }
-
-        void getActiveSoftLocks( AutoSoftLocks & activeLocks_r )
-        {
-          activeLocks_r = _autoSoftLocks; // current soft-locks
-          AutoSoftLocks todel;            // + names to be deleted
-          AutoSoftLocks toins;            // - names to be installed
-
-          for_( it, begin(), end() )
-          {
-            ResStatus & status( it->status() );
-            if ( ! status.isByUser() )
-              continue; // ignore non-uer requests
-
-            switch ( status.getTransactValue() )
-            {
-              case ResStatus::KEEP_STATE:
-                // Filter only items included in the last recommended set.
-                if ( status.isRecommended() )
-                  activeLocks_r.insert( it->satSolvable().ident() );
-                break;
-              case ResStatus::LOCKED:
-                //  NOOP
-                break;
-              case ResStatus::TRANSACT:
-                (status.isInstalled() ? todel : toins).insert( it->satSolvable().ident() );
-                break;
-            }
-          }
-          for_( it, todel.begin(), todel.end() )
-          {
-            activeLocks_r.insert( *it );
-          }
-          for_( it, toins.begin(), toins.end() )
-          {
-            activeLocks_r.erase( *it );
-          }
-        }
-
-      public:
         const ContainerT & store() const
         {
           checkSerial();
@@ -369,12 +367,10 @@ namespace zypp
           {
             sat::Pool pool( satpool() );
             bool addedItems = false;
+           bool reusedIDs = _watcherIDs.remember( pool.serialIDs() );
             std::list<PoolItem> addedProducts;
 
-            if ( pool.capacity() != _store.capacity() )
-            {
-              _store.resize( pool.capacity() );
-            }
+           _store.resize( pool.capacity() );
 
             if ( pool.capacity() )
             {
@@ -387,18 +383,13 @@ namespace zypp
                   // the PoolItem got invalidated (e.g unloaded repo)
                   pi = PoolItem();
                 }
-                else if ( s && ! pi )
+                else if ( reusedIDs || (s && ! pi) )
                 {
                   // new PoolItem to add
                   pi = PoolItem::makePoolItem( s ); // the only way to create a new one!
                   // remember products for buddy processing (requires clean store)
                   if ( s.isKind( ResKind::product ) )
                     addedProducts.push_back( pi );
-                  // and on the fly check for weak locks...
-                  if ( autoSoftLockAppliesTo( s ) )
-                  {
-                    pi.status().setSoftLock( ResStatus::USER );
-                  }
                   if ( !addedItems )
                     addedItems = true;
                 }
@@ -422,6 +413,10 @@ namespace zypp
             {
               reapplyHardLocks();
             }
+
+           // Compute the initial status of Patches etc.
+            if ( !_establishedStates )
+             _establishedStates.reset( new EstablishedStatesImpl );
           }
           return _store;
         }
@@ -464,11 +459,14 @@ namespace zypp
          _id2itemDirty = true;
          _id2item.clear();
           _poolProxy.reset();
+         _establishedStates.reset();
         }
 
       private:
         /** Watch sat pools serial number. */
         SerialNumberWatcher                   _watcher;
+       /** Watch sat pools Serial number of IDs - changes whenever resusePoolIDs==true - ResPool must also invalidate it's PoolItems! */
+        SerialNumberWatcher                   _watcherIDs;
         mutable ContainerT                    _store;
         mutable DefaultIntegral<bool,true>    _storeDirty;
        mutable Id2ItemT                      _id2item;
@@ -476,10 +474,9 @@ namespace zypp
 
       private:
         mutable shared_ptr<ResPoolProxy>      _poolProxy;
+       mutable shared_ptr<EstablishedStatesImpl> _establishedStates;
 
       private:
-        /** Set of solvable idents that should be soft locked per default. */
-        AutoSoftLocks                         _autoSoftLocks;
         /** Set of queries that define hardlocks. */
         HardLockQueries                       _hardLockQueries;
     };