Использование ets: foldl в качестве forEach для бедняков на каждой записи

Краткая версия: безопасно ли использовать 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, или стол любого типа. Спасибо!

5
задан JasonSmith 5 December 2010 в 19:18
поделиться