<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>