Incorporated patch from Michael Matz to speedup cache reading.
authorMichael Andres <ma@suse.de>
Mon, 1 Oct 2007 18:32:52 +0000 (18:32 +0000)
committerMichael Andres <ma@suse.de>
Mon, 1 Oct 2007 18:32:52 +0000 (18:32 +0000)
zypp/CapFactory.cc
zypp/cache/CacheTypes.cc
zypp/cache/CacheTypes.h
zypp/capability/CapabilityImpl.cc
zypp/capability/CapabilityImpl.h
zypp/capability/NamedCap.cc
zypp/capability/NamedCap.h
zypp/capability/VersionedCap.cc
zypp/capability/VersionedCap.h
zypp/repo/cached/RepoImpl.cc

index 9a61d4843d4d18ad24c3927bafaf5e2d4870421b..0cebed9042d756f4086dd4f7924839545143e26e 100644 (file)
@@ -38,7 +38,8 @@ namespace
   {
     size_t operator() ( const CapabilityImpl::Ptr & p ) const
     {
-      return __gnu_cxx::hash<const char*>()( p->encode().c_str() );
+      //return __gnu_cxx::hash<const char*>()( p->encode().c_str() );
+      return p->hash();
     }
   };
 
@@ -46,9 +47,10 @@ namespace
   {
     bool operator() ( const CapabilityImpl::Ptr & lhs, const CapabilityImpl::Ptr & rhs ) const
     {
-      return (    lhs->encode() == rhs->encode()
-               && lhs->kind()   == rhs->kind()
-               && lhs->refers() == rhs->refers() );
+      return ::zypp::capability::exactly_same_caps_p (lhs, rhs);
+      /*return (    lhs->refers() == rhs->refers()
+              && lhs->kind()   == rhs->kind()
+              && lhs->encode() == rhs->encode() );*/
     }
   };
 
index 3fbeb4845b0e97b2b662e8a024d9f34a36e0db81..404a0fa2ca74313f45ef09a9b699aeb6d3635833 100644 (file)
@@ -67,7 +67,8 @@ namespace zypp
           if ( klass == "kind" )
             _kind_cache[id] = Resolvable::Kind(name);
           if ( klass == "deptype" )
-            _deptype_cache[id] = name;
+           /* As Dep has no default ctor we can't use the [] accessor.  */
+           _deptype_cache.insert (make_pair (id, Dep(name)));
         }
         
         MIL << "archs: " << _arch_cache.size() << endl;
@@ -130,9 +131,9 @@ namespace zypp
     
     Dep CacheTypes::deptypeFor( const data::RecordId &id )
     {
-      std::map<data::RecordId, string>::const_iterator it;
+      std::map<data::RecordId, Dep>::const_iterator it;
       if ( (it = _deptype_cache.find(id) ) != _deptype_cache.end() )
-        return Dep(it->second);
+        return it->second;
       else
       {
         ERR << "deptype: " << id << endl;
@@ -142,10 +143,10 @@ namespace zypp
 
     data::RecordId CacheTypes::idForDeptype( const Dep & dep )
     {
-      std::map<data::RecordId, string>::const_iterator it;
+      std::map<data::RecordId, Dep>::const_iterator it;
       for ( it = _deptype_cache.begin(); it != _deptype_cache.end(); ++it )
       {
-        if ( dep.asString() == it->second )
+        if ( dep == it->second )
          return it->first;
       }
       ZYPP_THROW(Exception("Inconsistent deptype"));   
index 7158789610570c3cd5a9225561abf7df2286c6c5..ecf090326ac2a8bf7f4564f3b47dcc09d35a295c 100644 (file)
@@ -136,7 +136,7 @@ namespace zypp
       
       std::map<data::RecordId, Rel> _rel_cache;
       std::map<data::RecordId, Resolvable::Kind> _kind_cache;
-      std::map<data::RecordId, std::string> _deptype_cache;
+      std::map<data::RecordId, Dep> _deptype_cache;
       std::map<data::RecordId, Arch> _arch_cache;
       Pathname _dbdir;
     };
index 544c80fa21eaec091a56d5ee3e580d28802d2be7..46cfff89ce22fb73a77dfc5e8ad8f7e53da265f4 100644 (file)
@@ -10,6 +10,7 @@
  *
 */
 #include <iostream>
+#include <ext/hash_fun.h>
 
 #include "zypp/base/Logger.h"
 #include "zypp/base/Regex.h"
@@ -46,6 +47,18 @@ namespace zypp
       return encode() < rhs->encode();
     }
 
+    std::size_t CapabilityImpl::hash() const
+    {
+      std::size_t ret = __gnu_cxx::hash<const char*>()( encode().c_str() );
+      return ret;
+    }
+
+    bool CapabilityImpl::same (const constPtr &rhs) const
+    {
+      /* refers and kind are known to be the same */
+      return encode() == rhs->encode();
+    }
+
     ///////////////////////////////////////////////////////////////////
     //
     // METHOD NAME : CapabilityImpl::capImplOrderLess
@@ -167,11 +180,14 @@ namespace zypp
       }
 
       //split:   name:/absolute/path
