ref: refs/heads/ma-misc
commit cdd51dfd2bc6fb64d22a99e325462cab6e180299
Author: Michael Andres
Date: Fri Oct 30 11:27:42 2009 +0100
New class PoolItemBest: Find the best candidates e.g. in a PoolQuery result.
---
zypp/CMakeLists.txt | 2 +
zypp/PoolItemBest.cc | 80 ++++++++++++++++++++++++
zypp/PoolItemBest.h | 155 ++++++++++++++++++++++++++++++++++++++++++++++
zypp/PoolQuery.h | 6 ++
zypp/sat/SolvIterMixin.h | 6 ++
5 files changed, 249 insertions(+), 0 deletions(-)
diff --git a/zypp/CMakeLists.txt b/zypp/CMakeLists.txt
index 4a124e6..40973fc 100644
--- a/zypp/CMakeLists.txt
+++ b/zypp/CMakeLists.txt
@@ -41,6 +41,7 @@ SET( zypp_SRCS
Pathname.cc
Pattern.cc
PoolItem.cc
+ PoolItemBest.cc
PoolQuery.cc
PoolQueryResult.cc
ProblemSolution.cc
@@ -131,6 +132,7 @@ SET( zypp_HEADERS
Pathname.h
Pattern.h
PoolItem.h
+ PoolItemBest.h
PoolQuery.h
PoolQueryUtil.tcc
PoolQueryResult.h
diff --git a/zypp/PoolItemBest.cc b/zypp/PoolItemBest.cc
new file mode 100644
index 0000000..d6e4062
--- /dev/null
+++ b/zypp/PoolItemBest.cc
@@ -0,0 +1,80 @@
+/*---------------------------------------------------------------------\
+| ____ _ __ __ ___ |
+| |__ / \ / / . \ . \ |
+| / / \ V /| _/ _/ |
+| / /__ | | | | | | |
+| /_____||_| |_| |_| |
+| |
+\---------------------------------------------------------------------*/
+/** \file zypp/PoolItemBest.cc
+ *
+*/
+#include <iostream>
+#include "zypp/base/LogTools.h"
+
+#include "zypp/PoolItemBest.h"
+#include "zypp/ui/SelectableTraits.h"
+
+using std::endl;
+
+///////////////////////////////////////////////////////////////////
+namespace zypp
+{ /////////////////////////////////////////////////////////////////
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : PoolItemBest::Impl
+ //
+ /** PoolItemBest implementation. */
+ struct PoolItemBest::Impl
+ {
+ Container _container;
+
+ private:
+ friend Impl * rwcowClone<Impl>( const Impl * rhs );
+ /** clone for RWCOW_pointer */
+ Impl * clone() const
+ { return new Impl( *this ); }
+ };
+ ///////////////////////////////////////////////////////////////////
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : PoolItemBest
+ //
+ ///////////////////////////////////////////////////////////////////
+
+ void PoolItemBest::_ctor_init()
+ { _dont_use_this_use_pimpl.reset( new RWCOW_pointer<Impl>(new Impl) ); }
+
+ const PoolItemBest::Container & PoolItemBest::container() const
+ { return pimpl()->_container; }
+
+ void PoolItemBest::add( const PoolItem & pi_r )
+ {
+ Container & container( pimpl()->_container );
+ PoolItem & ccand( container[pi_r.satSolvable().ident()] );
+ if ( ! ccand || ui::SelectableTraits::AVOrder()( pi_r, ccand ) )
+ ccand = pi_r;
+ }
+
+ PoolItem PoolItemBest::find( IdString ident_r ) const
+ {
+ const Container & container( pimpl()->_container );
+ Container::const_iterator it( container.find( ident_r ) );
+ return it != container.end() ? it->second : PoolItem();
+ }
+
+ /******************************************************************
+ **
+ ** FUNCTION NAME : operator<<
+ ** FUNCTION TYPE : std::ostream &
+ */
+ std::ostream & operator<<( std::ostream & str, const PoolItemBest & obj )
+ {
+ return dumpRange( str << "(" << obj.size() << ") ", obj.begin(), obj.end() );
+ }
+
+ /////////////////////////////////////////////////////////////////
+} // namespace zypp
+///////////////////////////////////////////////////////////////////
diff --git a/zypp/PoolItemBest.h b/zypp/PoolItemBest.h
new file mode 100644
index 0000000..2dbebcb
--- /dev/null
+++ b/zypp/PoolItemBest.h
@@ -0,0 +1,155 @@
+/*---------------------------------------------------------------------\
+| ____ _ __ __ ___ |
+| |__ / \ / / . \ . \ |
+| / / \ V /| _/ _/ |
+| / /__ | | | | | | |
+| /_____||_| |_| |_| |
+| |
+\---------------------------------------------------------------------*/
+/** \file zypp/PoolItemBest.h
+ *
+*/
+#ifndef ZYPP_POOLITEMBEST_H
+#define ZYPP_POOLITEMBEST_H
+
+#include <iosfwd>
+
+#include "zypp/base/PtrTypes.h"
+#include "zypp/base/Function.h"
+#include "zypp/base/Iterator.h"
+#include "zypp/base/Tr1hash.h"
+
+#include "zypp/PoolItem.h"
+
+///////////////////////////////////////////////////////////////////
+namespace zypp
+{ /////////////////////////////////////////////////////////////////
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : PoolItemBest
+ //
+ /** Find the best candidates e.g. in a \ref PoolQuery result.
+ *
+ * The class basically maintains a \c map and remembers
+ * for each \c ident (\ref sat::Solvable::ident) the best \ref PoolItem that
+ * was added.
+ *
+ * The default \ref Predicate to determine the best choice is the same that
+ * sorts the \ref ui::Selectable list of available objects, thus follows the
+ * same rules the \ref resolver will apply.
+ *
+ * \code
+ * PoolQuery q;
+ * q.addAttribute(sat::SolvAttr::name, "lib*");
+ * q.setMatchGlob();
+ *
+ * // get the best matches and tag them for installation:
+ * PoolItemBest bestMatches( q.begin(), q.end() );
+ * if ( ! bestMatches.empty() )
+ * {
+ * for_( it, bestMatches.begin(), bestMatches.end() )
+ * {
+ * ui::asSelectable()( *it )->setOnSystem( *it, ResStatus::USER );
+ * }
+ * }
+ * \endcode
+ *
+ * \todo Support arbitrary Predicates.
+ */
+ class PoolItemBest
+ {
+ typedef std::tr1::unordered_map Container;
+ public:
+ /** Predicate returning \c True if \a lhs is a better choice. */
+ typedef boost::function Predicate;
+
+ typedef Container::size_type size_type;
+ typedef Container::value_type value_type;
+ typedef MapKVIteratorTraits<Container>::Value_const_iterator iterator;
+ typedef MapKVIteratorTraits<Container>::Key_const_iterator ident_iterator;
+
+ public:
+ /** Default ctor. */
+ PoolItemBest()
+ {}
+
+ /** Ctor feeding a \ref sat::Solvable. */
+ PoolItemBest( sat::Solvable slv_r )
+ { _ctor_init(); add( slv_r ); }
+
+ /** Ctor feeding a \ref PoolItem. */
+ PoolItemBest( const PoolItem & pi_r )
+ { _ctor_init(); add( pi_r ); }
+
+ /** Ctor feeding a range of \ref sat::Solvable or \ref PoolItem. */
+ template<class _Iterator>
+ PoolItemBest( _Iterator begin_r, _Iterator end_r )
+ { _ctor_init(); add( begin_r, end_r ); }
+
+ public:
+ /** Feed one \ref sat::Solvable. */
+ void add( sat::Solvable slv_r )
+ { add( PoolItem( slv_r ) ); }
+
+ /** Feed one \ref PoolItem. */
+ void add( const PoolItem & pi_r );
+
+ /** Feed a range of \ref sat::Solvable or \ref PoolItem. */
+ template<class _Iterator>
+ void add( _Iterator begin_r, _Iterator end_r )
+ {
+ for_( it, begin_r, end_r )
+ add( *it );
+ }
+
+ public:
+ /** \name Iterate the collected PoolItems. */
+ //@{
+ /** Whether PoolItems were collected. */
+ bool empty() const { return container().empty(); }
+ /** Number of PoolItems collected. */
+ size_type size() const { return container().size(); }
+ /** Pointer to the first PoolItem. */
+ iterator begin() const { return make_map_value_begin( container() ); }
+ /** Pointer behind the last PoolItem. */
+ iterator end() const { return make_map_value_end( container() ); }
+
+ /** Return the collected \ref PoolItem with \ref sat::Solvable::ident \a ident_r. */
+ PoolItem find( IdString ident_r ) const;
+ /** \overload Use Solvables ident string. */
+ PoolItem find( sat::Solvable slv_r ) const { return find( slv_r.ident() ); }
+ /** \overload Use PoolItems ident string. */
+ PoolItem find( const PoolItem & pi_r ) const { return find( pi_r.satSolvable().ident() ); }
+ //@}
+
+ /** \name Iterate the collected PoolItems ident strings. */
+ //@{
+ /** Pointer to the first item. */
+ ident_iterator identBegin() const { return make_map_key_begin( container() ); }
+ /** Pointer behind the last item. */
+ ident_iterator identEnd() const { return make_map_key_end( container() ); }
+ //@}
+
+ private:
+ void _ctor_init();
+ const Container & container() const;
+ private:
+ /** Implementation */
+ class Impl;
+ /** Pointer to implementation */
+ RWCOW_pointer<Impl> & pimpl() { return *(reinterpret_cast( _dont_use_this_use_pimpl.get() )); }
+ /** Pointer to implementation */
+ const RWCOW_pointer<Impl> & pimpl() const { return *(reinterpret_cast( _dont_use_this_use_pimpl.get() )); }
+ /** Avoid need to include Impl definition when inlined ctors (due to tepmlate) are provided. */
+ shared_ptr<void> _dont_use_this_use_pimpl;
+ };
+ ///////////////////////////////////////////////////////////////////
+
+ /** \relates PoolItemBest Stream output */
+ std::ostream & operator<<( std::ostream & str, const PoolItemBest & obj );
+
+ /////////////////////////////////////////////////////////////////
+} // namespace zypp
+///////////////////////////////////////////////////////////////////
+#endif // ZYPP_POOLITEMBEST_H
diff --git a/zypp/PoolQuery.h b/zypp/PoolQuery.h
index 8f783fa..ec974fd 100644
--- a/zypp/PoolQuery.h
+++ b/zypp/PoolQuery.h
@@ -53,6 +53,12 @@ namespace zypp
* objects. Additionally, thanx to the \ref sat::SolvIterMixin, a Selectable
* and PoolItem iterators are automatically available.
*
+ * \note You will sometimes face the problem, that when using the \ref PoolItem
+ * iterator you hit multiple version of the same package, while when using the
+ * \ref ui::Selectable iterator the information which of the available candidates
+ * actually matched got lost. In this case class \ref PoolItemBest may help you.
+ * Use it to pick the best version only.
+ *
* <code>
* PoolQuery q;
* q.addAttribute(sat::SolvAttr::name, "zypp*");
diff --git a/zypp/sat/SolvIterMixin.h b/zypp/sat/SolvIterMixin.h
index f5a79ff..811d60e 100644
--- a/zypp/sat/SolvIterMixin.h
+++ b/zypp/sat/SolvIterMixin.h
@@ -77,6 +77,12 @@ namespace zypp
* and \ref size by iterating from \c begin to \c end. In case \c Derived is
* able to provide a more efficient implementation, the methods should be overloaded.
*
+ * \note You will sometimes face the problem, that when using the \ref PoolItem
+ * iterator you hit multiple version of the same package, while when using the
+ * \ref ui::Selectable iterator the information which of the available candidates
+ * actually matched got lost. In this case class \ref PoolItemBest may help you.
+ * Use it to pick the best version only.
+ *
* \code
* namespace detail
* {
--
To unsubscribe, e-mail: zypp-commit+unsubscribe@opensuse.org
For additional commands, e-mail: zypp-commit+help@opensuse.org