From 2c8bc8ed6a2dc4ecdde08e779e4882f189485271 Mon Sep 17 00:00:00 2001 From: John Christopher Anderson Date: Sun, 10 May 2009 09:12:01 +0000 Subject: Refactor the make_view_fold_function stuff. Added a proper Acc to both map and reduce view folds. Cleaned up some pattern matchers. git-svn-id: https://svn.apache.org/repos/asf/couchdb/trunk@773319 13f79535-47bb-0310-9956-ffa450edef68 --- src/couchdb/couch_httpd_show.erl | 89 ++++++++++++++++++---------------------- 1 file changed, 41 insertions(+), 48 deletions(-) (limited to 'src/couchdb/couch_httpd_show.erl') diff --git a/src/couchdb/couch_httpd_show.erl b/src/couchdb/couch_httpd_show.erl index c38522df..49dd88bc 100644 --- a/src/couchdb/couch_httpd_show.erl +++ b/src/couchdb/couch_httpd_show.erl @@ -117,10 +117,10 @@ send_view_list_response(Lang, ListSrc, ViewName, DesignId, Req, Db, Keys) -> end end. -make_map_start_resp_fun(QueryServer, Req, Db, CurrentEtag) -> - fun(Req2, _Etag, TotalViewCount, Offset) -> +make_map_start_resp_fun(QueryServer, Db) -> + fun(Req, CurrentEtag, TotalViewCount, Offset, _Acc) -> ExternalResp = couch_query_servers:render_list_head(QueryServer, - Req2, Db, TotalViewCount, Offset), + Req, Db, TotalViewCount, Offset), JsonResp = apply_etag(ExternalResp, CurrentEtag), #extern_resp_args{ code = Code, @@ -134,8 +134,7 @@ make_map_start_resp_fun(QueryServer, Req, Db, CurrentEtag) -> end. make_map_send_row_fun(QueryServer, Req) -> - fun(Resp, Db2, {{Key, DocId}, Value}, - RowFront, _IncludeDocs) -> + fun(Resp, Db2, {{Key, DocId}, Value}, _IncludeDocs, RowFront) -> try JsonResp = couch_query_servers:render_list_row(QueryServer, Req, Db2, {{Key, DocId}, Value}), @@ -144,17 +143,14 @@ make_map_send_row_fun(QueryServer, Req) -> data = RowBody } = couch_httpd_external:parse_external_response(JsonResp), case StopIter of - true -> stop; + true -> {stop, ""}; _ -> - RowFront2 = case RowFront of - nil -> []; - _ -> RowFront - end, - Chunk = RowFront2 ++ binary_to_list(RowBody), + Chunk = RowFront ++ binary_to_list(RowBody), case Chunk of - [] -> {ok, Resp}; + [] -> ok; _ -> send_chunk(Resp, Chunk) - end + end, + {ok, ""} end catch throw:Error -> @@ -182,7 +178,7 @@ output_map_list(#httpd{mochi_req=MReq}=Req, Lang, ListSrc, View, Group, Db, Quer % pass it into the view fold with closures {ok, QueryServer} = couch_query_servers:start_view_list(Lang, ListSrc), - StartListRespFun = make_map_start_resp_fun(QueryServer, Req, Db, CurrentEtag), + StartListRespFun = make_map_start_resp_fun(QueryServer, Db), SendListRowFun = make_map_send_row_fun(QueryServer, Req), FoldlFun = couch_httpd_view:make_view_fold_fun(Req, QueryArgs, CurrentEtag, Db, RowCount, @@ -192,7 +188,7 @@ output_map_list(#httpd{mochi_req=MReq}=Req, Lang, ListSrc, View, Group, Db, Quer send_row = SendListRowFun }), FoldAccInit = {Limit, SkipCount, undefined, []}, - FoldResult = couch_view:fold(View, Start, Dir, FoldlFun, FoldAccInit), + {ok, FoldResult} = couch_view:fold(View, Start, Dir, FoldlFun, FoldAccInit), finish_list(Req, Db, QueryServer, CurrentEtag, FoldResult, StartListRespFun, RowCount) end); @@ -213,11 +209,11 @@ output_map_list(#httpd{mochi_req=MReq}=Req, Lang, ListSrc, View, Group, Db, Quer % pass it into the view fold with closures {ok, QueryServer} = couch_query_servers:start_view_list(Lang, ListSrc), - StartListRespFun = make_map_start_resp_fun(QueryServer, Req, Db, CurrentEtag), + StartListRespFun = make_map_start_resp_fun(QueryServer, Db), SendListRowFun = make_map_send_row_fun(QueryServer, Req), FoldAccInit = {Limit, SkipCount, undefined, []}, - FoldResult = lists:foldl( + {ok, FoldResult} = lists:foldl( fun(Key, {ok, FoldAcc}) -> FoldlFun = couch_httpd_view:make_view_fold_fun(Req, QueryArgs#view_query_args{ start_key = Key, @@ -234,7 +230,7 @@ output_map_list(#httpd{mochi_req=MReq}=Req, Lang, ListSrc, View, Group, Db, Quer end). make_reduce_start_resp_fun(QueryServer, Req, Db, CurrentEtag) -> - fun(Req2, _Etag, _, _) -> + fun(Req2, _Etag, _Acc) -> JsonResp = couch_query_servers:render_reduce_head(QueryServer, Req2, Db), JsonResp2 = apply_etag(JsonResp, CurrentEtag), @@ -258,18 +254,15 @@ make_reduce_send_row_fun(QueryServer, Req, Db) -> stop = StopIter, data = RowBody } = couch_httpd_external:parse_external_response(JsonResp), - RowFront2 = case RowFront of - nil -> []; - _ -> RowFront - end, case StopIter of - true -> stop; + true -> {stop, ""}; _ -> - Chunk = RowFront2 ++ binary_to_list(RowBody), + Chunk = RowFront ++ binary_to_list(RowBody), case Chunk of - [] -> {ok, Resp}; + [] -> ok; _ -> send_chunk(Resp, Chunk) - end + end, + {ok, ""} end catch throw:Error -> @@ -307,7 +300,7 @@ output_reduce_list(#httpd{mochi_req=MReq}=Req, Lang, ListSrc, View, Group, Db, Q send_row = SendListRowFun }), FoldAccInit = {Limit, SkipCount, undefined, []}, - FoldResult = couch_view:fold_reduce(View, Dir, {StartKey, StartDocId}, + {ok, FoldResult} = couch_view:fold_reduce(View, Dir, {StartKey, StartDocId}, {EndKey, EndDocId}, GroupRowsFun, RespFun, FoldAccInit), finish_list(Req, Db, QueryServer, CurrentEtag, FoldResult, StartListRespFun, null) @@ -341,7 +334,7 @@ output_reduce_list(#httpd{mochi_req=MReq}=Req, Lang, ListSrc, View, Group, Db, Q send_row = SendListRowFun }), FoldAccInit = {Limit, SkipCount, undefined, []}, - FoldResult = lists:foldl( + {ok, FoldResult} = lists:foldl( fun(Key, {ok, FoldAcc}) -> couch_view:fold_reduce(View, Dir, {Key, StartDocId}, {Key, EndDocId}, GroupRowsFun, RespFun, FoldAcc) @@ -350,29 +343,29 @@ output_reduce_list(#httpd{mochi_req=MReq}=Req, Lang, ListSrc, View, Group, Db, Q end). finish_list(Req, Db, QueryServer, Etag, FoldResult, StartListRespFun, TotalRows) -> - case FoldResult of - {ok, Acc} -> - JsonTail = couch_query_servers:render_list_tail(QueryServer, Req, Db), - #extern_resp_args{ - data = Tail - } = couch_httpd_external:parse_external_response(JsonTail), - {Resp, BeginBody} = case Acc of + {Resp, BeginBody} = case FoldResult of {_, _, undefined, _} -> - {ok, Resp2, BeginBody2} = StartListRespFun(Req, Etag, TotalRows, null), + {ok, Resp2, BeginBody2} = render_head_for_empty_list(StartListRespFun, Req, Etag, TotalRows), {Resp2, BeginBody2}; - {_, _, Resp2, _} -> - {Resp2, ""} - end, - Chunk = BeginBody ++ binary_to_list(Tail), - case Chunk of - [] -> ok; - _ -> send_chunk(Resp, Chunk) - end, - send_chunk(Resp, []); - Error -> - throw(Error) - end. + {_, _, Resp0, _} -> + {Resp0, ""} + end, + JsonTail = couch_query_servers:render_list_tail(QueryServer, Req, Db), + #extern_resp_args{ + data = Tail + } = couch_httpd_external:parse_external_response(JsonTail), + Chunk = BeginBody ++ binary_to_list(Tail), + case Chunk of + [] -> ok; + _ -> send_chunk(Resp, Chunk) + end, + send_chunk(Resp, []). +render_head_for_empty_list(StartListRespFun, Req, Etag, null) -> + StartListRespFun(Req, Etag, []); +render_head_for_empty_list(StartListRespFun, Req, Etag, TotalRows) -> + StartListRespFun(Req, Etag, TotalRows, null, []). + send_doc_show_response(Lang, ShowSrc, DocId, nil, #httpd{mochi_req=MReq}=Req, Db) -> % compute etag with no doc Headers = MReq:get(headers), -- cgit v1.2.3