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
otp_release:
- 17.5
- 18.3
- 19.2
- 19.0
- 20.3
- 21.1
services:
- redis-server

10
README
View File

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

View File

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

View File

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

View File

@ -887,7 +887,7 @@ get_room_occupants(RoomJIDString) ->
MucService = RoomJID#jid.lserver,
StateData = get_room_state(RoomName, MucService),
[{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().

File diff suppressed because it is too large Load Diff