`
DiaoCow
  • 浏览: 244195 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

Eralng ets学习总结

阅读更多
ets是什么?
ets是Erlang Term Storage的缩写,它是一个基于内存的KV Table,支持大数据量存储以及高效查询.

ets有4种类型的table:
settable中的每一个Value(Tuple)都是唯一,并且一个Key只能对应一个Value
ordered_set同set,唯一不同的是table中的Key是有序的
bagtable中的每一个Value都是唯一,但是一个key可以对应多个Value
duplicate_bagtable中每一个key可以对应多个Value,并且允许Value重复

那么table中的Key如何定义,Value又是什么呢?
table中的Value是一个tuple,而它的Key就是tuple中的第一个元素(默认),譬如,我往ets table插入一个{name, diaocow},那么Key就是name,Value就是{name, diaocow},于是就在ets table中建立了这么一条映射关系:name -> {name, diaocow}

这4种类型table有什么区别,查找效率又如何?
set, bag, duplicate_bag内部是采用哈希结构实现,因此查找效率很高,O(1);
ordered_set 内部是采用平衡树结构实现(Key之间是有序的),查找效率相比其他类型略低,是logN级别的;

至于选用何种类型的table,需要根据实际需求来确定,如果你需要元素之间有序,那么你只能选用ordered_sets(需要牺牲一点效率)

bag,duplicate_bag 虽然在查找效率上差不多,但是在插入元素时却有可能千差万别,为什么呢?
因为bag虽然允许table中每一个Key对应多个Value,但是它不允许这些Value重复,所以在插入具有相同Key的Value时,它必须与每一个现有元素作对比,而duplicate bag 允许table中的Value重复,所以它在插入时就完全不需要考虑这些,只管插,所以效率很高.

现在我们就来看看书上的一个例子,加上理解:


运行结果:


注意对于set和ordered_set 当插入具有相同Key的Value时,后插入的Value会替代上一个Value(譬如这里的{a,1}被{a,3}替代),另外在erlang的每一个node中,可以创建的ets table数量是有限的(默认为1440,不过我的测试结果确是2037???),这个值可以通过修改环境变量ERL_MAX_ETS_TABLES来修改(官方文档建议实际中采用的值比这个高些)

-------------------------------------------------------------------------------华丽分割线-------------------------------------------------------------------------------
现在我们重新回到刚才那个例子,来学习几个api:

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

set,ordered_set,bag,duplicate_bag指定创建的table类型
public,private,protected指定table的访问权限,若是public表示所有process都可以对该table进行读写(只要你知道TableId或者TableName),private表示只有创建表的process才能对table进行读写,而protected则表示所有的process都可以对表进行读取,但是只有创建表的process能够对表进行写操作(ps: ets table仅可以被同一个erlang node中的processes共享)
named_table若指定了named_table这个属性,就可以使用表名(也就是new函数的第一个参数Name)对表进行操作,而无需使用TableId
{keypos,Pos}上面说到,我们默认使用tuple中第一个元素作为Key,那么是否可以修改这个规则呢?自然可以,使用{keypos,Pos}即可,其中Pos就是表示使用tuple中第几个元素作为Key
{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}]作为默认值(关于write_concurrency和read_concurrency这个两个参数的具体含义自己不是特别的清楚,目前只是了解到该参数用于设置是否允许并发读或者写,和性能调优相关,所以暂时hold)

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是否相同呢?它分为matchcompare 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,3} 替换了老值{1, 2}(注意看tab2list方法),相关官方文档:
引用
Also worth noting is the subtle difference between matching and comparing equal, which is demonstrated by the different table types set and ordered_set. Two Erlang terms match if they are of the same type and have the same value, so that 1 matches 1, but not 1.0 (as 1.0 is a float() and not an integer()). Two Erlang terms compare equal if they either are of the same type and value, or if both are numeric types and extend to the same value, so that 1 compares equal to both 1 and 1.0. The ordered_set works on the Erlang term order and there is no defined order between an integer() and a float() that extends to the same value, hence the key 1 and the key 1.0 are regarded as equal in an ordered_set table.

3. ets:lookup(Tab, Key) -> [Object]
第一个参数Tab,不再解释,与insert函数中的一样,第二个参数就是需要查找的Key,它以list的形式返回符合条件的tuple(可以参看我们上一个例子代码),相关官方文档:
引用
In the case of set, bag and duplicate_bag, an object is returned only if the given key matches the key of the object in the table. If the table is an ordered_set however, an object is returned if the key given compares equal to the key of an object in the table. The difference being the same as between =:= and ==. As an example, one might insert an object with the integer() 1 as a key in an ordered_set and get the object returned as a result of doing a lookup/2 with the float() 1.0 as the key to search for.

If the table is of type set or ordered_set, the function returns either the empty list or a list with one element, as there cannot be more than one object with the same key. If the table is of type bag or duplicate_bag, the function returns a list of arbitrary length.

除了使用lookup来查找,ets还提供了一些更为强大的查找方法:

4.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值,那么查找起来非常快速(相当于索引查询),否则需要全表遍历

我们除了可以一次性查找出所有满足匹配的tuples,也可以采用"分页查询"的方式查询,即每次只查询出部分结果,然后通过迭代查找出所有结果:


其中:
5.match(Tab, Pattern, Limit) -> {[Match],Continuation} | '$end_of_table' 
用来返回table中满足匹配的tuples并且数量限制为Limit,返回值Continuation用来传递给match(Continuation) 方法进行下一次迭代,直到遍历完table(返回结尾标示:'$end_of_table'); Api文档中提到:用这种方式遍历表的效率高于first和next方法(这两个方法后面会提到)

最后我们来看下ets table的遍历
first(Tab) -> Key | '$end_of_table'
next(Tab, Key1) -> Key2 | '$end_of_table'
first方法用来返回table中第一个Key,而next方法返回table中在Key1后面的Key2,如果这是一张空表或者Key1已经是表的最后一个Key,那么first方法以及next方法将返回'$end_of_table'作为结尾标记,我们可以使用这组方法对一个table的Key进行遍历:


另外对于ordered_set类型table,它的Key本身就是有序的(因为它内部采用平衡树结构,按照Erlang Term Order排列),所以在遍历ordered_set类型table时,它的Key会按Erlang Term Order输出,而对于其他类型的table,遍历table时Key的顺序是不确定的;

last(Tab) -> Key | '$end_of_table'
prev(Tab, Key1) -> Key2 | '$end_of_table'
这组遍历方式和first/last基本相同,唯一不同的是,它是从后往前遍历

至此我想大家已经基本了解了:
1.ets table的类型分类
2.ets table的创建
3.ets table的插入和查找
4.ets table的遍历

-------------------------------------------------------------------------------华丽分割线-------------------------------------------------------------------------------

ets其他一些细节:
1.官方文档中提到: In the current implementation, every object insert and look-up operation results in a copy of the object,这是什么意思呢?
意思是,在当前erlang的实现版本中,插入一个tuple:会从当前process中的stack和heap拷贝tuple的一副副本到ets table中去,同样查询操作也会导致从表中拷贝一份tuple(或多个tuples)到执行查询的process的stack和heap中去,这种行为适用于erlang所有的数据类型,除了binaries;

2.ets table是不会被垃圾回收的,只有当下面两种情况它会被销毁:
a.调用delete方法;
b.创建ets table的process结束;

3.关于ordered_set类型table,它的内部元素根据Key值按照Erlang Term Order排序,那么Erlang Term Order是什么呢?
a.如果比较的两个值不是同一种数据类型,则按照这种规则比较:number < atom < reference < fun < port < pid < tuple < list < bit string
b.如果比较的两个值都是List,那么它会逐个比较其中元素;
3.如果比较的两个值都是Tuple,那么它首先会比较Tuple Size是否相同(即元素个数),若Size相同则逐个比较其中的元素;



关于ets更详细内容,请参看文档:http://www.erlang.org/doc/man/ets.html



  • 大小: 22 KB
  • 大小: 7.9 KB
  • 大小: 23.4 KB
  • 大小: 11.8 KB
  • 大小: 27.6 KB
  • 大小: 8.4 KB
  • 大小: 20.8 KB
  • 大小: 11.8 KB
  • 大小: 13.8 KB
  • 大小: 9.8 KB
  • 大小: 10.2 KB
分享到:
评论

相关推荐

    ETS5 版本ETS5.7.5(官网下载)

    ETS5,全称为Engineering ToolSoftware 5,是KNX协会官方推出的一款专业级的智能建筑控制系统编程工具。这款软件主要用于设计、配置、调试以及维护基于KNX标准的智能家居和楼宇自动化系统。版本5.7.5是ETS5的一个...

    ETS 5.6.6 学习工具

    ETS 5.6.6 学习工具是针对软件或插件领域的一个特定版本,它提供了丰富的学习资源和功能,帮助用户深入理解相关技术。这个和谐版是为教育和自我提升设计的,强调非商业使用,并鼓励用户在商业环境中选择官方正版支持...

    ETS5 最新调试教程视频

    ETS5(Engineering Tool Software Version 5)是KNX协会推出的一款强大的工程工具软件,用于设计、配置、调试和诊断基于KNX技术的智能建筑控制系统。KNX是一种国际标准(ISO/IEC 14543-3)的楼宇自动化通信协议,...

    ETS5 中文免费 试用

    对于中国用户来说,中文界面大大降低了学习和使用的难度,使得工程师和技术人员能够更方便地理解和操作软件的各项功能。同时,提供免费更新服务对于老用户来说是一个非常友好的政策,他们可以无须购买新的加密狗就能...

    ETS300_364手册

    ETS300_364手册是一份详尽的文档集合,主要针对ETS300与ETS364测试机的使用和...通过仔细阅读并理解这份ETS300_364手册,用户不仅能掌握测试机的基本操作,还能深入学习到电子测试领域的专业知识,提高测试效率和质量。

    ets 中文教程

    #### 总结 通过本教程,我们深入了解了使用ETS进行KNX智能家居系统设计的基本流程,包括项目创建、设备加载与配置、参数设置以及组态配置等核心环节。这些步骤不仅构成了智能家居项目的基础,也是实现设备互联、...

    ETS 5.6.6 和谐版

    这个版本主要是为教育和学习目的而设计的,提醒用户在商业环境中应使用官方正版软件,以确保合法性和获得全面的技术支持。 KNX(欧洲安装技术)是一种国际标准(ISO/IEC 14543-3),广泛应用于建筑自动化,包括智能...

    KNX调试软件ETS3附使用说明书.zip

    ETS3(EIB Tool Software...通过深入学习和实践,ETS3不仅能使初学者掌握KNX系统的基本操作,还能帮助专业人士实现复杂系统的优化设计。结合实际的KNX设备,如海格的设备,用户可以全面了解和掌握KNX系统调试的全过程。

    ets5.5.4中文版

    Ets5 V5.5.4简体中文版下载。Ets5 V5.5.4简体中文版下载。Ets5 V5.5.4简体中文版下载。Ets5 V5.5.4简体中文版下载。

    KNX编程软件 ETS5 专业版本 5.7.2

    **总结** ETS5 5.7.2是KNX编程的必备工具,其丰富的功能和友好的中文界面使其在中国市场备受青睐。对于从事智能家居或楼宇自动化工作的工程师和爱好者来说,掌握这款软件的使用技巧,将极大地提升工作效率,并确保...

    ETS v5.7.2 中文演示版(支持5个项目的设备)

    ETS,全称是Engineering ToolSoftware,是由KNX协会开发的一款专业工具,用于设计、配置以及调试基于KNX技术的智能建筑控制系统。ETS v5.7.2 是该软件的一个特定版本,它支持最多5个项目的设备配置,适用于中小型的...

    Ets5 v5.5.2.rar

    ETS5(KNX Engineering Tool Software)是KNX协会推出的一款专业的智能家居控制系统编程软件,主要用于设计、配置、调试和诊断基于KNX技术的智能建筑系统。KNX是一种国际标准(ISO/IEC 14543-3),广泛应用于楼宇...

    KNX编程软件 ETS5 Professional 版本 5.7.4(官网下载)

    8. **培训与学习资源**:作为一款专业软件,ETS5通常会配备详尽的在线帮助文档、教程和示例项目,帮助初学者快速上手,并持续为经验丰富的用户提供参考资料。 总的来说,ETS5 Professional 5.7.4是KNX系统开发与...

    KNX编程软件 ETS5 Professional 版本 5.7.6

    6. **培训和学习资源**:ETS5通常包含丰富的教程和帮助文档,对于初学者和专业人士来说都是宝贵的参考资料。 7. **数据安全与备份**:版本5.7.6可能增强了数据安全措施,并提供项目备份功能,保护用户的工作成果不...

    ETS 操作手册

    用户可以通过该文件快速查找并学习ETS系统的具体操作方法。 综上所述,ETS操作手册是制衣行业从业人员的得力助手,通过深入理解和熟练运用手册中的知识,可以提升工作效率,优化生产流程,实现更有效的业务管理。

    ETS 5.6.5安装文件包

    ETS(Engineering ToolSet)是KNX协会开发的专业工具,用于设计、配置和调试基于KNX技术的楼宇自动化系统。KNX是一种国际标准(ISO/IEC 14543-3),在智能建筑领域广泛应用,它允许集成照明、温控、遮阳、安全和能源...

    ETS最新版软件仿真软件

    ETS(Engineering ToolSet)是KNX协会官方推出的专业软件,用于设计、配置和调试基于KNX/EIB(欧洲安装总线)智能家居控制系统。这个“ETS最新版软件仿真软件”是针对KNX系统的最新版本,旨在提供高效且精确的工程...

    KNX编程软件 ETS5 Professional 版本 5.6.6(官网下载)

    **ETS5 Professional 5.6.6:KNX编程的核心工具** ETS5(Engineering Tool Software)是KNX协会官方推出的编程软件,专为KNX智能建筑控制系统设计。它提供了全面的功能,让专业工程师能够设计、配置、调试和诊断...

    ETS(PHP模板系统)

    通过以上知识点的学习和实践,开发者可以充分利用ETS的特性,构建出高效且易于维护的PHP应用程序。在实际开发过程中,应结合项目需求和团队习惯,灵活运用ETS提供的工具和方法,从而提高开发效率和代码质量。

    ETS3安装使用说明1

    ### ETS3安装使用说明详解 #### 一、软件安装 **1.1 安装启动** - **启动安装:** 打开`Ets30f`文件夹,找到并运行`Ets3ProSetup.exe`来启动安装过程。 **1.2 语言设置** - **语言选择:** 在出现的语言选择...

Global site tag (gtag.js) - Google Analytics