libzypp  10.5.0
WhatObsoletes.cc
Go to the documentation of this file.
00001 /*---------------------------------------------------------------------\
00002 |                          ____ _   __ __ ___                          |
00003 |                         |__  / \ / / . \ . \                         |
00004 |                           / / \ V /|  _/  _/                         |
00005 |                          / /__ | | | | | |                           |
00006 |                         /_____||_| |_| |_|                           |
00007 |                                                                      |
00008 \---------------------------------------------------------------------*/
00012 #include <iostream>
00013 
00014 #include "zypp/base/LogTools.h"
00015 #include "zypp/base/Tr1hash.h"
00016 #include "zypp/sat/WhatObsoletes.h"
00017 #include "zypp/sat/detail/PoolImpl.h"
00018 #include "zypp/PoolItem.h"
00019 
00020 using std::endl;
00021 
00023 namespace zypp
00024 { 
00025 
00026   namespace sat
00027   { 
00028 
00029     // Obsoletes may either match against provides, or names.
00030     // Configuration depends on the behaviour of rpm.
00031     bool obsoleteUsesProvides = false;
00032 
00034     namespace
00035     { 
00036 
00037       typedef std::tr1::unordered_set<detail::IdType> set_type;
00038       typedef std::vector<sat::detail::IdType>        vector_type;
00039 
00041     } // namespace
00043 
00044     WhatObsoletes::WhatObsoletes( Solvable item_r )
00045     : _begin( 0 )
00046     {
00047       ctorAdd( item_r );
00048       ctorDone();
00049     }
00050 
00051     WhatObsoletes::WhatObsoletes( const PoolItem & item_r )
00052     : _begin( 0 )
00053     {
00054       ctorAdd( item_r );
00055       ctorDone();
00056     }
00057 
00058     WhatObsoletes::WhatObsoletes( const ResObject::constPtr item_r )
00059     : _begin( 0 )
00060     {
00061       if ( item_r )
00062       {
00063         ctorAdd( item_r->satSolvable() );
00064         ctorDone();
00065       }
00066     }
00067 
00068     void WhatObsoletes::ctorAdd( const PoolItem & item_r )
00069     { ctorAdd( item_r->satSolvable() ); }
00070 
00071     void WhatObsoletes::ctorAdd( ResObject_constPtr item_r )
00072     { if ( item_r ) ctorAdd( item_r->satSolvable() ); }
00073 
00074 
00075     namespace
00076     {
00078       inline void addToSet( Solvable item, set_type *& pdata, shared_ptr<void>& _private )
00079       {
00080         if ( ! pdata )
00081         {
00082           _private.reset( (pdata = new set_type) );
00083         }
00084         pdata->insert( item.id() );
00085       }
00086     }
00087 
00088     void WhatObsoletes::ctorAdd( Solvable item_r )
00089     {
00090       if ( item_r.multiversionInstall() )
00091         return; // multiversion (rpm -i) does not evaluate any obsoletes
00092 
00093       if ( obsoleteUsesProvides )
00094       {
00095         WhatProvides obsoleted( item_r.obsoletes() );
00096         if ( obsoleted.empty() )
00097           return;
00098 
00099         // use allocated private data to collect the results
00100         set_type * pdata = ( _private ? reinterpret_cast<set_type*>( _private.get() ) : 0 );
00101         for_( it, obsoleted.begin(), obsoleted.end() )
00102         {
00103           if ( it->isSystem() )
00104             addToSet( *it, pdata, _private );
00105         }
00106       }
00107       else // Obsoletes match names
00108       {
00109         Capabilities obsoletes( item_r.obsoletes() );
00110         if ( obsoletes.empty() )
00111           return;
00112 
00113         // use allocated private data to collect the results
00114         set_type * pdata = ( _private ? reinterpret_cast<set_type*>( _private.get() ) : 0 );
00115         for_( it, obsoletes.begin(), obsoletes.end() )
00116         {
00117           // For each obsoletes find providers, but with the same name
00118           IdString ident( it->detail().name() );
00119           WhatProvides obsoleted( *it );
00120           for_( iit, obsoleted.begin(), obsoleted.end() )
00121           {
00122             if ( iit->isSystem() && iit->ident() == ident )
00123               addToSet( *iit, pdata, _private );
00124           }
00125         }
00126       }
00127     }
00128 
00129     void WhatObsoletes::ctorDone()
00130     {
00131       if ( _private )
00132       {
00133         // copy set to vector and terminate _private
00134         set_type * sdata = reinterpret_cast<set_type*>( _private.get() );
00135 
00136         vector_type * pdata = new vector_type( sdata->begin(), sdata->end() );
00137         pdata->push_back( sat::detail::noId );
00138         _begin = &pdata->front();
00139 
00140         _private.reset( pdata );
00141       }
00142     }
00143 
00144     WhatObsoletes::size_type WhatObsoletes::size() const
00145     {
00146       if ( ! _begin )
00147         return 0;
00148 
00149       Capabilities::size_type ret = 0;
00150       for ( const sat::detail::IdType * end = _begin; *end; ++end )
00151       {
00152         ++ret;
00153       }
00154       return ret;
00155     }
00156 
00157     /******************************************************************
00158     **
00159     **  FUNCTION NAME : operator<<
00160     **  FUNCTION TYPE : std::ostream &
00161     */
00162     std::ostream & operator<<( std::ostream & str, const WhatObsoletes & obj )
00163     {
00164       return dumpRange( str << "(" << obj.size() << ")", obj.begin(), obj.end() );
00165     }
00166 
00168   } // namespace sat
00171 } // namespace zypp