]> cloud.milkyroute.net Git - dolphin.git/blobdiff - src/kitemviews/private/kfileitemmodelsortalgorithm.cpp
Prevent repeated re-layouting of all items while previews are generated
[dolphin.git] / src / kitemviews / private / kfileitemmodelsortalgorithm.cpp
index e0aac13de3e1f7848280ae26d8b5e9a92c081ff2..ab650efea1e66451309f542081ede7c83b31ae36 100644 (file)
 
 #include "kfileitemmodelsortalgorithm.h"
 
+#include <QThread>
+#include <QtCore>
+
 void KFileItemModelSortAlgorithm::sort(KFileItemModel* model,
                                        QList<KFileItemModel::ItemData*>::iterator begin,
                                        QList<KFileItemModel::ItemData*>::iterator end)
+{
+    if (model->sortRole() == model->roleForType(KFileItemModel::NameRole)) {
+        // Sorting by name can be expensive, in particular if natural sorting is
+        // enabled. Use all CPU cores to speed up the sorting process.
+        static const int numberOfThreads = QThread::idealThreadCount();
+        parallelSort(model, begin, end, numberOfThreads);
+    } else {
+        // Sorting by other roles is quite fast. Use only one thread to prevent
+        // problems caused by non-reentrant comparison functions, see
+        // https://bugs.kde.org/show_bug.cgi?id=312679
+        sequentialSort(model, begin, end);
+    }
+}
+
+void KFileItemModelSortAlgorithm::sequentialSort(KFileItemModel* model,
+                                                 QList< KFileItemModel::ItemData* >::iterator begin,
+                                                 QList< KFileItemModel::ItemData* >::iterator end)
 {
     // The implementation is based on qStableSortHelper() from qalgorithms.h
     // Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
@@ -32,11 +52,33 @@ void KFileItemModelSortAlgorithm::sort(KFileItemModel* model,
     }
 
     const QList<KFileItemModel::ItemData*>::iterator middle = begin + span / 2;
-    sort(model, begin, middle);
-    sort(model, middle, end);
+    sequentialSort(model, begin, middle);
+    sequentialSort(model, middle, end);
     merge(model, begin, middle, end);
 }
 
+void KFileItemModelSortAlgorithm::parallelSort(KFileItemModel* model,
+                                               QList< KFileItemModel::ItemData* >::iterator begin,
+                                               QList< KFileItemModel::ItemData* >::iterator end,
+                                               const int numberOfThreads)
+{
+    const int span = end - begin;
+
+    if (numberOfThreads > 1 && span > 100) {
+        const int newNumberOfThreads = numberOfThreads / 2;
+        const QList<KFileItemModel::ItemData*>::iterator middle = begin + span / 2;
+
+        QFuture<void> future = QtConcurrent::run(parallelSort, model, begin, middle, newNumberOfThreads);
+        parallelSort(model, middle, end, newNumberOfThreads);
+
+        future.waitForFinished();
+
+        merge(model, begin, middle, end);
+    } else {
+        sequentialSort(model, begin, end);
+    }
+}
+
 void KFileItemModelSortAlgorithm::merge(KFileItemModel* model,
                                         QList<KFileItemModel::ItemData*>::iterator begin,
                                         QList<KFileItemModel::ItemData*>::iterator pivot,