ets:foldl vs deleted elements

本小妞迷上赌 提交于 2019-12-23 05:23:04

问题


The documentation for ets:foldl/3 says:

If Function inserts objects into the table, or another process inserts objects into the table, those objects may (depending on key ordering) be included in the traversal.

But what happens if Function deletes objects from the table? Is there any guarantee that all remaining objects will be included in the traversal in that case?


回答1:


According to the source of ets.erl if one process is iterating the table and during that it deletes records those records won't be processed if they haven't processed so far.

foldl(F, Accu, T) ->
  ets:safe_fixtable(T, true),
  First = ets:first(T),
  try
    do_foldl(F, Accu, First, T)
  after
    ets:safe_fixtable(T, false)
  end.

and the helper function is

do_foldl(F, Accu0, Key, T) ->
  case Key of
    '$end_of_table' ->
      Accu0;
    _ ->
      do_foldl(F,
               lists:foldl(F, Accu0, ets:lookup(T, Key)),
               ets:next(T, Key), T)
  end.

At first foldl fixes the table. When a process fixes a table it will be recorded into a {Time, Pid} list. In a fixed table ets:first and ets:next are guaranteed to succeed and each object will be only returned once. In case of ordered tables ets:next can give back a key whose object no longer exists. But it is not a problem since ets:lookup give back an empty list in case the record is not in the table. lists:foldl won't fail in that case.

So the answer is yes, the other records will be processed by ets:foldl.

If you have multiple processes manipulating the tables concurrently, the safe_fixtable will protect the table from the concurrent manipulations. Docs of safe_fixtable/2 says:

A process fixes a table by calling safe_fixtable(Tab, true). The table remains fixed until the process releases it by calling safe_fixtable(Tab, false), or until the process terminates.

Take care what the documentation say here:

Note that no deleted objects are actually removed from a fixed table until it has been released. If a process fixes a table but never releases it, the memory used by the deleted objects will never be freed. The performance of operations on the table will also degrade significantly.

So fixing the table for traversal has a price. Don't do too much manipulations in the foldl function, and it shouldn't take too long either.



来源:https://stackoverflow.com/questions/20327171/etsfoldl-vs-deleted-elements

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!