3939
4040-define (SYMLINK_KEEPFOR_S , 60 ).
4141
42+ % % type for configuring automatic major compaction strategies
43+ -type major_compaction_strategy () :: manual |
44+ {num_minors , pos_integer ()}.
45+
4246-type compaction_conf () :: #{max_count => non_neg_integer (),
43- max_size => non_neg_integer ()}.
47+ max_size => non_neg_integer (),
48+ major_strategy => major_compaction_strategy ()}.
49+ % % hardly every used anymore, the sequential access pattern is only activated
50+ % % during recovery
4451-type access_pattern () :: sequential | random .
4552% % holds static or rarely changing fields
4653-record (cfg , {uid :: ra_uid (),
5865 segment_refs :: ra_lol :state (),
5966 open_segments :: ra_flru :state (),
6067 compaction :: undefined | major | minor ,
61- next_compaction :: undefined | major | minor
68+ minor_compaction_count = 0 :: non_neg_integer ()
6269 }).
6370
6471-record (compaction_result ,
7481-export_type ([
7582 state / 0 ,
7683 read_plan / 0 ,
77- read_plan_options / 0
84+ read_plan_options / 0 ,
85+ major_compaction_strategy / 0
7886 ]).
7987
8088% % PUBLIC
8593 map (),
8694 unicode :chardata ()) -> state ().
8795init (UId , Dir , MaxOpen , AccessPattern , SegRefs0 , Counter , CompConf , LogId )
88- when is_binary (UId ) ->
96+ when is_binary (UId ) andalso
97+ is_map (CompConf ) ->
8998 Cfg = # cfg {uid = UId ,
9099 log_id = LogId ,
91100 counter = Counter ,
@@ -173,27 +182,42 @@ update_segments(NewSegmentRefs, #?STATE{open_segments = Open0,
173182-spec schedule_compaction (minor | major , ra :index (),
174183 ra_seq :state (), state ()) ->
175184 {state (), [ra_server :effect ()]}.
185+ schedule_compaction (minor , SnapIdx , LiveIndexes ,
186+ #? MODULE {cfg =
187+ # cfg {compaction_conf =
188+ #{major_strategy :=
189+ {num_minors , NumMinors }}},
190+ minor_compaction_count = MinorCount } = State )
191+ when MinorCount >= NumMinors ->
192+ % % promote to major compaction
193+ schedule_compaction (major , SnapIdx , LiveIndexes , State );
176194schedule_compaction (Type , SnapIdx , LiveIndexes ,
177195 #? MODULE {cfg = # cfg {log_id = LogId ,
178196 compaction_conf = CompConf ,
179197 directory = Dir } = Cfg ,
198+ minor_compaction_count = MinorCompCnt ,
180199 compaction = undefined } = State ) ->
181200 case compactable_segrefs (SnapIdx , State ) of
182201 [] ->
183202 {State , []};
184203 SegRefs when LiveIndexes == [] ->
204+
185205 % % if LiveIndexes is [] we can just delete all compactable
186206 % % segment refs
187207 Unreferenced = [F || {F , _ } <- SegRefs ],
208+ ok = incr_counter (Cfg , ? C_RA_LOG_COMPACTIONS_MINOR_COUNT , 1 ),
188209 Result = # compaction_result {unreferenced = Unreferenced },
189- {State #? MODULE {compaction = minor },
210+ {State #? MODULE {compaction = minor ,
211+ minor_compaction_count = MinorCompCnt + 1 },
190212 [{next_event ,
191213 {ra_log_event , {compaction_result , Result }}}]};
192214 SegRefs when Type == minor ->
193- % % TODO evaluate if minor compactions are fast enough to run
215+ % % TODO: evaluate if minor compactions are fast enough to run
194216 % % in server process
217+ ok = incr_counter (Cfg , ? C_RA_LOG_COMPACTIONS_MINOR_COUNT , 1 ),
195218 Result = minor_compaction (SegRefs , LiveIndexes ),
196- {State #? MODULE {compaction = minor },
219+ {State #? MODULE {compaction = minor ,
220+ minor_compaction_count = MinorCompCnt + 1 },
197221 [{next_event ,
198222 {ra_log_event , {compaction_result , Result }}}]};
199223 SegRefs ->
@@ -213,7 +237,8 @@ schedule_compaction(Type, SnapIdx, LiveIndexes,
213237 ok
214238 end ,
215239
216- {State #? MODULE {compaction = major },
240+ {State #? MODULE {compaction = major ,
241+ minor_compaction_count = 0 },
217242 [{bg_work , Fun ,
218243 fun (Err ) ->
219244 % % send an empty compaction result to ensure the
@@ -385,9 +410,11 @@ fetch_term(Idx, #?STATE{cfg = #cfg{} = Cfg} = State0) ->
385410
386411- spec info (state ()) -> map ().
387412info (#? STATE {cfg = # cfg {} = _Cfg ,
413+ minor_compaction_count = MinorCount ,
388414 open_segments = Open } = State ) ->
389415 #{max_size => ra_flru :max_size (Open ),
390- num_segments => segment_ref_count (State )}.
416+ num_segments => segment_ref_count (State ),
417+ minor_compactions_count => MinorCount }.
391418
392419- spec purge_symlinks (file :filename_all (),
393420 OlderThanSec :: non_neg_integer ()) -> ok .
0 commit comments