avoid map in PoolImpl
[platform/upstream/libzypp.git] / zypp / pool / PoolImpl.h
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file       zypp/pool/PoolImpl.h
10  *
11 */
12 #ifndef ZYPP_POOL_POOLIMPL_H
13 #define ZYPP_POOL_POOLIMPL_H
14
15 #include <iosfwd>
16 #include <map>
17
18 #include "zypp/base/Easy.h"
19 #include "zypp/base/SerialNumber.h"
20 #include "zypp/base/Deprecated.h"
21
22 #include "zypp/pool/PoolTraits.h"
23 #include "zypp/ResPoolProxy.h"
24
25 #include "zypp/sat/Pool.h"
26
27 using std::endl;
28
29 ///////////////////////////////////////////////////////////////////
30 namespace zypp
31 { /////////////////////////////////////////////////////////////////
32   ///////////////////////////////////////////////////////////////////
33   namespace pool
34   { /////////////////////////////////////////////////////////////////
35
36     ///////////////////////////////////////////////////////////////////
37     //
38     //  CLASS NAME : PoolImpl
39     //
40     /** */
41     class PoolImpl
42     {
43       friend std::ostream & operator<<( std::ostream & str, const PoolImpl & obj );
44
45       public:
46         /** */
47         typedef PoolTraits::ItemContainerT              ContainerT;
48         typedef PoolTraits::size_type                   size_type;
49         typedef PoolTraits::const_iterator              const_iterator;
50
51         typedef sat::detail::SolvableIdType             SolvableIdType;
52
53         typedef PoolTraits::AdditionalCapabilities      AdditionalCapabilities;
54         typedef PoolTraits::RepoContainerT              KnownRepositories;
55
56       public:
57         /** Default ctor */
58         PoolImpl();
59         /** Dtor */
60         ~PoolImpl();
61
62       public:
63         /** convenience. */
64         const sat::Pool satpool() const
65         { return sat::Pool::instance(); }
66
67         /** Housekeeping data serial number. */
68         const SerialNumber & serial() const
69         { return satpool().serial(); }
70
71         ///////////////////////////////////////////////////////////////////
72         //
73         ///////////////////////////////////////////////////////////////////
74       public:
75         /**  */
76         bool empty() const
77         { return satpool().solvablesEmpty(); }
78
79         /**  */
80         size_type size() const
81         { return satpool().solvablesSize(); }
82
83       public:
84         /** Return the corresponding \ref PoolItem.
85          * Pool and sat pool should be in sync. Returns an empty
86          * \ref PoolItem if there is no corresponding \ref PoolItem.
87          * \see \ref PoolItem::satSolvable.
88          */
89         PoolItem find( const sat::Solvable & slv_r ) const
90         {
91           return store()[slv_r.id()];
92         }
93
94         ///////////////////////////////////////////////////////////////////
95         //
96         ///////////////////////////////////////////////////////////////////
97       public:
98         /** \name Save and restore state. */
99         //@{
100         void SaveState( const ResObject::Kind & kind_r );
101
102         void RestoreState( const ResObject::Kind & kind_r );
103         //@}
104
105         ///////////////////////////////////////////////////////////////////
106         //
107         ///////////////////////////////////////////////////////////////////
108       public:
109         /**
110          *  Handling additional requirement. E.G. need package "foo" and package
111          *  "foo1" which has a greater version than 1.0:
112          *
113          *  Capset capset;
114          *  capset.insert (CapFactory().parse( ResTraits<Package>::kind, "foo"));
115          *  capset.insert (CapFactory().parse( ResTraits<Package>::kind, "foo1 > 1.0"));
116          *
117          *  setAdditionalRequire( capset );
118          */
119         void setAdditionalRequire( const AdditionalCapabilities & capset ) const
120         { _additionalRequire = capset; }
121         AdditionalCapabilities & additionalRequire() const
122         { return _additionalRequire; }
123
124         /**
125          *  Handling additional conflicts. E.G. do not install anything which provides "foo":
126          *
127          *  Capset capset;
128          *  capset.insert (CapFactory().parse( ResTraits<Package>::kind, "foo"));
129          *
130          *  setAdditionalConflict( capset );
131          */
132         void setAdditionalConflict( const AdditionalCapabilities & capset ) const
133         { _additionaConflict = capset; }
134         AdditionalCapabilities & additionaConflict() const
135         { return _additionaConflict; }
136
137         /**
138          *  Handling additional provides. This is used for ignoring a requirement.
139          *  e.G. Do ignore the requirement "foo":
140          *
141          *  Capset capset;
142          *  capset.insert (CapFactory().parse( ResTraits<Package>::kind, "foo"));
143          *
144          *  setAdditionalProvide( cap );
145          */
146         void setAdditionalProvide( const AdditionalCapabilities & capset ) const
147         { _additionaProvide = capset; }
148         AdditionalCapabilities & additionaProvide() const
149         { return _additionaProvide; }
150
151         ///////////////////////////////////////////////////////////////////
152         //
153         ///////////////////////////////////////////////////////////////////
154       public:
155         ResPoolProxy proxy( ResPool self ) const
156         {
157           checkSerial();
158           if ( !_poolProxy )
159             _poolProxy.reset( new ResPoolProxy( self ) );
160           return *_poolProxy;
161         }
162
163       public:
164         /** Access list of Repositories that contribute ResObjects.
165          * Built on demand.
166          */
167         const KnownRepositories & knownRepositories() const
168         {
169           checkSerial();
170           if ( ! _knownRepositoriesPtr )
171           {
172             _knownRepositoriesPtr.reset( new KnownRepositories );
173
174             sat::Pool pool( satpool() );
175             for_( it, pool.reposBegin(), pool.reposEnd() )
176             {
177               _knownRepositoriesPtr->push_back( Repository( it->info() ) );
178             }
179           }
180           return *_knownRepositoriesPtr;
181         }
182
183         ///////////////////////////////////////////////////////////////////
184         //
185         ///////////////////////////////////////////////////////////////////
186       public:
187         const ContainerT & store() const
188         {
189           checkSerial();
190           if ( _storeDirty )
191           {
192             sat::Pool pool( satpool() );
193
194             if ( pool.capacity() != _store.capacity() )
195             {
196               _store.resize( pool.capacity() );
197             }
198
199             if ( pool.capacity() )
200             {
201               for ( sat::detail::SolvableIdType i = pool.capacity()-1; i != 0; --i )
202               {
203                 sat::Solvable s( i );
204                 PoolItem & pi( _store[i] );
205                 if ( ! s &&  pi )
206                   pi = PoolItem();
207                 else if ( s && ! pi )
208                   pi = PoolItem( s );
209               }
210             }
211 #if 0
212             // pass 1: delete no longer existing solvables
213             for ( ContainerT::iterator it = _store.begin(); it != _store.end(); /**/ )
214             {
215               if ( ! it->first ) // solvable became invalid
216                 _store.erase( it++ ); // postfix! Incrementing before erase
217               else
218                 ++it;
219             }
220
221             // pass 2: add new solvables
222             sat::Pool pool( satpool() );
223             if ( _store.size() != pool.solvablesSize() )
224             {
225               for_( it, pool.solvablesBegin(), pool.solvablesEnd() )
226               {
227                 PoolItem & pi( _store[*it] );
228                 if ( ! pi ) // newly created
229                 {
230                   pi = PoolItem( *it );
231                 }
232               }
233             }
234 #endif
235             _storeDirty = false;
236           }
237           return _store;
238         }
239
240         ///////////////////////////////////////////////////////////////////
241         //
242         ///////////////////////////////////////////////////////////////////
243       private:
244         void checkSerial() const
245         {
246           if ( _watcher.remember( serial() ) )
247             invalidate();
248         }
249
250         void invalidate() const
251         {
252           _storeDirty = true;
253           _poolProxy.reset();
254           _knownRepositoriesPtr.reset();
255         }
256
257       private:
258         /** Watch sat pools serial number. */
259         SerialNumberWatcher                   _watcher;
260         mutable ContainerT                    _store;
261         mutable DefaultIntegral<bool,true>    _storeDirty;
262
263       private:
264         mutable AdditionalCapabilities        _additionalRequire;
265         mutable AdditionalCapabilities        _additionaConflict;
266         mutable AdditionalCapabilities        _additionaProvide;
267
268         mutable shared_ptr<ResPoolProxy>      _poolProxy;
269         mutable scoped_ptr<KnownRepositories> _knownRepositoriesPtr;
270
271       public:
272         /** \bug FAKE capindex */
273         const PoolTraits::CapItemContainerT   _caphashfake;
274     };
275     ///////////////////////////////////////////////////////////////////
276
277     /////////////////////////////////////////////////////////////////
278   } // namespace pool
279   ///////////////////////////////////////////////////////////////////
280   /////////////////////////////////////////////////////////////////
281 } // namespace zypp
282 ///////////////////////////////////////////////////////////////////
283 #endif // ZYPP_POOL_POOLIMPL_H