5252 fd :: option (file :io_device ()),
5353 index_size :: pos_integer (),
5454 access_pattern :: sequential | random ,
55+ file_advise = normal :: posix_file_advise (),
5556 mode = append :: read | append ,
5657 compute_checksums = true :: boolean ()}).
5758
7071 cache :: undefined | {non_neg_integer (), non_neg_integer (), binary ()}
7172 }).
7273
74+ -type posix_file_advise () :: 'normal' | 'sequential' | 'random'
75+ | 'no_reuse' | 'will_need' | 'dont_need' .
76+
7377-type ra_log_segment_options () :: #{max_count => non_neg_integer (),
7478 max_pending => non_neg_integer (),
7579 compute_checksums => boolean (),
7680 mode => append | read ,
77- access_pattern => sequential | random }.
81+ access_pattern => sequential | random ,
82+ file_advise => posix_file_advise ()}.
7883-opaque state () :: # state {}.
7984
8085-export_type ([state / 0 ,
86+ posix_file_advise / 0 ,
8187 ra_log_segment_options / 0 ]).
8288
8389-spec open (Filename :: file :filename_all ()) ->
@@ -116,6 +122,15 @@ open(Filename, Options) ->
116122
117123process_file (true , Mode , Filename , Fd , Options ) ->
118124 AccessPattern = maps :get (access_pattern , Options , random ),
125+ FileAdvise = maps :get (file_advise , Options , normal ),
126+ if FileAdvise == random andalso
127+ Mode == read ->
128+ Offs = maps :get (max_count , Options , ? SEGMENT_MAX_ENTRIES ) * ? INDEX_RECORD_SIZE_V2 ,
129+ _ = file :advise (Fd , Offs , 0 , random ),
130+ ok ;
131+ true ->
132+ ok
133+ end ,
119134 case read_header (Fd ) of
120135 {ok , Version , MaxCount } ->
121136 MaxPending = maps :get (max_pending , Options , ? SEGMENT_MAX_PENDING ),
@@ -124,7 +139,6 @@ process_file(true, Mode, Filename, Fd, Options) ->
124139 {NumIndexRecords , DataOffset , Range , Index } =
125140 recover_index (Fd , Version , MaxCount ),
126141 IndexOffset = ? HEADER_SIZE + NumIndexRecords * IndexRecordSize ,
127- Mode = maps :get (mode , Options , append ),
128142 ComputeChecksums = maps :get (compute_checksums , Options , true ),
129143 {ok , # state {cfg = # cfg {version = Version ,
130144 max_count = MaxCount ,
@@ -133,6 +147,7 @@ process_file(true, Mode, Filename, Fd, Options) ->
133147 mode = Mode ,
134148 index_size = IndexSize ,
135149 access_pattern = AccessPattern ,
150+ file_advise = FileAdvise ,
136151 compute_checksums = ComputeChecksums ,
137152 fd = Fd },
138153 data_start = ? HEADER_SIZE + IndexSize ,
@@ -156,6 +171,7 @@ process_file(false, Mode, Filename, Fd, Options) ->
156171 ComputeChecksums = maps :get (compute_checksums , Options , true ),
157172 IndexSize = MaxCount * ? INDEX_RECORD_SIZE_V2 ,
158173 ok = write_header (MaxCount , Fd ),
174+ FileAdvise = maps :get (file_advise , Options , dont_need ),
159175 {ok , # state {cfg = # cfg {version = ? VERSION ,
160176 max_count = MaxCount ,
161177 max_pending = MaxPending ,
@@ -164,6 +180,7 @@ process_file(false, Mode, Filename, Fd, Options) ->
164180 index_size = IndexSize ,
165181 fd = Fd ,
166182 compute_checksums = ComputeChecksums ,
183+ file_advise = FileAdvise ,
167184 access_pattern = random },
168185 index_write_offset = ? HEADER_SIZE ,
169186 index_offset = ? HEADER_SIZE ,
@@ -422,13 +439,15 @@ is_same_as(#state{cfg = #cfg{filename = Fn0}}, Fn) ->
422439 is_same_filename_all (Fn0 , Fn ).
423440
424441-spec close (state ()) -> ok .
425- close (# state {cfg = # cfg {fd = Fd , mode = append }} = State ) ->
442+ close (# state {cfg = # cfg {fd = Fd ,
443+ mode = append ,
444+ file_advise = FileAdvise }} = State ) ->
426445 % close needs to be defensive and idempotent so we ignore the return
427446 % values here
428447 _ = sync (State ),
429448 case is_full (State ) of
430449 true ->
431- _ = file :advise (Fd , 0 , 0 , dont_need );
450+ _ = file :advise (Fd , 0 , 0 , FileAdvise );
432451 false ->
433452 ok
434453 end ,
@@ -675,3 +694,4 @@ cache_length_test() ->
675694
676695-endif .
677696
697+
0 commit comments