summaryrefslogtreecommitdiff
path: root/src/db.erl
diff options
context:
space:
mode:
authorLinus Nordberg <linus@nordberg.se>2014-09-27 15:45:14 +0200
committerLinus Nordberg <linus@nordberg.se>2014-09-29 10:21:56 +0200
commitb676b219edbc7f743dc4e186433a48e36424723a (patch)
tree3c527ffb679bada1ab0c9a746bf02b2868ad8514 /src/db.erl
parentf44b7bf29dc10a4dc3a13bbe8ae5ad74979517b1 (diff)
Clean up the plop interface, in preparation for a new db implementation.
Diffstat (limited to 'src/db.erl')
-rw-r--r--src/db.erl126
1 files changed, 75 insertions, 51 deletions
diff --git a/src/db.erl b/src/db.erl
index 3ab2d1b..ddebbeb 100644
--- a/src/db.erl
+++ b/src/db.erl
@@ -7,7 +7,8 @@
%% API.
-export([start_link/0, stop/0]).
-export([init_db/0, init_db/1, init_tables/0, init_tables/1]).
--export([add/1, find/2, get_by_index/2, get_by_index_sorted/2, size/0]).
+-export([add/4, size/0]).
+-export([get_by_index/1, get_by_indices/3, get_by_leaf_hash/1, get_by_entry_hash/1]).
%% API for testing.
-export([dump/1, destroy_tables/0, info_tables/0, dump_to_file/1]).
%% gen_server callbacks.
@@ -72,24 +73,31 @@ stop() ->
%%%%%%%%%%%%%%%%%%%%
%% Public API.
--spec add(plop()) -> {atomic, ok}.
-add(Entry) ->
- gen_server:call(?MODULE, {add, Entry}).
+-spec add(binary(), binary(), binary(), non_neg_integer()) -> ok.
+add(LeafHash, EntryHash, Data, Index) ->
+ gen_server:call(?MODULE, {add, {LeafHash, EntryHash, Data, Index}}).
-%% @doc Find one entry.
--spec find(entryhash | mtlhash | index, binary()) ->
- [] | plop() | duplicate_hash_in_db.
-find(Type, Hash) ->
- gen_server:call(?MODULE, {find, Type, Hash}).
+-spec get_by_indices(non_neg_integer(),
+ non_neg_integer(),
+ {sorted, true|false}) ->
+ [{non_neg_integer(), binary(), binary()}].
+get_by_indices(Start, End, {sorted, Sorted}) ->
+ gen_server:call(?MODULE, {get_by_indices, {Start, End, Sorted}}).
--spec get_by_index(non_neg_integer(), non_neg_integer()) -> [{mtl(), binary()}].
-get_by_index(Start, End) ->
- gen_server:call(?MODULE, {get_by_index, {Start, End}}).
+-spec get_by_index(binary()) -> notfound |
+ {non_neg_integer(), binary(), binary()}.
+get_by_index(Index) ->
+ gen_server:call(?MODULE, {get_by_index, Index}).
--spec get_by_index_sorted(non_neg_integer(), non_neg_integer()) ->
- [{mtl(), binary()}].
-get_by_index_sorted(Start, End) ->
- gen_server:call(?MODULE, {get_by_index_sorted, {Start, End}}).
+-spec get_by_leaf_hash(binary()) -> notfound |
+ {non_neg_integer(), binary(), binary()}.
+get_by_leaf_hash(LeafHash) ->
+ gen_server:call(?MODULE, {get_by_leaf_hash, LeafHash}).
+
+-spec get_by_entry_hash(binary()) -> notfound |
+ {non_neg_integer(), binary(), binary()}.
+get_by_entry_hash(EntryHash) ->
+ gen_server:call(?MODULE, {get_by_entry_hash, EntryHash}).
%% Testing and debugging.
dump(Table) ->
@@ -117,50 +125,64 @@ terminate(_Reason, _State) ->
handle_call(stop, _From, State) ->
{stop, normal, stopped, State};
-handle_call({add, Entry}, _From, State) ->
- F = fun() ->
- mnesia:write(Entry)
- end,
- Res = mnesia:transaction(F),
- {reply, Res, State};
-
-handle_call({dump, Table}, _From, State) ->
- F = fun() ->
- Q = qlc:q([E || E <- mnesia:table(Table)]),
- qlc:e(Q)
+handle_call({add, {LeafHash, EntryHash, Data, Index}}, _From, State) ->
+ R = mnesia:transaction(
+ fun() ->
+ mnesia:write(
+ #plop{
+ index = Index,
+ mtlhash = LeafHash,
+ entryhash = EntryHash,
+ logentry = Data})
+ end),
+ {reply, R, State};
+
+handle_call({get_by_indices, {Start, End, Sorted}}, _From, State) ->
+ R = case Sorted of
+ false ->
+ select_index(Start, End);
+ true ->
+ %% FIXME: RAM hog -- how bad is it?
+ lists:sort(select_index(Start, End))
end,
- Res = mnesia:transaction(F),
- {reply, Res, State};
+ {reply, R, State};
-handle_call({find, entryhash, Hash}, _From, State) ->
+handle_call({get_by_index, Index}, _From, State) ->
{reply,
- find_entry(fun() -> mnesia:index_read(plop, Hash, #plop.entryhash) end),
- State};
-handle_call({find, mtlhash, Hash}, _From, State) ->
- {reply,
- find_entry(fun() -> mnesia:index_read(plop, Hash, #plop.mtlhash) end),
+ find_entry(fun() -> mnesia:read(plop, Index) end),
State};
-handle_call({find, index, Index}, _From, State) ->
+
+handle_call({get_by_leaf_hash, LeafHash}, _From, State) ->
{reply,
- find_entry(fun() -> mnesia:read(plop, Index) end),
+ find_entry(fun() ->
+ mnesia:index_read(plop, LeafHash, #plop.mtlhash)
+ end),
State};
-handle_call({get_by_index, {Start, End}}, _From, State) ->
- Res = [{MTL, Extra} || [_Index, MTL, Extra] <- select_index(Start, End)],
- {reply, Res, State};
+handle_call({get_by_entry_hash, EntryHash}, _From, State) ->
+ {reply,
+ find_entry(fun() ->
+ mnesia:index_read(plop, EntryHash, #plop.entryhash)
+ end),
+ State};
-handle_call({get_by_index_sorted, {Start, End}}, _From, State) ->
- %% FIXME: RAM hog -- how bad is it?
- Res = [{MTL, Extra} || [_Index, MTL, Extra] <- lists:sort(select_index(Start, End))],
- {reply, Res, State}.
+handle_call({dump, Table}, _From, State) ->
+ R = mnesia:transaction(
+ fun() ->
+ Q = qlc:q([E || E <- mnesia:table(Table)]),
+ qlc:e(Q)
+ end),
+ {reply, R, State}.
%%%%%%%%%%%%%%%%%%%%
%% Helper functions.
+-spec select_index(non_neg_integer(), non_neg_integer()) ->
+ [{non_neg_integer(), binary(), binary()}].
select_index(Start, End) ->
F = fun() ->
- %% Get index, mtl and extra_data.
- MatchHead = {plop, '$1', '_', '_', '$2', '$3', '_'},
+ %% Get index, mtlhash and logentry.
+ MatchHead = {plop, '$1', '$2', '_', '$3'},
Guard = [{'>=', '$1', Start}, {'=<', '$1', End}],
Result = ['$$'],
mnesia:select(plop, [{MatchHead, Guard, Result}])
@@ -168,11 +190,13 @@ select_index(Start, End) ->
{atomic, Res} = mnesia:transaction(F),
Res.
--spec find_entry(fun()) -> [] | plop() | duplicate_hash_in_db.
+-spec find_entry(fun()) -> notfound |
+ {non_neg_integer(), binary(), binary()} |
+ duplicate.
find_entry(Fun) ->
{atomic, Result} = mnesia:transaction(Fun),
- case length(Result) of
- 0 -> [];
- 1 -> hd(Result);
- _ -> duplicate_hash_in_db % FIXME: log an error?
+ case Result of
+ [] -> notfound;
+ [#plop{index = I, mtlhash = H, logentry = E}] -> {I, H, E};
+ _ -> duplicate
end.