我正在编写一个 gen_server,我想将 ets 表作为状态保存,然后在其他地方创建 ets 表。我应该如何将它添加到 gen_server 的状态中?
我想使用 ets 表而不是为它创建一个新字典,因为我想节省内存。
另外,如何遍历 ets 表?我想迭代或读取表中的每个值并检查值,然后我想根据值执行两个选项之一。
将ets表变成列表并遍历列表会更容易吗?
谢谢
我正在编写一个 gen_server,我想将 ets 表作为状态保存,然后在其他地方创建 ets 表。我应该如何将它添加到 gen_server 的状态中?
我想使用 ets 表而不是为它创建一个新字典,因为我想节省内存。
另外,如何遍历 ets 表?我想迭代或读取表中的每个值并检查值,然后我想根据值执行两个选项之一。
将ets表变成列表并遍历列表会更容易吗?
谢谢
一些建议:
erl -man ets
ETS 表通过其名称(在named_table
选项的情况下)或通过其表 id 来标识。将该信息传递给 gen_server 并将其保持在状态:
-record(state, { ..., tbl = none }).
init([TableID]) ->
...,
{ok, #state { tbl = TableID }}.
ETS 可能不会节省那么多内存。稍后的 Erlang/OTP 版本会出现一个新标志,其中可以使用 ETS 表,compressed
以便它们的内容在存储之前被压缩并在读取时解压缩(这会产生计算开销)。
要遍历 ETS 表,您有多种选择。ets:first/1 ets:next/2
就是这样一个接口。ets:foldl/3 ets:foldr/3
其他。ets:match/3
给你一个延续(一个光标)走。ets:select
比 match 还要通用。
把它变成一个列表会更容易吗?这取决于。ETS 表的强大之处在于它们有一个选项来{keypos, N}
定义存储元素的键。ets:lookup(?TAB, Key)
速度非常快,因此您可以快速查找键。列表并非如此。但另一方面,如果您总是遍历所有列表,它可能是一个更简单的解决方案(只要您不在进程之间传递大列表)。
也许应该避免将整个表变成一个列表并遍历它。您将在内存中生成列表,然后遍历它,这很昂贵。一次遍历它会更好,这样实时内存量就会很低。