-      static const str::regex  rx( "([^/]*):(/.*)" );
-      str::smatch what;
-      if( str::regex_match( name_r, what, rx ) )
+      if (isSplitSpec (name_r))
       {
-        return new capability::SplitCap( refers_r, what[1], what[2] );
+        static const str::regex  rx( "([^/]*):(/.*)" );
+        str::smatch what;
+        if( str::regex_match( name_r, what, rx ) )
+        {
+          return new capability::SplitCap( refers_r, what[1], what[2] );
+        }
       }
 
       //name:    name
@@ -292,7 +308,8 @@ namespace zypp
       // improve regex!
       static const str::regex  rx( "(.*[^ \t])([ \t]+)([^ \t]+)([ \t]+)([^ \t]+)" );
       str::smatch what;
-      if( str::regex_match( strval_r,what, rx ) )
+      if( strval_r.find(' ') != std::string::npos
+         && str::regex_match( strval_r,what, rx ) )
         {
           Rel op;
           Edition edition;
index 01020dc5b964df31f7021c77fe7cf5688f9c402b..0a304b7672fb00b0bc243af169d6a793b43bd70e 100644 (file)
@@ -110,6 +110,9 @@ namespace zypp
       virtual std::string index() const
       { return encode(); }
 
+      virtual size_t hash() const;
+      virtual bool same (const constPtr &rhs) const;
+
     public:
       /** Solver hack. */
       struct SplitInfo
@@ -318,6 +321,14 @@ namespace zypp
 
     typedef std::set<CapabilityImpl::Ptr> CapabilityImplPtrSet;
 
+    inline bool exactly_same_caps_p (const CapabilityImpl::constPtr & lhs,
+                             const CapabilityImpl::constPtr & rhs )
+    {
+      return (   lhs->refers() == rhs->refers()
+             && lhs->kind() == rhs->kind()
+             && lhs->same(rhs) );
+    }
+
     /////////////////////////////////////////////////////////////////
   } // namespace capability
   ///////////////////////////////////////////////////////////////////
index a8efd803d74c4f3f89281618326c9f0e257e3ba7..1e2d623e30f2885ba728a27a4d98c7c3eb811af7 100644 (file)
@@ -21,7 +21,7 @@ namespace zypp
   { /////////////////////////////////////////////////////////////////
 
     IMPL_PTR_TYPE(NamedCap)
-    
+
     const CapabilityImpl::Kind & NamedCap::kind() const
     { return CapTraits<Self>::kind; }
 
@@ -36,6 +36,27 @@ namespace zypp
       return false;
     }
 
+    bool NamedCap::same( const CapabilityImpl_constPtr & rhs ) const
+    {
+      intrusive_ptr<const Self> namedrhs( asKind<Self>(rhs) );
+      if ( ! ( namedrhs && sameRefers( namedrhs ) ) )
+        return false;
+
+      if ( name() != namedrhs->name() )
+        return false;
+
+      const Edition::MatchRange & myrange( range() );
+      const Edition::MatchRange & otherrange( namedrhs->range() );
+
+      if ( myrange.op != otherrange.op )
+        return false;
+
+      if ( myrange.op == Rel::ANY ) // ANY ==> editions are irrelevant
+        return true;
+
+      return( myrange.value == otherrange.value );
+    }
+
     std::string NamedCap::encode() const
     { return _name; }
 
