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