Краткая версия: безопасно ли использовать ets: foldl
для удаления каждой записи ETS по мере их итерации?
Предположим, таблица ETS накапливает информацию и теперь она пора все это обработать. Запись считывается из таблицы, используется каким-либо образом, а затем удаляется. (Также предположим, что таблица является частной
, поэтому проблем с параллелизмом нет.)
На другом языке, с аналогичной структурой данных, вы можете использовать цикл for ... each, обрабатывая каждую запись, а затем удалив его из хеша / dict / map / что угодно. Однако модуль ets
не имеет foreach
, как, например, списки
.
Но это может работать:
1> ets:new(ex, [named_table]).
ex
2> ets:insert(ex, {alice, "high"}).
true
3> ets:insert(ex, {bob, "medium"}).
true
4> ets:insert(ex, {charlie, "low"}).
true
5> ets:foldl(fun({Name, Adjective}, DontCare) ->
io:format("~p has a ~p opinion of you~n", [Name, Adjective]),
ets:delete(ex, Name),
DontCare
end, notused, ex).
bob has a "medium" opinion of you
alice has a "high" opinion of you
charlie has a "low" opinion of you
notused
6> ets:info(ex).
[...
{size,0},
...]
7> ets:lookup(ex, bob).
[]
Это предпочтительный подход? По крайней мере, это правильно и без ошибок?
В целом меня беспокоит изменение структуры данных во время ее обработки, однако документация ets: foldl подразумевает, что ETS вполне комфортно, когда вы изменяете записи внутри свернуть
. Поскольку я, по сути, вытираю таблицу, я хочу быть уверенным.
Я использую Erlang R14B с таблицей set
, однако я хотел бы знать, есть ли какие-либо оговорки с какой-либо версией Erlang, или стол любого типа. Спасибо!