summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Vatamaniuc <vatamane@gmail.com>2021-09-23 18:43:14 -0400
committerNick Vatamaniuc <nickva@users.noreply.github.com>2021-09-24 16:29:42 -0400
commit4f33f14deb733f36cf0df03aedceebc746716d8c (patch)
treef7e29858b9b1d8a266ffd61c9429a2bf76505f86
parent22189ea6ad3665639bd3223d9ef915fe2561e2d1 (diff)
downloadcouchdb-4f33f14deb733f36cf0df03aedceebc746716d8c.tar.gz
Make view merge row aggregation in fabric stable
We do that by matching the comparator function behavior used during row merging [1] in with the comparison function used when sorting the rows on view shards [2]. This goes along with the constraint in the lists:merge/3 docs which indicates that the input lists should be sorted according to the same comparator [3] as the one passed to the lists:merge/3 call. The stability of returned rows results from the case when both keys match as equal. Now `lists:merge/3` will favor the element in the existing rows list instead of always replacing [4] the older matching row with the last arriving row, since now `less(A, A)` will be `false`, while previously it was `true`. The fix was found by Adam when discussing issue #3750 https://github.com/apache/couchdb/issues/3750#issuecomment-920947424 Co-author: Adam Kocoloski <kocolosk@apache.org> [1] https://github.com/apache/couchdb/blob/3.x/src/fabric/src/fabric_view_map.erl#L244-L248 [2] https://github.com/apache/couchdb/blob/3.x/src/couch_mrview/src/couch_mrview_util.erl#L1103-L1107 [3] https://erlang.org/doc/man/lists.html#merge-3 [4] https://github.com/erlang/otp/blob/master/lib/stdlib/src/lists.erl#L2668-L2675
-rw-r--r--src/fabric/src/fabric_view.erl1
-rw-r--r--src/fabric/src/fabric_view_map.erl1
2 files changed, 0 insertions, 2 deletions
diff --git a/src/fabric/src/fabric_view.erl b/src/fabric/src/fabric_view.erl
index 425f864c4..bd5e42f09 100644
--- a/src/fabric/src/fabric_view.erl
+++ b/src/fabric/src/fabric_view.erl
@@ -298,7 +298,6 @@ transform_row(#view_row{key=Key, id=_Id, value=_Value, doc={error,Reason}}) ->
transform_row(#view_row{key=Key, id=Id, value=Value, doc=Doc}) ->
{row, [{id,Id}, {key,Key}, {value,Value}, {doc,Doc}]}.
-compare(_, _, A, A) -> true;
compare(fwd, <<"raw">>, A, B) -> A < B;
compare(rev, <<"raw">>, A, B) -> B < A;
compare(fwd, _, A, B) -> couch_ejson_compare:less_json(A, B);
diff --git a/src/fabric/src/fabric_view_map.erl b/src/fabric/src/fabric_view_map.erl
index 8ab808314..adfe7d648 100644
--- a/src/fabric/src/fabric_view_map.erl
+++ b/src/fabric/src/fabric_view_map.erl
@@ -241,7 +241,6 @@ merge_row(Dir, Collation, KeyDict0, Row, Rows0) ->
{Rows1, KeyDict1}
end.
-compare(_, _, A, A) -> true;
compare(fwd, <<"raw">>, A, B) -> A < B;
compare(rev, <<"raw">>, A, B) -> B < A;
compare(fwd, _, A, B) -> couch_ejson_compare:less_json_ids(A, B);