]> cloud.milkyroute.net Git - dolphin.git/blob - src/tests/kfileitemmodelbenchmark.cpp
Merge remote-tracking branch 'origin/KDE/4.10'
[dolphin.git] / src / tests / kfileitemmodelbenchmark.cpp
1 /***************************************************************************
2 * Copyright (C) 2011 by Peter Penz <peter.penz19@gmail.com> *
3 * Copyright (C) 2013 by Frank Reininghaus <frank78ac@googlemail.com> *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
19 ***************************************************************************/
20
21 #include <qtest_kde.h>
22
23 #include <KGlobalSettings>
24
25 #include "kitemviews/kfileitemmodel.h"
26 #include "kitemviews/private/kfileitemmodelsortalgorithm.h"
27
28 void myMessageOutput(QtMsgType type, const char* msg)
29 {
30 switch (type) {
31 case QtDebugMsg:
32 break;
33 case QtWarningMsg:
34 break;
35 case QtCriticalMsg:
36 fprintf(stderr, "Critical: %s\n", msg);
37 break;
38 case QtFatalMsg:
39 fprintf(stderr, "Fatal: %s\n", msg);
40 abort();
41 default:
42 break;
43 }
44 }
45
46 Q_DECLARE_METATYPE(KFileItemList)
47 Q_DECLARE_METATYPE(KItemRangeList)
48
49 class KFileItemModelBenchmark : public QObject
50 {
51 Q_OBJECT
52
53 public:
54 KFileItemModelBenchmark();
55
56 private slots:
57 void insertAndRemoveManyItems_data();
58 void insertAndRemoveManyItems();
59
60 private:
61 static KFileItemList createFileItemList(const QStringList& fileNames, const QString& urlPrefix = QLatin1String("file:///"));
62 };
63
64 KFileItemModelBenchmark::KFileItemModelBenchmark()
65 {
66 }
67
68 void KFileItemModelBenchmark::insertAndRemoveManyItems_data()
69 {
70 QTest::addColumn<KFileItemList>("initialItems");
71 QTest::addColumn<KFileItemList>("newItems");
72 QTest::addColumn<KFileItemList>("removedItems");
73 QTest::addColumn<KFileItemList>("expectedFinalItems");
74 QTest::addColumn<KItemRangeList>("expectedItemsInserted");
75 QTest::addColumn<KItemRangeList>("expectedItemsRemoved");
76
77 QList<int> sizes;
78 sizes << 1000 << 4000 << 16000 << 64000 << 256000;
79 //sizes << 50000 << 100000 << 150000 << 200000 << 250000;
80
81 foreach (int n, sizes) {
82 QStringList allStrings;
83 for (int i = 0; i < n; ++i) {
84 allStrings << QString::number(i);
85 }
86
87 // We want to keep the sorting overhead in the benchmark low.
88 // Therefore, we do not use natural sorting. However, this
89 // means that our list is currently not sorted.
90 allStrings.sort();
91
92 KFileItemList all = createFileItemList(allStrings);
93
94 KFileItemList firstHalf, secondHalf, even, odd;
95 for (int i = 0; i < n; ++i) {
96 if (i < n / 2) {
97 firstHalf << all.at(i);
98 } else {
99 secondHalf << all.at(i);
100 }
101
102 if (i % 2 == 0) {
103 even << all.at(i);
104 } else {
105 odd << all.at(i);
106 }
107 }
108
109 KItemRangeList itemRangeListFirstHalf;
110 itemRangeListFirstHalf << KItemRange(0, firstHalf.count());
111
112 KItemRangeList itemRangeListSecondHalf;
113 itemRangeListSecondHalf << KItemRange(firstHalf.count(), secondHalf.count());
114
115 KItemRangeList itemRangeListOddInserted, itemRangeListOddRemoved;
116 for (int i = 0; i < odd.count(); ++i) {
117 // Note that the index in the KItemRange is the index of
118 // the model *before* the items have been inserted.
119 itemRangeListOddInserted << KItemRange(i + 1, 1);
120 itemRangeListOddRemoved << KItemRange(2 * i + 1, 1);
121 }
122
123 const int bufferSize = 128;
124 char buffer[bufferSize];
125
126 snprintf(buffer, bufferSize, "all--n=%i", n);
127 QTest::newRow(buffer) << all << KFileItemList() << KFileItemList() << all << KItemRangeList() << KItemRangeList();
128
129 snprintf(buffer, bufferSize, "1st half + 2nd half--n=%i", n);
130 QTest::newRow(buffer) << firstHalf << secondHalf << KFileItemList() << all << itemRangeListSecondHalf << KItemRangeList();
131
132 snprintf(buffer, bufferSize, "2nd half + 1st half--n=%i", n);
133 QTest::newRow(buffer) << secondHalf << firstHalf << KFileItemList() << all << itemRangeListFirstHalf << KItemRangeList();
134
135 snprintf(buffer, bufferSize, "even + odd--n=%i", n);
136 QTest::newRow(buffer) << even << odd << KFileItemList() << all << itemRangeListOddInserted << KItemRangeList();
137
138 snprintf(buffer, bufferSize, "all - 2nd half--n=%i", n);
139 QTest::newRow(buffer) << all << KFileItemList() << secondHalf << firstHalf << KItemRangeList() << itemRangeListSecondHalf;
140
141 snprintf(buffer, bufferSize, "all - 1st half--n=%i", n);
142 QTest::newRow(buffer) << all << KFileItemList() << firstHalf << secondHalf << KItemRangeList() << itemRangeListFirstHalf;
143
144 snprintf(buffer, bufferSize, "all - odd--n=%i", n);
145 QTest::newRow(buffer) << all << KFileItemList() << odd << even << KItemRangeList() << itemRangeListOddRemoved;
146 }
147 }
148
149 void KFileItemModelBenchmark::insertAndRemoveManyItems()
150 {
151 QFETCH(KFileItemList, initialItems);
152 QFETCH(KFileItemList, newItems);
153 QFETCH(KFileItemList, removedItems);
154 QFETCH(KFileItemList, expectedFinalItems);
155 QFETCH(KItemRangeList, expectedItemsInserted);
156 QFETCH(KItemRangeList, expectedItemsRemoved);
157
158 KFileItemModel model;
159
160 // Avoid overhead caused by natural sorting
161 // and determining the isDir/isLink roles.
162 model.m_naturalSorting = false;
163 model.setRoles(QSet<QByteArray>() << "text");
164
165 QSignalSpy spyItemsInserted(&model, SIGNAL(itemsInserted(KItemRangeList)));
166 QSignalSpy spyItemsRemoved(&model, SIGNAL(itemsRemoved(KItemRangeList)));
167
168 QBENCHMARK {
169 model.slotClear();
170 model.slotNewItems(initialItems);
171 model.slotCompleted();
172 QCOMPARE(model.count(), initialItems.count());
173
174 if (!newItems.isEmpty()) {
175 model.slotNewItems(newItems);
176 model.slotCompleted();
177 }
178 QCOMPARE(model.count(), initialItems.count() + newItems.count());
179
180 if (!removedItems.isEmpty()) {
181 model.removeItems(removedItems);
182 }
183 QCOMPARE(model.count(), initialItems.count() + newItems.count() - removedItems.count());
184 }
185
186 QVERIFY(model.isConsistent());
187
188 for (int i = 0; i < model.count(); ++i) {
189 QCOMPARE(model.fileItem(i), expectedFinalItems.at(i));
190 }
191
192 if (!expectedItemsInserted.empty()) {
193 QVERIFY(!spyItemsInserted.empty());
194 const KItemRangeList actualItemsInserted = spyItemsInserted.last().first().value<KItemRangeList>();
195 QCOMPARE(actualItemsInserted, expectedItemsInserted);
196 }
197
198 if (!expectedItemsRemoved.empty()) {
199 QVERIFY(!spyItemsRemoved.empty());
200 const KItemRangeList actualItemsRemoved = spyItemsRemoved.last().first().value<KItemRangeList>();
201 QCOMPARE(actualItemsRemoved, expectedItemsRemoved);
202 }
203 }
204
205 KFileItemList KFileItemModelBenchmark::createFileItemList(const QStringList& fileNames, const QString& prefix)
206 {
207 // Suppress 'file does not exist anymore' messages from KFileItemPrivate::init().
208 qInstallMsgHandler(myMessageOutput);
209
210 KFileItemList result;
211 foreach (const QString& name, fileNames) {
212 const KUrl url(prefix + name);
213 const KFileItem item(url, QString(), KFileItem::Unknown);
214 result << item;
215 }
216 return result;
217 }
218
219 QTEST_KDEMAIN(KFileItemModelBenchmark, NoGUI)
220
221 #include "kfileitemmodelbenchmark.moc"