|
|
@ -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, |
|
|
|