summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Newson <rnewson@apache.org>2020-07-28 21:38:10 +0100
committerRobert Newson <rnewson@apache.org>2020-07-28 21:38:10 +0100
commit102e250fd92e5ccaad5bdaa0f5a378cd84e7beab (patch)
tree24436634a66fd5325338f0a3a24da28218963876
parentc7e85389243a188db38dcd6426848838d4dfdc0b (diff)
downloadcouchdb-prototype/fdb-layer-ebtree-inclusive_startend.tar.gz
Support inclusive_start/end for group_reduceprototype/fdb-layer-ebtree-inclusive_startend
-rw-r--r--src/ebtree/src/ebtree.erl28
1 files changed, 22 insertions, 6 deletions
diff --git a/src/ebtree/src/ebtree.erl b/src/ebtree/src/ebtree.erl
index b227be035..edbc9c607 100644
--- a/src/ebtree/src/ebtree.erl
+++ b/src/ebtree/src/ebtree.erl
@@ -302,6 +302,8 @@ group_reduce(Db, #tree{} = Tree, StartKey, EndKey, GroupKeyFun, UserAccFun, User
%% @returns the final accumulator.
-type group_key() :: term().
+-type group_option() :: [{inclusive_start, boolean()} | {inclusive_end, boolean()}].
+
-spec group_reduce(
Db :: term(),
Tree :: #tree{},
@@ -310,7 +312,7 @@ group_reduce(Db, #tree{} = Tree, StartKey, EndKey, GroupKeyFun, UserAccFun, User
GroupKeyFun :: fun((term()) -> group_key()),
UserAccFun :: fun(({group_key(), GroupValue :: term()}, Acc0 :: term()) -> Acc1 :: term()),
UserAcc0 :: term(),
- Options :: [fold_option()]) -> Acc1 :: term().
+ Options :: [fold_option() | group_option()]) -> Acc1 :: term().
group_reduce(Db, #tree{} = Tree, StartKey, EndKey, GroupKeyFun, UserAccFun, UserAcc0, Options) ->
Dir = proplists:get_value(dir, Options, fwd),
NoGroupYet = ?MIN,
@@ -318,7 +320,7 @@ group_reduce(Db, #tree{} = Tree, StartKey, EndKey, GroupKeyFun, UserAccFun, User
({visit, Key, Value}, {CurrentGroup, UserAcc, MapAcc, ReduceAcc}) ->
BeforeStart = less_than(Tree, Key, StartKey),
AfterEnd = greater_than(Tree, Key, EndKey),
- InRange = in_range(Tree, StartKey, Key, EndKey),
+ InRange = in_range(Tree, StartKey, Key, EndKey, Options),
KeyGroup = GroupKeyFun(Key),
SameGroup = CurrentGroup =:= KeyGroup,
if
@@ -341,8 +343,8 @@ group_reduce(Db, #tree{} = Tree, StartKey, EndKey, GroupKeyFun, UserAccFun, User
BeforeStart = less_than(Tree, LastKey, StartKey),
AfterEnd = greater_than(Tree, FirstKey, EndKey),
Whole = CurrentGroup =:= GroupKeyFun(FirstKey) andalso CurrentGroup =:= GroupKeyFun(LastKey),
- FirstInRange = in_range(Tree, StartKey, FirstKey, EndKey),
- LastInRange = in_range(Tree, StartKey, LastKey, EndKey),
+ FirstInRange = in_range(Tree, StartKey, FirstKey, EndKey, Options),
+ LastInRange = in_range(Tree, StartKey, LastKey, EndKey, Options),
if
Dir == fwd andalso BeforeStart ->
{skip, {CurrentGroup, UserAcc, MapAcc, ReduceAcc}};
@@ -876,8 +878,22 @@ reduce_values(#tree{} = Tree, Values, Rereduce) when is_list(Values) ->
%% collation functions
-in_range(#tree{} = Tree, StartOfRange, Key, EndOfRange) ->
- greater_than_or_equal(Tree, Key, StartOfRange) andalso less_than_or_equal(Tree, Key, EndOfRange).
+in_range(#tree{} = Tree, StartOfRange, Key, EndOfRange, Options) ->
+ InclusiveStart = proplists:get_value(inclusive_start, Options, true),
+ InclusiveEnd = proplists:get_value(inclusive_end, Options, true),
+ Left = if
+ InclusiveStart ->
+ greater_than_or_equal(Tree, Key, StartOfRange);
+ true ->
+ greater_than(Tree, Key, StartOfRange)
+ end,
+ Right = if
+ InclusiveEnd ->
+ less_than_or_equal(Tree, Key, EndOfRange);
+ true ->
+ less_than(Tree, Key, EndOfRange)
+ end,
+ Left andalso Right.
greater_than(#tree{} = Tree, A, B) ->