You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by da...@apache.org on 2014/01/17 23:09:51 UTC

[06/49] git commit: Use #doc_info{} optimization for _all_docs.

Use #doc_info{} optimization for _all_docs.

During the refactor I accidentally undid the optimization from
COUCHDB-1061 which uses a #doc_info{} to get a #doc{} from disk
which avoids a lookup in the id btree.



git-svn-id: https://svn.apache.org/repos/asf/couchdb/trunk@1172309 13f79535-47bb-0310-9956-ffa450edef68


Project: http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/commit/32f3ae04
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/tree/32f3ae04
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/diff/32f3ae04

Branch: refs/heads/import
Commit: 32f3ae04e956508aa4e6b772ea3fdcaccecaee62
Parents: 81ed68e
Author: Paul Joseph Davis <da...@apache.org>
Authored: Sun Sep 18 17:57:16 2011 +0000
Committer: Paul Joseph Davis <da...@apache.org>
Committed: Sun Sep 18 17:57:16 2011 +0000

----------------------------------------------------------------------
 src/couch_mrview.erl           | 89 ++++++++++++++++++++++---------------
 src/couch_mrview_compactor.erl |  3 +-
 src/couch_mrview_util.erl      | 31 +++++++++++--
 3 files changed, 83 insertions(+), 40 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/32f3ae04/src/couch_mrview.erl
----------------------------------------------------------------------
diff --git a/src/couch_mrview.erl b/src/couch_mrview.erl
index 2804758..53a555b 100644
--- a/src/couch_mrview.erl
+++ b/src/couch_mrview.erl
@@ -29,6 +29,7 @@
     limit,
     skip,
     group_level,
+    doc_info,
     callback,
     user_acc,
     last_go=ok,
@@ -117,7 +118,7 @@ cleanup(Db) ->
     couch_mrview_cleanup:run(Db).
 
 
-all_docs_fold(Db, Args, Callback, UAcc) ->
+all_docs_fold(Db, #mrargs{keys=undefined}=Args, Callback, UAcc) ->
     {ok, Info} = couch_db:get_db_info(Db),
     Total = couch_util:get_value(doc_count, Info),
     UpdateSeq = couch_db:get_update_seq(Db),
@@ -132,38 +133,47 @@ all_docs_fold(Db, Args, Callback, UAcc) ->
         update_seq=UpdateSeq,
         args=Args
     },
