Skip to content

Commit

Permalink
Merge pull request #72 from helium/adt/acs-serialization
Browse files Browse the repository at this point in the history
Attempt to use a keytree serialization for rbc to help performance
  • Loading branch information
evanmcc committed Nov 16, 2021
2 parents 3a7f806 + c51f9dd commit c8d9af0
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 6 deletions.
12 changes: 8 additions & 4 deletions src/hbbft_acs.erl
Expand Up @@ -308,15 +308,19 @@ deser_bba_key(AK) ->
"bba_" ++ Int = atom_to_list(AK),
list_to_integer(Int).

-spec serialize_rbc_state(rbc_state()) -> binary().
-spec serialize_rbc_state(rbc_state()) -> map().
serialize_rbc_state(#rbc_state{rbc_data=RBCData, result=undefined}) ->
#{data => hbbft_rbc:serialize(RBCData)};
serialize_rbc_state(#rbc_state{rbc_data=RBCData, result=Result}) ->
term_to_binary(#rbc_serialized_state{rbc_data=RBCData, result=Result},
[compressed]).
#{result => Result, data => hbbft_rbc:serialize(RBCData)}.

-spec deserialize_rbc_state(rbc_serialized_state() | #{}) -> rbc_state().
deserialize_rbc_state(#{ data := RBCData}=Data) ->
%% new RBC sub serialization
#rbc_state{rbc_data=hbbft_rbc:deserialize(RBCData), result=maps:get(result, Data, undefined)};
deserialize_rbc_state(#rbc_serialized_state{rbc_data=RBCData, result=Result}) ->
#rbc_state{rbc_data=RBCData, result=Result};
deserialize_rbc_state(BinRec) ->
deserialize_rbc_state(BinRec) when is_binary(BinRec) ->
#rbc_serialized_state{rbc_data=RBCData, result=Result} =
binary_to_term(BinRec),
#rbc_state{rbc_data=RBCData, result=Result}.
Expand Down
22 changes: 20 additions & 2 deletions src/hbbft_rbc.erl
@@ -1,6 +1,6 @@
-module(hbbft_rbc).

-export([init/4, input/2, handle_msg/3, status/1]).
-export([init/4, input/2, handle_msg/3, status/1, serialize/1, deserialize/1]).

-record(rbc_data, {
state = init :: init | waiting | done,
Expand All @@ -17,7 +17,7 @@
seen_val = false :: boolean(),
ready_sent = false :: boolean(),
%% roothash: #{sender: {size, shard}}
stripes = #{} :: #{merkerl:hash() => #{non_neg_integer() => {pos_integer(), binary()}}}
stripes = #{} :: #{merkerl:hash() => #{non_neg_integer() => {pos_integer(), pos_integer(), binary()}}}
}).

%% rbc protocol requires three message types: ECHO(h, bj, sj), VAL(h, bj, sj) and READY(h)
Expand Down Expand Up @@ -278,3 +278,21 @@ hash_key(Map) ->
maps:fold(fun(Key, Value, Acc) ->
maps:put(binary:part(Key, 0, Len), Value, Acc)
end, #{}, Map).

serialize(#rbc_data{stripes=Stripes}=Data) when Stripes /= #{} ->
#{rbc_data => term_to_binary(Data#rbc_data{stripes=#{}}), stripes =>
maps:map(fun(_K, V) ->
maps:map(fun(_K2, {Index, Size, Shard}) ->
#{index => <<Index:8/integer>>, size => <<Size:32/integer>>, shard => Shard}
end, V)
end, Stripes)};
serialize(#rbc_data{}=Data) ->
#{rbc_data => term_to_binary(Data)}.

deserialize(#{rbc_data := BinData}=Map) ->
Data = binary_to_term(BinData),
Data#rbc_data{stripes=maps:map(fun(_K, V) ->
maps:map(fun(_K2, #{index := <<Index:8/integer>>, size := <<Size:32/integer>>, shard := Shard}) ->
{Index, Size, Shard}
end, V)
end, maps:get(stripes, Map, #{}))}.

0 comments on commit c8d9af0

Please sign in to comment.