73409f8bc41bfa6987f29a23b4fc42d97ebfc4b0
[platform/upstream/libzypp.git] / zypp / pool / PoolImpl.cc
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file       zypp/pool/PoolImpl.cc
10  *
11 */
12 #include <iostream>
13 #include "zypp/base/Logger.h"
14
15 #include "zypp/pool/PoolImpl.h"
16 #include "zypp/pool/PoolStats.h"
17 #include "zypp/CapSet.h"
18 #include "zypp/Package.h"
19 #include "zypp/VendorAttr.h"
20
21 using std::endl;
22
23 ///////////////////////////////////////////////////////////////////
24 namespace zypp
25 { /////////////////////////////////////////////////////////////////
26
27   std::ostream & operator<<( std::ostream & str, const CapAndItem & obj )
28   {
29     return str << "{" << obj.cap << ", " << obj.item << "}";
30   }
31
32   ///////////////////////////////////////////////////////////////////
33   namespace pool
34   { /////////////////////////////////////////////////////////////////
35
36     ///////////////////////////////////////////////////////////////////
37     //
38     //  METHOD NAME : NameHash::NameHash
39     //  METHOD TYPE : Ctor
40     //
41     NameHash::NameHash()
42     {}
43
44     ///////////////////////////////////////////////////////////////////
45     //
46     //  METHOD NAME : NameHash::~NameHash
47     //  METHOD TYPE : Dtor
48     //
49     NameHash::~NameHash()
50     {}
51
52     void
53     NameHash::insert( const PoolItem & item_r )
54     {
55       _store[item_r->name()].insert( item_r );
56     }
57
58     void
59     NameHash::erase( const PoolItem & item_r )
60     {
61       PoolTraits::ItemContainerT & items = _store[item_r->name()];
62       for ( PoolTraits::iterator nit = items.begin(); nit != items.end(); /**/ )
63       {
64         if ( *nit == item_r )
65           items.erase( nit++ ); // postfix! Incrementing before erase
66         else
67           ++nit;
68       }
69     }
70
71     NameHash::ItemContainerT & NameHash::getItemContainer( const std::string & tag_r )
72         { ContainerT::iterator it = _store.find( tag_r );
73           if (it == _store.end()) {
74 //XXX << "item container for " << tag_r << " not found" << endl;
75             return _empty;
76           }
77 //XXX << "item container for " << tag_r << " contains " << it->second.size() << " items" << endl;
78           return it->second;
79         }
80
81     const NameHash::ItemContainerT & NameHash::getConstItemContainer( const std::string & tag_r ) const
82         { ContainerT::const_iterator it = _store.find( tag_r );
83           if (it == _store.end()) {
84 //XXX << "const item container for " << tag_r << " not found" << endl;
85             return _empty;
86           }
87 //XXX << "const item container for " << tag_r << " contains " << it->second.size() << " items" << endl;
88           return it->second;
89         }
90
91     ///////////////////////////////////////////////////////////////////
92     //
93     //  METHOD NAME : CapHash::CapHash
94     //  METHOD TYPE : Ctor
95     //
96     CapHash::CapHash()
97     {}
98
99     ///////////////////////////////////////////////////////////////////
100     //
101     //  METHOD NAME : CapHash::~CapHash
102     //  METHOD TYPE : Dtor
103     //
104     CapHash::~CapHash()
105     {}
106
107     static void
108     storeInsert( CapHash::ContainerT & store_r, const PoolItem & item_r, Dep cap_r )
109     {
110       CapSet caps = item_r->dep( cap_r );
111       for (CapSet::iterator ic = caps.begin(); ic != caps.end(); ++ic) {
112         store_r[cap_r][ic->index()].push_back( CapAndItem( *ic, item_r ) );
113       }
114     }
115
116     void CapHash::insert( const PoolItem & item_r )
117     {
118       storeInsert( _store, item_r, Dep::PROVIDES );
119       storeInsert( _store, item_r, Dep::REQUIRES );
120       storeInsert( _store, item_r, Dep::CONFLICTS );
121       storeInsert( _store, item_r, Dep::OBSOLETES );
122       storeInsert( _store, item_r, Dep::FRESHENS );
123       storeInsert( _store, item_r, Dep::SUPPLEMENTS );
124     }
125
126     static void
127     storeDelete( PoolTraits::DepCapItemContainerT & store_r, const PoolItem & item_r, Dep cap_r )
128     {
129       CapSet caps = item_r->dep( cap_r );
130 //XXX << "storeDelete(" << item_r << ")" << endl;
131       for ( CapSet::iterator ic = caps.begin(); ic != caps.end(); ++ic )
132         {
133           PoolTraits::CapItemContainerT & capitems = store_r[cap_r][ic->index()];
134           for ( PoolTraits::CapItemContainerT::iterator pos = capitems.begin(); pos != capitems.end(); /**/ )
135             {
136               if ( pos->item == item_r )
137                 capitems.erase( pos++ ); // postfix! Incrementing before erase
138               else
139                 ++pos;
140             }
141         }
142     }
143
144     void CapHash::erase( const PoolItem & item_r )
145     {
146 //XXX << "CapHash::erase(" << item_r << ")" << endl;
147       storeDelete( _store, item_r, Dep::PROVIDES );
148       storeDelete( _store, item_r, Dep::REQUIRES );
149       storeDelete( _store, item_r, Dep::CONFLICTS );
150       storeDelete( _store, item_r, Dep::OBSOLETES );
151       storeDelete( _store, item_r, Dep::FRESHENS );
152       storeDelete( _store, item_r, Dep::SUPPLEMENTS );
153     }
154
155       const CapHash::CapItemStoreT & CapHash::capItemStore ( Dep cap_r ) const
156       { static CapItemStoreT capitemstore;
157         ContainerT::const_iterator it = store().find( cap_r );
158         if (it == store().end()) {
159 //XXX << "CapItemStoreT for " << cap_r << " not found" << endl;
160             return capitemstore;
161         }
162 //XXX << "CapItemStoreT for " << cap_r << " contains " << it->second.size() << " items" << endl;
163         return it->second;
164       }
165
166       // CapItemStoreT, index -> CapItemContainerT
167       const CapHash::CapItemContainerT & CapHash::capItemContainer( const CapItemStoreT & cis, const std::string & tag_r ) const
168       { static CapItemContainerT captemcontainer;
169         CapItemStoreT::const_iterator it = cis.find( tag_r );
170         if (it == cis.end()) {
171 //XXX << "CapItemContainerT for " << tag_r << " not found" << endl;
172             return captemcontainer;
173         }
174 //XXX << "CapItemContainerT for " << tag_r << " contains " << it->second.size() << " items" << endl;
175 //for (CapItemContainerT::const_iterator cai = it->second.begin(); cai != it->second.end(); ++cai) XXX << *cai << endl;
176         return it->second;
177       }
178
179     ///////////////////////////////////////////////////////////////////
180     //
181     //  Class PoolImpl::PoolImpl
182     //
183     ///////////////////////////////////////////////////////////////////
184
185     ///////////////////////////////////////////////////////////////////
186     //
187     //  METHOD NAME : PoolImpl::PoolImpl
188     //  METHOD TYPE : Ctor
189     //
190     PoolImpl::PoolImpl()
191     {}
192
193     ///////////////////////////////////////////////////////////////////
194     //
195     //  METHOD NAME : PoolImpl::~PoolImpl
196     //  METHOD TYPE : Dtor
197     //
198     PoolImpl::~PoolImpl()
199     {}
200
201     /******************************************************************
202     **
203     **  FUNCTION NAME : operator<<
204     **  FUNCTION TYPE : std::ostream &
205     */
206     std::ostream & operator<<( std::ostream & str, const PoolImpl & obj )
207     {
208       return dumpPoolStats( str << "ResPool ",
209                             obj.begin(), obj.end() );
210     }
211
212     /******************************************************************
213     **
214     **  FUNCTION NAME : PoolImplInserter::operator()
215     **  FUNCTION TYPE : void
216     */
217     /** Bottleneck inserting ResObjects in to the pool.
218      * Filters arch incomatible available(!) objects.
219     */
220     void PoolImplInserter::operator()( ResObject::constPtr ptr_r )
221     {
222       /* -------------------------------------------------------------------------------
223        * 1.) Filter unwanted items
224        * ------------------------------------------------------------------------------- */
225        if ( ! ptr_r )
226         return;
227
228       if ( isKind<SrcPackage>( ptr_r ) )
229         return;
230
231       if ( ! _installed )
232         {
233           // filter arch incomatible available(!) non-atoms
234           // atoms are allowed since patches are multi-arch and require atoms of all archs
235           // the atoms themselves will 'filter' the arch via their frehen dependencies
236           if ( ptr_r->kind() != ResTraits<Atom>::kind ) {
237             if ( ! ptr_r->arch().compatibleWith( _poolImpl.targetArch() ) )
238               return;
239           }
240         }
241
242       /* -------------------------------------------------------------------------------
243        * 2.) Create ResStatus object
244        * ------------------------------------------------------------------------------- */
245       PoolImpl::Item item( ptr_r, ResStatus (_installed) );
246
247
248       /* -------------------------------------------------------------------------------
249        * 3.) Status adjustments
250        * ------------------------------------------------------------------------------- */
251       if ( _installed )
252         {
253           Package::constPtr pkgptr( asKind<Package>( ptr_r ) );
254           if ( pkgptr && VendorAttr::instance().autoProtect( pkgptr->vendor() ) )
255             {
256               item.status().setTransactValue( ResStatus::LOCKED, ResStatus::USER );
257               MIL << "Protect vendor '" << pkgptr->vendor() << "' " << *pkgptr << endl;
258             }
259         }
260
261       /* -------------------------------------------------------------------------------
262        * 3.) Feed
263        * ------------------------------------------------------------------------------- */
264       _poolImpl._store.insert( item );
265       _poolImpl._namehash.insert( item );
266       _poolImpl._caphash.insert( item );
267       // don't miss to invalidate ResPoolProxy
268       _poolImpl.invalidateProxy();
269     }
270
271     /******************************************************************
272     **
273     **  FUNCTION NAME : PoolImplDeleter::operator()
274     **  FUNCTION TYPE : void
275     */
276     void PoolImplDeleter::operator()( ResObject::constPtr ptr_r )
277     {
278       PoolImpl::Item item( ptr_r );
279       _poolImpl._store.erase( item );
280       _poolImpl._namehash.erase( item );
281       _poolImpl._caphash.erase( item );
282
283       // don't miss to invalidate ResPoolProxy
284       _poolImpl.invalidateProxy();
285     }
286
287
288     /////////////////////////////////////////////////////////////////
289   } // namespace pool
290   ///////////////////////////////////////////////////////////////////
291   /////////////////////////////////////////////////////////////////
292 } // namespace zypp
293 ///////////////////////////////////////////////////////////////////