25
1
mirror of https://github.com/processone/ejabberd.git synced 2024-11-20 16:15:59 +01:00

Replace dict with maps

This will improve performance and memory consumptions of large MUCs
This commit is contained in:
Evgeny Khramtsov 2018-11-15 14:13:45 +03:00
parent 2b09d6a761
commit 43498b39c1
6 changed files with 370 additions and 441 deletions

View File

@ -1,9 +1,9 @@
language: erlang language: erlang
otp_release: otp_release:
- 17.5 - 19.0
- 18.3 - 20.3
- 19.2 - 21.1
services: services:
- redis-server - redis-server

10
README
View File

@ -105,11 +105,11 @@ To compile ejabberd you need:
- GNU Make. - GNU Make.
- GCC. - GCC.
- Libexpat 1.95 or higher. - Libexpat 1.95.
- Libyaml 0.1.4 or higher. - Libyaml 0.1.4.
- Erlang/OTP 17.5 or higher. - Erlang/OTP ≥ 19.0.
- OpenSSL 1.0.0 or higher, for STARTTLS, SASL and SSL encryption. - OpenSSL 1.0.0.
- Zlib 1.2.3 or higher, for Stream Compression support (XEP-0138). Optional. - Zlib 1.2.3, for Stream Compression support (XEP-0138). Optional.
- PAM library. Optional. For Pluggable Authentication Modules (PAM). - PAM library. Optional. For Pluggable Authentication Modules (PAM).
- ImageMagick's Convert program. Optional. For CAPTCHA challenges. - ImageMagick's Convert program. Optional. For CAPTCHA challenges.

View File

