Make byIdent{Begin,End} an indexed iterator globally, remove PoolIndex
authorMichael Matz <matz@suse.de>
Thu, 14 Feb 2008 11:37:51 +0000 (11:37 +0000)
committerMichael Matz <matz@suse.de>
Thu, 14 Feb 2008 11:37:51 +0000 (11:37 +0000)
from doUpgrade.

zypp/ResPool.cc
zypp/ResPool.h
zypp/pool/PoolImpl.h
zypp/pool/PoolTraits.h
zypp/solver/detail/ResolverUpgrade.cc

index cd15b93595d52f81dc6e0925d8aa1db190ecca93..dd2bd30914e87ca584f07dbd4c8b1d4cc2c895c0 100644 (file)
@@ -101,6 +101,9 @@ namespace zypp
   const pool::PoolTraits::ItemContainerT & ResPool::store() const
   { return _pimpl->store(); }
 
+  const pool::PoolTraits::Id2ItemT & ResPool::id2item() const
+  { return _pimpl->id2item(); }
+
   /******************************************************************
   **
   **   FUNCTION NAME : operator<<
index 3b12153fd5fcad639bf86babb95ff8433dbe5908..864e7f0e87a1bee5e1f259934866b3e98fc5e3f1 100644 (file)
@@ -112,56 +112,71 @@ namespace zypp
       /** \name Iterate through all PoolItems of a certain name and kind. */
       //@{
       typedef pool::ByIdent ByIdent;
-      typedef filter_iterator<ByIdent,const_iterator> byIdent_iterator;
+      typedef pool::PoolTraits::Id2ItemT        Id2ItemT;
+      typedef transform_iterator<std::_Select2nd<Id2ItemT::value_type>, Id2ItemT::const_iterator> byIdent_iterator;
+
+      byIdent_iterator byIdentBegin( sat::detail::IdType id ) const
+      {
+        std::pair<Id2ItemT::const_iterator, Id2ItemT::const_iterator> it2
+             = id2item().equal_range(id);
+       return make_transform_iterator(it2.first, std::_Select2nd<Id2ItemT::value_type>());
+      }
+
+      byIdent_iterator byIdentEnd( sat::detail::IdType id ) const
+      {
+        std::pair<Id2ItemT::const_iterator, Id2ItemT::const_iterator> it2
+             = id2item().equal_range(id);
+       return make_transform_iterator(it2.second, std::_Select2nd<Id2ItemT::value_type>());
+      }
 
       byIdent_iterator byIdentBegin( ResKind kind_r, IdString name_r ) const
-      { return make_filter_begin( ByIdent(kind_r,name_r), *this ); }
+      { return byIdentBegin( ByIdent(kind_r,name_r).get() ); }
 
       byIdent_iterator byIdentBegin( ResKind kind_r, const C_Str & name_r ) const
-      { return make_filter_begin( ByIdent(kind_r,name_r), *this ); }
+      { return byIdentBegin( ByIdent(kind_r,name_r).get() ); }
 
       template<class _Res>
       byIdent_iterator byIdentBegin( IdString name_r ) const
-      { return make_filter_begin( ByIdent(ResTraits<_Res>::kind,name_r), *this ); }
+      { return byIdentBegin( ByIdent(ResTraits<_Res>::kind,name_r).get() ); }
 
       template<class _Res>
       byIdent_iterator byIdentBegin( const C_Str & name_r ) const
-      { return make_filter_begin( ByIdent(ResTraits<_Res>::kind,name_r), *this ); }
+      { return byIdentBegin( ByIdent(ResTraits<_Res>::kind,name_r).get() ); }
 
       /** Derive name and kind from \ref PoolItem. */
       byIdent_iterator byIdentBegin( const PoolItem & pi_r ) const
-      { return make_filter_begin( ByIdent(pi_r.satSolvable()), *this ); }
+      { return byIdentBegin( ByIdent(pi_r.satSolvable()).get() ); }
       /** Derive name and kind from \ref sat::Solvable. */
       byIdent_iterator byIdentBegin( sat::Solvable slv_r ) const
