Merge branch 'aria'
[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     bool obsoleteUsesProvides = false;
32
33     ///////////////////////////////////////////////////////////////////
34     namespace
35     { /////////////////////////////////////////////////////////////////
36
37       typedef std::tr1::unordered_set<detail::IdType> set_type;
38       typedef std::vector<sat::detail::IdType>        vector_type;
39
40       /////////////////////////////////////////////////////////////////
41     } // namespace
42     ///////////////////////////////////////////////////////////////////
43
44     WhatObsoletes::WhatObsoletes( Solvable item_r )
45     : _begin( 0 )
46     {
47       ctorAdd( item_r );
48       ctorDone();
49     }
50
51     WhatObsoletes::WhatObsoletes( const PoolItem & item_r )
52     : _begin( 0 )
53     {
54       ctorAdd( item_r );
55       ctorDone();
56     }
57
58     WhatObsoletes::WhatObsoletes( const ResObject::constPtr item_r )
59     : _begin( 0 )
60     {
61       if ( item_r )
62       {
63         ctorAdd( item_r->satSolvable() );
64         ctorDone();
65       }
66     }
67
68     void WhatObsoletes::ctorAdd( const PoolItem & item_r )
69     { ctorAdd( item_r->satSolvable() ); }
70
71     void WhatObsoletes::ctorAdd( ResObject_constPtr item_r )
72     { if ( item_r ) ctorAdd( item_r->satSolvable() ); }
73
74
75     namespace
76     {
77       /** Add item to the set created on demand. */
78       inline void addToSet( Solvable item, set_type *& pdata, shared_ptr<void>& _private )
79       {
80         if ( ! pdata )
81         {
82           _private.reset( (pdata = new set_type) );
83         }
84         pdata->insert( item.id() );
85       }
86     }
87
88     void WhatObsoletes::ctorAdd( Solvable item_r )
89     {
90       if ( obsoleteUsesProvides )
91       {
92         WhatProvides obsoleted( item_r.obsoletes() );
93         if ( obsoleted.empty() )
94           return;
95
96         // use allocated private data to collect the results
97         set_type * pdata = ( _private ? reinterpret_cast<set_type*>( _private.get() ) : 0 );
98         for_( it, obsoleted.begin(), obsoleted.end() )
99         {
100           if ( it->isSystem() )
101             addToSet( *it, pdata, _private );
102         }
103       }
104       else // Obsoletes match names
105       {
106         Capabilities obsoletes( item_r.obsoletes() );
107         if ( obsoletes.empty() )
108           return;
109
110         // use allocated private data to collect the results
111         set_type * pdata = ( _private ? reinterpret_cast<set_type*>( _private.get() ) : 0 );
112         for_( it, obsoletes.begin(), obsoletes.end() )
113         {
114           // For each obsoletes find providers, but with the same name
115           IdString ident( it->detail().name() );
116           WhatProvides obsoleted( *it );
117           for_( iit, obsoleted.begin(), obsoleted.end() )
118           {
119             if ( iit->isSystem() && iit->ident() == ident )
120               addToSet( *iit, pdata, _private );
121           }
122         }
123       }
124     }
125
126     void WhatObsoletes::ctorDone()
127     {
128       if ( _private )
129       {
130         // copy set to vector and terminate _private
131         set_type * sdata = reinterpret_cast<set_type*>( _private.get() );
132
133         vector_type * pdata = new vector_type( sdata->begin(), sdata->end() );
134         pdata->push_back( sat::detail::noId );
135         _begin = &pdata->front();
136
137         _private.reset( pdata );
138       }
139     }
140
141     WhatObsoletes::size_type WhatObsoletes::size() const
142     {
143       if ( ! _begin )
144         return 0;
145
146       Capabilities::size_type ret = 0;
147       for ( const sat::detail::IdType * end = _begin; *end; ++end )
148       {
149         ++ret;
150       }
151       return ret;
152     }
153
154     /******************************************************************
155     **
156     **  FUNCTION NAME : operator<<
157     **  FUNCTION TYPE : std::ostream &
158     */
159     std::ostream & operator<<( std::ostream & str, const WhatObsoletes & obj )
160     {
161       return dumpRange( str << "(" << obj.size() << ")", obj.begin(), obj.end() );
162     }
163
164     /////////////////////////////////////////////////////////////////
165   } // namespace sat
166   ///////////////////////////////////////////////////////////////////
167   /////////////////////////////////////////////////////////////////
168 } // namespace zypp
169 ///////////////////////////////////////////////////////////////////