Browse files

Backend module abstracted

Now we can switch between leveldb and others
  • Loading branch information...
1 parent 8113c38 commit 753cc5bdbc11a51df7b8bee02d8a1904c095e1a8 Fernando "Brujo" Benavides committed Nov 3, 2011
Showing with 333 additions and 260 deletions.
  1. +1 −0 Emakefile
  2. +2 −2 rebar.config
  3. +71 −0 src/backends/edis_eleveldb_backend.erl
  4. +25 −0 src/edis_backend.erl
  5. +4 −2 src/edis_config.erl
  6. +230 −256 src/edis_db.erl
View
1 Emakefile
@@ -1,3 +1,4 @@
{"src/*", [warn_unused_vars, warn_export_all, warn_shadow_vars, warn_unused_import, warn_unused_function, warn_bif_clash, warn_unused_record, warn_deprecated_function, warn_obsolete_guard, strict_validation, report, warn_export_vars, warn_exported_vars, warn_missing_spec, warn_untyped_record, debug_info, {outdir, "ebin"}, {i, "include"}, {i, "deps/elog/include"}]}.
+{"src/*/*", [warn_unused_vars, warn_export_all, warn_shadow_vars, warn_unused_import, warn_unused_function, warn_bif_clash, warn_unused_record, warn_deprecated_function, warn_obsolete_guard, strict_validation, report, warn_export_vars, warn_exported_vars, warn_missing_spec, warn_untyped_record, debug_info, {outdir, "ebin"}, {i, "include"}, {i, "deps/elog/include"}]}.
{"test/*", [warn_unused_vars, warn_shadow_vars, warn_unused_import, warn_unused_function, warn_bif_clash, warn_unused_record, warn_deprecated_function, warn_obsolete_guard, strict_validation, report, warn_export_vars, warn_exported_vars, warn_missing_spec, warn_untyped_record, debug_info, {outdir, "ebin"}, {i, "include"}, {i, "deps/elog/include"}]}.
{"test/*/*", [warn_unused_vars, warn_export_all, warn_shadow_vars, warn_unused_import, warn_unused_function, warn_bif_clash, warn_unused_record, warn_deprecated_function, warn_obsolete_guard, strict_validation, report, warn_export_vars, warn_exported_vars, warn_missing_spec, warn_untyped_record, debug_info, {outdir, "ebin"}, {i, "include"}, {i, "deps/elog/include"}]}.
View
4 rebar.config
@@ -2,8 +2,8 @@
{erldis, "\.*", {git, "git://github.com/inaka/erldis.git", "master"}},
{eleveldb, "\.*", {git, "git@github.com:inaka/eleveldb.git", "master"}}]}.
{require_otp_vsn, "R14"}.
-{erl_first_files, ["test/edis_bench.erl"]}.
-{erl_opts, [{src_dirs, ["src", "tests", "test/benchmarks"]},
+{erl_first_files, ["src/edis_backend.erl", "test/edis_bench.erl"]}.
+{erl_opts, [{src_dirs, ["src", "src/backends", "tests", "test/benchmarks"]},
{i, "deps/elog/include"},
warn_unused_vars,
warn_export_all,
View
71 src/backends/edis_eleveldb_backend.erl
@@ -0,0 +1,71 @@
+%%%-------------------------------------------------------------------
+%%% @author Fernando Benavides <fernando.benavides@inakanetworks.com>
+%%% @author Chad DePue <chad@inakanetworks.com>
+%%% @copyright (C) 2011 InakaLabs SRL
+%%% @doc leveldb based backend
+%%% @end
+%%%-------------------------------------------------------------------
+-module(edis_eleveldb_backend).
+-author('Fernando Benavides <fernando.benavides@inakanetworks.com>').
+-author('Chad DePue <chad@inakanetworks.com>').
+
+-behaviour(edis_backend).
+
+-include("edis.hrl").
+
+-record(ref, {db :: eleveldb:db_ref(),
+ file :: string()}).
+-opaque ref() :: #ref{}.
+-export_type([ref/0]).
+
+-export([init/3, write/2, put/3, delete/2, fold/3, is_empty/1, destroy/1, status/1, get/2]).
+
+%% ====================================================================
+%% Behaviour functions
+%% ====================================================================
+-spec init(string(), non_neg_integer(), eleveldb:open_options()) -> {ok, ref()} | {error, term()}.
+init(Dir, Index, Options) ->
+ File = Dir ++ "/edis-" ++ integer_to_list(Index),
+ case eleveldb:open(File, Options) of
+ {ok, Db} -> {ok, #ref{db = Db, file = File}};
+ Error -> Error
+ end.
+
+-spec write(ref(), edis_backend:write_actions()) -> ok | {error, term()}.
+write(#ref{db = Db}, Actions) ->
+ ParseAction = fun({put, Key, Item}) -> {put, Key, erlang:term_to_binary(Item)};
+ (Action) -> Action
+ end,
+ eleveldb:write(Db, lists:map(ParseAction, Actions), []).
+
+-spec put(ref(), binary(), #edis_item{}) -> ok | {error, term()}.
+put(#ref{db = Db}, Key, Item) ->
+ eleveldb:put(Db, Key, erlang:term_to_binary(Item), []).
+
+-spec delete(ref(), binary()) -> ok | {error, term()}.
+delete(#ref{db = Db}, Key) ->
+ eleveldb:delete(Db, Key, []).
+
+-spec fold(ref(), edis_backend:fold_fun(), term()) -> term().
+fold(#ref{db = Db}, Fun, InitValue) ->
+ eleveldb:fold(
+ Db,
+ fun({_Key, Bin}, Acc) ->
+ Fun(erlang:binary_to_term(Bin), Acc)
+ end, InitValue, [{fill_cache, false}]).
+
+-spec is_empty(ref()) -> boolean().
+is_empty(#ref{db = Db}) -> eleveldb:is_empty(Db).
+
+-spec destroy(ref()) -> ok | {error, term()}.
+destroy(#ref{file = File}) -> eleveldb:destroy(File, []).
+
+-spec status(ref()) -> {ok, binary()} | error.
+status(#ref{db = Db}) -> eleveldb:status(Db, <<"leveldb.stats">>).
+
+-spec get(ref(), binary()) -> #edis_item{} | not_found | {error, term()}.
+get(#ref{db = Db}, Key) ->
+ case eleveldb:get(Db, Key, []) of
+ {ok, Bin} -> erlang:binary_to_term(Bin);
+ NotFoundOrError -> NotFoundOrError
+ end.
View
25 src/edis_backend.erl
@@ -0,0 +1,25 @@
+%%%-------------------------------------------------------------------
+%%% @author Fernando Benavides <fernando.benavides@inakanetworks.com>
+%%% @author Chad DePue <chad@inakanetworks.com>
+%%% @copyright (C) 2011 InakaLabs SRL
+%%% @doc DB backend behaviour for edis
+%%% @end
+%%%-------------------------------------------------------------------
+-module(edis_backend).
+-author('Fernando Benavides <fernando.benavides@inakanetworks.com>').
+-author('Chad DePue <chad@inakanetworks.com>').
+
+-include("edis.hrl").
+
+-type write_actions() :: [{put, Key::binary(), Value::#edis_item{}} |
+ {delete, Key::binary()} |
+ clear].
+-type fold_fun() :: fun((Item::#edis_item{}, any()) -> any()).
+-export_type([write_actions/0, fold_fun/0]).
+
+-export([behaviour_info/1]).
+
+-spec behaviour_info(callbacks|term()) -> undefined | [{atom(), non_neg_integer()}].
+behaviour_info(callbacks) -> [{init, 3}, {write, 2}, {put, 3}, {delete, 2}, {is_empty, 1},
+ {destroy, 1}, {status, 1}, {get, 2}];
+behaviour_info(_) -> undefined.
View
6 src/edis_config.erl
@@ -13,7 +13,7 @@
-include("edis.hrl").
--type config_option() :: listener_port_range | client_timeout | databases | requirepass | dir.
+-type config_option() :: listener_port_range | client_timeout | databases | requirepass | dir | backend.
-spec set(config_option(), term()) -> ok.
set(listener_port_range, {P1, P2}) when is_integer(P1), is_integer(P2), P1 =< P2 ->
@@ -39,7 +39,7 @@ set(dir, Dir) when is_binary(Dir) ->
ok = application:set_env(edis, dir, binary_to_list(Dir)),
edis_db_sup:reload();
set(dir, Param) ->
- ?THROW("Invalid password: ~p~n", [Param]),
+ ?THROW("Invalid dir: ~p~n", [Param]),
throw(invalid_param);
set(Param, Value) ->
?THROW("Unsupported param: ~p: ~p~n", [Param, Value]),
@@ -56,6 +56,8 @@ get(requirepass) ->
get(requirepass, undefined);
get(dir) ->
get(dir, "./db/");
+get(backend) ->
+ get(backend, {edis_eleveldb_backend, [{create_if_missing, true}]});
get(Pattern) ->
[{K, V} ||
{K, V} <- application:get_all_env(edis),
View
486 src/edis_db.erl
@@ -24,7 +24,8 @@
-export_type([item_encoding/0, item_type/0]).
-record(state, {index :: non_neg_integer(),
- db :: eleveldb:db_ref(),
+ backend_mod :: atom(),
+ backend_ref :: term(),
start_time :: pos_integer(),
accesses :: dict(),
updates :: dict(),
@@ -79,13 +80,14 @@ run(Db, Command, Timeout) ->
-spec init(non_neg_integer()) -> {ok, state()} | {stop, any()}.
init(Index) ->
_ = random:seed(erlang:now()),
- case eleveldb:open(edis_config:get(dir) ++ "/edis-" ++ integer_to_list(Index), [{create_if_missing, true}]) of
+ {Mod, InitArgs} = edis_config:get(backend),
+ case Mod:init(edis_config:get(dir), Index, InitArgs) of
{ok, Ref} ->
- {ok, #state{index = Index, db = Ref, last_save = edis_util:timestamp(),
- start_time = edis_util:now(), accesses = dict:new(), updates = dict:new(),
- blocked_list_ops = dict:new()}};
+ {ok, #state{index = Index, backend_mod = Mod, backend_ref = Ref,
+ last_save = edis_util:timestamp(), start_time = edis_util:now(),
+ accesses = dict:new(), updates = dict:new(), blocked_list_ops = dict:new()}};
{error, Reason} ->
- ?THROW("Couldn't start level db #~p:~b\t~p~n", [Index, Reason]),
+ ?THROW("Couldn't start backend (~p): ~p~n", [{Mod, InitArgs}, Reason]),
{stop, Reason}
end.
@@ -98,7 +100,7 @@ handle_call(#edis_command{cmd = <<"ECHO">>, args = [Word]}, _From, State) ->
%% -- Strings --------------------------------------------------------------------------------------
handle_call(#edis_command{cmd = <<"APPEND">>, args = [Key, Value]}, _From, State) ->
Reply =
- update(State#state.db, Key, string, raw,
+ update(State#state.backend_mod, State#state.backend_ref, Key, string, raw,
fun(Item = #edis_item{value = OldV}) ->
NewV = <<OldV/binary, Value/binary>>,
{erlang:size(NewV), Item#edis_item{value = NewV}}
@@ -108,7 +110,7 @@ handle_call(#edis_command{cmd = <<"DECR">>, args = [Key]}, From, State) ->
handle_call(#edis_command{cmd = <<"DECRBY">>, args = [Key, 1]}, From, State);
handle_call(#edis_command{cmd = <<"DECRBY">>, args = [Key, Decrement]}, _From, State) ->
Reply =
- update(State#state.db, Key, string, raw,
+ update(State#state.backend_mod, State#state.backend_ref, Key, string, raw,
fun(Item = #edis_item{value = OldV}) ->
try edis_util:binary_to_integer(OldV) of
OldInt ->
@@ -122,15 +124,15 @@ handle_call(#edis_command{cmd = <<"DECRBY">>, args = [Key, Decrement]}, _From, S
{reply, Reply, stamp(Key, write, State)};
handle_call(#edis_command{cmd = <<"GET">>, args = [Key]}, _From, State) ->
Reply =
- case get_item(State#state.db, string, Key) of
+ case get_item(State#state.backend_mod, State#state.backend_ref, string, Key) of
#edis_item{type = string, value = Value} -> {ok, Value};
not_found -> {ok, undefined};
{error, Reason} -> {error, Reason}
end,
{reply, Reply, stamp(Key, read, State)};
handle_call(#edis_command{cmd = <<"GETBIT">>, args = [Key, Offset]}, _From, State) ->
Reply =
- case get_item(State#state.db, string, Key) of
+ case get_item(State#state.backend_mod, State#state.backend_ref, string, Key) of
#edis_item{value =
<<_:Offset/unit:1, Bit:1/unit:1, _Rest/bitstring>>} -> {ok, Bit};
#edis_item{} -> {ok, 0}; %% Value is shorter than offset
@@ -141,7 +143,7 @@ handle_call(#edis_command{cmd = <<"GETBIT">>, args = [Key, Offset]}, _From, Stat
handle_call(#edis_command{cmd = <<"GETRANGE">>, args = [Key, Start, End]}, _From, State) ->
Reply =
try
- case get_item(State#state.db, string, Key) of
+ case get_item(State#state.backend_mod, State#state.backend_ref, string, Key) of
#edis_item{value = Value} ->
L = erlang:size(Value),
StartPos =
@@ -171,7 +173,7 @@ handle_call(#edis_command{cmd = <<"GETRANGE">>, args = [Key, Start, End]}, _From
{reply, Reply, stamp(Key, read, State)};
handle_call(#edis_command{cmd = <<"GETSET">>, args = [Key, Value]}, _From, State) ->
Reply =
- update(State#state.db, Key, string, raw,
+ update(State#state.backend_mod, State#state.backend_ref, Key, string, raw,
fun(Item = #edis_item{value = OldV}) ->
{OldV, Item#edis_item{value = Value}}
end, undefined),
@@ -180,7 +182,7 @@ handle_call(#edis_command{cmd = <<"INCR">>, args = [Key]}, From, State) ->
handle_call(#edis_command{cmd = <<"INCRBY">>, args = [Key, 1]}, From, State);
handle_call(#edis_command{cmd = <<"INCRBY">>, args = [Key, Increment]}, _From, State) ->
Reply =
- update(State#state.db, Key, string, raw,
+ update(State#state.backend_mod, State#state.backend_ref, Key, string, raw,
fun(Item = #edis_item{value = OldV}) ->
try edis_util:binary_to_integer(OldV) of
OldInt ->
@@ -196,7 +198,7 @@ handle_call(#edis_command{cmd = <<"MGET">>, args = Keys}, _From, State) ->
Reply =
lists:foldr(
fun(Key, {ok, AccValues}) ->
- case get_item(State#state.db, string, Key) of
+ case get_item(State#state.backend_mod, State#state.backend_ref, string, Key) of
#edis_item{type = string, value = Value} -> {ok, [Value | AccValues]};
not_found -> {ok, [undefined | AccValues]};
{error, bad_item_type} -> {ok, [undefined | AccValues]};
@@ -207,36 +209,34 @@ handle_call(#edis_command{cmd = <<"MGET">>, args = Keys}, _From, State) ->
{reply, Reply, stamp(Keys, read, State)};
handle_call(#edis_command{cmd = <<"MSET">>, args = KVs}, _From, State) ->
Reply =
- eleveldb:write(State#state.db,
- [{put, Key,
- erlang:term_to_binary(
- #edis_item{key = Key, encoding = raw,
- type = string, value = Value})} || {Key, Value} <- KVs],
- []),
+ (State#state.backend_mod):write(
+ State#state.backend_ref,
+ [{put, Key,
+ #edis_item{key = Key, encoding = raw,
+ type = string, value = Value}} || {Key, Value} <- KVs]),
{reply, Reply, stamp([K || {K, _} <- KVs], write, State)};
handle_call(#edis_command{cmd = <<"MSETNX">>, args = KVs}, _From, State) ->
{Reply, Action} =
case lists:any(
fun({Key, _}) ->
- exists_item(State#state.db, Key)
+ exists_item(State#state.backend_mod, State#state.backend_ref, Key)
end, KVs) of
true ->
{{ok, 0}, read};
false ->
- ok = eleveldb:write(State#state.db,
- [{put, Key,
- erlang:term_to_binary(
- #edis_item{key = Key, encoding = raw,
- type = string, value = Value})} || {Key, Value} <- KVs],
- []),
+ ok = (State#state.backend_mod):write(
+ State#state.backend_ref,
+ [{put, Key,
+ #edis_item{key = Key, encoding = raw,
+ type = string, value = Value}} || {Key, Value} <- KVs]),
{{ok, 1}, write}
end,
{reply, Reply, stamp([K || {K, _} <- KVs], Action, State)};
handle_call(#edis_command{cmd = <<"SET">>, args = [Key, Value]}, From, State) ->
handle_call(#edis_command{cmd = <<"MSET">>, args = [{Key, Value}]}, From, State);
handle_call(#edis_command{cmd = <<"SETBIT">>, args = [Key, Offset, Bit]}, _From, State) ->
Reply =
- update(State#state.db, Key, string, raw,
+ update(State#state.backend_mod, State#state.backend_ref, Key, string, raw,
fun(Item = #edis_item{value = <<Prefix:Offset/unit:1, OldBit:1/unit:1, _Rest/bitstring>>}) ->
{OldBit,
Item#edis_item{value = <<Prefix:Offset/unit:1, Bit:1/unit:1, _Rest/bitstring>>}};
@@ -253,19 +253,18 @@ handle_call(#edis_command{cmd = <<"SETBIT">>, args = [Key, Offset, Bit]}, _From,
{reply, Reply, stamp(Key, write, State)};
handle_call(#edis_command{cmd = <<"SETEX">>, args = [Key, Seconds, Value]}, _From, State) ->
Reply =
- eleveldb:put(
- State#state.db, Key,
- erlang:term_to_binary(
+ (State#state.backend_mod):put(
+ State#state.backend_ref, Key,
#edis_item{key = Key, type = string, encoding = raw,
expire = edis_util:now() + Seconds,
- value = Value}), []),
+ value = Value}),
{reply, Reply, stamp(Key, write, State)};
handle_call(#edis_command{cmd = <<"SETNX">>, args = [Key, Value]}, From, State) ->
handle_call(#edis_command{cmd = <<"MSETNX">>, args = [{Key, Value}]}, From, State);
handle_call(#edis_command{cmd = <<"SETRANGE">>, args = [Key, Offset, Value]}, _From, State) ->
Length = erlang:size(Value),
Reply =
- update(State#state.db, Key, string, raw,
+ update(State#state.backend_mod, State#state.backend_ref, Key, string, raw,
fun(Item = #edis_item{value = <<Prefix:Offset/binary, _:Length/binary, Suffix/binary>>}) ->
NewV = <<Prefix/binary, Value/binary, Suffix/binary>>,
{erlang:size(NewV), Item#edis_item{value = NewV}};
@@ -280,7 +279,7 @@ handle_call(#edis_command{cmd = <<"SETRANGE">>, args = [Key, Offset, Value]}, _F
{reply, Reply, stamp(Key, write, State)};
handle_call(#edis_command{cmd = <<"STRLEN">>, args = [Key]}, _From, State) ->
Reply =
- case get_item(State#state.db, string, Key) of
+ case get_item(State#state.backend_mod, State#state.backend_ref, string, Key) of
#edis_item{value = Value} -> {ok, erlang:size(Value)};
not_found -> {ok, 0};
{error, Reason} -> {error, Reason}
@@ -289,16 +288,16 @@ handle_call(#edis_command{cmd = <<"STRLEN">>, args = [Key]}, _From, State) ->
%% -- Keys -----------------------------------------------------------------------------------------
handle_call(#edis_command{cmd = <<"DEL">>, args = Keys}, _From, State) ->
DeleteActions =
- [{delete, Key} || Key <- Keys, exists_item(State#state.db, Key)],
+ [{delete, Key} || Key <- Keys, exists_item(State#state.backend_mod, State#state.backend_ref, Key)],
Reply =
- case eleveldb:write(State#state.db, DeleteActions, []) of
+ case (State#state.backend_mod):write(State#state.backend_ref, DeleteActions) of
ok -> {ok, length(DeleteActions)};
{error, Reason} -> {error, Reason}
end,
{reply, Reply, stamp(Keys, write, State)};
handle_call(#edis_command{cmd = <<"EXISTS">>, args = [Key]}, _From, State) ->
Reply =
- case exists_item(State#state.db, Key) of
+ case exists_item(State#state.backend_mod, State#state.backend_ref, Key) of
true -> {ok, true};
false -> {ok, false};
{error, Reason} -> {error, Reason}
@@ -310,19 +309,17 @@ handle_call(#edis_command{cmd = <<"EXPIREAT">>, args = [Key, Timestamp]}, _From,
Reply =
case edis_util:now() of
Now when Timestamp =< Now -> %% It's a delete (it already expired)
- case exists_item(State#state.db, Key) of
+ case exists_item(State#state.backend_mod, State#state.backend_ref, Key) of
true ->
- case eleveldb:delete(State#state.db, Key, []) of
- ok ->
- {ok, true};
- {error, Reason} ->
- {error, Reason}
+ case (State#state.backend_mod):delete(State#state.backend_ref, Key) of
+ ok -> {ok, true};
+ {error, Reason} -> {error, Reason}
end;
false ->
{ok, false}
end;
_ ->
- case update(State#state.db, Key, any,
+ case update(State#state.backend_mod, State#state.backend_ref, Key, any,
fun(Item) ->
{ok, Item#edis_item{expire = Timestamp}}
end) of
@@ -340,21 +337,22 @@ handle_call(#edis_command{cmd = <<"KEYS">>, args = [Pattern]}, _From, State) ->
case re:compile(Pattern) of
{ok, Compiled} ->
Now = edis_util:now(),
- Keys = eleveldb:fold(
- State#state.db,
- fun({Key, Bin}, Acc) ->
- case re:run(Key, Compiled) of
+ Keys =
+ (State#state.backend_mod):fold(
+ State#state.backend_ref,
+ fun(Item, Acc) ->
+ case re:run(Item#edis_item.key, Compiled) of
nomatch ->
Acc;
_ ->
- case erlang:binary_to_term(Bin) of
- #edis_item{expire = Expire} when Expire >= Now ->
- [Key | Acc];
+ case Item#edis_item.expire of
+ Expire when Expire >= Now ->
+ [Item#edis_item.key | Acc];
_ ->
Acc
end
end
- end, [], [{fill_cache, false}]),
+ end, []),
{ok, lists:reverse(Keys)};
{error, {Reason, _Line}} when is_list(Reason) ->
{error, "Invalid pattern: " ++ Reason};
@@ -364,15 +362,15 @@ handle_call(#edis_command{cmd = <<"KEYS">>, args = [Pattern]}, _From, State) ->
{reply, Reply, State};
handle_call(#edis_command{cmd = <<"MOVE">>, args = [Key, NewDb]}, _From, State) ->
{Reply, Action} =
- case get_item(State#state.db, string, Key) of
+ case get_item(State#state.backend_mod, State#state.backend_ref, string, Key) of
not_found ->
{{ok, false}, none};
{error, Reason} ->
{{error, Reason}, read};
Item ->
try run(NewDb, #edis_command{cmd = <<"-INTERNAL-RECV">>, args = [Item]}) of
ok ->
- case eleveldb:delete(State#state.db, Key, []) of
+ case (State#state.backend_mod):delete(State#state.backend_ref, Key) of
ok ->
{{ok, true}, write};
{error, Reason} ->
@@ -387,29 +385,30 @@ handle_call(#edis_command{cmd = <<"MOVE">>, args = [Key, NewDb]}, _From, State)
{reply, Reply, stamp(Key, Action, State)};
handle_call(#edis_command{cmd = <<"-INTERNAL-RECV">>, args = [Item]}, _From, State) ->
{Reply, Action} =
- case exists_item(State#state.db, Item#edis_item.key) of
+ case exists_item(State#state.backend_mod, State#state.backend_ref, Item#edis_item.key) of
true -> {{error, found}, read};
- false -> {eleveldb:put(State#state.db, Item#edis_item.key, erlang:term_to_binary(Item), []), write}
+ false -> {(State#state.backend_mod):put(
+ State#state.backend_ref, Item#edis_item.key, Item), write}
end,
{reply, Reply, stamp(Item#edis_item.key, Action, State)};
handle_call(#edis_command{cmd = <<"OBJECT REFCOUNT">>, args = [Key]}, _From, State) ->
Reply =
- case exists_item(State#state.db, Key) of
+ case exists_item(State#state.backend_mod, State#state.backend_ref, Key) of
true -> {ok, 1};
false -> {ok, 0}
end,
{reply, Reply, State};
handle_call(#edis_command{cmd = <<"OBJECT ENCODING">>, args = [Key]}, _From, State) ->
Reply =
- case get_item(State#state.db, any, Key) of
+ case get_item(State#state.backend_mod, State#state.backend_ref, any, Key) of
#edis_item{encoding = Encoding} -> {ok, atom_to_binary(Encoding, utf8)};
not_found -> {ok, undefined};
{error, Reason} -> {error, Reason}
end,
{reply, Reply, State};
handle_call(#edis_command{cmd = <<"OBJECT IDLETIME">>, args = [Key]}, _From, State) ->
Reply =
- case exists_item(State#state.db, Key) of
+ case exists_item(State#state.backend_mod, State#state.backend_ref, Key) of
true ->
Offset =
case dict:find(Key, State#state.accesses) of
@@ -430,7 +429,7 @@ handle_call(#edis_command{cmd = <<"OBJECT LASTUPDATE">>, args = [Key]}, _From, S
{reply, Reply, State};
handle_call(#edis_command{cmd = <<"PERSIST">>, args = [Key]}, _From, State) ->
Reply =
- case update(State#state.db, Key, any,
+ case update(State#state.backend_mod, State#state.backend_ref, Key, any,
fun(Item) ->
{ok, Item#edis_item{expire = infinity}}
end) of
@@ -444,54 +443,50 @@ handle_call(#edis_command{cmd = <<"PERSIST">>, args = [Key]}, _From, State) ->
{reply, Reply, stamp(Key, write, State)};
handle_call(#edis_command{cmd = <<"RANDOMKEY">>}, _From, State) ->
Reply =
- case eleveldb:is_empty(State#state.db) of
+ case (State#state.backend_mod):is_empty(State#state.backend_ref) of
true -> {ok, undefined};
false ->
%%TODO: Make it really random... not just on the first xx tops
%% BUT we need to keep it O(1)
RandomIndex = random:uniform(?RANDOM_THRESHOLD),
- key_at(State#state.db, RandomIndex)
+ key_at(State#state.backend_mod, State#state.backend_ref, RandomIndex)
end,
{reply, Reply, State};
handle_call(#edis_command{cmd = <<"RENAME">>, args = [Key, NewKey]}, _From, State) ->
Reply =
- case get_item(State#state.db, any, Key) of
+ case get_item(State#state.backend_mod, State#state.backend_ref, any, Key) of
not_found ->
{error, no_such_key};
{error, Reason} ->
{error, Reason};
Item ->
- eleveldb:write(State#state.db,
- [{delete, Key},
- {put, NewKey,
- erlang:term_to_binary(Item#edis_item{key = NewKey})}],
- [])
+ (State#state.backend_mod):write(State#state.backend_ref,
+ [{delete, Key},
+ {put, NewKey, Item#edis_item{key = NewKey}}])
end,
{reply, Reply, stamp([Key, NewKey], write, State)};
handle_call(#edis_command{cmd = <<"RENAMENX">>, args = [Key, NewKey]}, _From, State) ->
{Reply, Action} =
- case get_item(State#state.db, any, Key) of
+ case get_item(State#state.backend_mod, State#state.backend_ref, any, Key) of
not_found ->
{{error, no_such_key}, none};
{error, Reason} ->
{{error, Reason}, read};
Item ->
- case exists_item(State#state.db, NewKey) of
+ case exists_item(State#state.backend_mod, State#state.backend_ref, NewKey) of
true ->
{{ok, false}, read};
false ->
- ok = eleveldb:write(State#state.db,
- [{delete, Key},
- {put, NewKey,
- erlang:term_to_binary(Item#edis_item{key = NewKey})}],
- []),
+ ok = (State#state.backend_mod):write(State#state.backend_ref,
+ [{delete, Key},
+ {put, NewKey, Item#edis_item{key = NewKey}}]),
{{ok, true}, write}
end
end,
{reply, Reply, stamp([Key, NewKey], Action, State)};
handle_call(#edis_command{cmd = <<"TTL">>, args = [Key]}, _From, State) ->
Reply =
- case get_item(State#state.db, any, Key) of
+ case get_item(State#state.backend_mod, State#state.backend_ref, any, Key) of
not_found ->
{ok, -1};
#edis_item{expire = infinity} ->
@@ -502,7 +497,7 @@ handle_call(#edis_command{cmd = <<"TTL">>, args = [Key]}, _From, State) ->
{reply, Reply, stamp(Key, read, State)};
handle_call(#edis_command{cmd = <<"TYPE">>, args = [Key]}, _From, State) ->
Reply =
- case get_item(State#state.db, any, Key) of
+ case get_item(State#state.backend_mod, State#state.backend_ref, any, Key) of
not_found ->
{ok, <<"none">>};
Item ->
@@ -511,10 +506,10 @@ handle_call(#edis_command{cmd = <<"TYPE">>, args = [Key]}, _From, State) ->
{reply, Reply, stamp(Key, read, State)};
handle_call(#edis_command{cmd = <<"SORT">>, args = [Key, Options = #edis_sort_options{store_in = undefined}]}, _From, State) ->
Reply =
- case get_item(State#state.db, [list, set, zset], Key) of
+ case get_item(State#state.backend_mod, State#state.backend_ref, [list, set, zset], Key) of
not_found -> {ok, []};
{error, Reason} -> {error, Reason};
- Item -> sort(State#state.db, Item, Options)
+ Item -> sort(State#state.backend_mod, State#state.backend_ref, Item, Options)
end,
{reply, Reply, stamp(Key, read, State)};
handle_call(C = #edis_command{cmd = <<"SORT">>, args = [Key, Options = #edis_sort_options{store_in = Destination}]}, From, State) ->
@@ -523,10 +518,9 @@ handle_call(C = #edis_command{cmd = <<"SORT">>, args = [Key, Options = #edis_sor
{reply, {ok, []}, NewState};
{reply, {ok, Sorted}, NewState} ->
Reply =
- case eleveldb:put(NewState#state.db, Destination,
- erlang:term_to_binary(
- #edis_item{key = Destination, type = list, encoding = linkedlist,
- value = Sorted}), []) of
+ case (State#state.backend_mod):put(
+ NewState#state.backend_ref, Destination,
+ #edis_item{key = Destination, type = list, encoding = linkedlist, value = Sorted}) of
ok -> {ok, erlang:length(Sorted)};
{error, Reason} -> {error, Reason}
end,
@@ -538,15 +532,15 @@ handle_call(C = #edis_command{cmd = <<"SORT">>, args = [Key, Options = #edis_sor
%% -- Hashes ---------------------------------------------------------------------------------------
handle_call(#edis_command{cmd = <<"HDEL">>, args = [Key | Fields]}, _From, State) ->
{Reply, Action} =
- case update(State#state.db, Key, hash,
+ case update(State#state.backend_mod, State#state.backend_ref, Key, hash,
fun(Item) ->
NewDict = lists:foldl(fun dict:erase/2, Item#edis_item.value, Fields),
{{dict:size(Item#edis_item.value) - dict:size(NewDict),
dict:size(NewDict)},
Item#edis_item{value = NewDict}}
end) of
{ok, {Deleted, 0}} ->
- _ = eleveldb:delete(State#state.db, Key, []),
+ _ = (State#state.backend_mod):delete(State#state.backend_ref, Key),
{{ok, Deleted}, write};
{ok, {Deleted, _}} ->
{{ok, Deleted}, write};
@@ -558,15 +552,15 @@ handle_call(#edis_command{cmd = <<"HDEL">>, args = [Key | Fields]}, _From, State
{reply, Reply, stamp(Key, Action, State)};
handle_call(#edis_command{cmd = <<"HEXISTS">>, args = [Key, Field]}, _From, State) ->
Reply =
- case get_item(State#state.db, hash, Key) of
+ case get_item(State#state.backend_mod, State#state.backend_ref, hash, Key) of
not_found -> {ok, false};
{error, Reason} -> {error, Reason};
Item -> {ok, dict:is_key(Field, Item#edis_item.value)}
end,
{reply, Reply, stamp(Key, read, State)};
handle_call(#edis_command{cmd = <<"HGET">>, args = [Key, Field]}, _From, State) ->
Reply =
- case get_item(State#state.db, hash, Key) of
+ case get_item(State#state.backend_mod, State#state.backend_ref, hash, Key) of
not_found -> {ok, undefined};
{error, Reason} -> {error, Reason};
Item -> {ok, case dict:find(Field, Item#edis_item.value) of
@@ -577,7 +571,7 @@ handle_call(#edis_command{cmd = <<"HGET">>, args = [Key, Field]}, _From, State)
{reply, Reply, stamp(Key, read, State)};
handle_call(#edis_command{cmd = <<"HGETALL">>, args = [Key]}, _From, State) ->
Reply =
- case get_item(State#state.db, hash, Key) of
+ case get_item(State#state.backend_mod, State#state.backend_ref, hash, Key) of
not_found -> {ok, []};
{error, Reason} -> {error, Reason};
Item -> {ok, lists:flatmap(fun tuple_to_list/1, dict:to_list(Item#edis_item.value))}
@@ -586,7 +580,7 @@ handle_call(#edis_command{cmd = <<"HGETALL">>, args = [Key]}, _From, State) ->
handle_call(#edis_command{cmd = <<"HINCRBY">>, args = [Key, Field, Increment]}, _From, State) ->
Reply =
update(
- State#state.db, Key, hash, hashtable,
+ State#state.backend_mod, State#state.backend_ref, Key, hash, hashtable,
fun(Item) ->
case dict:find(Field, Item#edis_item.value) of
error ->
@@ -612,23 +606,23 @@ handle_call(#edis_command{cmd = <<"HINCRBY">>, args = [Key, Field, Increment]},
{reply, Reply, stamp(Key, write, State)};
handle_call(#edis_command{cmd = <<"HKEYS">>, args = [Key]}, _From, State) ->
Reply =
- case get_item(State#state.db, hash, Key) of
+ case get_item(State#state.backend_mod, State#state.backend_ref, hash, Key) of
not_found -> {ok, []};
{error, Reason} -> {error, Reason};
Item -> {ok, dict:fetch_keys(Item#edis_item.value)}
end,
{reply, Reply, stamp(Key, read, State)};
handle_call(#edis_command{cmd = <<"HLEN">>, args = [Key]}, _From, State) ->
Reply =
- case get_item(State#state.db, hash, Key) of
+ case get_item(State#state.backend_mod, State#state.backend_ref, hash, Key) of
not_found -> {ok, 0};
{error, Reason} -> {error, Reason};
Item -> {ok, dict:size(Item#edis_item.value)}
end,
{reply, Reply, stamp(Key, read, State)};
handle_call(#edis_command{cmd = <<"HMGET">>, args = [Key | Fields]}, _From, State) ->
Reply =
- case get_item(State#state.db, hash, Key) of
+ case get_item(State#state.backend_mod, State#state.backend_ref, hash, Key) of
not_found -> {ok, [undefined || _ <- Fields]};
{error, Reason} -> {error, Reason};
Item ->
@@ -646,7 +640,7 @@ handle_call(#edis_command{cmd = <<"HMGET">>, args = [Key | Fields]}, _From, Stat
handle_call(#edis_command{cmd = <<"HMSET">>, args = [Key, FVs]}, _From, State) ->
Reply =
update(
- State#state.db, Key, hash, hashtable,
+ State#state.backend_mod, State#state.backend_ref, Key, hash, hashtable,
fun(Item) ->
lists:foldl(
fun({Field, Value}, {AccStatus, AccItem}) ->
@@ -668,7 +662,7 @@ handle_call(#edis_command{cmd = <<"HSET">>, args = [Key, Field, Value]}, From, S
handle_call(#edis_command{cmd = <<"HSETNX">>, args = [Key, Field, Value]}, _From, State) ->
Reply =
update(
- State#state.db, Key, hash, hashtable,
+ State#state.backend_mod, State#state.backend_ref, Key, hash, hashtable,
fun(Item) ->
case dict:is_key(Field, Item#edis_item.value) of
true -> {false, Item};
@@ -679,7 +673,7 @@ handle_call(#edis_command{cmd = <<"HSETNX">>, args = [Key, Field, Value]}, _From
{reply, Reply, stamp(Key, write, State)};
handle_call(#edis_command{cmd = <<"HVALS">>, args = [Key]}, _From, State) ->
Reply =
- case get_item(State#state.db, hash, Key) of
+ case get_item(State#state.backend_mod, State#state.backend_ref, hash, Key) of
not_found -> {ok, []};
{error, Reason} -> {error, Reason};
Item -> {ok, dict:fold(fun(_,Value,Acc) ->
@@ -754,7 +748,7 @@ handle_call(C = #edis_command{cmd = <<"BRPOPLPUSH">>, args = [Source, Destinatio
end;
handle_call(#edis_command{cmd = <<"LINDEX">>, args = [Key, Index]}, _From, State) ->
Reply =
- case get_item(State#state.db, list, Key) of
+ case get_item(State#state.backend_mod, State#state.backend_ref, list, Key) of
#edis_item{value = Value} ->
try
case Index of
@@ -773,7 +767,7 @@ handle_call(#edis_command{cmd = <<"LINDEX">>, args = [Key, Index]}, _From, State
{reply, Reply, stamp(Key, read, State)};
handle_call(#edis_command{cmd = <<"LINSERT">>, args = [Key, Position, Pivot, Value]}, _From, State) ->
Reply =
- update(State#state.db, Key, list,
+ update(State#state.backend_mod, State#state.backend_ref, Key, list,
fun(Item) ->
case {lists:splitwith(fun(Val) ->
Val =/= Pivot
@@ -791,15 +785,15 @@ handle_call(#edis_command{cmd = <<"LINSERT">>, args = [Key, Position, Pivot, Val
{reply, Reply, stamp(Key, write, State)};
handle_call(#edis_command{cmd = <<"LLEN">>, args = [Key]}, _From, State) ->
Reply =
- case get_item(State#state.db, list, Key) of
+ case get_item(State#state.backend_mod, State#state.backend_ref, list, Key) of
#edis_item{value = Value} -> {ok, length(Value)};
not_found -> {ok, 0};
{error, Reason} -> {error, Reason}
end,
{reply, Reply, stamp(Key, read, State)};
handle_call(#edis_command{cmd = <<"LPOP">>, args = [Key]}, _From, State) ->
Reply =
- case update(State#state.db, Key, list,
+ case update(State#state.backend_mod, State#state.backend_ref, Key, list,
fun(Item) ->
case Item#edis_item.value of
[Value] ->
@@ -811,7 +805,7 @@ handle_call(#edis_command{cmd = <<"LPOP">>, args = [Key]}, _From, State) ->
end
end, {keep, undefined}) of
{ok, {delete, Value}} ->
- _ = eleveldb:delete(State#state.db, Key, []),
+ _ = (State#state.backend_mod):delete(State#state.backend_ref, Key),
{ok, Value};
{ok, {keep, Value}} ->
{ok, Value};
@@ -821,7 +815,7 @@ handle_call(#edis_command{cmd = <<"LPOP">>, args = [Key]}, _From, State) ->
{reply, Reply, stamp(Key, write, State)};
handle_call(#edis_command{cmd = <<"LPUSH">>, args = [Key | Values]}, _From, State) ->
Reply =
- update(State#state.db, Key, list, linkedlist,
+ update(State#state.backend_mod, State#state.backend_ref, Key, list, linkedlist,
fun(Item) ->
{length(Item#edis_item.value) + length(Values),
Item#edis_item{value =
@@ -831,7 +825,7 @@ handle_call(#edis_command{cmd = <<"LPUSH">>, args = [Key | Values]}, _From, Stat
{reply, Reply, stamp(Key, write, NewState)};
handle_call(#edis_command{cmd = <<"LPUSHX">>, args = [Key, Value]}, _From, State) ->
Reply =
- update(State#state.db, Key, list,
+ update(State#state.backend_mod, State#state.backend_ref, Key, list,
fun(Item) ->
{length(Item#edis_item.value) + 1,
Item#edis_item{value = [Value | Item#edis_item.value]}}
@@ -840,7 +834,7 @@ handle_call(#edis_command{cmd = <<"LPUSHX">>, args = [Key, Value]}, _From, State
handle_call(#edis_command{cmd = <<"LRANGE">>, args = [Key, Start, Stop]}, _From, State) ->
Reply =
try
- case get_item(State#state.db, list, Key) of
+ case get_item(State#state.backend_mod, State#state.backend_ref, list, Key) of
#edis_item{value = Value} ->
L = erlang:length(Value),
StartPos =
@@ -870,7 +864,7 @@ handle_call(#edis_command{cmd = <<"LRANGE">>, args = [Key, Start, Stop]}, _From,
{reply, Reply, stamp(Key, read, State)};
handle_call(#edis_command{cmd = <<"LREM">>, args = [Key, Count, Value]}, _From, State) ->
Reply =
- update(State#state.db, Key, list,
+ update(State#state.backend_mod, State#state.backend_ref, Key, list,
fun(Item) ->
NewV =
case Count of
@@ -891,7 +885,7 @@ handle_call(#edis_command{cmd = <<"LREM">>, args = [Key, Count, Value]}, _From,
handle_call(#edis_command{cmd = <<"LSET">>, args = [Key, Index, Value]}, _From, State) ->
Reply =
case
- update(State#state.db, Key, list,
+ update(State#state.backend_mod, State#state.backend_ref, Key, list,
fun(Item) ->
case Index of
0 ->
@@ -922,7 +916,7 @@ handle_call(#edis_command{cmd = <<"LSET">>, args = [Key, Index, Value]}, _From,
{reply, Reply, stamp(Key, write, State)};
handle_call(#edis_command{cmd = <<"LTRIM">>, args = [Key, Start, Stop]}, _From, State) ->
Reply =
- case update(State#state.db, Key, list,
+ case update(State#state.backend_mod, State#state.backend_ref, Key, list,
fun(Item) ->
L = erlang:length(Item#edis_item.value),
StartPos =
@@ -948,14 +942,14 @@ handle_call(#edis_command{cmd = <<"LTRIM">>, args = [Key, Start, Stop]}, _From,
end, ok) of
{ok, ok} -> ok;
{error, empty} ->
- _ = eleveldb:delete(State#state.db, Key, []),
+ _ = (State#state.backend_mod):delete(State#state.backend_ref, Key),
ok;
{error, Reason} -> {error, Reason}
end,
{reply, Reply, stamp(Key, write, State)};
handle_call(#edis_command{cmd = <<"RPOP">>, args = [Key]}, _From, State) ->
Reply =
- case update(State#state.db, Key, list,
+ case update(State#state.backend_mod, State#state.backend_ref, Key, list,
fun(Item) ->
case lists:reverse(Item#edis_item.value) of
[Value] ->
@@ -967,7 +961,7 @@ handle_call(#edis_command{cmd = <<"RPOP">>, args = [Key]}, _From, State) ->
end
end, {keep, undefined}) of
{ok, {delete, Value}} ->
- _ = eleveldb:delete(State#state.db, Key, []),
+ _ = (State#state.backend_mod):delete(State#state.backend_ref, Key),
{ok, Value};
{ok, {keep, Value}} ->
{ok, Value};
@@ -977,7 +971,7 @@ handle_call(#edis_command{cmd = <<"RPOP">>, args = [Key]}, _From, State) ->
{reply, Reply, stamp(Key, write, State)};
handle_call(#edis_command{cmd = <<"RPOPLPUSH">>, args = [Key, Key]}, _From, State) ->
Reply =
- update(State#state.db, Key, list,
+ update(State#state.backend_mod, State#state.backend_ref, Key, list,
fun(Item) ->
case lists:reverse(Item#edis_item.value) of
[Value|Rest] ->
@@ -990,7 +984,7 @@ handle_call(#edis_command{cmd = <<"RPOPLPUSH">>, args = [Key, Key]}, _From, Stat
{reply, Reply, stamp(Key, write, State)};
handle_call(#edis_command{cmd = <<"RPOPLPUSH">>, args = [Source, Destination]}, _From, State) ->
Reply =
- case update(State#state.db, Source, list,
+ case update(State#state.backend_mod, State#state.backend_ref, Source, list,
fun(Item) ->
case lists:reverse(Item#edis_item.value) of
[Value] ->
@@ -1004,13 +998,13 @@ handle_call(#edis_command{cmd = <<"RPOPLPUSH">>, args = [Source, Destination]},
{ok, undefined} ->
{ok, undefined};
{ok, {delete, Value}} ->
- _ = eleveldb:delete(State#state.db, Source, []),
- update(State#state.db, Destination, list, linkedlist,
+ _ = (State#state.backend_mod):delete(State#state.backend_ref, Source),
+ update(State#state.backend_mod, State#state.backend_ref, Destination, list, linkedlist,
fun(Item) ->
{Value, Item#edis_item{value = [Value | Item#edis_item.value]}}
end, []);
{ok, {keep, Value}} ->
- update(State#state.db, Destination, list, linkedlist,
+ update(State#state.backend_mod, State#state.backend_ref, Destination, list, linkedlist,
fun(Item) ->
{Value, Item#edis_item{value = [Value | Item#edis_item.value]}}
end, []);
@@ -1021,7 +1015,7 @@ handle_call(#edis_command{cmd = <<"RPOPLPUSH">>, args = [Source, Destination]},
{reply, Reply, stamp([Destination, Source], write, NewState)};
handle_call(#edis_command{cmd = <<"RPUSH">>, args = [Key | Values]}, _From, State) ->
Reply =
- update(State#state.db, Key, list, linkedlist,
+ update(State#state.backend_mod, State#state.backend_ref, Key, list, linkedlist,
fun(Item) ->
{length(Item#edis_item.value) + length(Values),
Item#edis_item{value = lists:append(Item#edis_item.value, Values)}}
@@ -1030,7 +1024,7 @@ handle_call(#edis_command{cmd = <<"RPUSH">>, args = [Key | Values]}, _From, Stat
{reply, Reply, stamp(Key, write, NewState)};
handle_call(#edis_command{cmd = <<"RPUSHX">>, args = [Key, Value]}, _From, State) ->
Reply =
- update(State#state.db, Key, list,
+ update(State#state.backend_mod, State#state.backend_ref, Key, list,
fun(Item) ->
{length(Item#edis_item.value) + 1,
Item#edis_item{value =
@@ -1042,7 +1036,7 @@ handle_call(#edis_command{cmd = <<"RPUSHX">>, args = [Key, Value]}, _From, State
%% -- Sets -----------------------------------------------------------------------------------------
handle_call(#edis_command{cmd = <<"SADD">>, args = [Key | Members]}, _From, State) ->
Reply =
- update(State#state.db, Key, set, hashtable,
+ update(State#state.backend_mod, State#state.backend_ref, Key, set, hashtable,
fun(Item) ->
NewValue =
lists:foldl(fun gb_sets:add_element/2, Item#edis_item.value, Members),
@@ -1052,28 +1046,28 @@ handle_call(#edis_command{cmd = <<"SADD">>, args = [Key | Members]}, _From, Stat
{reply, Reply, stamp(Key, write, State)};
handle_call(#edis_command{cmd = <<"SCARD">>, args = [Key]}, _From, State) ->
Reply =
- case get_item(State#state.db, set, Key) of
+ case get_item(State#state.backend_mod, State#state.backend_ref, set, Key) of
#edis_item{value = Value} -> {ok, gb_sets:size(Value)};
not_found -> {ok, 0};
{error, Reason} -> {error, Reason}
end,
{reply, Reply, stamp(Key, read, State)};
handle_call(#edis_command{cmd = <<"SDIFF">>, args = [Key]}, _From, State) ->
Reply =
- case get_item(State#state.db, set, Key) of
+ case get_item(State#state.backend_mod, State#state.backend_ref, set, Key) of
#edis_item{value = Value} -> {ok, gb_sets:to_list(Value)};
not_found -> {ok, []};
{error, Reason} -> {error, Reason}
end,
{reply, Reply, stamp(Key, read, State)};
handle_call(#edis_command{cmd = <<"SDIFF">>, args = [Key | Keys]}, _From, State) ->
Reply =
- case get_item(State#state.db, set, Key) of
+ case get_item(State#state.backend_mod, State#state.backend_ref, set, Key) of
#edis_item{value = Value} ->
{ok, gb_sets:to_list(
lists:foldl(
fun(SKey, AccSet) ->
- case get_item(State#state.db, set, SKey) of
+ case get_item(State#state.backend_mod, State#state.backend_ref, set, SKey) of
#edis_item{value = SValue} -> gb_sets:subtract(AccSet, SValue);
not_found -> AccSet;
{error, Reason} -> throw(Reason)
@@ -1086,16 +1080,15 @@ handle_call(#edis_command{cmd = <<"SDIFF">>, args = [Key | Keys]}, _From, State)
handle_call(#edis_command{cmd = <<"SDIFFSTORE">>, args = [Destination | Keys]}, From, State) ->
case handle_call(#edis_command{cmd = <<"SDIFF">>, args = Keys}, From, State) of
{reply, {ok, []}, NewState} ->
- _ = eleveldb:delete(State#state.db, Destination, []),
+ _ = (State#state.backend_mod):delete(State#state.backend_ref, Destination),
{reply, {ok, 0}, stamp(Keys, read, stamp(Destination, write, NewState))};
{reply, {ok, Members}, NewState} ->
Value = gb_sets:from_list(Members),
Reply =
- case eleveldb:put(State#state.db,
- Destination,
- erlang:term_to_binary(
- #edis_item{key = Destination, type = set, encoding = hashtable,
- value = Value}), []) of
+ case (State#state.backend_mod):put(
+ State#state.backend_ref,
+ Destination,
+ #edis_item{key = Destination, type = set, encoding = hashtable, value = Value}) of
ok -> {ok, gb_sets:size(Value)};
{error, Reason} -> {error, Reason}
end,
@@ -1106,7 +1099,7 @@ handle_call(#edis_command{cmd = <<"SDIFFSTORE">>, args = [Destination | Keys]},
handle_call(#edis_command{cmd = <<"SINTER">>, args = Keys}, _From, State) ->
Reply =
try gb_sets:intersection(
- [case get_item(State#state.db, set, Key) of
+ [case get_item(State#state.backend_mod, State#state.backend_ref, set, Key) of
#edis_item{value = Value} -> Value;
not_found -> throw(empty);
{error, Reason} -> throw(Reason)
@@ -1120,16 +1113,15 @@ handle_call(#edis_command{cmd = <<"SINTER">>, args = Keys}, _From, State) ->
handle_call(#edis_command{cmd = <<"SINTERSTORE">>, args = [Destination | Keys]}, From, State) ->
case handle_call(#edis_command{cmd = <<"SINTER">>, args = Keys}, From, State) of
{reply, {ok, []}, NewState} ->
- _ = eleveldb:delete(State#state.db, Destination, []),
+ _ = (State#state.backend_mod):delete(State#state.backend_ref, Destination),
{reply, {ok, 0}, stamp(Keys, read, stamp(Destination, write, NewState))};
{reply, {ok, Members}, NewState} ->
Value = gb_sets:from_list(Members),
Reply =
- case eleveldb:put(State#state.db,
- Destination,
- erlang:term_to_binary(
- #edis_item{key = Destination, type = set, encoding = hashtable,
- value = Value}), []) of
+ case (State#state.backend_mod):put(
+ State#state.backend_ref,
+ Destination,
+ #edis_item{key = Destination, type = set, encoding = hashtable, value = Value}) of
ok -> {ok, gb_sets:size(Value)};
{error, Reason} -> {error, Reason}
end,
@@ -1139,23 +1131,23 @@ handle_call(#edis_command{cmd = <<"SINTERSTORE">>, args = [Destination | Keys]},
end;
handle_call(#edis_command{cmd = <<"SISMEMBER">>, args = [Key, Member]}, _From, State) ->
Reply =
- case get_item(State#state.db, set, Key) of
+ case get_item(State#state.backend_mod, State#state.backend_ref, set, Key) of
#edis_item{value = Value} -> {ok, gb_sets:is_element(Member, Value)};
not_found -> {ok, false};
{error, Reason} -> {error, Reason}
end,
{reply, Reply, stamp(Key, read, State)};
handle_call(#edis_command{cmd = <<"SMEMBERS">>, args = [Key]}, _From, State) ->
Reply =
- case get_item(State#state.db, set, Key) of
+ case get_item(State#state.backend_mod, State#state.backend_ref, set, Key) of
#edis_item{value = Value} -> {ok, gb_sets:to_list(Value)};
not_found -> {ok, []};
{error, Reason} -> {error, Reason}
end,
{reply, Reply, stamp(Key, read, State)};
handle_call(#edis_command{cmd = <<"SMOVE">>, args = [Source, Destination, Member]}, _From, State) ->
Reply =
- case update(State#state.db, Source, set,
+ case update(State#state.backend_mod, State#state.backend_ref, Source, set,
fun(Item) ->
case gb_sets:is_element(Member, Item#edis_item.value) of
false ->
@@ -1169,14 +1161,14 @@ handle_call(#edis_command{cmd = <<"SMOVE">>, args = [Source, Destination, Member
end
end, false) of
{ok, delete} ->
- _ = eleveldb:delete(State#state.db, Source, []),
- update(State#state.db, Destination, set, hashtable,
+ _ = (State#state.backend_mod):delete(State#state.backend_ref, Source),
+ update(State#state.backend_mod, State#state.backend_ref, Destination, set, hashtable,
fun(Item) ->
{true, Item#edis_item{value =
gb_sets:add_element(Member, Item#edis_item.value)}}
end, gb_sets:empty());
{ok, true} ->
- update(State#state.db, Destination, set, hashtable,
+ update(State#state.backend_mod, State#state.backend_ref, Destination, set, hashtable,
fun(Item) ->
{true, Item#edis_item{value =
gb_sets:add_element(Member, Item#edis_item.value)}}
@@ -1187,7 +1179,7 @@ handle_call(#edis_command{cmd = <<"SMOVE">>, args = [Source, Destination, Member
{reply, Reply, stamp([Source, Destination], write, State)};
handle_call(#edis_command{cmd = <<"SPOP">>, args = [Key]}, _From, State) ->
Reply =
- case update(State#state.db, Key, set,
+ case update(State#state.backend_mod, State#state.backend_ref, Key, set,
fun(Item) ->
{Member, NewValue} = gb_sets:take_smallest(Item#edis_item.value),
case gb_sets:size(NewValue) of
@@ -1196,7 +1188,7 @@ handle_call(#edis_command{cmd = <<"SPOP">>, args = [Key]}, _From, State) ->
end
end, undefined) of
{ok, {delete, Member}} ->
- _ = eleveldb:delete(State#state.db, Key, []),
+ _ = (State#state.backend_mod):delete(State#state.backend_ref, Key),
{ok, Member};
OtherReply ->
OtherReply
@@ -1205,7 +1197,7 @@ handle_call(#edis_command{cmd = <<"SPOP">>, args = [Key]}, _From, State) ->
handle_call(#edis_command{cmd = <<"SRANDMEMBER">>, args = [Key]}, _From, State) ->
_ = random:seed(erlang:now()),
Reply =
- case get_item(State#state.db, set, Key) of
+ case get_item(State#state.backend_mod, State#state.backend_ref, set, Key) of
#edis_item{value = Value} ->
Iterator = gb_sets:iterator(Value),
{Res, _} =
@@ -1221,7 +1213,7 @@ handle_call(#edis_command{cmd = <<"SRANDMEMBER">>, args = [Key]}, _From, State)
{reply, Reply, stamp(Key, read, State)};
handle_call(#edis_command{cmd = <<"SREM">>, args = [Key | Members]}, _From, State) ->
Reply =
- case update(State#state.db, Key, set,
+ case update(State#state.backend_mod, State#state.backend_ref, Key, set,
fun(Item) ->
NewValue =
lists:foldl(fun gb_sets:del_element/2, Item#edis_item.value, Members),
@@ -1235,7 +1227,7 @@ handle_call(#edis_command{cmd = <<"SREM">>, args = [Key | Members]}, _From, Stat
end
end, 0) of
{ok, {delete, Count}} ->
- _ = eleveldb:delete(State#state.db, Key, []),
+ _ = (State#state.backend_mod):delete(State#state.backend_ref, Key),
{ok, Count};
OtherReply ->
OtherReply
@@ -1244,7 +1236,7 @@ handle_call(#edis_command{cmd = <<"SREM">>, args = [Key | Members]}, _From, Stat
handle_call(#edis_command{cmd = <<"SUNION">>, args = Keys}, _From, State) ->
Reply =
try gb_sets:union(
- [case get_item(State#state.db, set, Key) of
+ [case get_item(State#state.backend_mod, State#state.backend_ref, set, Key) of
#edis_item{value = Value} -> Value;
not_found -> gb_sets:empty();
{error, Reason} -> throw(Reason)
@@ -1258,16 +1250,15 @@ handle_call(#edis_command{cmd = <<"SUNION">>, args = Keys}, _From, State) ->
handle_call(#edis_command{cmd = <<"SUNIONSTORE">>, args = [Destination | Keys]}, From, State) ->
case handle_call(#edis_command{cmd = <<"SUNION">>, args = Keys}, From, State) of
{reply, {ok, []}, NewState} ->
- _ = eleveldb:delete(State#state.db, Destination, []),
+ _ = (State#state.backend_mod):delete(State#state.backend_ref, Destination),
{reply, {ok, 0}, stamp(Keys, read, stamp(Destination, write, NewState))};
{reply, {ok, Members}, NewState} ->
Value = gb_sets:from_list(Members),
Reply =
- case eleveldb:put(State#state.db,
- Destination,
- erlang:term_to_binary(
- #edis_item{key = Destination, type = set, encoding = hashtable,
- value = Value}), []) of
+ case (State#state.backend_mod):put(
+ State#state.backend_ref,
+ Destination,
+ #edis_item{key = Destination, type = set, encoding = hashtable, value = Value}) of
ok -> {ok, gb_sets:size(Value)};
{error, Reason} -> {error, Reason}
end,
@@ -1278,7 +1269,7 @@ handle_call(#edis_command{cmd = <<"SUNIONSTORE">>, args = [Destination | Keys]},
%% -- ZSets -----------------------------------------------------------------------------------------
handle_call(#edis_command{cmd = <<"ZADD">>, args = [Key, SMs]}, _From, State) ->
Reply =
- update(State#state.db, Key, zset, skiplist,
+ update(State#state.backend_mod, State#state.backend_ref, Key, zset, skiplist,
fun(Item) ->
NewValue =
lists:foldl(fun zsets:enter/2, Item#edis_item.value, SMs),
@@ -1288,23 +1279,23 @@ handle_call(#edis_command{cmd = <<"ZADD">>, args = [Key, SMs]}, _From, State) ->
{reply, Reply, stamp(Key, write, State)};
handle_call(#edis_command{cmd = <<"ZCARD">>, args = [Key]}, _From, State) ->
Reply =
- case get_item(State#state.db, zset, Key) of
+ case get_item(State#state.backend_mod, State#state.backend_ref, zset, Key) of
#edis_item{value = Value} -> {ok, zsets:size(Value)};
not_found -> {ok, 0};
{error, Reason} -> {error, Reason}
end,
{reply, Reply, stamp(Key, read, State)};
handle_call(#edis_command{cmd = <<"ZCOUNT">>, args = [Key, Min, Max]}, _From, State) ->
Reply =
- case get_item(State#state.db, zset, Key) of
+ case get_item(State#state.backend_mod, State#state.backend_ref, zset, Key) of
#edis_item{value = Value} -> {ok, zsets:count(Min, Max, Value)};
not_found -> {ok, 0};
{error, Reason} -> {error, Reason}
end,
{reply, Reply, stamp(Key, read, State)};
handle_call(#edis_command{cmd = <<"ZINCRBY">>, args = [Key, Increment, Member]}, _From, State) ->
Reply =
- update(State#state.db, Key, zset, skiplist,
+ update(State#state.backend_mod, State#state.backend_ref, Key, zset, skiplist,
fun(Item) ->
NewScore =
case zsets:find(Member, Item#edis_item.value) of
@@ -1319,29 +1310,28 @@ handle_call(#edis_command{cmd = <<"ZINTERSTORE">>, args = [Destination, Weighted
Reply =
try weighted_intersection(
Aggregate,
- [case get_item(State#state.db, zset, Key) of
+ [case get_item(State#state.backend_mod, State#state.backend_ref, zset, Key) of
#edis_item{value = Value} -> {Value, Weight};
not_found -> throw(empty);
{error, Reason} -> throw(Reason)
end || {Key, Weight} <- WeightedKeys]) of
ZSet ->
case zsets:size(ZSet) of
0 ->
- _ = eleveldb:delete(State#state.db, Destination, []),
+ _ = (State#state.backend_mod):delete(State#state.backend_ref, Destination),
{ok, 0};
Size ->
- case eleveldb:put(State#state.db,
- Destination,
- erlang:term_to_binary(
- #edis_item{key = Destination, type = zset, encoding = skiplist,
- value = ZSet}), []) of
+ case (State#state.backend_mod):put(
+ State#state.backend_ref,
+ Destination,
+ #edis_item{key = Destination, type = zset, encoding = skiplist, value = ZSet}) of
ok -> {ok, Size};
{error, Reason} -> {error, Reason}
end
end
catch
_:empty ->
- _ = eleveldb:delete(State#state.db, Destination, []),
+ _ = (State#state.backend_mod):delete(State#state.backend_ref, Destination),
{ok, 0};
_:Error ->
?ERROR("~p~n", [Error]),
@@ -1351,7 +1341,7 @@ handle_call(#edis_command{cmd = <<"ZINTERSTORE">>, args = [Destination, Weighted
handle_call(#edis_command{cmd = <<"ZRANGE">>, args = [Key, Start, Stop | Options]}, _From, State) ->
Reply =
try
- case get_item(State#state.db, zset, Key) of
+ case get_item(State#state.backend_mod, State#state.backend_ref, zset, Key) of
#edis_item{value = Value} ->
L = zsets:size(Value),
StartPos =
@@ -1387,15 +1377,15 @@ handle_call(#edis_command{cmd = <<"ZRANGE">>, args = [Key, Start, Stop | Options
{reply, Reply, stamp(Key, read, State)};
handle_call(#edis_command{cmd = <<"ZRANGEBYSCORE">>, args = [Key, Min, Max | _Options]}, _From, State) ->
Reply =
- case get_item(State#state.db, zset, Key) of
+ case get_item(State#state.backend_mod, State#state.backend_ref, zset, Key) of
#edis_item{value = Value} -> {ok, zsets:list(Min, Max, Value)};
not_found -> {ok, 0};
{error, Reason} -> {error, Reason}
end,
{reply, Reply, stamp(Key, read, State)};
handle_call(#edis_command{cmd = <<"ZRANK">>, args = [Key, Member]}, _From, State) ->
Reply =
- case get_item(State#state.db, zset, Key) of
+ case get_item(State#state.backend_mod, State#state.backend_ref, zset, Key) of
#edis_item{value = Value} ->
case zsets:find(Member, Value) of
error -> {ok, undefined};
@@ -1407,7 +1397,7 @@ handle_call(#edis_command{cmd = <<"ZRANK">>, args = [Key, Member]}, _From, State
{reply, Reply, stamp(Key, read, State)};
handle_call(#edis_command{cmd = <<"ZREM">>, args = [Key | Members]}, _From, State) ->
Reply =
- case update(State#state.db, Key, zset,
+ case update(State#state.backend_mod, State#state.backend_ref, Key, zset,
fun(Item) ->
NewValue =
lists:foldl(fun zsets:delete_any/2, Item#edis_item.value, Members),
@@ -1421,7 +1411,7 @@ handle_call(#edis_command{cmd = <<"ZREM">>, args = [Key | Members]}, _From, Stat
end
end, 0) of
{ok, {delete, Count}} ->
- _ = eleveldb:delete(State#state.db, Key, []),
+ _ = (State#state.backend_mod):delete(State#state.backend_ref, Key),
{ok, Count};
OtherReply ->
OtherReply
@@ -1447,7 +1437,7 @@ handle_call(#edis_command{cmd = <<"ZREMRANGEBYSCORE">>, args = [Key, Min, Max]},
handle_call(#edis_command{cmd = <<"ZREVRANGE">>, args = [Key, Start, Stop | Options]}, _From, State) ->
Reply =
try
- case get_item(State#state.db, zset, Key) of
+ case get_item(State#state.backend_mod, State#state.backend_ref, zset, Key) of
#edis_item{value = Value} ->
L = zsets:size(Value),
StartPos =
@@ -1484,15 +1474,15 @@ handle_call(#edis_command{cmd = <<"ZREVRANGE">>, args = [Key, Start, Stop | Opti
{reply, Reply, stamp(Key, read, State)};
handle_call(#edis_command{cmd = <<"ZREVRANGEBYSCORE">>, args = [Key, Min, Max | _Options]}, _From, State) ->
Reply =
- case get_item(State#state.db, zset, Key) of
+ case get_item(State#state.backend_mod, State#state.backend_ref, zset, Key) of
#edis_item{value = Value} -> {ok, zsets:list(Min, Max, Value, backwards)};
not_found -> {ok, 0};
{error, Reason} -> {error, Reason}
end,
{reply, Reply, stamp(Key, read, State)};
handle_call(#edis_command{cmd = <<"ZREVRANK">>, args = [Key, Member]}, _From, State) ->
Reply =
- case get_item(State#state.db, zset, Key) of
+ case get_item(State#state.backend_mod, State#state.backend_ref, zset, Key) of
#edis_item{value = Value} ->
case zsets:find(Member, Value) of
error -> {ok, undefined};
@@ -1504,7 +1494,7 @@ handle_call(#edis_command{cmd = <<"ZREVRANK">>, args = [Key, Member]}, _From, St
{reply, Reply, stamp(Key, read, State)};
handle_call(#edis_command{cmd = <<"ZSCORE">>, args = [Key, Member]}, _From, State) ->
Reply =
- case get_item(State#state.db, zset, Key) of
+ case get_item(State#state.backend_mod, State#state.backend_ref, zset, Key) of
#edis_item{value = Value} ->
case zsets:find(Member, Value) of
error -> {ok, undefined};
@@ -1518,29 +1508,28 @@ handle_call(#edis_command{cmd = <<"ZUNIONSTORE">>, args = [Destination, Weighted
Reply =
try weighted_union(
Aggregate,
- [case get_item(State#state.db, zset, Key) of
+ [case get_item(State#state.backend_mod, State#state.backend_ref, zset, Key) of
#edis_item{value = Value} -> {Value, Weight};
not_found -> {zsets:new(), 0.0};
{error, Reason} -> throw(Reason)
end || {Key, Weight} <- WeightedKeys]) of
ZSet ->
case zsets:size(ZSet) of
0 ->
- _ = eleveldb:delete(State#state.db, Destination, []),
+ _ = (State#state.backend_mod):delete(State#state.backend_ref, Destination),
{ok, 0};
Size ->
- case eleveldb:put(State#state.db,
- Destination,
- erlang:term_to_binary(
- #edis_item{key = Destination, type = zset, encoding = skiplist,
- value = ZSet}), []) of
+ case (State#state.backend_mod):put(
+ State#state.backend_ref,
+ Destination,
+ #edis_item{key = Destination, type = zset, encoding = skiplist, value = ZSet}) of
ok -> {ok, Size};
{error, Reason} -> {error, Reason}
end
end
catch
_:empty ->
- _ = eleveldb:delete(State#state.db, Destination, []),
+ _ = (State#state.backend_mod):delete(State#state.backend_ref, Destination),
{ok, 0};
_:Error ->
?ERROR("~p~n", [Error]),
@@ -1552,19 +1541,14 @@ handle_call(#edis_command{cmd = <<"DBSIZE">>}, _From, State) ->
%%TODO: We need to
Now = edis_util:now(),
Reply =
- {ok, eleveldb:fold(
- State#state.db,
- fun({_Key, Bin}, Acc) ->
- case erlang:binary_to_term(Bin) of
- #edis_item{expire = Expire} when Expire >= Now ->
- Acc + 1;
- _ ->
- Acc
- end
- end, 0, [{fill_cache, false}])},
+ {ok, (State#state.backend_mod):fold(
+ State#state.backend_ref,
+ fun(#edis_item{expire = Expire}, Acc) when Expire >= Now -> Acc + 1;
+ (_, Acc) -> Acc
+ end, 0)},
{reply, Reply, State};
handle_call(#edis_command{cmd = <<"FLUSHDB">>}, _From, State) ->
- ok = eleveldb:destroy(edis_config:get(dir) ++ "/edis-" ++ integer_to_list(State#state.index), []),
+ ok = (State#state.backend_mod):destroy(State#state.backend_ref),
case init(State#state.index) of
{ok, NewState} ->
{reply, ok, NewState};
@@ -1577,7 +1561,7 @@ handle_call(#edis_command{cmd = <<"INFO">>}, _From, State) ->
false -> "0";
{edis, _Desc, V} -> V
end,
- {ok, Stats} = eleveldb:status(State#state.db, <<"leveldb.stats">>),
+ {ok, Stats} = (State#state.backend_mod):status(State#state.backend_ref),
Reply =
{ok,
iolist_to_binary(
@@ -1727,16 +1711,12 @@ first_that_works([Req|Reqs], From, State) ->
end.
%% @private
-exists_item(Db, Key) ->
- case eleveldb:get(Db, Key, []) of
- {ok, _} -> true;
- not_found -> false;
- {error, Reason} -> {error, Reason}
- end.
+exists_item(Mod, Ref, Key) ->
+ not_found /= get_item(Mod, Ref, any, Key).
%% @private
-get_item(Db, Types, Key) when is_list(Types) ->
- case get_item(Db, any, Key) of
+get_item(Mod, Ref, Types, Key) when is_list(Types) ->
+ case get_item(Mod, Ref, any, Key) of
Item = #edis_item{type = T} ->
case lists:member(T, Types) of
true -> Item;
@@ -1745,37 +1725,35 @@ get_item(Db, Types, Key) when is_list(Types) ->
Other ->
Other
end;
-get_item(Db, Type, Key) ->
- case eleveldb:get(Db, Key, []) of
- {ok, Bin} ->
+get_item(Mod, Ref, Type, Key) ->
+ case Mod:get(Ref, Key) of
+ Item = #edis_item{type = T, expire = Expire} when Type =:= any orelse T =:= Type ->
Now = edis_util:now(),
- case erlang:binary_to_term(Bin) of
- Item = #edis_item{type = T, expire = Expire} when Type =:= any orelse T =:= Type ->
- case Expire of
- Expire when Expire >= Now ->
- Item;
- _ ->
- _ = eleveldb:delete(Db, Key, []),
- not_found
- end;
- _Other -> {error, bad_item_type}
+ case Expire of
+ Expire when Expire >= Now ->
+ Item;
+ _ ->
+ _ = Mod:delete(Ref, Key),
+ not_found
end;
+ #edis_item{} ->
+ {error, bad_item_type};
not_found ->
not_found;
{error, Reason} ->
{error, Reason}
end.
%% @private
-update(Db, Key, Type, Fun) ->
+update(Mod, Ref, Key, Type, Fun) ->
try
{Res, NewItem} =
- case get_item(Db, Type, Key) of
+ case get_item(Mod, Ref, Type, Key) of
not_found -> throw(not_found);
{error, Reason} -> throw(Reason);
Item -> Fun(Item)
end,
- case eleveldb:put(Db, Key, erlang:term_to_binary(NewItem), []) of
+ case Mod:put(Ref, Key, NewItem) of
ok -> {ok, Res};
{error, Reason2} -> {error, Reason2}
end
@@ -1784,15 +1762,15 @@ update(Db, Key, Type, Fun) ->
{error, Error}
end.
-update(Db, Key, Type, Fun, ResultIfNotFound) ->
+update(Mod, Ref, Key, Type, Fun, ResultIfNotFound) ->
try
{Res, NewItem} =
- case get_item(Db, Type, Key) of
+ case get_item(Mod, Ref, Type, Key) of
not_found -> throw(not_found);
{error, Reason} -> throw(Reason);
Item -> Fun(Item)
end,
- case eleveldb:put(Db, Key, erlang:term_to_binary(NewItem), []) of
+ case Mod:put(Ref, Key, NewItem) of
ok -> {ok, Res};
{error, Reason2} -> {error, Reason2}
end
@@ -1804,58 +1782,54 @@ update(Db, Key, Type, Fun, ResultIfNotFound) ->
end.
%% @private
-update(Db, Key, Type, Encoding, Fun, Default) ->
+update(Mod, Ref, Key, Type, Encoding, Fun, Default) ->
try
{Res, NewItem} =
- case get_item(Db, Type, Key) of
+ case get_item(Mod, Ref, Type, Key) of
not_found ->
Fun(#edis_item{key = Key, type = Type, encoding = Encoding, value = Default});
{error, Reason} ->
throw(Reason);
Item ->
Fun(Item)
end,
- case eleveldb:put(Db, Key, erlang:term_to_binary(NewItem), []) of
+ case Mod:put(Ref, Key, NewItem) of
ok -> {ok, Res};
{error, Reason2} -> {error, Reason2}
end
catch
_:Error ->
+ ?ERROR("~p~n", [Error]),
{error, Error}
end.
%% @private
-key_at(Db, 0) ->
+key_at(Mod, Ref, 0) ->
try
Now = edis_util:now(),
- eleveldb:fold(
- Db, fun({_Key, Bin}, Acc) ->
- case erlang:binary_to_term(Bin) of
- #edis_item{key = Key, expire = Expire} when Expire >= Now ->
- throw({ok, Key});
- _ ->
- Acc
- end
- end, {ok, undefined}, [{fill_cache, false}])
+ Mod:fold(
+ Ref,
+ fun(#edis_item{key = Key, expire = Expire}, _Acc) when Expire >= Now ->
+ throw({ok, Key});
+ (_, Acc) -> Acc
+ end, {ok, undefined})
catch
_:{ok, Key} -> {ok, Key}
end;
-key_at(Db, Index) when Index > 0 ->
+key_at(Mod, Ref, Index) when Index > 0 ->
try
Now = edis_util:now(),
NextIndex =
- eleveldb:fold(
- Db, fun({_Key, Bin}, 0) ->
- case erlang:binary_to_term(Bin) of
- #edis_item{key = Key, expire = Expire} when Expire >= Now ->
- throw({ok, Key});
- _ ->
- 0
- end;
- (_, AccIndex) ->
- AccIndex - 1
- end, Index, [{fill_cache, false}]),
- key_at(Db, NextIndex)
+ Mod:fold(
+ Ref,
+ fun(#edis_item{key = Key, expire = Expire}, 0) when Expire >= Now ->
+ throw({ok, Key});
+ (_, 0) ->
+ 0;
+ (_, AccIndex) ->
+ AccIndex - 1
+ end, Index),
+ key_at(Mod, Ref, NextIndex)
catch
_:{ok, Key} -> {ok, Key}
end.
@@ -1892,9 +1866,9 @@ weighted_union(Aggregate, [{ZSet, Weight} | Rest], AccWeight, AccZSet) ->
lists:Aggregate([Score * Weight, AccScore * AccWeight])
end, ZSet, AccZSet)).
-sort(_Db, _Item, #edis_sort_options{limit = {_Off, 0}}) -> {ok, []};
-sort(_Db, _Item, #edis_sort_options{limit = {Off, _Lim}}) when Off < 0 -> {ok, []};
-sort(Db, #edis_item{type = Type, value = Value}, Options) ->
+sort(_Mod, _Ref, _Item, #edis_sort_options{limit = {_Off, 0}}) -> {ok, []};
+sort(_Mod, _Ref, _Item, #edis_sort_options{limit = {Off, _Lim}}) when Off < 0 -> {ok, []};
+sort(Mod, Ref, #edis_item{type = Type, value = Value}, Options) ->
Elements =
case Type of
list -> Value;
@@ -1903,7 +1877,7 @@ sort(Db, #edis_item{type = Type, value = Value}, Options) ->
end,
Mapped =
lists:map(fun(Element) ->
- {retrieve(Db, Element, Options#edis_sort_options.by), Element}
+ {retrieve(Mod, Ref, Element, Options#edis_sort_options.by), Element}
end, Elements),
Sorted =
case {Options#edis_sort_options.type, Options#edis_sort_options.direction} of
@@ -1923,7 +1897,7 @@ sort(Db, #edis_item{type = Type, value = Value}, Options) ->
lists:flatmap(
fun({_Map, Element}) ->
lists:map(
- fun(Pattern) -> retrieve(Db, Element, Pattern) end,
+ fun(Pattern) -> retrieve(Mod, Ref, Element, Pattern) end,
Options#edis_sort_options.get)
end, Limited),
{ok, Complete}.
@@ -1933,21 +1907,21 @@ default_sort({undefined, _}, {_Binary, _}) -> false; %% binary() < atom()
default_sort({Bin1, _}, {Bin2, _}) ->
edis_util:binary_to_float(Bin1, undefined) =< edis_util:binary_to_float(Bin2, undefined).
-retrieve(_Db, Element, self) -> Element;
-retrieve(Db, Element, {KeyPattern, FieldPattern}) ->
+retrieve(_Mod, _Ref, Element, self) -> Element;
+retrieve(Mod, Ref, Element, {KeyPattern, FieldPattern}) ->
Key = binary:replace(KeyPattern, <<"*">>, Element, [global]),
Field = binary:replace(FieldPattern, <<"*">>, Element, [global]),
- case get_item(Db, hash, Key) of
+ case get_item(Mod, Ref, hash, Key) of
not_found -> undefined;
{error, _Reason} -> undefined;
Item -> case dict:find(Field, Item#edis_item.value) of
{ok, Value} -> Value;
error -> undefined
end
end;
-retrieve(Db, Element, Pattern) ->
+retrieve(Mod, Ref, Element, Pattern) ->
Key = binary:replace(Pattern, <<"*">>, Element, [global]),
- case get_item(Db, string, Key) of
+ case get_item(Mod, Ref, string, Key) of
#edis_item{type = string, value = Value} -> Value;
not_found -> undefined;
{error, _Reason} -> undefined

0 comments on commit 753cc5b

Please sign in to comment.