首页 > 解决方案 > bag ETS 在 tab2list 中的排序是什么?

问题描述

我在玩bag桌子:

30> W = ets:new(w, [bag]).
#Ref<0.616284823.3413770252.143386>
31> ets:insert(W, [{1, a}, {2, a}, {1, b}, {2, b}, {a}, {b}]).
true
32> ets:tab2list(W).
[{1,a},{1,b},{b},{a},{2,a},{2,b}]

我完全不明白这里的订购是如何工作的。为什么最小的元组在中间?它们如何大于{1,_}但小于{2,_}


编辑:示例中的结果来自 OTP21

标签: erlangets

解决方案


根据ets:lookup/2的文档:

对象插入的时间顺序被保留。

这意味着当插入两个具有相同键的元组时,它们的顺序由插入时间决定。我不知道这是否也适用于ets:tab2list/1. 无论如何,这是唯一的保证。而且,您的结果似乎与 ONE 保证一致。

我查看了 的源代码ets:tab2list/1,它调用了ets:first/1--not ets:lookup/2ets:first/1的文档说:

对于ordered_set 表,返回Erlang term order 中的第一个键。对于其他表类型,根据表的内部顺序返回第一个键。

因为ordered_set提到了从an返回键的顺序,但是从a返回的键的顺序bag据说是“按照表的内部顺序”,我认为你不能指望在ets:first/1返回键任何订单。因此,您必须将返回的列表tab2list/1视为无序的。

而且,直接从 rvirding 自己:

使用 set、bag 或 duplicate_bag 获取密钥的顺序是内部的。这与您是否使用match,selectfirstand无关next。我指的是在执行 a 时返回的 bag 或 duplicate_bag 中一个键的元素的顺序lookupmatch 或者select[保留对象插入的时间顺序;使用指定键插入的第一个对象是结果列表中的第一个,依此类推。]

[否则,] 键的内部顺序未定义,您永远不能依赖它,因为正如您所说,它可以在版本之间更改。当然除了定义排序的类型 ordered_set 。

https://elixirforum.com/t/retrieval-in-ets/10413/2


推荐阅读