{
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();
}
};
{
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() );*/
}
};
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;
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;
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"));
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;
};
*
*/
#include <iostream>
+#include <ext/hash_fun.h>
#include "zypp/base/Logger.h"
#include "zypp/base/Regex.h"
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
}
//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
// 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;
virtual std::string index() const
{ return encode(); }
+ virtual size_t hash() const;
+ virtual bool same (const constPtr &rhs) const;
+
public:
/** Solver hack. */
struct SplitInfo
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
///////////////////////////////////////////////////////////////////
{ /////////////////////////////////////////////////////////////////
IMPL_PTR_TYPE(NamedCap)
-
+
const CapabilityImpl::Kind & NamedCap::kind() const
{ return CapTraits<Self>::kind; }
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; }
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 )
virtual Edition edition() const
{ return Edition::noedition; }
+ virtual bool same( const CapabilityImpl_constPtr & rhs ) const;
+
protected:
/** Rel::ANY. */
virtual const Edition::MatchRange & range() const;
/** \file zypp/capability/VersionedCap.cc
*
*/
+#include <iostream>
+#include <ext/hash_fun.h>
#include "zypp/capability/VersionedCap.h"
using namespace std;
{ /////////////////////////////////////////////////////////////////
IMPL_PTR_TYPE(VersionedCap)
-
+
std::string VersionedCap::encode() const
{
std::string ret( name() );
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(); }
{ /////////////////////////////////////////////////////////////////
DEFINE_PTR_TYPE(VersionedCap)
-
+
///////////////////////////////////////////////////////////////////
//
// CLASS NAME : VersionedCap
{
public:
typedef VersionedCap Self;
-
+
/** Ctor */
VersionedCap( const Resolvable::Kind & refers_r,
const std::string & name_r,
/** Edition. */
virtual Edition edition () const;
+ virtual size_t hash() const;
+
protected:
/** Implementation dependent value. */
virtual const Edition::MatchRange & range() const;
//
// }
// }
- 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;");
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);
// 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);
}
}