Hi,
the same problem as with dist upgrade also hits with zypper lu, it does a
linear walk over all poolitems, for each calling the ByName iterator,
which in turn also walks over the entire pool. Not So Clever, except if
you want to test how the machine behaves with O(N^2) algorithms :)
This of course could be fixed in libzypp by building a name->poolitem
index itself and use it in the ByName iterator. But in the old libzypp a
considerable amount of space and time was used for just building several
dozen indices, and ideally we don't repeat this again. For one or two
ByName filters (e.g. when done in reaction to a user action) such index is
not necessary.
In this case of course it is. The question is, if we want to support such
use case in libzypp nicely, and if yes in which way. We could add an
ByNameFast filter which builds an index, or just rely on the callers being
fixed (like I do here).
What the SAT library can provide without much overhead is an index for a
ByKindName filter (doesn't exist yet), so _that_ one could be made fast
without taking many resources. Interestingly that happens to be the
usecase of zypper too.
Anyway, for the time being for people testing zypper of the sat branch,
this patch makes one usecase (which happens to be my primary performance
testcase) fast.
Ciao,
Michael.
Index: zypper-misc.cc
===================================================================
--- zypper-misc.cc (revision 8599)
+++ zypper-misc.cc (working copy)
@@ -1,6 +1,7 @@
#include <fstream>
#include <sstream>
#include
+#include
#include
#include
#include
@@ -33,6 +34,7 @@
//using namespace zypp::detail;
using namespace std;
+using namespace std::tr1;
using namespace zypp;
using namespace boost;
@@ -1231,6 +1233,7 @@ findArchUpdateItem( const ResPool & pool
// ----------------------------------------------------------------------------
typedef set<PoolItem> Candidates;
+typedef unordered_multimap Name2Item;
static void
find_updates( const ResObject::Kind &kind, Candidates &candidates )
@@ -1240,6 +1243,42 @@ find_updates( const ResObject::Kind &kin
it = pool.byKindBegin (kind),
e = pool.byKindEnd (kind);
cerr_vv << "Finding update candidates" << endl;
+#if 1
+ Name2Item name2item;
+ for (; it != e; ++it)
+ name2item.insert(std::make_pair((*it)->name(), *it));
+
+ it = pool.byKindBegin (kind);
+ for (; it != e; ++it)
+ {
+ if (it->status().isUninstalled())
+ continue;
+ PoolItem item = *it;
+ LookForArchUpdate info;
+ std::pair it2
+ = name2item.equal_range(item->name());
+ invokeOnEach( make_transform_iterator(it2.first, _Select2ndName2Item::value_type()),
+ make_transform_iterator(it2.second, _Select2ndName2Item::value_type()),
+ // get uninstalled, equal kind and arch, better edition
+ functor::chain (
+ functor::chain (
+ functor::chain (
+ resfilter::ByUninstalled (),
+ resfilter::ByKind( item->kind() ) ),
+ resfilter::byArch( item->arch() ) ),
+ resfilter::byEdition( item->edition() )),
+ functor::functorRef (info) );
+
+ _XDEBUG("findArchUpdateItem(" << item << ") => " << info.best);
+ PoolItem candidate = info.best;
+ if (!candidate.resolvable())
+ continue;
+
+ cerr_vv << "item " << *it << endl;
+ cerr_vv << "cand " << candidate << endl;
+ candidates.insert (candidate);
+ }
+#else
for (; it != e; ++it)
{
if (it->status().isUninstalled())
@@ -1253,6 +1292,7 @@ find_updates( const ResObject::Kind &kin
cerr_vv << "cand " << candidate << endl;
candidates.insert (candidate);
}
+#endif
}
// ----------------------------------------------------------------------------
--
To unsubscribe, e-mail: zypp-devel+unsubscribe@opensuse.org
For additional commands, e-mail: zypp-devel+help@opensuse.org