我想将函数应用于ETS表中的所有元组:
该表是一个集合,每个键只出现一次。
我的表只包含相同类型的元组:
{Key, X, Y, VX, VY}
所有值均为::integer()
我想要做的是获得一定的价值并更新全部
我的元组有一个函数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}.
如果我使用ets:foldl
,我的插入内容可以在折叠过程中遍历,并且
导致无限(非常长)的循环。
我可以使用ets:foldl
准备新元组,然后插入整个元组
列表
我可以插入新表,然后用新表替换旧表, 但是我不希望通过调用a来限制对表的访问 gen_server,该表必须随时可访问。
我无法使用ets:update_element
,因为我需要读取VX和VY值
更新X和Y。
我知道有一些迭代器实用程序,但似乎没有人允许 传递乐趣。
我需要每隔1到5秒进行一次此更新。所以,解决方案是 最有效的10元组?有100个元组?有更多?
谢谢!
我保留一份船只清单,钥匙是船只ID,X和Y是地理位置 坐标,VX和VY代表运动的矢量:一个移位 一秒钟Elapsed是一个比率,自上次以来的秒数 更新。该表有助于随时了解每艘船的位置。
答案 0 :(得分:1)
我可能会使用ets:foldl。
在我看来,您只需要对此数据进行迭代访问即可。所以你可以在这里使用记录列表。
另一种方法(我会选择)是为船主管并为每艘船创建一个gen_server。这样每艘船都有自己的状态,你实际上不需要遍历任何列表。
同时结帐qlc http://www.erlang.org/doc/man/qlc.html qlc让你在ets或mnesia表上使用list comrehensions。它可能具有与foldl相同的性能。
答案 1 :(得分:1)
没有什么好方法可以做你正在做的事情。
最近,我遇到了类似的问题(更新〜5000行,每秒一次)
这使我采取了完全不同的方法 那么,你需要存储解释的值吗?或者你可以在查找时计算价值吗?
如何存储: {K,X,Y,VX,VY,LastUpdateTime}
然后做一些像(无法编译的例子):
boats:get_all() -> % Record syntax would be smarter here, but it's an example...
ets:foldl(?TABLE,[],fun(Row={Id,_,_,_,_,_},Acc) -> [{Id,calc(Row)}|Acc] end).
boats:get(Id) ->
[Row] = ets:lookup(?TABLE,Id),
calc(Row).
calc({_K,X,Y,VX,VY,LastUpdate}) ->
{X + (VX * (now() - LastUpdate)), Y + (VY * (now() - LastUpdate)}
这允许您不要阻止genserver,也不必每5秒更新一次表。您基本上只会在每次船只报告时更新表格。