查看源代码 dets (stdlib v6.2)
基于磁盘的项存储。
此模块提供文件上的项存储。在此模块中,存储的项称为对象,是元组,其中一个元素定义为键。Dets 表是在文件中存储的键位于相同位置的对象集合。
Mnesia 应用程序使用此模块,并为那些仅对磁盘上高效存储 Erlang 项感兴趣的用户“按原样”提供。许多应用程序只需要在文件中存储一些项。Mnesia 添加了事务、查询和分布式。Dets 文件的大小不能超过 2 GB。如果需要更大的表,可以使用 Mnesia 中的表碎片化。
存在三种类型的 Dets 表
set
。这种类型的表对于给定的键最多有一个对象。如果插入一个键已存在于表中的对象,则现有对象将被新对象覆盖。bag
。这种类型的表对于给定的键有零个或多个不同的对象。duplicate_bag
。这种类型的表对于给定的键有零个或多个可能匹配的对象。
Dets 表必须先打开才能更新或读取,完成后必须正确关闭。如果表未正确关闭,Dets 会自动修复该表。如果表很大,这可能需要相当长的时间。当打开表的进程终止时,Dets 表会被关闭。如果许多 Erlang 进程(用户)打开同一个 Dets 表,它们会共享该表。当所有用户都终止或关闭表时,该表会被正确关闭。如果 Erlang 运行时系统异常终止,则 Dets 表不会被正确关闭。
注意
在具有中断处理程序的 Unix 环境中,
^C
命令会异常终止 Erlang 运行时系统。
由于 Dets 执行的所有操作都是磁盘操作,因此必须认识到,单个查找操作涉及一系列磁盘寻道和读取操作。因此,Dets 函数比相应的 ets
函数慢得多,尽管 Dets 导出类似的接口。
Dets 将数据组织为线性哈希列表,并且随着更多数据插入表中,哈希列表会平稳增长。文件上的空间管理由所谓的伙伴系统执行。当前实现将整个伙伴系统保留在 RAM 中,这意味着如果表严重碎片化,则会占用相当多的内存。对表进行碎片整理的唯一方法是关闭它,然后使用选项 repair
设置为 force
再次打开它。
请注意,Ets 中的 ordered_set
类型尚未由 Dets 提供,对于固定 ETS 表,first
和 next
调用序列的安全使用提供的并发更新支持也有限。这两种功能都可能在 Erlang/OTP 的未来版本中由 Dets 提供。在此之前,必须使用 Mnesia 应用程序(或一些用户实现的锁定方法)来实现安全的并发性。目前,没有 Erlang/OTP 库支持基于磁盘的有序项存储。
如果发生错误,所有 Dets 函数都会返回 {error, Reason}
(first/1
和 next/2
是例外,它们会使用错误元组退出进程)。如果指定了格式错误的参数,则所有函数都会使用 badarg
消息退出进程。
另请参阅
摘要
类型
匹配规范,请参阅 ERTS 用户指南中的Erlang 中的匹配规范部分以及 ms_transform
模块。
match_object/1
和 match_object/3
使用的不透明延续。
有关模式的描述,请参阅 ets:match/2
。
函数
返回此节点上所有打开的表的名称列表。
返回表中存储的对象列表。返回对象的精确表示不是公开的。
关闭表。只有打开表的进程才能关闭它。
从表 Name
中删除所有键为 Key
的对象。
几乎以恒定的时间从表中删除所有对象。但是,如果表是固定的,delete_all_objects(T)
等效于 match_delete(T, '_')
。
从表中删除指定对象的所有实例。如果表类型为 bag
或 duplicate_bag
,则可以使用此函数仅删除某些具有指定键的对象。
根据表的内部顺序返回表 Name
中存储的第一个键,如果表为空,则返回 '$end_of_table'
。
使用额外的参数 AccIn
在表 Name
的连续元素上调用 Function
。表元素以未指定的顺序遍历。Function
必须返回一个新累加器,该累加器将传递给下一次调用。如果表为空,则返回 Acc0
。
删除表 Name
的所有对象,然后插入 ETS 表 EtsTab
的所有对象。对象以未指定的顺序插入。由于调用了 ets:safe_fixtable/2
,因此 ETS 表必须是公共的或由调用进程拥有。
返回有关表 Name
的信息,作为元组列表
返回与表 Name
的 Item
关联的信息。除了为 info/1
定义的 {Item, Value}
对之外,还允许以下项
使用调用输入函数 InitFun
创建的对象替换表 Name
的现有对象。
将一个或多个对象插入到表 Name
中。如果已经存在一个键与某些给定对象的键匹配的对象,并且表类型为 set
,则旧对象将被替换。
将一个或多个对象插入到表 Name
中。如果已经存在一个键与任何指定对象的键匹配的对象,则不会更新该表,并返回 false
。否则,将插入对象并返回 true
。
如果可以使用选项 {format, bchunk}
使用 init_table/3
初始化表 Name
,并使用 bchunk/2
从某个表 T
读取对象,并且调用 info(T, bchunk_format)
返回 BchunkFormat
,则返回 true
。
如果文件 Filename
是 Dets 表,则返回 true
,否则返回 false
。
返回存储在表 Name
中键为 Key
的所有对象列表,例如
对于与 Pattern
匹配的表 Name
的每个对象,以未指定的顺序返回绑定列表。有关模式的描述,请参阅 ets:match/2
。如果 Pattern
的 keypos'th 元素是未绑定的,则会匹配所有表对象。如果 keypos'th 元素是绑定的,则只会匹配具有正确键的对象。
匹配表 Name
的某些或全部对象,并以未指定的顺序返回与 Pattern
匹配的绑定非空列表。有关模式的描述,请参阅 ets:match/2
。
从表 Name
中删除与 Pattern
匹配的所有对象。有关模式的描述,请参阅 ets:match/2
。
以未指定的顺序返回存储在表中的某些与给定模式匹配的对象的非空列表。表、模式和匹配的对象数量均由 Continuation
定义,该延续由先前对 match_object/1
或 match_object/3
的调用返回。
以未指定的顺序返回表 Name
中与 Pattern
匹配的所有对象列表。有关模式的描述,请参阅 ets:match/2
。
匹配存储在表 Name
中的部分或所有对象,并返回一个非空列表,其中包含与 Pattern
匹配的对象,顺序不确定。有关模式的描述,请参阅 ets:match/2
。
与 lookup/2
类似,但不返回对象。如果一个或多个表元素具有键 Key
,则返回 true
,否则返回 false
。
根据表的内部顺序,返回表 Name
中键 Key1
之后的键,如果没有下一个键,则返回 '$end_of_table'
。
打开一个已存在的表。如果表没有正确关闭,则会进行修复。返回的引用将用作表名。此函数对于调试目的最有用。
打开一个表。如果文件不存在,则创建一个空的 Dets 表。
返回处理表请求的进程的 pid 所对应的表名,如果没有这样的表,则返回 undefined
。
如果 Fix
为 true
,则调用进程会(再次)固定表 Name
,否则会释放该表。当固定进程终止时,表也会被释放。
返回将匹配规范 MatchSpec
应用于存储在表 Name
中的全部或部分对象的结果。对象的顺序未指定。有关匹配规范的描述,请参阅 ERTS 用户指南。
返回将匹配规范 MatchSpec
应用于存储在表 Name
中的部分或所有对象的结果。对象的顺序未指定。有关匹配规范的描述,请参阅 ERTS 用户指南。
从表 Name
中删除每个对象,使得将匹配规范 MatchSpec
应用于该对象会返回 true
值。有关匹配规范的描述,请参阅 ERTS 用户指南。返回已删除对象的数量。
表的对象分布在槽中,从槽 0
开始,到槽 n
结束。返回与槽 I
关联的对象列表。如果 I
> n
,则返回 '$end_of_table'
。
确保对表 Name
进行的所有更新都写入磁盘。这也适用于使用标志 ram_file
设置为 true
打开的表。在这种情况下,RAM 文件的内容会被刷新到磁盘。
返回查询列表推导(QLC)查询句柄。qlc
模块提供了一种主要针对 Mnesia 的查询语言,但 qlc
也将 ETS 表、Dets 表和列表识别为数据源。调用 dets:table/1,2
是使 Dets 表 Name
可用于 qlc
的方法。
将 Dets 表 Name
的对象插入到 ETS 表 EtsTab
中。插入对象的顺序未指定。除非被覆盖,否则会保留 ETS 表的现有对象。
以某种未指定的顺序将 Fun
应用于存储在表 Name
中的每个对象。根据 Fun
的返回值采取不同的操作。允许使用以下 Fun
返回值
通过将 Incr
添加到 Pos
:th 位置的元素,更新存储在类型为 set
的表 Name
中键为 Key
的对象。返回新的计数器值。如果未指定位置,则更新紧跟在键之后的元素。
类型
-type access() :: read | read_write.
-type auto_save() :: infinity | non_neg_integer().
-opaque bindings_cont()
-opaque cont()
bchunk/2
使用的不透明延续。
-type keypos() :: pos_integer().
-type match_spec() :: ets:match_spec().
匹配规范,请参阅 ERTS 用户指南中的Erlang 中的匹配规范部分以及 ms_transform
模块。
-type no_slots() :: default | non_neg_integer().
-type object() :: tuple().
-opaque object_cont()
match_object/1
和 match_object/3
使用的不透明延续。
有关模式的描述,请参阅 ets:match/2
。
-opaque select_cont()
-type tab_name() :: term().
-type type() :: bag | duplicate_bag | set.
函数
-spec all() -> [tab_name()].
返回此节点上所有打开的表的名称列表。
-spec bchunk(Name, Continuation) -> {Continuation2, Data} | '$end_of_table' | {error, Reason} when Name :: tab_name(), Continuation :: start | cont(), Continuation2 :: cont(), Data :: binary() | tuple(), Reason :: term().
返回表中存储的对象列表。返回对象的精确表示不是公开的。
数据列表可以通过将值 bchunk
指定给函数 init_table/3
的选项 format
来用于初始化表。Mnesia 应用程序使用此函数来复制打开的表。
除非使用 safe_fixtable/2
保护表,否则如果同时对表进行更新,则调用 bchunk/2
可能无法按预期工作。
第一次调用 bchunk/2
时,必须提供初始延续符,即原子 start
。
bchunk/2
返回一个元组 {Continuation2, Data}
,其中 Data
是一个对象列表。Continuation2
是另一个延续符,将传递给后续调用 bchunk/2
。通过一系列对 bchunk/2
的调用,可以提取所有表对象。
当返回所有对象时,bchunk/2
返回 '$end_of_table'
,如果发生错误,则返回 {error, Reason}
。
关闭表。只有打开表的进程才能关闭它。
在系统停止之前,必须关闭所有打开的表。如果尝试打开未正确关闭的表,Dets 会自动尝试修复它。
-spec delete(Name, Key) -> ok | {error, Reason} when Name :: tab_name(), Key :: term(), Reason :: term().
从表 Name
中删除所有键为 Key
的对象。
几乎以恒定的时间从表中删除所有对象。但是,如果表是固定的,delete_all_objects(T)
等效于 match_delete(T, '_')
。
-spec delete_object(Name, Object) -> ok | {error, Reason} when Name :: tab_name(), Object :: object(), Reason :: term().
从表中删除指定对象的所有实例。如果表类型为 bag
或 duplicate_bag
,则可以使用此函数仅删除某些具有指定键的对象。
根据表的内部顺序返回表 Name
中存储的第一个键,如果表为空,则返回 '$end_of_table'
。
除非使用 safe_fixtable/2
保护表,否则如果同时对表进行更新,则后续调用 next/2
可能无法按预期工作。
如果发生错误,进程将退出并显示错误元组 {error, Reason}
。错误元组不会返回,因为它无法与键区分开来。
有两个原因不应使用 first/1
和 next/2
:它们效率不高,并且会阻止使用键 '$end_of_table'
,因为此原子用于指示表的末尾。如果可能,请使用函数 match
、match_object
和 select
来遍历表。
-spec foldl(Function, Acc0, Name) -> Acc | {error, Reason} when Name :: tab_name(), Function :: fun((Object :: object(), AccIn) -> AccOut), Acc0 :: term(), Acc :: term(), AccIn :: term(), AccOut :: term(), Reason :: term().
等效于 foldr/3
。
-spec foldr(Function, Acc0, Name) -> Acc | {error, Reason} when Name :: tab_name(), Function :: fun((Object :: object(), AccIn) -> AccOut), Acc0 :: term(), Acc :: term(), AccIn :: term(), AccOut :: term(), Reason :: term().
使用额外的参数 AccIn
在表 Name
的连续元素上调用 Function
。表元素以未指定的顺序遍历。Function
必须返回一个新累加器,该累加器将传递给下一次调用。如果表为空,则返回 Acc0
。
-spec from_ets(Name, EtsTab) -> ok | {error, Reason} when Name :: tab_name(), EtsTab :: ets:table(), Reason :: term().
删除表 Name
的所有对象,然后插入 ETS 表 EtsTab
的所有对象。对象以未指定的顺序插入。由于调用了 ets:safe_fixtable/2
,因此 ETS 表必须是公共的或由调用进程拥有。
-spec info(Name) -> InfoList | undefined when Name :: tab_name(), InfoList :: [InfoTuple], InfoTuple :: {file_size, non_neg_integer()} | {filename, file:name()} | {keypos, keypos()} | {size, non_neg_integer()} | {type, type()}.
返回有关表 Name
的信息,作为元组列表
{file_size, integer() >= 0}}
- 文件大小,以字节为单位。{filename,
file:name/0
}
- 存储对象的文件名。{keypos,
keypos/0
}
- 键的位置。{size, integer() >= 0}
- 表中存储的对象数量。{type,
type/0
}
- 表的类型。
-spec info(Name, Item) -> Value | undefined when Name :: tab_name(), Item :: access | auto_save | bchunk_format | hash | file_size | filename | keypos | memory | no_keys | no_objects | no_slots | owner | ram_file | safe_fixed | safe_fixed_monotonic_time | size | type, Value :: term().
返回与表 Name
的 Item
关联的信息。除了为 info/1
定义的 {Item, Value}
对之外,还允许以下项
{access,
access/0
}
- 访问模式。{auto_save,
auto_save/0
}
- 自动保存间隔。{bchunk_format, binary()}
- 一个不透明的二进制文件,描述bchunk/2
返回的对象格式。该二进制文件可以用作is_compatible_bchunk_format/2
的参数。{hash, Hash}
- 描述哪个 BIF 用于计算存储在 Dets 表中的对象的哈希值。Hash
的可能值phash
- 表示使用erlang:phash/2
BIF。phash2
- 表示使用erlang:phash2/1
BIF。
{memory, integer() >= 0}
- 文件大小,以字节为单位。该值与file_size
项关联的值相同。{no_keys, integer >= 0()}
- 表中存储的不同键的数量。{no_objects, integer >= 0()}
- 表中存储的对象数量。{no_slots, {Min, Used, Max}}
- 表的槽位数。Min
是最小槽位数,Used
是当前已使用的槽位数,Max
是最大槽位数。{owner, pid()}
- 处理 Dets 表请求的进程的 pid。{ram_file, boolean()}
- 表是否保存在 RAM 中。{safe_fixed_monotonic_time, SafeFixed}
- 如果表是固定的,则SafeFixed
是一个元组{FixedAtTime, [{Pid,RefCount}]}
。FixedAtTime
是表首次被固定的时间,Pid
是固定该表的进程的 pid,RefCount
是该进程固定表的次数。列表中可以有任意数量的进程。如果表未被固定,则SafeFixed
是原子false
。FixedAtTime
对应于erlang:monotonic_time/0
在固定时返回的结果。使用safe_fixed_monotonic_time
是 时间扭曲安全的。{safe_fixed, SafeFixed}
- 与{safe_fixed_monotonic_time, SafeFixed}
相同,只是FixedAtTime
的格式和值不同。FixedAtTime
对应于erlang:timestamp/0
在固定时返回的结果。请注意,当系统使用单或多 时间扭曲模式 时,这可能会产生奇怪的结果。这是因为使用safe_fixed
不是 时间扭曲安全的。时间扭曲安全的代码必须使用safe_fixed_monotonic_time
来代替。
-spec init_table(Name, InitFun, Options) -> ok | {error, Reason} when Name :: tab_name(), InitFun :: fun((Arg) -> Res), Arg :: read | close, Res :: end_of_input | {[object()], InitFun} | {Data, InitFun} | term(), Options :: Option | [Option], Option :: {min_no_slots, no_slots()} | {format, term | bchunk}, Reason :: term(), Data :: binary() | tuple().
使用调用输入函数 InitFun
创建的对象替换表 Name
的现有对象。
使用此函数而不是调用 insert/2
的原因是效率更高。请注意,输入函数是由处理 Dets 表请求的进程调用的,而不是由调用进程调用的。
当使用参数 read
调用时,假设函数 InitFun
在没有更多输入时返回 end_of_input
,或者返回 {Objects, Fun}
,其中 Objects
是一个对象列表,Fun
是一个新的输入函数。任何其他值 Value
都作为错误 {error, {init_fun, Value}}
返回。每个输入函数都会被精确调用一次,如果发生错误,则最后一个函数会使用参数 close
调用,其回复将被忽略。
如果表类型为 set
且存在多个具有给定键的对象,则会选择其中一个对象。这不一定是输入函数返回的对象序列中具有给定键的最后一个对象。避免重复的键,否则文件会不必要地碎片化。这对于存储在 bag
类型的表中的重复对象也适用。
重要的是,表具有足够数量的槽位来存储对象。如果没有,哈希列表会在 init_table/2
返回时开始增长,这会在一段时间内显著降低对表的访问速度。最小槽位数由 open_file/2
选项 min_no_slots
设置,并由 info/2
项 no_slots
返回。另请参见下面的选项 min_no_slots
。
参数 Options
是一个 {Key, Val}
元组列表,其中允许以下值
{min_no_slots, no_slots()}
- 指定要存储在表中的不同键的估计数量。忽略具有相同名称的open_file/2
选项,除非创建表,在这种情况下,在初始化表时提供估计值可以提高性能。{format, Format}
- 指定函数InitFun
返回的对象的格式。如果Format
是term
(默认值),则假设InitFun
返回一个元组列表。如果Format
是bchunk
,则假设InitFun
返回由bchunk/2
返回的Data
。此选项会覆盖选项min_no_slots
。
-spec insert(Name, Objects) -> ok | {error, Reason} when Name :: tab_name(), Objects :: object() | [object()], Reason :: term().
将一个或多个对象插入到表 Name
中。如果已经存在一个键与某些给定对象的键匹配的对象,并且表类型为 set
,则旧对象将被替换。
-spec insert_new(Name, Objects) -> boolean() | {error, Reason} when Name :: tab_name(), Objects :: object() | [object()], Reason :: term().
将一个或多个对象插入到表 Name
中。如果已经存在一个键与任何指定对象的键匹配的对象,则不会更新该表,并返回 false
。否则,将插入对象并返回 true
。
-spec is_compatible_bchunk_format(Name, BchunkFormat) -> boolean() when Name :: tab_name(), BchunkFormat :: binary().
如果可以使用选项 {format, bchunk}
使用 init_table/3
初始化表 Name
,并使用 bchunk/2
从某个表 T
读取对象,并且调用 info(T, bchunk_format)
返回 BchunkFormat
,则返回 true
。
-spec is_dets_file(Filename) -> boolean() | {error, Reason} when Filename :: file:name(), Reason :: term().
如果文件 Filename
是 Dets 表,则返回 true
,否则返回 false
。
-spec lookup(Name, Key) -> Objects | {error, Reason} when Name :: tab_name(), Key :: term(), Objects :: [object()], Reason :: term().
返回存储在表 Name
中键为 Key
的所有对象列表,例如
2> dets:open_file(abc, [{type, bag}]).
{ok,abc}
3> dets:insert(abc, {1,2,3}).
ok
4> dets:insert(abc, {1,3,4}).
ok
5> dets:lookup(abc, 1).
[{1,2,3},{1,3,4}]
如果表类型为 set
,则该函数返回空列表或包含一个对象的列表,因为不能有多个具有给定键的对象。如果表类型为 bag
或 duplicate_bag
,则该函数返回任意长度的列表。
请注意,返回的对象的顺序是未指定的。特别是,不反映插入对象的顺序。
-spec match(Continuation) -> {[Match], Continuation2} | '$end_of_table' | {error, Reason} when Continuation :: bindings_cont(), Continuation2 :: bindings_cont(), Match :: [term()], Reason :: term().
匹配存储在表中的一些对象,并以未指定的顺序返回与指定模式匹配的绑定非空列表。表、模式和匹配的对象数量均由 Continuation
定义,该延续由先前对 match/1
或 match/3
的调用返回。
当所有表对象都匹配时,将返回 '$end_of_table'
。
-spec match(Name, Pattern) -> [Match] | {error, Reason} when Name :: tab_name(), Pattern :: pattern(), Match :: [term()], Reason :: term().
对于与 Pattern
匹配的表 Name
的每个对象,以未指定的顺序返回绑定列表。有关模式的描述,请参阅 ets:match/2
。如果 Pattern
的 keypos'th 元素是未绑定的,则会匹配所有表对象。如果 keypos'th 元素是绑定的,则只会匹配具有正确键的对象。
-spec match(Name, Pattern, N) -> {[Match], Continuation} | '$end_of_table' | {error, Reason} when Name :: tab_name(), Pattern :: pattern(), N :: default | non_neg_integer(), Continuation :: bindings_cont(), Match :: [term()], Reason :: term().
匹配表 Name
的某些或全部对象,并以未指定的顺序返回与 Pattern
匹配的绑定非空列表。有关模式的描述,请参阅 ets:match/2
。
返回绑定和延续的元组,除非表为空,在这种情况下将返回 '$end_of_table'
。延续符用于通过调用 match/1
来匹配更多对象。
如果 Pattern
的 keypos'th 元素已绑定,则会匹配所有表对象。如果 keypos'th 元素未绑定,则会一次匹配 N
个表对象,直到至少一个对象匹配或到达表的末尾。默认值(由 N
的值 default
表示)是让对象的数量根据对象的大小而变化。具有相同键的所有对象始终同时匹配,这意味着有时可以匹配超过 N 个对象。
始终必须在使用 match/3
之前使用 safe_fixtable/2
保护表,否则在调用 match/1
时可能会发生错误。
-spec match_delete(Name, Pattern) -> ok | {error, Reason} when Name :: tab_name(), Pattern :: pattern(), Reason :: term().
从表 Name
中删除与 Pattern
匹配的所有对象。有关模式的描述,请参阅 ets:match/2
。
如果 Pattern
的 keypos'th 元素已绑定,则只会匹配具有正确键的对象。
-spec match_object(Continuation) -> {Objects, Continuation2} | '$end_of_table' | {error, Reason} when Continuation :: object_cont(), Continuation2 :: object_cont(), Objects :: [object()], Reason :: term().
以未指定的顺序返回存储在表中的某些与给定模式匹配的对象的非空列表。表、模式和匹配的对象数量均由 Continuation
定义,该延续由先前对 match_object/1
或 match_object/3
的调用返回。
当所有表对象都匹配时,将返回 '$end_of_table'
。
-spec match_object(Name, Pattern) -> Objects | {error, Reason} when Name :: tab_name(), Pattern :: pattern(), Objects :: [object()], Reason :: term().
以未指定的顺序返回表 Name
中与 Pattern
匹配的所有对象列表。有关模式的描述,请参阅 ets:match/2
。
如果 Pattern
的 keypos'th 元素未绑定,则会匹配所有表对象。如果 Pattern
的 keypos'th 元素已绑定,则只会匹配具有正确键的对象。
-spec match_object(Name, Pattern, N) -> {Objects, Continuation} | '$end_of_table' | {error, Reason} when Name :: tab_name(), Pattern :: pattern(), N :: default | non_neg_integer(), Continuation :: object_cont(), Objects :: [object()], Reason :: term().
匹配存储在表 Name
中的部分或所有对象,并返回一个非空列表,其中包含与 Pattern
匹配的对象,顺序不确定。有关模式的描述,请参阅 ets:match/2
。
返回一个对象列表和一个延续符,除非表为空,在这种情况下返回 '$end_of_table'
。延续符用于通过调用 match_object/1
来匹配更多对象。
如果 Pattern
的 keypos'th 元素已绑定,则会匹配所有表对象。如果 keypos'th 元素未绑定,则会一次匹配 N
个表对象,直到至少一个对象匹配或到达表的末尾。默认值(由 N
的值 default
表示)是让对象的数量根据对象的大小而变化。具有相同键的所有匹配对象始终在相同的回复中返回,这意味着有时可以返回超过 N 个对象。
始终必须在使用 match_object/3
之前使用 safe_fixtable/2
保护表,否则在调用 match_object/1
时可能会发生错误。
-spec member(Name, Key) -> boolean() | {error, Reason} when Name :: tab_name(), Key :: term(), Reason :: term().
与 lookup/2
类似,但不返回对象。如果一个或多个表元素具有键 Key
,则返回 true
,否则返回 false
。
-spec next(Name, Key1) -> Key2 | '$end_of_table' when Name :: tab_name(), Key1 :: term(), Key2 :: term().
根据表的内部顺序,返回表 Name
中键 Key1
之后的键,如果没有下一个键,则返回 '$end_of_table'
。
如果发生错误,进程将以错误元组 {error, Reason}
退出。
要查找表中的第一个键,请使用 first/1
。
-spec open_file(Filename) -> {ok, Reference} | {error, Reason} when Filename :: file:name(), Reference :: reference(), Reason :: term().
打开一个已存在的表。如果表没有正确关闭,则会进行修复。返回的引用将用作表名。此函数对于调试目的最有用。
-spec open_file(Name, Args) -> {ok, Name} | {error, Reason} when Name :: tab_name(), Args :: [OpenArg], OpenArg :: {access, access()} | {auto_save, auto_save()} | {estimated_no_objects, non_neg_integer()} | {file, file:name()} | {max_no_slots, no_slots()} | {min_no_slots, no_slots()} | {keypos, keypos()} | {ram_file, boolean()} | {repair, boolean() | force} | {type, type()}, Reason :: term().
打开一个表。如果文件不存在,则创建一个空的 Dets 表。
原子 Name
是表名。在对表进行所有后续操作时,必须提供表名。该名称也可以由其他进程使用,并且许多进程可以共享一个表。
如果两个进程通过提供相同的名称和参数打开同一个表,则该表有两个用户。如果一个用户关闭了表,它将保持打开状态,直到第二个用户关闭它。
参数 Args
是 {Key, Val}
元组的列表,其中允许以下值
{access,
access/0
}
- 现有的表可以在只读模式下打开。如果以后在崩溃后重新打开,以只读模式打开的表不会进行自动文件修复算法。默认为read_write
。{auto_save,
auto_save/0
}
- 自动保存间隔。如果间隔是整数Time
,则只要在Time
毫秒内未访问该表,就会将该表刷新到磁盘。刷新后的表在不受控制的仿真器停止后重新打开时无需修复。如果间隔是原子infinity
,则禁用自动保存。默认为 180000(3 分钟)。{estimated_no_objects,
no_slots/0
}
- 等效于选项min_no_slots
。{file,
file:name/0
}
- 要打开的文件的名称。默认为表名。{max_no_slots,
no_slots/0
}
- 要使用的最大槽位数。默认为 32 M,即最大值。请注意,较高的值可能会增加表碎片,而较小的值可以减少碎片,但会牺牲执行时间。{min_no_slots,
no_slots/0
}
- 通过此标志,可以在创建表时指定估计要存储在表中的不同键的数量,从而提高应用程序性能。默认为 256,这是最小值。{keypos,
keypos/0
}
- 用作键的每个对象的元素的位置。默认为 1。当我们想存储 Erlang 记录时,显式声明键位置的能力非常方便,其中记录的第一个位置是记录类型的名称。{ram_file, boolean()}
- 表是否要保存在 RAM 中。将表保存在 RAM 中听起来可能有些反常,但可以提高应用程序的性能,这些应用程序打开一个表,插入一组对象,然后关闭表。当表关闭时,其内容将写入磁盘文件。默认为false
。{repair, Value}
-Value
可以是boolean/0
或者原子force
。该标志指定 Dets 服务器是否调用自动文件修复算法。默认为true
。如果指定了false
,则不尝试修复文件,如果必须修复表,则返回{error, {needs_repair, FileName}}
。值
force
表示即使表已正确关闭,也会进行修复。这是一个很少需要的选项。如果表已打开,则忽略选项
repair
。{type,
type/0
}
- 表类型。默认为set
。
返回处理表请求的进程的 pid 所对应的表名,如果没有这样的表,则返回 undefined
。
此函数仅用于调试。
-spec repair_continuation(Continuation, MatchSpec) -> Continuation2 when Continuation :: select_cont(), Continuation2 :: select_cont(), MatchSpec :: match_spec().
如果延续符(Continuation)已经通过外部术语格式(在节点之间发送或存储在磁盘上),则可以使用此函数来恢复由 select/3
或 select/1
返回的不透明延续符。
此函数的原因是 continuation term 包含已编译的匹配规范,因此如果转换为外部 term 格式,则会失效。鉴于原始匹配规范保持不变,可以恢复 continuation,这意味着即使它已存储在磁盘上或另一个节点上,也可以再次在后续的 select/1
调用中使用。
有关更多信息和示例,请参阅 ets
模块。
注意
此函数在应用程序代码中很少需要。它由应用程序 Mnesia 使用,以提供分布式
select/3
和select/1
序列。正常的应用程序将使用 Mnesia 或使 continuation 不被转换为外部格式。不使用已编译的匹配规范的外部表示形式的原因是为了性能。它可能会在未来的版本中发生更改,而此接口将保持向后兼容性。
如果 Fix
为 true
,则调用进程会(再次)固定表 Name
,否则会释放该表。当固定进程终止时,表也会被释放。
如果许多进程固定一个表,则该表将保持固定状态,直到所有进程都释放它或终止为止。每个进程都会维护一个引用计数器,并且 N 个连续的固定需要 N 个释放才能释放表。
即使表已固定,也不能保证对 first/1
,next/2
或 select 和 match 函数的调用按预期工作; ets
模块提供的有限并发性尚未由 Dets 提供。固定表目前仅禁用调整表哈希列表的大小。
如果在表被固定时添加了对象,则在表释放时哈希列表开始增长,这会显著减慢一段时间内对表的访问速度。
-spec select(Continuation) -> {Selection, Continuation2} | '$end_of_table' | {error, Reason} when Continuation :: select_cont(), Continuation2 :: select_cont(), Selection :: [term()], Reason :: term().
将匹配规范应用于存储在表中的某些对象,并返回一个非空的结果列表。表、匹配规范和匹配的对象数量都由 Continuation
定义,而 Continuation
是先前调用 select/1
或 select/3
返回的。
当表的所有对象都匹配时,将返回 '$end_of_table'
。
-spec select(Name, MatchSpec) -> Selection | {error, Reason} when Name :: tab_name(), MatchSpec :: match_spec(), Selection :: [term()], Reason :: term().
返回将匹配规范 MatchSpec
应用于存储在表 Name
中的全部或部分对象的结果。对象的顺序未指定。有关匹配规范的描述,请参阅 ERTS 用户指南。
如果 MatchSpec
的第 keypos 个元素未绑定,则匹配规范将应用于表的所有对象。如果第 keypos 个元素已绑定,则匹配规范仅应用于具有正确键的对象。
-spec select(Name, MatchSpec, N) -> {Selection, Continuation} | '$end_of_table' | {error, Reason} when Name :: tab_name(), MatchSpec :: match_spec(), N :: default | non_neg_integer(), Continuation :: select_cont(), Selection :: [term()], Reason :: term().
返回将匹配规范 MatchSpec
应用于存储在表 Name
中的部分或所有对象的结果。对象的顺序未指定。有关匹配规范的描述,请参阅 ERTS 用户指南。
将返回应用匹配规范的结果的元组和一个 continuation,除非表为空,在这种情况下将返回 '$end_of_table'
。当通过调用 select/1
匹配更多对象时,将使用该 continuation。
如果 MatchSpec
的第 keypos 个元素已绑定,则匹配规范将应用于表中具有正确键的所有对象。如果 MatchSpec
的第 keypos 个元素未绑定,则匹配规范将应用于表的所有对象,一次 N
个对象,直到至少一个对象匹配或到达表末尾为止。默认值(由给 N
赋值 default
表示)是让对象的数量根据对象的大小而变化。具有相同键的所有对象始终同时处理,这意味着匹配规范可以应用于超过 N 个对象。
在调用 select/3
之前,始终必须使用 safe_fixtable/2
保护表,否则在调用 select/1
时可能会发生错误。
-spec select_delete(Name, MatchSpec) -> N | {error, Reason} when Name :: tab_name(), MatchSpec :: match_spec(), N :: non_neg_integer(), Reason :: term().
从表 Name
中删除每个对象,使得将匹配规范 MatchSpec
应用于该对象会返回 true
值。有关匹配规范的描述,请参阅 ERTS 用户指南。返回已删除对象的数量。
如果 MatchSpec
的第 keypos 个元素已绑定,则匹配规范仅应用于具有正确键的对象。
-spec slot(Name, I) -> '$end_of_table' | Objects | {error, Reason} when Name :: tab_name(), I :: non_neg_integer(), Objects :: [object()], Reason :: term().
表的对象分布在槽中,从槽 0
开始,到槽 n
结束。返回与槽 I
关联的对象列表。如果 I
> n
,则返回 '$end_of_table'
。
确保对表 Name
进行的所有更新都写入磁盘。这也适用于使用标志 ram_file
设置为 true
打开的表。在这种情况下,RAM 文件的内容会被刷新到磁盘。
请注意,保存在 RAM 中的空间管理数据结构(伙伴系统)也会写入磁盘。如果表碎片化,则可能需要一些时间。
-spec table(Name) -> QueryHandle when Name :: tab_name(), QueryHandle :: qlc:query_handle().
等效于 table(Name, [])
。
-spec table(Name, Options) -> QueryHandle when Name :: tab_name(), Options :: Option | [Option], Option :: {n_objects, Limit} | {traverse, TraverseMethod}, Limit :: default | pos_integer(), TraverseMethod :: first_next | select | {select, match_spec()}, QueryHandle :: qlc:query_handle().
返回查询列表推导(QLC)查询句柄。qlc
模块提供了一种主要针对 Mnesia 的查询语言,但 qlc
也将 ETS 表、Dets 表和列表识别为数据源。调用 dets:table/1,2
是使 Dets 表 Name
可用于 qlc
的方法。
当对键位置只有简单限制时,qlc
使用 dets:lookup/2
来查找键。当无法做到这一点时,将遍历整个表。选项 traverse
确定如何执行此操作。
first_next
- 通过调用dets:first/1
和dets:next/2
,一次遍历一个键。select
- 通过调用dets:select/3
和dets:select/1
遍历表。选项n_objects
确定返回的对象数(select/3
的第三个参数)。匹配规范(select/3
的第二个参数)由qlc
组装。- 简单的过滤器会转换为等效的匹配规范。
- 更复杂的过滤器必须应用于
select/3
返回的所有对象,给定一个匹配所有对象的匹配规范。
{select,
match_spec/0
}
- 与select
相同,通过调用dets:select/3
和dets:select/1
来遍历表。区别在于匹配规范是显式指定的。这就是如何声明无法在qlc
提供的语法中轻松表达的匹配规范。
以下示例使用显式匹配规范来遍历表
1> dets:open_file(t, []),
ok = dets:insert(t, [{1,a},{2,b},{3,c},{4,d}]),
MS = ets:fun2ms(fun({X,Y}) when (X > 1) or (X < 5) -> {Y} end),
QH1 = dets:table(t, [{traverse, {select, MS}}]).
一个带有隐式匹配规范的示例
2> QH2 = qlc:q([{Y} || {X,Y} <- dets:table(t), (X > 1) or (X < 5)]).
后一个示例等效于前一个示例,可以使用函数 qlc:info/1
进行验证
3> qlc:info(QH1) =:= qlc:info(QH2).
true
qlc:info/1
返回有关查询句柄的信息。在这种情况下,为两个查询句柄返回相同的信息。
-spec to_ets(Name, EtsTab) -> EtsTab | {error, Reason} when Name :: tab_name(), EtsTab :: ets:table(), Reason :: term().
将 Dets 表 Name
的对象插入到 ETS 表 EtsTab
中。插入对象的顺序未指定。除非被覆盖,否则会保留 ETS 表的现有对象。
-spec traverse(Name, Fun) -> Return | {error, Reason} when Name :: tab_name(), Fun :: fun((Object) -> FunReturn), Object :: object(), FunReturn :: continue | {continue, Val} | {done, Value} | OtherValue, Return :: [term()] | OtherValue, Val :: term(), Value :: term(), OtherValue :: term(), Reason :: term().
以某种未指定的顺序将 Fun
应用于存储在表 Name
中的每个对象。根据 Fun
的返回值采取不同的操作。允许使用以下 Fun
返回值
continue
- 继续执行遍历。例如,以下函数可用于打印表的内容fun(X) -> io:format("~p~n", [X]), continue end.
{continue, Val}
- 继续遍历并累积Val
。提供以下函数以在列表中收集表的所有对象fun(X) -> {continue, X} end.
{done, Value}
- 终止遍历并返回[Value | Acc]
。
Fun
返回的任何其他值 OtherValue
都会终止遍历并立即返回。
-spec update_counter(Name, Key, Increment) -> Result when Name :: tab_name(), Key :: term(), Increment :: {Pos, Incr} | Incr, Pos :: integer(), Incr :: integer(), Result :: integer().
通过将 Incr
添加到 Pos
:th 位置的元素,更新存储在类型为 set
的表 Name
中键为 Key
的对象。返回新的计数器值。如果未指定位置,则更新紧跟在键之后的元素。
此函数提供了一种更新计数器的方法,而无需查找对象,通过递增元素来更新对象,并将结果对象再次插入到表中。