couchdb-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bbast...@apache.org
Subject [30/41] couch-mrview commit: updated refs/heads/master to 28e51f3
Date Fri, 31 Oct 2014 19:53:45 GMT
Make they key-by-key-and-seq view btree optional independently of the key-by-seq view btree


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/c0eedd42
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/tree/c0eedd42
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/diff/c0eedd42

Branch: refs/heads/master
Commit: c0eedd422415f36cf2d5bb68f7c72944fb373c79
Parents: 690d878
Author: Benjamin Bastian <benjamin.bastian@gmail.com>
Authored: Tue Aug 26 15:28:56 2014 +0700
Committer: Benjamin Bastian <benjamin.bastian@gmail.com>
Committed: Thu Oct 30 13:40:31 2014 -0700

----------------------------------------------------------------------
 include/couch_mrview.hrl       |   2 +
 src/couch_mrview.erl           |  31 +++++-----
 src/couch_mrview_compactor.erl |  30 ++++++----
 src/couch_mrview_index.erl     |   4 ++
 src/couch_mrview_updater.erl   |  71 ++++++++++++++---------
 src/couch_mrview_util.erl      | 111 ++++++++++++++++++++++++------------
 6 files changed, 159 insertions(+), 90 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/c0eedd42/include/couch_mrview.hrl
----------------------------------------------------------------------
diff --git a/include/couch_mrview.hrl b/include/couch_mrview.hrl
index f1911db..b8ea08a 100644
--- a/include/couch_mrview.hrl
+++ b/include/couch_mrview.hrl
@@ -19,6 +19,7 @@
     language,
     design_opts=[],
     seq_indexed=false,
+    keyseq_indexed=false,
     lib,
     views,
     id_btree=nil,
@@ -45,6 +46,7 @@
     seq_btree=nil,
     key_byseq_btree=nil,
     seq_indexed=false,
+    keyseq_indexed=false,
     options=[]
 }).
 

http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/c0eedd42/src/couch_mrview.erl
----------------------------------------------------------------------
diff --git a/src/couch_mrview.erl b/src/couch_mrview.erl
index c6e413b..f6dec66 100644
--- a/src/couch_mrview.erl
+++ b/src/couch_mrview.erl
@@ -155,21 +155,22 @@ view_changes_since(Db, DDoc, VName, StartSeq, Fun, Options, Acc) ->
     Args0 = make_view_changes_args(Options),
     {ok, {_, View, _}, _, Args} = couch_mrview_util:get_view(Db, DDoc, VName,
                                                              Args0),
-    case View#mrview.seq_indexed of
-        true ->
-            OptList = make_view_changes_opts(StartSeq, Options, Args),
-            Btree = case is_key_byseq(Options) of
-                true -> View#mrview.key_byseq_btree;
-                _ -> View#mrview.seq_btree
-            end,
-            AccOut = lists:foldl(fun(Opts, Acc0) ->
-                {ok, _R, A} = couch_mrview_util:fold_changes(
-                    Btree, Fun, Acc0, Opts),
-                A
-            end, Acc, OptList),
-            {ok, AccOut};
-        _ ->
-            {error, seqs_not_indexed}
+    #mrview{seq_indexed=SIndexed, keyseq_indexed=KSIndexed} = View,
+    IsKSQuery = is_key_byseq(Options),
+    if (SIndexed andalso not IsKSQuery) orelse (KSIndexed andalso IsKSQuery) ->
+        OptList = make_view_changes_opts(StartSeq, Options, Args),
+        Btree = case IsKSQuery of
+            true -> View#mrview.key_byseq_btree;
+            _ -> View#mrview.seq_btree
+        end,
+        AccOut = lists:foldl(fun(Opts, Acc0) ->
+            {ok, _R, A} = couch_mrview_util:fold_changes(
+                Btree, Fun, Acc0, Opts),
+            A
+        end, Acc, OptList),
+        {ok, AccOut};
+    true ->
+        {error, seqs_not_indexed}
     end.
 
 count_view_changes_since(Db, DDoc, VName, SinceSeq) ->

