atomic ETS update with a function?

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

atomic ETS update with a function?

Vans S
Currently there is no atomic function to update a ETS value when its not a tuple.  For example if one of my ETS values is a map, and I want to put an element into the map, I have no atomic way to do so.

Is there anyone else that really has a need for a function like :ets.update/3 where arg 1 is ets_table, 2 is key, 3 is fun callback that is called passing the original element and the reply should be the new element?

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: atomic ETS update with a function?

Stanislaw Klekot
On Mon, Nov 19, 2018 at 06:44:09PM +0000, Vans S wrote:
> Currently there is no atomic function to update a ETS value when its not a tuple.  For example if one of my ETS values is a map, and I want to put an element into the map, I have no atomic way to do so.

My guess is that there's no function to update non-tuples, because ETS
tables can only contain tuples -- or at least documentation doesn't say
otherwise. Or did I get your question wrong?

--
Stanislaw Klekot
_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Leo
Reply | Threaded
Open this post in threaded view
|

Re: atomic ETS update with a function?

Leo


Il giorno mar 20 nov 2018 alle ore 00:22 Stanislaw Klekot <[hidden email]> ha scritto:
On Mon, Nov 19, 2018 at 06:44:09PM +0000, Vans S wrote:
> Currently there is no atomic function to update a ETS value when its not a tuple.  For example if one of my ETS values is a map, and I want to put an element into the map, I have no atomic way to do so.

My guess is that there's no function to update non-tuples, because ETS
tables can only contain tuples -- or at least documentation doesn't say
otherwise. Or did I get your question wrong?

Neither using qlc module?

Leo

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: atomic ETS update with a function?

Lukas Larsson-3
In reply to this post by Vans S
Hello,

On Mon, Nov 19, 2018 at 7:44 PM Vans S <[hidden email]> wrote:
Currently there is no atomic function to update a ETS value when its not a tuple.  For example if one of my ETS values is a map, and I want to put an element into the map, I have no atomic way to do so.

Is there anyone else that really has a need for a function like :ets.update/3 where arg 1 is ets_table, 2 is key, 3 is fun callback that is called passing the original element and the reply should be the new element?

I've long wanted to do this for match specs, it would however be a huge undertaking to implement this. The main problem is what to do if the process runs out of reductions while doing the update.

Should it be allowed to continue to run? and thus potentially starve other processes.
Should it be preempted? what do we then do with the locks on the ETS table?

Lukas

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: atomic ETS update with a function?

Vans S
What are the chances it would run out of reductions? What about drop the update if it runs out of reductions.  

Most use cases I see are putting/removing/merging elements into various collections. Complex business logic should be done outside, then you get inside the lock and simply do a ++, --, :maps.put, :maps.merge, etc.

On Tuesday, November 20, 2018, 4:36:22 a.m. EST, Lukas Larsson <[hidden email]> wrote:


Hello,

On Mon, Nov 19, 2018 at 7:44 PM Vans S <[hidden email]> wrote:
Currently there is no atomic function to update a ETS value when its not a tuple.  For example if one of my ETS values is a map, and I want to put an element into the map, I have no atomic way to do so.

Is there anyone else that really has a need for a function like :ets.update/3 where arg 1 is ets_table, 2 is key, 3 is fun callback that is called passing the original element and the reply should be the new element?

I've long wanted to do this for match specs, it would however be a huge undertaking to implement this. The main problem is what to do if the process runs out of reductions while doing the update.

Should it be allowed to continue to run? and thus potentially starve other processes.
Should it be preempted? what do we then do with the locks on the ETS table?

Lukas

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: atomic ETS update with a function?

Sverker Eriksson-5
In reply to this post by Vans S

You can use ets:select_replace/2 to do an atomic compare-and-swap operation:


[Old] = ets:lookup(T, Key),
New = update_object(Old),
Success = (1 =:= ets:select_replace(T, [{Old, [], [{const, New}]}])),


ets:select_replace/2 was introduced in OTP-20.


/Sverker
	

On mån, 2018-11-19 at 18:44 +0000, Vans S wrote:
Currently there is no atomic function to update a ETS value when its not a tuple.  For example if one of my ETS values is a map, and I want to put an element into the map, I have no atomic way to do so.

Is there anyone else that really has a need for a function like :ets.update/3 where arg 1 is ets_table, 2 is key, 3 is fun callback that is called passing the original element and the reply should be the new element?
_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: atomic ETS update with a function?

Vans S
Interesting use for select_replace, I think I see. If Old changes in the meantime, it wont succeed as Old wont be found.

I am aware of select_replace, did not realise you could use it this way. Nifty!

On Tuesday, November 20, 2018, 9:16:04 a.m. EST, Sverker Eriksson <[hidden email]> wrote:


You can use ets:select_replace/2 to do an atomic compare-and-swap operation:


[Old] = ets:lookup(T, Key),
New = update_object(Old),
Success = (1 =:= ets:select_replace(T, [{Old, [], [{const, New}]}])),


ets:select_replace/2 was introduced in OTP-20.


/Sverker
	

On mån, 2018-11-19 at 18:44 +0000, Vans S wrote:
Currently there is no atomic function to update a ETS value when its not a tuple.  For example if one of my ETS values is a map, and I want to put an element into the map, I have no atomic way to do so.

Is there anyone else that really has a need for a function like :ets.update/3 where arg 1 is ets_table, 2 is key, 3 is fun callback that is called passing the original element and the reply should be the new element?
_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions