Skip to content

Commit 927efa4

Browse files
authored
Merge pull request #195 from rabbitmq/md/timestamp-skip-search
osiris_log: Use index skip search for timestamp offset specs
2 parents 7376fba + 6ccb78b commit 927efa4

File tree

1 file changed

+32
-23
lines changed

1 file changed

+32
-23
lines changed

src/osiris_log.erl

Lines changed: 32 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2723,31 +2723,40 @@ open(File, Options) ->
27232723
throw_missing(file:open(File, Options)).
27242724

27252725
chunk_location_for_timestamp(Idx, Ts) ->
2726-
%% TODO: optimise using skip search approach
2727-
Fd = open_index_read(Idx),
2728-
%% scan index file for nearest timestamp
2729-
{ChunkId, _Timestamp, _Epoch, FilePos} = timestamp_idx_scan(Fd, Ts),
2726+
{ok, IdxFd} = open(Idx, [read, raw, binary]),
2727+
_ = file:advise(IdxFd, 0, 0, random),
2728+
{Ts, {ChunkId, _Timestamp, _Epoch, FilePos}} =
2729+
idx_skip_search(IdxFd, ?IDX_HEADER_SIZE,
2730+
fun timestamp_search_fun/3,
2731+
{Ts, not_found}),
2732+
ok = file:close(IdxFd),
27302733
{ChunkId, FilePos}.
27312734

2732-
timestamp_idx_scan(Fd, Ts) ->
2733-
case file:read(Fd, ?INDEX_RECORD_SIZE_B) of
2734-
{ok,
2735-
<<ChunkId:64/unsigned,
2736-
Timestamp:64/signed,
2737-
Epoch:64/unsigned,
2738-
FilePos:32/unsigned,
2739-
_ChType:8/unsigned>>} ->
2740-
case Ts =< Timestamp of
2741-
true ->
2742-
ok = file:close(Fd),
2743-
{ChunkId, Timestamp, Epoch, FilePos};
2744-
false ->
2745-
timestamp_idx_scan(Fd, Ts)
2746-
end;
2747-
eof ->
2748-
ok = file:close(Fd),
2749-
eof
2750-
end.
2735+
%% NOTE: this is slightly different than offset_search_fun/3. When searching
2736+
%% for offsets, if the given offset is not a chunk ID then the search returns
2737+
%% the chunk ID less than the given offset. When searching for timestamps,
2738+
%% if the given timestamp is between the timestamp of two chunks, the later
2739+
%% chunk is returned.
2740+
timestamp_search_fun(scan, <<ChunkId:64/unsigned,
2741+
Timestamp:64/signed,
2742+
Epoch:64/unsigned,
2743+
FilePos:32/unsigned,
2744+
_ChType:8/unsigned>>, {Ts, _})
2745+
when Ts =< Timestamp ->
2746+
{return, {Ts, {ChunkId, Timestamp, Epoch, FilePos}}};
2747+
timestamp_search_fun(peek, <<_ChunkId:64/unsigned,
2748+
Timestamp:64/signed,
2749+
_Epoch:64/unsigned,
2750+
_FilePos:32/unsigned,
2751+
_ChType:8/unsigned>>, {Ts, _} = State)
2752+
when Ts =< Timestamp ->
2753+
{scan, State};
2754+
timestamp_search_fun(_Type, <<ChunkId:64/unsigned,
2755+
Timestamp:64/signed,
2756+
Epoch:64/unsigned,
2757+
FilePos:32/unsigned,
2758+
_ChType:8/unsigned>>, {Ts, _}) ->
2759+
{continue, {Ts, {ChunkId, Timestamp, Epoch, FilePos}}}.
27512760

27522761
validate_crc(ChunkId, Crc, IOData) ->
27532762
case erlang:crc32(IOData) of

0 commit comments

Comments
 (0)