首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >erlang ets选择坏arg

erlang ets选择坏arg
EN

Stack Overflow用户
提问于 2016-06-21 15:36:13
回答 1查看 792关注 0票数 2

erlang版本18.3

使用Erlang ets得到一个奇怪的错误:select/1

下面的代码将从表中选择元素并接受它们为

如果我做了

代码语言:javascript
复制
save(10), %% insert 10 data

remove(3) %% remove 3 data per time

它起作用了

如果我做了

代码语言:javascript
复制
save(6007), %% insert  more datas

remove(400) %% remove 400 data per time

ets:select(Cont)中,这也是糟糕的arg,第一个或第二个循环中的不是,而是始终存在。

有什么建议吗?

代码语言:javascript
复制
 -record(item, {name, age}).
 %% start the table
 start() ->
 ets:new(example_table, [public, {keypos, 2},
 named_table,
 {read_concurrency, true},
 {write_concurrency, true}]).

 %% insert n demo data
 save(Limit) ->
 All = lists:seq(1 ,Limit),
 All_rec = [#item{name = {<<"demo">>, integer_to_binary(V)} , age = V} || V <- All],
 ets:insert(example_table, All_rec).

 %% remove all data, n data per select
 remove(Limit) ->
   M_head   = #item{name = '$1', _ = '_'},
 M_guards = [],
 M_result = ['$1'],
 M_spec   = [{M_head, M_guards, M_result}],

 case ets:select(example_table, M_spec, Limit) of
      '$end_of_table' ->
      0;
      {Keys, Cont} ->

      remove(example_table, Keys, Cont, 0, [])
      end.

      remove(Table, [],  Cont, Count, _Acc) ->

        case ets:select(Cont) of
          '$end_of_table' ->
            Count;
          {Keys, Cont_1} ->

            remove(Table, Keys,  Cont_1, Count, [])
        end;
      remove(Table,[Key | T],  Cont, Count, Acc) ->
        case ets:take(example_table, Key) of
          [] ->
       remove(Table, T,  Cont, Count, Acc);
          [Rec] ->
       io:format("Rec [~p] ~n", [Rec]),
       remove(Table, T,  Cont, Count + 1, [Rec | Acc])
        end.

堆栈跟踪

代码语言:javascript
复制
     4> example_remove:save(6007).
      true
     5> example_remove:remove(500).
    ** exception error: bad argument
   in function  ets:select/1
    called as ets:select({example_table,304,500,<<>>,
                             [{<<"demo">>,<<"2826">>},
                              {<<"demo">>,<<"3837">>},
                              {<<"demo">>,<<"5120">>},
                              {<<"demo">>,<<"878">>},
                              {<<"demo">>,<<"1195">>},
                              {<<"demo">>,<<"1256">>},
                              {<<"demo">>,<<"1449">>},
                              {<<"demo">>,<<"5621">>},
                              {<<"demo">>,<<"5768">>}],
                             9})
 in call from example_remove:remove/5 (d:/workspace/simple-cache/src/example_remove.erl, line 47)
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-06-21 20:27:27

我认为发生这种情况是因为您同时遍历并修改了表。

我建议用safe_fixtable的护罩包装主拆卸周期。

代码语言:javascript
复制
remove(Limit) ->
    ets:safe_fixtable(example_table, true),
    M_head   = #item{name = '$1', _ = '_'},
    M_guards = [],
    M_result = ['$1'],
    M_spec   = [{M_head, M_guards, M_result}],

    R = case ets:select(example_table, M_spec, Limit) of
        '$end_of_table' ->
            0;
        {Keys, Cont} ->
            remove(example_table, Keys, Cont, 0, [])
    end,
    ets:safe_fixtable(example_table, false),
    R. 
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37948776

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档