ref: refs/heads/master
commit 728253d2aa930e19a8637b1e94e09c96a6c38128
Author: Michael Andres
Date: Mon Aug 3 13:53:35 2009 +0200
Use IdStrings for vendor equivalence detection.
---
zypp/VendorAttr.cc | 121 +++++++++++++++++++++++-------------
zypp/VendorAttr.h | 12 ++++-
zypp/solver/detail/Helper.cc | 2 +-
zypp/solver/detail/SATResolver.cc | 8 +-
zypp/ui/SelectableImpl.h | 2 +-
5 files changed, 94 insertions(+), 51 deletions(-)
diff --git a/zypp/VendorAttr.cc b/zypp/VendorAttr.cc
index 5481a96..d111b41 100644
--- a/zypp/VendorAttr.cc
+++ b/zypp/VendorAttr.cc
@@ -48,15 +48,73 @@ namespace zypp
{ /////////////////////////////////////////////////////////////////
typedef map VendorMap;
-
VendorMap _vendorMap;
- VendorMap _matchMap;
unsigned int vendorGroupCounter;
/////////////////////////////////////////////////////////////////
} // namespace
///////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////
+ namespace
+ { /////////////////////////////////////////////////////////////////
+ typedef DefaultIntegral VendorMatchEntry;
+ typedef std::tr1::unordered_map VendorMatch;
+ int _nextId = -1;
+ VendorMatch _vendorMatch;
+
+ /** Reset match cache if global VendorMap was changed. */
+ inline void vendorMatchIdReset()
+ {
+ _nextId = -1;
+ _vendorMatch.clear();
+ }
+
+ /**
+ * Helper mapping vendor string to eqivalence class ID.
+ *
+ * \li Return the vendor strings eqivalence class ID stored in _vendorMatch.
+ * \li If not found, assign and return the eqivalence class ID of the lowercased string.
+ * \li If not found, assign and return a new ID (look into the predefined VendorMap (id>0),
+ * otherwise create a new ID (<0)).
+ */
+ inline unsigned vendorMatchId( IdString vendor )
+ {
+ VendorMatchEntry & ent( _vendorMatch[vendor] );
+ if ( ! ent )
+ {
+ IdString lcvendor( str::toLower( vendor.asString() ) );
+ VendorMatchEntry & lcent( _vendorMatch[lcvendor] );
+ if ( ! lcent )
+ {
+ unsigned myid = 0;
+ // Compare this entry with the global vendor map.
+ // Reversed to get the longes prefix.
+ for ( VendorMap::reverse_iterator it = _vendorMap.rbegin(); it != _vendorMap.rend(); ++it )
+ {
+ if ( str::hasPrefix( lcvendor.c_str(), it->first ) )
+ {
+ myid = it->second;
+ break; // found
+ }
+ }
+ if ( ! myid )
+ {
+ myid = --_nextId; // get a new class ID
+ }
+ ent = lcent = myid; // remember the new DI
+ }
+ else
+ {
+ ent = lcent; // take the ID from the lowercased vendor string
+ }
+ }
+ return ent;
+ }
+ /////////////////////////////////////////////////////////////////
+ } // namespace
+ ///////////////////////////////////////////////////////////////////
+
const VendorAttr & VendorAttr::instance()
{
static VendorAttr _val;
@@ -154,6 +212,9 @@ namespace zypp
if (nextId == vendorGroupCounter + 1)
++vendorGroupCounter;
+
+ // invalidate any match cache
+ vendorMatchIdReset();
}
bool VendorAttr::addVendorFile( const Pathname & filename ) const
@@ -226,57 +287,29 @@ namespace zypp
return true;
}
+ //////////////////////////////////////////////////////////////////
+ // vendor equivalence:
+ //////////////////////////////////////////////////////////////////
+
bool VendorAttr::equivalent( IdString lVendor, IdString rVendor ) const
{
if ( lVendor == rVendor )
return true;
- return equivalent( lVendor.asString(), rVendor.asString() );
+ return vendorMatchId( lVendor ) == vendorMatchId( rVendor );
}
bool VendorAttr::equivalent( const Vendor & lVendor, const Vendor & rVendor ) const
- {
- unsigned int lhsID = 0;
- unsigned int rhsID = 0;
- Vendor lhs = str::toLower (lVendor);
- Vendor rhs = str::toLower (rVendor);
-
- if ( lhs == rhs )
- return true;
-
- // NOTE: iterate reverse to get find longest prefix first!
-
- if (_matchMap.find(lhs) != _matchMap.end()) {
- lhsID = _matchMap[lhs];
- } else {
- // compare this entry with the vendor map
- for (VendorMap::reverse_iterator it = _vendorMap.rbegin();
- it != _vendorMap.rend();
- ++it) {
- if (lhs.substr (0, it->first.size()) == it->first) {
- lhsID = it->second;
- _matchMap[lhs] = lhsID;
- break; // exit for
- }
- }
- }
-
- if (_matchMap.find(rhs) != _matchMap.end()) {
- rhsID = _matchMap[rhs];
- } else {
- // compare this entry with the vendor map
- for (VendorMap::reverse_iterator it = _vendorMap.rbegin();
- it != _vendorMap.rend();
- ++it) {
- if (rhs.substr (0, it->first.size()) == it->first) {
- rhsID = it->second;
- _matchMap[rhs] = rhsID;
- break; // exit for
- }
- }
- }
- return( lhsID && rhsID && lhsID == rhsID );
+ { return equivalent( IdString( lVendor ), IdString( rVendor ) );
}
+ bool VendorAttr::equivalent( sat::Solvable lVendor, sat::Solvable rVendor ) const
+ { return equivalent( lVendor.vendor(), rVendor.vendor() ); }
+
+ bool VendorAttr::equivalent( const PoolItem & lVendor, const PoolItem & rVendor ) const
+ { return equivalent( lVendor.satSolvable().vendor(), rVendor.satSolvable().vendor() ); }
+
+ //////////////////////////////////////////////////////////////////
+
std::ostream & operator<<( std::ostream & str, const VendorAttr & /*obj*/ )
{
str << "Equivalent vendors:";
diff --git a/zypp/VendorAttr.h b/zypp/VendorAttr.h
index 7ddda98..22ef3b5 100644
--- a/zypp/VendorAttr.h
+++ b/zypp/VendorAttr.h
@@ -23,6 +23,12 @@
namespace zypp {
//////////////////////////////////////////////////////////////////
+ class PoolItem;
+ namespace sat
+ {
+ class Solvable;
+ }
+
/** Definition of vendor equivalence.
*
* Packages with equivalment vendor strings may replace themself without
@@ -63,8 +69,12 @@ class VendorAttr
* different vendor usually must be confirmed by the user.
*/
bool equivalent( const Vendor & lVendor, const Vendor & rVendor ) const;
- /** \overload using IdStrings */
+ /** \overload using \ref IdStrings */
bool equivalent( IdString lVendor, IdString rVendor ) const;
+ /** \overload using \ref sat::Solvable */
+ bool equivalent( sat::Solvable lVendor, sat::Solvable rVendor ) const;
+ /** \overload using \ref PoolItem */
+ bool equivalent( const PoolItem & lVendor, const PoolItem & rVendor ) const;
private:
VendorAttr();
diff --git a/zypp/solver/detail/Helper.cc b/zypp/solver/detail/Helper.cc
index 45130c4..37a20da 100644
--- a/zypp/solver/detail/Helper.cc
+++ b/zypp/solver/detail/Helper.cc
@@ -132,7 +132,7 @@ class LookForUpdate : public resfilter::PoolItemFilterFunctor
if ( installed.resolvable() )
{
- if ( !VendorAttr::instance().equivalent(installed->vendor(),provider->vendor()) )
+ if ( !VendorAttr::instance().equivalent( installed, provider ) )
{
MIL << "Discarding '" << provider << "' from vendor '"
<< provider->vendor() << "' different to uninstalled '"
diff --git a/zypp/solver/detail/SATResolver.cc b/zypp/solver/detail/SATResolver.cc
index 1e67c6a..e336d22 100644
--- a/zypp/solver/detail/SATResolver.cc
+++ b/zypp/solver/detail/SATResolver.cc
@@ -69,10 +69,10 @@ IMPL_PTR_TYPE(SATResolver);
// Callbacks for SAT policies
//---------------------------------------------------------------------------
-int vendorCheck (Pool *pool, Solvable *solvable1, Solvable *solvable2) {
-// DBG << "vendorCheck: " << IdString(solvable1->vendor) << " <--> " << IdString(solvable2->vendor) << endl;
- return VendorAttr::instance().equivalent( IdString(solvable1->vendor).asString(),
- IdString(solvable2->vendor).asString() ) ? 0 : 1;
+int vendorCheck( Pool *pool, Solvable *solvable1, Solvable *solvable2 )
+{
+ return VendorAttr::instance().equivalent( IdString(solvable1->vendor),
+ IdString(solvable2->vendor) ) ? 0 : 1;
}
diff --git a/zypp/ui/SelectableImpl.h b/zypp/ui/SelectableImpl.h
index 008333b..8b71ae7 100644
--- a/zypp/ui/SelectableImpl.h
+++ b/zypp/ui/SelectableImpl.h
@@ -225,7 +225,7 @@ namespace zypp
{
if ( ! solver_allowVendorChange )
{
- if ( VendorAttr::instance().equivalent( (*iit).satSolvable().vendor(), (*it).satSolvable().vendor() ) )
+ if ( VendorAttr::instance().equivalent( (*iit), (*it) ) )
return *it;
else if ( ! sameArch ) // remember best same arch in case no same vendor found
sameArch = *it;
--
To unsubscribe, e-mail: zypp-commit+unsubscribe@opensuse.org
For additional commands, e-mail: zypp-commit+help@opensuse.org