From e8aad795d73c3e7c88792f370cac6c9a616569a9 Mon Sep 17 00:00:00 2001 From: b7ack42 Date: Wed, 5 Jun 2013 16:46:19 +0800 Subject: [PATCH] backup 6-5-2013 --- ref.erl | 44 +++++++++++ runes.app | 2 +- runes.erl | 10 ++- runes_agenda.erl | 118 ++++++++++++++++++++++++---- runes_app.erl | 51 +++++++++++++ runes_compile.erl | 103 +++++++++++++++---------- runes_engine.erl | 32 +++++--- runes_kb.erl | 191 +++++++++++++++++++++++++++++++++++++--------- runes_sup.erl | 4 +- 9 files changed, 446 insertions(+), 109 deletions(-) create mode 100644 ref.erl diff --git a/ref.erl b/ref.erl new file mode 100644 index 0000000..2f6962c --- /dev/null +++ b/ref.erl @@ -0,0 +1,44 @@ +-module(ref). + +-export([init/1, + handle_call/3, + handle_cast/2, + handle_info/2, + terminate/2, + code_change/3]). + +-export([new_ref/0 + ]). + +-compile(export_all). + +-behaviour(gen_server). + +-define(SERVER,?MODULE). + +-record(state,{ref_num}). + +start() -> + gen_server:start_link({global,?SERVER},?MODULE,[],[]). + +new_ref() -> + gen_server:call({global,?SERVER},mr). + +init([]) -> + {ok,#state{ref_num=0}}. + +handle_cast(_Msg, State) -> + {noreply,State}. + +handle_call(mr,_From,State) -> + Ref_num = State#state.ref_num, + {reply,make_ref(),State#state{ref_num = Ref_num+1}}. + +handle_info(_Msg,State) -> + {noreply,State}. + +terminate(_Reason,_State) -> + ok. + +code_change(_OldVsn,State,_Extra) -> + {ok,State}. diff --git a/runes.app b/runes.app index cc9fff1..b407556 100644 --- a/runes.app +++ b/runes.app @@ -10,6 +10,6 @@ runes ]}, {registered,[runes_sup]}, - {application,[kernel,stdlib]}, + {application,[kernel,stdlib,mnesia,resource_discovery]}, {mod, {runes_app,[]}} ]}. \ No newline at end of file diff --git a/runes.erl b/runes.erl index fd12cc1..37f2187 100644 --- a/runes.erl +++ b/runes.erl @@ -24,11 +24,17 @@ add_fact(Fact) -> info() -> runes_agenda:show_working_memory(), + io:format("All classes: ~p~n",[runes_agenda:get_class_set(node())]), runes_agenda:get_node_num(all_nodes). fire() -> - runes_agenda:get_conflict_set(). - + [_|T] = nodes(), + Nodes = [node()|T], + lists:map(fun(N) -> + {ok,CSet} = runes_agenda:get_conflict_set(N), + io:format("the length of conflict_set at ~p: ~p~n",[N,length(CSet)]), + {N,CSet} + end,Nodes). diff --git a/runes_agenda.erl b/runes_agenda.erl index e97aec8..4e8d3df 100644 --- a/runes_agenda.erl +++ b/runes_agenda.erl @@ -8,39 +8,62 @@ code_change/3]). -export([start/0, - get_conflict_set/0, + get_conflict_set/1, + get_class_set/1, + get_process_set/1, + silent/1, + create_node/3, put_pn/2, get_pn/1, delete_rn/1, - get_root/0, + get_root_and_set_class/2, get_node_num/1, inc_node_num/1, dec_node_num/1, show_working_memory/0, + get_all_processes/0, fire_able/2]). -compile(export_all). -behaviour(gen_server). +-define(SERVER,agenda). --record(agenda, {conflict_set}). + +-record(agenda, {conflict_set,class_set,process_set}). start() -> {ok,Agenda} = gen_server:start_link(?MODULE,[],[]), register(agenda,Agenda). +create_node(Where,Type,Paras) -> + gen_server:call({agenda,Where},{new,Type,Paras}). + +get_root_and_set_class(Where,Class) -> + gen_server:call({agenda,Where},{root,Class}). + +get_dummy_top_node(Where) -> + gen_server:call({agenda,Where},dtn). + fire_able(Pn,_State) -> - gen_server:cast(agenda,{fa,Pn}). + gen_server:cast({agenda,node()},{fa,Pn}). + +get_conflict_set(Where) -> + gen_server:call({agenda,Where},get_cs). + +get_class_set(Where) -> + gen_server:call({agenda,Where},get_cls). + +get_process_set(Where) -> + gen_server:call({agenda,Where},get_ps). -get_conflict_set() -> - gen_server:call(agenda,get_cs). +silent(Where) -> + gen_server:call({agenda,Where},silent). init([]) -> ets:new(agenda, [public,named_table,{read_concurrency,true}]), -% ets:new(am,[public,named_table,{read_concurrency,true}]), -% ets:new(bm,[public,named_table,{read_concurrency,true}]), Root = runes_compile:build_root_node_only_once(), Dummy_top_node = runes_compile:build_dummy_top_node_only_once(), ets:insert(agenda,{dummy_top_node,Dummy_top_node}), @@ -50,18 +73,51 @@ init([]) -> ets:insert(agenda,{ctn_num,0}), ets:insert(agenda,{pn_num,0}), ets:insert(agenda,{jn_num,0}), - {ok,#agenda{conflict_set=[]}}. + {ok,#agenda{conflict_set=[],class_set=[],process_set=[]}}. handle_cast({fa,Pn},State) -> Cset0 = State#agenda.conflict_set, Cset1 = [Pn|Cset0], - {noreply,#agenda{conflict_set=Cset1}}. + {noreply,State#agenda{conflict_set=Cset1}}. + +handle_call({new,Type,Paras},_From,State) -> + inc_node_num(Type), + {ok,Pro} = runes_engine:create(Type,Paras), + Pset0 = State#agenda.process_set, + {reply,{ok,Pro},State#agenda{process_set=[Pro|Pset0]}}; + +handle_call({root,Class},_From,State) -> + Old_Classes = State#agenda.class_set, + Where = runes_kb:find_class(Class), + if Where =:= no_class -> + runes_kb:insert(class,Class,node()), + {reply, + get_rn(), + State#agenda{class_set = [Class|Old_Classes]}}; + true -> + {reply,get_rn(),State} + end; + +handle_call(dtn,_From,State) -> + {reply,get_dtn(),State}; handle_call(get_cs,_From,State) -> Set= State#agenda.conflict_set, - io:format("the length of conflict_set: ~p~n", [length(Set)]), - {reply,{ok,Set},State}. + %io:format("the length of conflict_set: ~p~n", [length(Set)]), + {reply,{ok,Set},State}; +handle_call(get_ps,_From,State) -> + {reply,{ok,State#agenda.process_set},State}; + +handle_call(get_cls,_From,State) -> + {reply,{ok,State#agenda.class_set},State}; + +handle_call(silent,_From,State) -> + Pl = State#agenda.process_set, + % io:format("~p ps: ~p~n",[self(),Pl]), + {reply,isnull(Pl),State}. + + handle_info(_Msg,State) -> {noreply,State}. @@ -72,7 +128,7 @@ code_change(_OldVsn,State,_Extra) -> {ok,State}. -get_root() -> +get_rn() -> case ets:lookup(agenda,root_node) of [{root_node,Root}] -> {ok,Root}; @@ -80,7 +136,7 @@ get_root() -> no_root end. -get_dummy_top_node() -> +get_dtn() -> case ets:lookup(agenda,dummy_top_node) of [{dummy_top_node,Dn}] -> {ok,Dn}; @@ -103,8 +159,38 @@ delete_rn(Rn) -> show_working_memory() -> io:format("All wme_refs: ~p~n",[runes_kb:get_all_wme_refs()]), - Trs = lists:flatten(ets:match(token_store,{'$1','_'})), - io:format("All token_refs: ~p~n",[Trs]). + io:format("All token_refs: ~p~n",[runes_kb:get_all_token_refs()]). + +get_all_processes() -> + [_|T] = nodes(), + Nodes = [node()|T], + lists:flatmap(fun(N) -> + {ok,Ps} = get_process_set(N), + Ps + end,Nodes). + + +loop(Pl) -> + T2 = erlang:now(), + Null = silent(Pl), + io:format("~p",[z]), + if Null -> + T3 = erlang:now(), + {T2,T3}; + true -> + loop(Pl) + end. + +isnull([]) -> + true; +isnull([P|Pl]) -> + Len = proplists:get_value(message_queue_len,process_info(P),1), + % io:format("Len: ~p",[Len]), + if Len /= 0 -> + false; + true -> + isnull(Pl) + end. get_node_num(all_nodes) -> Ls = lists:map(fun(Class) -> diff --git a/runes_app.erl b/runes_app.erl index debb603..cb66f02 100644 --- a/runes_app.erl +++ b/runes_app.erl @@ -4,10 +4,19 @@ -export([start/2,stop/1]). +-define(WAIT_FOR_RESOURCES,2500). + start(_StartType, _StartArgs) -> + ok = ensure_contact(), + resource_discovery:add_local_resource(runes,node()), + resource_discovery:add_target_resource_type(runes), + resource_discovery:trade_resources(), + timer:sleep(?WAIT_FOR_RESOURCES), runes_kb:init(), + io:format("success"), case runes_sup:start_link() of {ok,Pid} -> + io:format("success"), runes_agenda:start(), {ok, Pid}; Other-> @@ -16,3 +25,45 @@ start(_StartType, _StartArgs) -> stop(_State) -> ok. + +ensure_contact() -> + DefaultNodes = ['contact@202.38.95.139'], + case get_env(runes, contact_nodes, DefaultNodes) of + [] -> + {error, no_contact_nodes}; + ContactNodes -> + ensure_contact(ContactNodes) + end. + +ensure_contact(ContactNodes) -> + Answering = [N || N <- ContactNodes, net_adm:ping(N) =:= pong], + case Answering of + [] -> + {error, no_contact_nodes_reachable}; + _ -> + DefaultTime = 3000, + WaitTime = get_env(runes, wait_time, DefaultTime), + wait_for_nodes(length(Answering), WaitTime) + end. + +wait_for_nodes(MinNodes, WaitTime) -> + Slices = 10, + SliceTime = round(WaitTime/Slices), + wait_for_nodes(MinNodes, SliceTime, Slices). + +wait_for_nodes(_MinNodes, _SliceTime, 0) -> + ok; +wait_for_nodes(MinNodes, SliceTime, Iterations) -> + case length(nodes()) > MinNodes of + true -> + ok; + false -> + timer:sleep(SliceTime), + wait_for_nodes(MinNodes, SliceTime, Iterations - 1) + end. + +get_env(AppName, Key, Default) -> + case application:get_env(AppName, Key) of + undefined -> Default; + {ok, Value} -> Value + end. diff --git a/runes_compile.erl b/runes_compile.erl index c4192a7..3b6452a 100644 --- a/runes_compile.erl +++ b/runes_compile.erl @@ -16,45 +16,58 @@ build_dummy_top_node_only_once() -> {ok,Dn} = runes_engine:create(dummy_top_node,Paras), Dn. -build_or_share_constant_test_node(root_node,Fi,Va) -> - {ok,Root} = runes_agenda:get_root(), - build_or_share_constant_test_node(Root,Fi,Va); -build_or_share_constant_test_node(Parent,Fi,Va) -> +build_or_share_constant_test_node(root_node,Fi,Va,_Where) -> + {_,Class} = Va, + Wh = runes_kb:find_class(Class), + if Wh /= no_class -> + Where = Wh; + true -> + [_F|T] = nodes(), + Nodes = [node()|T], + Where = lists:nth(random:uniform(length(Nodes)),Nodes) + end, + {ok,Root} = runes_agenda:get_root_and_set_class(Where,Class), + build_or_share_constant_test_node(Root,Fi,Va,Where); +build_or_share_constant_test_node(Parent,Fi,Va,Where) -> {Tag,Val} = Va, if Tag == con -> {ok,Re} = runes_engine:quarry_child_as(Parent,{c,Fi,Val}), if Re /= nil -> - Re; + {Re,Where}; true -> Paras = #constant_test_node{field = Fi, value = Val, out_put_mem = nil, parent = Parent, children = []}, - {ok,New} = runes_engine:create(constant_test_node,Paras), + %{ok,New} = runes_engine:create(constant_test_node,Paras), + {ok,New} = runes_agenda:create_node(Where, + ctn, + Paras), runes_engine:c_linkto_pc(New,Parent), - runes_agenda:inc_node_num(ctn), - New + %runes_agenda:inc_node_num(ctn), + {New,Where} end; true -> - Parent + {Parent,Where} end. -build_or_share_alpha_memory(Cond)-> +build_or_share_alpha_memory(Cond,_Where)-> %#fields{id=Id,attr=Attr,value=Val} = Cond, %Ls = [{id,Id},{attr,Attr},{value,Val}], - Cur_n = lists:foldl(fun({F,V},Cur)-> - build_or_share_constant_test_node(Cur,F,V) - end, root_node,Cond), + {Cur_n,Where} = lists:foldl(fun({F,V},{Cur,Where})-> + build_or_share_constant_test_node(Cur,F,V,Where) + end, {root_node,nil},Cond), {ok,[{o,Om}]} = runes_engine:quarry_keys(Cur_n,[o]), if Om /= nil -> - Om; + {Om,Where}; true -> Paras = #alpha_memory{succs = [], parent = Cur_n, ref_count = 0, wme_refs = []}, - {ok,Am} = runes_engine:create(alpha_memory,Paras), + %{ok,Am} = runes_engine:create(alpha_memory,Paras), + {ok,Am} = runes_agenda:create_node(Where,am,Paras), runes_engine:a_linkto_pc(Am,Cur_n), Wrs = runes_kb:get_all_wme_refs(), lists:foreach(fun(Wr) -> @@ -63,14 +76,12 @@ build_or_share_alpha_memory(Cond)-> runes_engine:alpha_memory_activation(Am,Wr) end end,Wrs), - runes_agenda:inc_node_num(am), - %ets:new(list_to_atom(pid_to_list(Am)), - % [public,named_table,{read_concurrency,true}]), - Am + %runes_agenda:inc_node_nSum(am), + {Am,Where} end. -build_or_share_beta_memory_node(dummy_top_node) -> - {ok,Dn} = runes_agenda:get_dummy_top_node(), +build_or_share_beta_memory_node(dummy_top_node,Where) -> + {ok,Dn} = runes_agenda:get_dummy_top_node(Where), {ok,Ch} = runes_engine:quarry_child_as(Dn,b), if Ch /= nil -> Ch; @@ -80,16 +91,14 @@ build_or_share_beta_memory_node(dummy_top_node) -> children=[], parent={Dn,d}, variant = Bm}, - {ok,Bnew} = runes_engine:create(beta_memory,Paras), - %Name = list_to_atom(pid_to_list(Bnew)), - %ets:new(Name,[public,named_table,{read_concurrency,true}]), +% {ok,Bnew} = runes_engine:create(beta_memory,Paras), + {ok,Bnew} = runes_agenda:create_node(Where,bm,Paras), runes_engine:set_bm(Bnew,[nil]), - %ets:insert(list_to_atom(pid_to_list(Bnew)),{bm,[nil]}), runes_engine:b_linkto_p(Bnew,Dn), - runes_agenda:inc_node_num(bm), + %runes_agenda:inc_node_num(bm), {Bnew,b} end; -build_or_share_beta_memory_node({Parent,Type}) -> +build_or_share_beta_memory_node({Parent,Type},Where) -> {ok,Ch} = runes_engine:quarry_child_as(Parent,b), if Ch /= nil -> Ch; @@ -99,16 +108,17 @@ build_or_share_beta_memory_node({Parent,Type}) -> children=[], parent={Parent,Type}, variant = Bm}, - {ok,Bnew} = runes_engine:create(beta_memory,Paras), + %{ok,Bnew} = runes_engine:create(beta_memory,Paras), + {ok,Bnew} = runes_agenda:create_node(Where,bm,Paras), %Name = list_to_atom(pid_to_list(Bnew)), %ets:new(Name,[public,named_table,{read_concurrency,true}]), runes_engine:b_linkto_p(Bnew,Parent), update_new_node_with_matches_from_above({Bnew,b}), - runes_agenda:inc_node_num(bm), + %runes_agenda:inc_node_num(bm), {Bnew,b} end. -build_or_share_p_node({Pa,Type},Rule) -> +build_or_share_p_node({Pa,Type},Rule,Where) -> #rule{name = Na,rhs= Rhs} = Rule, {ok,Ch} = runes_engine:quarry_child_as(Pa,{p,Na}), if Ch /= nil -> @@ -118,10 +128,11 @@ build_or_share_p_node({Pa,Type},Rule) -> rule_name= Na, token_refs = [], action = Rhs}, - {ok,Pn} = runes_engine:create(p_node,Paras), + % {ok,Pn} = runes_engine:create(p_node,Paras), + {ok,Pn} = runes_agenda:create_node(Where,pn,Paras), runes_engine:pn_linkto_p(Pn,Pa), runes_agenda:put_pn(Na,Pn), - runes_agenda:inc_node_num(pn), + %runes_agenda:inc_node_num(pn), {Pn,p} end. @@ -197,7 +208,7 @@ find_nearest_ancestor_with_same_amem(Nt,Am)-> end end. -build_or_share_join_node({Parent,Type},Am,Tests) -> +build_or_share_join_node({Parent,Type},Am,Tests,Where) -> {ok,Ch} = runes_engine:quarry_child_as(Parent,{j,Am,Tests}), if Ch /= nil -> Ch; @@ -211,7 +222,8 @@ build_or_share_join_node({Parent,Type},Am,Tests) -> children = [], parent = {Parent,Type}, variant = Jn}, - {ok,New} = runes_engine:create(join,Paras), + %{ok,New} = runes_engine:create(join,Paras), + {ok,New} = runes_agenda:create_node(Where,jn,Paras), %Bm_nil = runes_engine:is_bm_nil(Parent), %if Bm_nil -> % Am_nil = false; @@ -222,7 +234,7 @@ build_or_share_join_node({Parent,Type},Am,Tests) -> Am_nil = false, runes_engine:j_linkto_p(New,Parent,Am_nil), runes_engine:j_linkto_a(New,Am,Bm_nil), - runes_agenda:inc_node_num(jn), + %runes_agenda:inc_node_num(jn), {New,j} end. @@ -236,12 +248,15 @@ build_or_share_network_for_conditions(Pa,Conds,EConds) -> one_step_build(Cond,{Cur_n,Conds_h}) -> % case Cond of % positive -> - Cur_nn = build_or_share_beta_memory_node(Cur_n), - {ok,Tests} = get_join_tests_from_condition(Cond,Conds_h), - Am = build_or_share_alpha_memory(Cond), - Cur_nnn = build_or_share_join_node(Cur_nn,Am,Tests), - Conds_hh = [Cond|Conds_h], - {Cur_nnn,Conds_hh}. +% [_|T] = nodes(), +% Nodes = [node()|T], +% Node = lists:nth(random:uniform(lenght(Nodes)),Nodes), + {Am,Where} = build_or_share_alpha_memory(Cond,wherenil), + Cur_nn = build_or_share_beta_memory_node(Cur_n,Where), + {ok,Tests} = get_join_tests_from_condition(Cond,Conds_h), + Cur_nnn = build_or_share_join_node(Cur_nn,Am,Tests,Where), + Conds_hh = [Cond|Conds_h], + {Cur_nnn,Conds_hh}. % _ -> % {fail,no_such_cond} % end. @@ -250,9 +265,13 @@ one_step_build(Cond,{Cur_n,Conds_h}) -> add_production(Rule) -> + random:seed(erlang:now()), Lhs = Rule#rule.lhs, Cur_n = build_or_share_network_for_conditions(dummy_top_node,Lhs,[]), - P_node = build_or_share_p_node(Cur_n,Rule), + [_|T] = nodes(), + Nodes = [node()|T], + P_node = build_or_share_p_node(Cur_n,Rule,lists:nth(random:uniform(length(Nodes)), + Nodes)), update_new_node_with_matches_from_above(P_node). update_new_node_with_matches_from_above(New) -> diff --git a/runes_engine.erl b/runes_engine.erl index efa9e7a..f6866d0 100644 --- a/runes_engine.erl +++ b/runes_engine.erl @@ -10,7 +10,7 @@ left_activation/3, right_activation/3, fake_right_activation/2, - root_activation/1, + root_activation/2, constant_test_node_activation/2, alpha_memory_activation/2, delete/1, @@ -62,10 +62,16 @@ start_link(_Type,Paras) -> add_wme(Wme) -> Wme_ref = runes_kb:make_wm_ref(Wme), - root_activation(Wme_ref). + [{class,Class}|_] = Wme#wme.fields, + Where = runes_kb:find_class(Class), + if Where /= no_node -> + root_activation(Wme_ref,Where); + true -> + ok + end. -root_activation(Wr) -> - {ok,Root} = runes_agenda:get_root(), +root_activation(Wr,Where) -> + {ok,Root} = runes_agenda:get_root_and_set_class(Where,nil), gen_server:cast(Root,{ra,Wr}). constant_test_node_activation(CNode,Wme_ref) -> @@ -265,6 +271,8 @@ init([Paras]) -> handle_cast({ra,Wr},State) -> Chn = State#root_node.children, + %{ok,Pl} = runes_agenda:get_process_set(node()), + %runes_agenda:loop(Pl), lists:foreach(fun(Ch) -> constant_test_node_activation(Ch,Wr) end,Chn), {noreply,State}; @@ -292,15 +300,15 @@ handle_cast({ca,Wme_ref}, State) -> out_put_mem = Om, children = Chn} = State, if Fi /= no_test -> - Wme = runes_kb:get_wme(Wme_ref), - V2 = runes_kb:get_f(Wme,Fi), + Wme = runes_kb:get_wme(Wme_ref), + V2 = runes_kb:get_f(Wme,Fi), % io:format("~p v: ~p, va: ~p~n",[self(),V2, Va]), - if V2 /= Va -> - Flag = 0; - true -> - Flag = 1 - end; - true -> Flag = 1 + if V2 /= Va -> + Flag = 0; + true -> + Flag = 1 + end; + true -> Flag = 1 end, if Flag == 1 -> if Om /= nil -> diff --git a/runes_kb.erl b/runes_kb.erl index 667e073..14ea653 100644 --- a/runes_kb.erl +++ b/runes_kb.erl @@ -8,30 +8,51 @@ get_am/1, get_bm/1, get_wme/1, + find_class/1, get_f/2, get_token/1, get_nth_wr_from_token/2, - get_all_wme_refs/0 + get_all_wme_refs/0, + find_all_classes/0 ]). -compile(export_all). -include("internal.hrl"). +%5-behavior(gen_server). + +-define(WAIT_FOR_TABLES,3000). + +-record(class_store,{class,node}). +-record(wm_store,{wr,wme}). +-record(token_store,{tr,token}). +-record(bm_store,{pid,bm}). +-record(am_store,{pid,am}). + init() -> - ets:new(wm_store, [public, named_table, {read_concurrency, true}]), - ets:new(token_store, [public, named_table,{read_concurrency, true}]), - ets:new(bm,[public,named_table,{read_concurrency,true}]), - ets:new(am,[public,named_table,{read_concurrency,true}]), + mnesia:stop(), + mnesia:delete_schema([node()]), + mnesia:start(), + {ok, CacheNodes} = resource_discovery:fetch_resources(runes), + dynamic_db_init(lists:delete(node(),CacheNodes)), + % ets:new(wm_store, [public, named_table, {read_concurrency, true}]), + % ets:new(token_store, [public, named_table,{read_concurrency, true}]), + % ets:new(bm,[public,named_table,{read_concurrency,true}]), + % ets:new(am,[public,named_table,{read_concurrency,true}]), + %5{ok,Kb} = gen_server:start_link(?MODULE,[],[]), + %5register(kb,Kb), ok. make_wm_ref(Wme) -> - Ref = make_ref(), +% Ref = make_ref(), + Ref = ref:new_ref(), insert(wm,Ref,Wme), Ref. make_token_ref(Token) -> - Ref = make_ref(), + %Ref = make_ref(), + Ref = ref:new_ref(), insert(token,Ref,Token), Ref. @@ -44,7 +65,7 @@ make_token(Node,Tr,Wr) -> Wme0 = get_wme(Wr), Wme_trs0 = Wme0#wme.token_refs, Wme1 = Wme0#wme{token_refs = [Ref|Wme_trs0]}, - ets:insert(wm_store,{Wr,Wme1}), + insert(wm,Wr,Wme1), if Tr /= nil -> Parent = get_token(Tr), PChildren = Parent#token.children, @@ -54,51 +75,100 @@ make_token(Node,Tr,Wr) -> ok end, Ref. - + +insert(class,Class,Where) -> + %5 mnesia:dirty_write(#class_store{class=Class,node=Where}); + mnesia:transaction( + fun()-> + mnesia:write(#class_store{class=Class,node=Where}) + end); insert(wm, Ref, Wme) -> - ets:insert(wm_store,{Ref, Wme}); + %5 mnesia:dirty_write(#wm_store{wr=Ref,wme=Wme}); +% ets:insert(wm_store,{Ref, Wme}); + mnesia:transaction( + fun() -> + mnesia:write(#wm_store{wr=Ref,wme=Wme}) + end); insert(token, Ref, Token) -> - ets:insert(token_store, {Ref, Token}). +%5 mnesia:dirty_write(#token_store{tr=Ref,token=Token}). + % ets:insert(token_store, {Ref, Token}). + mnesia:transaction( + fun() -> + mnesia:write(#token_store{tr=Ref,token=Token}) + end). delete(am,Am) -> - ets:delete(am,Am); + mnesia:dirty_delete({am_store,Am}); + %ets:delete(am,Am); delete(bm,Bm) -> - ets:delete(bm,Bm); + mnesia:dirty_delete({bm_store,Bm}); +% ets:delete(bm,Bm); delete(wm,Wme_ref) -> - ets:delete(wm_store,Wme_ref); + mnesia:dirty_delete({wm_store,Wme_ref}); +% ets:delete(wm_store,Wme_ref); delete(token,Tr) -> - ets:delete(token_store,Tr). + mnesia:dirty_delete({token_store,Tr}). + %ets:delete(token_store,Tr). set_am(Am,Mem) -> - ets:insert(am,{Am,Mem}). + mnesia:dirty_write(#am_store{pid=Am,am=Mem}). + %ets:insert(am,{Am,Mem}). set_bm(Bm,Mem) -> - ets:insert(bm,{Bm,Mem}). + %ets:insert(bm,{Bm,Mem}). + mnesia:dirty_write(#bm_store{pid=Bm,bm=Mem}). get_am(Am) -> - case ets:lookup(am,Am) of - [{Am,Mem}] -> + %case ets:lookup(am,Am) of + case mnesia:dirty_read(am_store,Am) of + [{am_store,Am,Mem}] -> Mem; [] -> [] end. get_bm(Bm) -> - case ets:lookup(bm,Bm) of - [{Bm,Mem}] -> + %case ets:lookup(bm,Bm) of + case mnesia:dirty_read(bm_store,Bm) of + [{bm_store,Bm,Mem}] -> Mem; [] -> [] end. -get_wme(Ref) -> - case ets:lookup(wm_store,Ref) of - [{Ref,Wme}] -> - Wme; - [] -> no_wme + +find_class(Class) -> + case mnesia:dirty_read(class_store,Class) of + [{class_store,Class,Where}] -> + Where; + [] -> + no_class end. +get_wme(Ref) -> +% case ets:lookup(wm_store,Ref) of + case mnesia:dirty_read(wm_store,Ref) of + [{wm_store,Ref,Wme}] -> + Wme; + [] -> +%5 {atomic,[{wm_store,Ref,Wme}]} = +%5 mnesia:transaction( +%5 fun() -> +%5 mnesia:read(wm_store,Ref) +%5 end), +% Wrs = get_all_wme_refs(), +% Bool = lists:member(Ref,Wrs), +% io:format("NO WME FOUND: ~p Bool: ~p~n",[Ref,Bool]), + no_wme +%5 Wme. + end. + get_f(Wme, Field) -> - Fields = Wme#wme.fields, - proplists:get_value(Field,Fields). - % case Field of + try + Fields = Wme#wme.fields, + proplists:get_value(Field,Fields) + catch + error:_Error -> io:format("Wme:~p~n",[Wme]), + error + end. +% case Field of % id -> Fields#fields.id; % attr -> Fields#fields.attr; % value -> Fields#fields.value @@ -108,8 +178,9 @@ get_token(Ref) -> if Ref == nil -> []; true -> - case ets:lookup(token_store,Ref) of - [{Ref,Token}] -> + %case ets:lookup(token_store,Ref) of + case mnesia:dirty_read(token_store,Ref) of + [{token_store,Ref,Token}] -> Token; [] -> no_Token end @@ -127,11 +198,63 @@ get_nth_wr_from_token(Token_ref,Nth) -> get_nth_wr_from_token(Parent_r,Nth1). get_all_wme_refs() -> - Pairs = ets:match(wm_store,{'$1','_'}), - lists:flatten(Pairs). - + {atomic,Wrs} = + mnesia:transaction( + fun() -> + mnesia:select(wm_store,[{#wm_store{wr='$1',wme='_'},[],['$1']}]) + end), + Wrs. +get_all_token_refs() -> + {atomic,Trs} = + mnesia:transaction( + fun() -> + mnesia:select(token_store,[{#token_store{tr='$1',token='_'},[],['$1']}]) + end), + Trs. +find_all_classes() -> + {atomic,Class_Nodes} = + mnesia:transaction( + fun() -> + mnesia:select(class_store,[{#class_store{class='$1',node='$2'}, + [],['$$']}]) + end), + Class_Nodes. + +dynamic_db_init([]) -> + {atomic,ok} = + mnesia:create_table(class_store, + [{attributes,record_info(fields,class_store)}]), + {atomic,ok} = + mnesia:create_table(wm_store, + [{attributes,record_info(fields,wm_store)}]), + {atomic,ok} = + mnesia:create_table(token_store, + [{attributes,record_info(fields,token_store)}]), + {atomic,ok} = + mnesia:create_table(bm_store, + [{attributes,record_info(fields,bm_store)}]), + {atomic,ok} = + mnesia:create_table(am_store, + [{attributes,record_info(fields,am_store)}]); +dynamic_db_init(Nodes) -> + add_extra_nodes(Nodes) . + +add_extra_nodes([Node|T]) -> + case mnesia:change_config(extra_db_nodes,[Node]) of + {ok,[Node]} -> + mnesia:add_table_copy(schema,node(),ram_copies), + mnesia:add_table_copy(class_store,node(),ram_copies), + mnesia:add_table_copy(wm_store,node(),ram_copies), + mnesia:add_table_copy(token_store,node(),ram_copies), + mnesia:add_table_copy(am_store,node(),ram_copies), + mnesia:add_table_copy(bm_store,node(),ram_copies), + Tables = mnesia:system_info(tables), + mnesia:wait_for_tables(Tables,?WAIT_FOR_TABLES); + _ -> + add_extra_nodes(T) + end. diff --git a/runes_sup.erl b/runes_sup.erl index 07cbb46..2c91539 100644 --- a/runes_sup.erl +++ b/runes_sup.erl @@ -11,10 +11,10 @@ -define(SERVER, ?MODULE). start_link() -> - supervisor:start_link({global, ?SERVER}, ?MODULE, []). + supervisor:start_link({local, ?SERVER}, ?MODULE, []). start_child(Type,Paras ) -> - supervisor:start_child({global, ?SERVER},[Type, Paras]). + supervisor:start_child(?SERVER,[Type, Paras]). init([]) -> Rete_node = {runes_engine, {runes_engine, start_link, []},