http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/c0eedd42/src/couch_mrview_compactor.erl
----------------------------------------------------------------------
diff --git a/src/couch_mrview_compactor.erl b/src/couch_mrview_compactor.erl
index b6a8e78..6d9382f 100644
--- a/src/couch_mrview_compactor.erl
+++ b/src/couch_mrview_compactor.erl
@@ -42,6 +42,7 @@ compact(State) ->
         id_btree=IdBtree,
         log_btree=LogBtree,
         seq_indexed=SeqIndexed,
+        keyseq_indexed=KeySeqIndexed,
         views=Views
     } = State,
     erlang:put(io_priority, {view_compact, DbName, IdxName}),
@@ -63,7 +64,7 @@ compact(State) ->
         views = EmptyViews
     } = EmptyState,
 
-    TotalChanges0 = case SeqIndexed of
+    TotalChanges0 = case SeqIndexed orelse KeySeqIndexed of
         true -> NumDocIds * 2;
         _ -> NumDocIds
     end,
@@ -71,10 +72,10 @@ compact(State) ->
     TotalChanges = lists:foldl(
         fun(View, Acc) ->
             {ok, Kvs} = couch_mrview_util:get_row_count(View),
-            case SeqIndexed of
+            case SeqIndexed orelse KeySeqIndexed of
                 true ->
                     {ok, SKvs} = couch_mrview_util:get_view_changes_count(View),
-                    Acc + Kvs + SKvs * 2;
+                    Acc + Kvs + SKvs;
                 false ->
                     Acc + Kvs
             end
@@ -187,18 +188,23 @@ compact_view(#mrview{id_num=VID}=View, EmptyView, BufferSize, Acc0)
->
                                        VID, BufferSize, Acc0),
 
     %% are we indexing changes by sequences?
-    {NewSeqBt, NewKeyBySeqBt, FinalAcc} = case View#mrview.seq_indexed of
+    {NewSeqBt, Acc2} = case View#mrview.seq_indexed of
         true ->
-            {SBt, Acc2} = compact_view_btree(View#mrview.seq_btree,
-                                             EmptyView#mrview.seq_btree,
-                                             VID, BufferSize, Acc1),
-            {KSBt, Acc3} = compact_view_btree(View#mrview.key_byseq_btree,
-                                              EmptyView#mrview.key_byseq_btree,
-                                              VID, BufferSize, Acc2),
-            {SBt, KSBt, Acc3};
+            compact_view_btree(View#mrview.seq_btree,
+                               EmptyView#mrview.seq_btree,
+                               VID, BufferSize, Acc1);
         _ ->
-            {nil, nil, Acc1}
+            {nil, Acc1}
     end,
+    {NewKeyBySeqBt, FinalAcc} = case View#mrview.keyseq_indexed of
+        true ->
+            compact_view_btree(View#mrview.key_byseq_btree,
+                               EmptyView#mrview.key_byseq_btree,
+                               VID, BufferSize, Acc2);
+        _ ->
+            {nil, Acc2}
+    end,
+
     {EmptyView#mrview{btree=NewBt,
                       seq_btree=NewSeqBt,
                       key_byseq_btree=NewKeyBySeqBt}, FinalAcc}.

http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/c0eedd42/src/couch_mrview_index.erl
----------------------------------------------------------------------
diff --git a/src/couch_mrview_index.erl b/src/couch_mrview_index.erl
index 0e6ef6f..63340cb 100644
--- a/src/couch_mrview_index.erl
+++ b/src/couch_mrview_index.erl
@@ -40,8 +40,10 @@ get(Property, State) ->
             IncDesign = couch_util:get_value(<<"include_design">>, Opts, false),
             LocalSeq = couch_util:get_value(<<"local_seq">>, Opts, false),
             SeqIndexed = couch_util:get_value(<<"seq_indexed">>, Opts, false),
+            KeySeqIndexed = couch_util:get_value(<<"keyseq_indexed">>, Opts,
false),
             if IncDesign -> [include_design]; true -> [] end
                 ++ if LocalSeq -> [local_seq]; true -> [] end
+                ++ if KeySeqIndexed -> [keyseq_indexed]; true -> [] end
                 ++ if SeqIndexed -> [seq_indexed]; true -> [] end;
         fd ->
             State#mrst.fd;
@@ -70,9 +72,11 @@ get(Property, State) ->
             IncDesign = couch_util:get_value(<<"include_design">>, Opts, false),
             LocalSeq = couch_util:get_value(<<"local_seq">>, Opts, false),
             SeqIndexed = couch_util:get_value(<<"seq_indexed">>, Opts, false),
