diff options
| author | Simon MacMullen <simon@rabbitmq.com> | 2015-01-15 17:51:24 +0000 |
|---|---|---|
| committer | Simon MacMullen <simon@rabbitmq.com> | 2015-01-15 17:51:24 +0000 |
| commit | 29598b5481feef02c0fc2dd4e3ec84f5dbd9b33f (patch) | |
| tree | 1fd78702d621d0237b6fad48ce360c8ca6246585 /src | |
| parent | 7346bfbabed632077e8c1f6974811b9b541bfc72 (diff) | |
| download | rabbitmq-server-git-29598b5481feef02c0fc2dd4e3ec84f5dbd9b33f.tar.gz | |
Allow seeking backwards through the read buffer.
Diffstat (limited to 'src')
| -rw-r--r-- | src/file_handle_cache.erl | 85 |
1 files changed, 46 insertions, 39 deletions
diff --git a/src/file_handle_cache.erl b/src/file_handle_cache.erl index 6b1502d32a..5a916c75bc 100644 --- a/src/file_handle_cache.erl +++ b/src/file_handle_cache.erl @@ -179,7 +179,8 @@ write_buffer_size_limit, write_buffer, read_buffer, - read_buffer_size, + read_buffer_pos, + read_buffer_rem, %% Num of bytes from pos to end read_buffer_size_limit, at_eof, path, @@ -338,36 +339,40 @@ read(Ref, Count) -> [Ref], keep, fun ([#handle { is_read = false }]) -> {error, not_open_for_reading}; - ([Handle = #handle{read_buffer = Buf, - read_buffer_size = BufSz, - offset = Offset}]) when BufSz >= Count -> - <<Hd:Count/binary, Tl/binary>> = Buf, - {{ok, Hd}, [Handle#handle{offset = Offset + Count, - read_buffer = Tl, - read_buffer_size = BufSz - Count}]}; + ([Handle = #handle{read_buffer = Buf, + read_buffer_pos = BufPos, + read_buffer_rem = BufRem, + offset = Offset}]) when BufRem >= Count -> + <<_:BufPos/binary, Res:Count/binary, _/binary>> = Buf, + {{ok, Res}, [Handle#handle{offset = Offset + Count, + read_buffer_pos = BufPos + Count, + read_buffer_rem = BufRem - Count}]}; ([Handle = #handle{read_buffer = Buf, - read_buffer_size = BufSz, + read_buffer_pos = BufPos, + read_buffer_rem = BufRem, read_buffer_size_limit = BufSzLimit, hdl = Hdl, offset = Offset}]) -> - WantedCount = Count - BufSz, + WantedCount = Count - BufRem, case prim_file_read(Hdl, lists:max([BufSzLimit, WantedCount])) of {ok, Data} -> + <<_:BufPos/binary, BufTl/binary>> = Buf, ReadCount = size(Data), case ReadCount < WantedCount of true -> - OffSet1 = Offset + BufSz + ReadCount, - {{ok, <<Buf/binary, Data/binary>>}, + OffSet1 = Offset + BufRem + ReadCount, + {{ok, <<BufTl/binary, Data/binary>>}, [reset_read_buffer( Handle#handle{offset = OffSet1})]}; false -> - <<Hd:WantedCount/binary, Tl/binary>> = Data, - OffSet1 = Offset + BufSz + WantedCount, - BufSz1 = ReadCount - WantedCount, - {{ok, <<Buf/binary, Hd/binary>>}, - [Handle#handle{offset = OffSet1, - read_buffer = Tl, - read_buffer_size = BufSz1}]} + <<Hd:WantedCount/binary, _/binary>> = Data, + OffSet1 = Offset + BufRem + WantedCount, + BufRem1 = ReadCount - WantedCount, + {{ok, <<BufTl/binary, Hd/binary>>}, + [Handle#handle{offset = OffSet1, + read_buffer = Data, + read_buffer_pos = WantedCount, + read_buffer_rem = BufRem1}]} end; eof -> {eof, [Handle #handle { at_eof = true }]}; @@ -781,9 +786,10 @@ new_closed_handle(Path, Mode, Options) -> write_buffer_size = 0, write_buffer_size_limit = WriteBufferSize, write_buffer = [], - read_buffer_size = 0, - read_buffer_size_limit = ReadBufferSize, read_buffer = <<>>, + read_buffer_pos = 0, + read_buffer_rem = 0, + read_buffer_size_limit = ReadBufferSize, at_eof = false, path = Path, mode = Mode, @@ -844,23 +850,23 @@ hard_close(Handle) -> Result end. -maybe_seek(NewOffset, Handle = #handle{hdl = Hdl, - offset = Offset, - read_buffer = Buf, - read_buffer_size = BufSz, - at_eof = AtEoF}) -> - {AtEoF1, NeedsSeek} = needs_seek(AtEoF, Offset, NewOffset), +maybe_seek(New, Handle = #handle{hdl = Hdl, + offset = Old, + read_buffer_pos = BufPos, + read_buffer_rem = BufRem, + at_eof = AtEoF}) -> + {AtEoF1, NeedsSeek} = needs_seek(AtEoF, Old, New), case NeedsSeek of - true when is_number(NewOffset) andalso - NewOffset >= Offset andalso NewOffset =< BufSz + Offset -> - Diff = NewOffset - Offset, - <<_:Diff/binary, Rest/binary>> = Buf, - {{ok, NewOffset}, Handle#handle{offset = NewOffset, - at_eof = AtEoF1, - read_buffer = Rest, - read_buffer_size = BufSz - Diff}}; + true when is_number(New) andalso + ((New >= Old andalso New =< BufRem + Old) + orelse (New < Old andalso Old - New =< BufPos)) -> + Diff = New - Old, + {{ok, New}, Handle#handle{offset = New, + at_eof = AtEoF1, + read_buffer_pos = BufPos + Diff, + read_buffer_rem = BufRem - Diff}}; true -> - case prim_file_position(Hdl, NewOffset) of + case prim_file_position(Hdl, New) of {ok, Offset1} = Result -> {Result, reset_read_buffer(Handle#handle{offset = Offset1, at_eof = AtEoF1})}; @@ -868,7 +874,7 @@ maybe_seek(NewOffset, Handle = #handle{hdl = Hdl, {Error, Handle} end; false -> - {{ok, Offset}, Handle} + {{ok, Old}, Handle} end. needs_seek( AtEoF, _CurOffset, cur ) -> {AtEoF, false}; @@ -909,8 +915,9 @@ write_buffer(Handle = #handle { hdl = Hdl, offset = Offset, end. reset_read_buffer(Handle) -> - Handle#handle{read_buffer = <<>>, - read_buffer_size = 0}. + Handle#handle{read_buffer = <<>>, + read_buffer_pos = 0, + read_buffer_rem = 0}. infos(Items, State) -> [{Item, i(Item, State)} || Item <- Items]. |
