我使用elang ets表作为简单的缓存.我想使用进程扫描表并删除过期的元素(多个).
与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]).
Run Code Online (Sandbox Code Playgroud)
我有
[{f,7},{e,5},{d,4}|ets_tab] %% the ets_tab is NOT expected.
Run Code Online (Sandbox Code Playgroud)
我怎样才能解决这个问题?
任何其他API会做得更好吗?
我使用ets通过elixir作为一个简单的内存持久层来存储和检索键,也用于偶尔的foldl,它涉及减少许多具有不同值的重复键.我正在使用行李选项.
是否有一种简单的O(1)方法来检索当前密钥的列表而无需进行更多涉及的表遍历或匹配或折叠?
Erlang或Elixir语法响应欢迎.
:ets.new(:cache, [:bag, :named_table, :protected])
Run Code Online (Sandbox Code Playgroud)
我有一个原子键的静态映射,由我用来帮助插入的整数索引.但并非所有的钥匙都被使用..
chunk_key_map = %{2 => :chunk_key_2, ..... 28 => :chunk_key_28}
Run Code Online (Sandbox Code Playgroud)
如果没有快速的方法,我知道我可以做一个ets:查找我的每个静态原子键值并测试!= []并生成我自己的列表,但想看看ets是否支持这样的功能.
谢谢
我想在ets中创建一个表,如果它不存在的话.如何检查此命名是否存在?
我正在从csv文件中读取邮政编码,获取该数据并使用ets进行缓存.
邮政编码文件相当大(95MB),因为它包含大约180万条目.
我只缓存目前查找所需的邮政编码(大约200k),因此存储在ets中的数据量应该不是问题.然而,无论插入的数量有多少,该过程占用的内存量实际上都没有变化.如果我插入1行或全部180万,似乎并不重要.
# not logging all functions defs so it is not too long.
# Comment if more into is needed.
defmodule PostcodeCache do
use GenServer
def cache_postcodes do
"path_to_postcode.csv"
|> File.read!()
|> function_to_parse()
|> function_to_filter()
|> function_to_format()
|> Enum.map(&(:ets.insert_new(:cache, &1)))
end
end
Run Code Online (Sandbox Code Playgroud)
我在终端上iex -S mix运行它并运行命令:observer.start.当我进入进程选项卡时,我的postcodeCache内存很大(超过600MB)
即使我过滤文件,所以我最终只在其中存储1个邮政编码:ets仍然超过600MB.
在服务器中,我试图将其连接的客户端及其 PID 存储在 ets 表中。
该表在服务器启动时创建
initate_server() ->
ets:new(users, [set, named_table]).
Run Code Online (Sandbox Code Playgroud)
当用户连接到服务器时,我正在调用一个函数
add_user(PID, Nick) ->
ets:insert_new(users, {Nick, PID}).
Run Code Online (Sandbox Code Playgroud)
这反过来会产生一个错误,说我在上面使用了一个错误的参数。是否可以将 PID 存储在这样的 ets 表中?
错误说明如下:
Something went very wrong!
{{case_clause,
{'EXIT',
{badarg,
[{ets,insert,[users,{"user01", <0.66.0>}],[]},
{server, loop, 2,
[{file,
filenames and such...
Run Code Online (Sandbox Code Playgroud) 可能吗?如果是这样,怎么样?
以下代码在IEX中执行.
但是,编译的代码会生成运行时错误.
:ets.fun2ms(fn({a,b}) -> a and b end)
Run Code Online (Sandbox Code Playgroud)
错误就像这样:我想知道如何正确调用.
** (exit) exited in: :ets.fun2ms(:function, :called, :with, :real, :fun, :should, :be, :transformed, :with, :parse_transform, :or, :called, :with, :a, :fun, :generated, :in, :the, :shell)
** (EXIT) :badarg
stacktrace:
(stdlib) ets.erl:554: :ets.fun2ms/1
test/game/ets_lookup_test.exs:27
Run Code Online (Sandbox Code Playgroud) 我想在 ETS 表中存储有关其他网络参与者信息的元组。我想使用{ip_address(), port_number()}(return ofinet:peername(Socket)的元组作为条目的键。又名我想使用地址/端口的组合作为 ETS 表中其他节点/条目的标识符。
这对于 ets 来说可能吗?或者我必须使用其他类型作为密钥?
我正在使用Elixir 1.6.3.我正在使用:etsElixir中的Erlang 模块,我对:ets.new/2函数的返回值感到有点困惑.
根据doc的例子,在调用时:ets.new(:whatever, []),我应该返回一个看似是整数值的东西:
iex> table = :ets.new(:buckets_registry, [:set, :protected])
8207
Run Code Online (Sandbox Code Playgroud)
但是,当我运行完全相同的代码时iex,我得到一个引用:
iex(1)> table = :ets.new(:buckets_registry, [:set, :protected])
#Reference<0.1885502827.460455937.234656>
Run Code Online (Sandbox Code Playgroud)
那么,自编写文档以来有什么变化吗?或者它是一样的,我对参考是什么感到困惑?
我知道(至少)有三种方法可以在 Erlang 中实现可变状态:
persistent_term它们的基本用法与我看起来非常相似:
% ETS
1> ets:new(table1, [named_table]).
2> ets:insert(table1, {thing}).
3> ets:lookup(table1, thing).
[{thing}]
% persistent_term
1> persistent_term:put(table2, thing).
2> persistent_term:get(table2).
thing
% Process dictionary
1> put(table3, thing).
2> get(table3).
thing
Run Code Online (Sandbox Code Playgroud)
使用其中一种与另一种有什么区别和优缺点?
我发现 ETS 的行为更像是映射,但它与将映射保存在persistent_terms 或过程字典中有何不同?
根据说明书 ETS 表有 4 种类型:
\n\n\n\n
\n- \n
set\xe2\x80\x93 该表是一个集合表:一个键,一个对象,对象之间没有顺序。这是默认的表类型。- \n
ordered_set\xe2\x80\x93 该表是一张ordered_set表:一个键,一个对象,按照Erlang术语顺序排序,这是<和>运算符隐含的顺序。在某些情况下,这种类型的表与其他类型的表有一些不同的行为。最值得注意的是,ordered_set 表在比较相等时将键视为相等,而不仅仅是在匹配时。这意味着对于ordered_set表来说,integer() 1和float() 1.0被认为是相等的。这也意味着,如果 float() 和 integer() 混合在表的键中,则用于查找元素的键不一定与返回元素中的键匹配。- \n
bag\xe2\x80\x93 该表是一个 bag 表,它可以有许多对象,但每个键只能有一个对象的实例。- \n
duplicate_bag\xe2\x80\x93 该表是一个duplicate_bag 表,每个键可以有许多对象,包括同一对象的多个副本。
虽然我从他们的描述中不太明白它们之间的区别。这里的“对象”和“对象实例”是什么?
\n