erlang ets 选择错误的参数
Posted
技术标签:
【中文标题】erlang ets 选择错误的参数【英文标题】:erlang ets select bad arg 【发布时间】:2016-10-23 06:12:45 【问题描述】:erlang 版本 18.3
Erlang ets:select/1
遇到一个奇怪的错误以下代码将从表格中选择元素并获取它们。
如果我这样做
save(10), %% insert 10 data
remove(3) %% remove 3 data per time
有效
如果我这样做
save(6007), %% insert more datas
remove(400) %% remove 400 data per time
ets:select(Cont)
中的 arg 也是错误的,它不是在第一个或第二个循环中,但始终存在。
有什么建议吗?
-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 = [#itemname = <<"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 = #itemname = '$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.
堆栈跟踪
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)
【问题讨论】:
这段代码的目的是什么?另外,请向我们展示您收到的错误日志。 我无法复制。 @Lol4t0 你用的是哪个版本的erlang? @A.Sarid 日志已更新 【参考方案1】:我相信发生这种情况是因为您同时遍历表并对其进行修改。
我建议用safe_fixtable
的守卫来包装主删除周期
remove(Limit) ->
ets:safe_fixtable(example_table, true),
M_head = #itemname = '$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.
【讨论】:
谢谢。这是有道理的。以上是关于erlang ets 选择错误的参数的主要内容,如果未能解决你的问题,请参考以下文章