-    {Reds, FinalAcc} = case Args#mrargs.keys of
-        Keys when is_list(Keys) ->
-            KeyFoldFun = case Args#mrargs.direction of
-                fwd -> fun lists:foldl/3;
-                rev -> fun lists:foldr/3
-            end,
-            FoldFun = fun(Key, Acc0) ->
-                DocInfo = (catch couch_db:get_doc_info(Db, Key)),
-                Doc = case DocInfo of
-                    {ok, #doc_info{id=Id, revs=[RevInfo | _RestRevs]}} ->
-                        Rev = couch_doc:rev_to_str(RevInfo#rev_info.rev),
-                        Props = [{rev, Rev}] ++ case RevInfo#rev_info.deleted of
-                            true -> [{deleted, true}];
-                            false -> []
-                        end,
-                        {{Id, Id}, {Props}};
-                    not_found ->
-                        {{Key, error}, not_found}
+    [Opts] = couch_mrview_util:all_docs_key_opts(Args),
+    {ok, Offset, FinalAcc} = couch_db:enum_docs(Db, fun map_fold/3, Acc, Opts),
+    finish_fold(FinalAcc, [{total, Total}, {offset, Offset}]);
+all_docs_fold(Db, #mrargs{direction=Dir, keys=Keys0}=Args, Callback, UAcc) ->
+    {ok, Info} = couch_db:get_db_info(Db),
+    Total = couch_util:get_value(doc_count, Info),
+    UpdateSeq = couch_db:get_update_seq(Db),
+    Acc = #mracc{
+        db=Db,
+        total_rows=Total,
+        limit=Args#mrargs.limit,
+        skip=Args#mrargs.skip,
+        callback=Callback,
+        user_acc=UAcc,
+        reduce_fun=fun couch_mrview_util:all_docs_reduce_to_count/1,
+        update_seq=UpdateSeq,
+        args=Args
+    },
+    % Backwards compatibility hack. The old _all_docs iterates keys
+    % in reverse if descending=true was passed. Here we'll just
+    % reverse the list instead.
+    Keys = if Dir =:= fwd -> Keys0; true -> lists:reverse(Keys0) end,
+
+    FoldFun = fun(Key, Acc0) ->
+        DocInfo = (catch couch_db:get_doc_info(Db, Key)),
+        {Doc, Acc1} = case DocInfo of
+            {ok, #doc_info{id=Id, revs=[RevInfo | _RestRevs]}=DI} ->
+                Rev = couch_doc:rev_to_str(RevInfo#rev_info.rev),
+                Props = [{rev, Rev}] ++ case RevInfo#rev_info.deleted of
+                    true -> [{deleted, true}];
+                    false -> []
                 end,
-                {_, Acc1} = map_fold(Doc, {[], [{0, 0, 0}]}, Acc0),
-                Acc1
-            end,
-            KeyAcc = KeyFoldFun(FoldFun, Acc, Keys),
-            {{[], [{0, 0, 0}]}, KeyAcc};
-        _ ->
-            [Opts] = couch_mrview_util:all_docs_key_opts(Args),
-            Bt = Db#db.fulldocinfo_by_id_btree,
-            {ok, R, A} = couch_btree:fold(Bt, fun map_fold/3, Acc, Opts),
-            {R, A}
+                {{{Id, Id}, {Props}}, Acc0#mracc{doc_info=DI}};
+            not_found ->
+                {{{Key, error}, not_found}, Acc0}
+        end,
+        {_, Acc2} = map_fold(Doc, {[], [{0, 0, 0}]}, Acc1),
+        Acc2
     end,
-    Offset = couch_mrview_util:all_docs_reduce_to_count(Reds),
-    finish_fold(FinalAcc, [{total, Total}, {offset, Offset}]).
+    FinalAcc = lists:foldl(FoldFun, Acc, Keys),
+    finish_fold(FinalAcc, [{total, Total}]).
 
 
 map_fold(Db, View, Args, Callback, UAcc) ->
@@ -191,9 +201,9 @@ map_fold(Db, View, Args, Callback, UAcc) ->
 map_fold(#full_doc_info{} = FullDocInfo, OffsetReds, Acc) ->
     % matches for _all_docs and translates #full_doc_info{} -> KV pair
     case couch_doc:to_doc_info(FullDocInfo) of
-        #doc_info{id=Id, revs=[#rev_info{deleted=false, rev=Rev}|_]} ->
+        #doc_info{id=Id, revs=[#rev_info{deleted=false, rev=Rev}|_]} = DI ->
             Value = {[{rev, couch_doc:rev_to_str(Rev)}]},
-            map_fold({{Id, Id}, Value}, OffsetReds, Acc);
+            map_fold({{Id, Id}, Value}, OffsetReds, Acc#mracc{doc_info=DI});
         #doc_info{revs=[#rev_info{deleted=true}|_]} ->
             {ok, Acc}
     end;
@@ -222,14 +232,23 @@ map_fold({{Key, Id}, Val}, _Offset, Acc) ->
     #mracc{
         db=Db,
         limit=Limit,
+        doc_info=DI,
         callback=Callback,
         user_acc=UAcc0,
         args=Args
     } = Acc,
-    Doc = couch_mrview_util:maybe_load_doc(Db, Id, Val, Args),
+    Doc = case DI of
+        #doc_info{} -> couch_mrview_util:maybe_load_doc(Db, DI, Args);
+        _ -> couch_mrview_util:maybe_load_doc(Db, Id, Val, Args)
+    end,
     Row = [{id, Id}, {key, Key}, {val, Val}] ++ Doc,
     {Go, UAcc1} = Callback({row, Row}, UAcc0),
-    {Go, Acc#mracc{limit=Limit-1, user_acc=UAcc1, last_go=Go}}.
+    {Go, Acc#mracc{
+        limit=Limit-1,
+        doc_info=undefined,
+        user_acc=UAcc1,
+        last_go=Go
+    }}.
 
 
 red_fold(Db, {_Nth, _Lang, View}=RedView, Args, Callback, UAcc) ->

http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/32f3ae04/src/couch_mrview_compactor.erl
----------------------------------------------------------------------
diff --git a/src/couch_mrview_compactor.erl b/src/couch_mrview_compactor.erl
index ef3f158..b96e63e 100644
--- a/src/couch_mrview_compactor.erl
+++ b/src/couch_mrview_compactor.erl
@@ -161,8 +161,7 @@ update_task(#acc{changes = Changes, total_changes = Total} = Acc, ChangesInc) ->
 swap_compacted(OldState, NewState) ->
     #mrst{
         sig=Sig,
-        db_name=DbName,
-        idx_name=IdxName
+        db_name=DbName
     } = NewState,
 
     link(NewState#mrst.fd),

http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/32f3ae04/src/couch_mrview_util.erl
----------------------------------------------------------------------
diff --git a/src/couch_mrview_util.erl b/src/couch_mrview_util.erl
index 0b9e5fc..0c26109 100644
--- a/src/couch_mrview_util.erl
+++ b/src/couch_mrview_util.erl
@@ -23,7 +23,7 @@
 -export([temp_view_to_ddoc/1]).
 -export([calculate_data_size/2]).
 -export([validate_args/1]).
--export([maybe_load_doc/4]).
+-export([maybe_load_doc/3, maybe_load_doc/4]).
 
 -define(MOD, couch_mrview_index).
 
@@ -659,12 +659,37 @@ expand_dups([KV | Rest], Acc) ->
     expand_dups(Rest, [KV | Acc]).
 
 
+maybe_load_doc(_Db, _DI, #mrargs{include_docs=false}) ->
+    [];
+maybe_load_doc(Db, #doc_info{}=DI, #mrargs{conflicts=true}) ->
+    doc_row(couch_index_util:load_doc(Db, DI, [conflicts]));
+maybe_load_doc(Db, #doc_info{}=DI, _Args) ->
+    doc_row(couch_index_util:load_doc(Db, DI, [])).
+
+
 maybe_load_doc(_Db, _Id, _Val, #mrargs{include_docs=false}) ->
     [];
 maybe_load_doc(Db, Id, Val, #mrargs{conflicts=true}) ->
-    [couch_index_util:load_doc(Db, Id, Val, [conflicts])];
+    doc_row(couch_index_util:load_doc(Db, docid_rev(Id, Val), [conflicts]));
 maybe_load_doc(Db, Id, Val, _Args) ->
-    [couch_index_util:load_doc(Db, Id, Val, [])].
+    doc_row(couch_index_util:load_doc(Db, docid_rev(Id, Val), [])).
+
+
+doc_row(null) ->
+    [{doc, null}];
+doc_row(Doc) ->
+    [{doc, couch_doc:to_json_obj(Doc, [])}].
+
+
+docid_rev(Id, {Props}) ->
+    DocId = couch_util:get_value(<<"_id">>, Props, Id),
+    Rev = case couch_util:get_value(<<"_rev">>, Props, nil) of
+        nil -> nil;
+        Rev0 -> couch_doc:parse_rev(Rev0)
+    end,
+    {DocId, Rev};
+docid_rev(Id, _) ->
+    {Id, nil}.
 
 
 index_of(Key, List) ->