@@ -250,12 +250,19 @@ impl StripedBlockStream {
250
250
let block_read_len = block_end - block_start;
251
251
252
252
assert_eq ! ( self . block. block_indices( ) . len( ) , self . block. locs. len( ) ) ;
253
- let block_map: HashMap < u8 , & hdfs:: DatanodeInfoProto > = self
253
+ let datanode_infos: Vec < ( & hdfs:: DatanodeInfoProto , & common:: TokenProto ) > = self
254
+ . block
255
+ . locs
256
+ . iter ( )
257
+ . zip ( self . block . block_tokens . iter ( ) )
258
+ . collect ( ) ;
259
+
260
+ let block_map: HashMap < u8 , ( & hdfs:: DatanodeInfoProto , & common:: TokenProto ) > = self
254
261
. block
255
262
. block_indices ( )
256
263
. iter ( )
257
264
. copied ( )
258
- . zip ( self . block . locs . iter ( ) )
265
+ . zip ( datanode_infos . into_iter ( ) )
259
266
. collect ( ) ;
260
267
261
268
let mut stripe_results: Vec < Option < Bytes > > =
@@ -264,10 +271,12 @@ impl StripedBlockStream {
264
271
let mut futures = Vec :: new ( ) ;
265
272
266
273
for index in 0 ..self . ec_schema . data_units as u8 {
274
+ let datanode_info = block_map. get ( & index) ;
267
275
futures. push ( self . read_vertical_stripe (
268
276
& self . ec_schema ,
269
277
index,
270
- block_map. get ( & index) ,
278
+ datanode_info. map ( |( datanode, _) | datanode) ,
279
+ datanode_info. map ( |( _, token) | token) ,
271
280
block_start,
272
281
block_read_len,
273
282
) ) ;
@@ -287,12 +296,13 @@ impl StripedBlockStream {
287
296
let mut parity_unit = 0usize ;
288
297
while blocks_needed > 0 && parity_unit < self . ec_schema . parity_units {
289
298
let block_index = ( self . ec_schema . data_units + parity_unit) as u8 ;
290
- let datanode_info = block_map. get ( & block_index) . unwrap ( ) ;
299
+ let datanode_info = block_map. get ( & block_index) ;
291
300
let result = self
292
301
. read_vertical_stripe (
293
302
& self . ec_schema ,
294
303
block_index,
295
- Some ( datanode_info) ,
304
+ datanode_info. map ( |( datanode, _) | datanode) ,
305
+ datanode_info. map ( |( _, token) | token) ,
296
306
block_start,
297
307
block_read_len,
298
308
)
@@ -337,6 +347,7 @@ impl StripedBlockStream {
337
347
ec_schema : & EcSchema ,
338
348
index : u8 ,
339
349
datanode : Option < & & hdfs:: DatanodeInfoProto > ,
350
+ token : Option < & & common:: TokenProto > ,
340
351
offset : usize ,
341
352
len : usize ,
342
353
) -> Result < Bytes > {
@@ -347,32 +358,32 @@ impl StripedBlockStream {
347
358
return Err ( HdfsError :: InternalError ( "Testing error" . to_string ( ) ) ) ;
348
359
}
349
360
}
361
+ let max_block_offset =
362
+ ec_schema. max_offset ( index as usize , self . block . b . num_bytes ( ) as usize ) ;
350
363
351
- let mut buf = BytesMut :: zeroed ( len) ;
352
- if let Some ( datanode_info) = datanode {
353
- let max_block_offset =
354
- ec_schema. max_offset ( index as usize , self . block . b . num_bytes ( ) as usize ) ;
364
+ let read_len = usize:: min ( len, max_block_offset - offset) ;
355
365
356
- let read_len = usize:: min ( len, max_block_offset - offset) ;
366
+ if read_len == 0 {
367
+ // We're past the end of the file so there's nothign to read, just return a zeroed buffer
368
+ Ok ( BytesMut :: zeroed ( len) . freeze ( ) )
369
+ } else if let Some ( ( datanode_info, token) ) = datanode. zip ( token) {
370
+ let mut buf = BytesMut :: zeroed ( len) ;
357
371
358
372
// Each vertical stripe has a block ID of the original located block ID + block index
359
373
// That was fun to figure out
360
374
let mut block = self . block . b . clone ( ) ;
361
375
block. block_id += index as u64 ;
362
376
363
- // The token of the first block is the main one, then all the rest are in the `block_tokens` list
364
- let token = & self . block . block_tokens [ self
365
- . block
366
- . block_indices ( )
367
- . iter ( )
368
- . position ( |x| * x == index)
369
- . unwrap ( ) ] ;
370
-
371
377
self . read_from_datanode ( & datanode_info. id , & block, token, offset, read_len, & mut buf)
372
378
. await ?;
373
- }
374
379
375
- Ok ( buf. freeze ( ) )
380
+ Ok ( buf. freeze ( ) )
381
+ } else {
382
+ // There should be data to read but we didn't get block info for this index, so this shard is missing
383
+ Err ( HdfsError :: ErasureCodingError (
384
+ "Shard is missing" . to_string ( ) ,
385
+ ) )
386
+ }
376
387
}
377
388
378
389
async fn read_from_datanode (
0 commit comments