-      { return make_filter_begin( ByIdent(slv_r), *this ); }
+      { return byIdentBegin( ByIdent(slv_r).get() ); }
       /** Takes a \ref sat::Solvable::ident string. */
       byIdent_iterator byIdentBegin( IdString ident_r ) const
-      { return make_filter_begin( ByIdent(ident_r), *this ); }
+      { return byIdentBegin( ByIdent(ident_r).get() ); }
 
 
       byIdent_iterator byIdentEnd( ResKind kind_r, IdString name_r ) const
-      { return make_filter_end( ByIdent(kind_r,name_r), *this ); }
+      { return byIdentEnd( ByIdent(kind_r,name_r).get() ); }
 
       byIdent_iterator byIdentEnd( ResKind kind_r, const C_Str & name_r ) const
-      { return make_filter_end( ByIdent(kind_r,name_r), *this ); }
+      { return byIdentEnd( ByIdent(kind_r,name_r).get() ); }
 
       template<class _Res>
       byIdent_iterator byIdentEnd( IdString name_r ) const
-      { return make_filter_end( ByIdent(ResTraits<_Res>::kind,name_r), *this ); }
+      { return byIdentEnd( ByIdent(ResTraits<_Res>::kind,name_r).get() ); }
 
       template<class _Res>
       byIdent_iterator byIdentEnd( const C_Str & name_r ) const
-      { return make_filter_end( ByIdent(ResTraits<_Res>::kind,name_r), *this ); }
+      { return byIdentEnd( ByIdent(ResTraits<_Res>::kind,name_r).get() ); }
 
       /** Derive name and kind from \ref PoolItem. */
       byIdent_iterator byIdentEnd( const PoolItem & pi_r ) const
-      { return make_filter_end( ByIdent(pi_r.satSolvable()), *this ); }
+      { return byIdentEnd( ByIdent(pi_r.satSolvable()).get() ); }
       /** Derive name and kind from \ref sat::Solvable. */
       byIdent_iterator byIdentEnd( sat::Solvable slv_r ) const
-      { return make_filter_end( ByIdent(slv_r), *this ); }
+      { return byIdentEnd( ByIdent(slv_r).get() ); }
       /** Takes a \ref sat::Solvable::ident string. */
       byIdent_iterator byIdentEnd( IdString ident_r ) const
-      { return make_filter_end( ByIdent(ident_r), *this ); }
+      { return byIdentEnd( ByIdent(ident_r).get() ); }
      //@}
 
     public:
@@ -286,6 +301,7 @@ namespace zypp
 
     private:
       const pool::PoolTraits::ItemContainerT & store() const;
+      const pool::PoolTraits::Id2ItemT & id2item() const;
 
     private:
       /** Ctor */
index c3aef9a618e61f6516535137008b5caef7f7b804..10e6635a8cd0a2477659857ef729dbb3ce559749 100644 (file)
@@ -47,6 +47,7 @@ namespace zypp
         typedef PoolTraits::ItemContainerT             ContainerT;
         typedef PoolTraits::size_type                  size_type;
         typedef PoolTraits::const_iterator             const_iterator;
+       typedef PoolTraits::Id2ItemT                    Id2ItemT;
 
         typedef sat::detail::SolvableIdType            SolvableIdType;
 
@@ -237,6 +238,30 @@ namespace zypp
           return _store;
         }
 
+       const Id2ItemT & id2item () const
+       {
+         checkSerial();
+         if (_id2itemDirty)
+         {
+           _id2itemDirty = false;
+           store();
+           _id2item = Id2ItemT(size());
+           const_iterator it = make_filter_begin( ByPoolItem(), store() );
+           const_iterator e = make_filter_end( ByPoolItem(), store() );
+           for (; it != e; ++it)
+             {
+               sat::detail::IdType id;
+               const sat::Solvable &s = (*it)->satSolvable();
+               id = s.ident().id();
+               if (s.isKind( ResKind::srcpackage ))
+                 id = -id;
+               _id2item.insert(std::make_pair(id, *it));
+             }
+         }
+         return _id2item;
+       }
+
+
         ///////////////////////////////////////////////////////////////////
         //
         ///////////////////////////////////////////////////////////////////
