@@ -2723,31 +2723,40 @@ open(File, Options) ->
27232723 throw_missing (file :open (File , Options )).
27242724
27252725chunk_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
27522761validate_crc (ChunkId , Crc , IOData ) ->
27532762 case erlang :crc32 (IOData ) of
0 commit comments