Langs = ets:new(couch_query_server_langs, [set, private]),
PidProcs = ets:new(couch_query_server_pid_langs, [set, private]),
LangProcs = ets:new(couch_query_server_procs, [set, private]),
% 'query_servers' specifies an OS command-line to execute.
lists:foreach(fun({Lang, Command}) ->
true = ets:insert(Langs, {?l2b(Lang),
couch_os_process, start_link, [Command]})
end, couch_config:get("query_servers")),
% 'native_query_servers' specifies a {Module, Func, Arg} tuple.
lists:foreach(fun({Lang, SpecStr}) ->
{ok, {Mod, Fun, SpecArg}} = couch_util:parse_term(SpecStr),
true = ets:insert(Langs, {?l2b(Lang),
Mod, Fun, SpecArg})
end, couch_config:get("native_query_servers")),
process_flag(trap_exit, true),
{ok, {Langs, % Keyed by language name, value is {Mod,Func,Arg}
PidProcs, % Keyed by PID, valus is a #proc record.
LangProcs % Keyed by language name, value is a #proc record
}}.
add_value(Tid, Key, Value) ->
true = ets:insert(Tid, {Key, Value}).
rem_value(Tid, Key) ->
true = ets:delete(Tid, Key).
add_to_list(Tid, Key, Value) ->
case ets:lookup(Tid, Key) of
[{Key, Vals}] ->
true = ets:insert(Tid, {Key, [Value|Vals]});
[] ->
true = ets:insert(Tid, {Key, [Value]})
end.
rem_from_list(Tid, Key, Value) when is_record(Value, proc)->
Pid = Value#proc.pid,
case ets:lookup(Tid, Key) of
[{Key, Vals}] ->
% make a new values list that doesn't include the Value arg
NewValues = [Val || #proc{pid=P}=Val <- Vals, P /= Pid],
ets:insert(Tid, {Key, NewValues});
[] -> ok
end;
rem_from_list(Tid, Key, Value) ->
case ets:lookup(Tid, Key) of
[{Key, Vals}] ->
% make a new values list that doesn't include the Value arg
NewValues = [Val || Val <- Vals, Val /= Value],
ets:insert(Tid, {Key, NewValues});
[] -> ok
end.