+            KeySeqIndexed = couch_util:get_value(<<"keyseq_indexed">>, Opts,
false),
             UpdateOptions =
                 if IncDesign -> [<<"include_design">>]; true -> [] end
                 ++ if LocalSeq -> [<<"local_seq">>]; true -> [] end
+                ++ if KeySeqIndexed -> [<<"keyseq_indexed">>]; true ->
[] end
                 ++ if SeqIndexed -> [<<"seq_indexed">>]; true -> [] end,
 
 

http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/c0eedd42/src/couch_mrview_updater.erl
----------------------------------------------------------------------
diff --git a/src/couch_mrview_updater.erl b/src/couch_mrview_updater.erl
index 3fe1dd6..2a67dff 100644
--- a/src/couch_mrview_updater.erl
+++ b/src/couch_mrview_updater.erl
@@ -86,27 +86,37 @@ purge(_Db, PurgeSeq, PurgedIdRevs, State) ->
     SeqsToRemove = lists:foldl(MakeDictFun, dict:new(), LLookups),
 
     RemKeysFun = fun(#mrview{id_num=ViewId}=View) ->
+        #mrview{seq_indexed=SIndexed, keyseq_indexed=KSIndexed} = View,
         ToRem = couch_util:dict_find(ViewId, KeysToRemove, []),
         {ok, VBtree2} = couch_btree:add_remove(View#mrview.btree, [], ToRem),
         NewPurgeSeq = case VBtree2 =/= View#mrview.btree of
             true -> PurgeSeq;
             _ -> View#mrview.purge_seq
         end,
-        {SeqBtree2, KeyBySeqBtree2} = case View#mrview.seq_indexed of
-            true ->
-                SToRem = couch_util:dict_find(ViewId, SeqsToRemove, []),
+        {SeqBtree3, KeyBySeqBtree3} = if SIndexed orelse KSIndexed ->
+            SToRem = couch_util:dict_find(ViewId, SeqsToRemove, []),
+            {ok, SeqBtree2} = if SIndexed ->
                 SKs = [{Seq, Key} || {Key, Seq, _} <- SToRem],
+                couch_btree:add_remove(View#mrview.seq_btree,
+                                       [], SKs);
+            true ->
+                {ok, nil}
+            end,
+            {ok, KeyBySeqBtree2} = if KSIndexed ->
                 KSs = [{[Seq, Key], DocId} || {Key, Seq, DocId} <- SToRem],
-                {ok, SBt} = couch_btree:add_remove(View#mrview.seq_btree,
-                                                   [], SKs),
-                {ok, KSbt} = couch_btree:add_remove(View#mrview.key_byseq_btree,
-                                                    [], KSs),
-                {SBt, KSbt};
-            _ -> {nil, nil}
+                couch_btree:add_remove(View#mrview.key_byseq_btree,
+                                       [], KSs);
+            true ->
+                {ok, nil}
+            end,
+            {SeqBtree2, KeyBySeqBtree2};
+        true ->
+            {nil, nil}
         end,
+
         View#mrview{btree=VBtree2,
-                    seq_btree=SeqBtree2,
-                    key_byseq_btree=KeyBySeqBtree2,
+                    seq_btree=SeqBtree3,
+                    key_byseq_btree=KeyBySeqBtree3,
                     purge_seq=NewPurgeSeq}
 
     end,
@@ -301,6 +311,7 @@ write_kvs(State, UpdateSeq, ViewKVs, DocIdKeys, Log) ->
     end,
 
     UpdateView = fun(#mrview{id_num=ViewId}=View, {ViewId, {KVs, SKVs}}) ->
+        #mrview{seq_indexed=SIndexed, keyseq_indexed=KSIndexed} = View,
         ToRem = couch_util:dict_find(ViewId, ToRemByView, []),
         {ok, VBtree2} = couch_btree:add_remove(View#mrview.btree, KVs, ToRem),
         NewUpdateSeq = case VBtree2 =/= View#mrview.btree of
@@ -309,25 +320,33 @@ write_kvs(State, UpdateSeq, ViewKVs, DocIdKeys, Log) ->
         end,
 
         %% store the view changes.
-        {SeqBtree2, KeyBySeqBtree2} = case View#mrview.seq_indexed of
-            true ->
-                SToRem = couch_util:dict_find(ViewId, SeqsToRemove, []),
-                SToAdd = couch_util:dict_find(ViewId, SeqsToAdd, []),
+        {SeqBtree3, KeyBySeqBtree3} = if SIndexed orelse KSIndexed ->
+            SToRem = couch_util:dict_find(ViewId, SeqsToRemove, []),
+            SToAdd = couch_util:dict_find(ViewId, SeqsToAdd, []),
+            SKVs1 = SKVs ++ SToAdd,
+
+            {ok, SeqBtree2} = if SIndexed ->
                 RemSKs = [{Seq, Key} || {Key, Seq, _} <- SToRem],
+                couch_btree:add_remove(View#mrview.seq_btree,
+                                       SKVs1, RemSKs);
+            true ->
+                {ok, nil}
+            end,
+            {ok, KeyBySeqBtree2} = if KSIndexed ->
                 RemKSs = [{[Key, Seq], DocId} || {Key, Seq, DocId} <- SToRem],
-                SKVs1 = SKVs ++ SToAdd,
-                {ok, SBt} = couch_btree:add_remove(View#mrview.seq_btree,
-                                                   SKVs1, RemSKs),
-
-                {ok, KSbt} = couch_btree:add_remove(View#mrview.key_byseq_btree,
-                                                    couch_mrview_util:to_key_seq(SKVs1),
-                                                    RemKSs),
-                {SBt, KSbt};
-            _ -> {nil, nil}
+                couch_btree:add_remove(View#mrview.key_byseq_btree,
+                                       couch_mrview_util:to_key_seq(SKVs1),
+                                       RemKSs);
+            true ->
+                {ok, nil}
+            end,
+            {SeqBtree2, KeyBySeqBtree2};
+        true ->
+            {nil, nil}
         end,
         View#mrview{btree=VBtree2,
-                    seq_btree=SeqBtree2,
-                    key_byseq_btree=KeyBySeqBtree2,
+                    seq_btree=SeqBtree3,
+                    key_byseq_btree=KeyBySeqBtree3,
                     update_seq=NewUpdateSeq}
     end,
 

http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/c0eedd42/src/couch_mrview_util.erl
----------------------------------------------------------------------
diff --git a/src/couch_mrview_util.erl b/src/couch_mrview_util.erl
index 7c639af..ce037d5 100644
--- a/src/couch_mrview_util.erl
+++ b/src/couch_mrview_util.erl
@@ -97,12 +97,13 @@ ddoc_to_mrst(DbName, #doc{id=Id, body={Fields}}) ->
     end,
     {DesignOpts} = proplists:get_value(<<"options">>, Fields, {[]}),
     SeqIndexed = proplists:get_value(<<"seq_indexed">>, DesignOpts, false),
+    KeySeqIndexed = proplists:get_value(<<"keyseq_indexed">>, DesignOpts, false),
 
     {RawViews} = couch_util:get_value(<<"views">>, Fields, {[]}),
     BySrc = lists:foldl(MakeDict, dict:new(), RawViews),
 
     NumViews = fun({_, View}, N) ->
-            {View#mrview{id_num=N, seq_indexed=SeqIndexed}, N+1}
+            {View#mrview{id_num=N, seq_indexed=SeqIndexed, keyseq_indexed=KeySeqIndexed},
N+1}
     end,
     {Views, _} = lists:mapfoldl(NumViews, 0, lists:sort(dict:to_list(BySrc))),
 
@@ -116,7 +117,8 @@ ddoc_to_mrst(DbName, #doc{id=Id, body={Fields}}) ->
         views=Views,
         language=Language,
         design_opts=DesignOpts,
-        seq_indexed=SeqIndexed
+        seq_indexed=SeqIndexed,
+        keyseq_indexed=KeySeqIndexed
     },
     SigInfo = {Views, Language, DesignOpts, couch_index_util:sort_lib(Lib)},
     {ok, IdxState#mrst{sig=couch_util:md5(term_to_binary(SigInfo))}}.
@@ -161,7 +163,7 @@ view_sig(Db, State, View, #mrargs{include_docs=true}=Args) ->
     UpdateSeq = couch_db:get_update_seq(Db),
     PurgeSeq = couch_db:get_purge_seq(Db),
     Bin = term_to_binary({BaseSig, UpdateSeq, PurgeSeq,
-                          State#mrst.seq_indexed}),
+                          State#mrst.seq_indexed, State#mrst.keyseq_indexed}),
     couch_index_util:hexsig(couch_util:md5(Bin));
 view_sig(Db, State, {_Nth, _Lang, View}, Args) ->
     view_sig(Db, State, View, Args);
@@ -170,11 +172,12 @@ view_sig(_Db, State, View, Args0) ->
     UpdateSeq = View#mrview.update_seq,
     PurgeSeq = View#mrview.purge_seq,
     SeqIndexed = View#mrview.seq_indexed,
+    KeySeqIndexed = View#mrview.keyseq_indexed,
     Args = Args0#mrargs{
         preflight_fun=undefined,
         extra=[]
     },
-    Bin = term_to_binary({Sig, UpdateSeq, PurgeSeq, SeqIndexed, Args}),
+    Bin = term_to_binary({Sig, UpdateSeq, PurgeSeq, KeySeqIndexed, SeqIndexed, Args}),
     couch_index_util:hexsig(couch_util:md5(Bin)).
 
 
@@ -202,7 +205,12 @@ init_state(Db, Fd, State, #index_header{
         view_states=[{Bt, nil, nil, USeq, PSeq} || {Bt, USeq, PSeq} <- ViewStates]
         });
 init_state(Db, Fd, State, Header) ->
-    #mrst{language=Lang, views=Views, seq_indexed=SeqIndexed} = State,
+    #mrst{
+        language=Lang,
+        views=Views,
+        seq_indexed=SeqIndexed,
+        keyseq_indexed=KeySeqIndexed
+    } = State,
     #mrheader{
         seq=Seq,
         purge_seq=PurgeSeq,
@@ -219,7 +227,7 @@ init_state(Db, Fd, State, Header) ->
 
     IdBtOpts = [{compression, couch_db:compression(Db)}],
     {ok, IdBtree} = couch_btree:open(IdBtreeState, Fd, IdBtOpts),
-    {ok, LogBtree} = case SeqIndexed of
+    {ok, LogBtree} = case SeqIndexed orelse KeySeqIndexed of
         true -> couch_btree:open(LogBtreeState, Fd, IdBtOpts);
         false -> {ok, nil}
     end,
@@ -266,20 +274,23 @@ open_view(Db, Fd, Lang, {BTState, SeqBTState, KSeqBTState, USeq, PSeq},
View) ->
     ],
     {ok, Btree} = couch_btree:open(BTState, Fd, ViewBtOpts),
 
-    {SeqBtree, KeyBySeqBtree} = case View#mrview.seq_indexed of
-        true ->
-            BySeqReduceFun = fun couch_db_updater:btree_by_seq_reduce/2,
-            ViewSeqBtOpts = [{less, fun less_json_seqs/2},
-                             {reduce, BySeqReduceFun},
-                             {compression, couch_db:compression(Db)}],
-            KeyBySeqBtOpts = [{less, Less},
-                              {reduce, BySeqReduceFun},
-                              {compression, couch_db:compression(Db)}],
-            {ok, SBt} = couch_btree:open(SeqBTState, Fd, ViewSeqBtOpts),
-            {ok, KSBt} = couch_btree:open(KSeqBTState, Fd, KeyBySeqBtOpts),
-            {SBt, KSBt};
-        false ->
-            {nil, nil}
+    BySeqReduceFun = fun couch_db_updater:btree_by_seq_reduce/2,
+    {ok, SeqBtree} = if View#mrview.seq_indexed ->
+        ViewSeqBtOpts = [{less, fun less_json_seqs/2},
+                         {reduce, BySeqReduceFun},
+                         {compression, couch_db:compression(Db)}],
+
+        couch_btree:open(SeqBTState, Fd, ViewSeqBtOpts);
+    true ->
+        {ok, nil}
+    end,
+    {ok, KeyBySeqBtree} = if View#mrview.keyseq_indexed ->
+        KeyBySeqBtOpts = [{less, Less},
+                          {reduce, BySeqReduceFun},
+                          {compression, couch_db:compression(Db)}],
+        couch_btree:open(KSeqBTState, Fd, KeyBySeqBtOpts);
+    true ->
+        {ok, nil}
     end,
 
     View#mrview{btree=Btree,
@@ -335,11 +346,25 @@ reduce_to_count(Reductions) ->
     Count.
 
 %% @doc get all changes for a view
-get_view_changes_count(#mrview{seq_btree=Btree}) ->
-    couch_btree:fold_reduce(
-            Btree, fun(_SeqStart, PartialReds, 0) ->
-                    {ok, couch_btree:final_reduce(Btree, PartialReds)}
-            end,0, []).
+get_view_changes_count(View) ->
+    #mrview{seq_btree=SBtree, key_byseq_btree=KSBtree} = View,
+    CountFun = fun(_SeqStart, PartialReds, 0) ->
+        {ok, couch_btree:final_reduce(SBtree, PartialReds)}
+    end,
+    {ok, Count} = case {SBtree, KSBtree} of
+        {nil, nil} ->
+            {ok, 0};
+        {#btree{}, nil} ->
+            couch_btree:fold_reduce(SBtree, CountFun, 0, []);
+        {nil, #btree{}} ->
+            couch_btree:fold_reduce(KSBtree, CountFun, 0, [])
+    end,
+    case {SBtree, KSBtree} of
+        {#btree{}, #btree{}} ->
+            {ok, Count*2};
+        _ ->
+            {ok, Count}
+    end.
 
 fold(#mrview{btree=Bt}, Fun, Acc, Opts) ->
     WrapperFun = fun(KV, Reds, Acc2) ->
@@ -563,11 +588,17 @@ make_header(State) ->
     } = State,
 
     ViewStates = lists:foldr(fun(V, Acc) ->
-                    {SeqBtState, KSeqBtState} = case V#mrview.seq_indexed of
+                    SeqBtState = case V#mrview.seq_indexed of
+                        true ->
+                            couch_btree:get_state(V#mrview.seq_btree);
+                        _ ->
+                            nil
+                    end,
+                    KSeqBtState = case V#mrview.keyseq_indexed of
                         true ->
-                            {couch_btree:get_state(V#mrview.seq_btree),
-                             couch_btree:get_state(V#mrview.key_byseq_btree)};
-                        _ -> {nil, nil}
+                            couch_btree:get_state(V#mrview.key_byseq_btree);
+                        _ ->
+                            nil
                     end,
                     [{couch_btree:get_state(V#mrview.btree),
                       SeqBtState,
@@ -642,12 +673,14 @@ reset_state(State) ->
         fd=nil,
         qserver=nil,
         seq_indexed=State#mrst.seq_indexed,
+        keyseq_indexed=State#mrst.keyseq_indexed,
         update_seq=0,
         id_btree=nil,
         log_btree=nil,
         views=[View#mrview{btree=nil, seq_btree=nil,
                            key_byseq_btree=nil,
-                           seq_indexed=View#mrview.seq_indexed}
+                           seq_indexed=View#mrview.seq_indexed,
+                           keyseq_indexed=View#mrview.keyseq_indexed}
                || View <- State#mrst.views]
     }.
 
@@ -757,14 +790,18 @@ changes_ekey_opts(_StartSeq, #mrargs{end_key=EKey,
 
 
 
+
 calculate_external_size(IdBt, LogBt, Views) ->
-    SumFun = fun
-        (#mrview{btree=Bt, seq_btree=nil}, Acc) ->
-            sum_btree_sizes(Acc, couch_btree:size(Bt));
-        (#mrview{btree=Bt, seq_btree=SBt, key_byseq_btree=KSBt}, Acc) ->
-            Acc1 = sum_btree_sizes(Acc, couch_btree:size(Bt)),
-            Acc2 = sum_btree_sizes(Acc1, couch_btree:size(SBt)),
-            sum_btree_sizes(Acc2, couch_btree:size(KSBt))
+    SumFun = fun(#mrview{btree=Bt, seq_btree=SBt, key_byseq_btree=KSBt}, Acc) ->
+        Size0 = sum_btree_sizes(Acc, couch_btree:size(Bt)),
+        Size1 = case SBt of
+            nil -> Size0;
+            _ -> sum_btree_sizes(Size0, couch_btree:size(SBt))
+        end,
+        case KSBt of
+            nil -> Size1;
+            _ -> sum_btree_sizes(Size1, couch_btree:size(KSBt))
+        end
     end,
     Size = case LogBt of
         nil ->


Mime
View raw message