#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).
}
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,