From 5fc1ec8ac6d76f5798373658b06021696f5e1e02 Mon Sep 17 00:00:00 2001 From: Linus Nordberg Date: Thu, 29 May 2014 12:38:41 +0200 Subject: Add db:size/0 and some error checking. --- src/db.erl | 23 +++++++++++++++-------- src/plop.erl | 28 ++++++++++++++++++++++------ 2 files changed, 37 insertions(+), 14 deletions(-) diff --git a/src/db.erl b/src/db.erl index 50117e4..08960f7 100644 --- a/src/db.erl +++ b/src/db.erl @@ -4,7 +4,7 @@ %% API. -export([start_link/0, stop/0]). -export([init_db/0, init_db/1, init_tables/0, init_tables/1]). --export([add/1, find/1, get_by_index/2]). +-export([add/1, find/1, get_by_index/2, size/0]). %% API for testing. -export([dump/1, destroy_tables/0, info_tables/0, dump_to_file/1]). %% gen_server callbacks. @@ -37,18 +37,24 @@ init_tables(Nodes) -> DiscCopies = [], DiscOnlyCopies = Nodes, mnesia:start(), - mnesia:create_table(plop, [{type, set}, - {ram_copies, RamCopies}, - {disc_copies, DiscCopies}, - {disc_only_copies, DiscOnlyCopies}, - {attributes, record_info(fields, plop)}]), - mnesia:add_table_index(plop, hash). + {atomic, ok} = + mnesia:create_table(plop, + [{type, set}, + {ram_copies, RamCopies}, + {disc_copies, DiscCopies}, + {disc_only_copies, DiscOnlyCopies}, + {attributes, record_info(fields, plop)}, + {majority, true}]), + {atomic, ok} = mnesia:add_table_index(plop, hash). + destroy_tables() -> mnesia:delete_table(plop). info_tables() -> mnesia:table_info(plop, all). dump_to_file(Filename) -> mnesia:dump_to_textfile(Filename). +size() -> + mnesia:table_info(plop, size). init(_Args) -> {mnesia:wait_for_tables([plop], 5000), []}. @@ -59,6 +65,7 @@ start_link() -> stop() -> gen_server:call(?MODULE, stop). +%% API. add(Entry) -> gen_server:call(?MODULE, {add, Entry}). @@ -119,5 +126,5 @@ handle_call({get_by_index, {Start, End}}, _From, State) -> Result = ['$2'], mnesia:select(plop, [{MatchHead, Guard, Result}]) end, - Res = mnesia:transaction(F), + {atomic, Res} = mnesia:transaction(F), {reply, Res, State}. diff --git a/src/plop.erl b/src/plop.erl index 08c74c8..a28f915 100644 --- a/src/plop.erl +++ b/src/plop.erl @@ -71,6 +71,7 @@ stop() -> %%%%%%%%%%%%%%%%%%%% init([PrivKeyfile, PubKeyfile]) -> + io:format("plop starting~n"), %% Read RSA keypair. %% {Private_key, Public_key} = read_keyfile_rsa(Keyfile, Passphrase), %% LogID = crypto:hash(sha256, @@ -80,10 +81,13 @@ init([PrivKeyfile, PubKeyfile]) -> LogID = crypto:hash(sha256, public_key:der_encode( 'ECPoint', element(2, element(1, Public_key)))), % FIXME! + %% WARNING FIXME: The building of the tree is immensely expensive + %% and slow -- don't do this with more than a couple of hundred of + %% entries! {ok, #state{pubkey = Public_key, privkey = Private_key, logid = LogID, - hashtree = ht:create()}}. + hashtree = build_tree_from_db()}}. handle_cast(_Request, State) -> {noreply, State}. @@ -142,6 +146,20 @@ handle_call({test, pubkey}, _From, {reply, PK, Plop}. %%%%%%%%%%%%%%%%%%%% +-spec build_tree_from_db() -> ht:head(). +build_tree_from_db() -> + build_tree(ht:create(), lists:seq(0, db:size() - 1)). +-spec build_tree(ht:head(), list()) -> ht:head(). +build_tree(Tree, []) -> + Tree; +build_tree(Tree, [H|T]) -> + Data = db_get_single_entry(H), + build_tree(ht:append(Tree, Data), T). + +db_get_single_entry(N) -> + [#mtl{entry = #timestamped_entry{entry = #plop_entry{data = Data}}}] = + db:get_by_index(N, N), + Data. -spec do_add(timestamped_entry(), public_key:rsa_private_key(), binary(), any()) -> {any(), binary()}. @@ -151,8 +169,7 @@ do_add(TimestampedEntry = #timestamped_entry{entry = PlopEntry}, Record = db:find(DB_hash), case Record of #plop{index = I, mtl = #mtl{entry = E}, spt = SPT} -> - io:format("Found entry: index=~p, data=~p~n", - [I, E#timestamped_entry.entry#plop_entry.data]), + io:format("Found entry: index=~p~n", [I]), %% Database consistency checking. FIXME: Remove. Record = Record#plop{ hash = DB_hash, @@ -164,13 +181,12 @@ do_add(TimestampedEntry = #timestamped_entry{entry = PlopEntry}, [] -> NewSPT = spt(LogID, Privkey, TimestampedEntry), MTL = #mtl{entry = TimestampedEntry}, - io:format("Creating new entry: index=~p,data=~p~n", - [ht:size(Tree), PlopEntry#plop_entry.data]), + io:format("Creating new entry: index=~p~n", [ht:size(Tree)]), DB_data = #plop{index = ht:size(Tree), hash = DB_hash, mtl = MTL, spt = NewSPT}, - ok = db:add(DB_data), + {atomic, ok} = db:add(DB_data), {ht:append(Tree, serialise(MTL)), % New tree. NewSPT}; % New SPT. Err -> {error, Err} -- cgit v1.1