erlang学习笔记之深入了解ets

一、类型

4种类型

set   :table中的每一个Value(Tuple)都是唯一,并且一个Key只能对应一个Value
ordered_set  :同set,唯一不同的是table中的Key是有序的
bag  :table中的每一个Value都是唯一,但是一个key可以对应多个Value
duplicate_bag  :table中每一个key可以对应多个Value,并且允许Value重复

set是默认类型,ordered_sets是唯一有序的

bag,duplicate_bag 虽然在查找效率上差不多,但是在插入元素时差距缺非常大

因为bag虽然允许table中每一个Key对应多个Value,但是它不允许这些Value重复,所以在插入具有相同Key的Value时,它必须与每一个现有元素作对比,

而duplicate_bag 允许table中的Value重复,所以它在插入时就完全不需要考虑这些,只管插,所以效率相对于bag来说很高. 

测试:

ordered_set 

可以看出ordered_set有着 set的特性,同时会自动排序

bag  

duplicate_bag

通过测试进行对比,可以很明显看出bag 和duplicate_bag的区别,一个允许重复,一个不允许重复

二、常见api

1.ets:new(Name, Options) -> tid() | atom()  

这个函数用来创建一个名为Name的table(若创建成功,返回一个TableId或者TableName供process引用);Options是一个选项list,用来指定创建table的各种属性,它的值有: 

1.set,ordered_set,bag,duplicate_bag:指定创建的table类型。

2.public,private,protected:指定table的访问权限,若是public表示所有process都可以对该table进行读写(只要你知道TableId或者TableName),private表示只有创建表的process才能对table进行读写,而protected则表示所有的process都可以对表进行读取,但是只有创建表的process能够对表进行写操作(ps: ets table仅可以被同一个erlang node中的processes共享)。

3.named_table:若指定了named_table这个属性,就可以使用表名(也就是new函数的第一个参数Name)对表进行操作,而无需使用TableId。

4.{keypos,Pos}:默认使用tuple中第一个元素作为Key,,使用{keypos,Pos}可选择第几个元素作为Key其中Pos就是表示使用tuple中第几个元素作为Key。

5.{heir, Pid, HeirData},{heir,none}:这个heir属性指明当创建table的process终止时,是否有其他process来继承这个table,默认值是{heir,none},表示没有继承者,所以当创建表的process终止时,表也随之被delete;若我们指定了{heir,Pid,HeirData},那么当创建表的process终止时,process identifer为Pid的process将会收到一个消息:{'ETS-TRANSFER',tid(),FromPid,HeirData},这样表的拥有权就转交了

如果你不指定任何Options(即参数值为[]),那么ets将会使用[set, protected, {keypos,1}, {heir,none}, {write_concurrency,false}, {read_concurrency,false}]作为默认值 。

2. ets:insert(Tab, ObjectOrObjects) -> true 

这个函数是用来往table里插入数据,其中第一个参数Tab表示需要操作哪一张表,它可以是TableId或者TableName(若创建表时指定了named_table选项),

第二个参数ObjectOrObjects表示需要插入的数据,它可以是一个tuple或者是一个tuple list;注意这个insert方法是一个原子操作,并且对于set或者ordered_set类型table,在插入具有相同Key的Value时,会用新值去替换老值; 

ets判断两个Key是否相同,它分为 match 和 compare equal  两种情况: 

1.如果两个Key(erlang term)match,那么这两个Key不仅值相同,类型也相同; 
2.如果两个Key (erlang term)compare equal, 那么只需要这两个Key的值相同,而无需类型相同(譬如 1.0 compare equal 1,但是1 not match 1.0) 

所以若两个Key match,则它们一定compare equal,反过来则不行,那在ets中到底是采用match还是compare equal进行判断与table的类型有关,其中ordered_set采用compare equal方式匹配,其余类型都采用match方式匹配

这是一个set类型table,所以在比较Key时采用match方式进行匹配(既比较类型也比较值),所以它认为1.0和1是两个不同的Key,因此插入了两个Tuole



对于ordered_set类型table,它采用compare equal方式进行匹配(仅比较值),所以它认为1.0和1是两个相同的Key,因此用新值{1.0,1} 替换了老值{1, 1}

3.match(Tab, Pattern) -> [Match]  

该方法用来查找table中所有匹配Pattern的tuple并返回tuple中某些或全部元素(这个由pattern指定)

其中Pattern可以包含以下字符 
1.一个绑定变量或者任意Erlang Term; 
2.一个占位符'_',可以匹配任何Erlang Term; 
3.一个变量符'$N' (N可以为0,1,2,3....),该变量指定了match方法需要返回tuple中哪些元素; 

若Pattern中包含Key值,那么查找起来非常快速(相当于索引查询),否则需要全表遍历 

测试

match与match_object,select的对比

用法:

match:获取 ets 存储数据结构的某几个数据集合。

match_object:1.获取 ets 存储的符合条件的整个结构,只能支持直接值匹配                                                           2.迭代的遍历整个 ets 列表 match_object/3                                                                                       3.查找指定数据的 ets 列表 match_object/2

select:一般用于条件判定来筛选符合条件的数据和指定格式 (>=, =/=,<,=< 等)

效率对比:

select效率较前两个较为慢一些,特别是 ets 中 key 的查找,效率就更慢了,能用 match_object 的就不要用 select

match函数使用特殊的元组语法(match_pattern)来决定返回什么。

select函数使用特殊的元组语法(match_spec),它是match_pattern的超集,能够指定保护并从结果集中提取元素(而不仅仅是返回匹配的密钥)。

select将match_spec编译成匿名函数,加快运行速度

为此功能提供警卫的能力比仅使用match_pattern(因为它们将首先运行)更快地消除误报。
从结果集中提取元素的能力可以节省您以后必须完成的工作,而不是迭代返回的键来提取数据。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值