Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Adds serialization and restoration functionality to seresye

  • Loading branch information...
commit 2d0c7a2c516b1643e213e95431a98ca6da523854 1 parent 5e1e86e
Yurii Rashkovskii authored
Showing with 69 additions and 5 deletions.
  1. +16 −4 src/seresye.erl
  2. +53 −1 src/seresye_engine.erl
View
20 src/seresye.erl
@@ -16,7 +16,8 @@
add_rules/2, add_rule/2, add_rule/3, assert/2, get_kb/1,
get_rules_fired/1, get_client_state/1,
set_hooks/2, get_fired_rule/1,
- set_client_state/2, query_kb/2, remove_rule/2, retract/2]).
+ set_client_state/2, query_kb/2, serialize/1,
+ remove_rule/2, retract/2]).
%% gen_server callbacks
-export([start_link/0, start_link/1, start_link/2, init/1, handle_call/3,
@@ -27,7 +28,7 @@
%%====================================================================
start() ->
seresye_sup:start_engine().
-
+
start(Name) ->
seresye_sup:start_engine(Name).
@@ -86,6 +87,8 @@ get_kb(Name) ->
query_kb(Name, Pattern) ->
gen_server:call(Name, {query_kb, Pattern}).
+serialize(Name) ->
+ gen_server:call(Name, serialize).
%%%===================================================================
%%% gen_server callbacks
@@ -94,7 +97,10 @@ start_link() ->
gen_server:start_link(?MODULE, [], []).
start_link(Name) when is_atom(Name) ->
- gen_server:start_link({local, Name}, ?MODULE, [], []).
+ gen_server:start_link({local, Name}, ?MODULE, [], []);
+
+start_link(ClientState) when not is_atom(ClientState) ->
+ gen_server:start_link(?MODULE, [ClientState], []).
start_link(ClientState, Name) when is_atom(Name) ->
gen_server:start_link({local, Name}, ?MODULE, [ClientState], []).
@@ -102,6 +108,8 @@ start_link(ClientState, Name) when is_atom(Name) ->
init([]) ->
{ok, seresye_engine:new()};
+init([Engine]) when element(1, Engine) == seresye ->
+ {ok, seresye_engine:restore(Engine)};
init([ClientState]) ->
{ok, seresye_engine:new(ClientState)}.
@@ -208,7 +216,11 @@ handle_call({query_kb, Pattern}, _From, State0) ->
Type:Reason ->
{error, {Type, Reason}}
end,
- {reply, Reply, State0}.
+ {reply, Reply, State0};
+
+handle_call(serialize, _From, State) ->
+ Reply = seresye_engine:serialize(State),
+ {reply, Reply, State}.
handle_cast({set_hooks, Hooks}, State) ->
{noreply, seresye_engine:set_hooks(State, Hooks)};
View
54 src/seresye_engine.erl
@@ -24,7 +24,7 @@
%% External exports
%%====================================================================
--export([new/0, new/1,
+-export([new/0, new/1, serialize/1, restore/1,
set_hooks/2, get_fired_rule/1,
add_rules/2, add_rule/2, add_rule/3, assert/2, get_kb/1,
get_rules_fired/1, get_client_state/1, set_client_state/2,
@@ -51,6 +51,58 @@ set_client_state(EngineState, NewState) ->
get_client_state(#seresye{client_state=State}) ->
State.
+restore(#seresye{ alfa = Alfa0, join = Join0 } = Engine) ->
+ TabCache = ets:new(tab_cache, []),
+ Alfa = [ {Cond, restore_tab(TabCache, Tab), Alfa_fun}
+ || {Cond, Tab, Alfa_fun} <- Alfa0 ],
+ Join = [ {case Key of
+ {Tab,V} when element(1,Tab) == ets_table ->
+ {restore_tab(TabCache, Tab), V};
+ _ ->
+ Key
+ end, Beta, Children, Parent, Pos} ||
+ {Key, Beta, Children, Parent, Pos} <- Join0 ],
+ ets:delete(TabCache),
+ Engine#seresye{ alfa = Alfa, join = Join }.
+
+serialize(#seresye{ alfa = Alfa0, join = Join0 } = Engine) ->
+ Alfa = [ {Cond, serialize_tab(Tab), Alfa_fun}
+ || {Cond, Tab, Alfa_fun} <- Alfa0 ],
+ Join = [ {case Key of
+ {Tab,V} when is_integer(Tab) ->
+ {serialize_tab(Tab), V};
+ _ ->
+ Key
+ end, Beta, Children, Parent, Pos} ||
+ {Key, Beta, Children, Parent, Pos} <- Join0 ],
+ Engine#seresye{ alfa = Alfa, join = Join }.
+
+% where
+serialize_tab(Tab) ->
+ case ets:info(Tab) of
+ undefined ->
+ Tab;
+ Info ->
+ {ets_table, Tab, Info, ets:tab2list(Tab)}
+ end.
+restore_tab(Cache, {ets_table, Tab, Info, Content}) ->
+ case ets:lookup(Cache, Tab) of
+ [{Tab, NewTab}] ->
+ NewTab;
+ [] ->
+ NewTab = ets:new(proplists:get_value(name, Info),
+ [ proplists:get_value(Opt, Info) ||
+ Opt <- [type,protection] ] ++
+ [ {Opt, proplists:get_value(Opt, Info)} ||
+ Opt <- [keypos] ]),
+ ets:insert(NewTab, Content),
+ ets:insert(Cache, {Tab, NewTab}),
+ NewTab
+ end;
+restore_tab(_Cache, Tab) ->
+ Tab.
+
+
%% @doc Insert a fact in the KB.
%% It also checks if the fact verifies any condition,
%% if this is the case the fact is also inserted in the alpha-memory
Please sign in to comment.
Something went wrong with that request. Please try again.