ets:foldl和已删除的元素 [英] ets:foldl vs deleted elements

查看:198
本文介绍了ets:foldl和已删除的元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

ets:foldl / 3的文档说:


如果函数将对象插入到表中,或者另一个进程将对象插入到表,那些对象可能(取决于密钥排序)被包含在遍历中。

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?

推荐答案

根据ets的来源。如果一个进程正在迭代表,那么它将删除记录,如果它们尚未处理,那么这些记录将不被处理。

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.

,帮助函数是

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.

首先折叠修复表。当进程修复一个表时,它将被记录到{Time,Pid}列表中。在一个固定的表中ets:first和ets:next保证成功,每个对象将只返回一次。在有顺序表ets的情况下:下一个可以返回其对象不再存在的键。但是,这不是一个问题,因为ets:查找返回一个空列表,以防记录不在表中。列表:在这种情况下,foldl不会失败。

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.

所以答案是肯定的,其他记录将由ets:foldl处理。

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

如果您有多个进程同时操作表,则safe_fixtable将保护表不受并发操作的影响。文件的safe_fixtable / 2说:

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:


一个进程通过调用safe_fixtable(Tab,true)来修复表。该表保持固定,直到该进程通过调用safe_fixtable(Tab,false)释放它,或者直到该进程终止。

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.

文档在这里说:


请注意,在已经释放之前,没有删除的对象实际上从固定表中删除。如果一个进程修复了一个表,但是没有释放它,那么被删除的对象所使用的内存将永远不会被释放。表上的操作也将显着降低。

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.

所以修复表进行遍历有一个代价。不要在foldl函数中做太多的操作,也不要太长时间。

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.

这篇关于ets:foldl和已删除的元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