You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@couchdb.apache.org by Jan Lehnardt <ja...@apache.org> on 2010/10/17 21:30:06 UTC

Re: svn commit: r987084 - in /couchdb/trunk/src/couchdb: couch_httpd_db.erl couch_stream.erl

On 19 Aug 2010, at 10:55, rnewson@apache.org wrote:

> Author: rnewson
> Date: Thu Aug 19 08:55:10 2010
> New Revision: 987084
> 
> URL: http://svn.apache.org/viewvc?rev=987084&view=rev
> Log:
> Support Range header for all attachments, even without compaction upgrade. It's just less efficient.

How much "less"?

Cheers
Jan
-- 


> 
> Modified:
>    couchdb/trunk/src/couchdb/couch_httpd_db.erl
>    couchdb/trunk/src/couchdb/couch_stream.erl
> 
> Modified: couchdb/trunk/src/couchdb/couch_httpd_db.erl
> URL: http://svn.apache.org/viewvc/couchdb/trunk/src/couchdb/couch_httpd_db.erl?rev=987084&r1=987083&r2=987084&view=diff
> ==============================================================================
> --- couchdb/trunk/src/couchdb/couch_httpd_db.erl (original)
> +++ couchdb/trunk/src/couchdb/couch_httpd_db.erl Thu Aug 19 08:55:10 2010
> @@ -883,7 +883,8 @@ db_attachment_req(#httpd{method='GET',mo
>         Headers = [
>             {"ETag", Etag},
>             {"Cache-Control", "must-revalidate"},
> -            {"Content-Type", binary_to_list(Type)}
> +            {"Content-Type", binary_to_list(Type)},
> +            {"Accept-Ranges", "bytes"}
>         ] ++ case ReqAcceptsAttEnc of
>         true ->
>             [{"Content-Encoding", atom_to_list(Enc)}];
> @@ -925,22 +926,13 @@ db_attachment_req(#httpd{method='GET',mo
>                     AttFun(Att, fun(Seg, _) -> send_chunk(Resp, Seg) end, {ok, Resp}),
>                     last_chunk(Resp);
>                 _ ->
> -                    #att{data={_,StreamInfo}} = Att, %% layering violation
> -                    SupportsRange = case StreamInfo of
> -                        [{_,_}|_] -> true;
> -                        _ -> false
> -                    end,
>                     Ranges = MochiReq:get(range),
>                     HasSingleRange = case Ranges of
>                         [_] -> true;
>                         _ -> false
>                     end,
> -                    Headers1 = case SupportsRange of
> -                        false ->[{<<"Accept-Ranges">>, <<"none">>}] ++ Headers;
> -                        true -> [{<<"Accept-Ranges">>, <<"bytes">>}] ++ Headers
> -                    end,
>                     if
> -                        Enc == identity andalso SupportsRange == true andalso HasSingleRange == true ->
> +                        Enc == identity andalso HasSingleRange == true ->
>                             [{From, To}] = Ranges,
>                             {From1, To1} = case {From, To} of
>                                 {none, To} ->
> @@ -956,13 +948,13 @@ db_attachment_req(#httpd{method='GET',mo
>                                 true ->
>                                     ok
>                             end,
> -                            Headers2 = [{<<"Content-Range">>,
> +                            Headers1 = [{<<"Content-Range">>,
>                                 ?l2b(io_lib:format("bytes ~B-~B/~B", [From1, To1, Len]))}]
> -                                ++ Headers1,
> -                            {ok, Resp} = start_response_length(Req, 206, Headers2, To1 - From1 + 1),
> +                                ++ Headers,
> +                            {ok, Resp} = start_response_length(Req, 206, Headers1, To1 - From1 + 1),
>                             couch_doc:range_att_foldl(Att, From1, To1 + 1, fun(Seg, _) -> send(Resp, Seg) end, {ok, Resp});
>                         true ->
> -                            {ok, Resp} = start_response_length(Req, 200, Headers1, Len),
> +                            {ok, Resp} = start_response_length(Req, 200, Headers, Len),
>                             AttFun(Att, fun(Seg, _) -> send(Resp, Seg) end, {ok, Resp})
>                     end
>                 end
> 
> Modified: couchdb/trunk/src/couchdb/couch_stream.erl
> URL: http://svn.apache.org/viewvc/couchdb/trunk/src/couchdb/couch_stream.erl?rev=987084&r1=987083&r2=987084&view=diff
> ==============================================================================
> --- couchdb/trunk/src/couchdb/couch_stream.erl (original)
> +++ couchdb/trunk/src/couchdb/couch_stream.erl Thu Aug 19 08:55:10 2010
> @@ -129,6 +129,9 @@ range_foldl(Fd, PosList, From, To, Fun, 
> 
> range_foldl(_Fd, _PosList, _From, To, Off, _Fun, Acc) when Off >= To ->
>     Acc;
> +range_foldl(Fd, [Pos|Rest], From, To, Off, Fun, Acc) when is_integer(Pos) -> % old-style attachment
> +    {ok, Bin} = couch_file:pread_iolist(Fd, Pos),
> +    range_foldl(Fd, [{Pos, iolist_size(Bin)}] ++ Rest, From, To, Off, Fun, Acc);
> range_foldl(Fd, [{_Pos, Size}|Rest], From, To, Off, Fun, Acc) when From > Off + Size ->
>     range_foldl(Fd, Rest, From, To, Off + Size, Fun, Acc);
> range_foldl(Fd, [{Pos, Size}|Rest], From, To, Off, Fun, Acc) ->
> 
> 


Re: svn commit: r987084 - in /couchdb/trunk/src/couchdb: couch_httpd_db.erl couch_stream.erl

Posted by Robert Newson <ro...@gmail.com>.
In order to honor any range request when the lengths of each fragment
are not known, all fragments up to the start of the range must be read
and discarded (fragments after the range are not read). So "less
efficient" means that the worst case is it reads the entire
attachment. It's not less efficient than it was before this work.

B.

On Sun, Oct 17, 2010 at 3:30 PM, Jan Lehnardt <ja...@apache.org> wrote:
>
> On 19 Aug 2010, at 10:55, rnewson@apache.org wrote:
>
>> Author: rnewson
>> Date: Thu Aug 19 08:55:10 2010
>> New Revision: 987084
>>
>> URL: http://svn.apache.org/viewvc?rev=987084&view=rev
>> Log:
>> Support Range header for all attachments, even without compaction upgrade. It's just less efficient.
>
> How much "less"?
>
> Cheers
> Jan
> --
>
>
>>
>> Modified:
>>    couchdb/trunk/src/couchdb/couch_httpd_db.erl
>>    couchdb/trunk/src/couchdb/couch_stream.erl
>>
>> Modified: couchdb/trunk/src/couchdb/couch_httpd_db.erl
>> URL: http://svn.apache.org/viewvc/couchdb/trunk/src/couchdb/couch_httpd_db.erl?rev=987084&r1=987083&r2=987084&view=diff
>> ==============================================================================
>> --- couchdb/trunk/src/couchdb/couch_httpd_db.erl (original)
>> +++ couchdb/trunk/src/couchdb/couch_httpd_db.erl Thu Aug 19 08:55:10 2010
>> @@ -883,7 +883,8 @@ db_attachment_req(#httpd{method='GET',mo
>>         Headers = [
>>             {"ETag", Etag},
>>             {"Cache-Control", "must-revalidate"},
>> -            {"Content-Type", binary_to_list(Type)}
>> +            {"Content-Type", binary_to_list(Type)},
>> +            {"Accept-Ranges", "bytes"}
>>         ] ++ case ReqAcceptsAttEnc of
>>         true ->
>>             [{"Content-Encoding", atom_to_list(Enc)}];
>> @@ -925,22 +926,13 @@ db_attachment_req(#httpd{method='GET',mo
>>                     AttFun(Att, fun(Seg, _) -> send_chunk(Resp, Seg) end, {ok, Resp}),
>>                     last_chunk(Resp);
>>                 _ ->
>> -                    #att{data={_,StreamInfo}} = Att, %% layering violation
>> -                    SupportsRange = case StreamInfo of
>> -                        [{_,_}|_] -> true;
>> -                        _ -> false
>> -                    end,
>>                     Ranges = MochiReq:get(range),
>>                     HasSingleRange = case Ranges of
>>                         [_] -> true;
>>                         _ -> false
>>                     end,
>> -                    Headers1 = case SupportsRange of
>> -                        false ->[{<<"Accept-Ranges">>, <<"none">>}] ++ Headers;
>> -                        true -> [{<<"Accept-Ranges">>, <<"bytes">>}] ++ Headers
>> -                    end,
>>                     if
>> -                        Enc == identity andalso SupportsRange == true andalso HasSingleRange == true ->
>> +                        Enc == identity andalso HasSingleRange == true ->
>>                             [{From, To}] = Ranges,
>>                             {From1, To1} = case {From, To} of
>>                                 {none, To} ->
>> @@ -956,13 +948,13 @@ db_attachment_req(#httpd{method='GET',mo
>>                                 true ->
>>                                     ok
>>                             end,
>> -                            Headers2 = [{<<"Content-Range">>,
>> +                            Headers1 = [{<<"Content-Range">>,
>>                                 ?l2b(io_lib:format("bytes ~B-~B/~B", [From1, To1, Len]))}]
>> -                                ++ Headers1,
>> -                            {ok, Resp} = start_response_length(Req, 206, Headers2, To1 - From1 + 1),
>> +                                ++ Headers,
>> +                            {ok, Resp} = start_response_length(Req, 206, Headers1, To1 - From1 + 1),
>>                             couch_doc:range_att_foldl(Att, From1, To1 + 1, fun(Seg, _) -> send(Resp, Seg) end, {ok, Resp});
>>                         true ->
>> -                            {ok, Resp} = start_response_length(Req, 200, Headers1, Len),
>> +                            {ok, Resp} = start_response_length(Req, 200, Headers, Len),
>>                             AttFun(Att, fun(Seg, _) -> send(Resp, Seg) end, {ok, Resp})
>>                     end
>>                 end
>>
>> Modified: couchdb/trunk/src/couchdb/couch_stream.erl
>> URL: http://svn.apache.org/viewvc/couchdb/trunk/src/couchdb/couch_stream.erl?rev=987084&r1=987083&r2=987084&view=diff
>> ==============================================================================
>> --- couchdb/trunk/src/couchdb/couch_stream.erl (original)
>> +++ couchdb/trunk/src/couchdb/couch_stream.erl Thu Aug 19 08:55:10 2010
>> @@ -129,6 +129,9 @@ range_foldl(Fd, PosList, From, To, Fun,
>>
>> range_foldl(_Fd, _PosList, _From, To, Off, _Fun, Acc) when Off >= To ->
>>     Acc;
>> +range_foldl(Fd, [Pos|Rest], From, To, Off, Fun, Acc) when is_integer(Pos) -> % old-style attachment
>> +    {ok, Bin} = couch_file:pread_iolist(Fd, Pos),
>> +    range_foldl(Fd, [{Pos, iolist_size(Bin)}] ++ Rest, From, To, Off, Fun, Acc);
>> range_foldl(Fd, [{_Pos, Size}|Rest], From, To, Off, Fun, Acc) when From > Off + Size ->
>>     range_foldl(Fd, Rest, From, To, Off + Size, Fun, Acc);
>> range_foldl(Fd, [{Pos, Size}|Rest], From, To, Off, Fun, Acc) ->
>>
>>
>
>