From 66902b788bc8534e56de28ea598f05108c6e87e8 Mon Sep 17 00:00:00 2001 From: Pablo Polvorin Date: Mon, 12 Nov 2012 22:32:33 -0300 Subject: [PATCH] Do not require special api for ejabberd_set Remove the pack() function, make mod_roster return subscriptions splitted by {From, To, Both} --- src/ejabberd_c2s.erl | 60 ++++++++-------------------------- src/ejabberd_sets.erl | 19 +---------- src/mod_roster.erl | 20 ++++++------ src/mod_shared_roster.erl | 4 +-- src/mod_shared_roster_ldap.erl | 4 +-- 5 files changed, 29 insertions(+), 78 deletions(-) diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl index db9e52bee..68bb7c34c 100644 --- a/src/ejabberd_c2s.erl +++ b/src/ejabberd_c2s.erl @@ -690,16 +690,17 @@ wait_for_auth({xmlstreamelement, El}, StateData) -> Res = Res1#xmlel{children = []}, send_element(StateData, Res), change_shaper(StateData, JID), - {Fs, Ts} = + {Fs, Ts, Bs} = ejabberd_hooks:run_fold(roster_get_subscription_lists, StateData#state.server, - {[], []}, + {[], [], []}, [U, StateData#state.server]), LJID = jlib:jid_tolower(jlib:jid_remove_resource(JID)), - Fs1 = [LJID | Fs], - Ts1 = [LJID | Ts], + SharedSet = ?SETS:from_list([LJID|Bs]), + FSet = lists:foldl(fun ?SETS:add_element/2, SharedSet, Fs), + TSet = lists:foldl(fun ?SETS:add_element/2, SharedSet, Ts), PrivList = ejabberd_hooks:run_fold(privacy_get_user_list, StateData#state.server, @@ -712,10 +713,8 @@ wait_for_auth({xmlstreamelement, El}, StateData) -> conn = Conn, auth_module = AuthModule, - pres_f = - (?SETS):from_list(Fs1), - pres_t = - (?SETS):from_list(Ts1), + pres_f = FSet, + pres_t = TSet, privacy_list = PrivList}, DebugFlag = @@ -1203,13 +1202,14 @@ wait_for_session({xmlstreamelement, El}, StateData) -> Res = jlib:make_result_iq_reply(El), send_element(StateData, Res), change_shaper(StateData, JID), - {Fs, Ts} = + {Fs, Ts, Bs} = ejabberd_hooks:run_fold(roster_get_subscription_lists, StateData#state.server, {[], []}, [U, StateData#state.server]), LJID = jlib:jid_tolower(jlib:jid_remove_resource(JID)), - Fs1 = [LJID | Fs], - Ts1 = [LJID | Ts], + SharedSet = ?SETS:from_list([LJID|Bs]), + FSet = lists:foldl(fun ?SETS:add_element/2, SharedSet, Fs), + TSet = lists:foldl(fun ?SETS:add_element/2, SharedSet, Ts), PrivList = ejabberd_hooks:run_fold(privacy_get_user_list, StateData#state.server, #userlist{}, @@ -1218,8 +1218,8 @@ wait_for_session({xmlstreamelement, El}, StateData) -> Conn = (StateData#state.sockmod):get_conn_type( StateData#state.socket), NewStateData = StateData#state{sid = SID, conn = Conn, - pres_f = (?SETS):from_list(Fs1), - pres_t = (?SETS):from_list(Ts1), + pres_f = FSet, + pres_t = TSet, privacy_list = PrivList}, DebugFlag = ejabberd_hooks:run_fold(c2s_debug_start_hook, @@ -3425,39 +3425,7 @@ route_blocking(What, StateData) -> %%% JID Set memory footprint reduction code %%%---------------------------------------------------------------------- -pack(S = #state{pres_a = A, pres_f = F, - pres_t = T}) -> - {NewA, Pack2} = pack_jid_set(A, gb_trees:empty()), - {NewF, Pack3} = pack_jid_set(F, Pack2), - {NewT, _Pack4} = pack_jid_set(T, Pack3), - {SetF, SetT} = ?SETS:pack_sets(NewF, NewT), - S#state{pres_a = ?SETS:from_list(NewA), pres_f = SetF, - pres_t = SetT}. - -pack_jid_set(Set, Pack) -> - Jids = (?SETS):to_list(Set), - {PackedJids, NewPack} = pack_jids(Jids, Pack, []), - {PackedJids, NewPack}. - -pack_jids([], Pack, Acc) -> {Acc, Pack}; -pack_jids([{U, S, R} = Jid | Jids], Pack, Acc) -> - case gb_trees:lookup(Jid, Pack) of - {value, PackedJid} -> - pack_jids(Jids, Pack, [PackedJid | Acc]); - none -> - {NewU, Pack1} = pack_string(U, Pack), - {NewS, Pack2} = pack_string(S, Pack1), - {NewR, Pack3} = pack_string(R, Pack2), - NewJid = {NewU, NewS, NewR}, - NewPack = gb_trees:insert(NewJid, NewJid, Pack3), - pack_jids(Jids, NewPack, [NewJid | Acc]) - end. - -pack_string(String, Pack) -> - case gb_trees:lookup(String, Pack) of - {value, PackedString} -> {PackedString, Pack}; - none -> {String, gb_trees:insert(String, String, Pack)} - end. +pack(S) -> S. flash_policy_string() -> Listen = ejabberd_config:get_local_option(listen, fun(V) -> V end), diff --git a/src/ejabberd_sets.erl b/src/ejabberd_sets.erl index 46e919823..554be06b2 100644 --- a/src/ejabberd_sets.erl +++ b/src/ejabberd_sets.erl @@ -12,10 +12,7 @@ foldl/3, size/1]). -%% new method --export([ - pack_sets/2 - ]). + %% Asumptions: %% It is common that roster items are of type "both", present in both pres_a and pres_f sets. @@ -48,20 +45,6 @@ new() -> from_list(L) -> lists:foldl(fun add_element/2, new(), L). -%% Given two list, return the two respective sets, but with the sets sharing their underling -%% representation as much as possible ( -pack_sets(L1, L2) -> - Set2 = gb_sets:from_list(L2), - Shared = lists:filter(fun(I) -> gb_sets:is_element(I, Set2) end, L1), - SharedSet = from_list(Shared), - %% add_element already verify that the elements doesn't exists, so no need to - %% filter L1 and L2 before. - R1 = lists:foldl( fun add_element/2, SharedSet, L1), - R2 = lists:foldl( fun add_element/2, SharedSet, L2), - {R1, R2}. - - - to_list(S) -> foldl(fun(JID, Acc) -> [JID | Acc] end, [], S). diff --git a/src/mod_roster.erl b/src/mod_roster.erl index 44dbc86b6..e1d683881 100644 --- a/src/mod_roster.erl +++ b/src/mod_roster.erl @@ -590,7 +590,7 @@ get_subscription_lists(Acc, User, Server) -> DBType = gen_mod:db_type(LServer, ?MODULE), Items = get_subscription_lists(Acc, LUser, LServer, DBType), - fill_subscription_lists(LServer, Items, [], []). + fill_subscription_lists(LServer, Items, [], [], []). get_subscription_lists(_, LUser, LServer, mnesia) -> US = {LUser, LServer}, @@ -612,24 +612,24 @@ get_subscription_lists(_, LUser, LServer, odbc) -> end. fill_subscription_lists(LServer, [#roster{} = I | Is], - F, T) -> + F, T, B) -> J = element(3, I#roster.usj), case I#roster.subscription of both -> - fill_subscription_lists(LServer, Is, [J | F], [J | T]); + fill_subscription_lists(LServer, Is, F, T, [J|B]); from -> - fill_subscription_lists(LServer, Is, [J | F], T); - to -> fill_subscription_lists(LServer, Is, F, [J | T]); - _ -> fill_subscription_lists(LServer, Is, F, T) + fill_subscription_lists(LServer, Is, [J | F], T, B); + to -> fill_subscription_lists(LServer, Is, F, [J | T], B); + _ -> fill_subscription_lists(LServer, Is, F, T, B) end; -fill_subscription_lists(LServer, [RawI | Is], F, T) -> +fill_subscription_lists(LServer, [RawI | Is], F, T, B) -> I = raw_to_record(LServer, RawI), case I of %% Bad JID in database: - error -> fill_subscription_lists(LServer, Is, F, T); - _ -> fill_subscription_lists(LServer, [I | Is], F, T) + error -> fill_subscription_lists(LServer, Is, F, T, B); + _ -> fill_subscription_lists(LServer, [I | Is], F, T, B) end; -fill_subscription_lists(_LServer, [], F, T) -> {F, T}. +fill_subscription_lists(_LServer, [], F, T, B) -> {F, T, B}. ask_to_pending(subscribe) -> out; ask_to_pending(unsubscribe) -> none; diff --git a/src/mod_shared_roster.erl b/src/mod_shared_roster.erl index ca0898af7..7ae3a378c 100644 --- a/src/mod_shared_roster.erl +++ b/src/mod_shared_roster.erl @@ -302,7 +302,7 @@ set_item(User, Server, Resource, Item) -> jlib:make_jid(<<"">>, Server, <<"">>), jlib:iq_to_xml(ResIQ)). -get_subscription_lists({F, T}, User, Server) -> +get_subscription_lists({F, T, B}, User, Server) -> LUser = jlib:nodeprep(User), LServer = jlib:nameprep(Server), US = {LUser, LServer}, @@ -312,7 +312,7 @@ get_subscription_lists({F, T}, User, Server) -> end, DisplayedGroups)), SRJIDs = [{U1, S1, <<"">>} || {U1, S1} <- SRUsers], - {lists:usort(SRJIDs ++ F), lists:usort(SRJIDs ++ T)}. + {F, T, lists:usort(SRJIDs ++ B)}. get_jid_info({Subscription, Groups}, User, Server, JID) -> diff --git a/src/mod_shared_roster_ldap.erl b/src/mod_shared_roster_ldap.erl index 024612334..c00d90e6b 100644 --- a/src/mod_shared_roster_ldap.erl +++ b/src/mod_shared_roster_ldap.erl @@ -148,7 +148,7 @@ process_item(RosterItem, _Host) -> _ -> RosterItem#roster{subscription = both, ask = none} end. -get_subscription_lists({F, T}, User, Server) -> +get_subscription_lists({F, T, B}, User, Server) -> LUser = jlib:nodeprep(User), LServer = jlib:nameprep(Server), US = {LUser, LServer}, @@ -158,7 +158,7 @@ get_subscription_lists({F, T}, User, Server) -> end, DisplayedGroups)), SRJIDs = [{U1, S1, <<"">>} || {U1, S1} <- SRUsers], - {lists:usort(SRJIDs ++ F), lists:usort(SRJIDs ++ T)}. + {F, T, lists:usort(SRJIDs ++ B)}. get_jid_info({Subscription, Groups}, User, Server, JID) ->