File indexing completed on 2024-11-10 04:40:12

0001 /*
0002     SPDX-FileCopyrightText: 2009 Volker Krause <vkrause@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "agentinstance.h"
0008 #include "agentmanager.h"
0009 #include "item.h"
0010 #include "itemcreatejob.h"
0011 #include "itemdeletejob.h"
0012 #include "itemfetchjob.h"
0013 #include "itemfetchscope.h"
0014 #include "itemmodifyjob.h"
0015 #include "qtest_akonadi.h"
0016 
0017 #include <QDebug>
0018 
0019 using namespace Akonadi;
0020 
0021 class ItemBenchmark : public QObject
0022 {
0023     Q_OBJECT
0024 public Q_SLOTS:
0025     void createResult(KJob *job)
0026     {
0027         Q_ASSERT(job->error() == KJob::NoError);
0028         Item createdItem = static_cast<ItemCreateJob *>(job)->item();
0029         mCreatedItems[createdItem.size()].append(createdItem);
0030     }
0031 
0032     void fetchResult(KJob *job)
0033     {
0034         Q_ASSERT(job->error() == KJob::NoError);
0035     }
0036 
0037     void modifyResult(KJob *job)
0038     {
0039         Q_ASSERT(job->error() == KJob::NoError);
0040     }
0041 
0042 private:
0043     QMap<int, Item::List> mCreatedItems;
0044 
0045 private Q_SLOTS:
0046     void initTestCase()
0047     {
0048         AkonadiTest::checkTestIsIsolated();
0049         AkonadiTest::setAllResourcesOffline();
0050     }
0051 
0052     void data()
0053     {
0054         QTest::addColumn<int>("count");
0055         QTest::addColumn<int>("size");
0056 
0057         const int counts[]{1, 10, 100, 1000}; // , 10000 };
0058         const int sizes[]{0, 256, 1024, 8192, 32768, 65536};
0059         for (int count : counts)
0060             for (int size : sizes)
0061                 QTest::newRow(QString::fromLatin1("%1-%2").arg(count).arg(size).toLatin1().constData()) << count << size;
0062     }
0063 
0064     void itemBenchmarkCreate_data()
0065     {
0066         data();
0067     }
0068     void itemBenchmarkCreate() /// Tests performance of creating items in the cache
0069     {
0070         QFETCH(int, count);
0071         QFETCH(int, size);
0072 
0073         const Collection parent(AkonadiTest::collectionIdFromPath(QStringLiteral("res1/foo")));
0074         QVERIFY(parent.isValid());
0075 
0076         Item item(QStringLiteral("application/octet-stream"));
0077         item.setPayload(QByteArray(size, 'X'));
0078         item.setSize(size);
0079 
0080         Job *lastJob = 0;
0081         QBENCHMARK {
0082             for (int i = 0; i < count; ++i) {
0083                 lastJob = new ItemCreateJob(item, parent, this);
0084                 connect(lastJob, SIGNAL(result(KJob *)), SLOT(createResult(KJob *)));
0085             }
0086             AkonadiTest::akWaitForSignal(lastJob, SIGNAL(result(KJob *)));
0087         }
0088     }
0089 
0090     void itemBenchmarkFetch_data()
0091     {
0092         data();
0093     }
0094     void itemBenchmarkFetch() /// Tests performance of fetching cached items
0095     {
0096         QFETCH(int, count);
0097         QFETCH(int, size);
0098 
0099         // With only one iteration itemBenchmarkCreate() should have created count
0100         // items, otherwise iterations * count, however, at least count items should
0101         // be there.
0102         QVERIFY(mCreatedItems.value(size).count() >= count);
0103 
0104         QBENCHMARK {
0105             Item::List items;
0106             for (int i = 0; i < count; ++i) {
0107                 items << mCreatedItems[size].at(i);
0108             }
0109 
0110             ItemFetchJob *fetchJob = new ItemFetchJob(items, this);
0111             fetchJob->fetchScope().fetchFullPayload();
0112             fetchJob->fetchScope().setCacheOnly(true);
0113             connect(fetchJob, SIGNAL(result(KJob *)), SLOT(fetchResult(KJob *)));
0114             AkonadiTest::akWaitForSignal(fetchJob, SIGNAL(result(KJob *)));
0115         }
0116     }
0117 
0118     void itemBenchmarkModifyPayload_data()
0119     {
0120         data();
0121     }
0122     void itemBenchmarkModifyPayload() /// Tests performance of modifying payload of cached items
0123     {
0124         QFETCH(int, count);
0125         QFETCH(int, size);
0126 
0127         // With only one iteration itemBenchmarkCreate() should have created count
0128         // items, otherwise iterations * count, however, at least count items should
0129         // be there.
0130         QVERIFY(mCreatedItems.value(size).count() >= count);
0131 
0132         Job *lastJob = 0;
0133         const int newSize = qMax(size, 1);
0134         QBENCHMARK {
0135             for (int i = 0; i < count; ++i) {
0136                 Item item = mCreatedItems.value(size).at(i);
0137                 item.setPayload(QByteArray(newSize, 'Y'));
0138                 ItemModifyJob *job = new ItemModifyJob(item, this);
0139                 job->disableRevisionCheck();
0140                 lastJob = job;
0141                 connect(lastJob, SIGNAL(result(KJob *)), SLOT(modifyResult(KJob *)));
0142             }
0143             AkonadiTest::akWaitForSignal(lastJob, SIGNAL(result(KJob *)));
0144         }
0145     }
0146 
0147     void itemBenchmarkDelete_data()
0148     {
0149         data();
0150     }
0151     void itemBenchmarkDelete() /// Tests performance of removing items from the cache
0152     {
0153         QFETCH(int, count);
0154         QFETCH(int, size);
0155 
0156         Job *lastJob = 0;
0157         int emptyItemArrayIterations = 0;
0158         QBENCHMARK {
0159             if (mCreatedItems[size].isEmpty()) {
0160                 ++emptyItemArrayIterations;
0161             }
0162 
0163             Item::List items;
0164             for (int i = 0; i < count && !mCreatedItems[size].isEmpty(); ++i) {
0165                 items << mCreatedItems[size].takeFirst();
0166             }
0167             lastJob = new ItemDeleteJob(items, this);
0168             AkonadiTest::akWaitForSignal(lastJob, SIGNAL(result(KJob *)));
0169         }
0170 
0171         if (emptyItemArrayIterations) {
0172             qDebug() << "Delete Benchmark performed" << emptyItemArrayIterations << "times on an empty list.";
0173         }
0174     }
0175 };
0176 
0177 QTEST_AKONADIMAIN(ItemBenchmark)
0178 
0179 #include "itembenchmark.moc"