@@ -46,63 +46,38 @@ bool MergeTreePrefetchedReadPool::TaskHolder::operator<(const TaskHolder & other
4646}
4747
4848
49- MergeTreePrefetchedReadPool::PrefetchedReaders::~PrefetchedReaders ()
50- {
51- for (auto & prefetch_future : prefetch_futures)
52- if (prefetch_future.valid ())
53- prefetch_future.wait ();
54- }
55-
5649MergeTreePrefetchedReadPool::PrefetchedReaders::PrefetchedReaders (
50+ ThreadPool & pool,
5751 MergeTreeReadTask::Readers readers_,
5852 Priority priority_,
59- MergeTreePrefetchedReadPool & pool_ )
53+ MergeTreePrefetchedReadPool & read_prefetch )
6054 : is_valid(true )
6155 , readers(std::move(readers_))
56+ , prefetch_runner(pool, " ReadPrepare" )
6257{
63- try
64- {
65- prefetch_futures.reserve (1 + readers.prewhere .size ());
66-
67- prefetch_futures.push_back (pool_.createPrefetchedFuture (readers.main .get (), priority_));
58+ prefetch_runner (read_prefetch.createPrefetchedTask (readers.main .get (), priority_));
6859
69- for (const auto & reader : readers.prewhere )
70- prefetch_futures. push_back (pool_. createPrefetchedFuture (reader.get (), priority_));
60+ for (const auto & reader : readers.prewhere )
61+ prefetch_runner (read_prefetch. createPrefetchedTask (reader.get (), priority_));
7162
72- fiu_do_on (FailPoints::prefetched_reader_pool_failpoint,
73- {
74- throw Exception (ErrorCodes::BAD_ARGUMENTS, " Failpoint for prefetched reader enabled" );
75- });
76- }
77- catch (...) // / in case of memory exceptions we have to wait
63+ fiu_do_on (FailPoints::prefetched_reader_pool_failpoint,
7864 {
79- for (auto & prefetch_future : prefetch_futures)
80- if (prefetch_future.valid ())
81- prefetch_future.wait ();
82-
83- throw ;
84- }
65+ throw Exception (ErrorCodes::BAD_ARGUMENTS, " Failpoint for prefetched reader enabled" );
66+ });
8567}
8668
8769void MergeTreePrefetchedReadPool::PrefetchedReaders::wait ()
8870{
8971 ProfileEventTimeIncrement<Microseconds> watch (ProfileEvents::WaitPrefetchTaskMicroseconds);
90- for (auto & prefetch_future : prefetch_futures)
91- prefetch_future.wait ();
72+ prefetch_runner.waitForAllToFinish ();
9273}
9374
9475MergeTreeReadTask::Readers MergeTreePrefetchedReadPool::PrefetchedReaders::get ()
9576{
9677 SCOPE_EXIT ({ is_valid = false ; });
9778 ProfileEventTimeIncrement<Microseconds> watch (ProfileEvents::WaitPrefetchTaskMicroseconds);
9879
99- // / First wait for completion of all futures.
100- for (auto & prefetch_future : prefetch_futures)
101- prefetch_future.wait ();
102-
103- // / Then rethrow first exception if any.
104- for (auto & prefetch_future : prefetch_futures)
105- prefetch_future.get ();
80+ prefetch_runner.waitForAllToFinishAndRethrowFirstError ();
10681
10782 return std::move (readers);
10883}
@@ -139,22 +114,20 @@ MergeTreePrefetchedReadPool::MergeTreePrefetchedReadPool(
139114 fillPerThreadTasks (pool_settings.threads , pool_settings.sum_marks );
140115}
141116
142- std::future <void > MergeTreePrefetchedReadPool::createPrefetchedFuture (IMergeTreeReader * reader, Priority priority)
117+ std::function <void () > MergeTreePrefetchedReadPool::createPrefetchedTask (IMergeTreeReader * reader, Priority priority)
143118{
144119 // / In order to make a prefetch we need to wait for marks to be loaded. But we just created
145120 // / a reader (which starts loading marks in its constructor), then if we do prefetch right
146121 // / after creating a reader, it will be very inefficient. We can do prefetch for all parts
147122 // / only inside this MergeTreePrefetchedReadPool, where read tasks are created and distributed,
148123 // / and we cannot block either, therefore make prefetch inside the pool and put the future
149124 // / into the thread task. When a thread calls getTask(), it will wait for it is not ready yet.
150- auto task = [=, context = getContext ()]() mutable
125+ return [=, context = getContext ()]() mutable
151126 {
152127 // / For async read metrics in system.query_log.
153128 PrefetchIncrement watch (context->getAsyncReadCounters ());
154129 reader->prefetchBeginOfRange (priority);
155130 };
156-
157- return scheduleFromThreadPoolUnsafe<void >(std::move (task), prefetch_threadpool, " ReadPrepare" , priority);
158131}
159132
160133void MergeTreePrefetchedReadPool::createPrefetchedReadersForTask (ThreadTask & task)
@@ -164,7 +137,7 @@ void MergeTreePrefetchedReadPool::createPrefetchedReadersForTask(ThreadTask & ta
164137
165138 auto extras = getExtras ();
166139 auto readers = MergeTreeReadTask::createReaders (task.read_info , extras, task.ranges );
167- task.readers_future = std::make_unique<PrefetchedReaders>(std::move (readers), task.priority , *this );
140+ task.readers_future = std::make_unique<PrefetchedReaders>(prefetch_threadpool, std::move (readers), task.priority , *this );
168141}
169142
170143void MergeTreePrefetchedReadPool::startPrefetches ()
0 commit comments