add type specs

This commit is contained in:
Steve Vinoski 2012-03-11 20:18:59 -04:00
parent 7219281b31
commit 91a6acc2a4
3 changed files with 75 additions and 21 deletions

View file

@ -50,9 +50,9 @@
%%-define(CAPABILITIES, [async_fold, indexes]). %%-define(CAPABILITIES, [async_fold, indexes]).
-define(CAPABILITIES, [async_fold]). -define(CAPABILITIES, [async_fold]).
-record(state, {conn :: reference(), -record(state, {conn :: wterl:connection(),
table :: string(), table :: string(),
session :: reference(), session :: wterl:session(),
partition :: integer()}). partition :: integer()}).
-type state() :: #state{}. -type state() :: #state{}.
@ -109,9 +109,9 @@ start(Partition, Config) ->
%% @doc Stop the wterl backend %% @doc Stop the wterl backend
-spec stop(state()) -> ok. -spec stop(state()) -> ok.
stop(#state{session=SRef}) -> stop(#state{conn=ConnRef, session=SRef}) ->
ok = wterl:session_close(SRef), ok = wterl:session_close(SRef),
wterl_conn:close(). wterl_conn:close(ConnRef).
%% @doc Retrieve an object from the wterl backend %% @doc Retrieve an object from the wterl backend
-spec get(riak_object:bucket(), riak_object:key(), state()) -> -spec get(riak_object:bucket(), riak_object:key(), state()) ->
@ -246,7 +246,7 @@ fold_objects(FoldObjectsFun, Acc, Opts, #state{conn=ConnRef, table=Table}) ->
{ok, SRef} = wterl:session_open(ConnRef), {ok, SRef} = wterl:session_open(ConnRef),
{ok, Cursor} = wterl:cursor_open(SRef, Table), {ok, Cursor} = wterl:cursor_open(SRef, Table),
try try
wterl:fold(Cursor, FoldFun, Acc) wterl:fold_keys(Cursor, FoldFun, Acc)
catch catch
{break, AccFinal} -> {break, AccFinal} ->
AccFinal AccFinal

View file

@ -20,8 +20,6 @@
%% %%
%% ------------------------------------------------------------------- %% -------------------------------------------------------------------
-module(wterl). -module(wterl).
-export([conn_open/2, -export([conn_open/2,
conn_close/1, conn_close/1,
cursor_close/1, cursor_close/1,
@ -62,6 +60,16 @@
config_to_bin/1, config_to_bin/1,
fold_keys/3]). fold_keys/3]).
-type config() :: binary().
-type config_list() :: [{atom(), any()}].
-opaque connection() :: reference().
-opaque session() :: reference().
-opaque cursor() :: reference().
-type key() :: binary().
-type value() :: binary().
-export_type([connection/0, session/0]).
-on_load(init/0). -on_load(init/0).
-define(nif_stub, nif_stub_error(?LINE)). -define(nif_stub, nif_stub_error(?LINE)).
@ -74,6 +82,7 @@ nif_stub_error(Line) ->
-include_lib("eunit/include/eunit.hrl"). -include_lib("eunit/include/eunit.hrl").
-endif. -endif.
-spec init() -> ok | {error, any()}.
init() -> init() ->
PrivDir = case code:priv_dir(?MODULE) of PrivDir = case code:priv_dir(?MODULE) of
{error, bad_name} -> {error, bad_name} ->
@ -85,109 +94,147 @@ init() ->
end, end,
erlang:load_nif(filename:join(PrivDir, ?MODULE), 0). erlang:load_nif(filename:join(PrivDir, ?MODULE), 0).
-spec conn_open(string(), config()) -> {ok, connection()} | {error, term()}.
conn_open(_HomeDir, _Config) -> conn_open(_HomeDir, _Config) ->
?nif_stub. ?nif_stub.
-spec conn_close(connection()) -> ok | {error, term()}.
conn_close(_ConnRef) -> conn_close(_ConnRef) ->
?nif_stub. ?nif_stub.
-spec session_open(connection()) -> {ok, reference()} | {error, term()}.
session_open(_ConnRef) -> session_open(_ConnRef) ->
?nif_stub. ?nif_stub.
-spec session_close(session()) -> ok | {error, term()}.
session_close(_Ref) -> session_close(_Ref) ->
?nif_stub. ?nif_stub.
-spec session_create(session(), string()) -> ok | {error, term()}.
-spec session_create(session(), string(), config()) -> ok | {error, term()}.
session_create(Ref, Name) -> session_create(Ref, Name) ->
session_create(Ref, Name, ?EMPTY_CONFIG). session_create(Ref, Name, ?EMPTY_CONFIG).
session_create(_Ref, _Name, _Config) -> session_create(_Ref, _Name, _Config) ->
?nif_stub. ?nif_stub.
-spec session_drop(session(), string()) -> ok | {error, term()}.
-spec session_drop(session(), string(), config()) -> ok | {error, term()}.
session_drop(Ref, Name) -> session_drop(Ref, Name) ->
session_drop(Ref, Name, ?EMPTY_CONFIG). session_drop(Ref, Name, ?EMPTY_CONFIG).
session_drop(_Ref, _Name, _Config) -> session_drop(_Ref, _Name, _Config) ->
?nif_stub. ?nif_stub.
-spec session_delete(session(), string(), key()) -> ok | {error, term()}.
session_delete(_Ref, _Table, _Key) -> session_delete(_Ref, _Table, _Key) ->
?nif_stub. ?nif_stub.
-spec session_get(session(), string(), key()) -> {ok, value()} | not_found | {error, term()}.
session_get(_Ref, _Table, _Key) -> session_get(_Ref, _Table, _Key) ->
?nif_stub. ?nif_stub.
-spec session_put(session(), string(), key(), value()) -> ok | {error, term()}.
session_put(_Ref, _Table, _Key, _Value) -> session_put(_Ref, _Table, _Key, _Value) ->
?nif_stub. ?nif_stub.
-spec session_rename(session(), string(), string()) -> ok | {error, term()}.
-spec session_rename(session(), string(), string(), config()) -> ok | {error, term()}.
session_rename(Ref, OldName, NewName) -> session_rename(Ref, OldName, NewName) ->
session_rename(Ref, OldName, NewName, ?EMPTY_CONFIG). session_rename(Ref, OldName, NewName, ?EMPTY_CONFIG).
session_rename(_Ref, _OldName, _NewName, _Config) -> session_rename(_Ref, _OldName, _NewName, _Config) ->
?nif_stub. ?nif_stub.
-spec session_salvage(session(), string()) -> ok | {error, term()}.
-spec session_salvage(session(), string(), config()) -> ok | {error, term()}.
session_salvage(Ref, Name) -> session_salvage(Ref, Name) ->
session_salvage(Ref, Name, ?EMPTY_CONFIG). session_salvage(Ref, Name, ?EMPTY_CONFIG).
session_salvage(_Ref, _Name, _Config) -> session_salvage(_Ref, _Name, _Config) ->
?nif_stub. ?nif_stub.
-spec session_sync(session(), string()) -> ok | {error, term()}.
-spec session_sync(session(), string(), config()) -> ok | {error, term()}.
session_sync(Ref, Name) -> session_sync(Ref, Name) ->
session_sync(Ref, Name, ?EMPTY_CONFIG). session_sync(Ref, Name, ?EMPTY_CONFIG).
session_sync(_Ref, _Name, _Config) -> session_sync(_Ref, _Name, _Config) ->
?nif_stub. ?nif_stub.
-spec session_truncate(session(), string()) -> ok | {error, term()}.
-spec session_truncate(session(), string(), config()) -> ok | {error, term()}.
session_truncate(Ref, Name) -> session_truncate(Ref, Name) ->
session_truncate(Ref, Name, ?EMPTY_CONFIG). session_truncate(Ref, Name, ?EMPTY_CONFIG).
session_truncate(_Ref, _Name, _Config) -> session_truncate(_Ref, _Name, _Config) ->
?nif_stub. ?nif_stub.
-spec session_upgrade(session(), string()) -> ok | {error, term()}.
-spec session_upgrade(session(), string(), config()) -> ok | {error, term()}.
session_upgrade(Ref, Name) -> session_upgrade(Ref, Name) ->
session_upgrade(Ref, Name, ?EMPTY_CONFIG). session_upgrade(Ref, Name, ?EMPTY_CONFIG).
session_upgrade(_Ref, _Name, _Config) -> session_upgrade(_Ref, _Name, _Config) ->
?nif_stub. ?nif_stub.
-spec session_verify(session(), string()) -> ok | {error, term()}.
-spec session_verify(session(), string(), config()) -> ok | {error, term()}.
session_verify(Ref, Name) -> session_verify(Ref, Name) ->
session_verify(Ref, Name, ?EMPTY_CONFIG). session_verify(Ref, Name, ?EMPTY_CONFIG).
session_verify(_Ref, _Name, _Config) -> session_verify(_Ref, _Name, _Config) ->
?nif_stub. ?nif_stub.
-spec cursor_open(session(), string()) -> {ok, cursor()} | {error, term()}.
cursor_open(_Ref, _Table) -> cursor_open(_Ref, _Table) ->
?nif_stub. ?nif_stub.
-spec cursor_close(cursor()) -> ok | {error, term()}.
cursor_close(_Cursor) -> cursor_close(_Cursor) ->
?nif_stub. ?nif_stub.
-spec cursor_next(cursor()) -> {ok, key(), value()} | not_found | {error, term()}.
cursor_next(_Cursor) -> cursor_next(_Cursor) ->
?nif_stub. ?nif_stub.
-spec cursor_next_key(cursor()) -> {ok, key()} | not_found | {error, term()}.
cursor_next_key(_Cursor) -> cursor_next_key(_Cursor) ->
?nif_stub. ?nif_stub.
-spec cursor_next_value(cursor()) -> {ok, value()} | not_found | {error, term()}.
cursor_next_value(_Cursor) -> cursor_next_value(_Cursor) ->
?nif_stub. ?nif_stub.
-spec cursor_prev(cursor()) -> {ok, key(), value()} | not_found | {error, term()}.
cursor_prev(_Cursor) -> cursor_prev(_Cursor) ->
?nif_stub. ?nif_stub.
-spec cursor_prev_key(cursor()) -> {ok, key()} | not_found | {error, term()}.
cursor_prev_key(_Cursor) -> cursor_prev_key(_Cursor) ->
?nif_stub. ?nif_stub.
-spec cursor_prev_value(cursor()) -> {ok, value()} | not_found | {error, term()}.
cursor_prev_value(_Cursor) -> cursor_prev_value(_Cursor) ->
?nif_stub. ?nif_stub.
-spec cursor_search(cursor(), key()) -> {ok, value()} | {error, term()}.
cursor_search(_Cursor, _Key) -> cursor_search(_Cursor, _Key) ->
?nif_stub. ?nif_stub.
-spec cursor_search_near(cursor(), key()) -> {ok, value()} | {error, term()}.
cursor_search_near(_Cursor, _Key) -> cursor_search_near(_Cursor, _Key) ->
?nif_stub. ?nif_stub.
-spec cursor_reset(cursor()) -> ok | {error, term()}.
cursor_reset(_Cursor) -> cursor_reset(_Cursor) ->
?nif_stub. ?nif_stub.
-spec cursor_insert(cursor(), key(), value()) -> ok | {error, term()}.
cursor_insert(_Cursor, _Key, _Value) -> cursor_insert(_Cursor, _Key, _Value) ->
?nif_stub. ?nif_stub.
-spec cursor_update(cursor(), key(), value()) -> ok | {error, term()}.
cursor_update(_Cursor, _Key, _Value) -> cursor_update(_Cursor, _Key, _Value) ->
?nif_stub. ?nif_stub.
-spec cursor_remove(cursor(), key(), value()) -> ok | {error, term()}.
cursor_remove(_Cursor, _Key, _Value) -> cursor_remove(_Cursor, _Key, _Value) ->
?nif_stub. ?nif_stub.
-spec fold_keys(cursor(), fun(), any()) -> any().
fold_keys(Cursor, Fun, Acc0) -> fold_keys(Cursor, Fun, Acc0) ->
fold_keys(Cursor, Fun, Acc0, cursor_next_key(Cursor)). fold_keys(Cursor, Fun, Acc0, cursor_next_key(Cursor)).
fold_keys(_Cursor, _Fun, Acc, not_found) -> fold_keys(_Cursor, _Fun, Acc, not_found) ->
@ -232,6 +279,7 @@ config_encode(bool, false) ->
config_encode(_Type, _Value) -> config_encode(_Type, _Value) ->
invalid. invalid.
-spec config_to_bin(config_list()) -> config().
config_to_bin(Opts) -> config_to_bin(Opts) ->
config_to_bin(Opts, []). config_to_bin(Opts, []).
config_to_bin([], Acc) -> config_to_bin([], Acc) ->

View file

@ -30,35 +30,41 @@
%% API %% API
-export([start_link/0, stop/0, -export([start_link/0, stop/0,
open/1, is_open/0, get/0, close/0]). open/1, is_open/0, get/0, close/1]).
%% gen_server callbacks %% gen_server callbacks
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, -export([init/1, handle_call/3, handle_cast/2, handle_info/2,
terminate/2, code_change/3]). terminate/2, code_change/3]).
-record(state, {conn, -record(state, {conn :: reference(),
monitors}). monitors :: ets:tid()}).
%% ==================================================================== %% ====================================================================
%% API %% API
%% ==================================================================== %% ====================================================================
-spec start_link() -> {ok, pid()} | {error, term()}.
start_link() -> start_link() ->
gen_server:start_link({local, ?MODULE}, ?MODULE, [], []). gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
-spec stop() -> ok.
stop() -> stop() ->
gen_server:cast(?MODULE, stop). gen_server:cast(?MODULE, stop).
-spec open(string()) -> {ok, wterl:connection()} | {error, term()}.
open(Dir) -> open(Dir) ->
gen_server:call(?MODULE, {open, Dir, self()}, infinity). gen_server:call(?MODULE, {open, Dir, self()}, infinity).
-spec is_open() -> boolean().
is_open() -> is_open() ->
gen_server:call(?MODULE, is_open, infinity). gen_server:call(?MODULE, is_open, infinity).
-spec get() -> {ok, reference()} | {error, term()}.
get() -> get() ->
gen_server:call(?MODULE, get, infinity). gen_server:call(?MODULE, get, infinity).
close() -> -spec close(wterl:connection()) -> ok.
close(_Conn) ->
gen_server:call(?MODULE, {close, self()}, infinity). gen_server:call(?MODULE, {close, self()}, infinity).
%% ==================================================================== %% ====================================================================
@ -99,7 +105,7 @@ handle_call({close, Caller}, _From, #state{conn=ConnRef, monitors=Monitors}=Stat
true = ets:delete(Monitors, Monitor), true = ets:delete(Monitors, Monitor),
NState = case ets:info(Monitors, size) of NState = case ets:info(Monitors, size) of
0 -> 0 ->
close(ConnRef), do_close(ConnRef),
ets:delete(Monitors), ets:delete(Monitors),
State#state{conn=undefined, monitors=undefined}; State#state{conn=undefined, monitors=undefined};
_ -> _ ->
@ -110,7 +116,7 @@ handle_call({close, Caller}, _From, #state{conn=ConnRef, monitors=Monitors}=Stat
handle_cast(stop, #state{conn=undefined}=State) -> handle_cast(stop, #state{conn=undefined}=State) ->
{noreply, State}; {noreply, State};
handle_cast(stop, #state{conn=ConnRef, monitors=Monitors}=State) -> handle_cast(stop, #state{conn=ConnRef, monitors=Monitors}=State) ->
close(ConnRef), do_close(ConnRef),
ets:foldl(fun({Monitor, _}, _) -> ets:foldl(fun({Monitor, _}, _) ->
true = erl:demonitor(Monitor, [flush]) true = erl:demonitor(Monitor, [flush])
end, true, Monitors), end, true, Monitors),
@ -124,7 +130,7 @@ handle_info({'DOWN', Monitor, _, _, _}, #state{conn=ConnRef, monitors=Monitors}=
true = ets:delete(Monitors, Monitor), true = ets:delete(Monitors, Monitor),
case ets:info(Monitors, size) of case ets:info(Monitors, size) of
0 -> 0 ->
close(ConnRef), do_close(ConnRef),
ets:delete(Monitors), ets:delete(Monitors),
State#state{conn=undefined, monitors=undefined}; State#state{conn=undefined, monitors=undefined};
_ -> _ ->
@ -138,7 +144,7 @@ handle_info(_Info, State) ->
{noreply, State}. {noreply, State}.
terminate(_Reason, #state{conn = ConnRef}) -> terminate(_Reason, #state{conn = ConnRef}) ->
close(ConnRef), do_close(ConnRef),
ok. ok.
code_change(_OldVsn, State, _Extra) -> code_change(_OldVsn, State, _Extra) ->
@ -148,9 +154,9 @@ code_change(_OldVsn, State, _Extra) ->
%% Internal functions %% Internal functions
%% ==================================================================== %% ====================================================================
close(undefined) -> do_close(undefined) ->
ok; ok;
close(ConnRef) -> do_close(ConnRef) ->
wterl:conn_close(ConnRef). wterl:conn_close(ConnRef).
@ -182,18 +188,18 @@ simple_test_() ->
end}]}. end}]}.
open_one() -> open_one() ->
{ok, _Ref} = open("test/wterl-backend"), {ok, Ref} = open("test/wterl-backend"),
true = is_open(), true = is_open(),
close(), close(Ref),
false = is_open(), false = is_open(),
ok. ok.
open_and_wait(Pid) -> open_and_wait(Pid) ->
{ok, _Ref} = open("test/wterl-backend"), {ok, Ref} = open("test/wterl-backend"),
Pid ! open, Pid ! open,
receive receive
close -> close ->
close(), close(Ref),
Pid ! close; Pid ! close;
exit -> exit ->
exit(normal) exit(normal)