52679fbbe7ed31a3007d6e93247783fa5cd8ce7e
[platform/upstream/libzypp.git] / zypp / sat / WhatObsoletes.cc
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file       zypp/sat/WhatObsoletes.cc
10  *
11 */
12 #include <iostream>
13
14 #include "zypp/base/LogTools.h"
15 #include "zypp/base/Tr1hash.h"
16 #include "zypp/sat/WhatObsoletes.h"
17 #include "zypp/sat/detail/PoolImpl.h"
18 #include "zypp/PoolItem.h"
19
20 using std::endl;
21
22 ///////////////////////////////////////////////////////////////////
23 namespace zypp
24 { /////////////////////////////////////////////////////////////////
25   ///////////////////////////////////////////////////////////////////
26   namespace sat
27   { /////////////////////////////////////////////////////////////////
28
29     // Obsoletes may either match against provides, or names.
30     // Configuration depends on the behaviour of rpm.
31 #ifdef _RPM_5
32     bool obsoleteUsesProvides = true;
33 #else
34     bool obsoleteUsesProvides = false;
35 #endif
36
37     ///////////////////////////////////////////////////////////////////
38     namespace
39     { /////////////////////////////////////////////////////////////////
40
41       typedef std::tr1::unordered_set<detail::IdType> set_type;
42       typedef std::vector<sat::detail::IdType>        vector_type;
43
44       /////////////////////////////////////////////////////////////////
45     } // namespace
46     ///////////////////////////////////////////////////////////////////
47
48     WhatObsoletes::WhatObsoletes( Solvable item_r )
49     : _begin( 0 )
50     {
51       ctorAdd( item_r );
52       ctorDone();
53     }
54
55     WhatObsoletes::WhatObsoletes( const PoolItem & item_r )
56     : _begin( 0 )
57     {
58       ctorAdd( item_r );
59       ctorDone();
60     }
61
62     WhatObsoletes::WhatObsoletes( const ResObject::constPtr item_r )
63     : _begin( 0 )
64     {
65       if ( item_r )
66       {
67         ctorAdd( item_r->satSolvable() );
68         ctorDone();
69       }
70     }
71
72     void WhatObsoletes::ctorAdd( const PoolItem & item_r )
73     { ctorAdd( item_r->satSolvable() ); }
74
75     void WhatObsoletes::ctorAdd( ResObject_constPtr item_r )
76     { if ( item_r ) ctorAdd( item_r->satSolvable() ); }
77
78
79     namespace
80     {
81       /** Add item to the set created on demand. */
82       inline void addToSet( Solvable item, set_type *& pdata, shared_ptr<void>& _private )
83       {
84         if ( ! pdata )
85         {
86           _private.reset( (pdata = new set_type) );
87         }
88         pdata->insert( item.id() );
89       }
90     }
91
92     void WhatObsoletes::ctorAdd( Solvable item_r )
93     {
94       if ( item_r.multiversionInstall() )
95         return; // multiversion (rpm -i) does not evaluate any obsoletes
96
97       if ( obsoleteUsesProvides )
98       {
99         WhatProvides obsoleted( item_r.obsoletes() );
100         if ( obsoleted.empty() )
101           return;
102
103         // use allocated private data to collect the results
104         set_type * pdata = ( _private ? reinterpret_cast<set_type*>( _private.get() ) : 0 );
105         for_( it, obsoleted.begin(), obsoleted.end() )
106         {
107           if ( it->isSystem() )
108             addToSet( *it, pdata, _private );
109         }
110       }
111       else // Obsoletes match names
112       {
113         Capabilities obsoletes( item_r.obsoletes() );
114         if ( obsoletes.empty() )
115           return;
116
117         // use allocated private data to collect the results
118         set_type * pdata = ( _private ? reinterpret_cast<set_type*>( _private.get() ) : 0 );
119         for_( it, obsoletes.begin(), obsoletes.end() )
120         {
121           // For each obsoletes find providers, but with the same name
122           IdString ident( it->detail().name() );
123           WhatProvides obsoleted( *it );
124           for_( iit, obsoleted.begin(), obsoleted.end() )
125           {
126             if ( iit->isSystem() && iit->ident() == ident )
127               addToSet( *iit, pdata, _private );
128           }
129         }
130       }
131     }
132
133     void WhatObsoletes::ctorDone()
134     {
135       if ( _private )
136       {
137         // copy set to vector and terminate _private
138         set_type * sdata = reinterpret_cast<set_type*>( _private.get() );
139
140         vector_type * pdata = new vector_type( sdata->begin(), sdata->end() );
141         pdata->push_back( sat::detail::noId );
142         _begin = &pdata->front();
143
144         _private.reset( pdata );
145       }
146     }
147
148     WhatObsoletes::size_type WhatObsoletes::size() const
149     {
150       if ( ! _begin )
151         return 0;
152
153       Capabilities::size_type ret = 0;
154       for ( const sat::detail::IdType * end = _begin; *end; ++end )
155       {
156         ++ret;
157       }
158       return ret;
159     }
160
161     /******************************************************************
162     **
163     **  FUNCTION NAME : operator<<
164     **  FUNCTION TYPE : std::ostream &
165     */
166     std::ostream & operator<<( std::ostream & str, const WhatObsoletes & obj )
167     {
168       return dumpRange( str << "(" << obj.size() << ")", obj.begin(), obj.end() );
169     }
170
171     /////////////////////////////////////////////////////////////////
172   } // namespace sat
173   ///////////////////////////////////////////////////////////////////
174   /////////////////////////////////////////////////////////////////
175 } // namespace zypp
176 ///////////////////////////////////////////////////////////////////