You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by be...@apache.org on 2014/07/13 14:29:45 UTC

[5/7] couch-mrview commit: updated refs/heads/1994-merge-rcouch to 4e0f295

fix: log removed keys

When a key is removed make sure we correctly remove it from the records.


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

Branch: refs/heads/1994-merge-rcouch
Commit: 44a61c32f20512880e081b43c5dedf68a88cf75e
Parents: 91df48a
Author: benoitc <bc...@gmail.com>
Authored: Thu Jul 3 10:45:40 2014 +0200
Committer: benoitc <bc...@gmail.com>
Committed: Thu Jul 3 10:45:40 2014 +0200

----------------------------------------------------------------------
 src/couch_mrview_updater.erl | 65 ++++++++++++++++++++++++++++++---------
 1 file changed, 51 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/44a61c32/src/couch_mrview_updater.erl
----------------------------------------------------------------------
diff --git a/src/couch_mrview_updater.erl b/src/couch_mrview_updater.erl
index be1055c..d6f2713 100644
--- a/src/couch_mrview_updater.erl
+++ b/src/couch_mrview_updater.erl
@@ -251,7 +251,19 @@ insert_results(DocId, Seq, [KVs | RKVs], [{Id, {VKVs, SKVs}} | RVKVs], VKVAcc,
                   [{Id, {FinalKVs, FinalSKVs}} | VKVAcc], VIdKeys0, Log1).
 
 
-write_kvs(State, UpdateSeq, ViewKVs, DocIdKeys, Log) ->
+log_removed([], _, Log) ->
+    Log;
+log_removed([{ok, {DocId, VIdKeys}} | Rest], Seq, Log) ->
+    Log2 = lists:foldl(fun({Id, Keys}, Log1) ->
+                    lists:foldl(fun(Key, Log3) ->
+                                dict:append(DocId, {Id, {Key, Seq, del}}, Log3)
+                        end, Log1, Keys)
+            end, Log, VIdKeys),
+    log_removed(Rest, Seq, Log2);
+log_removed([_ | Rest], Seq, Log) ->
+    log_removed(Rest, Seq, Log).
+
+write_kvs(State, UpdateSeq, ViewKVs, DocIdKeys, Log0) ->
     #mrst{
         id_btree=IdBtree,
         log_btree=LogBtree,
@@ -261,6 +273,9 @@ write_kvs(State, UpdateSeq, ViewKVs, DocIdKeys, Log) ->
     {ok, ToRemove, IdBtree2} = update_id_btree(IdBtree, DocIdKeys, FirstBuild),
     ToRemByView = collapse_rem_keys(ToRemove, dict:new()),
 
+    %% add removed keys to the log
+    Log = log_removed(ToRemove, UpdateSeq, Log0),
+
     {ok, SeqsToAdd, SeqsToRemove, LogBtree2} = case LogBtree of
         nil -> {ok, undefined, undefined, nil};
         _ -> update_log(LogBtree, Log, UpdateSeq, FirstBuild)
@@ -331,31 +346,53 @@ update_log(Btree, Log, _UpdatedSeq, true) ->
     {ok, dict:new(), dict:new(), LogBtree2};
 update_log(Btree, Log, UpdatedSeq, _) ->
     %% build list of updated keys and Id
-    {ToLook, Updated} = dict:fold(fun
-                (Id, [], {IdsAcc, KeysAcc}) ->
-                    {[Id | IdsAcc], KeysAcc};
-                (Id, DIKeys, {IdsAcc, KeysAcc}) ->
-                    KeysAcc1 = lists:foldl(fun({ViewId, {Key, _Seq, _Op}},
-                                               KeysAcc2) ->
-                                    [{Id, ViewId, Key} | KeysAcc2]
-                            end, KeysAcc, DIKeys),
-                {[Id | IdsAcc], KeysAcc1} end, {[], []}, Log),
+    {ToLook, Updated, Removed} = dict:fold(fun
+                (Id, [], {IdsAcc, KeysAcc, RemAcc}) ->
+                    {[Id | IdsAcc], KeysAcc, RemAcc};
+                (Id, DIKeys, {IdsAcc, KeysAcc, RemAcc}) ->
+                    {KeysAcc1, RemAcc1} = lists:foldl(fun
+                                ({ViewId, {Key, _Seq, Op}},
+                                 {KeysAcc2, RemAcc2}) ->
+                                    KeysAcc3 = [{Id, ViewId, Key} | KeysAcc2],
+                                    RemAcc3 = case Op of
+                                        add -> RemAcc2;
+                                        del -> [{Id, ViewId, Key} | RemAcc2]
+                                    end,
+                                    {KeysAcc3, RemAcc3}
+                            end, {KeysAcc, RemAcc}, DIKeys),
+                    {[Id | IdsAcc], KeysAcc1, RemAcc1}
+            end, {[], [], []}, Log),
 
     RemValue = {[{<<"_removed">>, true}]},
-    {Log1, AddAcc, DelAcc} = walk_log(Btree, fun({DocId, VIdKeys},
-                                                          {Log2, AddAcc2, DelAcc2}) ->
+    {Log1, AddAcc, DelAcc} = walk_log(Btree, fun({DocId, VIdKeys}, {Log2, AddAcc2, DelAcc2}) ->
 
                 {Log3, AddAcc3, DelAcc3} = lists:foldl(fun({ViewId,{Key, Seq, Op}},
                                                            {Log4, AddAcc4, DelAcc4}) ->
 
-                            case lists:member({DocId, ViewId, Key}, Updated) of
+                            IsUpdated = lists:member({DocId, ViewId, Key},
+                                                     Updated),
+                            IsRemoved = lists:member({DocId, ViewId, Key},
+                                                     Removed),
+
+                            case IsUpdated of
                                 true ->
                                     %% the log is updated, deleted old
                                     %% record from the view
                                     DelAcc5 = dict:append(ViewId,
                                                           {Key, Seq, DocId},
                                                           DelAcc4),
-                                    {Log4, AddAcc4, DelAcc5};
+                                    %% check if the key has been deleted
+                                    %% and if true, update the view with a
+                                    %% removed record.
+                                    AddAcc5 = case IsRemoved of
+                                        false -> AddAcc4;
+                                        true ->
+                                            dict:append(ViewId,
+                                                        {{UpdatedSeq, Key},
+                                                         {DocId, RemValue}},
+                                                        AddAcc4)
+                                    end,
+                                    {Log4, AddAcc5, DelAcc5};
                                 false when Op /= del ->
                                     %% an update operation has been
                                     %% logged for this key. We must now