|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| -module(seb_kernel_nif).
|
| -behaviour(gen_server).
|
|
|
| -export([start_link/0]).
|
| -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).
|
|
|
| -export([
|
| init_kernel/2,
|
| append_event/4,
|
| rotate_segment/3,
|
| verify_chain/1,
|
| worm_flush/1,
|
| get_state/1,
|
| get_tip_hash/1
|
| ]).
|
|
|
| -define(SERVER, ?MODULE).
|
| -define(NIF_LIB, "seb_wal_nif").
|
|
|
| -record(state, {handle}).
|
|
|
|
|
|
|
|
|
|
|
| start_link() ->
|
| gen_server:start_link({local, ?SERVER}, ?MODULE, [], []).
|
|
|
| -spec init_kernel(non_neg_integer(), non_neg_integer()) ->
|
| {ok, reference()} | {error, term()}.
|
| init_kernel(SegId, Seq) ->
|
| gen_server:call(?SERVER, {init_kernel, SegId, Seq}).
|
|
|
| -spec append_event(reference(), binary(), binary(), binary()) ->
|
| {ok, non_neg_integer()} | {error, term()}.
|
| append_event(Handle, Header, Payload, Footer) ->
|
| gen_server:call(?SERVER, {append_event, Handle, Header, Payload, Footer}).
|
|
|
| -spec rotate_segment(reference(), non_neg_integer(), non_neg_integer()) ->
|
| {ok, 0} | {error, term()}.
|
| rotate_segment(Handle, NewSegId, NewSeq) ->
|
| gen_server:call(?SERVER, {rotate_segment, Handle, NewSegId, NewSeq}).
|
|
|
| -spec verify_chain(reference()) -> {ok, non_neg_integer()} | {error, term()}.
|
| verify_chain(Handle) ->
|
| gen_server:call(?SERVER, {verify_chain, Handle}).
|
|
|
| -spec worm_flush(reference()) -> ok.
|
| worm_flush(Handle) ->
|
| gen_server:call(?SERVER, {worm_flush, Handle}).
|
|
|
| -spec get_state(reference()) ->
|
| {non_neg_integer(), non_neg_integer(), non_neg_integer(),
|
| non_neg_integer(), non_neg_integer()}.
|
| get_state(Handle) ->
|
| gen_server:call(?SERVER, {get_state, Handle}).
|
|
|
| -spec get_tip_hash(reference()) -> {ok, binary()} | {error, term()}.
|
| get_tip_hash(Handle) ->
|
| gen_server:call(?SERVER, {get_tip_hash, Handle}).
|
|
|
|
|
|
|
|
|
|
|
| init([]) ->
|
| SoPath = filename:join([code:priv_dir(seb), ?NIF_LIB]),
|
| case erlang:load_nif(SoPath, []) of
|
| ok ->
|
| {ok, Handle} = nif_init_kernel(0, 0),
|
| {ok, #state{handle = Handle}};
|
| {error, {reload, _}} ->
|
| {ok, Handle} = nif_init_kernel(0, 0),
|
| {ok, #state{handle = Handle}};
|
| {error, Reason} ->
|
| {stop, {nif_load_failed, SoPath, Reason}}
|
| end.
|
|
|
| handle_call({init_kernel, SegId, Seq}, _From, State) ->
|
| {reply, nif_init_kernel(SegId, Seq), State};
|
| handle_call({append_event, Handle, Hdr, Pay, Ftr}, _From, State) ->
|
| {reply, nif_append_event(Handle, Hdr, Pay, Ftr), State};
|
| handle_call({rotate_segment, Handle, Id, Seq}, _From, State) ->
|
| {reply, nif_rotate_segment(Handle, Id, Seq), State};
|
| handle_call({verify_chain, Handle}, _From, State) ->
|
| {reply, nif_verify_chain(Handle), State};
|
| handle_call({worm_flush, Handle}, _From, State) ->
|
| {reply, nif_worm_flush(Handle), State};
|
| handle_call({get_state, Handle}, _From, State) ->
|
| {reply, nif_get_state(Handle), State};
|
| handle_call({get_tip_hash, Handle}, _From, State) ->
|
| {reply, nif_get_tip_hash(Handle), State};
|
| handle_call(_Req, _From, State) ->
|
| {reply, {error, unknown_call}, State}.
|
|
|
| handle_cast(_Msg, State) -> {noreply, State}.
|
| handle_info(_Info, State) -> {noreply, State}.
|
| terminate(_Reason, _State) -> ok.
|
| code_change(_OldVsn, State, _Extra) -> {ok, State}.
|
|
|
|
|
|
|
|
|
|
|
| nif_init_kernel(_SegId, _Seq) -> erlang:nif_error(nif_not_loaded).
|
| nif_append_event(_H, _Hdr, _Pay, _Ftr) -> erlang:nif_error(nif_not_loaded).
|
| nif_rotate_segment(_H, _Id, _Seq) -> erlang:nif_error(nif_not_loaded).
|
| nif_verify_chain(_H) -> erlang:nif_error(nif_not_loaded).
|
| nif_worm_flush(_H) -> erlang:nif_error(nif_not_loaded).
|
| nif_get_state(_H) -> erlang:nif_error(nif_not_loaded).
|
| nif_get_tip_hash(_H) -> erlang:nif_error(nif_not_loaded).
|
|
|