File 2619-speed-up-pg-all_local_pids-by-using-gen_server-state.patch of Package erlang
From 51eb34da60f0018f05b74beadbdbdaa793cfd02c Mon Sep 17 00:00:00 2001
From: Zeyu Zhang <zeyu@fb.com>
Date: Wed, 10 Mar 2021 14:05:18 -0800
Subject: [PATCH] speed up pg:all_local_pids by using gen_server state
pg:all_local_pids used to use ets:select to scan the entire ets table.
It will be very slow when there is a lot of remote groups.
Changed it to use gen_server state to only scan local groups.
---
lib/kernel/src/pg.erl | 21 ++++++++++++++++-----
1 file changed, 16 insertions(+), 5 deletions(-)
diff --git a/lib/kernel/src/pg.erl b/lib/kernel/src/pg.erl
index 37265a5db0..a83270fdfa 100644
--- a/lib/kernel/src/pg.erl
+++ b/lib/kernel/src/pg.erl
@@ -306,8 +306,8 @@ handle_info({leave, Peer, PidOrPids, Groups}, #state{scope = Scope, nodes = Node
end;
%% we're being discovered, let's exchange!
-handle_info({discover, Peer}, #state{scope = Scope, nodes = Nodes} = State) ->
- gen_server:cast(Peer, {sync, self(), all_local_pids(Scope)}),
+handle_info({discover, Peer}, #state{nodes = Nodes, monitors = Monitors} = State) ->
+ gen_server:cast(Peer, {sync, self(), all_local_pids(Monitors)}),
%% do we know who is looking for us?
case maps:is_key(Peer, Nodes) of
true ->
@@ -524,9 +524,20 @@ leave_remote(Scope, Pids, Groups) ->
end ||
Group <- Groups].
-all_local_pids(Scope) ->
- %% selector: ets:fun2ms(fun({N,_,L}) when L =/=[] -> {N,L}end).
- ets:select(Scope, [{{'$1','_','$2'},[{'=/=','$2',[]}],[{{'$1','$2'}}]}]).
+all_local_pids(Monitors) ->
+ maps:to_list(maps:fold(
+ fun(Pid, {_Ref, Groups}, Acc) ->
+ lists:foldl(
+ fun(Group, Acc1) ->
+ Acc1#{Group => [Pid | maps:get(Group, Acc1, [])]}
+ end,
+ Acc,
+ Groups
+ )
+ end,
+ #{},
+ Monitors
+ )).
%% Works as gen_server:abcast(), but accepts a list of processes
%% instead of nodes list.
--
2.26.2