File indexing completed on 2024-05-12 05:11:16

0001 /*
0002  * SPDX-FileCopyrightText: 2014 Christian Mollekopf <mollekopf@kolabsys.com>
0003  *
0004  * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0005  *
0006  */
0007 
0008 #pragma once
0009 
0010 #include "index.h"
0011 #include <Akonadi/Collection>
0012 #include <Akonadi/Item>
0013 #include <KSharedConfig>
0014 #include <QObject>
0015 #include <QQueue>
0016 
0017 class CollectionIndexingJob;
0018 
0019 class JobFactory
0020 {
0021 public:
0022     virtual ~JobFactory();
0023     virtual CollectionIndexingJob *createCollectionIndexingJob(Index &index,
0024                                                                const Akonadi::Collection &col,
0025                                                                const QList<Akonadi::Item::Id> &pending,
0026                                                                bool fullSync,
0027                                                                QObject *parent = nullptr);
0028 };
0029 
0030 /**
0031  * The scheduler is responsible for scheduling all scheduled tasks.
0032  *
0033  * In normal operation this simply involves indexing items and collections that have been added.
0034  *
0035  * The scheduler automatically remembers if we failed to index some items before shutting down, and
0036  * issues a full sync for the affected collections.
0037  */
0038 class Scheduler : public QObject
0039 {
0040     Q_OBJECT
0041 public:
0042     explicit Scheduler(Index &index,
0043                        const KSharedConfigPtr &config,
0044                        const QSharedPointer<JobFactory> &jobFactory = QSharedPointer<JobFactory>(),
0045                        QObject *parent = nullptr);
0046     ~Scheduler() override;
0047     void addItem(const Akonadi::Item &);
0048     void scheduleCollection(const Akonadi::Collection &, bool fullSync = false);
0049 
0050     void abort();
0051 
0052     /**
0053      * Sets the timeout used to detect when a collection is no longer busy (in ms). Used for testing.
0054      * Default is 5000.
0055      */
0056     void setBusyTimeout(int);
0057 
0058     [[nodiscard]] int numberOfCollectionQueued() const;
0059 
0060 Q_SIGNALS:
0061     void status(int status, const QString &message = QString());
0062     void percent(int);
0063     void collectionIndexingFinished(Akonadi::Collection::Id id);
0064 
0065 public Q_SLOTS:
0066     void scheduleCompleteSync();
0067 
0068 private Q_SLOTS:
0069     void processNext();
0070     void slotIndexingFinished(KJob *);
0071     void slotRootCollectionsFetched(KJob *);
0072     void slotCollectionsToIndexFetched(KJob *);
0073 
0074 private:
0075     void collectDirtyCollections();
0076 
0077     KSharedConfigPtr m_config;
0078     QHash<Akonadi::Collection::Id, QQueue<Akonadi::Item::Id>> m_queues;
0079     QQueue<Akonadi::Collection::Id> m_collectionQueue;
0080     Index &m_index;
0081     KJob *m_currentJob = nullptr;
0082     QTimer m_processTimer;
0083     QHash<Akonadi::Collection::Id, qint64> m_lastModifiedTimestamps;
0084     QSet<Akonadi::Collection::Id> m_dirtyCollections;
0085     QSharedPointer<JobFactory> m_jobFactory;
0086     int m_busyTimeout;
0087 };