Skip to content

Commit

Permalink
Optimise read planning.
Browse files Browse the repository at this point in the history
Previously we had to do do a linear search through the list of
segment reference to find which file to read a given entry from.

This commit introduced a new module `ra_lol` which is a
"list of list" type of ordered data structure that replaces
the use of a plain list.

ra_log keeps data in a list of 64 entry sized "rows" which
subtantially reduces the amount of work needed to find a
given segment ref as we first scan each row to find the
row with the segref in then we can the fixed size row.

Even a server with 4096 segment only need to scan at most
128 to find any given entry.

This commit also fixes a few issues in segref compaction
and changes the type of the segment ref to a {ra_range:range(), filename()}
to work better with the ra_range module.
  • Loading branch information
kjnilsson committed Dec 11, 2024
1 parent c8dbe23 commit 9ed2089
Show file tree
Hide file tree
Showing 8 changed files with 462 additions and 178 deletions.
9 changes: 4 additions & 5 deletions src/ra_log.erl
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,7 @@
-define(WAL_RESEND_TIMEOUT, 5000).

-type ra_meta_key() :: atom().
-type segment_ref() :: {From :: ra_index(), To :: ra_index(),
File :: file:filename_all()}.
-type segment_ref() :: {ra_range:range(), File :: file:filename_all()}.
-type event_body() :: {written, ra_term(), ra:range()} |
{segments, [{ets:tid(), ra:range()}], [segment_ref()]} |
{resend_write, ra_index()} |
Expand Down Expand Up @@ -279,7 +278,7 @@ init(#{uid := UId,
LastSegRefIdx = case SegRefs of
[] ->
-1;
[{_, L, _} | _] ->
[{{_, L}, _} | _] ->
L
end,
LastWrittenIdx = case ra_log_wal:last_writer_seq(Wal, UId) of
Expand Down Expand Up @@ -969,7 +968,7 @@ should_snapshot(snapshot, Idx,
% We should take a snapshot if the new snapshot index would allow us
% to discard any segments or if the we've handled enough commands
% since the last snapshot.
CanFreeSegments = lists:any(fun({_, To, _}) -> To =< Idx end,
CanFreeSegments = lists:any(fun({{_, To}, _}) -> To =< Idx end,
ra_log_reader:segment_refs(Reader)),
CanFreeSegments orelse Idx > SnapLimit;
should_snapshot(checkpoint, Idx,
Expand Down Expand Up @@ -1331,7 +1330,7 @@ recover_ranges(UId, MtRange, SegWriter) ->
[SegRef | Acc]
end
end, [], SegFiles),
SegRanges = [{F, L} || {F, L, _} <- SegRefs],
SegRanges = [Range || {Range, _} <- SegRefs],
Ranges = [MtRange | SegRanges],
{pick_range(Ranges, undefined), SegRefs}.

Expand Down
Loading

0 comments on commit 9ed2089

Please sign in to comment.