@@ -38,6 +38,7 @@ all_tests() ->
3838 subbatch ,
3939 subbatch_compressed ,
4040 iterator_read_chunk ,
41+ iterator_read_chunk_with_read_ahead ,
4142 iterator_read_chunk_mixed_sizes_with_credit ,
4243 read_chunk_parsed ,
4344 read_chunk_parsed_2 ,
@@ -344,14 +345,16 @@ iterator_read_chunk(Config) ->
344345 EntriesRev = [Batch ,
345346 <<" ho" >>,
346347 {<<" filter" >>, <<" hi" >>}],
347- {ChId , _S1 } = write_committed (EntriesRev , S0 ),
348- {ok , _H , I0 , _R2 } = osiris_log :chunk_iterator (R1 ),
348+ {ChId , S1 } = write_committed (EntriesRev , S0 ),
349+ {ok , _H , I0 , R2 } = osiris_log :chunk_iterator (R1 ),
349350 HoOffs = ChId + 1 ,
350351 BatchOffs = ChId + 2 ,
351352 {{ChId , <<" hi" >>}, I1 } = osiris_log :iterator_next (I0 ),
352353 {{HoOffs , <<" ho" >>}, I2 } = osiris_log :iterator_next (I1 ),
353354 {{BatchOffs , Batch }, I } = osiris_log :iterator_next (I2 ),
354355 ? assertMatch (end_of_chunk , osiris_log :iterator_next (I )),
356+ osiris_log :close (R2 ),
357+ osiris_log :close (S1 ),
355358 ok .
356359
357360iterator_read_chunk_mixed_sizes_with_credit (Config ) ->
@@ -365,16 +368,79 @@ iterator_read_chunk_mixed_sizes_with_credit(Config) ->
365368 EntriesRev = [Big ,
366369 <<" ho" >>,
367370 {<<" filter" >>, <<" hi" >>}],
368- {ChId , _S1 } = write_committed (EntriesRev , S0 ),
371+ {ChId , S1 } = write_committed (EntriesRev , S0 ),
369372 % % this is a less than ideal case where we have one large and two very
370- % % small entries inthe same batch. The read ahead only
371- {ok , _H , I0 , _R2 } = osiris_log :chunk_iterator (R1 , 2 ),
373+ % % small entries in the same batch. We read ahead only the 2 first entries.
374+ {ok , _H , I0 , R2 } = osiris_log :chunk_iterator (R1 , 2 ),
372375 HoOffs = ChId + 1 ,
373376 BigOffs = ChId + 2 ,
374377 {{ChId , <<" hi" >>}, I1 } = osiris_log :iterator_next (I0 ),
375378 {{HoOffs , <<" ho" >>}, I2 } = osiris_log :iterator_next (I1 ),
376379 {{BigOffs , Big }, I } = osiris_log :iterator_next (I2 ),
377380 ? assertMatch (end_of_chunk , osiris_log :iterator_next (I )),
381+ osiris_log :close (R2 ),
382+ osiris_log :close (S1 ),
383+ ok .
384+
385+ iterator_read_chunk_with_read_ahead (Config ) ->
386+ % % the test makes sure reading ahead on header reading does not break
387+ % % the iterator
388+ RAL = 4096 , % % read ahead limit
389+ Conf = ? config (osiris_conf , Config ),
390+ W = osiris_log :init (Conf ),
391+ Shared = osiris_log :get_shared (W ),
392+ RConf = Conf #{shared => Shared },
393+ {ok , R } = osiris_log :init_offset_reader (0 , RConf ),
394+ Tests =
395+ [
396+ fun (#{w := W0 , r := R0 }) ->
397+ % % first chunk, there won't be any data size hints in the reader
398+ EntriesRev = [<<" hi" >>, <<" ho" >>],
399+ {_ , W1 } = write_committed (EntriesRev , W0 ),
400+ {ok , H , I0 , R1 } = osiris_log :chunk_iterator (R0 ),
401+ {{_ , <<" ho" >>}, I1 } = osiris_log :iterator_next (I0 ),
402+ {{_ , <<" hi" >>}, I2 } = osiris_log :iterator_next (I1 ),
403+ ? assertMatch (end_of_chunk , osiris_log :iterator_next (I2 )),
404+ {H , W1 , R1 }
405+ end ,
406+ fun (#{w := W0 , r := R0 }) ->
407+ % % this one will be read ahead
408+ EntriesRev = [<<" foo" >>, <<" bar" >>],
409+ {_ , W1 } = write_committed (EntriesRev , W0 ),
410+ {ok , H , I0 , R1 } = osiris_log :chunk_iterator (R0 ),
411+ {{_ , <<" bar" >>}, I1 } = osiris_log :iterator_next (I0 ),
412+ {{_ , <<" foo" >>}, I2 } = osiris_log :iterator_next (I1 ),
413+ ? assertMatch (end_of_chunk , osiris_log :iterator_next (I2 )),
414+ {H , W1 , R1 }
415+ end ,
416+ fun (#{w := W0 , r := R0 }) ->
417+ % % this one will be read ahead
418+ E1 = rand :bytes (RAL - 100 ),
419+ EntriesRev = [E1 , <<" aaa" >>],
420+ {_ , W1 } = write_committed (EntriesRev , W0 ),
421+ {ok , H , I0 , R1 } = osiris_log :chunk_iterator (R0 ),
422+ {{_ , <<" aaa" >>}, I1 } = osiris_log :iterator_next (I0 ),
423+ {{_ , E1 }, I2 } = osiris_log :iterator_next (I1 ),
424+ ? assertMatch (end_of_chunk , osiris_log :iterator_next (I2 )),
425+ {H , W1 , R1 }
426+ end ,
427+ fun (#{w := W0 , r := R0 }) ->
428+ % % this one is too big to be read ahead
429+ E1 = rand :bytes (RAL * 2 ),
430+ EntriesRev = [E1 , <<" aaa" >>],
431+ {_ , W1 } = write_committed (EntriesRev , W0 ),
432+ {ok , H , I0 , R1 } = osiris_log :chunk_iterator (R0 ),
433+ {{_ , <<" aaa" >>}, I1 } = osiris_log :iterator_next (I0 ),
434+ {{_ , E1 }, I2 } = osiris_log :iterator_next (I1 ),
435+ ? assertMatch (end_of_chunk , osiris_log :iterator_next (I2 )),
436+ {H , W1 , R1 }
437+ end
438+ ],
439+
440+ #{w := Wr1 , r := Rd1 } = run_read_ahead_tests (Tests , offset ,
441+ ? DEFAULT_FILTER_SIZE , W , R ),
442+ osiris_log :close (Rd1 ),
443+ osiris_log :close (Wr1 ),
378444 ok .
379445
380446read_chunk_parsed (Config ) ->
0 commit comments