當前位置: 首頁>>代碼示例 >>用法及示例精選 >>正文


erlang q(QLC)用法及代碼示例


q(QLC) -> QH
q(QLC, Options) -> QH
類型:
QH = query_handle()
Options = [Option] | Option
Option = 
    {max_lookup, MaxLookup} |
    {cache, cache()} |
    cache |
    {join, Join} |
    {lookup, Lookup} |
    {unique, boolean()} |
    unique
MaxLookup = integer() >= 0 | infinity
Join = any | lookup | merge | nested_loop
Lookup = boolean() | any
QLC = query_list_comprehension()

返回 QLC 的查詢句柄。 QLC 必須是該函數的第一個參數,否則它將被評估為普通列表理解。還需要將以下行添加到源代碼中:

-include_lib("stdlib/include/qlc.hrl").

這會導致解析轉換用 fun 代替 QLC。當計算查詢句柄時,將調用(已編譯的)函數。

調用時qlc:q/1,2從 Erlang shell 中,會自動調用解析轉換。發生這種情況時,替換 QLC 的 fun 不會被編譯,而是通過以下方式進行評估erl_eval(3)。當表達式被評估時也是如此file:eval/1,2或者在調試器中。

明確地說,這是行不通的:

...
A = [X || {X} <- [{1},{2}]],
QH = qlc:q(A),
...

變量 A 綁定到列表理解的評估值 ( [1,2] )。編譯器發出錯誤消息(“參數不是查詢列表理解”); shell 進程因 badarg 原因而停止。

q(QLC) 相當於 q(QLC, [])

選項:

  • 選項 {cache, ets} 可用於緩存 QLC 的答案。每個緩存的 QLC 的答案都存儲在一個 ETS 表中。當再次評估緩存的 QLC 時,將從表中獲取答案,而不進行任何進一步的計算。因此,當已找到對緩存的QLC的所有答案時,可以清空用於緩存對QLC的限定符的答案的ETS表。選項 cache 相當於 {cache, ets}

  • 選項 {cache, list} 可用於緩存 QLC 的答案,例如 {cache, ets} 。不同之處在於答案保存在列表中(在進程堆上)。如果答案占用的 RAM 內存超過一定量,則使用臨時文件來存儲答案。選項 max_list_size 設置字節限製,並將臨時文件放置在選項 tmpdir 設置的目錄中。

    如果已知 QLC 最多評估一次,則選項 cache 無效。對於最頂層的 QLC 以及限定符列表中第一個生成器的列表表達式來說始終如此。請注意,在過濾器或回調函數中存在副作用的情況下,QLC 的答案可能會受到選項 cache 的影響。

  • 選項{unique, true}可用於刪除 QLC 的重複答案。每個 QLC 的唯一答案都存儲在一個 ETS 表中。每當知道 QLC 不再有答案時,該表就會被清空。選項unique相當於{unique, true}。如果選項unique與選項結合{cache, ets},使用了兩張 ETS 表,但完整答案僅存儲在一張表中。如果選項unique與選項結合{cache, list},答案使用排序兩次keysort/3;一次刪除重複項,一次恢複順序。

選項 cacheunique 不僅適用於 QLC 本身,還適用於查找常量、運行匹配規範和連接句柄的結果。

例子:

在以下示例中,針對 A 的每個值遍曆合並聯接的緩存結果。請注意,如果沒有選項 cache,連接將執行三次,對於 A 的每個值執行一次。

1> Q = qlc:q([{A,X,Z,W} ||
A <- [a,b,c],
{X,Z} <- [{a,1},{b,4},{c,6}],
{W,Y} <- [{2,a},{3,b},{4,c}],
X =:= Y],
{cache, list}),
io:format("~s~n", [qlc:info(Q)]).
begin
    V1 =
        qlc:q([
               P0 ||
                   P0 = {X, Z} <-
                       qlc:keysort(1, [{a, 1}, {b, 4}, {c, 6}], [])
              ]),
    V2 =
        qlc:q([
               P0 ||
                   P0 = {W, Y} <-
                       qlc:keysort(2, [{2, a}, {3, b}, {4, c}], [])
              ]),
    V3 =
        qlc:q([
               [G1 | G2] ||
                   G1 <- V1,
                   G2 <- V2,
                   element(1, G1) == element(2, G2)
              ],
              [{join, merge}, {cache, list}]),
    qlc:q([
           {A, X, Z, W} ||
               A <- [a, b, c],
               [{X, Z} | {W, Y}] <- V3,
               X =:= Y
          ])
end

sort/1,2keysort/2,3還可以用於緩存答案和刪除重複項。當排序答案緩存在列表中時,可能存儲在臨時文件中,並且不使用 ETS 表。

有時(參見table/2)表的遍曆可以通過查找鍵值來完成,假設速度很快。在某些(罕見)情況下,可能有太多鍵值需要查找。選項{max_lookup, MaxLookup}然後可以用來限製查找的數量:如果超過MaxLookup需要查找,不進行查找,而是遍曆表。默認為infinity,這意味著要查找的鍵的數量沒有限製。

例子:

在下麵的示例中,使用gb_table節中的模塊實施 QLC 表,有六個鍵可以查找:{1,a},{1,b},{1,c},{2,a},{2,b}, 和{2,c}。原因在於關鍵的兩個要素{X, Y}分別進行比較。

1> T = gb_trees:empty(),
QH = qlc:q([X || {{X,Y},_} <- gb_table:table(T),
((X == 1) or (X == 2)) andalso
((Y == a) or (Y == b) or (Y == c))]),
io:format("~s~n", [qlc:info(QH)]).
ets:match_spec_run(
       lists:flatmap(fun(K) ->
                            case
                                gb_trees:lookup(K,
                                                gb_trees:from_orddict([]))
                            of
                                {value, V} ->
                                    [{K, V}];
                                none ->
                                    []
                            end
                     end,
                     [{1, a},
                      {1, b},
                      {1, c},
                      {2, a},
                      {2, b},
                      {2, c}]),
       ets:match_spec_compile([{{{'$1', '$2'}, '_'},
                                [],
                                ['$1']}]))

選項:

  • 選項 {lookup, true} 可用於確保 qlc 模塊在某些 QLC 表中查找常量。如果生成器的列表表達式中有多個 QLC 表,則必須至少在其中一張表中查找常量。如果沒有要查找的常量,則查詢的評估將失敗。當無法接受遍曆某個表中的所有對象時,此選項非常有用。將選項 lookup 設置為 false 可確保不查找任何常量({max_lookup, 0} 具有相同的效果)。默認為 any ,這意味著隻要有可能就會查找常量。

  • 選項 {join, Join} 可用於確保使用某種連接方法:

    • {join, lookup} 調用查找連接方法。
    • {join, merge} 調用合並連接方法。
    • {join, nested_loop} 調用匹配來自兩個句柄的每對對象的方法。這種方法大多非常慢。

    如果qlc 模塊無法執行所選的連接方法,則查詢評估將失敗。默認為 any ,這意味著如果可能的話,使用某種快速連接方法。

相關用法


注:本文由純淨天空篩選整理自erlang.org大神的英文原創作品 q(QLC) -> QH。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。