<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    <p>Your are right, everything is ok!</p>
    <p>A simple example of key pool without gen_servers call, thanks to
      ets:select_delete!!</p>
    <pre style="background-color:#ffffff;color:#000000;font-family:'Menlo';font-size:18,0pt;">-module(key_pool)<span style="color:#000080;font-weight:bold;">.
</span><span style="color:#000080;font-weight:bold;">
</span><span style="color:#808080;font-style:italic;">%% API
</span>-export([new/<span style="color:#0000ff;">1</span>, in/<span style="color:#0000ff;">2</span>, in_new/<span style="color:#0000ff;">2</span>, out/<span style="color:#0000ff;">1</span>, out_compare/<span style="color:#0000ff;">1</span>, clear/<span style="color:#0000ff;">1</span>])<span style="color:#000080;font-weight:bold;">.
</span><span style="color:#000080;font-weight:bold;">
</span>-spec(new(atom()) -> {ok,atom() | {already_exists,atom()}})<span style="color:#000080;font-weight:bold;">.
</span>new(<span style="color:#660e7a;">Pool</span>) <span style="color:#000080;font-weight:bold;">when </span>is_atom(<span style="color:#660e7a;">Pool</span>) ->
  <span style="color:#000080;font-weight:bold;">case </span>ets:info(<span style="color:#660e7a;">Pool</span>,name) <span style="color:#000080;font-weight:bold;">of
</span><span style="color:#000080;font-weight:bold;">    </span>undefined ->
      {ok,ets:new(<span style="color:#660e7a;">Pool</span>,
        [ordered_set,named_table,public,
          {write_concurrency,true},{read_concurrency,true}])};
    <span style="color:#660e7a;">Pool </span>-> {already_exists,<span style="color:#660e7a;">Pool</span>}
  <span style="color:#000080;font-weight:bold;">end.
</span><span style="color:#000080;font-weight:bold;">
</span>-spec(in(atom(),{any(),any()}) -> true)<span style="color:#000080;font-weight:bold;">.
</span>in(<span style="color:#660e7a;">Pool</span>,{<span style="color:#660e7a;">Key</span>,<span style="color:#660e7a;">Val</span>}) ->
  ets:insert(<span style="color:#660e7a;">Pool</span>,{<span style="color:#660e7a;">Key</span>,<span style="color:#660e7a;">Val</span>})<span style="color:#000080;font-weight:bold;">.
</span><span style="color:#000080;font-weight:bold;">
</span>-spec(in_new(atom(),{any(),any()}) -> boolean())<span style="color:#000080;font-weight:bold;">.
</span>in_new(<span style="color:#660e7a;">Pool</span>,{<span style="color:#660e7a;">Key</span>,<span style="color:#660e7a;">Val</span>}) ->
  ets:insert_new(<span style="color:#660e7a;">Pool</span>,{<span style="color:#660e7a;">Key</span>,<span style="color:#660e7a;">Val</span>})<span style="color:#000080;font-weight:bold;">.
</span><span style="color:#000080;font-weight:bold;">
</span>-spec(out(atom()) -> {ok,{any(),any()} | empty})<span style="color:#000080;font-weight:bold;">.
</span>out(<span style="color:#660e7a;">Pool</span>) ->
  <span style="color:#000080;font-weight:bold;">case </span>ets:select(<span style="color:#660e7a;">Pool</span>,[{'_',[],['$_']}],<span style="color:#0000ff;">1</span>) <span style="color:#000080;font-weight:bold;">of
</span><span style="color:#000080;font-weight:bold;">    </span>{[{<span style="color:#660e7a;">Key</span>,<span style="color:#660e7a;">_</span>} = <span style="color:#660e7a;">Item</span>],<span style="color:#660e7a;">_</span>} ->
      <span style="color:#000080;font-weight:bold;">case </span>ets:select_delete(<span style="color:#660e7a;">Pool</span>,[{{<span style="color:#660e7a;">Key</span>,'_'},[],[true]}]) <span style="color:#000080;font-weight:bold;">of
</span><span style="color:#000080;font-weight:bold;">        </span><span style="color:#0000ff;">1 </span>->
          {ok,<span style="color:#660e7a;">Item</span>};
        <span style="color:#0000ff;">0 </span>->
          <span style="color:#808080;font-style:italic;">% context switch
</span><span style="color:#808080;font-style:italic;">          </span><span style="color:#000080;font-weight:bold;">receive
</span><span style="color:#000080;font-weight:bold;">          after </span><span style="color:#0000ff;">0 </span>-> out(<span style="color:#660e7a;">Pool</span>)
          <span style="color:#000080;font-weight:bold;">end
