@@ -1890,24 +1890,23 @@ read_header_ahead_offset_reader(Config) ->
18901890 % % the messages are large enough to be larger than the default
18911891 % % filter size which is always read ahead (16 bytes)
18921892 {_ , W1 } = write_committed ([<<" hiiiiiiiii" >>, <<" hooooooo" >>], W0 ),
1893- ct :pal (" R0 ~p " , [R0 ]),
18941893 {ok , H , Content , R1 } = osiris_log :read_header0 (R0 ),
18951894 ? assertEqual (undefined , Content ),
18961895 {H , W1 , R1 }
18971896 end ,
1898- fun (#{w := W0 , r := R0 }) ->
1897+ fun (#{w := W0 , r := R0 , fsize : = FSize }) ->
18991898 % % previous chunk too large to read ahead
1900- R1 = osiris_log :last_data_size (R0 , RAL * 2 ),
1899+ R1 = osiris_log :read_ahead_hints (R0 , RAL * 2 , FSize ),
19011900 {_ , W1 } = write_committed ([<<" hiiiiiiiii" >>, <<" hooooooo" >>], W0 ),
19021901 {ok , H , Content , R2 } = osiris_log :read_header0 (R1 ),
19031902 ? assertEqual (undefined , Content ),
19041903 {H , W1 , R2 }
19051904 end ,
1906- fun (#{w := W0 , r := R0 }) ->
1905+ fun (#{w := W0 , r := R0 , fsize : = FSize }) ->
19071906 % % trigger reading ahead by setting a small value for the
19081907 % % last chunk read.
19091908 % % this setting stays the same for the rest of the test
1910- R1 = osiris_log :last_data_size (R0 , 1 ),
1909+ R1 = osiris_log :read_ahead_hints (R0 , 1 , FSize ),
19111910 Entries = [<<" foo" >>, <<" bar" >>],
19121911 {_ , W1 } = write_committed (Entries , W0 ),
19131912 {ok , H , Content , R2 } = osiris_log :read_header0 (R1 ),
@@ -1941,10 +1940,13 @@ read_header_ahead_offset_reader(Config) ->
19411940 {H , W1 , R1 }
19421941 end ,
19431942 fun (#{w := W0 , r := R0 }) ->
1944- Entries1 = [binary :copy (<<" a" >>, 16 )],
1943+ Entries1 = [binary :copy (<<" a" >>, 2000 )],
19451944 {_ , W1 } = write_committed (Entries1 , W0 ),
1946- Entries2 = [binary :copy (<<" b" >>, 32 )],
1945+ Entries2 = [binary :copy (<<" b" >>, 2000 )],
19471946 {_ , W2 } = write_committed (Entries2 , W1 ),
1947+ % % this one is too big to be read ahead fully
1948+ Entries3 = [binary :copy (<<" c" >>, 5000 )],
1949+ {_ , W3 } = write_committed (Entries3 , W2 ),
19481950
19491951 {ok , H1 , Content1 , R1 } = osiris_log :read_header0 (R0 ),
19501952 [_ , _ , D1 , _ ] = fake_chunk (Entries1 , ? LINE , 1 , 100 ),
@@ -1953,7 +1955,11 @@ read_header_ahead_offset_reader(Config) ->
19531955 {ok , H2 , Content2 , R2 } = osiris_log :read_header0 (update_read (H1 , R1 )),
19541956 [_ , _ , D2 , _ ] = fake_chunk (Entries2 , ? LINE , 1 , 100 ),
19551957 ? assertEqual (iolist_to_binary (D2 ), Content2 ),
1956- {H2 , W2 , R2 }
1958+
1959+ {ok , H3 , Content3 , R3 } = osiris_log :read_header0 (update_read (H2 , R2 )),
1960+ ? assertEqual (undefined , Content3 ),
1961+
1962+ {H3 , W3 , R3 }
19571963 end
19581964 ],
19591965
@@ -1972,7 +1978,7 @@ read_header_ahead_offset_reader(Config) ->
19721978 FSize , Wr0 , Rd0 ),
19731979 osiris_log :close (Rd1 ),
19741980 osiris_log :close (Wr1 )
1975- end , [{FSize , RType } || FSize <- FilterSizes , RType <- [offset , data ]]),
1981+ end , [{FSize , RType } || FSize <- FilterSizes , RType <- [data , offset ]]),
19761982 ok .
19771983
19781984read_header_ahead_offset_reader_filter (Config ) ->
@@ -1992,30 +1998,85 @@ read_header_ahead_offset_reader_filter(Config) ->
19921998 Shared = osiris_log :get_shared (Wr0 ),
19931999 Conf = Conf1 #{shared => Shared },
19942000 {ok , Rd0 } = osiris_log :init_offset_reader (first , Conf ),
1995- Rd1 = osiris_log :last_data_size (Rd0 , 1 ),
1996- % % we always read ahead the default filter size.
1997- % % with a larger-than-default filter, we must consider
1998- % % the extra bytes that belong to the filter,
1999- % % that is (actual filter size) - (default filter size)
2000- % % this reduces the max entry size we can read ahead
2001- MES = MaxEntrySize - (FSize - DFS ),
2001+ % % we start by using the default filter size in the read ahead hints
2002+ Rd1 = osiris_log :read_ahead_hints (Rd0 , 1 , DFS ),
2003+ % % compute the max entry size
2004+ % % (meaning we don't read ahead enough above this entry size)
2005+ % % first we don't know the actual filter size in the stream,
2006+ % % so we assume the default filter size
2007+ % % this "reduces" the max size of data we can read in the case
2008+ % % of a larger-than-default filter size, because of the extra
2009+ % % bytes that belong to the filter
2010+ MES1 = MaxEntrySize - (FSize - DFS ),
2011+ % % then the max entry becomes accurate, whatever the actual filter size
2012+ MES2 = MaxEntrySize ,
20022013
20032014 Tests =
20042015 [
20052016 fun (#{w := W0 , r := R0 }) ->
2006- % % chunk with a non-empty filter
20072017 % % data do not fit in the read ahead
2008- EData = binary :copy (<<" a" >>, MES + 1 ),
2018+ EData = binary :copy (<<" a" >>, MES1 + 1 ),
2019+ Entries = [{<<" banana" >>, EData }],
2020+ {_ , W1 } = write_committed (Entries , W0 ),
2021+ {ok , H , Content , R1 } = osiris_log :read_header0 (R0 ),
2022+ ? assertEqual (undefined , Content ),
2023+ {H , W1 , R1 }
2024+ end ,
2025+ fun (#{w := W0 , r := R0 }) ->
2026+ % % data exactly fits in the read ahead
2027+ EData = binary :copy (<<" a" >>, MES1 ),
2028+ Entries = [{<<" banana" >>, EData }],
2029+ {_ , W1 } = write_committed (Entries , W0 ),
2030+ {ok , H , Content , R1 } = osiris_log :read_header0 (R0 ),
2031+ [_ , _ , D , _ ] = fake_chunk (Entries , ? LINE , 1 , 100 ),
2032+ ? assertEqual (iolist_to_binary (D ), Content ),
2033+ {H , W1 , R1 }
2034+ end ,
2035+ fun (#{w := W0 , r := R }) ->
2036+ % % assume we are now using the correct filter size
2037+ % % (this setting stays the same for the next tests)
2038+ R0 = osiris_log :read_ahead_hints (R , 1 , FSize ),
2039+ % % data just bigger than the first limit
2040+ EData = binary :copy (<<" a" >>, MES1 + 1 ),
2041+ Entries = [{<<" banana" >>, EData }],
2042+ {_ , W1 } = write_committed (Entries , W0 ),
2043+ {ok , H , Content , R1 } = osiris_log :read_header0 (R0 ),
2044+ case FSize =:= DFS of
2045+ true ->
2046+ % % default filter size: still does not fit
2047+ ? assertEqual (undefined , Content );
2048+ false ->
2049+ % % with the correct filter size, we now read
2050+ % % a bit further than with the first limit
2051+ [_ , _ , D , _ ] = fake_chunk (Entries , ? LINE , 1 , 100 ),
2052+ ? assertEqual (iolist_to_binary (D ), Content )
2053+ end ,
2054+ {H , W1 , R1 }
2055+ end ,
2056+ fun (#{w := W0 , r := R0 }) ->
2057+ % % data exactly fits in the read ahead
2058+ EData = binary :copy (<<" a" >>, MES1 ),
2059+ Entries = [{<<" banana" >>, EData }],
2060+ {_ , W1 } = write_committed (Entries , W0 ),
2061+ {ok , H , Content , R1 } = osiris_log :read_header0 (R0 ),
2062+ [_ , _ , D , _ ] = fake_chunk (Entries , ? LINE , 1 , 100 ),
2063+ ? assertEqual (iolist_to_binary (D ), Content ),
2064+ {H , W1 , R1 }
2065+ end ,
2066+ fun (#{w := W0 , r := R0 }) ->
2067+ % % we use the "new" max entry size
2068+ % % data do not fit in the read ahead
2069+ EData = binary :copy (<<" a" >>, MES2 + 1 ),
20092070 Entries = [{<<" banana" >>, EData }],
20102071 {_ , W1 } = write_committed (Entries , W0 ),
20112072 {ok , H , Content , R1 } = osiris_log :read_header0 (R0 ),
20122073 ? assertEqual (undefined , Content ),
20132074 {H , W1 , R1 }
20142075 end ,
20152076 fun (#{w := W0 , r := R0 }) ->
2016- % % chunk with a non-empty filter
2077+ % % we use the "new" max entry size
20172078 % % data exactly fits in the read ahead
2018- EData = binary :copy (<<" a" >>, MES ),
2079+ EData = binary :copy (<<" a" >>, MES2 ),
20192080 Entries = [{<<" banana" >>, EData }],
20202081 {_ , W1 } = write_committed (Entries , W0 ),
20212082 {ok , H , Content , R1 } = osiris_log :read_header0 (R0 ),
0 commit comments