diff --git a/src/libtomahawk/Album.cpp b/src/libtomahawk/Album.cpp index 4b3ebcf0d..89b46eef5 100644 --- a/src/libtomahawk/Album.cpp +++ b/src/libtomahawk/Album.cpp @@ -35,19 +35,11 @@ using namespace Tomahawk; QHash< QString, album_ptr > Album::s_albumsByName = QHash< QString, album_ptr >(); QHash< unsigned int, album_ptr > Album::s_albumsById = QHash< unsigned int, album_ptr >(); +QHash< QString, album_ptr > Album::s_albumsByUniqueId = QHash< QString, album_ptr >(); -static QMutex s_nameCacheMutex; -static QMutex s_idCacheMutex; +static QMutex s_mutex; static QReadWriteLock s_idMutex; -Album::~Album() -{ - m_ownRef.clear(); - -#ifndef ENABLE_HEADLESS - delete m_cover; -#endif -} inline QString albumCacheKey( const Tomahawk::artist_ptr& artist, const QString& albumName ) @@ -56,13 +48,29 @@ albumCacheKey( const Tomahawk::artist_ptr& artist, const QString& albumName ) } +Album::~Album() +{ + QMutexLocker lock( &s_mutex ); + s_albumsByName.remove( albumCacheKey( artist(), name() ) ); + s_albumsByUniqueId.remove( uniqueId() ); +/* if ( id() > 0 ) + s_albumsById.remove( id() );*/ + + m_ownRef.clear(); + +#ifndef ENABLE_HEADLESS + delete m_cover; +#endif +} + + album_ptr Album::get( const Tomahawk::artist_ptr& artist, const QString& name, bool autoCreate ) { if ( !Database::instance() || !Database::instance()->impl() ) return album_ptr(); - QMutexLocker l( &s_nameCacheMutex ); + QMutexLocker l( &s_mutex ); const QString key = albumCacheKey( artist, name ); if ( s_albumsByName.contains( key ) ) @@ -75,6 +83,7 @@ Album::get( const Tomahawk::artist_ptr& artist, const QString& name, bool autoCr album->setWeakRef( album.toWeakRef() ); album->loadId( autoCreate ); + s_albumsByUniqueId[ album->uniqueId() ] = album; s_albumsByName[ key ] = album; return album; @@ -85,9 +94,8 @@ album_ptr Album::get( unsigned int id, const QString& name, const Tomahawk::artist_ptr& artist ) { static QHash< unsigned int, album_ptr > s_albums; - static QMutex s_mutex; - QMutexLocker lock( &s_idCacheMutex ); + QMutexLocker lock( &s_mutex ); if ( s_albumsById.contains( id ) ) { return s_albumsById.value( id ); @@ -96,6 +104,8 @@ Album::get( unsigned int id, const QString& name, const Tomahawk::artist_ptr& ar album_ptr a = album_ptr( new Album( id, name, artist ), &QObject::deleteLater ); a->setWeakRef( a.toWeakRef() ); + s_albumsByUniqueId[ a->uniqueId() ] = a; + s_albumsByName[ albumCacheKey( artist, name ) ] = a; if ( id > 0 ) s_albumsById.insert( id, a ); @@ -103,6 +113,18 @@ Album::get( unsigned int id, const QString& name, const Tomahawk::artist_ptr& ar } +album_ptr +Album::getByUniqueId( const QString& uuid ) +{ + QMutexLocker lock( &s_mutex ); + + if ( s_albumsByUniqueId.contains( uuid ) ) + return s_albumsByUniqueId.value( uuid ); + + return album_ptr(); +} + + Album::Album( unsigned int id, const QString& name, const Tomahawk::artist_ptr& artist ) : QObject() , m_waitingForId( false ) @@ -202,7 +224,7 @@ Album::cover( const QSize& size, bool forceLoad ) const trackInfo["album"] = name(); Tomahawk::InfoSystem::InfoRequestData requestData; - requestData.caller = infoid(); + requestData.caller = uniqueId(); requestData.type = Tomahawk::InfoSystem::InfoAlbumCoverArt; requestData.input = QVariant::fromValue< Tomahawk::InfoSystem::InfoStringHash >( trackInfo ); requestData.customData = QVariantMap(); @@ -250,7 +272,7 @@ Album::cover( const QSize& size, bool forceLoad ) const void Album::infoSystemInfo( const Tomahawk::InfoSystem::InfoRequestData& requestData, const QVariant& output ) { - if ( requestData.caller != infoid() || + if ( requestData.caller != uniqueId() || requestData.type != Tomahawk::InfoSystem::InfoAlbumCoverArt ) { return; @@ -278,7 +300,7 @@ Album::infoSystemInfo( const Tomahawk::InfoSystem::InfoRequestData& requestData, void Album::infoSystemFinished( const QString& target ) { - if ( target != infoid() ) + if ( target != uniqueId() ) return; disconnect( Tomahawk::InfoSystem::InfoSystem::instance(), SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ), @@ -319,7 +341,7 @@ Album::tracks( ModelMode mode, const Tomahawk::collection_ptr& collection ) QString -Album::infoid() const +Album::uniqueId() const { if ( m_uuid.isEmpty() ) m_uuid = uuid(); diff --git a/src/libtomahawk/Album.h b/src/libtomahawk/Album.h index 41ea9c5d6..8942d87fd 100644 --- a/src/libtomahawk/Album.h +++ b/src/libtomahawk/Album.h @@ -47,6 +47,7 @@ Q_OBJECT public: static album_ptr get( const Tomahawk::artist_ptr& artist, const QString& name, bool autoCreate = false ); static album_ptr get( unsigned int id, const QString& name, const Tomahawk::artist_ptr& artist ); + static album_ptr getByUniqueId( const QString& uuid ); Album( unsigned int id, const QString& name, const Tomahawk::artist_ptr& artist ); Album( const QString& name, const Tomahawk::artist_ptr& artist ); @@ -55,6 +56,7 @@ public: unsigned int id() const; QString name() const { return m_name; } QString sortname() const { return m_sortname; } + QString uniqueId() const; artist_ptr artist() const; #ifndef ENABLE_HEADLESS @@ -82,7 +84,6 @@ private slots: private: Q_DISABLE_COPY( Album ) - QString infoid() const; void setIdFuture( QFuture future ); mutable bool m_waitingForId; @@ -109,6 +110,7 @@ private: static QHash< QString, album_ptr > s_albumsByName; static QHash< unsigned int, album_ptr > s_albumsById; + static QHash< QString, album_ptr > s_albumsByUniqueId; friend class ::IdThreadWorker; }; diff --git a/src/libtomahawk/Artist.cpp b/src/libtomahawk/Artist.cpp index d3c0d5751..03deda53e 100644 --- a/src/libtomahawk/Artist.cpp +++ b/src/libtomahawk/Artist.cpp @@ -36,13 +36,19 @@ using namespace Tomahawk; QHash< QString, artist_ptr > Artist::s_artistsByName = QHash< QString, artist_ptr >(); QHash< unsigned int, artist_ptr > Artist::s_artistsById = QHash< unsigned int, artist_ptr >(); +QHash< QString, artist_ptr > Artist::s_artistsByUniqueId = QHash< QString, artist_ptr >(); -static QMutex s_nameCacheMutex; -static QMutex s_idCacheMutex; +static QMutex s_mutex; static QReadWriteLock s_idMutex; Artist::~Artist() { + QMutexLocker lock( &s_mutex ); + s_artistsByName.remove( name() ); + s_artistsByUniqueId.remove( uniqueId() ); +/* if ( id() > 0 ) + s_artistsById.remove( id() );*/ + m_ownRef.clear(); #ifndef ENABLE_HEADLESS @@ -57,7 +63,7 @@ Artist::get( const QString& name, bool autoCreate ) if ( name.isEmpty() ) return artist_ptr(); - QMutexLocker lock( &s_nameCacheMutex ); + QMutexLocker lock( &s_mutex ); if ( s_artistsByName.contains( name ) ) return s_artistsByName.value( name ); @@ -68,6 +74,7 @@ Artist::get( const QString& name, bool autoCreate ) artist->setWeakRef( artist.toWeakRef() ); artist->loadId( autoCreate ); + s_artistsByUniqueId[ artist->uniqueId() ] = artist; s_artistsByName[ name ] = artist; return artist; @@ -77,7 +84,7 @@ Artist::get( const QString& name, bool autoCreate ) artist_ptr Artist::get( unsigned int id, const QString& name ) { - QMutexLocker lock( &s_idCacheMutex ); + QMutexLocker lock( &s_mutex ); if ( s_artistsById.contains( id ) ) { return s_artistsById.value( id ); @@ -86,6 +93,8 @@ Artist::get( unsigned int id, const QString& name ) artist_ptr a = artist_ptr( new Artist( id, name ), &QObject::deleteLater ); a->setWeakRef( a.toWeakRef() ); + s_artistsByUniqueId[ a->uniqueId() ] = a; + s_artistsByName[ name ] = a; if ( id > 0 ) s_artistsById.insert( id, a ); @@ -93,6 +102,18 @@ Artist::get( unsigned int id, const QString& name ) } +artist_ptr +Artist::getByUniqueId( const QString& uuid ) +{ + QMutexLocker lock( &s_mutex ); + + if ( s_artistsByUniqueId.contains( uuid ) ) + return s_artistsByUniqueId.value( uuid ); + + return artist_ptr(); +} + + Artist::Artist( unsigned int id, const QString& name ) : QObject() , m_waitingForFuture( false ) @@ -163,7 +184,7 @@ Artist::albums( ModelMode mode, const Tomahawk::collection_ptr& collection ) con artistInfo["artist"] = name(); Tomahawk::InfoSystem::InfoRequestData requestData; - requestData.caller = infoid(); + requestData.caller = uniqueId(); requestData.input = QVariant::fromValue< Tomahawk::InfoSystem::InfoStringHash >( artistInfo ); requestData.type = Tomahawk::InfoSystem::InfoArtistReleases; @@ -203,7 +224,7 @@ Artist::similarArtists() const artistInfo["artist"] = name(); Tomahawk::InfoSystem::InfoRequestData requestData; - requestData.caller = infoid(); + requestData.caller = uniqueId(); requestData.customData = QVariantMap(); requestData.input = QVariant::fromValue< Tomahawk::InfoSystem::InfoStringHash >( artistInfo ); @@ -273,7 +294,7 @@ Artist::biography() const if ( !m_biographyLoaded ) { Tomahawk::InfoSystem::InfoRequestData requestData; - requestData.caller = infoid(); + requestData.caller = uniqueId(); requestData.customData = QVariantMap(); requestData.input = name(); @@ -361,7 +382,7 @@ Artist::onAlbumsFound( const QList< album_ptr >& albums, const QVariant& data ) void Artist::infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output ) { - if ( requestData.caller != infoid() ) + if ( requestData.caller != uniqueId() ) return; QVariantMap returnedData = output.value< QVariantMap >(); @@ -450,7 +471,7 @@ Artist::infoSystemFinished( QString target ) { Q_UNUSED( target ); - if ( target != infoid() ) + if ( target != uniqueId() ) return; if ( --m_infoJobs == 0 ) @@ -481,7 +502,7 @@ Artist::cover( const QSize& size, bool forceLoad ) const trackInfo["artist"] = name(); Tomahawk::InfoSystem::InfoRequestData requestData; - requestData.caller = infoid(); + requestData.caller = uniqueId(); requestData.type = Tomahawk::InfoSystem::InfoArtistImages; requestData.input = QVariant::fromValue< Tomahawk::InfoSystem::InfoStringHash >( trackInfo ); requestData.customData = QVariantMap(); @@ -554,7 +575,7 @@ Artist::tracks( ModelMode mode, const Tomahawk::collection_ptr& collection ) QString -Artist::infoid() const +Artist::uniqueId() const { if ( m_uuid.isEmpty() ) m_uuid = uuid(); diff --git a/src/libtomahawk/Artist.h b/src/libtomahawk/Artist.h index af0dba4c0..e71f1e326 100644 --- a/src/libtomahawk/Artist.h +++ b/src/libtomahawk/Artist.h @@ -46,6 +46,7 @@ Q_OBJECT public: static artist_ptr get( const QString& name, bool autoCreate = false ); static artist_ptr get( unsigned int id, const QString& name ); + static artist_ptr getByUniqueId( const QString& uuid ); Artist( unsigned int id, const QString& name ); explicit Artist( const QString& name ); @@ -54,6 +55,7 @@ public: unsigned int id() const; QString name() const { return m_name; } QString sortname() const { return m_sortname; } + QString uniqueId() const; QList albums( ModelMode mode = Mixed, const Tomahawk::collection_ptr& collection = Tomahawk::collection_ptr() ) const; QList similarArtists() const; @@ -65,7 +67,7 @@ public: QList< Tomahawk::PlaybackLog > playbackHistory( const Tomahawk::source_ptr& source = Tomahawk::source_ptr() ) const; void setPlaybackHistory( const QList< Tomahawk::PlaybackLog >& playbackData ); unsigned int playbackCount( const Tomahawk::source_ptr& source = Tomahawk::source_ptr() ); - + QString biography() const; #ifndef ENABLE_HEADLESS @@ -98,7 +100,6 @@ private slots: private: Artist(); - QString infoid() const; void setIdFuture( QFuture idFuture ); @@ -133,11 +134,12 @@ private: #endif QHash< Tomahawk::ModelMode, QHash< Tomahawk::collection_ptr, Tomahawk::playlistinterface_ptr > > m_playlistInterface; - + QWeakPointer< Tomahawk::Artist > m_ownRef; static QHash< QString, artist_ptr > s_artistsByName; static QHash< unsigned int, artist_ptr > s_artistsById; + static QHash< QString, artist_ptr > s_artistsByUniqueId; friend class ::IdThreadWorker; }; diff --git a/src/libtomahawk/Query.cpp b/src/libtomahawk/Query.cpp index 24b219d7d..9457b2f81 100644 --- a/src/libtomahawk/Query.cpp +++ b/src/libtomahawk/Query.cpp @@ -39,6 +39,9 @@ using namespace Tomahawk; +QHash< QString, query_ptr > Query::s_queriesByUniqueId = QHash< QString, query_ptr >(); +static QMutex s_mutex; + SocialAction::SocialAction() {} SocialAction::~SocialAction() {} @@ -82,7 +85,7 @@ PlaybackLog::PlaybackLog( const PlaybackLog& other ) query_ptr Query::get( const QString& artist, const QString& track, const QString& album, const QID& qid, bool autoResolve ) { - if ( artist.trimmed().isEmpty() || track.trimmed().isEmpty() ) + if ( artist.trimmed().isEmpty() || track.trimmed().isEmpty() ) return query_ptr(); if ( qid.isEmpty() ) @@ -94,6 +97,9 @@ Query::get( const QString& artist, const QString& track, const QString& album, c if ( autoResolve ) Pipeline::instance()->resolve( q ); + QMutexLocker lock( &s_mutex ); + s_queriesByUniqueId[ qid ] = q; + return q; } @@ -109,10 +115,25 @@ Query::get( const QString& query, const QID& qid ) if ( !qid.isEmpty() ) Pipeline::instance()->resolve( q ); + QMutexLocker lock( &s_mutex ); + s_queriesByUniqueId[ qid ] = q; + return q; } +query_ptr +Query::getByUniqueId( const QString& qid ) +{ + QMutexLocker lock( &s_mutex ); + + if ( s_queriesByUniqueId.contains( qid ) ) + return s_queriesByUniqueId.value( qid ); + + return query_ptr(); +} + + Query::Query( const QString& artist, const QString& track, const QString& album, const QID& qid, bool autoResolve ) : m_qid( qid ) , m_artist( artist ) @@ -150,6 +171,10 @@ Query::Query( const QString& query, const QID& qid ) Query::~Query() { QMutexLocker lock( &m_mutex ); + QMutexLocker slock( &s_mutex ); + + s_queriesByUniqueId.remove( id() ); + m_ownRef.clear(); m_results.clear(); } @@ -502,7 +527,7 @@ Query::howSimilar( const Tomahawk::result_ptr& r ) Q_ASSERT( !r->album().isNull() ); if ( r->artist().isNull() || r->album().isNull() ) return 0.0; - + // result values const QString rArtistname = r->artist()->sortname(); const QString rAlbumname = r->album()->sortname(); diff --git a/src/libtomahawk/Query.h b/src/libtomahawk/Query.h index 62ee4e6ac..8c22a2bad 100644 --- a/src/libtomahawk/Query.h +++ b/src/libtomahawk/Query.h @@ -85,6 +85,7 @@ public: static query_ptr get( const QString& artist, const QString& track, const QString& album, const QID& qid = QString(), bool autoResolve = true ); static query_ptr get( const QString& query, const QID& qid ); + static query_ptr getByUniqueId( const QString& qid ); virtual ~Query(); @@ -271,6 +272,8 @@ private: QStringList m_lyrics; mutable int m_infoJobs; + + static QHash< QString, query_ptr > s_queriesByUniqueId; }; }; //ns