diff options
author | Nick Vatamaniuc <vatamane@gmail.com> | 2021-09-23 18:43:14 -0400 |
---|---|---|
committer | Nick Vatamaniuc <nickva@users.noreply.github.com> | 2021-09-24 16:29:42 -0400 |
commit | 4f33f14deb733f36cf0df03aedceebc746716d8c (patch) | |
tree | f7e29858b9b1d8a266ffd61c9429a2bf76505f86 | |
parent | 22189ea6ad3665639bd3223d9ef915fe2561e2d1 (diff) | |
download | couchdb-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.erl | 1 | ||||
-rw-r--r-- | src/fabric/src/fabric_view_map.erl | 1 |
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); |