Add backwards compatible key_group_level option This adds a new btree reduce fold option called `key_group_level` that can have the value `exact`, `0`, or `N` where `N` is any positive integer. The reason for adding this is so that calling code can pass a group level option instead of a function for key grouping. The important point is that the new option uses the btree's defined `less` operator to test equality which means that ICU collation is used for key grouping on most views.
BugzId: 19776 Project: http://git-wip-us.apache.org/repos/asf/couchdb-couch/repo Commit: http://git-wip-us.apache.org/repos/asf/couchdb-couch/commit/1d6c18e5 Tree: http://git-wip-us.apache.org/repos/asf/couchdb-couch/tree/1d6c18e5 Diff: http://git-wip-us.apache.org/repos/asf/couchdb-couch/diff/1d6c18e5 Branch: refs/heads/windsor-merge-209 Commit: 1d6c18e54478765ba4cda4379f0504a441bf5c9e Parents: caffc58 Author: Paul J. Davis <[email protected]> Authored: Wed May 29 13:19:32 2013 -0500 Committer: Robert Newson <[email protected]> Committed: Mon Aug 4 16:40:39 2014 +0100 ---------------------------------------------------------------------- src/couch_btree.erl | 58 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/1d6c18e5/src/couch_btree.erl ---------------------------------------------------------------------- diff --git a/src/couch_btree.erl b/src/couch_btree.erl index 9caceb8..e9d1ea8 100644 --- a/src/couch_btree.erl +++ b/src/couch_btree.erl @@ -73,7 +73,7 @@ fold_reduce(#btree{root=Root}=Bt, Fun, Acc, Options) -> Dir = couch_util:get_value(dir, Options, fwd), StartKey = couch_util:get_value(start_key, Options), InEndRangeFun = make_key_in_end_range_function(Bt, Dir, Options), - KeyGroupFun = couch_util:get_value(key_group_fun, Options, fun(_,_) -> true end), + KeyGroupFun = get_group_fun(Bt, Options), try {ok, Acc2, GroupedRedsAcc2, GroupedKVsAcc2, GroupedKey2} = reduce_stream_node(Bt, Dir, Root, StartKey, InEndRangeFun, undefined, [], [], @@ -103,6 +103,62 @@ size(#btree{root = {_P, _Red}}) -> size(#btree{root = {_P, _Red, Size}}) -> Size. +get_group_fun(Bt, Options) -> + case couch_util:get_value(key_group_level, Options) of + exact -> + make_group_fun(Bt, exact); + 0 -> + fun(_, _) -> true end; + N when is_integer(N), N > 0 -> + make_group_fun(Bt, N); + undefined -> + couch_util:get_value(key_group_fun, Options, fun(_,_) -> true end) + end. + +make_group_fun(Bt, exact) -> + fun({Key1, _}, {Key2, _}) -> + case less(Bt, {Key1, nil}, {Key2, nil}) of + false -> + case less(Bt, {Key2, nil}, {Key1, nil}) of + false -> + true; + _ -> + false + end; + _ -> + false + end + end; +make_group_fun(Bt, GroupLevel) when is_integer(GroupLevel), GroupLevel > 0 -> + fun + ({[_|_] = Key1, _}, {[_|_] = Key2, _}) -> + SL1 = lists:sublist(Key1, GroupLevel), + SL2 = lists:sublist(Key2, GroupLevel), + case less(Bt, {SL1, nil}, {SL2, nil}) of + false -> + case less(Bt, {SL2, nil}, {SL1, nil}) of + false -> + true; + _ -> + false + end; + _ -> + false + end; + ({Key1, _}, {Key2, _}) -> + case less(Bt, {Key1, nil}, {Key2, nil}) of + false -> + case less(Bt, {Key2, nil}, {Key1, nil}) of + false -> + true; + _ -> + false + end; + _ -> + false + end + end. + % wraps a 2 arity function with the proper 3 arity function convert_fun_arity(Fun) when is_function(Fun, 2) -> fun
