summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFilipe David Borba Manana <fdmanana@apache.org>2011-02-10 08:11:01 +0000
committerFilipe David Borba Manana <fdmanana@apache.org>2011-02-10 08:11:01 +0000
commit4158b51580cb27cbe143384f1ca41ac18c9ea0cb (patch)
treed41d82e6f7c390a42aa3052dfbb5ff0c7888b1b0
parent00d2709afbff6f402d91f5d1dc3e5a5075685c49 (diff)
Merged revision 1069262 from trunk
More efficient _changes?include_docs=true and _all_docs?include_docs=true Closes COUCHDB-1061 git-svn-id: https://svn.apache.org/repos/asf/couchdb/branches/1.1.x@1069264 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--src/couchdb/couch_changes.erl23
-rw-r--r--src/couchdb/couch_httpd_db.erl37
-rw-r--r--src/couchdb/couch_httpd_view.erl8
3 files changed, 49 insertions, 19 deletions
diff --git a/src/couchdb/couch_changes.erl b/src/couchdb/couch_changes.erl
index 838f7e66..6baaf7ec 100644
--- a/src/couchdb/couch_changes.erl
+++ b/src/couchdb/couch_changes.erl
@@ -261,8 +261,7 @@ end_sending_changes(Callback, UserAcc, EndSeq, ResponseType) ->
changes_enumerator(DocInfo, {Db, _, _, FilterFun, Callback, UserAcc,
"continuous", Limit, IncludeDocs}) ->
- #doc_info{id=Id, high_seq=Seq,
- revs=[#rev_info{deleted=Del,rev=Rev}|_]} = DocInfo,
+ #doc_info{high_seq = Seq} = DocInfo,
Results0 = FilterFun(DocInfo),
Results = [Result || Result <- Results0, Result /= null],
Go = if Limit =< 1 -> stop; true -> ok end,
@@ -272,7 +271,7 @@ changes_enumerator(DocInfo, {Db, _, _, FilterFun, Callback, UserAcc,
IncludeDocs}
};
_ ->
- ChangesRow = changes_row(Db, Seq, Id, Del, Results, Rev, IncludeDocs),
+ ChangesRow = changes_row(Db, Results, DocInfo, IncludeDocs),
UserAcc2 = Callback({change, ChangesRow, <<>>}, "continuous", UserAcc),
{Go, {Db, Seq, nil, FilterFun, Callback, UserAcc2, "continuous",
Limit - 1, IncludeDocs}
@@ -281,8 +280,7 @@ changes_enumerator(DocInfo, {Db, _, _, FilterFun, Callback, UserAcc,
changes_enumerator(DocInfo, {Db, _, Prepend, FilterFun, Callback, UserAcc,
ResponseType, Limit, IncludeDocs}) ->
- #doc_info{id=Id, high_seq=Seq, revs=[#rev_info{deleted=Del,rev=Rev}|_]}
- = DocInfo,
+ #doc_info{high_seq = Seq} = DocInfo,
Results0 = FilterFun(DocInfo),
Results = [Result || Result <- Results0, Result /= null],
Go = if (Limit =< 1) andalso Results =/= [] -> stop; true -> ok end,
@@ -292,7 +290,7 @@ changes_enumerator(DocInfo, {Db, _, Prepend, FilterFun, Callback, UserAcc,
Limit, IncludeDocs}
};
_ ->
- ChangesRow = changes_row(Db, Seq, Id, Del, Results, Rev, IncludeDocs),
+ ChangesRow = changes_row(Db, Results, DocInfo, IncludeDocs),
UserAcc2 = Callback({change, ChangesRow, Prepend}, ResponseType, UserAcc),
{Go, {Db, Seq, <<",\n">>, FilterFun, Callback, UserAcc2, ResponseType,
Limit - 1, IncludeDocs}
@@ -300,12 +298,15 @@ changes_enumerator(DocInfo, {Db, _, Prepend, FilterFun, Callback, UserAcc,
end.
-changes_row(Db, Seq, Id, Del, Results, Rev, true) ->
+changes_row(Db, Results, DocInfo, IncludeDoc) ->
+ #doc_info{
+ id = Id, high_seq = Seq, revs = [#rev_info{deleted = Del} | _]
+ } = DocInfo,
{[{<<"seq">>, Seq}, {<<"id">>, Id}, {<<"changes">>, Results}] ++
- deleted_item(Del) ++ couch_httpd_view:doc_member(Db, {Id, Rev})};
-changes_row(_, Seq, Id, Del, Results, _, false) ->
- {[{<<"seq">>, Seq}, {<<"id">>, Id}, {<<"changes">>, Results}] ++
- deleted_item(Del)}.
+ deleted_item(Del) ++ case IncludeDoc of
+ true -> couch_httpd_view:doc_member(Db, DocInfo);
+ false -> []
+ end}.
deleted_item(true) -> [{<<"deleted">>, true}];
deleted_item(_) -> [].
diff --git a/src/couchdb/couch_httpd_db.erl b/src/couchdb/couch_httpd_db.erl
index a051402b..9aa91277 100644
--- a/src/couchdb/couch_httpd_db.erl
+++ b/src/couchdb/couch_httpd_db.erl
@@ -505,12 +505,13 @@ all_docs_view(Req, Db, Keys) ->
nil ->
FoldlFun = couch_httpd_view:make_view_fold_fun(Req, QueryArgs, CurrentEtag, Db, UpdateSeq,
TotalRowCount, #view_fold_helper_funs{
- reduce_count = fun couch_db:enum_docs_reduce_to_count/1
+ reduce_count = fun couch_db:enum_docs_reduce_to_count/1,
+ send_row = fun all_docs_send_json_view_row/5
}),
AdapterFun = fun(#full_doc_info{id=Id}=FullDocInfo, Offset, Acc) ->
case couch_doc:to_doc_info(FullDocInfo) of
- #doc_info{revs=[#rev_info{deleted=false, rev=Rev}|_]} ->
- FoldlFun({{Id, Id}, {[{rev, couch_doc:rev_to_str(Rev)}]}}, Offset, Acc);
+ #doc_info{revs=[#rev_info{deleted=false}|_]} = DocInfo ->
+ FoldlFun({{Id, Id}, DocInfo}, Offset, Acc);
#doc_info{revs=[#rev_info{deleted=true}|_]} ->
{ok, Acc}
end
@@ -522,7 +523,8 @@ all_docs_view(Req, Db, Keys) ->
_ ->
FoldlFun = couch_httpd_view:make_view_fold_fun(Req, QueryArgs, CurrentEtag, Db, UpdateSeq,
TotalRowCount, #view_fold_helper_funs{
- reduce_count = fun(Offset) -> Offset end
+ reduce_count = fun(Offset) -> Offset end,
+ send_row = fun all_docs_send_json_view_row/5
}),
KeyFoldFun = case Dir of
fwd ->
@@ -534,10 +536,8 @@ all_docs_view(Req, Db, Keys) ->
fun(Key, FoldAcc) ->
DocInfo = (catch couch_db:get_doc_info(Db, Key)),
Doc = case DocInfo of
- {ok, #doc_info{id=Id, revs=[#rev_info{deleted=false, rev=Rev}|_]}} ->
- {{Id, Id}, {[{rev, couch_doc:rev_to_str(Rev)}]}};
- {ok, #doc_info{id=Id, revs=[#rev_info{deleted=true, rev=Rev}|_]}} ->
- {{Id, Id}, {[{rev, couch_doc:rev_to_str(Rev)}, {deleted, true}]}};
+ {ok, #doc_info{id = Id} = Di} ->
+ {{Id, Id}, Di};
not_found ->
{{Key, error}, not_found};
_ ->
@@ -551,6 +551,27 @@ all_docs_view(Req, Db, Keys) ->
end
end).
+all_docs_send_json_view_row(Resp, Db, KV, IncludeDocs, RowFront) ->
+ JsonRow = all_docs_view_row_obj(Db, KV, IncludeDocs),
+ send_chunk(Resp, RowFront ++ ?JSON_ENCODE(JsonRow)),
+ {ok, ",\r\n"}.
+
+all_docs_view_row_obj(_Db, {{DocId, error}, Value}, _IncludeDocs) ->
+ {[{key, DocId}, {error, Value}]};
+all_docs_view_row_obj(Db, {_KeyDocId, DocInfo}, true) ->
+ {all_docs_row(DocInfo) ++ couch_httpd_view:doc_member(Db, DocInfo)};
+all_docs_view_row_obj(_Db, {_KeyDocId, DocInfo}, _IncludeDocs) ->
+ {all_docs_row(DocInfo)}.
+
+all_docs_row(#doc_info{id = Id, revs = [RevInfo | _]}) ->
+ #rev_info{rev = Rev, deleted = Del} = RevInfo,
+ [ {id, Id}, {key, Id},
+ {value, {[{rev, couch_doc:rev_to_str(Rev)}] ++ case Del of
+ true -> [{deleted, true}];
+ false -> []
+ end}} ].
+
+
db_doc_req(#httpd{method='DELETE'}=Req, Db, DocId) ->
% check for the existence of the doc to handle the 404 case.
couch_doc_open(Db, DocId, nil, []),
diff --git a/src/couchdb/couch_httpd_view.erl b/src/couchdb/couch_httpd_view.erl
index 8656c43e..8906de70 100644
--- a/src/couchdb/couch_httpd_view.erl
+++ b/src/couchdb/couch_httpd_view.erl
@@ -660,6 +660,14 @@ view_row_obj(_Db, {{Key, DocId}, Value}, _IncludeDocs) ->
view_row_with_doc(Db, {{Key, DocId}, Value}, IdRev) ->
{[{id, DocId}, {key, Key}, {value, Value}] ++ doc_member(Db, IdRev)}.
+doc_member(Db, #doc_info{id = Id, revs = [#rev_info{rev = Rev} | _]} = Info) ->
+ ?LOG_DEBUG("Include Doc: ~p ~p", [Id, Rev]),
+ case couch_db:open_doc(Db, Info, [deleted]) of
+ {ok, Doc} ->
+ [{doc, couch_doc:to_json_obj(Doc, [])}];
+ _ ->
+ [{doc, null}]
+ end;
doc_member(Db, {DocId, Rev}) ->
?LOG_DEBUG("Include Doc: ~p ~p", [DocId, Rev]),
case (catch couch_httpd_db:couch_doc_open(Db, DocId, Rev, [])) of