Elang之ETS系列函数功能与用法详解

最常用函数:

new(Name, Options) -> tid() | atom()

新建一个表名为Name的ETS表,并返回表的一个标识符。  

  Types:

                 Name = atom()

                 Options = [Option]

                 Option = Type | Access | named_table | {keypos,Pos} | {heir,pid(),HeirData} | {heir,none} | Tweaks

                 Type = set | ordered_set | bag | duplicate_bag

                 Access = public | protected | private

                 Tweaks = {write_concurrency,boolean()} | {read_concurrency,boolean()} | compressed

                 Pos = integer()

                 HeirData = term()



tab2list(Tab) -> [Object]

 返回一个ETS表的所有对象数据的列表     

Types:

           Tab = tab()

          Object = tuple()

增/插入:

insert(Tab, ObjectOrObjects) -> true

向ETS表Tab中插入一个或一个对象列表数据ObjectOrObjects,如果是set类型和orderen_set类型的表,插入的数据和表里的数据有相同的键值,则旧数据会被替换:

insert_new(Tab, ObjectOrObjects) -> boolean()

与insert/2类似,但当插入的对象是一个列表,则在插入数据前,将检测列表里的每一个键,如果有和表中键值相同的则不插入任何数据对象:

删/删除:

delete(Tab) -> true

     Types:

          Tab = atom() |tid()

删除整个Tab表:

delete(Tab, Key) -> true

     Types:

          Tab = atom() | tid()

          Key = trem()

从Tab表中删除所有以Key为键的对象

例如:

Tab = ets:new(test_ets_new, [set, named_table]),
ets:insert(Tab, [{a, 1, 1}, {b, 2, 2}]),
ets:delete(Tab,c).

结果为:true

为了确认是否已经删除我们可以执行ets:tab2list(Tab). 可以看到返回结果是 :[{b,2,2}] 说明确实已经删除了。


delete_all_objects(Tab) -> true

     Types:

          Tab = atom() | tid()

删除Tab中的所有对象,该操作会保持数据的原子性和独立性

delete_object(Tab, Object) -> true

删除与Object精确匹配的对象,只有键值相同,但其他有不匹配的对象不会被删除(这对于Bag类型的表非常有用,在duplicate_bag表中,所有匹配的对象都会被删除)。

例子1:

TableId = ets:new(test_ets_new, [named_table, bag]),
ets:insert(TableId, [{a, 1}, {b, 2}, {a, 3}, {c, 4}]),
ets:delete_object(TableId, {a, 3}),
ets:tab2list(TableId).

结果: [{c,4},{b,2},{a,1}]

例子2:

TableId = ets:new(test_ets_new, [named_table, duplicate_bag]),
ets:insert(TableId, [{a, 3}, {b, 2}, {a, 3}, {c, 4}]),
ets:delete_object(TableId, {a, 3}),
ets:tab2list(TableId).

结果:[{c,4},{b,2}]

修改/更新

update_element(Tab, Key, ElementSpec :: {Pos, Value}) -> boolean().

update_element(Tab, Key, ElementSpec :: [{Pos, Value}]) -> boolean().

更新ETS表Tab里键为Key的对象数据的第Pos个元素数据的值更改为Value。可一次更改一个键的多个Pos

Types:

                Tab = tid() | atom()

                Key = Value = term()

                Pos = integer()

例:

Tab = ets:new(test_ets_new, [set, named_table]),
ets:insert(Tab, [{a, 1, 1}, {b, 2, 2}]),
ets:update_element(Tab, a, {2, 100}),
ets:tab2list(Tab).

结果:[{b,2,2},{a,100,1}]

一次修改多个位置:

Tab = ets:new(test_ets_new, [set, named_table]),
ets:insert(Tab, [{a, 1, 1}, {b, 2, 2}]),
ets:update_element(Tab, a, [{2, 100}, {3,10}]),
ets:tab2list(Tab).

结果:[{b,2,2},{a,100,10}]

查/查找

lookup(Tab, Key) -> [Object]

返回表Tab里键为Key的所有对象数据的列表,如果是ordered_set则键1.0 与 1相等。

例子1:


ets:new(test_ets_new, [set, named_table]),
ets:insert(test_ets_new, [{a, 1}, {b, 2}]),
ets:lookup(test_ets_new, a).

结果:[{a,1}]

例子2:


ets:new(test_ets_new, [ordered_set, named_table]),
ets:insert(test_ets_new, [{1, 1}, {2, 2}]),
ets:lookup(test_ets_new, 2.0).

结果:[{2,2}]

例子3:


TabId = ets:new(test_ets_new, [duplicate_bag, named_table]),
ets:insert(TabId, [{a, 1}, {b, 2}, {a, 3}]),
ets:lookup(TabId, a).

