- Install ResPoolProxy index to speedup Solvable to Selectable
[platform/upstream/libzypp.git] / zypp / ResPoolProxy.cc
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file       zypp/ResPoolProxy.cc
10  *
11 */
12 #include <iostream>
13 #include "zypp/base/LogTools.h"
14
15 #include "zypp/base/Measure.h"
16 using zypp::debug::Measure;
17
18 #include "zypp/base/Iterator.h"
19 #include "zypp/base/Algorithm.h"
20 #include "zypp/base/Functional.h"
21
22 #include "zypp/ResPoolProxy.h"
23 #include "zypp/pool/PoolImpl.h"
24 #include "zypp/ui/SelectableImpl.h"
25
26 using std::endl;
27
28 ///////////////////////////////////////////////////////////////////
29 namespace zypp
30 { /////////////////////////////////////////////////////////////////
31
32   /** Tem. friend of PoolItem */
33   struct PoolItemSaver
34   {
35     void saveState( ResPool pool_r )
36     {
37       std::for_each( pool_r.begin(), pool_r.end(),
38                      std::mem_fun_ref(&PoolItem::saveState) );
39     }
40
41     void saveState( ResPool pool_r, const ResKind & kind_r )
42     {
43       std::for_each( pool_r.byKindBegin(kind_r), pool_r.byKindEnd(kind_r),
44                      std::mem_fun_ref(&PoolItem::saveState) );
45     }
46
47     void restoreState( ResPool pool_r )
48     {
49       std::for_each( pool_r.begin(), pool_r.end(),
50                      std::mem_fun_ref(&PoolItem::restoreState) );
51     }
52
53     void restoreState( ResPool pool_r, const ResKind & kind_r )
54     {
55       std::for_each( pool_r.byKindBegin(kind_r), pool_r.byKindEnd(kind_r),
56                      std::mem_fun_ref(&PoolItem::restoreState) );
57     }
58
59     bool diffState( ResPool pool_r ) const
60     {
61       // return whether some PoolItem::sameState reported \c false.
62       return( invokeOnEach( pool_r.begin(), pool_r.end(),
63                             std::mem_fun_ref(&PoolItem::sameState) ) < 0 );
64     }
65
66     bool diffState( ResPool pool_r, const ResKind & kind_r ) const
67     {
68       // return whether some PoolItem::sameState reported \c false.
69       return( invokeOnEach( pool_r.byKindBegin(kind_r), pool_r.byKindEnd(kind_r),
70                             std::mem_fun_ref(&PoolItem::sameState) ) < 0 );
71     }
72   };
73
74   namespace
75   {
76     ui::Selectable::Ptr makeSelectablePtr( pool::PoolImpl::Id2ItemT::const_iterator begin_r,
77                                            pool::PoolImpl::Id2ItemT::const_iterator end_r )
78     {
79       pool::PoolTraits::byIdent_iterator begin( begin_r, pool::PoolTraits::Id2ItemValueSelector() );
80       pool::PoolTraits::byIdent_iterator end( end_r, pool::PoolTraits::Id2ItemValueSelector() );
81       sat::Solvable solv( begin->satSolvable() );
82
83       return new ui::Selectable( ui::Selectable::Impl_Ptr( new ui::Selectable::Impl( solv.kind(), solv.name(), begin, end ) ) );
84     }
85   } // namespace
86
87   ///////////////////////////////////////////////////////////////////
88   //
89   //    CLASS NAME : ResPoolProxy::Impl
90   //
91   /** ResPoolProxy implementation.
92    * \todo Seedup as it is still using old index
93   */
94   struct ResPoolProxy::Impl
95   {
96     typedef std::tr1::unordered_map<sat::detail::IdType,ui::Selectable::Ptr>
97             SelectableIndex;
98
99   public:
100     Impl()
101     :_pool( ResPool::instance() )
102     {}
103
104     Impl( ResPool pool_r, const pool::PoolImpl & poolImpl_r )
105     : _pool( pool_r )
106     {
107       Measure( "id2item" );
108       const pool::PoolImpl::Id2ItemT & id2item( poolImpl_r.id2item() );
109       if ( ! id2item.empty() )
110       {
111         sat::detail::IdType cidx = sat::detail::noId;
112         pool::PoolImpl::Id2ItemT::const_iterator cbegin = id2item.begin();
113
114         for_( it, id2item.begin(), id2item.end() )
115         {
116           sat::detail::IdType idx( it->first );
117           if ( idx != cidx )
118           {
119             // starting a new Selectable
120             if ( cidx )
121             {
122               // create the previous one
123               ui::Selectable::Ptr p( makeSelectablePtr( cbegin, it ) );
124               _selPool[p->kind()].push_back( p );
125               _selIndex[cidx] = p;
126             }
127             cidx = idx;
128             cbegin = it;
129           }
130         }
131         // create the final one
132         ui::Selectable::Ptr p( makeSelectablePtr( cbegin, id2item.end() ) );
133         _selPool[p->kind()].push_back( p );
134         _selIndex[cidx] = p;
135       }
136     }
137
138   public:
139     ui::Selectable::Ptr lookup( const pool::ByIdent & ident_r ) const
140     {
141       SelectableIndex::const_iterator it( _selIndex.find( ident_r.get() ) );
142       if ( it != _selIndex.end() )
143         return it->second;
144       return ui::Selectable::Ptr();
145     }
146
147   public:
148     bool empty( const ResKind & kind_r ) const
149     { return _selPool[kind_r].empty(); }
150
151     size_type size( const ResKind & kind_r ) const
152     { return _selPool[kind_r].size(); }
153
154     const_iterator byKindBegin( const ResKind & kind_r ) const
155     { return _selPool[kind_r].begin(); }
156
157     const_iterator byKindEnd( const ResKind & kind_r ) const
158     { return _selPool[kind_r].end(); }
159
160   public:
161     size_type knownRepositoriesSize() const
162     { return _pool.knownRepositoriesSize(); }
163
164     repository_iterator knownRepositoriesBegin() const
165     { return _pool.knownRepositoriesBegin(); }
166
167     repository_iterator knownRepositoriesEnd() const
168     { return _pool.knownRepositoriesEnd(); }
169
170   public:
171
172     void saveState() const
173     { PoolItemSaver().saveState( _pool ); }
174
175     void saveState( const ResKind & kind_r ) const
176     { PoolItemSaver().saveState( _pool, kind_r ); }
177
178     void restoreState() const
179     { PoolItemSaver().restoreState( _pool ); }
180
181     void restoreState( const ResKind & kind_r ) const
182     { PoolItemSaver().restoreState( _pool, kind_r ); }
183
184     bool diffState() const
185     { return PoolItemSaver().diffState( _pool ); }
186
187     bool diffState( const ResKind & kind_r ) const
188     { return PoolItemSaver().diffState( _pool, kind_r ); }
189
190   private:
191     ResPool _pool;
192     mutable SelectablePool _selPool;
193     mutable SelectableIndex _selIndex;
194
195   public:
196     /** Offer default Impl. */
197     static shared_ptr<Impl> nullimpl()
198     {
199       static shared_ptr<Impl> _nullimpl( new Impl );
200       return _nullimpl;
201     }
202   };
203   ///////////////////////////////////////////////////////////////////
204
205   /** \relates ResPoolProxy::Impl Stream output */
206   inline std::ostream & operator<<( std::ostream & str, const ResPoolProxy::Impl & obj )
207   {
208     return str << "ResPoolProxy::Impl";
209   }
210
211   ///////////////////////////////////////////////////////////////////
212   //
213   //    CLASS NAME : ResPoolProxy
214   //
215   ///////////////////////////////////////////////////////////////////
216
217   ///////////////////////////////////////////////////////////////////
218   //
219   //    METHOD NAME : ResPoolProxy::ResPoolProxy
220   //    METHOD TYPE : Ctor
221   //
222   ResPoolProxy::ResPoolProxy()
223   : _pimpl( Impl::nullimpl() )
224   {}
225
226   ///////////////////////////////////////////////////////////////////
227   //
228   //    METHOD NAME : ResPoolProxy::ResPoolProxy
229   //    METHOD TYPE : Ctor
230   //
231   ResPoolProxy::ResPoolProxy( ResPool pool_r, const pool::PoolImpl & poolImpl_r )
232   : _pimpl( new Impl( pool_r, poolImpl_r ) )
233   {}
234
235   ///////////////////////////////////////////////////////////////////
236   //
237   //    METHOD NAME : ResPoolProxy::~ResPoolProxy
238   //    METHOD TYPE : Dtor
239   //
240   ResPoolProxy::~ResPoolProxy()
241   {}
242
243   ///////////////////////////////////////////////////////////////////
244   //
245   // forward to implementation
246   //
247   ///////////////////////////////////////////////////////////////////
248
249   ui::Selectable::Ptr ResPoolProxy::lookup( const pool::ByIdent & ident_r ) const
250   { return _pimpl->lookup( ident_r ); }
251
252   bool ResPoolProxy::empty( const ResKind & kind_r ) const
253   { return _pimpl->empty( kind_r ); }
254
255   ResPoolProxy::size_type ResPoolProxy::size( const ResKind & kind_r ) const
256   { return _pimpl->size( kind_r ); }
257
258   ResPoolProxy::const_iterator ResPoolProxy::byKindBegin( const ResKind & kind_r ) const
259   { return _pimpl->byKindBegin( kind_r ); }
260
261   ResPoolProxy::const_iterator ResPoolProxy::byKindEnd( const ResKind & kind_r ) const
262   { return _pimpl->byKindEnd( kind_r ); }
263
264   ResPoolProxy::size_type ResPoolProxy::knownRepositoriesSize() const
265   { return _pimpl->knownRepositoriesSize(); }
266
267   ResPoolProxy::repository_iterator ResPoolProxy::knownRepositoriesBegin() const
268   { return _pimpl->knownRepositoriesBegin(); }
269
270   ResPoolProxy::repository_iterator ResPoolProxy::knownRepositoriesEnd() const
271   { return _pimpl->knownRepositoriesEnd(); }
272
273   void ResPoolProxy::saveState() const
274   { _pimpl->saveState(); }
275
276   void ResPoolProxy::saveState( const ResKind & kind_r ) const
277   { _pimpl->saveState( kind_r ); }
278
279   void ResPoolProxy::restoreState() const
280   { _pimpl->restoreState(); }
281
282   void ResPoolProxy::restoreState( const ResKind & kind_r ) const
283   { _pimpl->restoreState( kind_r ); }
284
285   bool ResPoolProxy::diffState() const
286   { return _pimpl->diffState(); }
287
288   bool ResPoolProxy::diffState( const ResKind & kind_r ) const
289   { return _pimpl->diffState( kind_r ); }
290
291   /******************************************************************
292    **
293    **   FUNCTION NAME : operator<<
294    **   FUNCTION TYPE : std::ostream &
295   */
296   std::ostream & operator<<( std::ostream & str, const ResPoolProxy & obj )
297   {
298     return str << *obj._pimpl;
299   }
300
301   /////////////////////////////////////////////////////////////////
302 } // namespace zypp
303 ///////////////////////////////////////////////////////////////////