I would like to apply a function to all the tuples in an ETS table :
The table is a set, each key appears only once.
My table contains only tuples of the same type:
{Key, X, Y, VX, VY}
All values are ::integer()
What i want to do is have a certain value Elapsed and update all
my tuples with a function apply_vector/2
apply_vector({K, X, Y, 0, 0}, _Elapsed) ->
{K, X, Y, 0, 0};
apply_vector({K, X, Y, VX, VY}, Elapsed) ->
NewX = X + (VX * Elapsed),
NewY = Y + (VY * Elapsed),
{K, NewX, NewY, VX, VY}.
Possible solutions
-
If i use
ets:foldl, my inserts could be traversed during the fold, and
result in an infinite (very long) loop. -
I could prepare the new tuples with a
ets:foldl, and then insert the whole
list. -
I could insert to a new table, then replace the old table by the new,
but i don’t want to limit access to the table with calls to a
gen_server, the table must be accessible at any time. -
I can not use
ets:update_elementbecause I need to read VX and VY values
to update X and Y. -
I know there are some iterators utilities but no one seems to allow to
pass a fun.
I need to make this update every 1 – 5 seconds. So, wich solution is
the most efficient with 10 tuples ? With 100 tuples ? With more ?
Thank You !
I Keep a list of boats, the Key is the Boat ID, X and Y are geographic
coordinates, VX and VY represents a vector of movement: a deplacement
for one second. Elapsed is a ratio, a number of seconds since the last
update. The table helps to know at any time the position of each boat.
I probably use ets:foldl for this.
Seems to me like you only need iterative access on this data. So you could just use list of records here.
Another approach (which I would go for) is to put a boat supervisor and create a gen_server for every boat. That way every boat will have its own state and you won’t actually need to traverse any list.
Also checkout qlc http://www.erlang.org/doc/man/qlc.html
qlc let’s you use list comrehensions on ets or mnesia tables. It will probably have the same performance as foldl though.