summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRandall Leeds <randall@apache.org>2011-07-30 00:37:28 +0000
committerRandall Leeds <randall@apache.org>2011-07-30 00:37:28 +0000
commitdaa640b113907bb28fc9b26e38849f239d353363 (patch)
treed35290acede667148c629f921ad9e31caffae51e
parent6f43183770b858906e6f41e59f65a0513615479d (diff)
Backport of r1152397 from trunk
Call traversal handlers in btree folds Previously the fold function was only invoked for leafs. With this change it's possible to define a fold function which is called for inner nodes and can return a tuple {skip, Acc} in order to skip exploration of the branch. git-svn-id: https://svn.apache.org/repos/asf/couchdb/branches/1.1.x@1152405 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--src/couchdb/couch_btree.erl29
1 files changed, 21 insertions, 8 deletions
diff --git a/src/couchdb/couch_btree.erl b/src/couchdb/couch_btree.erl
index f8c126f3..91bc8f1b 100644
--- a/src/couchdb/couch_btree.erl
+++ b/src/couchdb/couch_btree.erl
@@ -105,9 +105,17 @@ full_reduce(#btree{root={_P, Red}}) ->
% wraps a 2 arity function with the proper 3 arity function
convert_fun_arity(Fun) when is_function(Fun, 2) ->
- fun(KV, _Reds, AccIn) -> Fun(KV, AccIn) end;
+ fun
+ (visit, KV, _Reds, AccIn) -> Fun(KV, AccIn);
+ (traverse, _K, _Red, AccIn) -> {ok, AccIn}
+ end;
convert_fun_arity(Fun) when is_function(Fun, 3) ->
- Fun. % Already arity 3
+ fun
+ (visit, KV, Reds, AccIn) -> Fun(KV, Reds, AccIn);
+ (traverse, _K, _Red, AccIn) -> {ok, AccIn}
+ end;
+convert_fun_arity(Fun) when is_function(Fun, 4) ->
+ Fun. % Already arity 4
make_key_in_end_range_function(#btree{less=Less}, fwd, Options) ->
case couch_util:get_value(end_key_gt, Options) of
@@ -604,12 +612,17 @@ stream_node(Bt, Reds, {Pointer, _Reds}, InRange, Dir, Fun, Acc) ->
stream_kp_node(_Bt, _Reds, [], _InRange, _Dir, _Fun, Acc) ->
{ok, Acc};
-stream_kp_node(Bt, Reds, [{_Key, {Pointer, Red}} | Rest], InRange, Dir, Fun, Acc) ->
- case stream_node(Bt, Reds, {Pointer, Red}, InRange, Dir, Fun, Acc) of
+stream_kp_node(Bt, Reds, [{Key, {Pointer, Red}} | Rest], InRange, Dir, Fun, Acc) ->
+ case Fun(traverse, Key, Red, Acc) of
{ok, Acc2} ->
- stream_kp_node(Bt, [Red | Reds], Rest, InRange, Dir, Fun, Acc2);
- {stop, LastReds, Acc2} ->
- {stop, LastReds, Acc2}
+ case stream_node(Bt, Reds, {Pointer, Red}, InRange, Dir, Fun, Acc2) of
+ {ok, Acc3} ->
+ stream_kp_node(Bt, [Red | Reds], Rest, InRange, Dir, Fun, Acc3);
+ {stop, LastReds, Acc3} ->
+ {stop, LastReds, Acc3}
+ end;
+ {skip, Acc2} ->
+ stream_kp_node(Bt, [Red | Reds], Rest, InRange, Dir, Fun, Acc2)
end.
drop_nodes(_Bt, Reds, _StartKey, []) ->
@@ -670,7 +683,7 @@ stream_kv_node2(Bt, Reds, PrevKVs, [{K,V} | RestKVs], InRange, Dir, Fun, Acc) ->
{stop, {PrevKVs, Reds}, Acc};
true ->
AssembledKV = assemble(Bt, K, V),
- case Fun(AssembledKV, {PrevKVs, Reds}, Acc) of
+ case Fun(visit, AssembledKV, {PrevKVs, Reds}, Acc) of
{ok, Acc2} ->
stream_kv_node2(Bt, Reds, [AssembledKV | PrevKVs], RestKVs, InRange, Dir, Fun, Acc2);
{stop, Acc2} ->