File 5632-Use-ets-whereis-in-ets-fold.patch of Package erlang

From c05f35c0e25011bf1e5d4d63e921e9cde9203e72 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C5=82=20Muska=C5=82a?= <micmus@fb.com>
Date: Mon, 12 Feb 2024 11:45:32 +0000
Subject: [PATCH 2/2] Use ets:whereis in ets:fold*

Accessing the table by ref is significantly faster than by name. We know we'll
be accessing the table multiple times in a loop - it's worth it resolving the
name just once before starting the operation.
---
 lib/stdlib/src/ets.erl        | 13 +++++++++++--
 lib/stdlib/test/ets_SUITE.erl | 11 +++++++++--
 2 files changed, 20 insertions(+), 4 deletions(-)

diff --git a/lib/stdlib/src/ets.erl b/lib/stdlib/src/ets.erl
index 3716c5bfa2..54d687d21b 100644
--- a/lib/stdlib/src/ets.erl
+++ b/lib/stdlib/src/ets.erl
@@ -688,7 +688,8 @@ the traversal.
       AccIn :: term(),
       AccOut :: term().
 
-foldl(F, Accu, T) ->
+foldl(F, Accu, Tab) ->
+    T = soft_whereis(Tab),
     ets:safe_fixtable(T, true),
     First = ets:first_lookup(T),
     try
@@ -710,7 +711,8 @@ the traversal.
       AccIn :: term(),
       AccOut :: term().
 
-foldr(F, Accu, T) ->
+foldr(F, Accu, Tab) ->
+    T = soft_whereis(Tab),
     ets:safe_fixtable(T, true),
     Last = ets:last_lookup(T),
     try
@@ -724,6 +726,13 @@ do_foldr(F, Accu0, {Key, Objects}, T) ->
     Accu = lists:foldr(F, Accu0, Objects),
     do_foldr(F, Accu, ets:prev_lookup(T, Key), T).
 
+soft_whereis(Table) when is_atom(Table) ->
+    case ets:whereis(Table) of
+        undefined -> error(badarg, [Table], [{error_info, #{cause => id, module => erl_stdlib_errors}}]);
+        Ref -> Ref
+    end;
+soft_whereis(Table) -> Table.
+
 -spec from_dets(Table, DetsTab) -> 'true' when
       Table :: table(),
       DetsTab :: dets:tab_name().
diff --git a/lib/stdlib/test/ets_SUITE.erl b/lib/stdlib/test/ets_SUITE.erl
index 2aa692bea7..a9b83debe0 100644
--- a/lib/stdlib/test/ets_SUITE.erl
+++ b/lib/stdlib/test/ets_SUITE.erl
@@ -42,7 +42,8 @@
 	 tabfile_ext2/1, tabfile_ext3/1, tabfile_ext4/1, badfile/1]).
 -export([heavy_lookup/1, heavy_lookup_element/1, heavy_concurrent/1]).
 -export([lookup_element_mult/1, lookup_element_default/1]).
--export([foldl_ordered/1, foldr_ordered/1, foldl/1, foldr/1, fold_empty/1]).
+-export([foldl_ordered/1, foldr_ordered/1, foldl/1, foldr/1, fold_empty/1,
+         fold_badarg/1]).
 -export([t_delete_object/1, t_init_table/1, t_whitebox/1,
          select_bound_chunk/1, t_delete_all_objects/1, t_test_ms/1,
          t_delete_all_objects_trap/1,
@@ -118,6 +119,7 @@
 -export([t_select_reverse/1]).
 
 -include_lib("stdlib/include/ms_transform.hrl"). % ets:fun2ms
+-include_lib("stdlib/include/assert.hrl").
 -include_lib("common_test/include/ct.hrl").
 -include_lib("common_test/include/ct_event.hrl").
 
@@ -219,7 +221,7 @@ groups() ->
       [heavy_lookup, heavy_lookup_element, heavy_concurrent]},
      {fold, [],
       [foldl_ordered, foldr_ordered, foldl, foldr,
-       fold_empty]},
+       fold_empty, fold_badarg]},
      {meta_smp, [],
       [meta_lookup_unnamed_read, meta_lookup_unnamed_write,
        meta_lookup_named_read, meta_lookup_named_write,
@@ -6427,6 +6429,11 @@ fold_empty(Config) when is_list(Config) ->
       end),
     ok.
 
+fold_badarg(Config) when is_list(Config) ->
+    F = fun(_, _) -> ok end,
+    ?assertError(badarg, ets:foldl(F, [], non_existing)),
+    ?assertError(badarg, ets:foldr(F, [], non_existing)).
+
 foldl(Config) when is_list(Config) ->
     repeat_for_opts_all_table_types(
       fun(Opts) ->
-- 
2.35.3

openSUSE Build Service is sponsored by