index f16011c405d66df90f328877b84142d3e0f8a81b..a100ebf7cd5b497c71a6fb362ef07311f8930578 100644 (file)
@@ -36,7 +36,7 @@ namespace zypp
       typedef NamedCap Self;
       typedef NamedCap_Ptr Ptr;
       typedef NamedCap_constPtr constPtr;
-      
+
       /** Ctor */
       NamedCap( const Resolvable::Kind & refers_r, const std::string & name_r )
       : CapabilityImpl( refers_r )
@@ -63,6 +63,8 @@ namespace zypp
       virtual Edition edition() const
       { return Edition::noedition; }
 
+      virtual bool same( const CapabilityImpl_constPtr & rhs ) const;
+
     protected:
       /**  Rel::ANY. */
       virtual const Edition::MatchRange & range() const;
index dac6511d9d7eda7633166ca40a5b2195940b7802..a0489432e7aaaf79b65966d97b5d46b73714efdc 100644 (file)
@@ -9,6 +9,8 @@
 /** \file zypp/capability/VersionedCap.cc
  *
 */
+#include <iostream>
+#include <ext/hash_fun.h>
 #include "zypp/capability/VersionedCap.h"
 
 using namespace std;
@@ -21,7 +23,7 @@ namespace zypp
   { /////////////////////////////////////////////////////////////////
 
     IMPL_PTR_TYPE(VersionedCap)
-    
+
     std::string VersionedCap::encode() const
     {
       std::string ret( name() );
@@ -35,6 +37,13 @@ namespace zypp
       return ret;
     }
 
+    size_t VersionedCap::hash() const
+    {
+      size_t ret = __gnu_cxx::hash<const char*>()( name().c_str() );
+      ret ^= __gnu_cxx::hash<const char*>()( _range.value.version().c_str() );
+      return ret;
+    }
+
     std::string VersionedCap::index() const
     { return name(); }
 
index 5fe67a445bae6094de9b103fad49c0503980d1a5..c93b5027251dbff67f11ad6546c7cbf8d07cd2c6 100644 (file)
@@ -22,7 +22,7 @@ namespace zypp
   { /////////////////////////////////////////////////////////////////
 
     DEFINE_PTR_TYPE(VersionedCap)
-    
+
     ///////////////////////////////////////////////////////////////////
     //
     // CLASS NAME : VersionedCap
@@ -35,7 +35,7 @@ namespace zypp
     {
       public:
       typedef VersionedCap Self;
-      
+
       /** Ctor */
       VersionedCap( const Resolvable::Kind & refers_r,
                     const std::string & name_r,
@@ -56,6 +56,8 @@ namespace zypp
       /** Edition. */
       virtual Edition edition () const;
 
+      virtual size_t hash() const;
+
     protected:
       /** Implementation dependent value. */
       virtual const Edition::MatchRange & range() const;
index 6d7aa1388e36b0a6371f977d2f859928b1703f16..95029a46ceffb19779a4906c5b9022f3f5820d9d 100644 (file)
@@ -333,7 +333,7 @@ void RepoImpl::read_capabilities( sqlite3_connection &con,
 //
 //     }
 //   }
-  sqlite3_command select_named_cmd( con, "select v.refers_kind, n.name, v.version, v.release, v.epoch, v.relation, v.dependency_type, v.resolvable_id from named_capabilities v, names n, resolvables res where v.name_id=n.id and v.resolvable_id=res.id and res.repository_id=:repo_id;");
+  sqlite3_command select_named_cmd( con, "select v.refers_kind, v.name_id, v.version, v.release, v.epoch, v.relation, v.dependency_type, v.resolvable_id from named_capabilities v, resolvables res where res.repository_id=:repo_id and v.resolvable_id=res.id;");
 
   sqlite3_command select_file_cmd( con, "select fc.refers_kind, dn.name, fn.name, fc.dependency_type, fc.resolvable_id from file_capabilities fc, files f, dir_names dn, file_names fn, resolvables res where f.id=fc.file_id and f.dir_name_id=dn.id and f.file_name_id=fn.id and fc.resolvable_id=res.id and res.repository_id=:repo_id;");
 
@@ -348,6 +348,16 @@ void RepoImpl::read_capabilities( sqlite3_connection &con,
   sqlite3_command select_other_cmd( con, "select oc.refers_kind, oc.value, oc.dependency_type, oc.resolvable_id from other_capabilities oc, resolvables res where oc.resolvable_id=res.id and res.repository_id=:repo_id;");
 
 
+  std::map<int,std::string> namemap;
+  sqlite3_command get_names_cmd( con, "select id,name from names;" );
+  {
+    sqlite3_reader reader = get_names_cmd.executereader();
+    while  ( reader.read() )
+    {
+      namemap[reader.getint(0)] = reader.getstring(1);
+    }
+  }
+
   {
     debug::Measure mnc("read named capabilities");
     select_named_cmd.bind(":repo_id", repo_id);
@@ -355,27 +365,59 @@ void RepoImpl::read_capabilities( sqlite3_connection &con,
 
     // FIXME Move this logic to tick()?
     Date start(Date::now());
+    Capability oldcap;
+    Resolvable::Kind oldrefer;
+    Rel oldrel;
+    //std::string oldname;
+    int oldname = -1;
+    std::string oldver, oldrelease;
+    int oldepoch = 0;
+
+
     while  ( reader.read() )
     {
       ticks.tick();
 
       Resolvable::Kind refer = _type_cache.kindFor(reader.getint(0));
+      int name = reader.getint(1);
       Rel rel = _type_cache.relationFor(reader.getint(5));
 
-      data::RecordId rid = reader.getint64(7);
-
       if ( rel == zypp::Rel::NONE )
       {
-        capability::NamedCap *ncap = new capability::NamedCap( refer, reader.getstring(1) );
-        zypp::Dep deptype = _type_cache.deptypeFor(reader.getint(6));
-        nvras[rid].second[deptype].insert( capfactory.fromImpl( capability::CapabilityImpl::Ptr(ncap) ) );
+        if (oldname != name || rel != oldrel || refer!=oldrefer)
+       {
+         oldrel = rel;
+         oldrefer = refer;
+         oldname = name;
+          capability::NamedCap *ncap = new capability::NamedCap( refer, namemap[name] );
+         oldcap = capfactory.fromImpl ( capability::CapabilityImpl::Ptr(ncap) );
+       }
       }
       else
       {
-        capability::VersionedCap *vcap = new capability::VersionedCap( refer, reader.getstring(1), /* rel */ rel, Edition( reader.getstring(2), reader.getstring(3), reader.getint(4) ) );
-        zypp::Dep deptype = _type_cache.deptypeFor(reader.getint(6));
-        nvras[rid].second[deptype].insert( capfactory.fromImpl( capability::CapabilityImpl::Ptr(vcap) ) );
+       std::string ver = reader.getstring(2);
+       std::string release = reader.getstring(3);
+       int epoch = reader.getint(4);
+        if (oldname != name || rel != oldrel || refer!=oldrefer
+           || oldver != ver
+           || oldrelease != release
+           || oldepoch != epoch)
+       {
+         oldrel = rel;
+         oldrefer = refer;
+         oldname = name;
+         oldver = ver;
+         oldrelease = release;
+         oldepoch = epoch;
+
+          capability::VersionedCap *vcap = new capability::VersionedCap( refer, namemap[name], /* rel */ rel, Edition( ver, release, epoch ) );
+         oldcap = capfactory.fromImpl( capability::CapabilityImpl::Ptr(vcap) );
+       }
       }
+
+      zypp::Dep deptype = _type_cache.deptypeFor(reader.getint(6));
+      data::RecordId rid = reader.getint64(7);
+      nvras[rid].second[deptype].insert(oldcap);
     }
   }