1 | /* -*- C++ -*- |
2 | This file declares the Collection class. |
3 | |
4 | SPDX-FileCopyrightText: 2004-2013 Mirko Boehm <mirko@kde.org> |
5 | |
6 | SPDX-License-Identifier: LGPL-2.0-or-later |
7 | */ |
8 | |
9 | #ifndef JOBCOLLECTION_H |
10 | #define JOBCOLLECTION_H |
11 | |
12 | #include "job.h" |
13 | #include "jobpointer.h" |
14 | #include "lambda.h" |
15 | |
16 | #include <functional> |
17 | |
18 | namespace ThreadWeaver |
19 | { |
20 | class Thread; |
21 | class CollectionExecuteWrapper; |
22 | |
23 | namespace Private |
24 | { |
25 | class Collection_Private; |
26 | } |
27 | |
28 | /*! |
29 | * \class ThreadWeaver::Collection |
30 | * \inheaderfile ThreadWeaver/Collection |
31 | * \inmodule ThreadWeaver |
32 | * |
33 | * \brief A Collection is a vector of Jobs that will be queued together. |
34 | * In a Collection, the order of execution of the elements is not specified. |
35 | * |
36 | * It is intended that the collection is set up first and then |
37 | * queued. After queuing, no further jobs should be added to the collection. |
38 | */ |
39 | class THREADWEAVER_EXPORT Collection : public Job |
40 | { |
41 | public: |
42 | /*! |
43 | */ |
44 | Collection(); |
45 | /*! |
46 | */ |
47 | Collection(ThreadWeaver::Private::Collection_Private *d); |
48 | ~Collection() override; |
49 | |
50 | /*! Append a job to the collection. |
51 | * |
52 | * To use Collection, create the Job objects first, add them to the collection, and then queue it. After |
53 | * the collection has been queued, no further Jobs are supposed to be added. |
54 | * |
55 | * \note Once the job has been added, execute wrappers can no more be set on it */ |
56 | virtual void addJob(JobPointer); |
57 | |
58 | /*! Stop processing, dequeue all remaining Jobs. |
59 | * |
60 | * \since 6.0 |
61 | */ |
62 | void stop(); |
63 | |
64 | /*! Dequeue all remaining Jobs and request abortion of all running jobs |
65 | * \sa Job::requestAbort() |
66 | * |
67 | * \since 6.0 |
68 | */ |
69 | void requestAbort() override; |
70 | |
71 | /*! Return the number of elements in the collection. */ |
72 | int elementCount() const; |
73 | |
74 | /*! \brief Add the job to this collection by pointer. */ |
75 | Collection &operator<<(ThreadWeaver::JobInterface *job); |
76 | |
77 | /*! \brief Add the job to this collection. */ |
78 | Collection &operator<<(const ThreadWeaver::JobPointer &job); |
79 | /*! |
80 | */ |
81 | Collection &operator<<(JobInterface &job); |
82 | |
83 | protected: |
84 | /*! Overload to queue the collection. */ |
85 | void aboutToBeQueued_locked(QueueAPI *api) override; |
86 | |
87 | /*! Overload to dequeue the collection. */ |
88 | void aboutToBeDequeued_locked(QueueAPI *api) override; |
89 | |
90 | /*! Return a ref-erence to the job in the job list at position i. */ |
91 | JobPointer jobAt(int i); |
92 | |
93 | // FIXME remove |
94 | /*! Return the number of jobs in the joblist. |
95 | * Assumes that the mutex is being held. |
96 | */ |
97 | virtual int jobListLength_locked() const; |
98 | |
99 | protected: |
100 | /*! Overload the execute method. */ |
101 | void execute(const JobPointer &job, Thread *) override; |
102 | |
103 | /*! Overload run(). |
104 | * We have to. */ |
105 | void run(JobPointer self, Thread *thread) override; |
106 | |
107 | protected: |
108 | friend class CollectionExecuteWrapper; // needs to access d() |
109 | friend class Collection_Private; |
110 | /*! |
111 | */ |
112 | ThreadWeaver::Private::Collection_Private *d(); |
113 | /*! |
114 | */ |
115 | const ThreadWeaver::Private::Collection_Private *d() const; |
116 | }; |
117 | |
118 | /*! |
119 | * Make a Collection that will execute specified callable (eg. Lambda) for each item in given iterable container |
120 | * You can use it to have a parallel map function. |
121 | */ |
122 | template<typename Iterable, typename FN> |
123 | QSharedPointer<Collection> make_collection(Iterable iterable, FN callable) |
124 | { |
125 | QSharedPointer<Collection> collection(new Collection()); |
126 | for (auto it = iterable.begin(); it != iterable.end(); ++it) { |
127 | *collection << make_job([callable, item = *it, collectionJob = collection.get()]() { |
128 | callable(item, *collectionJob); |
129 | }); |
130 | } |
131 | return collection; |
132 | } |
133 | } |
134 | |
135 | #endif |
136 | |