┌   ┐
54
└   ┘

summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPeter Penz <[email protected]>2011-08-02 19:47:06 +0200
committerPeter Penz <[email protected]>2011-08-02 19:54:39 +0200
commit8ea76d0a0e67fbf03de5c2a10a77077b8fe51c08 (patch)
tree5e5f29a5bd07a099b4893f8ea3cc334790d9dd06 /src
parent94f3320444b9243bf52e4578ca9043fa690c5e4c (diff)
Improve performance for creating previews
The overall time for creating previews is faster the more items are passed to KIO::previewJob() in parallel instead of passing e.g. only 100 items once and start several KIO::previewJobs sequentially. However in the worst case KIO::previewJob() might block the application for several seconds if the MIME-type of the passed KFileItems are unknown and e.g. 10000 items are forwarded. So KFileItemModelRolesUpdater will now take care to resolve as many MIME-types as possible until a timeout is reached and will only pass those items to KIO::previewJob(). For huge image folders, where the MIME-type can be determined very fast, this means that the overall time for creating previews will decrease without blocking the application. For "worst case" directories where resolving the MIME-type can get very expensive this approach assures no blocking of the user-interface although the overall time until all previews are generated might slightly increase.
Diffstat (limited to 'src')
-rw-r--r--src/kitemviews/kfileitemmodelrolesupdater.cpp71
-rw-r--r--src/kitemviews/kfileitemmodelrolesupdater.h1
2 files changed, 36 insertions, 36 deletions
diff --git a/src/kitemviews/kfileitemmodelrolesupdater.cpp b/src/kitemviews/kfileitemmodelrolesupdater.cpp
index 4d36a4e05..5b589a9d5 100644
--- a/src/kitemviews/kfileitemmodelrolesupdater.cpp
+++ b/src/kitemviews/kfileitemmodelrolesupdater.cpp
@@ -44,6 +44,14 @@
#define KFILEITEMMODELROLESUPDATER_DEBUG
namespace {
+ // Maximum time in ms that the KFileItemModelRolesUpdater
+ // may perform a blocking operation
+ const int MaxBlockTimeout = 200;
+
+ // Maximum number of items that will get resolved synchronously.
+ // The value should roughly represent the number of maximum visible
+ // items, as it does not make sense to resolve more items synchronously
+ // and probably reach the MaxBlockTimeout because of invisible items.
const int MaxResolveItemsCount = 100;
}
@@ -344,9 +352,8 @@ void KFileItemModelRolesUpdater::slotPreviewJobFinished(KJob* job)
return;
}
- const KFileItemList visibleItems = sortedItems(m_pendingVisibleItems);
- const KFileItemList invisibleItems = itemSubSet(m_pendingInvisibleItems, MaxResolveItemsCount - visibleItems.count());
- startPreviewJob(visibleItems + invisibleItems);
+ const KFileItemList visibleItems = sortedItems(m_pendingVisibleItems);
+ startPreviewJob(visibleItems + m_pendingInvisibleItems.toList());
}
void KFileItemModelRolesUpdater::resolvePendingRoles()
@@ -358,10 +365,9 @@ void KFileItemModelRolesUpdater::resolvePendingRoles()
|| m_roles.contains("type");
const ResolveHint resolveHint = hasSlowRoles ? ResolveFast : ResolveAll;
- // Resolving the MIME type can be expensive. Assure that not more than 200 ms are
+ // 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.
- const int MaxTime = 200;
QElapsedTimer timer;
timer.start();
@@ -377,7 +383,7 @@ void KFileItemModelRolesUpdater::resolvePendingRoles()
}
++resolvedCount;
- if (timer.elapsed() > MaxTime) {
+ if (timer.elapsed() > MaxBlockTimeout) {
break;
}
}
@@ -397,7 +403,7 @@ void KFileItemModelRolesUpdater::resolvePendingRoles()
}
int index = 0;
- while (resolvedCount < MaxResolveItemsCount && index < invisibleItems.count() && timer.elapsed() <= MaxTime) {
+ while (resolvedCount < MaxResolveItemsCount && index < invisibleItems.count() && timer.elapsed() <= MaxBlockTimeout) {
const KFileItem item = invisibleItems.at(index);
applyResolvedRoles(item, resolveHint);
@@ -418,8 +424,9 @@ void KFileItemModelRolesUpdater::resolvePendingRoles()
}
#ifdef KFILEITEMMODELROLESUPDATER_DEBUG
- if (timer.elapsed() > MaxTime) {
- kDebug() << "Maximum time exceeded, skipping items... Remaining visible:" << m_pendingVisibleItems.count()
+ 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();
@@ -482,16 +489,28 @@ void KFileItemModelRolesUpdater::startPreviewJob(const KFileItemList& items)
const QSize cacheSize = (m_iconSize.width() > 128) || (m_iconSize.height() > 128)
? QSize(256, 256) : QSize(128, 128);
- KJob* job;
- if (items.count() <= MaxResolveItemsCount) {
- job = KIO::filePreview(items, cacheSize, &m_enabledPlugins);
- } else {
- KFileItemList itemsSubSet;
- for (int i = 0; i <= MaxResolveItemsCount; ++i) {
- itemsSubSet.append(items.at(i));
+ // KIO::filePreview() will request the MIME-type of all passed items, which (in the
+ // worst case) might block the application for several seconds. To prevent such
+ // a blocking the MIME-type of the items will determined until the MaxBlockTimeout
+ // has been reached and only those items will get passed. As soon as the MIME-type
+ // has been resolved once KIO::filePreview() can already access the resolved
+ // MIME-type in a fast way.
+ QElapsedTimer timer;
+ timer.start();
+ KFileItemList itemSubSet;
+ for (int i = 0; i < items.count(); ++i) {
+ KFileItem item = items.at(i);
+ item.determineMimeType();
+ itemSubSet.append(items.at(i));
+ if (timer.elapsed() > MaxBlockTimeout) {
+#ifdef KFILEITEMMODELROLESUPDATER_DEBUG
+ kDebug() << "Maximum time of" << MaxBlockTimeout << "ms exceeded, creating only previews for"
+ << (i + 1) << "items," << (items.count() - (i + 1)) << "will be resolved later";
+#endif
+ break;
}
- job = KIO::filePreview(itemsSubSet, cacheSize, &m_enabledPlugins);
}
+ KJob* job = KIO::filePreview(itemSubSet, cacheSize, &m_enabledPlugins);
connect(job, SIGNAL(gotPreview(KFileItem,QPixmap)),
this, SLOT(slotGotPreview(KFileItem,QPixmap)));
@@ -711,24 +730,6 @@ KFileItemList KFileItemModelRolesUpdater::sortedItems(const QSet<KFileItem>& ite
return itemList;
}
-KFileItemList KFileItemModelRolesUpdater::itemSubSet(const QSet<KFileItem>& items, int count)
-{
- KFileItemList itemList;
-
- int index = 0;
- QSetIterator<KFileItem> it(items);
- while (it.hasNext() && index < count) {
- const KFileItem item = it.next();
- if (item.isNull()) {
- continue;
- }
- itemList.append(item);
- ++index;
- }
-
- return itemList;
-}
-
int KFileItemModelRolesUpdater::subDirectoriesCount(const QString& path)
{
#ifdef Q_WS_WIN
diff --git a/src/kitemviews/kfileitemmodelrolesupdater.h b/src/kitemviews/kfileitemmodelrolesupdater.h
index 4931f9d64..3b173567e 100644
--- a/src/kitemviews/kfileitemmodelrolesupdater.h
+++ b/src/kitemviews/kfileitemmodelrolesupdater.h
@@ -137,7 +137,6 @@ private:
KFileItemList sortedItems(const QSet<KFileItem>& items) const;
- static KFileItemList itemSubSet(const QSet<KFileItem>& items, int count);
static int subDirectoriesCount(const QString& path);
private: