上星期的Erlang Thursday我们继续研究 ets:select/2 并且用 ets:fun2ms/1生成匹配规则来和它配合使用。
这个星期我们将看看ets模块提供的select函数的其它版本。
还是老样子,我们将设置好我们新的ETS表的环境,以便我们的shell崩溃了我们的表不会丢失。
|
|
接下来我们将装载我们的测试ETS表,它是一些测试“产品”。为了例子的简单,我们将仅用一个数字代表一个产品id,然后用一个100以内的随机整数加上0.99作为价格。
|
|
我们将创建一个匹配规则(价格在19.99至30之间)来查找数据。
|
|
如果我们用 ets:select/2 和上面这个匹配规则在我们的表上,我们在一个查询里得到所有结果就和前面我们看到的一样。
|
|
不过ets模块也给我们一个限制结果集的方式如果我们愿意的话,用 ets:select/3 并传入一个要一次返回结果数的限制。
那么我们来用 ets:select/3 并给它的限制是10,然后看看结果是什么。
|
|
我们的结果是一个元组而不是一个结果的列表。第一个元组元素是一个我们期望的10个结果组成的列表,第二个元素是一个奇怪的元组,我们查阅官方文档中 ets:select/3 的描述,这个奇怪的元组表示一个概念:continuation 。
所以我们再运行我们的查询,这次我们把结果绑定到变量。
|
|
现在我们有了这个continuation,不过它是什么?它对我们来说有什么用?
简而言之,它可以被认为是一个不可变的书签。它不仅表示我们在查询结果的哪一页,也表示我们正在读的内容(我们的查询)。
它允许我们把这个continuation传给 ets:select/1 ,就能快速获取我们前面看过的结果内容。
|
|
因为它是我们的特殊的不可变的书签,每次我们用这个书签它都带我们到这同样书的相同的地方,并且我们仅能读到我们原先设置的每页最大纪录数。
所以不管我们在我们同一个continuation上调用多少次 ets:select/1 ,每次我们都将获得相同的结果。
|
|
而如果我们仔细看结果的元组,我们看到得到一个不同的下一个continuation的元组。
|
|
我们可以用这个新的continuation用在我们下一次调用 ets:select/1 上,来得到下一个结果集和另一个continuation。
|
|
如果我们在获取完结果集后再执行一次查询,我们得到一个 ‘$end_of_table’ 原子。
|
|
指定一个限制并有一个continuation的能力也可以用在 ets:match/3 和 ets:match/1 上,同时也可以用在 ets:match_object/3 和 ets:match_object/1 上。
下星期,我们将继续研究ets模块里的不同select函数,同时看看它们的行为方式和有序集合,将比较一下 select 函数和 select_reverse函数的不同,也研究一下如果我们当我们用一个continuation的时候在结果集里插入一些数据,continuation将会怎样。
原文链接: https://www.proctor-it.com/erlang-thursday-using-ets-select-with-a-limit/