Parcourir la source

rebar_compiler_dag: store/load dag using internal knowledge

Saves a few seconds when loading DAG with thousands of files.
Unfortunately, uses internal knowledge about digraph implementation.
pull/2322/head
Maxim Fedorov il y a 4 ans
committed by Maxim Fedorov
Parent
révision
8fca72006a
1 fichiers modifiés avec 19 ajouts et 13 suppressions
  1. +19
    -13
      src/rebar_compiler_dag.erl

+ 19
- 13
src/rebar_compiler_dag.erl Voir le fichier

@ -7,17 +7,19 @@
-include("rebar.hrl").
-define(DAG_VSN, 3).
-define(DAG_VSN, 4).
-define(DAG_ROOT, "source").
-define(DAG_EXT, ".dag").
-type dag_v() :: {digraph:vertex(), term()} | 'false'.
-type dag_e() :: {digraph:vertex(), digraph:vertex()}.
-type critical_meta() :: term(). % if this changes, the DAG is invalid
-type dag_rec() :: {list(dag_v()), list(dag_e()), critical_meta()}.
-type dag() :: digraph:graph().
-type critical_meta() :: term().
-record(dag, {vsn = ?DAG_VSN :: pos_integer(),
info = {[], [], []} :: dag_rec()}).
meta :: critical_meta(),
vtab :: notable | [tuple()],
etab :: notable | [tuple()],
ntab :: notable | [tuple()]}).
-type dag() :: digraph:graph().
%% @doc You should initialize one DAG per compiler module.
%% `CritMeta' is any contextual information that, if it is found to change,
@ -260,9 +262,13 @@ restore_dag(G, File, CritMeta) ->
{ok, Data} ->
%% The CritMeta value is checked and if it doesn't match, we fail
%% the whole restore operation.
#dag{vsn=?DAG_VSN, info={Vs, Es, CritMeta}} = binary_to_term(Data),
[digraph:add_vertex(G, V, LastUpdated) || {V, LastUpdated} <- Vs],
[digraph:add_edge(G, V1, V2, Label) || {_, V1, V2, Label} <- Es],
#dag{vsn=?DAG_VSN, meta = CritMeta, vtab = VTab,
etab = ETab, ntab = NTab} = binary_to_term(Data),
{digraph, VT, ET, NT, false} = G,
true = ets:insert_new(VT, VTab),
true = ets:insert_new(ET, ETab),
true = ets:delete_all_objects(NT),
true = ets:insert(NT, NTab),
ok;
{error, _Err} ->
ok
@ -270,9 +276,9 @@ restore_dag(G, File, CritMeta) ->
store_dag(G, File, CritMeta) ->
ok = filelib:ensure_dir(File),
Vs = lists:map(fun(V) -> digraph:vertex(G, V) end, digraph:vertices(G)),
Es = lists:map(fun(E) -> digraph:edge(G, E) end, digraph:edges(G)),
Data = term_to_binary(#dag{info={Vs, Es, CritMeta}}, [{compressed, 2}]),
{digraph, VT, ET, NT, false} = G,
Data = term_to_binary(#dag{meta = CritMeta, vtab = ets:tab2list(VT),
etab = ets:tab2list(ET), ntab = ets:select(NT, [{'_',[],['$_']}])}, [{compressed, 2}]),
file:write_file(File, Data).
%% Drop a file from the digraph if it doesn't exist, and if so,

Chargement…
Annuler
Enregistrer