@@ -250,6 +275,8 @@ namespace zypp
         void invalidate() const
         {
           _storeDirty = true;
+         _id2itemDirty = true;
+         _id2item.clear();
           _poolProxy.reset();
           _knownRepositoriesPtr.reset();
         }
@@ -259,6 +286,8 @@ namespace zypp
         SerialNumberWatcher                   _watcher;
         mutable ContainerT                    _store;
         mutable DefaultIntegral<bool,true>    _storeDirty;
+       mutable Id2ItemT                      _id2item;
+        mutable DefaultIntegral<bool,true>    _id2itemDirty;
 
       private:
         mutable AdditionalCapabilities        _additionalRequire;
index 447dbf6249811f14501122e52429f08635d4b9d6..b399879e1b1649119758d0b31d06a9ce95aa513d 100644 (file)
@@ -14,6 +14,7 @@
 
 #include <set>
 #include <map>
+#include <tr1/unordered_map>
 
 #include "zypp/base/Iterator.h"
 
@@ -130,6 +131,7 @@ namespace zypp
       typedef filter_iterator<ByPoolItem,ItemContainerT::const_iterator>
                                                        const_iterator;
       typedef ItemContainerT::size_type                        size_type;
+      typedef std::tr1::unordered_multimap<sat::detail::IdType, PoolItem>      Id2ItemT;
 
       // internal organization
       typedef std::list<zypp::CapAndItem>              CapItemContainerT;      // (why,who) pairs
index 14c67b895257665fccfe775d9f49e0d1ce6b92f3..ba5dd9eae84aba400fce582e28f8fc748caed261 100644 (file)
@@ -70,27 +70,6 @@ namespace zypp
 using namespace std;
 using namespace zypp;
 
-struct PoolIndex
-{
-  PoolIndex()
-  {
-    ResPool pool( ResPool::instance() );
-    for_( it, pool.begin(), pool.end() )
-      _cache[it->satSolvable().ident()].push_back( *it );
-  }
-
-  std::vector<PoolItem> & get( const PoolItem & pi )
-  { return get( pi.satSolvable().ident() ); }
-
-  std::vector<PoolItem> & get( sat::Solvable slv_r )
-  { return get( slv_r.ident() );}
-
-  std::vector<PoolItem> & get( IdString ident_r )
-  { return _cache[ident_r]; }
-
-  std::map<IdString,std::vector<PoolItem> > _cache;
-};
-
 /** Order on AvialableItemSet.
  * \li best Arch
  * \li best Edition
@@ -364,7 +343,6 @@ Resolver::doUpgrade( UpgradeStatistics & opt_stats_r )
   }
 
   /* Find upgrade candidates for each package.  */
-  PoolIndex identIndex;
 
   for ( ResPool::const_iterator it = _pool.begin(); it != _pool.end(); ++it ) {
     PoolItem item = *it;
@@ -391,7 +369,7 @@ Resolver::doUpgrade( UpgradeStatistics & opt_stats_r )
        candidate = cand_it->second;                            // found candidate already
       }
       else {
-       candidate = Helper::findUpdateItem( identIndex.get( installed ), installed );   // find 'best' upgrade candidate
+       candidate = Helper::findUpdateItem( _pool, installed ); // find 'best' upgrade candidate
       }
       if (!candidate) {
        MIL << "doUpgrade available: SKIP no candidate for " << installed << endl;
@@ -412,7 +390,7 @@ Resolver::doUpgrade( UpgradeStatistics & opt_stats_r )
       }
       candidate = item;
       candidate.status().setSeen(true);                                // mark as seen
-      installed = Helper::findInstalledItem( identIndex.get( candidate ), candidate );
+      installed = Helper::findInstalledItem( _pool, candidate );
       if (installed) {                                         // check if we already have an installed
        if ( installed.status().isLocked() ) {
          MIL << "doUpgrade available: SKIP candidate " << candidate << ", locked " << installed << endl;