问题描述
说:
但是会发生什么如果函数
从表中删除对象?在这种情况下,有没有保证所有剩余的对象将被包含在遍历中?
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:
文档在这里说:
所以修复表进行遍历有一个代价。不要在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和已删除的元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!