结果: [{a,1},{a,3}]

lookup_element(Tab, Key, Pos) -> Elem如果表的类型是 set 或 ordered_set,那么该函数将返回键为 Key 的对象的第 Pos 个元素。如果表的类型是 bag 或 duplicate_bag,那么该函数将返回键为 Key 的对象的第 Pos 个元素的列表。如果表里没有键为 Key 的对象,函数将以 badarg 的原因退出。

例子1:set类型表:

ets:new(test_ets_new, [set, named_table]),
ets:insert(test_ets_new, [{a, 1}, {b, 2}]),
ets:lookup_element(test_ets_new, a, 2).

结果:1

例子2:duplicate_bag类型表:


ets:new(test_ets_new, [duplicate_bag, named_table]),
ets:insert(test_ets_new, [{a, 1}, {b, 2}, {a, 3}]),
ets:lookup_element(test_ets_new, a, 2).

结果:[1,3]

member(Tab, Key) -> true | false 判断表里是否存在指定键的数据:

TableId = ets:new(test_ets_new, [named_table, set]),
ets:insert(TableId, [{a, 1}, {b, 2}, {c, 3}]),
ets:member(TableId, b).

结果:true

模式匹配相关函数(同样会有增删改查):

fun2ms(LiteralFun) -> MatchSpec

把语法函数转为匹配规范的伪函数,例子:

ets:fun2ms(fun({M, N}) when N > 3, is_atom(M) -> M end).

结果:[{{'$1','$2'},[{'>','$2',3},{is_atom,'$1'}],['$1']}]

查/匹配查找

select(Tab, MatchSpec) -> [Match]

使用一个匹配描述从表Tab中匹配对象。MatchSpace是一个含有三个参数的元组元素: 第一个元素是ets:match/2的文档中描述的模式,第二个参数是含有多个断言测试的列表,第三个是包含关于实际返回值描述的列表。简单来说  第一个参数是传入的已知变量,第二个参数是判断条件,第三个参数是返回结果。返回值的结构使用 MatchHead 所绑定的 "match variables",或者使用特殊的匹配值 '$_'(整个匹配对象)和 '$$'(包含所有匹配值的列表):

Types:

          Tab = tid() | atom()

          Match = term()

          MatchSpec = match_spec()

例子1(返回值为‘$$’):

Tab = ets:new(test_ets_new, [private]),
ets:insert(Tab, [{a, 1}, {b, 2}]),
ets:select(Tab, [{{'$1', '$2'}, [], ['$$']}]).

结果:[[b,2],[a,1]]

例子2(返回值为‘$_’):

Tab = ets:new(test_ets_new, [private]),
ets:insert(Tab, [{a, 1}, {b, 2}]),
ets:select(Tab, [{{'$1', '$2'}, [], ['$_']}]).

结果:[{b,2},{a,1}]

例子3 (返回MatchHead所绑定的“match variables”):

Tab = ets:new(test_ets_new, [private]),
ets:insert(Tab, [{a, 1}, {b, 2}]),
ets:select(Tab, [{{'$1', '$2'}, [], ['$1']}]).

结果:[b,a]

例子4 ( 未弄明白为什么返回的是[2,1]):

Tab = ets:new(test_ets_new, [private]),
ets:insert(Tab, [{a, 1}, {b, 2}]),
ets:select(Tab, [{{'$1', '$2'}, [], ['$1', '$2']}]).

结果:[2,1]

select(Tab, MatchSpec, Limit) -> {[Match], Continuation} | '$end_of_table'用法和ets:select/2相似,只是返回限定数量(limit)的匹配对象数据。Continuation项可以在后续的ets:select/1调用中获取下一组匹配的对象数据。速度比ets:first/1 和ets:next/1逐个方位对象更快。

Types:

             Tab = tid() | atom()

             Match = term()

             MatchSpec = match_spec()

             Continuation = term()

select(Continuation) -> {[Match], Continuation} | '$end_of_table'

继续从ets:select/3开始的匹配,下一次匹配到的限定数量Limit的对象数据将与心得Continuation一起返回。心得Continuation 将会在后续调用该函数时被使用。

Types:

             Match = term()

             Continuation = term()

select_reverse(Tab, MatchSpec) -> [Match] 跟 ets:select/2 一样,都是根据匹配规范匹配表里的对象数据,不过如果是 ordered_set 类型的 ETS 表的话会返回一个倒序的列表,其他类型的表返回的值跟 ets:select/2 一样。

Types:

              Tab = tid() | atom()

              Match = term()

              MatchSpec = match_spec()

select_reverse(Tab, MatchSpec, Limit) -> {[Match], Continuation} | '$end_of_table'与select_reverse/2的关系就像 selet/2 和selet/3的关系:

