檢視原始碼 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
,並且從某個表格 T
使用 bchunk/2
讀取的物件來初始化表格 Name
,則傳回 true
,使得呼叫 info(T, bchunk_format)
傳回 BchunkFormat
。
如果檔案 Filename
是 Dets 表格,則傳回 true
,否則傳回 false
。
傳回表格 Name
中儲存的所有鍵為 Key
的物件清單,例如
以未指定的順序,針對表格 Name
中與 Pattern
比對的每個物件,傳回繫結清單。有關模式的描述,請參閱 ets:match/2
。如果 Pattern
的 keypos'th 元素是未繫結的,則會比對所有表格物件。如果 keypos'th 元素是繫結的,則只會比對具有正確鍵的物件。
比對表格 Name
的部分或所有物件,並以未指定的順序傳回與 Pattern
比對的非空繫結清單。有關模式的描述,請參閱 ets:match/2
。
從表格 Name
中刪除所有與 Pattern
比對的物件。有關模式的描述,請參閱 ets:match/2
。
以未指定的順序傳回表格中儲存的某些與指定模式比對的非空物件清單。表格、模式和比對的物件數量都由 Continuation
定義,此 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 檔案的內容會刷新到磁碟。
返回查詢列表解析 (Query List Comprehension, QLC) 查詢句柄。qlc
模組提供主要針對 Mnesia 的查詢語言,但 qlc
也將 ETS 表格、Dets 表格和列表識別為資料來源。呼叫 dets:table/1,2
是使 Dets 表格 Name
可供 qlc
使用的方法。
將 Dets 表格 Name
的物件插入到 ETS 表格 EtsTab
中。插入物件的順序未指定。ETS 表格的現有物件會保留,除非被覆寫。
以未指定的順序將 Fun
應用於表格 Name
中儲存的每個物件。根據 Fun
的傳回值會採取不同的動作。允許下列 Fun
的傳回值
將 Incr
加到表格 Name
中儲存的 set
類型且鍵為 Key
的物件位於第 Pos
個位置的元素,以更新該物件。返回新的計數器值。如果未指定位置,則會更新緊接在鍵之後的元素。
類型
-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().
傳回表格中儲存的物件清單。傳回物件的確切表示法不是公開的。
資料列表可用於透過指定函數 init_table/3
的選項 format
的值 bchunk
來初始化表格。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
是將表格固定RefCount
次的進程 PID。列表中可以有任意數量的進程。如果表格未被固定,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
,並且從某個表格 T
使用 bchunk/2
讀取的物件來初始化表格 Name
,則傳回 true
,使得呼叫 info(T, bchunk_format)
傳回 BchunkFormat
。
-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
定義,此 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().
以未指定的順序,針對表格 Name
中與 Pattern
比對的每個物件,傳回繫結清單。有關模式的描述,請參閱 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
定義,此 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 元素已綁定,則只會匹配具有正確鍵的物件。
使用 match_object
函數來遍歷所有表格物件,比呼叫 first/1
和 next/2
或 slot/2
更有效率。
-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().
此函數可用於還原 select/3
或 select/1
返回的不透明續程 (continuation),如果續程已通過外部術語格式(已在節點之間傳送或儲存在磁碟上)。
此函數的原因是,接續詞 (continuation terms) 包含編譯後的匹配規範 (match specifications),因此如果轉換為外部詞語格式,則會失效。由於原始匹配規範保持不變,因此可以還原接續詞,這表示即使它已儲存在磁碟或另一個節點上,也可以再次用於後續的 select/1
呼叫中。
如需更多資訊和範例,請參閱 ets
模組。
注意
此函數在應用程式程式碼中很少需要。它由應用程式 Mnesia 用來提供分散式
select/3
和select/1
序列。一般的應用程式會使用 Mnesia,或者讓接續詞不轉換為外部格式。沒有編譯後的匹配規範的外部表示形式的原因是效能考量。它在未來版本中可能會有所變更,而此介面會保持向後相容性。
如果 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().
將比對規格 (match specification) 應用到表格中儲存的一些物件,並返回非空的結果列表。表格、比對規格和比對的物件數量都由 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'th 元素未繫結,則匹配規範會套用至表格的所有物件。如果 keypos'th 元素已繫結,則匹配規範僅套用至具有正確鍵的物件。
-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 使用者指南。
會返回套用匹配規範的結果和接續詞的元組,除非表格為空,在這種情況下,會返回 '$end_of_table'
。接續詞會在呼叫 select/1
時用來匹配更多物件。
如果 MatchSpec
的 keypos'th 元素已繫結,則匹配規範會套用至表格中具有正確鍵的所有物件。如果 MatchSpec
的 keypos'th 元素未繫結,則匹配規範會一次套用至表格的所有物件,一次套用 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'th 元素已繫結,則匹配規範僅會套用至具有正確鍵的物件。
-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 中維護的空間管理資料結構 (buddy system) 也會寫入磁碟。如果表格分散,則可能需要一些時間。
-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().
返回查詢列表解析 (Query List Comprehension, 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
加到表格 Name
中儲存的 set
類型且鍵為 Key
的物件位於第 Pos
個位置的元素,以更新該物件。返回新的計數器值。如果未指定位置,則會更新緊接在鍵之後的元素。
此函數提供了一種更新計數器的方法,而無需查找物件、透過遞增元素來更新物件,然後再次將結果物件插入表格。