<!DOCTYPE html><html><head><title></title><style type="text/css">p.MsoNormal,p.MsoNoSpacing{margin:0}</style></head><body><div>If you just want to add a single element you can use `select_replace` like in the example in the docs <a href="https://erlang.org/doc/man/ets.html#select_replace-2">https://erlang.org/doc/man/ets.html#select_replace-2</a> since a matchspec can include a cons:<br></div><div><br></div><div><span class="bold_code bc-12">MS = ets:fun2ms(fun({K, L}) when is_list(L) -> {K, [marker | L]} end).</span><br></div><div><br></div><div>A bag might still be more appropriate, but if the goal is to just have a single call that handles this for you then `select_replace` can work. The third option would be a compare and swap with `select_replace`, which is the second example in the docs.<br></div><div><br></div><div>On Thu, Apr 22, 2021, at 05:32, Frank Muller wrote:<br></div><blockquote type="cite" id="qt" style=""><div><div><span style="word-spacing:1px;border-top-color:rgb(49, 49, 49);border-right-color:rgb(49, 49, 49);border-bottom-color:rgb(49, 49, 49);border-left-color:rgb(49, 49, 49);color:rgb(49, 49, 49);">Hi guys</span><br></div><div style="word-spacing:1px;border-top-color:rgb(49, 49, 49);border-right-color:rgb(49, 49, 49);border-bottom-color:rgb(49, 49, 49);border-left-color:rgb(49, 49, 49);color:rgb(49, 49, 49);" dir="auto"><br></div><div style="font-size:1rem;word-spacing:1px;border-top-color:rgb(49, 49, 49);border-right-color:rgb(49, 49, 49);border-bottom-color:rgb(49, 49, 49);border-left-color:rgb(49, 49, 49);color:rgb(49, 49, 49);" dir="auto">I’ve a little issue I’m unable to solve with the current ETS API.<br></div><div style="font-size:1rem;word-spacing:1px;border-top-color:rgb(49, 49, 49);border-right-color:rgb(49, 49, 49);border-bottom-color:rgb(49, 49, 49);border-left-color:rgb(49, 49, 49);color:rgb(49, 49, 49);" dir="auto"><br></div><div style="font-size:1rem;word-spacing:1px;border-top-color:rgb(49, 49, 49);border-right-color:rgb(49, 49, 49);border-bottom-color:rgb(49, 49, 49);border-left-color:rgb(49, 49, 49);color:rgb(49, 49, 49);" dir="auto">My table is of type set. Keys are integers and values are list of names:<br></div><div style="font-size:1rem;word-spacing:1px;border-top-color:rgb(49, 49, 49);border-right-color:rgb(49, 49, 49);border-bottom-color:rgb(49, 49, 49);border-left-color:rgb(49, 49, 49);color:rgb(49, 49, 49);" dir="auto">123 -> [ jane, john, bob ]<br></div><div style="word-spacing:1px;border-top-color:rgb(49, 49, 49);border-right-color:rgb(49, 49, 49);border-bottom-color:rgb(49, 49, 49);border-left-color:rgb(49, 49, 49);color:rgb(49, 49, 49);" dir="auto"><span style="border-top-color:rgb(0, 0, 0);border-right-color:rgb(0, 0, 0);border-bottom-color:rgb(0, 0, 0);border-left-color:rgb(0, 0, 0);color:rgb(0, 0, 0);"><span class="size" style="font-size:1rem;">456 -> [ joe, alice ]</span></span><br></div><div style="word-spacing:1px;border-top-color:rgb(49, 49, 49);border-right-color:rgb(49, 49, 49);border-bottom-color:rgb(49, 49, 49);border-left-color:rgb(49, 49, 49);color:rgb(49, 49, 49);" dir="auto"><span>…</span><br></div><div style="word-spacing:1px;border-top-color:rgb(49, 49, 49);border-right-color:rgb(49, 49, 49);border-bottom-color:rgb(49, 49, 49);border-left-color:rgb(49, 49, 49);color:rgb(49, 49, 49);" dir="auto"><span style="border-top-color:rgb(0, 0, 0);border-right-color:rgb(0, 0, 0);border-bottom-color:rgb(0, 0, 0);border-left-color:rgb(0, 0, 0);color:rgb(0, 0, 0);"></span><br></div><div style="word-spacing:1px;border-top-color:rgb(49, 49, 49);border-right-color:rgb(49, 49, 49);border-bottom-color:rgb(49, 49, 49);border-left-color:rgb(49, 49, 49);color:rgb(49, 49, 49);" dir="auto"><span style="border-top-color:rgb(0, 0, 0);border-right-color:rgb(0, 0, 0);border-bottom-color:rgb(0, 0, 0);border-left-color:rgb(0, 0, 0);color:rgb(0, 0, 0);"><span class="size" style="font-size:1rem;">Process A with Key=123 wants to delete ‘Jane’ while process B with Key=123 wants to add ‘Adam’</span></span><span>.</span><br></div><div style="word-spacing:1px;border-top-color:rgb(49, 49, 49);border-right-color:rgb(49, 49, 49);border-bottom-color:rgb(49, 49, 49);border-left-color:rgb(49, 49, 49);color:rgb(49, 49, 49);" dir="auto"><span></span><br></div><div style="word-spacing:1px;border-top-color:rgb(49, 49, 49);border-right-color:rgb(49, 49, 49);border-bottom-color:rgb(49, 49, 49);border-left-color:rgb(49, 49, 49);color:rgb(49, 49, 49);" dir="auto"><span>First, they both needs to read the value associated with Key=123, update that list accordingly and set back the new value.</span><br></div><div style="word-spacing:1px;border-top-color:rgb(49, 49, 49);border-right-color:rgb(49, 49, 49);border-bottom-color:rgb(49, 49, 49);border-left-color:rgb(49, 49, 49);color:rgb(49, 49, 49);" dir="auto"><span></span><br></div><div style="word-spacing:1px;border-top-color:rgb(49, 49, 49);border-right-color:rgb(49, 49, 49);border-bottom-color:rgb(49, 49, 49);border-left-color:rgb(49, 49, 49);color:rgb(49, 49, 49);" dir="auto"><span>But this lead to race condition (ex. process B could put back ‘jane’ - last write wins).</span><br></div><div style="word-spacing:1px;border-top-color:rgb(49, 49, 49);border-right-color:rgb(49, 49, 49);border-bottom-color:rgb(49, 49, 49);border-left-color:rgb(49, 49, 49);color:rgb(49, 49, 49);" dir="auto"><span></span><br></div><div style="word-spacing:1px;border-top-color:rgb(49, 49, 49);border-right-color:rgb(49, 49, 49);border-bottom-color:rgb(49, 49, 49);border-left-color:rgb(49, 49, 49);color:rgb(49, 49, 49);" dir="auto"><span>Could this problem be solved atomically without involving explicit locking per Key?</span><br></div><div style="word-spacing:1px;border-top-color:rgb(49, 49, 49);border-right-color:rgb(49, 49, 49);border-bottom-color:rgb(49, 49, 49);border-left-color:rgb(49, 49, 49);color:rgb(49, 49, 49);" dir="auto"><span></span><br></div><div style="word-spacing:1px;border-top-color:rgb(49, 49, 49);border-right-color:rgb(49, 49, 49);border-bottom-color:rgb(49, 49, 49);border-left-color:rgb(49, 49, 49);color:rgb(49, 49, 49);" dir="auto"><span>Is there any other better way to represent this data set which will not suffer from the race condition?</span><br></div></div><div><div style="word-spacing:1px;border-top-color:rgb(49, 49, 49);border-right-color:rgb(49, 49, 49);border-bottom-color:rgb(49, 49, 49);border-left-color:rgb(49, 49, 49);color:rgb(49, 49, 49);" dir="auto"><br></div><div style="word-spacing:1px;border-top-color:rgb(49, 49, 49);border-right-color:rgb(49, 49, 49);border-bottom-color:rgb(49, 49, 49);border-left-color:rgb(49, 49, 49);color:rgb(49, 49, 49);" dir="auto">Thanks<br></div><div style="font-size:1rem;word-spacing:1px;border-top-color:rgb(49, 49, 49);border-right-color:rgb(49, 49, 49);border-bottom-color:rgb(49, 49, 49);border-left-color:rgb(49, 49, 49);color:rgb(49, 49, 49);" dir="auto">/Frank<br></div></div></blockquote><div><br></div></body></html>