From dc5c0394f77ea3cd64a175ca970aa02b3e5cbb91 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Tue, 19 Jul 2011 22:53:35 +0200 Subject: [PATCH] * Release unused queries in Pipeline. --- src/libtomahawk/pipeline.cpp | 46 +++++++++++++++++++++++++----------- src/libtomahawk/pipeline.h | 13 +++++++--- src/libtomahawk/query.cpp | 16 +++++++++---- src/libtomahawk/query.h | 6 +++-- src/web/api_v1.cpp | 14 +++++++---- 5 files changed, 66 insertions(+), 29 deletions(-) diff --git a/src/libtomahawk/pipeline.cpp b/src/libtomahawk/pipeline.cpp index b11a54e08..fc8402557 100644 --- a/src/libtomahawk/pipeline.cpp +++ b/src/libtomahawk/pipeline.cpp @@ -27,6 +27,7 @@ #define DEFAULT_CONCURRENT_QUERIES 4 #define MAX_CONCURRENT_QUERIES 16 +#define CLEANUP_TIMEOUT 5 * 60 * 1000 using namespace Tomahawk; @@ -48,6 +49,9 @@ Pipeline::Pipeline( QObject* parent ) m_maxConcurrentQueries = qBound( DEFAULT_CONCURRENT_QUERIES, QThread::idealThreadCount(), MAX_CONCURRENT_QUERIES ); qDebug() << Q_FUNC_INFO << "Using" << m_maxConcurrentQueries << "threads"; + + m_temporaryQueryTimer.setInterval( CLEANUP_TIMEOUT ); + connect( &m_temporaryQueryTimer, SIGNAL( timeout() ), SLOT( onTemporaryQueryTimer() ) ); } @@ -104,7 +108,7 @@ Pipeline::addResolver( Resolver* r ) void -Pipeline::resolve( const QList& qlist, bool prioritized ) +Pipeline::resolve( const QList& qlist, bool prioritized, bool temporaryQuery ) { { QMutexLocker lock( &m_mut ); @@ -112,25 +116,24 @@ Pipeline::resolve( const QList& qlist, bool prioritized ) int i = 0; foreach( const query_ptr& q, qlist ) { -// qDebug() << Q_FUNC_INFO << (qlonglong)q.data() << q->toString(); if ( !m_qids.contains( q->id() ) ) - { m_qids.insert( q->id(), q ); - } if ( m_queries_pending.contains( q ) ) - { -// qDebug() << "Already queued for resolving:" << q->toString(); continue; - } if ( prioritized ) - { m_queries_pending.insert( i++, q ); - } else + m_queries_pending << q; + + if ( temporaryQuery ) { - m_queries_pending.append( q ); + m_queries_temporary << q; + + if ( m_temporaryQueryTimer.isActive() ) + m_temporaryQueryTimer.stop(); + m_temporaryQueryTimer.start(); } } } @@ -140,21 +143,21 @@ Pipeline::resolve( const QList& qlist, bool prioritized ) void -Pipeline::resolve( const query_ptr& q, bool prioritized ) +Pipeline::resolve( const query_ptr& q, bool prioritized, bool temporaryQuery ) { if ( q.isNull() ) return; QList< query_ptr > qlist; qlist << q; - resolve( qlist, prioritized ); + resolve( qlist, prioritized, temporaryQuery ); } void -Pipeline::resolve( QID qid, bool prioritized ) +Pipeline::resolve( QID qid, bool prioritized, bool temporaryQuery ) { - resolve( query( qid ), prioritized ); + resolve( query( qid ), prioritized, temporaryQuery ); } @@ -387,3 +390,18 @@ Pipeline::decQIDState( const Tomahawk::query_ptr& query ) return state; } + + +void +Pipeline::onTemporaryQueryTimer() +{ + QMutexLocker lock( &m_mut ); + qDebug() << Q_FUNC_INFO; + + for ( int i = m_queries_temporary.count() - 1; i >= 0; i-- ) + { + query_ptr q = m_queries_temporary.takeAt( i ); + m_qids.remove( q->id() ); + qDebug() << "Cleaning up:" << q->toString(); + } +} \ No newline at end of file diff --git a/src/libtomahawk/pipeline.h b/src/libtomahawk/pipeline.h index e29fb6144..599817572 100644 --- a/src/libtomahawk/pipeline.h +++ b/src/libtomahawk/pipeline.h @@ -23,6 +23,7 @@ #include #include #include +#include #include "typedefs.h" #include "query.h" @@ -65,9 +66,9 @@ public: } public slots: - void resolve( const query_ptr& q, bool prioritized = false ); - void resolve( const QList& qlist, bool prioritized = false ); - void resolve( QID qid, bool prioritized = false ); + void resolve( const query_ptr& q, bool prioritized = false, bool temporaryQuery = false ); + void resolve( const QList& qlist, bool prioritized = false, bool temporaryQuery = false ); + void resolve( QID qid, bool prioritized = false, bool temporaryQuery = false ); void start(); void stop(); @@ -85,6 +86,8 @@ private slots: void shunt( const query_ptr& q ); void shuntNext(); + void onTemporaryQueryTimer(); + private: Tomahawk::Resolver* nextResolver( const Tomahawk::query_ptr& query ) const; @@ -103,8 +106,12 @@ private: // store queries here until DB index is loaded, then shunt them all QList< query_ptr > m_queries_pending; + // store temporary queries here and clean up after timeout threshold + QList< query_ptr > m_queries_temporary; + int m_maxConcurrentQueries; bool m_running; + QTimer m_temporaryQueryTimer; static Pipeline* s_instance; }; diff --git a/src/libtomahawk/query.cpp b/src/libtomahawk/query.cpp index 9281d86e0..b4622c36b 100644 --- a/src/libtomahawk/query.cpp +++ b/src/libtomahawk/query.cpp @@ -33,11 +33,11 @@ using namespace Tomahawk; query_ptr -Query::get( const QString& artist, const QString& track, const QString& album, const QID& qid ) +Query::get( const QString& artist, const QString& track, const QString& album, const QID& qid, bool autoResolve ) { - query_ptr q = query_ptr( new Query( artist, track, album, qid ) ); + query_ptr q = query_ptr( new Query( artist, track, album, qid, autoResolve ) ); - if ( !qid.isEmpty() ) + if ( autoResolve && !qid.isEmpty() ) Pipeline::instance()->resolve( q ); return q; } @@ -54,7 +54,7 @@ Query::get( const QString& query, const QID& qid ) } -Query::Query( const QString& artist, const QString& track, const QString& album, const QID& qid ) +Query::Query( const QString& artist, const QString& track, const QString& album, const QID& qid, bool autoResolve ) : m_solved( false ) , m_playable( false ) , m_resolveFinished( false ) @@ -64,7 +64,7 @@ Query::Query( const QString& artist, const QString& track, const QString& album, , m_track( track ) , m_duration( -1 ) { - if ( !qid.isEmpty() ) + if ( autoResolve ) { connect( Database::instance(), SIGNAL( indexReady() ), SLOT( refreshResults() ), Qt::QueuedConnection ); } @@ -91,6 +91,12 @@ Query::Query( const QString& query, const QID& qid ) } +Query::~Query() +{ + qDebug() << Q_FUNC_INFO << toString(); +} + + void Query::addResults( const QList< Tomahawk::result_ptr >& newresults ) { diff --git a/src/libtomahawk/query.h b/src/libtomahawk/query.h index b0c1b7422..394773fc1 100644 --- a/src/libtomahawk/query.h +++ b/src/libtomahawk/query.h @@ -48,12 +48,14 @@ friend class ::DatabaseCommand_LoadPlaylistEntries; friend class Pipeline; public: - static query_ptr get( const QString& artist, const QString& track, const QString& album, const QID& qid = QString() ); + 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 ); - explicit Query( const QString& artist, const QString& track, const QString& album, const QID& qid ); + explicit Query( const QString& artist, const QString& track, const QString& album, const QID& qid, bool autoResolve ); explicit Query( const QString& query, const QID& qid ); + virtual ~Query(); + /// returns list of all results so far QList< result_ptr > results() const; diff --git a/src/web/api_v1.cpp b/src/web/api_v1.cpp index 5ae2ae149..d363796be 100644 --- a/src/web/api_v1.cpp +++ b/src/web/api_v1.cpp @@ -20,6 +20,8 @@ #include +using namespace Tomahawk; + void Api_v1::auth_1( QxtWebRequestEvent* event, QString arg ) { @@ -67,7 +69,9 @@ Api_v1::auth_2( QxtWebRequestEvent* event, QString arg ) params = params.mid( params.indexOf( '?' ) ); QStringList pieces = params.split( '&' ); QHash< QString, QString > queryItems; - foreach( const QString& part, pieces ) { + + foreach ( const QString& part, pieces ) + { QStringList keyval = part.split( '=' ); if( keyval.size() == 2 ) queryItems.insert( keyval.first(), keyval.last() ); @@ -149,7 +153,7 @@ void Api_v1::sid( QxtWebRequestEvent* event, QString unused ) { Q_UNUSED( unused ); - using namespace Tomahawk; + RID rid = event->url.path().mid( 5 ); qDebug() << "Request for sid " << rid; @@ -240,7 +244,8 @@ Api_v1::resolve( QxtWebRequestEvent* event ) else qid = uuid(); - Tomahawk::query_ptr qry = Tomahawk::Query::get( event->url.queryItemValue( "artist" ), event->url.queryItemValue( "track" ), event->url.queryItemValue( "album" ), qid ); + query_ptr qry = Query::get( event->url.queryItemValue( "artist" ), event->url.queryItemValue( "track" ), event->url.queryItemValue( "album" ), qid, false ); + Pipeline::instance()->resolve( qry, true, true ); QVariantMap r; r.insert( "qid", qid ); @@ -273,7 +278,6 @@ Api_v1::get_results( QxtWebRequestEvent* event ) send404(event); } - using namespace Tomahawk; query_ptr qry = Pipeline::instance()->query( event->url.queryItemValue( "qid" ) ); if( qry.isNull() ) { @@ -290,7 +294,7 @@ Api_v1::get_results( QxtWebRequestEvent* event ) r.insert( "query", qry->toVariant() ); QVariantList res; - foreach( Tomahawk::result_ptr rp, qry->results() ) + foreach( const result_ptr& rp, qry->results() ) { res << rp->toVariant(); }