使用 ets 表作为 gen_server 状态

发布于 2024-10-03 21:14:27 字数 224 浏览 2 评论 0原文

我正在编写一个 gen_server,我想将 ets 表保存为状态,然后在其他地方创建 ets 表。我应该如何将其添加到 gen_server 的状态中?

我想使用 ets 表而不是为其创建新字典,因为我想节省内存。

另外,如何迭代 ets 表?我想迭代或读取表中的每个值并检查该值,然后我想根据该值执行两个选项之一。

将 ets 表转为列表并遍历列表会更容易吗?

谢谢

I am writing a gen_server which I want to hold an ets table as a state, then ets table was created somewhere else. How should I add this to the state of the gen_server?

I want to use the ets table rather than create a new dictionary for it because I want to save memory.

Also, How does one iterate through a ets table? I want to iterate or read each value in the table and check the value, then I want to do one of two options depending on the value.

Would it be easier just to turn the ets table into a list and traverse the list?

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

意犹 2024-10-10 21:14:27

一些建议:

  • 阅读 ETS 手册页:erl -man ets
  • ETS 表通过其名称(在 named_table 选项的情况下)或通过它的表 ID。将该信息传递给 gen_server 并将其保存在以下状态:

    -record(state, { ..., tbl = none }).
    
    
    init([表ID]) ->
        ...,
        {好的,#state { tbl = TableID }}。
    

ETS 可能不会节省那么多内存。稍后的 Erlang/OTP 版本将出现一个新标志,其中 ETS 表可以被压缩,因此它们的内容在存储之前被压缩,并在读取时解压缩(这会产生计算开销)。

要迭代 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) 速度非常快,因此您可以快速查找键。列表则不然。但另一方面,如果您总是遍历所有列表,这可能是一个更简单的解决方案(只要您不在进程之间传递大列表)。

也许应该避免将整个表变成一个列表并遍历它。您将在内存中生成列表,然后遍历它,这是昂贵的。最好一次遍历一点,这样实时内存量就会很低。

Some suggestions:

  • Read the ETS man page: erl -man ets
  • An ETS table is identified either by its name (in the case of the named_table option) or by its table id. Pass that information to the gen_server and keep it in the state:

    -record(state, { ..., tbl = none }).
    
    
    init([TableID]) ->
        ...,
        {ok, #state { tbl = TableID }}.
    

ETS will perhaps not save that much memory. There is a new flag coming up for a later Erlang/OTP release where ETS tables can be compressed so their contents are compressed before storage and uncompressed upon reads (there is a computational overhead to this).

To iterate through an ETS table you have several options. ets:first/1 ets:next/2 is one such interface. ets:foldl/3 ets:foldr/3 another. ets:match/3 gives you a continuation (a cursor) to walk with. ets:select is even more general than match.

Would it be easier to turn it into a list? This depends. The power of an ETS table is that they have an option {keypos, N} defining a key on which elements are stored. ets:lookup(?TAB, Key) is extremely fast so you have fast lookups on keys. It is not so with lists. But on the other hand, if you always traverse all of the list it may be a simpler solution (as long as you don't pass the large list between processes).

Turning the whole table into a list and traversing it should perhaps be avoided. You will generate the list in memory and then traverse it which is expensive. It is way better to traverse it a bit at a time so the amount of live memory is low.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文