summaryrefslogtreecommitdiff
path: root/src/couchdb
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 /src/couchdb
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
Diffstat (limited to 'src/couchdb')
-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} ->