簡體   English   中英

遍歷和更新Erlang ETS表中的所有元素的最佳方法是什么?

[英]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/1next/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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM