2 * SPDX-FileCopyrightText: 2011 Peter Penz <peter.penz19@gmail.com>
3 * SPDX-FileCopyrightText: 2013 Frank Reininghaus <frank78ac@googlemail.com>
5 * SPDX-License-Identifier: GPL-2.0-or-later
13 #include "kitemviews/kfileitemmodel.h"
14 #include "kitemviews/private/kfileitemmodelsortalgorithm.h"
16 void myMessageOutput(QtMsgType type
, const QMessageLogContext
& context
, const QString
& msg
)
26 fprintf(stderr
, "Critical: %s\n", msg
.toLocal8Bit().data());
29 fprintf(stderr
, "Fatal: %s\n", msg
.toLocal8Bit().data());
36 Q_DECLARE_METATYPE(KFileItemList
)
37 Q_DECLARE_METATYPE(KItemRangeList
)
39 class KFileItemModelBenchmark
: public QObject
44 KFileItemModelBenchmark();
47 void insertAndRemoveManyItems_data();
48 void insertAndRemoveManyItems();
51 static KFileItemList
createFileItemList(const QStringList
& fileNames
, const QString
& urlPrefix
= QLatin1String("file:///"));
54 KFileItemModelBenchmark::KFileItemModelBenchmark()
58 void KFileItemModelBenchmark::insertAndRemoveManyItems_data()
60 QTest::addColumn
<KFileItemList
>("initialItems");
61 QTest::addColumn
<KFileItemList
>("newItems");
62 QTest::addColumn
<KFileItemList
>("removedItems");
63 QTest::addColumn
<KFileItemList
>("expectedFinalItems");
64 QTest::addColumn
<KItemRangeList
>("expectedItemsInserted");
65 QTest::addColumn
<KItemRangeList
>("expectedItemsRemoved");
70 for (int n
: qAsConst(sizes
)) {
71 QStringList allStrings
;
72 for (int i
= 0; i
< n
; ++i
) {
73 allStrings
<< QString::number(i
);
76 // We want to keep the sorting overhead in the benchmark low.
77 // Therefore, we do not use natural sorting. However, this
78 // means that our list is currently not sorted.
81 KFileItemList all
= createFileItemList(allStrings
);
83 KFileItemList firstHalf
, secondHalf
, even
, odd
;
84 for (int i
= 0; i
< n
; ++i
) {
86 firstHalf
<< all
.at(i
);
88 secondHalf
<< all
.at(i
);
98 KItemRangeList itemRangeListFirstHalf
;
99 itemRangeListFirstHalf
<< KItemRange(0, firstHalf
.count());
101 KItemRangeList itemRangeListSecondHalf
;
102 itemRangeListSecondHalf
<< KItemRange(firstHalf
.count(), secondHalf
.count());
104 KItemRangeList itemRangeListOddInserted
, itemRangeListOddRemoved
;
105 for (int i
= 0; i
< odd
.count(); ++i
) {
106 // Note that the index in the KItemRange is the index of
107 // the model *before* the items have been inserted.
108 itemRangeListOddInserted
<< KItemRange(i
+ 1, 1);
109 itemRangeListOddRemoved
<< KItemRange(2 * i
+ 1, 1);
112 const int bufferSize
= 128;
113 char buffer
[bufferSize
];
115 snprintf(buffer
, bufferSize
, "all--n=%i", n
);
116 QTest::newRow(buffer
) << all
<< KFileItemList() << KFileItemList() << all
<< KItemRangeList() << KItemRangeList();
118 snprintf(buffer
, bufferSize
, "1st half + 2nd half--n=%i", n
);
119 QTest::newRow(buffer
) << firstHalf
<< secondHalf
<< KFileItemList() << all
<< itemRangeListSecondHalf
<< KItemRangeList();
121 snprintf(buffer
, bufferSize
, "2nd half + 1st half--n=%i", n
);
122 QTest::newRow(buffer
) << secondHalf
<< firstHalf
<< KFileItemList() << all
<< itemRangeListFirstHalf
<< KItemRangeList();
124 snprintf(buffer
, bufferSize
, "even + odd--n=%i", n
);
125 QTest::newRow(buffer
) << even
<< odd
<< KFileItemList() << all
<< itemRangeListOddInserted
<< KItemRangeList();
127 snprintf(buffer
, bufferSize
, "all - 2nd half--n=%i", n
);
128 QTest::newRow(buffer
) << all
<< KFileItemList() << secondHalf
<< firstHalf
<< KItemRangeList() << itemRangeListSecondHalf
;
130 snprintf(buffer
, bufferSize
, "all - 1st half--n=%i", n
);
131 QTest::newRow(buffer
) << all
<< KFileItemList() << firstHalf
<< secondHalf
<< KItemRangeList() << itemRangeListFirstHalf
;
133 snprintf(buffer
, bufferSize
, "all - odd--n=%i", n
);
134 QTest::newRow(buffer
) << all
<< KFileItemList() << odd
<< even
<< KItemRangeList() << itemRangeListOddRemoved
;
138 void KFileItemModelBenchmark::insertAndRemoveManyItems()
140 QFETCH(KFileItemList
, initialItems
);
141 QFETCH(KFileItemList
, newItems
);
142 QFETCH(KFileItemList
, removedItems
);
143 QFETCH(KFileItemList
, expectedFinalItems
);
144 QFETCH(KItemRangeList
, expectedItemsInserted
);
145 QFETCH(KItemRangeList
, expectedItemsRemoved
);
147 KFileItemModel model
;
149 // Avoid overhead caused by natural sorting
150 // and determining the isDir/isLink roles.
151 model
.m_naturalSorting
= false;
152 model
.setRoles({"text"});
154 QSignalSpy
spyItemsInserted(&model
, &KFileItemModel::itemsInserted
);
155 QSignalSpy
spyItemsRemoved(&model
, &KFileItemModel::itemsRemoved
);
159 model
.slotItemsAdded(model
.directory(), initialItems
);
160 model
.slotCompleted();
161 QCOMPARE(model
.count(), initialItems
.count());
163 if (!newItems
.isEmpty()) {
164 model
.slotItemsAdded(model
.directory(), newItems
);
165 model
.slotCompleted();
167 QCOMPARE(model
.count(), initialItems
.count() + newItems
.count());
169 if (!removedItems
.isEmpty()) {
170 model
.slotItemsDeleted(removedItems
);
172 QCOMPARE(model
.count(), initialItems
.count() + newItems
.count() - removedItems
.count());
175 QVERIFY(model
.isConsistent());
177 for (int i
= 0; i
< model
.count(); ++i
) {
178 QCOMPARE(model
.fileItem(i
), expectedFinalItems
.at(i
));
181 if (!expectedItemsInserted
.empty()) {
182 QVERIFY(!spyItemsInserted
.empty());
183 const KItemRangeList actualItemsInserted
= spyItemsInserted
.last().first().value
<KItemRangeList
>();
184 QCOMPARE(actualItemsInserted
, expectedItemsInserted
);
187 if (!expectedItemsRemoved
.empty()) {
188 QVERIFY(!spyItemsRemoved
.empty());
189 const KItemRangeList actualItemsRemoved
= spyItemsRemoved
.last().first().value
<KItemRangeList
>();
190 QCOMPARE(actualItemsRemoved
, expectedItemsRemoved
);
194 KFileItemList
KFileItemModelBenchmark::createFileItemList(const QStringList
& fileNames
, const QString
& prefix
)
196 // Suppress 'file does not exist anymore' messages from KFileItemPrivate::init().
197 qInstallMessageHandler(myMessageOutput
);
199 KFileItemList result
;
200 for (const QString
& name
: fileNames
) {
201 const KFileItem
item(QUrl::fromLocalFile(prefix
+ name
), QString(), KFileItem::Unknown
);
207 QTEST_MAIN(KFileItemModelBenchmark
)
209 #include "kfileitemmodelbenchmark.moc"