fixed duplicates of target resolvables in sources - second part of #224673 fix
authorJan Kupec <jkupec@suse.cz>
Mon, 4 Dec 2006 07:08:52 +0000 (07:08 +0000)
committerJan Kupec <jkupec@suse.cz>
Mon, 4 Dec 2006 07:08:52 +0000 (07:08 +0000)
doc/TODO
package/zypper.changes
src/zypper-search.cc
src/zypper-search.h

index 4d72376..0255c03 100644 (file)
--- a/doc/TODO
+++ b/doc/TODO
@@ -6,8 +6,6 @@ General
 - installation and deletion notifications
 - --dry-run (use ZYppCommitPolicy.h)
 - confirm license: more user friendly (see confirm_licenses() comment)
-- FIXME zypper search ignores target packages that were not installed
-  from sources
 
 Patches
 
index b42f48a..658ccf9 100644 (file)
@@ -1,4 +1,9 @@
 -------------------------------------------------------------------
+Mon Dec  4 08:03:57 CET 2006 - jkupec@suse.cz
+
+- fixed missing target resolvables in search (#224673)
+
+-------------------------------------------------------------------
 Fri Dec  1 15:40:10 CET 2006 - mvidner@suse.cz
 
 - installation_sources: fixed to be compatible even with
index ce19e0c..224a713 100644 (file)
@@ -12,7 +12,6 @@ using namespace zypp;
 using namespace zypp::functor;
 using namespace zypp::resfilter;
 
-// TODO get rid of these globals
 extern RuntimeData gData;
 
 void ZyppSearchOptions::resolveConflicts() {
@@ -30,7 +29,7 @@ void ZyppSearchOptions::resolveConflicts() {
  * Initializes installation sources, creates search regex, caches installed
  * packages from RPM database, and populates ResPool with items from
  * installation sources.
- */ 
+ */
 ZyppSearch::ZyppSearch (
     ZYpp::Ptr & zypp,
     const ZyppSearchOptions & options,
@@ -51,6 +50,10 @@ ZyppSearch::ZyppSearch (
   setupRegexp();
   cacheInstalled();
   load_sources(); // populates ResPool with resolvables from inst. sources
+
+  // cache identification strings of source resolvables (used to check for
+  // duplicates of target resolvables in sources - DuplicateFilter)
+  invokeOnEachSearched(not_c(ByInstalled()), functorRef<bool,const zypp::PoolItem &>(_idcache));
 }
 
 /**
@@ -131,6 +134,8 @@ void ZyppSearch::doSearch(const boost::function<bool(const PoolItem &)> & f) {
     default:
       filter = Match(_reg,_options.searchDescriptions());
   }
+  
+  filter = chain(filter,DuplicateFilter(_idcache));
 
   invokeOnEachSearched(filter, f);
 }
index e4e8863..9841b0d 100644 (file)
 #define ZYPPERSEARCH_H_
 
 #include <string>
-#include <ext/hash_map>
 #include <boost/regex.hpp>
 #include <boost/function.hpp>
 #include <zypp/ZYpp.h>
+#include <zypp/base/Hash.h>
 
 #include "zmart.h"
 #include "zypper-tabulator.h"
@@ -81,11 +81,11 @@ struct GenericStringHash {
   }
 };
 
-typedef __gnu_cxx::hash_map<std::string, zypp::PoolItem, GenericStringHash> PoolItemHash;
+typedef zypp::hash_map<std::string, zypp::PoolItem> PoolItemHash;
 
 /**
  * Structure for caching installed PoolItems using a hash map.
- * Name + edition + (if _incl_kind_in_key) kind is used as a key.
+ * Name + (if _incl_kind_in_key) kind is used as a key.
  * The hash map is to be manipulated through addItem() and getItem() methods. 
  */
 struct InstalledCache  {
@@ -123,6 +123,39 @@ public:
   }
 };
 
+
+typedef zypp::hash_set<std::string> IdSet;
+
+/**
+ * Structure for caching identification strings of source PoolItems using
+ * a hash set. Name + edition + kind + architecture is used as a key.
+ * The has set is to be manipulated through addItem() and contains() methods. 
+ */
+struct IdCache {
+private:
+  IdSet _items;
+
+public:
+  std::string getKey(const zypp::PoolItem & pi) const {
+    return pi.resolvable()->name() + pi.resolvable()->edition().asString() +
+      pi.resolvable()->kind().asString() + pi.resolvable()->arch().asString();
+  }
+
+  void addItem(const zypp::PoolItem & pi) { _items.insert(getKey(pi)); }
+
+  bool contains(const zypp::PoolItem & pi) {
+    return _items.count(getKey(pi));
+  }
+
+  /** defined for use as a functor for filling the IdSet in a for_each */ 
+  bool operator()(const zypp::PoolItem & pi) {
+    addItem(pi);
+    return true;
+  }
+
+  int size() { return _items.size(); }
+};
+
 /**
  * TODO
  */
@@ -146,6 +179,7 @@ private:
   boost::regex _reg;
 
   InstalledCache _icache;
+  IdCache _idcache;
 
   void setupRegexp();
   void cacheInstalled();
@@ -215,7 +249,8 @@ struct FillTable
     zypp::PoolItem inst_item = _icache->getItem(pool_item);
     if (inst_item) {
       // check whether the pool item is installed...
-      if (pool_item.status().isInstalled())
+      if (inst_item.resolvable()->edition() == pool_item.resolvable()->edition() &&
+          inst_item.resolvable()->arch() == pool_item.resolvable()->arch())
         row << "i";
       // ... or there's just another version of it installed
       else
@@ -270,4 +305,18 @@ struct Match {
   }
 };
 
+/**
+ * Filters target poolitems which have their counterpart among source
+ * resolvables.
+ */
+struct DuplicateFilter {
+  IdCache * _idcache;
+
+  DuplicateFilter(IdCache & idcache) : _idcache(&idcache) {}
+
+  bool operator()(const zypp::PoolItem & pi) const {
+    return !(pi.status().isInstalled() && _idcache->contains(pi));
+  }
+};
+
 #endif /*ZYPPERSEARCH_H_*/