[英]What is the best way, to traverse and update all elements in an Erlang ETS table?
您能否以一种“最佳实践”方法帮助我,以便在更新每个元素的同时仅对ETS表中的所有元素进行一次迭代? 我的表是一个私有集,我ets:update_element
在输入函数中使用ets:update_element
使用ets:foldl
遍历该表,但是我不确定这是否安全,因为破坏性地更新元素可能会使我根据文档,一次也一次。 我不会插入新键,仅更新值,请告诉我这种方法是否安全,或者告诉我另一种有效实现更新的方法!
谢谢!
您可以使用first/1
和next/2
。 在此处查看next/2
doco: http ://www.erlang.org/doc/man/ets.html#next-2
我认为ets
文档已经解决了您的担忧:
ETS内没有其他可以保证对象之间一致性的支持。 但是,safe_fixtable / 2函数可用于确保first / 1和next / 2调用序列将无错误地遍历表,并且即使另一个进程(或相同的过程)同时将对象删除或插入到表中。 没有其他保证。 特别是在这种遍历过程中插入或删除的对象可能只被访问一次或根本不被访问。 内部遍历表的功能(例如选择和匹配)将提供与safe_fixtable相同的保证。
这是我最终得到的结果,也许有人会发现它有用:
%% @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 ) ).
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.