首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

ets

模块

ETS

模块摘要

内置的定期存储。

描述

该模块是Erlang内置的术语存储BIF的接口。这些提供了在Erlang运行时系统中存储大量数据的能力,并且能够持续访问数据。(ordered_set如下所示,访问时间与存储对象数的对数成正比。)

数据被组织成一组动态表,可以存储元组。每个表都由一个进程创建。当进程终止时,表将自动销毁。每个表都在创建时设置了访问权限。

表分为四种不同类型,setordered_setbag,和duplicate_bagsetordered_set表只能有一个与每个键相关的对象,bagduplicate_bag表可以有许多与每个键相关的对象。

在一个Erlang节点中存储的表的数量曾经是有限的。这不再是这种情况(除内存使用外)。以前的默认限制是大约1400个表,并且可以ERL_MAX_ETS_TABLES在启动Erlang运行时系统之前通过设置环境变量来增加。这个硬限制已被删除,但目前设置ERL_MAX_ETS_TABLES仍然有用。它应该设置为所用表格的最大数量的近似值。这是因为命名表的内部表使用此值来确定大小。如果使用大量的命名表并且ERL_MAX_ETS_TABLES尚未增加,则命名表查找的性能会降低。

注意,没有表的自动垃圾回收。即使没有从任何进程引用表,除非所有者进程终止,否则不会自动销毁表。若要显式销毁表,请使用函数delete/1默认所有者是创建表的进程。若要在进程终止时转移表所有权,请使用选项heir或调用give_away/3

一些实施细节:

  • 在当前实现中,每个对象插入和查找操作都会导致对象的副本。
  • '$end_of_table'不用作键,因为在使用函数时,这个原子用于标记表的结尾。first/1next/2

