forked from cstar/erldis
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
14 changed files
with
1,033 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{"src/*", [ | ||
debug_info, | ||
{i, "include/"}, | ||
{outdir, "ebin/"} | ||
]}. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
@doc Redis erlang client | ||
|
||
From dialtone on erldis_client: | ||
handle_info is the function that deals with parsing every line that comes from redis. save_or_reply is what is currently used to send replies back to the users. | ||
going through the State parameters: | ||
* socket is of course the current connection to redis | ||
* buffer contains intermediate results of parsing. it's used for multi-bulk replies. but it gets handy also for single bulk replies, although clearly it will be at most long 1 in those cases | ||
* reply_caller is a function used to abstract the reply to the user. since the call is synchronous, the client might put itself in listening slower than redis can answer the request. when it manages to listen before the answer it adds a call that registers the call request and when it's done the system uses that function to send back the results. if it comes afterwards it simply gets the results in save_or_reply the function checks for reply_caller and if it's not there it just appends to results | ||
* the field remaining is for how many remaining packets you need to handle before the end of this call. this is also especially useful for multi-bulk replies. when a call is made it's set to 1 then the rest of the state machine figures out if only 1 packet will be received or how many more (the state machine is in erldis_proto) | ||
* then the field calls is the number of calls that are waiting. basically at the end of a call remaining would go to 0. but if it goes to 0 the state machine would parse the remaining stuff. so using calls we keep track of how many more calls are incoming and until calls is 0 remaining is reset to 1 when it goes to 0 at the end of a parsing. and this is done in save_or_reply | ||
* then pstate is the parser state, there can be only 4 right now error, hold, read, empty. error means that the next line is an error message. hold means that the next number is the number of multi-bulk items in the reply and is used to set the remaining field to something else than 1. read tells you how long the next field is so you need to read those bytes + 2 (\r\n are added by redis but not counted in the bytes... I fought hard to avoid this but salvatore didn't change it...). then empty means that the system is ready to accept a new reply. the function trim2 exists just to remove the \r\n at the end of the reply |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,11 @@ | ||
{application, erldis, [ | ||
{description, "Erlang Redis application"}, | ||
{vsn, "0.0.1"}, | ||
{vsn, "0.0.7"}, | ||
{registered, [erldis_sup]}, | ||
{mod, {erldis_app, []}}, | ||
% TODO: include eunit? | ||
{applications, [kernel, stdlib]}, | ||
{modules, [erldis_client, erldis, erldis_proto, erldis_app, erldis_sup]}, | ||
{modules, [erldis_client, erldis, erldis_proto, erldis_app, erldis_sup, | ||
erldis_sync_client, erldis_sets, erldis_dict, erldis_list]}, | ||
{env, [{host, "localhost"}, {port, 6379}, {timeout, 500}]} | ||
]}. | ||
]}. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
{"0.0.7", [ | ||
{"0.0.6", [ | ||
{load_module, erldis_sync_client}, | ||
{load_module, erldis_dict}, | ||
{load_module, erldis_list} | ||
]}, | ||
{"0.0.5", [ | ||
{load_module, erldis_sync_client}, | ||
{load_module, erldis_sets}, | ||
{add_module, erldis_dict}, | ||
{add_module, erldis_list} | ||
]}, | ||
{"0.0.4", [ | ||
{load_module, erldis_sync_client}, | ||
{load_module, erldis_sets} | ||
]}, | ||
{"0.0.3", [ | ||
{load_module, erldis_sync_client}, | ||
{load_module, erldis_sets} | ||
]}, | ||
{"0.0.2", [ | ||
{add_module, erldis_sync_client}, | ||
{load_module, erldis_sets} | ||
]}, | ||
{"0.0.1", [ | ||
{add_module, erldis_client}, | ||
{add_module, erldis_proto}, | ||
{load_module, erldis}, | ||
{delete_module, client}, | ||
{delete_module, proto}, | ||
{add_module, erldis_sets} | ||
]} | ||
], [ | ||
{"0.0.6", [ | ||
{load_module, erldis_sync_client}, | ||
{load_module, erldis_dict}, | ||
{load_module, erldis_list} | ||
]}, | ||
{"0.0.5", [ | ||
{load_module, erldis_sync_client}, | ||
{load_module, erldis_sets}, | ||
{delete_module, erldis_dict}, | ||
{delete_module, erldis_list} | ||
]}, | ||
{"0.0.4", [ | ||
{load_module, erldis_sync_client}, | ||
{load_module, erldis_sets} | ||
]}, | ||
{"0.0.3", [ | ||
{load_module, erldis_sync_client}, | ||
{load_module, erldis_sets} | ||
]}, | ||
{"0.0.2", [ | ||
{delete_module, erldis_sync_client}, | ||
{load_module, erldis_sets} | ||
]}, | ||
{"0.0.1", [ | ||
{add_module, client}, | ||
{add_module, proto}, | ||
{load_module, erldis}, | ||
{delete_module, erldis_client}, | ||
{delete_module, erldis_proto}, | ||
{delete_module, erldis_sets} | ||
]} | ||
]}. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
-module(erldis_dict). | ||
|
||
-export([append/3, append_list/3, erase/2, fetch/2, fetch_keys/2, find/2, | ||
is_key/2, size/1, store/3, update/3, update/4, | ||
update_counter/2, update_counter/3]). | ||
|
||
% NOTE: use erldis_lists instead, fetch & find won't work for lists | ||
append(Key, Value, Client) -> set_call(Client, rpush, Key, Value). | ||
|
||
append_list(Key, Values, Client) -> | ||
lists:foreach(fun(Value) -> append(Key, Value, Client) end, Values). | ||
|
||
erase(Key, Client) -> scall(Client, del, [Key]). | ||
|
||
fetch(Key, Client) -> | ||
case scall(Client, get, [Key]) of | ||
[nil] -> undefined; | ||
[Value] -> Value | ||
end. | ||
|
||
% NOTE: this is only useful if keys have a known prefix | ||
fetch_keys(Pattern, Client) -> scall(Client, keys, [Pattern]). | ||
|
||
%filter(Pred, Client) -> ok. | ||
|
||
find(Key, Client) -> | ||
case fetch(Key, Client) of | ||
undefined -> error; | ||
Value -> {ok, Value} | ||
end. | ||
|
||
%fold(Fun, Acc0, Client) -> ok. | ||
|
||
%from_list(List, Client) -> ok. | ||
|
||
is_key(Key, Client) -> hd(scall(Client, exists, [Key])). | ||
|
||
size(Client) -> | ||
numeric_value(erldis_sync_client:scall(Client, dbsize)). | ||
|
||
store(Key, [], Client) -> erase(Key, Client); | ||
store(Key, Value, Client) -> set_call(Client, set, Key, Value). | ||
|
||
%to_list(Client) -> ok. | ||
|
||
% NOTE: update/3 & update/4 are not atomic | ||
|
||
update(Key, Fun, Client) -> store(Key, Fun(fetch(Key, Client)), Client). | ||
|
||
update(Key, Fun, Initial, Client) -> | ||
case find(Key, Client) of | ||
{ok, Value} -> store(Key, Fun(Value), Client); | ||
error -> store(Key, Initial, Client) | ||
end. | ||
|
||
update_counter(Key, Client) -> update_counter(Key, 1, Client). | ||
|
||
% NOTE: this returns new count value, not a modified dict | ||
update_counter(Key, 1, Client) -> | ||
numeric_value(scall(Client, incr, [Key])); | ||
update_counter(Key, Incr, Client) -> | ||
numeric_value(scall(Client, incrby, [Key, Incr])). | ||
|
||
%%%%%%%%%%%%% | ||
%% helpers %% | ||
%%%%%%%%%%%%% | ||
|
||
numeric_value([false]) -> 0; | ||
numeric_value([true]) -> 1; | ||
numeric_value([Val]) -> Val. | ||
|
||
% TODO: copied from erldis_sets, abstract if possible, maybe use a macro | ||
|
||
scall(Client, Cmd, Args) -> erldis_sync_client:scall(Client, Cmd, Args). | ||
|
||
set_call(Client, Cmd, Key, Val) -> | ||
erldis_sync_client:call(Client, Cmd, [[Key, length(Val)], [Val]]). |
Oops, something went wrong.