Types:

                Tab = tid() | atom()

                Match = term()

                MatchSpec = match_spec()

                Continuation = term()

select_reverse(Continuation) ->{[Match], Continuation} | '$end_of_table'
Types:

                    Match = term()

                    Continuation = term()

删除:

select_delete(Tab, MatchSpec) -> NumDeleted

根据匹配模式删除表里的对象数据

Types:

               Tab = tid() | atom()

               Object = tuple()

               MatchSpec = match_spec()

               NumMatched = integer()

不常用的匹配函数:

is_compiled_ms(Term) -> boolean()

检测一个 Erlang 数据是否是一个有效已编译的匹配规范:

match(Continuation) -> {[Match], Continuation} | '$end_of_table'

match(Tab, Pattern) -> [Match]

根据匹配模式 Pattern 匹配 ETS 表 Tab 里的对象数据。一个匹配模式也许包含的项值有:绑定部分(Erlang 项),'_' 可以匹配任何 Erlang 项,和匹配变量:'$N'(N>=0)函数将返回一个匹配每个对象数据的元素的列表,每个元素是一个绑定变量模式的有序列表:

Types:

    Tab = tid() | atom()

    Pattern = tuple()

    Match = [term()]

match(Tab, Pattern, Limit) -> {[Match], Continuation} | '$end_of_table'参考select/2与

Types:

                        Tab = tid() | atom()

                        Pattern = tuple()

                        Match = [term()]

                        Continuation = term()

match_delete(Tab, Pattern) -> true根据匹配模式删除表里的对象数据

Types:

    Tab = tab()

    Pattern = match_pattern()

一些不常用的函数:

all() -> [Tab]

返回当前节点中所有的ets表组成的列表。如果表有命名返回表名,否则返回表的标识符

i() -> ok

在输出端上打印显示所有的ETS表的信息

i(Tab) -> ok

在输出端上打印显示指定ETS表Tab的信息

     Types:

          Tab = atom() | tid()

info(Tab) ->  [{Item, Value}] | undefined返回一个以{Item, Value}元祖形式的列表的ETS表的信息。如果没有找到表则返回undefined,如果Tab不是一个表,则返回bagarg:

Tab = tid() | atom()

               Item = atom(), see below

               Value = term(), see below

info(Tab, Item) -> Value | undefined 返回给出的跟表Tab相关的项Item的信息。如果没有找到表则返回undefined,如果Tab不是一个表或者Item是一个无效值,则返回bagarg:

rename(Tab, Name) -> Name

给一个已命名的ETS表Tab重命名一个新的名字Name

first(Tab) -> Key | '$end_of_table'

返回ETS表Tab中的第一个对象数据的键。例子:

ets:new(test_ets_new, [set, named_table]),
ets:insert(test_ets_new, [{a, 1}, {b, 2}]),
ets:first(test_ets_new).

结果:a

last(Tab) -> Key | '$end_of_table' 如果类型是 ordered_set,则返回 Erlang 项顺序的最后一个键将被返回;如果是其他类型的表,该函数的处理跟 ets:first/1 一样

ets:new(test_ets_new, [ordered_set, named_table]),
ets:insert(test_ets_new, [{a, 1}, {b, 2}]),
ets:last(test_ets_new).

结果:b

next(Tab, Key1) -> Key2 | '$end_of_table' 返回表里紧随键Key1的下一个键Key2. 除ordered_set之外的类型的表,如果有并发更新了表,遍历将失败,除非使用ets:safe_fixtable/2函数对表进行保护锁定。

prev(Tab, Key1) -> Key2 | '$end_of_table'

返回在表里跟键 Key1 紧随的上一个键 Key2。如果是 ordered_set 类型的表,返回的是 Erlang 项顺序的前一个键将被返回;如果是其他类型的表,该函数的处理跟 ets:next/2 一样

Types:

              Tab = tid() | atom()

              Key1 = Key2 = term()

foldl(Function, Acc0, Tab) -> Acc1 n对ETS表数据进行循环遍历操作,规则和lists:foldl/3一样 

   Types:

      Function = fun((Element :: term(), AccIn) -> AccOut)

             Tab = tab()

             Acc0 = Acc1 = AccIn = AccOut = term()

例子:

Tab = ets:new(ets_tab, [named_table, set]),
ets:insert(Tab, [{a, 1}, {b, 2}, {c, 3}, {d, 4}, {e, 5}]),
ets:foldl(fun({_Key, Val}, AccVal) ->
    AccVal + Val
end, 0, Tab).

结果:15

foldr(Function, Acc0, Tab) -> Acc1 和ets:foldl/3一样,对ETS表进行遍历,区别是从表末端开始向前遍历

Types:



             Function = fun((Element :: term(), AccIn) -> AccOut)

            Tab = tab()

            Acc0 = Acc1 = AccIn = AccOut = term()

 例子:

