Использование таблицы ets для состояния gen_server

Я пишу gen_server, в котором я хочу хранить таблицу ets как состояние, тогда таблица ets была создана где-то еще. Как мне добавить это в состояние gen_server?

Я хочу использовать таблицу ets, а не создавать для нее новый словарь, потому что хочу сэкономить память.

Кроме того, как перебирать таблицу ets? Я хочу повторить или прочитать каждое значение в таблице и проверить значение, затем я хочу сделать один из двух вариантов в зависимости от значения.

Было бы проще просто превратить таблицу ets в список и пройтись по списку?

Спасибо


person some_id    schedule 24.11.2010    source источник


Ответы (1)


Некоторые предложения:

  • Прочтите справочную страницу ETS: erl -man ets
  • Таблица ETS идентифицируется либо по имени (в случае опции named_table), либо по идентификатору таблицы. Передайте эту информацию на gen_server и сохраните ее в состоянии:

    -record(state, { ..., tbl = none }).
    
    
    init([TableID]) ->
        ...,
        {ok, #state { tbl = TableID }}.
    

ETS, возможно, не сэкономит столько памяти. В более позднем выпуске Erlang/OTP появится новый флаг, в котором таблицы ETS могут быть compressed, чтобы их содержимое сжималось перед сохранением и распаковывалось при чтении (это связано с дополнительными вычислительными затратами).

Для перебора таблицы ETS у вас есть несколько вариантов. ets:first/1 ets:next/2 — один из таких интерфейсов. ets:foldl/3 ets:foldr/3 другой. ets:match/3 дает вам продолжение (курсор) для ходьбы. ets:select является еще более общим, чем match.

Не проще ли превратить его в список? Это зависит. Сила таблицы ETS заключается в том, что у них есть опция {keypos, N}, определяющая ключ, в котором хранятся элементы. ets:lookup(?TAB, Key) работает очень быстро, поэтому у вас есть быстрый поиск по ключам. Со списками не так. Но, с другой стороны, если вы всегда просматриваете весь список, это может быть более простым решением (пока вы не передаете большой список между процессами).

Возможно, следует избегать превращения всей таблицы в список и обхода ее. Вы сгенерируете список в памяти, а затем пройдете по нему, что дорого. Лучше проходить его понемногу, чтобы объем оперативной памяти был низким.

person I GIVE CRAP ANSWERS    schedule 24.11.2010
comment
Спасибо. Несколько вопросов, которые я хочу сделать правильно. Мы создаем таблицу ets для представления торрента перед созданием бинарного битового поля. Я хотел бы прочитать таблицу ets и создать очередь из нужных кусков. К этой очереди будет обращаться обработчик одноранговых узлов, чтобы избежать дублирования запросов. как только фрагмент получен правильно, элемент удаляется из очереди, а битовое поле или состояние торрента обновляются. Я хочу отслеживать состояние торрента, чтобы графический интерфейс отображал индикатор выполнения и т. д. Мне интересно, должен ли я создать словарь из таблицы ets или просто отредактировать таблицу напрямую? - person some_id; 24.11.2010
comment
etorrent использует двухэтапный процесс. Каждый одноранговый узел индивидуально читает таблицу ETS и решает, чего он хочет. Но таблица protected, поэтому все фактическое назначение происходит на втором этапе: вызывается управляющий менеджер фрагментов, и он сериализует доступ к таблице, чтобы никакие два процесса не захватили один и тот же фрагмент случайно. Это дает эффективный параллелизм, но при этом обеспечивает прогресс и безопасность. - person I GIVE CRAP ANSWERS; 25.11.2010
comment
Хорошо, мы создадим очередь из нужных чанков. Разве фрагменты не находятся на диске, если они не находятся в памяти, например. стол. Я предполагаю, что менеджер фрагментов может отслеживать, что захватывается, и блокировать дубликаты захвата, но выполняется ли захват или доступ к данным до тех пор, пока не будет отправлен весь двоичный файл? - person some_id; 25.11.2010
comment
Поскольку вы спрашиваете: я отправляю бинарные данные размером 16 КБ прямо в нужное место на диске и никогда не храню их в памяти. Таким образом, мы можем использовать уровень кэширования диска ядра как можно скорее (он работает лучше, чем мы), и мы сохраняем память на клиенте. В таблице ETS хранится то, что у нас есть на диске, а что нет. После завершения piece мы считываем весь фрагмент с диска, SHA1 и проверяем/аннулируем его. Если мы получим кусок быстро, то кеш диска все равно держит все это, поэтому цена не высока - person I GIVE CRAP ANSWERS; 27.11.2010