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 <[email protected]> wrote:
>
> On 19 Aug 2010, at 10:55, [email protected] 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) ->
>>
>>
>
>

Reply via email to