Знайомство з Erlang [15]

приклади роботи з ETS - Erlang Term Storage
продовження попереднього поста про ETS

ets:new(table_test, [ordered_set, public, named_table]).
ets:insert(table_test, {1, 777}).
ets:insert(table_test, {3, 779}).
ets:insert(table_test, {2, 778}).

ets:match_object(table_test, {'$1', '$2'}).
[{1,777},
 {2,778},
 {3,779}]

ets:fun2ms(fun({A,B}) -> {A,B} end).
[{{'$1','$2'},[],[{{'$1','$2'}}]}]

ets:select(table_test, [{{'$1','$2'},[],[{{'$1','$2'}}]}], 1).
{[{1,777}],
 {table_test,1,[],1,#Ref<0.2209292443.1747320834.54125>,[],0,
            0}}

ets:select(table_test, [{{'$1','$2'},[],[{{'$1','$2'}}]}], 5).
{[{1,777},{2,779},{3,778}],
  '$end_of_table'}

ets:delete(table_test, 2).
ets:match_object(table_test, {'$1', '$2'}).
[{1,777},{3,779}]
ets:new(table_test, [ordered_set, public, named_table]).
ets:insert(table_test, {{1, 777}, 888}).

ets:match_object(table_test, {'$1', '$2'}).
[{{1,777},888}]

ets:fun2ms(fun({A,B}) -> {A,B} end).
[{{'$1','$2'},[],[{{'$1','$2'}}]}]

ets:select(table_test, [{{'$1','$2'},[],[{{'$1','$2'}}]}], 1).
{[{{1,777},888}],
 {table_test,{1,777},
            [],1,#Ref<0.469085729.436600833.148380>,[],0,0}}

ets:insert(table_test, {{3, 772}, 880}).
ets:insert(table_test, {{2, 771}, 88760}).
ets:insert(table_test, {{3, 770}, 8890}).
ets:insert(table_test, {{4, 771}, 8760}).

ets:select(table_test, [{{'$1','$2'},[],[{{'$1','$2'}}]}], 10).
{[{{1,777},888},
  {{2,771},88760},
  {{3,770},8890},
  {{3,772},880},
  {{4,771},8760}],
 '$end_of_table'}

ets:delete(table_test, {2,771}).

ets:select(table_test, [{{'$1','$2'},[],[{{'$1','$2'}}]}], 10).
{[{{1,777},888},
  {{3,770},8890},
  {{3,772},880},
  {{4,771},8760}],
 '$end_of_table'}

upd. після написання тестового завдання я дізнався наступні моменти:

  • ets:lookup працює швидше, ніж ets:select / ets:match_object
  • таблиця ordered_set працює швидше, ніж bag
  • для невеличкого покращення швидкодії використовуємо private замість public
  • з ets:update_element/3 не получиться оновити запис, якщо він складається лише з ключа
  • gen_server:call надає деякі гарантії виконання завдань в черзі,
    на відміну від gen_server:cast -- з останнім черга може "забитись", а ми і не знатимемо
  • я ще не навчився користуватись qlc :D

Продовження

Посилання

https://erlang.org/doc/man/ets.html#fun2ms-1
https://erlang.org/doc/apps/erts/match_spec.html
https://learnyousomeerlang.com/ets
https://elixirschool.com/ru/lessons/specifics/ets/
https://www.proctor-it.com/erlang-thursday-using-ets-select-with-a-limit/