</span><span style="color:#000080;font-weight:bold;">      end</span>;
    '$end_of_table' ->
      empty
  <span style="color:#000080;font-weight:bold;">end.
</span><span style="color:#000080;font-weight:bold;">
</span>-spec(out_compare(atom()) -> {ok,{any(),any()} | empty})<span style="color:#000080;font-weight:bold;">.
</span>out_compare(<span style="color:#660e7a;">Pool</span>) ->
  <span style="color:#000080;font-weight:bold;">case </span>ets:select(<span style="color:#660e7a;">Pool</span>,[{'_',[],['$_']}],<span style="color:#0000ff;">1</span>) <span style="color:#000080;font-weight:bold;">of
</span><span style="color:#000080;font-weight:bold;">    </span>{[{<span style="color:#660e7a;">Key</span>,<span style="color:#660e7a;">Val</span>} = <span style="color:#660e7a;">Item</span>],<span style="color:#660e7a;">_</span>} ->
      <span style="color:#000080;font-weight:bold;">case </span>ets:select_delete(<span style="color:#660e7a;">Pool</span>,[{{<span style="color:#660e7a;">Key</span>,<span style="color:#660e7a;">Val</span>},[],[true]}]) <span style="color:#000080;font-weight:bold;">of
</span><span style="color:#000080;font-weight:bold;">        </span><span style="color:#0000ff;">1 </span>->
          {ok,<span style="color:#660e7a;">Item</span>};
        <span style="color:#0000ff;">0 </span>->
          <span style="color:#808080;font-style:italic;">% context switch
</span><span style="color:#808080;font-style:italic;">          </span><span style="color:#000080;font-weight:bold;">receive
</span><span style="color:#000080;font-weight:bold;">          after </span><span style="color:#0000ff;">0 </span>-> out(<span style="color:#660e7a;">Pool</span>)
          <span style="color:#000080;font-weight:bold;">end
</span><span style="color:#000080;font-weight:bold;">      end</span>;
    '$end_of_table' ->
      empty
  <span style="color:#000080;font-weight:bold;">end.
</span><span style="color:#000080;font-weight:bold;">
</span>-spec(clear(atom()) -> true)<span style="color:#000080;font-weight:bold;">.
</span>clear(<span style="color:#660e7a;">Pool</span>) -> ets:delete_all_objects(<span style="color:#660e7a;">Pool</span>)<span style="color:#000080;font-weight:bold;">.

Oliver
</span></pre>
    <div class="moz-cite-prefix">On 12.08.19 16:33, Sverker Eriksson
      wrote:<br>
    </div>
    <blockquote type="cite"
      cite="mid:1565620424.11130.11.camel@erlang.org">
      <pre class="moz-quote-pre" wrap="">On mån, 2019-08-12 at 14:16 +0200, Oliver Bollmann wrote:
</pre>
      <blockquote type="cite">
        <pre class="moz-quote-pre" wrap="">Hi,

EtsName = ets:new(test,[named_table,ordered_set]),
Res = ets:select_delete(EtsName,[{{Key},[],[true]}]).

Res should be 1 or 0!

But if i do this with a lot of process, at the same time,
it happend that two process get 1!

Start with: ets:insert(EtsName,{Key}).

Process One: ets:select_delete(EtsName,[{{Key},[],[true]}]).
Process Two: ets:select_delete(EtsName,[{{Key},[],[true]}]).

Process One get 1 AND Process Two get 1, with the same key, of course! 


Is this correct?

</pre>
      </blockquote>
      <pre class="moz-quote-pre" wrap="">
No, that does not seem right.

The table traversals done by ets:select* and ets:match* functions are not
atomic, but the operation done on each found object should be atomic.

That is, if you do ets:insert(T,{Key}) once and then several
ets:select_delete(T, [{{Key},[],[true]}]) in parallel, only of of them should
find {Key} and delete it.

What OTP version is this?

/Sverker

_______________________________________________
erlang-questions mailing list
<a class="moz-txt-link-abbreviated" href="mailto:erlang-questions@erlang.org">erlang-questions@erlang.org</a>
<a class="moz-txt-link-freetext" href="http://erlang.org/mailman/listinfo/erlang-questions">http://erlang.org/mailman/listinfo/erlang-questions</a>
</pre>
    </blockquote>
    <pre class="moz-signature" cols="72">-- 
Grüße
Oliver Bollmann</pre>
  </body>
</html>