Skip to content

Commit

Permalink
Merge branch 'master' of github.com:inaka/edis into test
Browse files Browse the repository at this point in the history
Conflicts:
	rebar.config
	test.config
  • Loading branch information
Marcos Almonacid committed Oct 5, 2011
2 parents b2442e4 + 02f804d commit 02c5daf
Show file tree
Hide file tree
Showing 16 changed files with 818 additions and 150 deletions.
13 changes: 2 additions & 11 deletions .gitignore
@@ -1,13 +1,4 @@
db
ebin
deps
log/*.log
tmp
tmp/**/*
.DS_Store
*.swp
*.swo
engine/*.dump
*.beam
config/database.yml
erl_crash.dump
priv/*
c_src/*.o
3 changes: 2 additions & 1 deletion Makefile
Expand Up @@ -7,7 +7,8 @@ clean:
rebar clean

build_plt: all
dialyzer --build_plt --apps ssl public_key kernel stdlib inets crypto --output_plt ~/.edis_plt -pa deps/*/ebin ebin
dialyzer --build_plt --apps kernel stdlib sasl erts ssl tools os_mon runtime_tools crypto inets \
xmerl webtool snmp public_key mnesia eunit syntax_tools compiler --output_plt ~/.edis_plt -pa deps/*/ebin ebin

analyze: all
dialyzer -pa deps/*/ebin --plt ~/.itweet_dialyzer_plt -Wunmatched_returns -Werror_handling -Wbehaviours ebin
Expand Down
14 changes: 14 additions & 0 deletions README.md
@@ -1 +1,15 @@
An *Erlang* version of [Redis](http://redis.io). Still in its very early stages.

## Usage
Just run `$ make run` and open connections with your favourite redis client.

## Differences with Redis
### Different Behaviour
* _SAVE_, _BGSAVE_ and _LASTSAVE_ are database dependent. The original Redis saves all databases at once, edis saves just the one you _SELECT_'ed.
* _INFO_ provides much less information and no statistics (so, _CONFIG RESETSTAT_ does nothing at all)

### Missing Features
* Dynamic node configuration (i.e. the _SLAVEOF_ command is not implemented)

### Unsupported Commands
_SYNC_, _SLOWLOG_, _SLAVEOF_, _DEBUG *_
10 changes: 0 additions & 10 deletions ebin/edis.app

This file was deleted.

11 changes: 8 additions & 3 deletions include/edis.hrl
@@ -1,5 +1,10 @@
-include("elog.hrl").

-record(edis_command, {name :: binary(),
args = 0 :: non_neg_integer(),
last_arg_is_safe = false :: boolean()}).
-record(edis_command, {timestamp :: float(),
db :: non_neg_integer(),
cmd :: atom(),
args = [] :: [term()]}).

-record(edis_item, {key :: binary(),
value :: term(),
type :: string | hash | list | set | zset}).
4 changes: 3 additions & 1 deletion rebar.config
@@ -1,5 +1,6 @@
{deps, [{elog, "\.*", {git, "git://github.com/inaka/elog.git", "master"}},
{erldis, "\.*", {git, "git://github.com/inaka/erldis.git", "master"}}]}.
{erldis, "\.*", {git, "git://github.com/inaka/erldis.git", "master"}},
{eleveldb, "\.*", {git, "git@github.com:inaka/eleveldb.git", "master"}}]}.
{require_otp_vsn, "R14"}.
{erl_opts, [{src_dirs, ["src", "tests"]},
{i, "deps/elog/include"},
Expand All @@ -18,3 +19,4 @@
warn_missing_spec,
warn_untyped_record, debug_info]}.
{xref_checks, [undefined_function_calls]}.
{edoc_opts, [{report_missing_types, true}, todo]}.
4 changes: 3 additions & 1 deletion src/edis.app.src
Expand Up @@ -10,5 +10,7 @@
]},
{mod, {edis, []}},
{env, [{listener_port_range, {6379,6379}},
{client_timeout, 32000}]}
{client_timeout, 32000},
{databases, 16},
{requirepass, false}]}
]}.
79 changes: 24 additions & 55 deletions src/edis_client.erl
Expand Up @@ -96,40 +96,29 @@ command_start({data, <<"*", N/binary>>}, State) -> %% Unified Request Protocol
command_start({data, OldCmd}, State) ->
[Command|Args] = binary:split(OldCmd, [<<" ">>, <<"\r\n">>], [global,trim]),
?DEBUG("Old protocol command - ~p args~n",[Command, length(Args)]),
case edis_command_runner:define_command(to_upper(Command)) of
undefined ->
ok = edis_command_runner:err(State#state.command_runner,
<<"unknown command '", Command/binary, "'">>),
{next_state, command_start, State, hibernate};
#edis_command{last_arg_is_safe = false} -> %% Last argument is inlined
ok = edis_command_runner:run(State#state.command_runner, to_upper(Command), Args),
case edis_command_runner:last_arg(edis_util:upper(Command)) of
inlined ->
ok = edis_command_runner:run(State#state.command_runner, edis_util:upper(Command), Args),
{next_state, command_start, State, hibernate};
#edis_command{args = N} ->
case erlang:length(Args) of
N ->
case lists:reverse(Args) of
[LastArg | FirstArgs] ->
case string:to_integer(binary_to_list(LastArg)) of
{error, no_integer} ->
ok = edis_command_runner:err(State#state.command_runner,
io_lib:format(
"lenght of last param expected for '~s'. ~s received instead",
[Command, LastArg])),
{next_state, command_start, State, hibernate};
{ArgSize, _Rest} ->
{next_state, argument, State#state{command_name = Command,
args = lists:reverse(FirstArgs),
missing_args = 1,
buffer = <<>>,
next_arg_size = ArgSize}}
end;
[] ->
ok = edis_command_runner:run(State#state.command_runner, to_upper(Command), []),
{next_state, command_start, State, hibernate}
safe ->
case lists:reverse(Args) of
[LastArg | FirstArgs] ->
case string:to_integer(binary_to_list(LastArg)) of
{error, no_integer} ->
ok = edis_command_runner:err(State#state.command_runner,
io_lib:format(
"lenght of last param expected for '~s'. ~s received instead",
[Command, LastArg])),
{next_state, command_start, State, hibernate};
{ArgSize, _Rest} ->
{next_state, argument, State#state{command_name = Command,
args = lists:reverse(FirstArgs),
missing_args = 1,
buffer = <<>>,
next_arg_size = ArgSize}}
end;
_ ->
ok = edis_command_runner:err(State#state.command_runner,
<<"wrong number of arguments for '", Command/binary, "' command">>),
[] ->
ok = edis_command_runner:run(State#state.command_runner, edis_util:upper(Command), []),
{next_state, command_start, State, hibernate}
end
end;
Expand Down Expand Up @@ -162,7 +151,7 @@ arg_size(Event, State) ->
command_name({data, Data}, State = #state{next_arg_size = Size, missing_args = 1}) ->
<<Command:Size/binary, _Rest/binary>> = Data,
?DEBUG("Command: ~p ~n", [Command]),
ok = edis_command_runner:run(State#state.command_runner, to_upper(Command), []),
ok = edis_command_runner:run(State#state.command_runner, edis_util:upper(Command), []),
{next_state, command_start, State, hibernate};
command_name({data, Data}, State = #state{next_arg_size = Size, missing_args = MissingArgs}) ->
<<Command:Size/binary, _Rest/binary>> = Data,
Expand All @@ -181,7 +170,7 @@ argument({data, Data}, State = #state{buffer = Buffer,
case State#state.missing_args of
1 ->
ok = edis_command_runner:run(State#state.command_runner,
to_upper(State#state.command_name),
edis_util:upper(State#state.command_name),
lists:reverse([Argument|State#state.args])),
{next_state, command_start, State, hibernate};
MissingArgs ->
Expand Down Expand Up @@ -241,24 +230,4 @@ terminate(Reason, _StateName, #state{socket = Socket, command_runner = CmdRunner
%% @hidden
-spec code_change(term(), atom(), state(), any()) -> {ok, atom(), state()}.
code_change(_OldVsn, StateName, StateData, _Extra) ->
{ok, StateName, StateData}.

%% ====================================================================
%% Internal functions
%% ====================================================================
%% @private
-spec to_upper(binary()) -> binary().
to_upper(Bin) ->
to_upper(Bin, <<>>).

%% @private
to_upper(<<>>, Acc) ->
Acc;
to_upper(<<C, Rest/binary>>, Acc) when $a =< C, C =< $z ->
to_upper(Rest, <<Acc/binary, (C-32)>>);
to_upper(<<195, C, Rest/binary>>, Acc) when 160 =< C, C =< 182 -> %% A-0 with tildes plus enye
to_upper(Rest, <<Acc/binary, 195, (C-32)>>);
to_upper(<<195, C, Rest/binary>>, Acc) when 184 =< C, C =< 190 -> %% U and Y with tilde plus greeks
to_upper(Rest, <<Acc/binary, 195, (C-32)>>);
to_upper(<<C, Rest/binary>>, Acc) ->
to_upper(Rest, <<Acc/binary, C>>).
{ok, StateName, StateData}.
10 changes: 8 additions & 2 deletions src/edis_client_sup.erl
Expand Up @@ -14,7 +14,7 @@

-behaviour(supervisor).

-export([start_link/0, start_client/0, init/1, count_clients/0]).
-export([start_link/0, start_client/0, init/1, count_clients/0, reload/0]).

%% ====================================================================
%% External functions
Expand All @@ -32,6 +32,12 @@ start_client() ->
list_to_atom("edis-client-mgr-" ++ integer_to_list(random:uniform(?MANAGERS))),
supervisor:start_child(Manager, []).

%% @doc Reloads configuration. Restarts the managers
-spec reload() -> ok.
reload() ->
true = exit(erlang:whereis(?MODULE), kill),
ok.

%% @doc Returns the count of reigstered clients under the supervision of this process
-spec count_clients() -> non_neg_integer().
count_clients() ->
Expand All @@ -57,4 +63,4 @@ init([]) ->
{edis_client_mgr, start_link, [list_to_atom("edis-client-mgr-" ++ integer_to_list(I))]},
permanent, brutal_kill, supervisor, [edis_client_mgr]}
|| I <- lists:seq(1, ?MANAGERS)],
{ok, {{one_for_one, 5, 10}, Managers}}.
{ok, {{one_for_one, length(Managers), 1}, Managers}}.

0 comments on commit 02c5daf

Please sign in to comment.