]> cloud.milkyroute.net Git - dolphin.git/commitdiff
KFileItemModelRolesUpdater: Optimize updates
authorPeter Penz <peter.penz19@gmail.com>
Wed, 1 Feb 2012 19:40:57 +0000 (20:40 +0100)
committerPeter Penz <peter.penz19@gmail.com>
Wed, 1 Feb 2012 19:46:23 +0000 (20:46 +0100)
The asynchronous resolving to bypass performance bottlenecks is not necessary
anymore as multiple ranges can be inserted in one step now. This solves the issue
that e.g. opening a tree resulted in temporary unknown icons for a short period
of time.

src/kitemviews/kfileitemlistview.cpp
src/kitemviews/kfileitemmodelrolesupdater.cpp
src/kitemviews/kfileitemmodelrolesupdater.h

index 86db28d3d1b26d2d0864d888e8e5bbf4b90bdd65..4762e8089f81e00e764365a09e9c986f55773b65 100644 (file)
@@ -376,8 +376,6 @@ void KFileItemListView::onScrollOffsetChanged(qreal current, qreal previous)
 
 void KFileItemListView::onVisibleRolesChanged(const QList<QByteArray>& current, const QList<QByteArray>& previous)
 {
 
 void KFileItemListView::onVisibleRolesChanged(const QList<QByteArray>& current, const QList<QByteArray>& previous)
 {
-    Q_UNUSED(current);
-    Q_UNUSED(previous);
     applyRolesToModel();
 
     if (m_itemLayout == DetailsLayout) {
     applyRolesToModel();
 
     if (m_itemLayout == DetailsLayout) {
index a974094d5844c23b135f9ae816e54bab56b9a33b..0c204e4745c0b1301c7c62987e1eebbbfcf67837 100644 (file)
@@ -72,7 +72,6 @@ KFileItemModelRolesUpdater::KFileItemModelRolesUpdater(KFileItemModel* model, QO
     m_pendingVisibleItems(),
     m_pendingInvisibleItems(),
     m_previewJobs(),
     m_pendingVisibleItems(),
     m_pendingInvisibleItems(),
     m_previewJobs(),
-    m_resolvePendingRolesTimer(0),
     m_changedItemsTimer(0),
     m_changedItems()
 {
     m_changedItemsTimer(0),
     m_changedItems()
 {
@@ -91,13 +90,6 @@ KFileItemModelRolesUpdater::KFileItemModelRolesUpdater(KFileItemModel* model, QO
     connect(m_model, SIGNAL(itemsChanged(KItemRangeList,QSet<QByteArray>)),
             this,    SLOT(slotItemsChanged(KItemRangeList,QSet<QByteArray>)));
 
     connect(m_model, SIGNAL(itemsChanged(KItemRangeList,QSet<QByteArray>)),
             this,    SLOT(slotItemsChanged(KItemRangeList,QSet<QByteArray>)));
 
-    // A timer with a minimal timeout is used to merge several triggerPendingRolesResolving() calls
-    // to only one call of resolvePendingRoles().
-    m_resolvePendingRolesTimer = new QTimer(this);
-    m_resolvePendingRolesTimer->setInterval(1);
-    m_resolvePendingRolesTimer->setSingleShot(true);
-    connect(m_resolvePendingRolesTimer, SIGNAL(timeout()), this, SLOT(resolvePendingRoles()));
-
     // Use a timer to prevent that each call of slotItemsChanged() results in a synchronous
     // resolving of the roles. Postpone the resolving until no update has been done for 2 seconds.
     m_changedItemsTimer = new QTimer(this);
     // Use a timer to prevent that each call of slotItemsChanged() results in a synchronous
     // resolving of the roles. Postpone the resolving until no update has been done for 2 seconds.
     m_changedItemsTimer = new QTimer(this);
@@ -379,84 +371,6 @@ void KFileItemModelRolesUpdater::slotPreviewJobFinished(KJob* job)
     startPreviewJob(visibleItems + m_pendingInvisibleItems.toList());
 }
 
     startPreviewJob(visibleItems + m_pendingInvisibleItems.toList());
 }
 
-void KFileItemModelRolesUpdater::resolvePendingRoles()
-{
-    int resolvedCount = 0;
-
-    const bool hasSlowRoles = m_previewShown
-                              || m_roles.contains("size")
-                              || m_roles.contains("type")
-                              || m_roles.contains("isExpandable");
-    const ResolveHint resolveHint = hasSlowRoles ? ResolveFast : ResolveAll;
-
-    // Resolving the MIME type can be expensive. Assure that not more than MaxBlockTimeout ms are
-    // spend for resolving them synchronously. Usually this is more than enough to determine
-    // all visible items, but there are corner cases where this limit gets easily exceeded.
-    QElapsedTimer timer;
-    timer.start();
-
-    // Resolve the MIME type of all visible items
-    QSetIterator<KFileItem> visibleIt(m_pendingVisibleItems);
-    while (visibleIt.hasNext()) {
-        const KFileItem item = visibleIt.next();
-        applyResolvedRoles(item, resolveHint);
-        if (!hasSlowRoles) {
-            Q_ASSERT(!m_pendingInvisibleItems.contains(item));
-            // All roles have been resolved already by applyResolvedRoles()
-            m_pendingVisibleItems.remove(item);
-        }
-        ++resolvedCount;
-
-        if (timer.elapsed() > MaxBlockTimeout) {
-            break;
-        }
-    }
-
-    // Resolve the MIME type of the invisible items at least until the timeout
-    // has been exceeded or the maximum number of items has been reached
-    KFileItemList invisibleItems;
-    if (m_lastVisibleIndex >= 0) {
-        // The visible range is valid, don't care about the order how the MIME
-        // type of invisible items get resolved
-        invisibleItems = m_pendingInvisibleItems.toList();
-    } else {
-        // The visible range is temporary invalid (e.g. happens when loading
-        // a directory) so take care to sort the currently invisible items where
-        // a part will get visible later
-        invisibleItems = sortedItems(m_pendingInvisibleItems);
-    }
-
-    int index = 0;
-    while (resolvedCount < MaxResolveItemsCount && index < invisibleItems.count() && timer.elapsed() <= MaxBlockTimeout) {
-        const KFileItem item = invisibleItems.at(index);
-        applyResolvedRoles(item, resolveHint);
-
-        if (!hasSlowRoles) {
-            // All roles have been resolved already by applyResolvedRoles()
-            m_pendingInvisibleItems.remove(item);
-        }
-        ++index;
-        ++resolvedCount;
-    }
-
-    if (m_previewShown) {
-        KFileItemList items = sortedItems(m_pendingVisibleItems);
-        items += invisibleItems;
-        startPreviewJob(items);
-    } else {
-        QTimer::singleShot(0, this, SLOT(resolveNextPendingRoles()));
-    }
-
-#ifdef KFILEITEMMODELROLESUPDATER_DEBUG
-    if (timer.elapsed() > MaxBlockTimeout) {
-        kDebug() << "Maximum time of" << MaxBlockTimeout
-                 << "ms exceeded, skipping items... Remaining visible:" << m_pendingVisibleItems.count()
-                 << "invisible:" << m_pendingInvisibleItems.count();
-    }
-    kDebug() << "[TIME] Resolved pending roles:" << timer.elapsed();
-#endif
-}
-
 void KFileItemModelRolesUpdater::resolveNextPendingRoles()
 {
     if (m_paused) {
 void KFileItemModelRolesUpdater::resolveNextPendingRoles()
 {
     if (m_paused) {
@@ -556,7 +470,7 @@ void KFileItemModelRolesUpdater::startUpdating(const KItemRangeList& itemRanges)
         }
     }
 
         }
     }
 
-    triggerPendingRolesResolving(rangesCount);
+    resolvePendingRoles();
 }
 
 void KFileItemModelRolesUpdater::startPreviewJob(const KFileItemList& items)
 }
 
 void KFileItemModelRolesUpdater::startPreviewJob(const KFileItemList& items)
@@ -612,6 +526,84 @@ bool KFileItemModelRolesUpdater::hasPendingRoles() const
     return !m_pendingVisibleItems.isEmpty() || !m_pendingInvisibleItems.isEmpty();
 }
 
     return !m_pendingVisibleItems.isEmpty() || !m_pendingInvisibleItems.isEmpty();
 }
 
+void KFileItemModelRolesUpdater::resolvePendingRoles()
+{
+    int resolvedCount = 0;
+
+    const bool hasSlowRoles = m_previewShown
+                              || m_roles.contains("size")
+                              || m_roles.contains("type")
+                              || m_roles.contains("isExpandable");
+    const ResolveHint resolveHint = hasSlowRoles ? ResolveFast : ResolveAll;
+
+    // Resolving the MIME type can be expensive. Assure that not more than MaxBlockTimeout ms are
+    // spend for resolving them synchronously. Usually this is more than enough to determine
+    // all visible items, but there are corner cases where this limit gets easily exceeded.
+    QElapsedTimer timer;
+    timer.start();
+
+    // Resolve the MIME type of all visible items
+    QSetIterator<KFileItem> visibleIt(m_pendingVisibleItems);
+    while (visibleIt.hasNext()) {
+        const KFileItem item = visibleIt.next();
+        applyResolvedRoles(item, resolveHint);
+        if (!hasSlowRoles) {
+            Q_ASSERT(!m_pendingInvisibleItems.contains(item));
+            // All roles have been resolved already by applyResolvedRoles()
+            m_pendingVisibleItems.remove(item);
+        }
+        ++resolvedCount;
+
+        if (timer.elapsed() > MaxBlockTimeout) {
+            break;
+        }
+    }
+
+    // Resolve the MIME type of the invisible items at least until the timeout
+    // has been exceeded or the maximum number of items has been reached
+    KFileItemList invisibleItems;
+    if (m_lastVisibleIndex >= 0) {
+        // The visible range is valid, don't care about the order how the MIME
+        // type of invisible items get resolved
+        invisibleItems = m_pendingInvisibleItems.toList();
+    } else {
+        // The visible range is temporary invalid (e.g. happens when loading
+        // a directory) so take care to sort the currently invisible items where
+        // a part will get visible later
+        invisibleItems = sortedItems(m_pendingInvisibleItems);
+    }
+
+    int index = 0;
+    while (resolvedCount < MaxResolveItemsCount && index < invisibleItems.count() && timer.elapsed() <= MaxBlockTimeout) {
+        const KFileItem item = invisibleItems.at(index);
+        applyResolvedRoles(item, resolveHint);
+
+        if (!hasSlowRoles) {
+            // All roles have been resolved already by applyResolvedRoles()
+            m_pendingInvisibleItems.remove(item);
+        }
+        ++index;
+        ++resolvedCount;
+    }
+
+    if (m_previewShown) {
+        KFileItemList items = sortedItems(m_pendingVisibleItems);
+        items += invisibleItems;
+        startPreviewJob(items);
+    } else {
+        QTimer::singleShot(0, this, SLOT(resolveNextPendingRoles()));
+    }
+
+#ifdef KFILEITEMMODELROLESUPDATER_DEBUG
+    if (timer.elapsed() > MaxBlockTimeout) {
+        kDebug() << "Maximum time of" << MaxBlockTimeout
+                 << "ms exceeded, skipping items... Remaining visible:" << m_pendingVisibleItems.count()
+                 << "invisible:" << m_pendingInvisibleItems.count();
+    }
+    kDebug() << "[TIME] Resolved pending roles:" << timer.elapsed();
+#endif
+}
+
 void KFileItemModelRolesUpdater::resetPendingRoles()
 {
     m_pendingVisibleItems.clear();
 void KFileItemModelRolesUpdater::resetPendingRoles()
 {
     m_pendingVisibleItems.clear();
@@ -623,21 +615,6 @@ void KFileItemModelRolesUpdater::resetPendingRoles()
     Q_ASSERT(m_previewJobs.isEmpty());
 }
 
     Q_ASSERT(m_previewJobs.isEmpty());
 }
 
-void KFileItemModelRolesUpdater::triggerPendingRolesResolving(int count)
-{
-    if (count == m_model->count()) {
-        // When initially loading a directory a synchronous resolving prevents a minor
-        // flickering when opening directories. This is also fine from a performance point
-        // of view as it is assured in resolvePendingRoles() to never block the event-loop
-        // for more than 200 ms.
-        resolvePendingRoles();
-    } else {
-        // Items have been added. This can be done in several small steps within one loop
-        // because of the sorting and hence may not trigger any expensive operation.
-        m_resolvePendingRolesTimer->start();
-    }
-}
-
 void KFileItemModelRolesUpdater::sortAndResolveAllRoles()
 {
     if (m_paused) {
 void KFileItemModelRolesUpdater::sortAndResolveAllRoles()
 {
     if (m_paused) {
@@ -675,8 +652,7 @@ void KFileItemModelRolesUpdater::sortAndResolveAllRoles()
         }
     }
 
         }
     }
 
-    triggerPendingRolesResolving(m_pendingVisibleItems.count() +
-                                 m_pendingInvisibleItems.count());
+    resolvePendingRoles();
 }
 
 void KFileItemModelRolesUpdater::sortAndResolvePendingRoles()
 }
 
 void KFileItemModelRolesUpdater::sortAndResolvePendingRoles()
