@@ -16,14 +16,16 @@ use std::ops::Range;
16
16
use std:: sync:: Arc ;
17
17
18
18
use common_arrow:: parquet:: metadata:: SchemaDescriptor ;
19
+ use common_base:: base:: tokio:: sync:: Semaphore ;
19
20
use common_base:: rangemap:: RangeMerger ;
20
- use common_base:: runtime:: UnlimitedFuture ;
21
+ use common_base:: runtime:: Runtime ;
21
22
use common_catalog:: plan:: Projection ;
22
23
use common_catalog:: table_context:: TableContext ;
23
24
use common_datavalues:: DataSchemaRef ;
24
25
use common_exception:: ErrorCode ;
25
26
use common_exception:: Result ;
26
27
use common_storage:: ColumnLeaves ;
28
+ use futures_util:: future;
27
29
use opendal:: Object ;
28
30
use opendal:: Operator ;
29
31
@@ -61,17 +63,42 @@ impl BlockReader {
61
63
let range_merger = RangeMerger :: from_iter ( ranges, max_gap_size, max_range_size) ;
62
64
let merged_ranges = range_merger. ranges ( ) ;
63
65
64
- // Read merged range data.
65
- let mut read_handlers = Vec :: with_capacity ( merged_ranges. len ( ) ) ;
66
- for ( idx, range) in merged_ranges. iter ( ) . enumerate ( ) {
67
- read_handlers. push ( UnlimitedFuture :: create ( Self :: read_range (
68
- object. clone ( ) ,
69
- idx,
70
- range. start ,
71
- range. end ,
72
- ) ) ) ;
73
- }
74
- let merged_range_data_results = futures:: future:: try_join_all ( read_handlers) . await ?;
66
+ // new joint,.
67
+ let max_runtime_threads = ctx. get_settings ( ) . get_max_threads ( ) ? as usize ;
68
+
69
+ // 1.1 combine all the tasks.
70
+ let mut iter = merged_ranges. iter ( ) . enumerate ( ) ;
71
+ let tasks = std:: iter:: from_fn ( move || {
72
+ if let Some ( ( idx, range) ) = iter. next ( ) {
73
+ Some ( Self :: read_range (
74
+ object. clone ( ) ,
75
+ idx,
76
+ range. start ,
77
+ range. end ,
78
+ ) )
79
+ } else {
80
+ None
81
+ }
82
+ } ) ;
83
+
84
+ // 1.2 build the runtime.
85
+ let semaphore = Semaphore :: new ( merged_ranges. len ( ) ) ;
86
+ let io_runtime = Arc :: new ( Runtime :: with_worker_threads (
87
+ max_runtime_threads,
88
+ Some ( "io-read-worker" . to_owned ( ) ) ,
89
+ ) ?) ;
90
+
91
+ // 1.3 spawn all the tasks to the runtime.
92
+ let join_handlers = io_runtime. try_spawn_batch ( semaphore, tasks) . await ?;
93
+
94
+ // 1.4 get all the result.
95
+ let merged_range_data_results = future:: try_join_all ( join_handlers)
96
+ . await
97
+ . map_err ( |e| {
98
+ ErrorCode :: StorageOther ( format ! ( "try io read join futures failure, {}" , e) )
99
+ } ) ?
100
+ . into_iter ( )
101
+ . collect :: < Result < Vec < _ > > > ( ) ?;
75
102
76
103
// Build raw range data from merged range data.
77
104
let mut final_result = Vec :: with_capacity ( raw_ranges. len ( ) ) ;
0 commit comments