zoukankan      html  css  js  c++  java
  • 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'
    Types:
                  Tab = tid() | atom()
                  Key1 = Key2 = term()
    返回在表里跟键 Key1 紧随的上一个键 Key2。如果是 ordered_set 类型的表,返回的是 Erlang 项顺序的前一个键将被返回;如果是其他类型的表,该函数的处理跟 ets:next/2 一样
     
    foldl(Function, Acc0, Tab) -> Acc1
    对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
    Types:
         Tab = tid() | atom()
         Fix = boolean()
    锁定一个类型是 set,bag 或 duplicate_bag 的表,使其可以安全遍历表里的数据
     
    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}
         Types:
              Tab = atom() | tid()
              Filename = file:name()
              Reason = term()
    将Tab表导出道文件Filename,等同于table2file(Tab, Filename, [])
    tab2file(Tab, Filename, Options) -> ok | {error, Reason}
         Types:
              Tab = atom() | tid()
              Filename = file:name()
              Options = [Option]
              Options = {extended_info, [ExtInfo]} | {sync, boolean()}
              ExtInfo = md5sum | object_count
              Reason = term()
    将Tab表到处导文件Filename。导表时,一些关于表的必须的信息被导到头部,这些信息包括表的类型,名字,访问权限,大小,版本和是否是已命名表,同事还有关于教导文件中的一些扩展信息相关的注释,这些可以使文件中的对象数或者是头部和文件中record的MD5值。如果标的访问权限是public并且在导表的过程中有田间或删除的对象,头部的大小字段值可能与实际的对象数不一致。public权限的表在导表时有更新,并且想在从文件中读取表时核对,则扩展信息中至少要有一个字段给读取和核对进程提供依据。
     
    扩展信息选项指出有哪些扩展信息被写到了文件中:
    object_count
    实际写入文件的对象数量写在了文件的尾部,因此即使在导表时有更新表,也可以核对。
    md5sum
    头部和表中的对象使用内建的MD5函数来校验.所有对象的MD5值写在文件的尾部,所以读取时的校验可以发现文件中的数据微小的比特级的反转。使用该选项将要耗费适量的CPU时间。
    一旦使用了扩展信息选项,将导致ets版本早于stdlib-1.15.1的文件无法读取.
     
    file2tab(Filename) -> {ok, Tab} | {error, Reason}
    Types:
         Filename = file:name()
         Tab = tab()
         Reason = term()
    读取一个由tab2file/2 或 tab2file/3生成的文件并创建对应的表,与file2tab(FileName, [])等效。
    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导入文件的标的信息
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
  • 相关阅读:
    指针与数组的区别 —— 《C语言深度剖析》读书心得
    console ouput 与 重定向输出 效率对比
    First day in 阿里
    TestNG 使用入门教程
    Spring简单使用简介
    玩转Spring JUnit+mockito+powermock单元测试(使用详解)
    Spring Boot Junit 单元测试详解
    spring @Value注入map、List、Bean、static变量方式及详细使用
    单元测试Junit使用详解
    Mockito & PowerMock详解
  • 原文地址:https://www.cnblogs.com/ACshasow/p/7000102.html
Copyright © 2011-2022 走看看