@@ -715,8 +691,7 @@ void KFileItemModelRolesUpdater::sortAndResolvePendingRoles()
         }
     }
 
         }
     }
 
-    triggerPendingRolesResolving(m_pendingVisibleItems.count() +
-                                 m_pendingInvisibleItems.count());
+    resolvePendingRoles();
 }
 
 bool KFileItemModelRolesUpdater::applyResolvedRoles(const KFileItem& item, ResolveHint hint)
 }
 
 bool KFileItemModelRolesUpdater::applyResolvedRoles(const KFileItem& item, ResolveHint hint)
index b3945d14de8bd4d5130f852fa548150a9bc24648..4db2dde973c0c44e61dfd42ee14fb033ea2b994e 100644 (file)
@@ -123,7 +123,6 @@ private slots:
      */
     void slotPreviewJobFinished(KJob* job);
 
      */
     void slotPreviewJobFinished(KJob* job);
 
-    void resolvePendingRoles();
     void resolveNextPendingRoles();
 
     /**
     void resolveNextPendingRoles();
 
     /**
@@ -150,8 +149,8 @@ private:
     void startPreviewJob(const KFileItemList& items);
 
     bool hasPendingRoles() const;
     void startPreviewJob(const KFileItemList& items);
 
     bool hasPendingRoles() const;
+    void resolvePendingRoles();
     void resetPendingRoles();
     void resetPendingRoles();
-    void triggerPendingRolesResolving(int count);
     void sortAndResolveAllRoles();
     void sortAndResolvePendingRoles();
 
     void sortAndResolveAllRoles();
     void sortAndResolvePendingRoles();
 
@@ -198,8 +197,6 @@ private:
     QSet<KFileItem> m_pendingInvisibleItems;
     QList<KJob*> m_previewJobs;
 
     QSet<KFileItem> m_pendingInvisibleItems;
     QList<KJob*> m_previewJobs;
 
-    QTimer* m_resolvePendingRolesTimer;
-
     // When downloading or copying large files, the slot slotItemsChanged()
     // will be called periodically within a quite short delay. To prevent
     // a high CPU-load by generating e.g. previews for each notification, the update
     // When downloading or copying large files, the slot slotItemsChanged()
     // will be called periodically within a quite short delay. To prevent
     // a high CPU-load by generating e.g. previews for each notification, the update