blob: 431894a5033fee913f2b94a1fec3219ab0742509 [file] [log] [blame]
% Licensed under the Apache License, Version 2.0 (the "License"); you may not
% use this file except in compliance with the License. You may obtain a copy of
% the License at
%
% http://www.apache.org/licenses/LICENSE-2.0
%
% Unless required by applicable law or agreed to in writing, software
% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
% License for the specific language governing permissions and limitations under
% the License.
-module(couch_bt_engine_stream).
-export([
foldl/3,
seek/2,
write/2,
finalize/1,
to_disk_term/1
]).
foldl({_Fd, []}, _Fun, Acc) ->
Acc;
foldl({Fd, [{Pos, _} | Rest]}, Fun, Acc) ->
foldl({Fd, [Pos | Rest]}, Fun, Acc);
foldl({Fd, [Bin | Rest]}, Fun, Acc) when is_binary(Bin) ->
% We're processing the first bit of data
% after we did a seek for a range fold.
foldl({Fd, Rest}, Fun, Fun(Bin, Acc));
foldl({Fd, [Pos | Rest]}, Fun, Acc) when is_integer(Pos) ->
{ok, Bin} = couch_file:pread_binary(Fd, Pos),
foldl({Fd, Rest}, Fun, Fun(Bin, Acc)).
seek({Fd, [{Pos, Length} | Rest]}, Offset) ->
case Length =< Offset of
true ->
seek({Fd, Rest}, Offset - Length);
false ->
seek({Fd, [Pos | Rest]}, Offset)
end;
seek({Fd, [Pos | Rest]}, Offset) when is_integer(Pos) ->
{ok, Bin} = couch_file:pread_binary(Fd, Pos),
case iolist_size(Bin) =< Offset of
true ->
seek({Fd, Rest}, Offset - size(Bin));
false ->
<<_:Offset/binary, Tail/binary>> = Bin,
{ok, {Fd, [Tail | Rest]}}
end.
write({Fd, Written}, Data) when is_pid(Fd) ->
{ok, Pos, _} = couch_file:append_binary(Fd, Data),
{ok, {Fd, [{Pos, iolist_size(Data)} | Written]}}.
finalize({Fd, Written}) ->
{ok, {Fd, lists:reverse(Written)}}.
to_disk_term({_Fd, Written}) ->
{ok, Written}.