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