Permalink
Browse files

renaming mcerlang to erlmc

  • Loading branch information...
1 parent 4e9885e commit f6d086a2a384ab3e3241cb2d91707963f9d0bc98 Jacob Vorreuter committed Oct 20, 2009
View
@@ -1,6 +1,6 @@
LIBDIR=`erl -eval 'io:format("~s~n", [code:lib_dir()])' -s init stop -noshell`
VERSION=0.2
-PKGNAME=mcerlang
+PKGNAME=erlmc
all: app
mkdir -p ebin/
View
@@ -1,54 +1,41 @@
-# MC Erlang caches beats on your face
+## erlmc
Erlang binary protocol memcached client
-## Dependencies
-
-Binary protocol build of memcached <http://github.com/dustin/memcached>
-
## External Documentation
-Text Protocol Spec <http://code.sixapart.com/svn/memcached/trunk/server/doc/protocol.txt>
-
Binary Protocol Spec <http://code.google.com/p/memcached/wiki/MemcacheBinaryProtocol>
## Quick Start
-**You must have the binary protocol branch of memcached running as mentioned above**
+**You must have version 1.3 or greater of memcached**
$> make
$> make test
$> sudo make install
- $> memcached -d -m 1024 -p 11211 -l localhost
- $> memcached -d -m 1024 -p 11121 -l localhost
+ $> memcached -d
- 1> mcerlang:start_link([{"localhost", 11211, 1}, {"localhost", 11121, 1}]).
- {ok,<0.37.0>}
+ 1> erlmc:start().
+ ok
- 2> mcerlang:stats().
+ 2> erlmc:stats().
[{{"localhost",11211},
[{evictions,"0"},
{total_items,"0"},
{curr_items,"0"},
{bytes,"0"},
- {...}|...]},
- {{"localhost",11121},
- [{evictions,"0"},
- {total_items,"0"},
- {curr_items,"0"},
- {bytes,"0"},
{...}|...]}]
- 3> mcerlang:set(hello, <<"World">>).
+ 3> erlmc:set(hello, <<"World">>).
<<>>
- 4> mcerlang:get(hello).
+ 4> erlmc:get(hello).
<<"World">>
- 5> mcerlang:add("foo", <<"bar">>).
+ 5> erlmc:add("foo", <<"bar">>).
<<>>
- 6> mcerlang:get("foo").
+ 6> erlmc:get("foo").
<<"bar">>
## Commands
@@ -3,11 +3,11 @@
VERSION=${1}
MODULES=`ls -1 src/*.erl | awk -F[/.] '{ print "\t\t" $2 }' | sed '$q;s/$/,/g'`
-cat > ebin/mcerlang.app << EOF
-{application, mcerlang,
+cat > ebin/erlmc.app << EOF
+{application, erlmc,
[{description, "Erlang binary protocol memcached client"},
{vsn, "${VERSION}"},
- {modules, [mcerlang]},
+ {modules, [erlmc]},
{registered, []},
{applications, [kernel, stdlib]}
]}.
File renamed without changes.
@@ -24,7 +24,7 @@
%%
%% http://code.google.com/p/memcached/wiki/MemcacheBinaryProtocol
%% @doc a binary protocol memcached client
--module(mcerlang).
+-module(erlmc).
-export([start/0, start/1, start_link/0, start_link/1, init/2,
add_server/3, remove_server/2, add_connection/2, remove_connection/2]).
@@ -35,7 +35,7 @@
append/2, prepend/2, stats/0, flush/0, flush/1, quit/0,
version/0]).
--include("mcerlang.hrl").
+-include("erlmc.hrl").
-define(TIMEOUT, 60000).
@@ -161,9 +161,9 @@ multi_call(Msg) ->
%%--------------------------------------------------------------------
init(Parent, CacheServers) ->
process_flag(trap_exit, true),
- register(mcerlang, self()),
- ets:new(mcerlang_continuum, [ordered_set, protected, named_table]),
- ets:new(mcerlang_connections, [bag, protected, named_table]),
+ register(erlmc, self()),
+ ets:new(erlmc_continuum, [ordered_set, protected, named_table]),
+ ets:new(erlmc_connections, [bag, protected, named_table]),
%% Continuum = [{uint(), {Host, Port}}]
[add_server_to_continuum(Host, Port) || {Host, Port, _} <- CacheServers],
@@ -183,17 +183,17 @@ loop() ->
add_server_to_continuum(Host, Port),
[start_connection(Host, Port) || _ <- lists:seq(1, ConnPoolSize)];
{remove_server, Host, Port} ->
- [(catch gen_server:call(Pid, quit, ?TIMEOUT)) || [Pid] <- ets:match(mcerlang_connections, {{Host, Port}, '$1'})],
+ [(catch gen_server:call(Pid, quit, ?TIMEOUT)) || [Pid] <- ets:match(erlmc_connections, {{Host, Port}, '$1'})],
remove_server_from_continuum(Host, Port);
{add_connection, Host, Port} ->
start_connection(Host, Port);
{remove_connection, Host, Port} ->
- [[Pid]|_] = ets:match(mcerlang_connections, {{Host, Port}, '$1'}),
+ [[Pid]|_] = ets:match(erlmc_connections, {{Host, Port}, '$1'}),
(catch gen_server:call(Pid, quit, ?TIMEOUT));
{'EXIT', Pid, Err} ->
- case ets:match(mcerlang_connections, {'$1', Pid}) of
+ case ets:match(erlmc_connections, {'$1', Pid}) of
[[{Host, Port}]] ->
- ets:delete_object(mcerlang_connections, {{Host, Port}, Pid}),
+ ets:delete_object(erlmc_connections, {{Host, Port}, Pid}),
case Err of
shutdown -> ok;
_ -> start_connection(Host, Port)
@@ -205,23 +205,23 @@ loop() ->
loop().
start_connection(Host, Port) ->
- case mcerlang_conn:start_link([Host, Port]) of
- {ok, Pid} -> ets:insert(mcerlang_connections, {{Host, Port}, Pid});
+ case erlmc_conn:start_link([Host, Port]) of
+ {ok, Pid} -> ets:insert(erlmc_connections, {{Host, Port}, Pid});
_ -> ok
end.
%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
add_server_to_continuum(Host, Port) ->
- [ets:insert(mcerlang_continuum, {hash_to_uint(Host, Port), {Host, Port}}) || _ <- lists:seq(1, 100)].
+ [ets:insert(erlmc_continuum, {hash_to_uint(Host, Port), {Host, Port}}) || _ <- lists:seq(1, 100)].
remove_server_from_continuum(Host, Port) ->
- case ets:match(mcerlang_continuum, {'$1', {Host, Port}}) of
+ case ets:match(erlmc_continuum, {'$1', {Host, Port}}) of
[] ->
ok;
List ->
- [ets:delete(mcerlang_continuum, Key) || [Key] <- List]
+ [ets:delete(erlmc_continuum, Key) || [Key] <- List]
end.
package_key(Key) when is_atom(Key) ->
@@ -240,7 +240,7 @@ unique_connections() ->
dict:to_list(lists:foldl(
fun({Key, Val}, Dict) ->
dict:append_list(Key, [Val], Dict)
- end, dict:new(), ets:tab2list(mcerlang_connections))).
+ end, dict:new(), ets:tab2list(erlmc_connections))).
%% Consistent hashing functions
%%
@@ -259,19 +259,19 @@ hash_to_uint(Key) when is_list(Key) ->
%% Key = string()
%% Conn = pid()
map_key(Key) when is_list(Key) ->
- First = ets:first(mcerlang_continuum),
+ First = ets:first(erlmc_continuum),
{Host, Port} =
case find_next_largest(hash_to_uint(Key), First) of
undefined ->
case First of
- '$end_of_table' -> exit(mcerlang_continuum_empty);
+ '$end_of_table' -> exit(erlmc_continuum_empty);
_ ->
- [{_, Value}] = ets:lookup(mcerlang_continuum, First),
+ [{_, Value}] = ets:lookup(erlmc_continuum, First),
Value
end;
Value -> Value
end,
- case ets:lookup(mcerlang_connections, {Host, Port}) of
+ case ets:lookup(erlmc_connections, {Host, Port}) of
[] -> exit({error, {connection_not_found, {Host, Port}}});
Pids ->
{_, Pid} = lists:nth(random:uniform(length(Pids)), Pids),
@@ -283,8 +283,8 @@ find_next_largest(_, '$end_of_table') ->
undefined;
find_next_largest(Int, Key) when Key > Int ->
- [{_, Val}] = ets:lookup(mcerlang_continuum, Key),
+ [{_, Val}] = ets:lookup(erlmc_continuum, Key),
Val;
find_next_largest(Int, Key) ->
- find_next_largest(Int, ets:next(mcerlang_continuum, Key)).
+ find_next_largest(Int, ets:next(erlmc_continuum, Key)).
@@ -24,10 +24,10 @@
%%
%% http://code.google.com/p/memcached/wiki/MemcacheBinaryProtocol
%% @doc a binary protocol memcached client
--module(mcerlang_conn).
+-module(erlmc_conn).
-behaviour(gen_server).
--include("mcerlang.hrl").
+-include("erlmc.hrl").
%% gen_server callbacks
-export([start_link/1, init/1, handle_call/3, handle_cast/2,
View
@@ -0,0 +1,48 @@
+#!/usr/bin/env escript
+%% -*- erlang -*-
+%%! -pa ./ebin -sasl errlog_type error -boot start_sasl -noshell
+
+main(_) ->
+ etap:plan(unknown),
+
+ (fun() ->
+ {ok, Socket} = gen_tcp:connect("localhost", 11211, [binary, {packet, 0}, {active, false}]),
+
+ gen_tcp:send(Socket, <<128,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0>>),
+ etap:ok((fun({ok, _}) -> true; (_) -> false end)(gen_tcp:recv(Socket, 0, 2000)), "noop"),
+
+ gen_tcp:send(Socket, <<128,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0>>),
+
+ ok
+ end)(),
+
+ (fun() ->
+ etap:is(erlmc:start(), ok, "erlmc connect to default memcached server ok"),
+
+ etap:is(erlmc:set("Hello", <<"World">>), <<>>, "set ok"),
+ etap:is(erlmc:add("Hello", <<"Fail">>), <<"Data exists for key.">>, "add ok"),
+ etap:is(erlmc:get("Hello"), <<"World">>, "get ok"),
+ etap:is(erlmc:delete("Hello"), <<>>, "delete ok"),
+ etap:is(erlmc:add("Hello", <<"World2">>), <<>>, "add ok"),
+ etap:is(erlmc:get("Hello"), <<"World2">>, "get ok"),
+ etap:is(erlmc:append("Hello", <<"!!!">>), <<>>, "append ok"),
+ etap:is(erlmc:get("Hello"), <<"World2!!!">>, "get ok"),
+ etap:is(erlmc:prepend("Hello", <<"$$$">>), <<>>, "prepend ok"),
+ etap:is(erlmc:get("Hello"), <<"$$$World2!!!">>, "get ok"),
+ etap:is(erlmc:delete("Hello"), <<>>, "delete ok"),
+ etap:is(erlmc:get("Hello"), <<>>, "get ok"),
+
+ erlmc:set("One", <<"A">>),
+ erlmc:set("Two", <<"B">>),
+ erlmc:set("Three", <<"C">>),
+
+ etap:is(erlmc:get_many(["One", "Two", "Two-and-a-half", "Three"]), [{"One",<<"A">>},{"Two",<<"B">>},{"Two-and-a-half",<<>>},{"Three",<<"C">>}], "get_many ok"),
+
+ etap:is(erlmc:flush(0), [{{"localhost",11211},<<>>}], "flush ok"),
+
+ etap:is(erlmc:quit(), [{{"localhost",11211},[true]}], "quit ok"),
+
+ ok
+ end)(),
+
+ etap:end_tests().
View
@@ -1,48 +0,0 @@
-#!/usr/bin/env escript
-%% -*- erlang -*-
-%%! -pa ./ebin -sasl errlog_type error -boot start_sasl -noshell
-
-main(_) ->
- etap:plan(unknown),
-
- (fun() ->
- {ok, Socket} = gen_tcp:connect("localhost", 11211, [binary, {packet, 0}, {active, false}]),
-
- gen_tcp:send(Socket, <<128,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0>>),
- etap:ok((fun({ok, _}) -> true; (_) -> false end)(gen_tcp:recv(Socket, 0, 2000)), "noop"),
-
- gen_tcp:send(Socket, <<128,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0>>),
-
- ok
- end)(),
-
- (fun() ->
- etap:is(mcerlang:start(), ok, "mcerlang connect to default memcached server ok"),
-
- etap:is(mcerlang:set("Hello", <<"World">>), <<>>, "set ok"),
- etap:is(mcerlang:add("Hello", <<"Fail">>), <<"Data exists for key.">>, "add ok"),
- etap:is(mcerlang:get("Hello"), <<"World">>, "get ok"),
- etap:is(mcerlang:delete("Hello"), <<>>, "delete ok"),
- etap:is(mcerlang:add("Hello", <<"World2">>), <<>>, "add ok"),
- etap:is(mcerlang:get("Hello"), <<"World2">>, "get ok"),
- etap:is(mcerlang:append("Hello", <<"!!!">>), <<>>, "append ok"),
- etap:is(mcerlang:get("Hello"), <<"World2!!!">>, "get ok"),
- etap:is(mcerlang:prepend("Hello", <<"$$$">>), <<>>, "prepend ok"),
- etap:is(mcerlang:get("Hello"), <<"$$$World2!!!">>, "get ok"),
- etap:is(mcerlang:delete("Hello"), <<>>, "delete ok"),
- etap:is(mcerlang:get("Hello"), <<>>, "get ok"),
-
- mcerlang:set("One", <<"A">>),
- mcerlang:set("Two", <<"B">>),
- mcerlang:set("Three", <<"C">>),
-
- etap:is(mcerlang:get_many(["One", "Two", "Two-and-a-half", "Three"]), [{"One",<<"A">>},{"Two",<<"B">>},{"Two-and-a-half",<<>>},{"Three",<<"C">>}], "get_many ok"),
-
- etap:is(mcerlang:flush(0), [{{"localhost",11211},<<>>}], "flush ok"),
-
- etap:is(mcerlang:quit(), [{{"localhost",11211},[true]}], "quit ok"),
-
- ok
- end)(),
-
- etap:end_tests().

1 comment on commit f6d086a

@ngerakines
Contributor

Is it safe to drop my mcerlang repos then?

Please sign in to comment.