你能帮助我采用“最佳实践”方法,只更新一次ETS表中的所有元素,同时更新每个元素吗?我的表是一个私有集,我正在使用ets:foldl
在我的输入函数中使用ets:update_element
遍历它,但我不确定,如果这是一种安全的方法,那么破坏性地更新元素根据文件,可能会在另一个时间给我相同的元素。我不打算插入新密钥,只更新值,请告诉我,这种方法是否安全,或者向我展示一种有效实现更新的替代方法!
谢谢!
答案 0 :(得分:1)
您可以使用first/1
和next/2
。在此处查看next/2
doco:http://www.erlang.org/doc/man/ets.html#next-2
我认为ets
文档已经回答了您的问题:
ETS内没有其他可以保证的支持 对象之间的一致性但是,safe_fixtable / 2函数可以 用于保证第一个/ 1和下一个/ 2个呼叫的序列 遍历表没有错误,并且每个现有对象都在 表只访问一次,即使是另一个进程(或相同的 process)同时删除或插入表中的对象。 没有更多的保证;特别是插入的对象或 在这种遍历期间删除可以被访问一次或根本不访问。 内部遍历表的函数,如select和 匹配,将提供与safe_fixtable相同的保证。
答案 1 :(得分:0)
这是我最终得到的结果,也许有人会发现它很有用:
%% @doc
%% Traverses each element in an ETS table, and calls Fun on them.
%% Use with caution, when inserting or deleting elements, see the
%% ETS documentation for details!
-spec ets_each(
TableRef :: ets:tid( ),
Fun :: fun( ( Key :: term( ), [ Element :: term( ) ], Extra :: term( ) ) -> ok ),
Extra :: term( )
) ->
ok.
ets_each( TableRef, Fun, Extra ) ->
ets:safe_fixtable( TableRef, true ),
First = ets:first( TableRef ),
try
do_ets_each( TableRef, Fun, Extra, First )
after
ets:safe_fixtable( TableRef, false )
end.
%% @doc
%% Recursive helper function for ets_each.
-spec do_ets_each(
TableRef :: ets:tid( ),
Fun :: fun( ( Key :: term( ), [ Element :: term( ) ], Extra :: term( ) ) -> ok ),
Extra :: term( ),
Key :: term( )
) ->
ok.
do_ets_each( _TableRef, _Fun, _Extra, '$end_of_table' ) ->
ok;
do_ets_each( TableRef, Fun, Extra, Key ) ->
Fun( Key, ets:lookup( TableRef, Key ), Extra ),
do_ets_each( TableRef, Fun, Extra, ets:next( TableRef, Key ) ).