File indexing completed on 2024-04-28 04:01:22

0001 /* -*- C++ -*-
0002     This file declares the Collection class.
0003 
0004     SPDX-FileCopyrightText: 2004-2013 Mirko Boehm <mirko@kde.org>
0005 
0006     SPDX-License-Identifier: LGPL-2.0-or-later
0007 */
0008 
0009 #ifndef JOBCOLLECTION_H
0010 #define JOBCOLLECTION_H
0011 
0012 #include "job.h"
0013 #include "jobpointer.h"
0014 #include "lambda.h"
0015 
0016 #include <functional>
0017 
0018 namespace ThreadWeaver
0019 {
0020 class Thread;
0021 class CollectionExecuteWrapper;
0022 
0023 namespace Private
0024 {
0025 class Collection_Private;
0026 }
0027 
0028 /** A Collection is a vector of Jobs that will be queued together.
0029  * In a Collection, the order of execution of the elements is not specified.
0030  *
0031  * It is intended that the collection is set up first and then
0032  * queued. After queuing, no further jobs should be added to the collection.
0033  */
0034 class THREADWEAVER_EXPORT Collection : public Job
0035 {
0036 public:
0037     Collection();
0038     Collection(ThreadWeaver::Private::Collection_Private *d);
0039     ~Collection() override;
0040 
0041     /** Append a job to the collection.
0042      *
0043      * To use Collection, create the Job objects first, add them to the collection, and then queue it. After
0044      * the collection has been queued, no further Jobs are supposed to be added.
0045      *
0046      * @note Once the job has been added, execute wrappers can no more be set on it */
0047     virtual void addJob(JobPointer);
0048 
0049     /** Stop processing, dequeue all remaining Jobs.
0050      *
0051      * @since 6.0
0052      */
0053     void stop();
0054 
0055     /** Dequeue all remaining Jobs and request abortion of all running jobs
0056      * @see Job::requestAbort()
0057      *
0058      * @since 6.0
0059      */
0060     void requestAbort() override;
0061 
0062     /** Return the number of elements in the collection. */
0063     int elementCount() const;
0064 
0065     /** @brief Add the job to this collection by pointer. */
0066     Collection &operator<<(ThreadWeaver::JobInterface *job);
0067 
0068     /** @brief Add the job to this collection. */
0069     Collection &operator<<(const ThreadWeaver::JobPointer &job);
0070     Collection &operator<<(JobInterface &job);
0071 
0072 protected:
0073     /** Overload to queue the collection. */
0074     void aboutToBeQueued_locked(QueueAPI *api) override;
0075 
0076     /** Overload to dequeue the collection. */
0077     void aboutToBeDequeued_locked(QueueAPI *api) override;
0078 
0079     /** Return a ref-erence to the job in the job list at position i. */
0080     JobPointer jobAt(int i);
0081 
0082     // FIXME remove
0083     /** Return the number of jobs in the joblist.
0084      *  Assumes that the mutex is being held.
0085      */
0086     virtual int jobListLength_locked() const;
0087 
0088 protected:
0089     /** Overload the execute method. */
0090     void execute(const JobPointer &job, Thread *) override;
0091 
0092     /** Overload run().
0093      * We have to. */
0094     void run(JobPointer self, Thread *thread) override;
0095 
0096 protected:
0097     friend class CollectionExecuteWrapper; // needs to access d()
0098     friend class Collection_Private;
0099     ThreadWeaver::Private::Collection_Private *d();
0100     const ThreadWeaver::Private::Collection_Private *d() const;
0101 };
0102 
0103 /**
0104  * Make a Collection that will execute specified callable (eg. Lambda) for each item in given iterable container
0105  * You can use it to have a parallel map function.
0106  */
0107 template<typename Iterable, typename FN>
0108 QSharedPointer<Collection> make_collection(Iterable iterable, FN callable)
0109 {
0110     QSharedPointer<Collection> collection(new Collection());
0111     for (auto it = iterable.begin(); it != iterable.end(); ++it) {
0112         *collection << make_job([callable, item = *it, collectionJob = collection.get()]() {
0113             callable(item, *collectionJob);
0114         });
0115     }
0116     return collection;
0117 }
0118 }
0119 
0120 #endif