[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: KDE/kdepim/kleopatra/models
From: Marc Mutz <mutz () kde ! org>
Date: 2008-02-06 16:22:28
Message-ID: 1202314948.658466.1704.nullmailer () svn ! kde ! org
[Download RAW message or body]
SVN commit 771645 by mutz:
Maintain issuer/subject relations in the KeyCache. Featuring KDE's first \
template-template-template argument... I'm scared myself :)
M +147 -2 keycache.cpp
M +14 -0 keycache.h
--- trunk/KDE/kdepim/kleopatra/models/keycache.cpp #771644:771645
@@ -153,9 +153,17 @@
return find<_detail::ByShortKeyID>( by.shortkeyid, shortkeyid );
}
+ std::pair<
+ std::vector<Key>::const_iterator,
+ std::vector<Key>::const_iterator
+ > find_subjects( const char * chain_id ) const {
+ return std::equal_range( by.chainid.begin(), by.chainid.end(),
+ chain_id, _detail::ByChainID<std::less>() );
+ }
+
private:
struct By {
- std::vector<Key> fpr, keyid, shortkeyid;
+ std::vector<Key> fpr, keyid, shortkeyid, chainid;
std::vector< std::pair<std::string,Key> > email;
} by;
};
@@ -286,6 +294,98 @@
return findByKeyIDOrFingerprint( fprs );
}
+std::vector<Key> KeyCache::findSubjects( const GpgME::Key & key, Option options ) \
const { + return findSubjects( std::vector<Key>( 1, key ), options );
+}
+
+std::vector<Key> KeyCache::findSubjects( const std::vector<Key> & keys, Option \
options ) const { + return findSubjects( keys.begin(), keys.end(), options );
+}
+
+std::vector<Key> KeyCache::findSubjects( std::vector<Key>::const_iterator first, \
std::vector<Key>::const_iterator last, Option options ) const { +
+ if ( first == last )
+ return std::vector<Key>();
+
+ std::vector<Key> result;
+ while ( first != last ) {
+ const std::pair<
+ std::vector<Key>::const_iterator,
+ std::vector<Key>::const_iterator
+ > pair = d->find_subjects( first->primaryFingerprint() );
+ result.insert( result.end(), pair.first, pair.second );
+ ++first;
+ }
+
+ std::sort( result.begin(), result.end(), _detail::ByFingerprint<std::less>() );
+ result.erase( std::unique( result.begin(), result.end(), \
_detail::ByFingerprint<std::equal_to>() ), result.end() ); +
+ if ( options & RecursiveSearch )
+ return findSubjects( result, options );
+ else
+ return result;
+}
+
+static const unsigned int LIKELY_CHAIN_DEPTH = 3;
+
+std::vector<Key> KeyCache::findIssuers( const Key & key, Option options ) const {
+
+ const Key & issuer = findByFingerprint( key.chainID() );
+
+ if ( issuer.isNull() )
+ return std::vector<Key>();
+
+ std::vector<Key> result( 1, issuer );
+ if ( !( options & RecursiveSearch ) )
+ return result;
+
+ do {
+ result.push_back( findByFingerprint( result.back().chainID() ) );
+ } while ( !result.back().isNull() );
+ result.pop_back();
+
+ return result;
+}
+
+std::vector<Key> KeyCache::findIssuers( const std::vector<Key> & keys, Option \
options ) const { + return findIssuers( keys.begin(), keys.end(), options );
+}
+
+std::vector<Key> KeyCache::findIssuers( std::vector<Key>::const_iterator first, \
std::vector<Key>::const_iterator last, Option options ) const { +
+ if ( first == last )
+ return std::vector<Key>();
+
+ // extract chain-ids, identifying issuers:
+ std::vector<const char *> chainIDs;
+ chainIDs.reserve( last - first );
+ std::transform( first, last,
+ std::back_inserter( chainIDs ),
+ bind( &Key::chainID, _1 ) );
+ std::sort( chainIDs.begin(), chainIDs.end(), _detail::ByFingerprint<std::less>() \
); +
+ const std::vector<const char*>::iterator lastUniqueChainID = std::unique( \
chainIDs.begin(), chainIDs.end(), _detail::ByFingerprint<std::less>() ); +
+ std::vector<Key> result;
+ result.reserve( lastUniqueChainID - chainIDs.begin() );
+
+ kdtools::set_intersection( d->by.fpr.begin(), d->by.fpr.end(),
+ chainIDs.begin(), lastUniqueChainID,
+ std::back_inserter( result ),
+ _detail::ByFingerprint<std::less>() );
+
+ if ( !( options & RecursiveSearch ) )
+ return result;
+
+ const std::vector<Key> l2result = findIssuers( result, options );
+
+ const unsigned long result_size = result.size();
+ result.insert( result.end(), l2result.begin(), l2result.end() );
+ std::inplace_merge( result.begin(), result.begin() + result_size, result.end(),
+ _detail::ByFingerprint<std::less>() );
+ return result;
+}
+
static std::string email( const UserID & uid ) {
const std::string email = uid.email();
if ( email.empty() )
@@ -331,7 +431,7 @@
= std::remove_if( begin( range ), end( range ), bind( \
_detail::ByFingerprint<std::equal_to>(), fpr, _1 ) ); d->by.keyid.erase( it, end( \
range ) ); }
-
+
if ( const char * shortkeyid = key.shortKeyID() ) {
const std::pair<std::vector<Key>::iterator,std::vector<Key>::iterator> range
= std::equal_range( d->by.shortkeyid.begin(), d->by.shortkeyid.end(), \
shortkeyid, @@ -341,6 +441,16 @@
d->by.shortkeyid.erase( it, end( range ) );
}
+ if ( const char * chainid = key.chainID() ) {
+ const std::pair<std::vector<Key>::iterator,std::vector<Key>::iterator> range
+ = std::equal_range( d->by.chainid.begin(), d->by.chainid.end(), chainid,
+ _detail::ByChainID<std::less>() );
+ const std::pair< std::vector<Key>::iterator, std::vector<Key>::iterator > \
range2 + = std::equal_range( begin( range ), end( range ), fpr, \
_detail::ByFingerprint<std::less>() ); + d->by.chainid.erase( begin( range2 ), \
end( range2 ) ); + }
+
+
Q_FOREACH( const std::string & email, emails( key ) ) {
const std::pair<std::vector<std::pair<std::string,Key> \
>::iterator,std::vector<std::pair<std::string,Key> >::iterator> range
= std::equal_range( d->by.email.begin(), d->by.email.end(), email, \
ByEMail<std::less>() ); @@ -350,6 +460,11 @@
}
}
+void KeyCache::remove( const std::vector<Key> & keys ) {
+ Q_FOREACH( const Key & key, keys )
+ remove( key );
+}
+
std::vector<GpgME::Key> KeyCache::keys() const
{
return d->by.fpr;
@@ -365,6 +480,26 @@
insert( std::vector<Key>( 1, key ) );
}
+namespace {
+
+ template <
+ template <template <typename T> class Op> class T1,
+ template <template <typename T> class Op> class T2
+ > struct lexicographically {
+ typedef bool result_type;
+
+ template <typename U, typename V>
+ bool operator()( const U & lhs, const V & rhs ) const {
+ return
+ T1<std::less>()( lhs, rhs ) ||
+ T1<std::equal_to>()( lhs, rhs ) &&
+ T2<std::less>()( lhs, rhs )
+ ;
+ }
+ };
+
+}
+
void KeyCache::insert( const std::vector<Key> & keys ) {
// 1. remove those with empty fingerprints:
@@ -413,6 +548,16 @@
std::back_inserter( by_email ),
ByEMail<std::less>() );
+ // 3.5: stable-sort by chain-id (effectively \
lexicographically<ByChainID,ByFingerprint>) + std::stable_sort( sorted.begin(), \
sorted.end(), _detail::ByChainID<std::less>() ); +
+ // 3.5a: insert into chain-id index:
+ std::vector<Key> by_chainid;
+ by_chainid.reserve( sorted.size() + d->by.chainid.size() );
+ std::merge( sorted.begin(), sorted.end(),
+ d->by.chainid.begin(), d->by.chainid.end(),
+ std::back_inserter( by_chainid ),
+ lexicographically<_detail::ByChainID,_detail::ByFingerprint>() );
// 4. sort by key id:
std::sort( sorted.begin(), sorted.end(), _detail::ByKeyID<std::less>() );
--- trunk/KDE/kdepim/kleopatra/models/keycache.h #771644:771645
@@ -63,6 +63,7 @@
void refresh( const std::vector<GpgME::Key> & keys );
void remove( const GpgME::Key & key );
+ void remove( const std::vector<GpgME::Key> & keys );
std::vector<GpgME::Key> keys() const;
@@ -89,6 +90,19 @@
std::vector<GpgME::Key> findRecipients( const GpgME::DecryptionResult & \
result ) const;
std::vector<GpgME::Key> findSigners( const GpgME::VerificationResult & \
result ) const;
+ enum Option {
+ NoOption = 0,
+ RecursiveSearch = 1,
+ };
+
+ std::vector<GpgME::Key> findSubjects( const GpgME::Key & key, Option \
option=RecursiveSearch ) const; + std::vector<GpgME::Key> findSubjects( const \
std::vector<GpgME::Key> & keys, Option options=RecursiveSearch ) const; + \
std::vector<GpgME::Key> findSubjects( std::vector<GpgME::Key>::const_iterator first, \
std::vector<GpgME::Key>::const_iterator last, Option options=RecursiveSearch ) const; \
+ + std::vector<GpgME::Key> findIssuers( const GpgME::Key & key, Option \
options=RecursiveSearch ) const; + std::vector<GpgME::Key> findIssuers( const \
std::vector<GpgME::Key> & keys, Option options=RecursiveSearch ) const; + \
std::vector<GpgME::Key> findIssuers( std::vector<GpgME::Key>::const_iterator first, \
std::vector<GpgME::Key>::const_iterator last, Option options=RecursiveSearch ) const; \
+ public Q_SLOTS:
void clear();
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic