diff --git a/src/library/coverartcache.cpp b/src/library/coverartcache.cpp index b15c8d0450b..252a23226da 100644 --- a/src/library/coverartcache.cpp +++ b/src/library/coverartcache.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include "coverartcache.h" #include "soundsourceproxy.h" @@ -11,7 +12,10 @@ CoverArtCache::CoverArtCache() : m_pCoverArtDAO(NULL), m_pTrackDAO(NULL), m_sDefaultCoverLocation(":/images/library/default_cover.png"), - m_defaultCover(m_sDefaultCoverLocation) { + m_defaultCover(m_sDefaultCoverLocation), + m_timer(new QTimer(this)) { + m_timer->setSingleShot(true); + connect(m_timer, SIGNAL(timeout()), SLOT(updateDB())); } CoverArtCache::~CoverArtCache() { @@ -70,6 +74,12 @@ QPixmap CoverArtCache::requestPixmap(int trackId, return QPixmap(); } + // check if we have already found a cover for this track + // and if it is just waiting to be inserted/updated in the DB. + if (m_queueOfUpdates.contains(trackId)) { + return QPixmap(); + } + // If this request comes from CoverDelegate (table view), // it'll want to get a cropped cover which is ready to be drawn // in the table view (cover art column). @@ -302,15 +312,33 @@ void CoverArtCache::imageFound() { } // update DB - if (res.newImgFound) { - int coverId = m_pCoverArtDAO->saveCoverArt(res.coverLocation, - res.md5Hash); - m_pTrackDAO->updateCoverArt(res.trackId, coverId); + if (res.newImgFound && !m_queueOfUpdates.contains(res.trackId)) { + m_queueOfUpdates.insert(res.trackId, + qMakePair(res.coverLocation, res.md5Hash)); + } + + if (m_queueOfUpdates.size() == 1 && !m_timer->isActive()) { + m_timer->start(500); // after 0.5s, it will call `updateDB()` } m_runningIds.remove(res.trackId); } +// sqlite can only do about 50 writes per second, +// so it is important to collect all new covers and write them at once. +void CoverArtCache::updateDB() { + if (m_queueOfUpdates.isEmpty()) { + return; + } + + QList coverIds = m_pCoverArtDAO->saveCoverArt(m_queueOfUpdates.values()); + + Q_ASSERT(m_queueOfUpdates.keys().size() == coverIds.size()); + m_pTrackDAO->updateCoverArt(m_queueOfUpdates.keys(), coverIds); + + m_queueOfUpdates.clear(); +} + // It will return a cropped cover that is ready to be // used by the tableview-cover_column (CoverDelegate). // As QImage is optimized to manipulate images, we will do it here diff --git a/src/library/coverartcache.h b/src/library/coverartcache.h index 612b6034718..479b1fcdf5e 100644 --- a/src/library/coverartcache.h +++ b/src/library/coverartcache.h @@ -30,6 +30,9 @@ class CoverArtCache : public QObject, public Singleton void imageFound(); void imageLoaded(); + private slots: + void updateDB(); + signals: void pixmapFound(int trackId, QPixmap pixmap); @@ -63,7 +66,9 @@ class CoverArtCache : public QObject, public Singleton TrackDAO* m_pTrackDAO; const QString m_sDefaultCoverLocation; const QPixmap m_defaultCover; + QTimer* m_timer; QSet m_runningIds; + QHash > m_queueOfUpdates; QString calculateMD5(QImage img); QImage cropImage(QImage img);