注意匹配比较相等,它由表类型演示。setordered_set*

  • 如果两个Erlang项的类型相同并具有相同的值,则它们匹配,因此1与1匹配,但不是1.0(因为1.0是float()而不是整数())。
  • 如果两个Erlang项的类型和值相同,或者两者都是数值类型并扩展为相同的值,则两个Erlang项相等,以便1将两者1和等同1.0
  • ordered_setErlang项序之间不存在定义的顺序。integer()和一个float()扩展到相同的值。所以关键1关键是1.0被认为是平等的。ordered_set桌子。失败本模块中的函数退出是有原因的。badarg如果任何参数格式错误,表标识符无效,或者由于表访问权限%28而拒绝操作protectedprivate29%。并发性该模块为并发访问提供了一些有限的支持。对单个对象的所有更新都保证两者兼备。原子孤立这意味着对单个对象的更新操作成功或完全失败,而不影响%28原子性%29,并且其他进程%28隔离%29看不到更新的中间结果。一些更新许多对象的函数甚至保证整个操作的原子性和隔离性。在数据库术语中,隔离级别可以被看作是“可序列化的”,就好像所有隔离操作都是按严格顺序依次执行的。在这个模块中没有任何其他支持可以保证对象之间的一致性。然而,功能safe_fixtable/2可以用来保证first/1next/2调用遍历该表而没有错误,并且访问表中的每个现有对象精确一次,即使另一个%28或相同的%29进程同时删除或插入表中的对象。没有其他保证;特别是在这样的遍历过程中插入或删除的对象可以一次访问,也可以根本不访问。在表上内部遍历的函数,如selectmatch,提供与safe_fixtable...匹配规格一些函数使用匹配规格,,,match_spec.关于一个简短的解释,见select/2有关详细说明,请参阅Match Specifications in Erlang在ERTS用户%27s指南中。数据类型access() = public | protected | privatecontinuation()不透明的延拓select/1,3,,,select_reverse/1,3,,,match/1,3,和match_object/1,3...match_spec() = [{match_pattern(), [term()], [term()]}]匹配规格,见上文。comp_match_spec()已编译的匹配规范。match_pattern() = atom() | tuple()tab() = atom() |tid()tid()表标识符,由new/2...type() = set | ordered_set | bag | duplicate_bag出口全部28%%29->标签类型返回节点上所有表的列表。命名表由其名称指定,未命名表由其表标识符指定。返回的列表不能保证一致性。“期间”由其他进程创建或删除的表。ets:all()调用是或不包括在列表中。仅创建/删除表以前ets:all()则保证包括/排除调用。删除%28 Tab%29->true类型删除整个表。Tab...删除%28 Tab,键%29->true类型用键删除所有对象。Key从桌子上Tab...删除[医]全[医]对象%28 Tab%29->true类型删除ETS表中的所有对象Tab.该行动保证atomic and isolated...删除[医]对象%28 Tab,对象%29->true类型删除确切的对象Object在ETS表中,使对象具有相同的键,但其他差异对类型有用bag29%。在...duplicate_bag表中,对象的所有实例都将被删除。文件2选项卡%28文件名%29->{ok,Tab}{Error,原因}类型读取由tab2file/2tab2file/3并创建相应的表。Tab...相当于file2tab(Filename, [])...文件2选项卡%28文件名,选项%29->{ok,Tab}{Error,原因}类型读取由tab2file/2tab2file/3并创建相应的表。Tab...唯一受支持的选项是{verify,boolean()}如果通过指定{verify,true}%29,函数使用文件中的任何信息来断言信息没有损坏。如何做到这一点取决于extended_info是用tab2file/3...如果没有extended_info存在于文件中,并且{verify,true}指定时,写入的对象数将与启动转储时原始表的大小进行比较。如果表是public在表转储到文件时添加或删除对象。若要避免此问题,请不要在同时更新时验证转储文件,或者使用选项。{extended_info, [object_count]}tab2file/3,它用写入的对象数扩展文件中的信息。如果打开了验证,并且使用选项写入了文件{extended_info, [md5sum]},读取文件的速度更慢,消耗的CPU时间比其他时间要多得多。{verify,false}是默认的。第一个%28 Tab%29->键%27$end[医]成[医]表%27类型返回第一个键。Key表中Tab...为了...ordered_set表中,将返回Erlang项顺序中的第一个键。对于其他表类型,将根据表的内部顺序返回第一个键。如果桌子是空的,'$end_of_table'会被归还。若要在表中查找后续键,请使用next/2...折叠%28功能,Acc0,Tab%29->Acc1类型Acc0如果表为空,则返回。此函数类似于lists:foldl/3表元素被遍历是未指定的顺序,但ordered_set表,在那里它们首先被遍历到最后。如果Function将对象插入到表中,或者另一个进程将对象插入到表中,即这些对象。%28取决于键顺序,在遍历中包含%29。折叠%28功能,Acc0,Tab%29->Acc1类型Acc0如果表为空,则返回。此函数类似于lists:foldr/3表元素被遍历是未指定的顺序,但ordered_set表,在这些表中,它们是最后到第一个遍历的。如果Function将对象插入到表中,或者另一个进程将对象插入到表中,即这些对象。%28取决于键顺序,在遍历中包含%29。从[医]Dets%28 Tab,DetsTab%29->true类型用已打开的dets表中的对象填充已创建的ETS表。DetsTab除非覆盖,否则ETS表中的现有对象将保持不变。如果不存在任何表或未打开dets表,则badarg引发异常。乐趣2ms%28识字FUN%29->MatchSpec类型由parse_transform翻译LiteralFun类的函数调用中键入为参数。match specification“文字”的意思是,乐趣必须以文本形式写成函数的参数,它不能保存在变量中,而变量又被传递给函数。中提供了解析转换。ms_transform模块和源包括文件ms_transform.hrl在STDLIB中,这个伪函数才能工作。未能在源中包含hrl文件将导致运行时错误,而不是编译时错误。通过添加行,包含文件是最简单的。-include_lib("stdlib/include/ms_transform.hrl").源文件。乐趣是非常有限的,它可以只需要一个参数%28对象匹配%29:一个唯一的变量或元组。它必须使用is_警卫测试。在匹配规范%28中没有表示的语言结构if,,,case,,,receive,等等,%29是不允许的。返回值是结果匹配规范。例子:1> ets:fun2ms(fun({M,N}) when N > 3 -> M end). [{{'$1','$2'},[{'>','$2',3}],['$1']}]可以从环境中导入变量,以便进行以下工作:2> X=3. 3 3> ets:fun2ms(fun({M,N}) when N > X -> M end). [{{'$1','$2'},[{'>','$2',{const,3}}],['$1']}]导入的变量由匹配规范替换。const表达式,这与Erlang Funs的静态作用域一致。然而,本地或全局函数调用不能在守卫或身体的乐趣。当然,对内置的匹配规范函数的调用是允许的:4> ets:fun2ms(fun({M,N}) when N > X, my_fun(M) -> M end). Error: fun containing local Erlang function calls ('my_fun' called in guard) cannot be translated into match_spec {error,transform_error} 5> ets:fun2ms(fun({M,N}) when N > X, is_atom(M) -> M end). [{{'$1','$2'},[{'>','$2',{const,3}},{is_atom,'$1'}],['$1']}]如示例所示,也可以从shell调用该函数。乐趣必须是字面上的调用时,从外壳使用以及。警告如果parse_transform不应用于调用此伪函数的模块,则调用在运行时%28中失败,badarg29%。大ets模块导出具有此名称的函数,但除非在shell中使用该函数,否则永远不会调用它。如果parse_transform通过包含头文件正确应用ms_transform.hrl,编译后的代码从不调用函数,但函数调用被文字匹配规范替换。有关更多信息,请参见ms_transform(3)...施予[医]离开%28 Tab,PID,GiftData%29->真类型制造过程Pid桌子的新主人Tab如果成功的话{'ETS-TRANSFER',Tab,FromPid,GiftData}被发送给新主人。过程Pid必须是活着的,本地的,而不是表的所有者。调用进程必须是表所有者。请注意,此函数不影响选项。heir在桌子上。例如,表所有者可以设置heir将表交给自己,然后在接收端终止时将其拿回来。I%28%29->OK显示终端上所有ETS表的信息。I%28 Tab%29->OK类型浏览表Tab在终点站。INFO%28 Tab%29->InfoList未定义类型返回有关表的信息。Tab作为一个元组列表。如果Tab具有表标识符的正确类型,但不引用现有的ETS表,undefined会被归还。如果Tab不是正确的类型,badarg引发异常。{compressed, boolean()}指示表是否已压缩。{heir, pid() | none}表继承人的PID,或none如果没有继承人。{keypos, integer() >= 1}关键位置。{memory, integer() >= 0分配给表的单词数。{name, atom()}表名。{named_table, boolean()}指示表是否已命名。{node, node()}存储表的节点。此字段不再有意义,因为不能从其他节点访问表。{owner, pid()}表所有者的PID。{protection,access()}表访问权限。{size, integer() >= 0插入表中的对象数。{type,type()}表格类型。{read_concurrency, boolean()}指示表是否使用read_concurrency或者不是。{write_concurrency, boolean()}指示表是否使用write_concurrency...INFO%28 Tab,项目%29->值未定义类型返回与Item供桌用Tab,或返回undefined如果Tab不引用现有的ETS表。如果Tab不属于正确的类型,或者Item不是允许的值之一,badarg引发异常。除了{Item,Value}定义为info/1,允许下列项目:
  • Item=fixed, Value=boolean()

指示表是否由任何进程修复。

  • Item=safe_fixed|safe_fixed_monotonic_time, Value={FixationTime,Info}|false如果表已使用safe_fixtable/2,调用将返回一个元组,其中FixationTime表第一次由进程修复的时间,该进程是或不是它现在固定的进程之一。 的格式和价值FixationTime依赖于Item*safe_fixedFixationTime返回的结果对应于erlang:timestamp/0在固定的时候。请注意,当系统使用单个或多个time warp modes这可能会产生奇怪的结果,如使用safe_fixed不是time warp safe时间扭曲安全代码必须使用safe_fixed_monotonic_time相反。safe_fixed_monotonic_timeFixationTime返回的结果对应于erlang:monotonic_time/0在固定的时候。使用safe_fixed_monotonic_timetime warp safe...Info可能是元组的空列表。{Pid,RefCount},到目前为止,表中的每个进程都有一个元组。RefCount是引用计数器的值,它跟踪该表被进程修复了多少次。 如果从未修复表,则调用将返回false...
  • Item=stats, Value=tuple()

返回有关OTP测试套件使用的内部格式的内部统计信息setbag以及duplicate_bag表格。不适用于生产用途。

init_table(Tab,InitFun) - > true

类型

替换表的现有对象。Tab使用通过调用输入函数创建的对象。InitFun见下文。此函数是为了与dets模块,它不会比使用insert/2

当用参数调用时read,功能InitFun假定返回end_of_input当没有更多的输入时,或者{Objects, Fun},在哪里Objects是一个对象列表,而Fun是一个新的输入函数。任何其他价值Value作为错误返回。{error, {init_fun, Value}}每个输入函数都被调用一次,如果发生错误,最后一个函数将使用参数调用。close的答复被忽略了。

如果表类型为set并且多个对象存在于一个给定的键中,其中一个对象被选择。这不一定是输入函数返回的对象序列中具有给定键的最后一个对象。这对于存储在类型表中的复制对象也是如此。bag

插入(Tab, ObjectOrObjects) -> true

类型

插入对象或列表中的所有对象。ObjectOrObjects成桌Tab...

  • 如果表类型为set和插入对象的键。火柴表中任何对象的键,旧对象都会被替换。
  • 如果表类型为ordered_set和插入对象的键。比较相等对于表中任何对象的键,将替换旧对象。
  • 如果列表包含多个对象,则为匹配键和表类型为set,一个被插入,一个没有定义。表类型的情况相同。ordered_set如果钥匙比较相等...整个操作保证是atomic and isolated,即使插入对象列表时也是如此。插入[医]新的%28 Tab,ObjectOrObjects%29->布尔值%28%29类型同insert/2但是,与其用相同的键%28覆盖对象,倒不如用setordered_set%29或添加更多具有键的对象(表%28)bagduplicate_bag%29,false会被归还。如果ObjectOrObjects是一个列表,函数将检查每一个插入任何东西之前先输入键。除非列表中的键不在表中。就像insert/2,整个操作将被保证atomic and isolated...是[医]编撰[医]ms%28 Term%29->boole%28%29类型检查某个术语是否为有效的已编译match specification编译的匹配规范是一个不透明的数据类型,不可能在Erlang节点之间发送或存储在磁盘上。任何创建已编译匹配规范的外部表示形式的尝试都会导致空二进制数%28<<>>29%。例子:下面的表达式产生true*ets:is_compiled_ms(ets:match_spec_compile([{'_',[],[true]}])).下面的表达式会产生false,作为变量Broken包含经过外部表示的已编译的匹配规范:MS = ets:match_spec_compile([{'_',[],[true]}]), Broken = binary_to_term(term_to_binary(MS)), ets:is_compiled_ms(Broken).注没有编译的匹配规范的外部表示形式的原因是性能。它可能会在将来的版本中被更改,而这个接口仍然是为了向后兼容性。最后%28 Tab%29->键%27$end[医]成[医]表%27类型返回最后一个键。Key根据表中的Erlang项顺序Tab类型ordered_set对于其他表类型,该函数与first/1如果桌子是空的'$end_of_table'会被归还。若要在表中查找前面的键,请使用prev/2...查找%28 Tab,键%29->对象类型返回带键的所有对象的列表。Key表中Tab...
  • 对于类型为setbag或的表格,duplicate_bag仅当指定的键匹配表中对象的键时才返回对象。
  • 类型表ordered_set,则如果指定的键是指定的,则返回对象。比较相等到表中对象的键。两者之间的区别是相同的。=:===...例如,可以用integer()1作为一个ordered_set的结果,并获得返回的对象。lookup/2带着float()1.0作为寻找的钥匙。类型表setordered_set函数返回空列表或带有一个元素的列表,因为不能有多个具有相同键的对象。类型表bagduplicate_bag函数返回任意长度的列表。注意,保留了对象插入的时间顺序;使用指定键插入的第一个对象是结果列表中的第一个对象,依此类推。类型表中的插入和查找时间set,,,bag,和duplicate_bag都是常数,而不管表大小如何。为ordered_set数据类型,时间与对象数的%28二进制%29对数成正比。查找[医]元素%28 Tab,key,pos%29->Elem类型为了一张桌子Tab类型setordered_set函数返回Pos*具有键的对象的th元素Key...类型表bagduplicate_bag函数返回一个具有Pos*每个具有键的对象的th元素Key...如果没有带键的对象Key存在时,该函数的退出是有原因的。badarg...之间的区别set,,,bag,和duplicate_bag一方面,和ordered_set另一方面,关于事实上ordered_set当键相同时查看它们比较相等而其他表类型只有在它们相同的情况下才会将它们视为相等。匹配,持有lookup_element/3...匹配%28连续%29->{匹配,继续}%27$end[医]成[医]表%27类型继续开始匹配match/3中指定的下一个大小块。match/3调用与新的Continuation,可以在以后调用此函数时使用。当表中没有对象时,'$end_of_table'会被归还。匹配%28 Tab,模式%29->匹配类型匹配表中的对象。Tab反模式Pattern...模式是一个术语,可以包含:
  • 绑定部分(Erlang条款)
  • '_'与任何Erlang项相匹配
  • 模式变量'$N',在哪里N=0,1,...

该函数返回一个包含每个匹配对象的一个元素的列表,其中每个元素都是模式变量绑定的有序列表,例如:

代码语言:javascript
复制
6> ets:match(T, '$1'). % Matches every object in table
[[{rufsen,dog,7}],[{brunte,horse,5}],[{ludde,dog,5}]]
7> ets:match(T, {'_',dog,'$1'}).
[[7],[5]]
8> ets:match(T, {'_',cow,'$1'}).
[]

如果在模式中指定了键,则匹配非常有效。如果没有指定键,也就是说,如果它是变量或下划线,则必须搜索整个表。如果表非常大,搜索时间可能很长。

类型表ordered_set,则结果的顺序与first/next穿越。

匹配(选项卡,模式,限制) - >

{匹配,延续} | '$ end_of_table'

类型

像那样工作match/2,但只返回有限Limit数量的匹配对象。Term Continuation可以在随后的调用中match/1用于获取下一块匹配对象。这是处理表中对象的空间高效方法,它比使用first/1和的对象遍历表对象更快next/2

如果桌子是空的,'$end_of_table'会被归还。

match_delete(Tab,Pattern) - > true

类型

删除所有匹配模式的对象。Pattern从桌子上Tab有关模式的说明,请参见match/2...

match_object(Continuation) - >

{对象,延续} | '$ end_of_table'

类型

继续开始匹配match_object/3中指定的下一个大小块。match_object/3调用与新的Continuation,可以在以后调用此函数时使用。

当表中没有对象时,'$end_of_table'会被归还。

match_object(Tab,Pattern) - > Object

类型

匹配表中的对象。Tab反模式Pattern有关模式的说明,请参见match/2函数返回与模式匹配的所有对象的列表。

如果在模式中指定了键,则匹配非常有效。如果没有指定键,也就是说,如果它是变量或下划线,则必须搜索整个表。如果表非常大,搜索时间可能很长。

类型表ordered_set,则结果的顺序与first/next穿越。

match_object(Tab,Pattern,Limit) - >

{对象,延续} | '$ end_of_table'

类型

像工作一样match_object/2,但只返回有限Limit数量的匹配对象。Term Continuation可以在随后的调用中match_object/1用于获取下一块匹配对象。这是处理表中对象的空间高效方法,它比使用first/1和的对象遍历表对象更快next/2

如果桌子是空的,'$end_of_table'会被归还。

match_spec_compile(MatchSpec) - > CompiledMatchSpec

类型

将a match specification转换为内部表示形式,可用于随后的调用match_spec_run/2。内部表示是不透明的,不能转换为外部术语格式,然后再次返回而不丢失其属性(也就是说,它不能被发送到另一个节点上的进程,仍然保持有效的编译匹配规范,也不能存储磁盘)。要检查编译的匹配规范的有效性,请使用is_compiled_ms/1

如果术语MatchSpec无法编译(不代表有效的匹配规范),badarg则会引发异常。

此函数在普通代码中的使用有限。它被dets模块执行dets:select()行动。

match_spec_run(List,CompiledMatchSpec) - > list()

类型

执行已编译的match specification在一个元组列表上。术语CompiledMatchSpec的结果是match_spec_compile/1因此,它是要使用的匹配规范的内部表示形式。

中的每个元素执行匹配。List函数返回一个包含所有结果的列表。中的元素List不匹配,则不会返回该元素的任何内容。因此,结果列表的长度等于或小于参数的长度。List...

例子:

以下两个调用给出了相同的结果(但执行时间肯定不相同):

代码语言:javascript
复制
Table = ets:new...
MatchSpec = ...
% The following call...
ets:match_spec_run(ets:tab2list(Table),
ets:match_spec_compile(MatchSpec)),
% ...gives the same result as the more common (and more efficient)
ets:select(Table, MatchSpec),

此函数在普通代码中的使用有限。它被dets模块执行dets:select()在交易期间由Mnesia操作。

成员(Tab,Key) - > boolean()

类型

就像lookup/2,但不返回对象。回报true如果表中的一个或多个元素具有键Key,否则false

新(名称,选项) - > tid()| 原子()

类型

创建一个新表并返回可用于后续操作的表标识符。表标识符可以发送到其他进程,以便在节点内的不同进程之间共享表。

参数Options是指定表类型,访问权限,关键位置以及表是否被命名的原子列表。默认值用于省略选项。这意味着不指定任何选项([])与指定相同[set, protected, {keypos,1}, {heir,none}, {write_concurrency,false}, {read_concurrency,false}]

set

这张桌子是set表:一个键,一个对象,对象之间没有顺序。这是默认的表类型。

ordered_set

该表格是一个ordered_set表格:一个关键字和一个对象,按Erlang术语顺序排列,这是<和>运算符隐含的顺序。在某些情况下,这种类型的表的行为与其他类型的表有些不同。最值得注意的是,这些ordered_set表格在比较相等的时候把它们看作是平等的,而不仅仅是当它们匹配时。这意味着对一张ordered_set桌子,integer() 1并被float() 1.0视为平等。这也意味着用于查找元素的键不一定返回元素的键相匹配,如果float()'s integer()' 和's'混合在一个表的键中。

bag

这张桌子是bag表,它可以有许多对象,但每个对象只有一个实例,每个键。

duplicate_bag

这张桌子是duplicate_bag表,它可以有多个对象,包括同一对象的多个副本。

public

任何进程都可以对表进行读写。

protected

所有者进程可以读写表。其他进程只能读取表。这是访问权限的默认设置。

private

只有所有者进程才能读写表。

named_table

如果存在此选项,请命名Name与表标识符关联。然后,可以在后续操作中使用该名称而不是表标识符。

{keypos,Pos}

指定存储的元组中用作键的元素。默认情况下,它是第一个元素,即,Pos=1然而,这并不总是适当的。特别是,如果要将Erlang记录存储在表中,则不希望第一个元素成为键。

请注意,存储在表中的任何元组必须至少有Pos元素数。

{heir,Pid,HeirData} | {heir,none}

设定程序为继承人。如果所有者终止,继承人将继承该表。讯息{'ETS-TRANSFER',tid(),FromPid,HeirData}会被送到继承人那里。继承人必须是当地的程序。默认继承人none,当所有者终止时,它会破坏表。

{write_concurrency,boolean()}

性能调优。默认为false在这种情况下,将%28写到%29的操作将获得独占访问,在完成之前阻止对同一表的任何并发访问。如果设置为true,该表被优化为并发写入访问。同一表的不同对象可以通过并发进程突变%28和读取%29。这在某种程度上是以牺牲内存消耗以及顺序访问和并发读取的性能为代价的。

期权write_concurrency可以与选项相结合read_concurrency当大型并发读突发和大型并发写入突发很常见时,通常希望将它们组合起来;有关详细信息,请参阅选项。read_concurrency...

注意这个选项并没有改变任何保证atomicity and isolation。对许多对象做出这种承诺的函数(如insert/2)从这个选项中获得更少(或者没有)。

表型ordered_set不受此选项的影响。同时,这两种方法造成的内存消耗write_concurrencyread_concurrency是每个表的固定开销。当这两个选项组合在一起时,这种开销可能会特别大。

{read_concurrency,boolean()}

性能调优。默认为false.当设置为true,对表进行了优化,以便进行并发读取操作。当在支持SMP的运行时系统上启用此选项时,读取操作将变得更便宜;特别是在具有多个物理处理器的系统上。然而,读写操作之间的切换变得更加昂贵。

当并发读取操作比写入操作更频繁时,或者并发读取和写入出现大量读取和写入突发时(即,许多读取未被写入中断,并且许多写入未被读取中断),您通常希望启用此选项)。

你通常会要启用此选项时,公共访问模式是与几个重复写入操作交织在一起的几个读操作。在这种情况下,启用此选项将导致性能下降。

期权read_concurrency可以与选项相结合write_concurrency通常,当大型并发读突发和大型并发写入突发很常见时,您通常希望将它们组合起来。

compressed

如果存在此选项,表数据将以更紧凑的格式存储,以减少内存消耗。然而,它将使表操作更慢。特别是需要检查整个对象的操作,例如matchselect慢得多。关键元素未被压缩。

下一步(Tab,Key1) - > Key2 | '$ end_of_table'

类型

返回下一个键。Key2,跟随键Key1表中Tab表型ordered_set,将返回Erlang术语顺序中的下一个键。对于其他表类型,将根据表的内部顺序返回下一个键。如果没有下一个密钥,'$end_of_table'会被归还。

要找到表格中的第一个键,请使用first/1

除非一个表类型setbag或被duplicate_bag保护使用safe_fixtable/2,否则如果对表进行并发更新,则遍历可能会失败。对于表类型ordered_set,该函数按顺序返回下一个键,即使该对象不再存在。

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

类型

返回前一个键。Key2,前键Key1根据表中的Erlang项顺序Tab类型ordered_set对于其他表类型,该函数与next/2如果之前的密钥不存在,'$end_of_table'会被归还。

若要查找表中的最后一个键,请使用last/1...

重命名(选项卡,名称) - >名称

类型

重命名命名表Tab换新名字Name之后,不能使用旧名称访问表。重命名未命名表没有任何效果。

repair_continuation(Continuation,MatchSpec) - > Continuation

类型

还原由select/3select/1如果延续已通过外部项格式,则%28在节点之间发送或存储在磁盘%29上。

此函数的原因是,连续术语包含编译的匹配规范,因此如果转换为外部术语格式,则无效。如果原始匹配规范保持不变,则可以恢复该延续,这意味着它可以再次用于后续的select/1调用,即使它已存储在磁盘上或另一个节点上。

例子:

以下调用顺序失败:

代码语言:javascript
复制
T=ets:new(x,[]),
...
{_,C} = ets:select(T,ets:fun2ms(fun({N,_}=A)
when (N rem 10) =:= 0 ->
A
end),10),
Broken = binary_to_term(term_to_binary(C)),
ets:select(Broken).

随着repair_continuation/2重新建立(故意)无效延续的呼叫,以下顺序起作用Broken

代码语言:javascript
复制
T=ets:new(x,[]),
...
MS = ets:fun2ms(fun({N,_}=A)
when (N rem 10) =:= 0 ->
A
end),
{_,C} = ets:select(T,MS,10),
Broken = binary_to_term(term_to_binary(C)),
ets:select(ets:repair_continuation(Broken,MS)).

此函数在应用程序代码中很少需要。Mnesia使用它来提供分布式select/3select/1序列。正常的应用程序要么使用Mnesia,要么阻止继续转换为外部格式。

没有编译的匹配规范的外部表示形式的原因是性能。它可能会在将来的版本中被更改,而这个接口仍然是为了向后兼容性。

safe_fixtable(Tab,Fix) - > true

类型

修复类型的表setbagduplicate_bag为安全穿越。

进程通过调用safe_fixtable(Tab, true)表保持固定状态,直到进程通过调用safe_fixtable(Tab, false),或者直到进程结束。

如果许多进程修复一个表,那么该表将保持固定状态,直到所有进程释放它(或终止)为止。参考计数器保持在每个进程基础上,并且连续N次修复需要N个版本才能释放表格。

当一个表被修复时,一系列的first/1next/2调用都会保证成功,并且表中的每个对象只返回一次,即使在遍历过程中删除或插入了对象。在遍历期间插入的新对象的键可以返回next/2(这取决于键的内部顺序)。

例子:

代码语言:javascript
复制
clean_all_with_value(Tab,X) ->
    safe_fixtable(Tab,true),
    clean_all_with_value(Tab,X,ets:first(Tab)),
    safe_fixtable(Tab,false).

clean_all_with_value(Tab,X,'$end_of_table') ->
    true;
clean_all_with_value(Tab,X,Key) ->
    case ets:lookup(Tab,Key) of
        [{Key,X}] ->
            ets:delete(Tab,Key);
        _ ->
            true
    end,
    clean_all_with_value(Tab,X,ets:next(Tab,Key)).

注意,在固定表释放之前,不会从固定表中删除已删除的对象。如果一个进程修复了一个表,但从未释放它,则删除对象所使用的内存永远不会被释放。桌面上的操作性能也显著下降。

若要检索有关哪些进程已固定哪些表的信息,请使用info(Tab, safe_fixed_monotonic_time)一个拥有许多进程修复表的系统可能需要一个监视器,当表被修复太久时,它会发送警报。

请注意,对于表类型ordered_setsafe_fixtable/2不需要,因为调用first/1next/2始终成功。

选择(继续) - > {匹配,延续} | '$ end_of_table'

类型

继续开始匹配select/3中指定的下一个大小块。select/3调用与新的Continuation,可以在以后调用此函数时使用。

当表中没有对象时,'$end_of_table'会被归还。

选择(Tab,MatchSpec) - >匹配

类型

匹配表中的对象。Tab使用match specification这是一个比match/2match_object/2打电话。最简单的形式是匹配规范如下:

代码语言:javascript
复制
MatchSpec = [MatchFunction]
MatchFunction = {MatchHead, [Guard], [Result]}
MatchHead = "Pattern as in ets:match"
Guard = {"Guardtest name", ...}
Result = "Term construct"

这意味着匹配规范始终是一个或多个元组(列表3)的列表。元组的第一个元素是一个模式,如下所述match/2。元组的第二个元素是一个包含0个或更多的守卫测试的列表(如下所述)。元组的第三个元素是一个包含要返回值的描述的列表。几乎在所有正常情况下,该列表都包含完全描述每个对象返回值的一个术语。

返回值是使用绑定在MatchHead或使用特殊匹配变量'$_'(整个匹配对象)和'$$'(列表中的所有匹配变量)中的“匹配变量”构造的,以便使用以下match/2表达式:

代码语言:javascript
复制
ets:match(Tab,{'$1','$2','$3'})

完全等同于:

代码语言:javascript
复制
ets:select(Tab,[{{'$1','$2','$3'},[],['$$']}])

以下是match_object/2呼叫:

代码语言:javascript
复制
ets:match_object(Tab,{'$1','$2','$1'})

完全等同于

代码语言:javascript
复制
ets:select(Tab,[{{'$1','$2','$1'},[],['$_']}])

组合项可以在Result部分只需编写一个列表,以便下面的代码:

代码语言:javascript
复制
ets:select(Tab,[{{'$1','$2','$3'},[],['$$']}])

提供与以下相同的输出:

代码语言:javascript
复制
ets:select(Tab,[{{'$1','$2','$3'},[],[['$1','$2','$3']]}])

也就是说,匹配头中的所有绑定变量都是一个列表。如果要构造元组,则必须编写一个元组1,其中元组中的单个元素是要构建的元组(因为普通元组可能会被误认为是a Guard)。

因此,以下呼吁:

代码语言:javascript
复制
ets:select(Tab,[{{'$1','$2','$1'},[],['$_']}])

提供与以下相同的输出:

代码语言:javascript
复制
ets:select(Tab,[{{'$1','$2','$1'},[],[{{'$1','$2','$3'}}]}])

此语法等同dbg(3)于Runtime_Tools中跟踪模式(请参阅)中使用的语法。

所述Guards的构造为元组,其中所述第一元件是所述测试名称和其余元件的测试参数。要检查绑定到匹配变量的元素的特定类型(比如列表)'$1',可以将测试写为{is_list, '$1'}。如果测试失败,表中的对象不匹配,并MatchFunction尝试下一个(如果有的话)。在Erlang中可以使用的大多数后卫测试都可以使用,但只is_允许前缀的新版本(is_floatis_atom等等)。

Guard部分还可以包含逻辑和算术运算,这些运算使用与守护测试(前缀符号)相同的语法编写,以便使用Erlang编写以下防护测试:

代码语言:javascript
复制
is_integer(X), is_integer(Y), X + Y < 4711

被表示为如下(X以代替'$1'Y'$2'):

代码语言:javascript
复制
[{is_integer, '$1'}, {is_integer, '$2'}, {'<', {'+', '$1', '$2'}, 4711}]

类型表ordered_set对象的访问顺序与first/next穿越。这意味着匹配规范是针对带有键的对象执行的。first/nextOrder和相应的结果列表按该执行的顺序排列。

选择(Tab,MatchSpec,Limit) - >

{匹配,延续} | '$ end_of_table'

类型

像工作一样select/2,但只返回有限Limit数量的匹配对象。Term Continuation可以在随后的调用中select/1用于获取下一块匹配对象。这是处理表中对象的空间高效方法,它仍然比使用first/1and 的对象遍历表对象更快next/2

如果桌子是空的,'$end_of_table'会被归还。

select_count(Tab,MatchSpec) - > NumMatched

类型

匹配表中的对象。Tab使用match specification.如果匹配规范返回true对于对象,该对象被认为是匹配的,并被计数。对于来自Match规范的任何其他结果,该对象不被视为匹配,因此不被计算。

此函数可描述为match_delete/2函数,该函数不删除任何元素,但只对其进行计数。

函数返回匹配的对象数。

select_delete(Tab,MatchSpec) - > NumDeleted

类型

匹配表中的对象。Tab使用match specification.如果匹配规范返回true对于对象,该对象将从表中移除。对于匹配规范中的任何其他结果,该对象将被保留。这是一个比match_delete/2打电话。

函数返回从表中删除的对象数。

匹配规范必须返回原子。true如果要删除对象。没有其他返回值会删除对象。因此,不能使用相同的匹配规范来查找元素和删除元素。

select_replace(Tab,MatchSpec) - > NumReplaced

类型

匹配表中的对象。Tab使用match specification对于每个匹配的对象,现有的对象被替换为匹配规范结果。

每个单独对象的匹配和替换操作保证为atomic and isolated...select_replace与所有其他选择函数一样,表迭代作为一个整体并不能提供这样的保证。

必须保证匹配指定为保留密钥任何匹配的对象。如果不是,select_replace会失败badarg而不更新任何对象。

目前,由于性能和语义限制,类型表bag还没有得到支持。

函数返回替换对象的总数。

对于所有具有第二位置列表的二元元组,添加原子。'marker'名单中第一位:

代码语言:javascript
复制
1> T = ets:new(x,[]), ets:insert(T, {key, [1, 2, 3]}).
true
2> MS = ets:fun2ms(fun({K, L}) when is_list(L) -> {K, [marker | L]} end).
[{{'$1','$2'},[{is_list,'$2'}],[{{'$1',[marker|'$2']}}]}]
3> ets:select_replace(T, MS).
1
4> ets:tab2list(T).
[{key,[marker,1,2,3]}]
	

一个通用的单个对象比较和交换操作:

代码语言:javascript
复制
[Old] = ets:lookup(T, Key),
New = update_object(Old),
Success = (1 =:= ets:select_replace(T, [{Old, [], [{const, New}]}])),
	

选择[医]反向%28连续%29->

{匹配,继续}%27$end[医]成[医]表%27

类型

继续开始匹配select_reverse/3.类型表ordered_set,该表的遍历将继续以Erlang项顺序中的键对对象进行遍历。返回的列表还包含具有按反向顺序键的对象。对于所有其他表类型,行为与select/1...

例子:

代码语言:javascript
复制
1> T = ets:new(x,[ordered_set]).
2> [ ets:insert(T,{N}) || N <- lists:seq(1,10) ].
...
3> {R0,C0} = ets:select_reverse(T,[{'_',[],['$_']}],4).
...
4> R0.
[{10},{9},{8},{7}]
5> {R1,C1} = ets:select_reverse(C0).
...
6> R1.
[{6},{5},{4},{3}]
7> {R2,C2} = ets:select_reverse(C1).
...
8> R2.
[{2},{1}]
9> '$end_of_table' = ets:select_reverse(C2).
...

select_reverse(Tab,MatchSpec) - > Match

类型

就像select/2,但按表类型的相反顺序返回列表。ordered_set对于所有其他表类型,返回值与select/2...

select_reverse(Tab,MatchSpec,Limit) - >

{匹配,延续} | '$ end_of_table'

类型

就像select/3,但是对于表类型ordered_set遍历是从Erlang项的最后一个对象开始,然后移动到第一个对象。对于所有其他表类型,返回值与select/3...

注意这是的结果列表。select/3调用,因为结果列表不仅被反转,而且还包含最后一个Limit匹配表中的对象,而不是第一个。

setopts(Tab,Opts) - > true

类型

设置表选项。创建表后唯一允许设置的选项是heir调用进程必须是表所有者。

插槽(Tab,I) - >对象| '$ end_of_table'

类型

此函数通常用于调试。first/nextlast/prev都是用来代替的。

返回槽中的所有对象。I表中Tab.表可以通过反复调用函数来遍历,从第一个插槽开始I=0结束时'$end_of_table'会被归还。IF论证I超出了范围,该函数就会有原因而失败。badarg...

除非一个表类型setbag或被duplicate_bag保护使用safe_fixtable/2,否则如果对表进行并发更新,则遍历可能会失败。对于表类型ordered_set,该函数返回一个包含IErlang术语顺序对象的列表。

tab2file(Tab,Filename) - > ok | {错误,原因}

类型

转储表Tab归档Filename...

相当于tab2file(Tab, Filename,[])

tab2file(Tab,Filename,Options) - > ok | {错误,原因}

类型

转储表Tab归档Filename...

当转储表时,有关表的一些信息将在转储开始时转储到标头。此信息包含有关表类型、名称、保护、大小、版本以及是否为命名表的数据。它还包含关于向文件中添加什么扩展信息的注释,这些信息可以是文件中对象的计数,也可以是头和文件中的MD5和记录。

如果表是公共的,并且在转储过程中从表中添加或删除记录,则标题中的大小字段可能与文件中的记录数不相对应。在转储过程中更新的公共表,以及在读取时希望验证的表,需要至少一个扩展信息字段才能使读取验证过程在以后变得可靠。

期权extended_info指定将哪些额外信息写入表转储:

object_count

写入文件的对象数量在文件页脚中注明,因此即使文件在转储期间被更新,也可以验证文件截断。

md5sum

文件中的头和对象使用内置的MD5函数进行校验和。所有对象的MD5和都写在文件页脚中,这样在读取时验证就可以检测到文件数据中的最小位翻转。使用此方法需要相当多的CPU时间。

随时随地选择extended_info,则会导致ETS版本在STDLIB 1.15.1之前无法读取的文件。

中频选项sync设置为true,它确保文件的内容在之前写入磁盘。tab2file退货。默认为{sync, false}...

tab2list(Tab) - > Object

类型

返回表中所有对象的列表。Tab...

tabfile_info(文件名) - > {ok,TableInfo} | {错误,原因}

类型

返回有关转储到文件中的表的信息。tab2file/2tab2file/3...

返回下列项目:

name

转储表的名称。如果表是一个命名表,则当表从文件中加载时,同名的表就不存在了。file2tab/2如果表未保存为命名表,则此字段在从文件中加载表时没有意义。

type

在ETS类型的转储的表(即,setbagduplicate_bag,或ordered_set)。这种类型在再次加载表格时使用。

protection

转储表的保护(即privateprotectedpublic)。从文件加载的表获得相同的保护。

named_table

true如果表在转储到文件时是一个命名表,则为false请注意,当从文件中加载指定表时,系统中不存在同名表。

keypos

keypos将表转储到文件中,在再次加载表时使用。

size

启动要文件的表转储时表中的对象数。为了public表中,此编号不需要与保存到文件中的对象数量相对应,因为对象可以在表转储期间由另一个进程添加或删除。

extended_info

在文件页脚中写入的扩展信息,以便在表从文件加载期间进行更强的验证,如tab2file/3注意,此函数只告诉哪种信息是存在的,而不是文件页脚中的值。该值是一个包含一个或多个原子的列表。object_countmd5sum...

version

元组{Major,Minor}包含ETS表转储文件格式的主版本和次要版本。这个版本字段是从STDLIB 1.5.1开始添加的。随旧版本转储的文件返回{0,0}在这个领域。

如果文件不可访问、损坏严重或未生成tab2file/2tab2file/3...

表(Tab) - > QueryHandle

表(Tab,Options) - > QueryHandle

类型

返回查询列表理解(QLC)查询句柄。该qlc模块提供主要针对Mnesia的查询语言,但ETS表格,Dets表格和列表也被QLC识别为数据源。呼叫table/1,2是使ETS表Tab可用于QLC的手段。

当对关键位置只有简单限制时,qlc使用lookup/2去查钥匙。如果这是不可能的,则遍历整个表。期权traverse确定如何做到这一点:

first_next

通过调用first/1next/2...

last_prev

通过调用last/1prev/2...

select

通过调用select/3和遍历表select/1。选项n_objects决定返回的对象的数量(第三个参数select/3); 默认是100一次返回对象。的match specification(第二个参数select/3)由QLC组装:简单过滤器被转换成等效的匹配规格而更复杂的过滤器必须被应用到由返回的所有对象select/3给出一个匹配规范的所有对象相匹配。

{select, MatchSpec}

至于select,则通过调用select/3select/1不同之处在于显式指定了匹配规范。这就是如何在QLC提供的语法中很难表达的匹配规范。

例子:

这里使用显式匹配规范遍历表:

代码语言:javascript
复制
9> true = ets:insert(Tab = ets:new(t, []), [{1,a},{2,b},{3,c},{4,d}]),
MS = ets:fun2ms(fun({X,Y}) when (X > 1) or (X < 5) -> {Y} end),
QH1 = ets:table(Tab, [{traverse, {select, MS}}]).

具有隐式匹配规范的示例:

代码语言:javascript
复制
10> QH2 = qlc:q([{Y} || {X,Y} <- ets:table(Tab), (X > 1) or (X < 5)]).

后一个例子等价于前者,可以使用函数进行验证。qlc:info/1*

代码语言:javascript
复制
11> qlc:info(QH1) =:= qlc:info(QH2).
true

qlc:info/1返回有关查询句柄的信息,在本例中,两个查询句柄返回相同的信息。

采取(Tab,Key) - >对象

类型

返回并移除带键的所有对象的列表。Key表中Tab...

指定Key用于通过比较ordered_set表中对象的相等键或其他类型表中的匹配来识别对象(有关区别的详细信息,请参阅lookup/2new/2)。

test_ms(Tuple,MatchSpec) - > {ok,Result} | {错误,错误}

类型

此函数是用于测试match specification用于调用select/2.两个测试的功能MatchSpec,以确保“语法”的正确性,并针对对象运行匹配规范。Tuple...

如果匹配规范在语法上是正确的,则函数将返回{ok,Result},在哪里Result是什么会导致一个真正的select/2打电话,或false如果匹配规范不匹配对象Tuple...

如果匹配规范包含错误,则元组{error, Errors}返回,其中Errors是一个自然语言描述的列表,描述了匹配规范的错误。

这是一个有用的调试和测试工具,特别是在编写复杂的程序时。select/2打电话。

另见:erlang:match_spec_test/3...

to_dets(Tab,DetsTab) - > DetsTab

类型

用已打开的ETS表中的对象填充已创建/打开的Dets表Tab.DETS表在插入对象之前被清空。

update_counter(Tab,Key,UpdateOp) - >结果

update_counter(Tab,Key,UpdateOp,Default) - >结果

update_counter(Tab,Key,X3 :: UpdateOp) - >结果

update_counter(Tab,Key,X3 :: UpdateOp,Default) - >结果

update_counter(Tab,Key,Incr) - >结果

update_counter(Tab,Key,Incr,Default) - >结果

类型

此函数提供了更新一个或多个计数器的有效方法,而不必查找对象,通过递增元素来更新对象,并将结果对象再次插入表中。(更新是以原子方式完成的,也就是说,在操作过程中没有进程可以访问ETS表。)

该函数通过添加到位置上的元素来破坏性地用Key表格中Tab的键更新对象。新的计数器值被返回。如果没有指定位置,则直接在key()后面的元素将被更新。IncrPos<keypos>+1

如果Threshold,则将计数器重置为值。SetValue如果出现下列情况:

  • Incr不是负数(>= 0),结果会大于(>Threshold
  • Incr是负数(< 0),结果会小于(<Threshold

一份清单UpdateOp可以提供用于在对象中执行许多更新操作。这些操作按照列表中指定的顺序执行。如果同一计数器位置在列表中发生多次,则相应计数器因此被更新多次,每次都基于先前的结果。返回值是来自每个更新操作的新计数器值的列表,其顺序与操作列表中的顺序相同。如果指定了空列表,则不会更新任何内容,并返回空列表。如果函数失败,则不会进行任何更新。

指定Key用于由任一识别对象相匹配的对象的密钥set表,或比较相等的一个对象的在密钥ordered_set表(该差值详见lookup/2new/2)。

如果默认对象Default如果表中缺少键,则将其用作要更新的对象。替换键的值将被忽略,并由适当的键值替换。返回值就好像没有使用默认对象一样,也就是说,一个更新的元素或它们的列表。

该函数有原因失败badarg在下列情况下:

  • 表类型不是setordered_set...
  • 不存在具有正确键的对象,也没有提供默认对象。
  • 对象有错误的特性。
  • 默认对象性小于<keypos>...
  • 更新的默认对象中的任何字段都不是整数。
  • 要更新的元素不是整数。
  • 要更新的元素也是关键。
  • 任何的PosIncrThreshold,或SetValue不是整数。

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

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

布尔值%28%29

类型

该函数提供了一种有效的方法来更新对象中的一个或多个元素,而无需查找、更新和写回整个对象。

此函数用键破坏性地更新对象。Key表中Tab.位置上的元素Pos给出的值Value...

一份清单{Pos,Value}可以提供来更新同一对象中的许多元素。如果同一位置在列表中发生多次,则会写入列表中的最后一个值。如果列表为空或函数失败,则不会进行任何更新。函数也是原子的,因为其他进程永远看不到任何中间结果。

回报true如果具有键的对象Key被找到,否则false...

指定Key用于由任一识别对象相匹配的对象的密钥set表,或比较相等的一个对象的在密钥ordered_set表(该差值详见lookup/2new/2)。

该函数有原因失败badarg在下列情况下:

  • 表类型不是setordered_set...
  • Pos<1.
  • Pos>对象性。
  • 要更新的元素也是关键。

扫码关注腾讯云开发者

领取腾讯云代金券