Skip to content

Commit 324f02b

Browse files
Sarah Hassanfacebook-github-bot
authored andcommitted
put back get_terms/fold_terms
Reviewed By: hsun324 Differential Revision: D72419076 fbshipit-source-id: 7e84f4f8dcae6216808c94456b40cd13998aba6a
1 parent c86d305 commit 324f02b

File tree

1 file changed

+60
-0
lines changed

1 file changed

+60
-0
lines changed

src/wa_raft_log.erl

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,13 @@
3030
fold/5,
3131
fold/6,
3232

33+
fold_terms/5,
3334

3435
term/2,
3536
get/2,
3637
get/3,
3738
get/4,
39+
get_terms/3,
3840

3941
config/1
4042
]).
@@ -434,6 +436,45 @@ fold_impl(Log, First, Last, SizeLimit, Func, AccIn) ->
434436
{error, Reason}
435437
end.
436438

439+
%% Folds over the terms in the log view of raw entries from the log provider
440+
%% between the provided first and last log indices (inclusive).
441+
%% If there exists a log term between the provided first and last indices then
442+
%% the accumulator function will be called on at least that term.
443+
%% This API provides no validation of the log indices and term passed by the
444+
%% provider to the callback function.
445+
-spec fold_terms(LogOrView :: log() | view(),
446+
First :: log_index(),
447+
Last :: log_index(),
448+
Func :: fun((Index :: log_index(), Term :: log_term(), Acc) -> Acc),
449+
Acc) ->
450+
{ok, Acc} | wa_raft:error().
451+
fold_terms(#log_view{log = Log, first = LogFirst, last = LogLast}, First, Last, Func, Acc) ->
452+
fold_terms_impl(Log, max(First, LogFirst), min(Last, LogLast), Func, Acc);
453+
fold_terms(Log, First, Last, Func, Acc) ->
454+
Provider = provider(Log),
455+
LogFirst = Provider:first_index(Log),
456+
LogLast = Provider:last_index(Log),
457+
fold_terms_impl(Log, max(First, LogFirst), min(Last, LogLast), Func, Acc).
458+
459+
-spec fold_terms_impl(
460+
Log :: log(),
461+
First :: log_index(),
462+
Last :: log_index(),
463+
Func :: fun((Index :: log_index(), Term :: log_term(), Acc) -> Acc),
464+
Acc :: term()
465+
) -> {ok, Acc} | wa_raft:error().
466+
fold_terms_impl(Log, First, Last, Func, AccIn) ->
467+
?RAFT_COUNT('raft.log.fold_terms'),
468+
?RAFT_COUNTV('raft.log.fold_terms.total', Last - First + 1),
469+
Provider = provider(Log),
470+
case Provider:fold_terms(Log, First, Last, Func, AccIn) of
471+
{ok, AccOut} ->
472+
{ok, AccOut};
473+
{error, Reason} ->
474+
?RAFT_COUNT('raft.log.fold_terms.error'),
475+
{error, Reason}
476+
end.
477+
437478
%% Gets the term of entry at the provided log index. When using a log view
438479
%% this function may return 'not_found' even if the underlying log entry still
439480
%% exists if the entry is outside of the log view.
@@ -492,6 +533,25 @@ get(LogOrView, First, CountLimit, SizeLimit) ->
492533
{error, corruption}
493534
end.
494535

536+
-spec get_terms(LogOrView :: log() | view(), First :: log_index(), Limit :: non_neg_integer()) ->
537+
{ok, Terms :: [wa_raft_log:log_term()]} | wa_raft:error().
538+
get_terms(LogOrView, First, Limit) ->
539+
try
540+
fold_terms(LogOrView, First, First + Limit - 1,
541+
fun
542+
(Index, Term, {Index, Acc}) -> {Index + 1, [Term | Acc]};
543+
(_Index, _Term, {ExpectedIndex, _Acc}) -> throw({missing, ExpectedIndex})
544+
end, {First, []})
545+
of
546+
{ok, {_, TermsRev}} -> {ok, lists:reverse(TermsRev)};
547+
{error, Reason} -> {error, Reason}
548+
catch
549+
throw:{missing, Index} ->
550+
?LOG_WARNING("[~p] detected log is missing index ~p during get of ~p ~~ ~p",
551+
[log_name(LogOrView), Index, First, First + Limit - 1], #{domain => [whatsapp, wa_raft]}),
552+
{error, corruption}
553+
end.
554+
495555
-spec config(LogOrView :: log() | view()) -> {ok, Index :: log_index(), Config :: wa_raft_server:config() | undefined} | not_found.
496556
config(#log_view{config_index = undefined}) ->
497557
not_found;

0 commit comments

Comments
 (0)