简体   繁体   English

Erlang ets删除/过滤元素

[英]Erlang ets remove / filter element

I use elang ets table as a simple cache. 我使用elang ets表作为简单的缓存。 I want to use a process to scan the table and remove expired elements (multiple). 我想使用进程扫描表并删除过期的元素(多个)。

with ets:foldl 与ets:foldl

expire_table_example() ->
Tab = ets:new(ets_tab, [named_table, set]),
ets:insert(Tab, [{a, 1}, {b, 2}, {c, 3}, {d, 4}, {e, 5},{f,7}]),
Tab1 = ets:foldl(fun({Key, Val}, Acc) ->
if
   (Val > 3) -> [{Key, Val} | Acc];
   true -> Acc
 end
end, Tab, Tab),
io:format("end ~p ~n", [Tab1]).

I got 我有

[{f,7},{e,5},{d,4}|ets_tab] %% the ets_tab is NOT expected.

How Can I fix This? 我怎样才能解决这个问题?

Any other API's would do this better? 任何其他API会做得更好吗?

You can't use ets table as accumulator. 您不能将ets表用作累加器。

For your purpose you can use ets:select_delete/2 : 为了您的目的,您可以使用ets:select_delete / 2

1> Tab = ets:new(ets_tab, [named_table, set]).
ets_tab
2> ets:insert(Tab, [{a, 1}, {b, 2}, {c, 3}, {d, 4}, {e, 5},{f,7}]).
true
3> ets:select_delete(Tab, [{{'$1','$2'},[{'=<','$2',3}],[true]}]).
3
4> ets:tab2list(Tab).
[{f,7},{e,5},{d,4}]

Or you can use ets:tab2list/1 to get list of all values, filter them and after that re-insert to table: 或者您可以使用ets:tab2list / 1获取所有值的列表,过滤它们,然后重新插入到表中:

1> Tab = ets:new(ets_tab, [named_table, set]).
ets_tab
2> ets:insert(Tab, [{a, 1}, {b, 2}, {c, 3}, {d, 4}, {e, 5},{f,7}]).
true
3> L = ets:tab2list(Tab).
[{f,7},{e,5},{d,4},{c,3},{b,2},{a,1}]
4> L2 = lists:filter(fun({Key,Val}) -> Val > 3 end, L).
[{f,7},{e,5},{d,4}]
5> ets:delete_all_objects(Tab).
true
6> ets:insert(Tab, L2).
true
7> ets:tab2list(Tab).
[{f,7},{e,5},{d,4}]

Another way it can be done is by using list comprehensions . 另一种方法是使用列表推导

1> Tab = ets:new(ets_tab, [named_table, set]).
ets_tab   
2> ets:insert(Tab, [{a, 1}, {b, 2}, {c, 3}, {d, 4}, {e, 5},{f,7}]).    
true    
3> [{X,Y} || {X,Y} <- ets:tab2list(Tab), Y>3].    
[{f,7},{e,5},{d,4}]

You may find that deleting huge numbers of objects periodically may result in undesirable latency spikes. 您可能会发现定期删除大量对象可能会导致不期望的延迟峰值。 There is interesting project which have cache segments as separate ets tables and deletes outdated objects by dropping whole ets, maybe you will find it interesting as well 有一个有趣的项目将缓存段作为单独的ets表并通过删除整个ets来删除过时的对象,也许你会发现它也很有趣

https://github.com/fogfish/cache https://github.com/fogfish/cache

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM