Browse files

Add keu_compare/3 for sorting keys in backend's disk-order

  • Loading branch information...
1 parent 87ab2c0 commit 10c07ceaabcc12b63f447cbca3267b1ef98a1170 @Vagabond Vagabond committed Aug 23, 2012
View
1 src/riak_kv_backend.erl
@@ -61,6 +61,7 @@ behaviour_info(callbacks) ->
% FoldObjectsFun(Bucket, Key, Object, Acc)
{is_empty,1}, % (State)
{status,1}, % (State)
+ {key_compare,3}, % ({Bucket1, Key1}, {Bucket2, Key2}, State)
{callback,3}]; % (Ref, Msg, State) ->
behaviour_info(_Other) ->
undefined.
View
4 src/riak_kv_bitcask_backend.erl
@@ -40,6 +40,7 @@
fold_objects/4,
is_empty/1,
status/1,
+ key_compare/3,
callback/3]).
%% Helper API
@@ -355,6 +356,9 @@ status(#state{ref=Ref}) ->
{KeyCount, Status} = bitcask:status(Ref),
[{key_count, KeyCount}, {status, Status}].
+key_compare(BKey1, BKey2, #state{ref=Ref}) ->
+ bitcask:get_offset(Ref, term_to_binary(BKey1)) =<
+ bitcask:get_offset(Ref, term_to_binary(BKey2)).
%% @doc Register an asynchronous callback
-spec callback(reference(), any(), state()) -> {ok, state()}.
View
6 src/riak_kv_eleveldb_backend.erl
@@ -38,6 +38,7 @@
fold_objects/4,
is_empty/1,
status/1,
+ key_compare/3,
callback/3]).
-compile({inline, [
@@ -302,6 +303,11 @@ status(State) ->
{ok, Stats} = eleveldb:status(State#state.ref, <<"leveldb.stats">>),
[{stats, Stats}].
+key_compare({Bucket1, Key1}, {Bucket2, Key2}, _State) ->
+ %% shouldn't need to use to_object_key because sext preserves the erlang
+ %% term order
+ {o, Bucket1, Key1} >= {o, Bucket2, Key2}.
+
%% @doc Register an asynchronous callback
-spec callback(reference(), any(), state()) -> {ok, state()}.
callback(_Ref, _Msg, State) ->
View
6 src/riak_kv_memory_backend.erl
@@ -54,6 +54,7 @@
fold_objects/4,
is_empty/1,
status/1,
+ key_compare/3,
callback/3]).
%% "Testing" backend API
@@ -355,6 +356,11 @@ status(#state{data_ref=DataRef,
{time_table_status, TimeStatus}]
end.
+key_compare(BKey1, BKey2, _State) ->
+ %% order in the memory backend should not matter, but at least be
+ %% deterministic
+ BKey1 =< BKey2.
+
%% @doc Register an asynchronous callback
-spec callback(reference(), any(), state()) -> {ok, state()}.
callback(_Ref, _Msg, State) ->
View
27 src/riak_kv_multi_backend.erl
@@ -38,6 +38,7 @@
fold_objects/4,
is_empty/1,
status/1,
+ key_compare/3,
callback/3]).
-ifdef(TEST).
@@ -316,6 +317,23 @@ status(#state{backends=Backends}) ->
%% @TODO Reexamine how this is handled
[{N, Mod:status(ModState)} || {N, Mod, ModState} <- Backends].
+key_compare({Bucket, Key1}, {Bucket, Key2}, State) ->
+ %% both keys in same bucket
+ {_Name, Module, SubState} = get_backend(Bucket, State),
+ Module:key_compare({Bucket, Key1}, {Bucket, Key2}, SubState);
+key_compare({Bucket1, Key1}, {Bucket2, Key2}, State) ->
+ {Name1, Module1, SubState1} = get_backend(Bucket1, State),
+ {Name2, _Module2, _SubState2} = get_backend(Bucket2, State),
+ case Name1 == Name2 of
+ true ->
+ %% same underlying backend
+ Module1:key_compare({Bucket1, Key1}, {Bucket2, Key2}, SubState1);
+ false ->
+ %% different buckets, use the order of the buckets in the list as
+ %% the sort order
+ backend_index(Name1, State) =< backend_index(Name2, State)
+ end.
+
%% @doc Register an asynchronous callback
-spec callback(reference(), any(), state()) -> {ok, state()}.
callback(Ref, Msg, #state{backends=Backends}=State) ->
@@ -447,6 +465,15 @@ error_filter({error, _, _}) ->
error_filter(_) ->
false.
+%% @private
+backend_index(Name, State) ->
+ backend_index(Name, State#state.backends, 0).
+
+backend_index(Name, [{Name, _Module, _SubState}|_T], Index) ->
+ Index;
+backend_index(Name, [_H|Tail], Index) ->
+ backend_index(Name, Tail, Index+1).
+
%% ===================================================================
%% EUnit tests
%% ===================================================================
View
4 src/riak_kv_yessir_backend.erl
@@ -94,6 +94,7 @@
fold_objects/4,
is_empty/1,
status/1,
+ key_compare/3,
callback/3]).
-ifdef(TEST).
@@ -254,6 +255,9 @@ is_empty(_S) ->
status(#state{op_put = Puts, op_get = Gets, op_delete = Deletes}) ->
[{puts, Puts}, {gets, Gets}, {deletes, Deletes}].
+key_compare(BKey1, BKey2, _State) ->
+ BKey1 =< BKey2.
+
%% @doc Register an asynchronous callback
-spec callback(reference(), any(), state()) -> {ok, state()}.
callback(_Ref, _Whatever, S) ->

0 comments on commit 10c07ce

Please sign in to comment.