Tab = ets:new(ets_tab, [named_table, set]),
ets:insert(Tab, [{a, 1}, {b, 2}, {c, 3}, {d, 4}, {e, 5}]),
ets:foldr(fun({_Key, Val}, AccVal) ->
    AccVal + Val
end, 0, Tab).

结果:15

一些很少用到的函数:

 safe_fixtable(Tab, Fix) -> true 锁定一个类型是 set,bag 或 duplicate_bag 的表,使其可以安全遍历表里的数据

Types:

     Tab = tid() | atom()

     Fix = boolean()

give_away(Tab, Pid, GiftData) -> true 让进程Pid成为表Tab的新的拥有者。

     Types:

        Tab = tid() | atom()

         Pid = pid()

         GiftData = term()

setopts(Tab, Opts) -> true 设置表的选项。目前可以在表创建后设置的选项只有heir,调用进程必须是表的所属进程。

update_counter(Tab, Key, X3 :: [UpdateOp], Default) -> [Result].

update_counter(Tab, Key, Incr) -> Result.

update_counter(Tab, Key, Incr, Default) -> Result.

更新ets中的数据,省去了从ets中“查找对象->更新对象数据->再插入新的对象”的过程:

Types:

             Tab = tid() | atom()

             Key = term()

             UpdateOp = {Pos,Incr} | {Pos,Incr,Threshold,SetValue}

             Pos = Incr = Threshold = SetValue = Result = integer()

文件转换为tab

tab2file(Tab, Filename) -> ok | {error, Reason} 将Tab表导出道文件Filename,等同于table2file(Tab, Filename, [])

     Types:

          Tab = atom() | tid()

          Filename = file:name()

          Reason = term()

tab2file(Tab, Filename, Options) -> ok | {error, Reason} 将Tab表到处导文件Filename。导表时,一些关于表的必须的信息被导到头部,这些信息包括表的类型,名字,访问权限,大小,版本和是否是已命名表,同事还有关于教导文件中的一些扩展信息相关的注释,这些可以使文件中的对象数或者是头部和文件中record的MD5值。如果标的访问权限是public并且在导表的过程中有田间或删除的对象,头部的大小字段值可能与实际的对象数不一致。public权限的表在导表时有更新,并且想在从文件中读取表时核对,则扩展信息中至少要有一个字段给读取和核对进程提供依据。

     Types:

          Tab = atom() | tid()

          Filename = file:name()

          Options = [Option]

          Options = {extended_info, [ExtInfo]} | {sync, boolean()}

          ExtInfo = md5sum | object_count

          Reason = term()

扩展信息选项指出有哪些扩展信息被写到了文件中:

object_count  实际写入文件的对象数量写在了文件的尾部,因此即使在导表时有更新表,也可以核对。

md5sum 头部和表中的对象使用内建的MD5函数来校验.所有对象的MD5值写在文件的尾部,所以读取时的校验可以发现文件中的数据微小的比特级的反转。使用该选项将要耗费适量的CPU时间。

注:一旦使用了扩展信息选项,将导致ets版本早于stdlib-1.15.1的文件无法读取.

file2tab(Filename) -> {ok, Tab} | {error, Reason} 读取一个由tab2file/2 或 tab2file/3生成的文件并创建对应的表,与file2tab(FileName, [])等效。

Types:

     Filename = file:name()

     Tab = tab()

     Reason = term()

file2tab(Filename, Options) ->  {ok, Tab} | {error, Reason} 

     Types:         

          Filename = file:name()

          Tab = atom() | tid()

          Options = [Option]

          Option = {verify,boolean()}

          Reason = term()

      读取一个由tab2file/2 或 tab2file/3生成的文件并创建对应的表。目前支持的选项只有{verify, boolean()}.如果检验打开(也就是设置为{verify, true}),该函数将利用文件中的所有信息来断定数据是否被损坏,实现方式依赖于调用tab2file/3时写入extended_info的信息。如果文件中没有extended_info数据,但却设置了{verify,true},写入对象的数量将依赖于转储时原始表的大小。

       如果在表是公共的并且在转储时有对象被删除或插入,将使得检验失败。为了避免这个问题,不要检验在转储的同时有更新的文件,或者在调用tab2file/3时使用{extended_info, [object_count]},这将会把实际写入的对象数记录到文件中。

       如果开启检验并且转储时使用{extended_info, [md5sum]}选项,在读取文件时将会比其他情况慢,消耗更多的CPU时间。

Options的默认值为{verify,false}.

tabfile_info(Filename) -> {ok, TableInfo} | {error, Reason} 返回通过tab2file/2或tab2file/3导入文件的标的信息

转载于:https://www.cnblogs.com/ACshasow/p/7000102.html

你可能感兴趣的:(大数据)