@ -22,8 +22,6 @@
-define(SETS, gb_sets). -define(SETS, gb_sets).
-define(DICT, dict).
-record(lqueue, -record(lqueue,
{ {
queue :: p1_queue:queue(), queue :: p1_queue:queue(),
@ -105,13 +103,13 @@
access = {none,none,none,none} :: {atom(), atom(), atom(), atom()}, access = {none,none,none,none} :: {atom(), atom(), atom(), atom()},
jid = #jid{} :: jid(), jid = #jid{} :: jid(),
config = #config{} :: config(), config = #config{} :: config(),
users = (?DICT):new() :: dict:dict(), users = #{} :: map(),
subscribers = (?DICT):new() :: dict:dict(), subscribers = #{} :: map(),
subscriber_nicks = (?DICT):new() :: dict:dict(), subscriber_nicks = #{} :: map(),
last_voice_request_time = treap:empty() :: treap:treap(), last_voice_request_time = treap:empty() :: treap:treap(),
robots = (?DICT):new() :: dict:dict(), robots = #{} :: map(),
nicks = (?DICT):new() :: dict:dict(), nicks = #{} :: map(),
affiliations = (?DICT):new() :: dict:dict(), affiliations = #{} :: map(),
history :: lqueue(), history :: lqueue(),
subject = [] :: [text()], subject = [] :: [text()],
subject_author = <<"">> :: binary(), subject_author = <<"">> :: binary(),

View File

@ -357,7 +357,7 @@ build_summary_room(Name, Host, Pid) ->
C = get_room_config(Pid), C = get_room_config(Pid),
Public = C#config.public, Public = C#config.public,
S = get_room_state(Pid), S = get_room_state(Pid),
Participants = dict:size(S#state.users), Participants = maps:size(S#state.users),
{<<Name/binary, "@", Host/binary>>, {<<Name/binary, "@", Host/binary>>,
misc:atom_to_binary(Public), misc:atom_to_binary(Public),
Participants Participants
@ -523,7 +523,7 @@ build_info_room({Name, Host, Pid}) ->
S = get_room_state(Pid), S = get_room_state(Pid),
Just_created = S#state.just_created, Just_created = S#state.just_created,
Num_participants = length(dict:fetch_keys(S#state.users)), Num_participants = maps:size(S#state.users),
History = (S#state.history)#lqueue.queue, History = (S#state.history)#lqueue.queue,
Ts_last_message = Ts_last_message =
@ -778,7 +778,7 @@ decide_room({_Room_name, _Host, Room_pid}, Last_allowed) ->
Just_created = S#state.just_created, Just_created = S#state.just_created,
Room_users = S#state.users, Room_users = S#state.users,
Num_users = length(?DICT:to_list(Room_users)), Num_users = maps:size(Room_users),
History = (S#state.history)#lqueue.queue, History = (S#state.history)#lqueue.queue,
Ts_now = calendar:universal_time(), Ts_now = calendar:universal_time(),
@ -854,7 +854,7 @@ get_room_occupants(Pid) ->
Info#user.nick, Info#user.nick,
atom_to_list(Info#user.role)} atom_to_list(Info#user.role)}
end, end,
dict:to_list(S#state.users)). maps:to_list(S#state.users)).
get_room_occupants_number(Room, Host) -> get_room_occupants_number(Room, Host) ->
case get_room_pid(Room, Host) of case get_room_pid(Room, Host) of
@ -862,7 +862,7 @@ get_room_occupants_number(Room, Host) ->
throw({error, room_not_found}); throw({error, room_not_found});
Pid -> Pid ->
S = get_room_state(Pid), S = get_room_state(Pid),
dict:size(S#state.users) maps:size(S#state.users)
end. end.
%%---------------------------- %%----------------------------
@ -1039,7 +1039,7 @@ get_room_affiliations(Name, Service) ->
{ok, Pid} -> {ok, Pid} ->
%% Get the PID of the online room, then request its state %% Get the PID of the online room, then request its state
{ok, StateData} = p1_fsm:sync_send_all_state_event(Pid, get_state), {ok, StateData} = p1_fsm:sync_send_all_state_event(Pid, get_state),
Affiliations = ?DICT:to_list(StateData#state.affiliations), Affiliations = maps:to_list(StateData#state.affiliations),
lists:map( lists:map(
fun({{Uname, Domain, _Res}, {Aff, Reason}}) when is_atom(Aff)-> fun({{Uname, Domain, _Res}, {Aff, Reason}}) when is_atom(Aff)->
{Uname, Domain, Aff, Reason}; {Uname, Domain, Aff, Reason};
@ -1173,7 +1173,7 @@ get_config_opt_name(Pos) ->
{get_config_opt_name(Opt), element(Opt, Config)}). {get_config_opt_name(Opt), element(Opt, Config)}).
make_opts(StateData) -> make_opts(StateData) ->
Config = StateData#state.config, Config = StateData#state.config,
Subscribers = (?DICT):fold( Subscribers = maps:fold(
fun(_LJID, Sub, Acc) -> fun(_LJID, Sub, Acc) ->
[{Sub#subscriber.jid, [{Sub#subscriber.jid,
Sub#subscriber.nick, Sub#subscriber.nick,
@ -1205,7 +1205,7 @@ make_opts(StateData) ->
{captcha_whitelist, {captcha_whitelist,
(?SETS):to_list((StateData#state.config)#config.captcha_whitelist)}, (?SETS):to_list((StateData#state.config)#config.captcha_whitelist)},
{affiliations, {affiliations,
(?DICT):to_list(StateData#state.affiliations)}, maps:to_list(StateData#state.affiliations)},
{subject, StateData#state.subject}, {subject, StateData#state.subject},
{subject_author, StateData#state.subject_author}, {subject_author, StateData#state.subject_author},
{subscribers, Subscribers}]. {subscribers, Subscribers}].

View File

@ -887,7 +887,7 @@ get_room_occupants(RoomJIDString) ->
MucService = RoomJID#jid.lserver, MucService = RoomJID#jid.lserver,
StateData = get_room_state(RoomName, MucService), StateData = get_room_state(RoomName, MucService),
[{U#user.jid, U#user.nick, U#user.role} [{U#user.jid, U#user.nick, U#user.role}
|| {_, U} <- (?DICT):to_list(StateData#state.users)]. || U <- maps:values(StateData#state.users)].
-spec get_room_state(binary(), binary()) -> mod_muc_room:state(). -spec get_room_state(binary(), binary()) -> mod_muc_room:state().

File diff suppressed because it is too large Load Diff