<div dir="ltr"><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">I think both would work.</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><br></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">There is also the possibility B sends a delete message to A which then deletes keys. This forces linearization in A.</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><br></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">How many concurrent deletes you have sort-of determines if this strategy is more viable, and also in which direction the system might go in the future. If you only have a handful deletes I would just factor it through a single process since a lot of things are easier that way, typically.</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><br></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">In any case, your Erlang/OTP version matter here. For 22.0 and onwards, you can set `{write_concurrency, true}` for ordered_set tables and expect an improvement as core count increases. Before, there is no effect and you are essentially grabbing a table lock for the whole table whenever you want to issue a write (i.e. delete). So before 22, concurrent deletes yields no performance improvement, which argues a messaging model might be simpler to reason about[0].</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><br></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">[0] Why? Because there is an invariant which is easy to maintain: if the process is purging, messages wait in the mailbox. So no other deletes can happen in between. If the process is deleting, it cannot be purging.</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><br></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sun, Dec 8, 2019 at 3:07 PM Frank Muller <<a href="mailto:frank.muller.erl@gmail.com">frank.muller.erl@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><div dir="auto">Crystal clear Jesper, thanks.</div><div dir="auto"><br></div><div dir="auto">is purge1/1 valid/correct?</div><div dir="auto"><br></div><div dir="auto">/Frank</div><br></div><div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div dir="ltr"><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><span style="font-family:Arial,Helvetica,sans-serif">On Sun, Dec 8, 2019 at 9:29 AM Frank Muller <<a href="mailto:frank.muller.erl@gmail.com" target="_blank">frank.muller.erl@gmail.com</a>> wrote:</span><br></div></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span style="color:rgb(49,49,49);word-spacing:1px"><div dir="auto">Hi all</div></span><br style="color:rgb(49,49,49);word-spacing:1px"><br style="color:rgb(49,49,49);word-spacing:1px"><span style="color:rgb(49,49,49);word-spacing:1px">Lets assume a public ETS table of type â€˜ordered_set’.</span><br style="color:rgb(49,49,49);word-spacing:1px"><br style="color:rgb(49,49,49);word-spacing:1px"></blockquote><div><br></div><div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">The ETS documentation defines "safe traversal". Traversal of `ordered_set` tables are always safe. That is, they will do the "right thing" if updates are done while traversal happens.</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><br></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">For tables of the other types, you either do the whole traversal in one call, or you use the safe_fixtable/2 call to fix the table while traversal is happening.</div></div><div><br></div></div><div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">The underlying reason is that the table has an order. This means we can always drill down into the table and find the place we "were" so to speak by utilizing this order. In the case of e.g., `set` tables, we don't a priori have an order, so we are encoding something like a hash bucket and the element we reached. But if that element is gone, we don't know where we were, and there is no other structural information to go by. The fixtable calls basically postpones changes to the table in a separate buffer until the traversal is done, then replays the buffer on the table. This ensures the core table is traversal-stable. Requests to the table first checks the buffer before checking the main core table[0]</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><br></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">[0] This model is essentially a 2 level log-structured-merge-tree (LSM tree) variant.</div></div></div><div dir="ltr"><div><br></div>-- <br><div dir="ltr">J.</div></div>
</blockquote></div></div>
</blockquote></div><br clear="all"><div><br></div>-- <br><div dir="ltr" class="gmail_signature">J.</div>